Skip to content
Snippets Groups Projects
Select Git revision
  • 4cca6a46aff14c778bea818effcc3c3d81d53c87
  • main default protected
  • editUser
  • loadTests
  • fixTests
  • userhandling
  • updateEmbeddings
  • addRAGSources
  • testing
  • conversations
  • inputValidation
  • rag
  • chatting
  • userauth
14 results

ollama.rest

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    calmod.f90 13.14 KiB
    !     =============
    !     MODULE CALMOD
    !     =============
    
          module calmod
          implicit none
          integer :: mondays(0:12) = (/0,31,28,31,30,31,30,31,31,30,31,30,31/)
          integer :: mona365(0:12) = (/0,31,59,90,120,151,181,212,243,273,304,334,365/)
          integer :: monaccu(0:12)
          integer :: ny400d = 400 * 365 + 97
          integer :: ny100d = 100 * 365 + 24
          integer :: ny004d =   4 * 365 +  1
          integer :: ny001d =       365
          integer :: nud        =  6
    
    !     These values are copied from pumamod in subroutine calini
    
          integer :: n_days_per_month =  30
          integer :: n_days_per_year  = 360
          integer :: n_start_step     =   0
          integer :: ntspd            =   0
          real    :: solar_day        = 86400.0 ! [sec]
    
          end module calmod
    
    
    !     =================
    !     SUBROUTINE CALINI
    !     =================
    
          subroutine calini(k_days_per_month,k_days_per_year,k_start_step &
                           ,ktspd,psolday,kpid)
          use calmod
    
          n_days_per_month = k_days_per_month
          n_days_per_year  = k_days_per_year
          n_start_step     = k_start_step
          ntspd            = ktspd
          solar_day        = psolday
    
          if (kpid == 0) then
             write(nud,1050)
             write(nud,1060)
             write(nud,1050)
             write(nud,1000) n_days_per_year
             write(nud,1010) n_days_per_month
             write(nud,1030) n_start_step
             write(nud,1040) ntspd
             write(nud,1050)
             endif
          return
     1060 format(" * Calmod initialization   *")
     1000 format(" * Days per year:    ",i5," *")
     1010 format(" * Days per month:   ",i5," *")
     1030 format(" * Start step:",i12," *")
     1040 format(" * Timesteps per day:",i5," *")
     1050 format(" ***************************")
          end subroutine calini
    
    !     ====================
    !     SUBROUTINE YDAY2MMDD
    !     ====================
    
          subroutine yday2mmdd(kyday,kmon,kday)
          use calmod
          if (n_days_per_year == 365) then
             kmon = 1
             do while (kyday > mona365(kmon))
                kmon = kmon + 1
             enddo
             kday = kyday - monaccu(kmon-1)
          else
             kmon = (kyday-1) / n_days_per_month
             kday = kyday - n_days_per_month * kmon
             kmon = kmon+1
          endif
          return
          end
    
    !     =================
    !     FUNCTION NWEEKDAY
    !     =================
    
          integer function nweekday(kday)
          nweekday = mod(kday+5,7)
          return
          end
    
    
    !     ===================
    !     FUNCTION NDAYOFYEAR
    !     ===================
    
          integer function ndayofyear(kstep)
          use calmod
          integer :: idatim(7)
    
          if (n_days_per_year == 365) then
             call step2cal(kstep,ntspd,idatim)
             ndayofyear = idatim(3) + monaccu(idatim(2)-1)
          else
             call step2cal30(kstep,ntspd,idatim)
             ndayofyear = idatim(3) + n_days_per_month * (idatim(2)-1)
          endif
    
          return
          end
    
    
    !     ===================
    !     SUBROUTINE STEP2CAL
    !     ===================
    
          subroutine step2cal(kstep,ktspd,kdatim)
          use calmod
          implicit none
          integer, intent(IN ) :: kstep     ! time step since simulation start
          integer, intent(IN ) :: ktspd     ! time steps per day
          integer, intent(OUT) :: kdatim(7) ! year,month,day,hour,min,weekday,leapyear
    
          integer :: iyea  ! current year   of simulation
          integer :: imon  ! current month  of simulation
          integer :: iday  ! current day    of simulation
          integer :: ihou  ! current hour   of simulation
          integer :: imin  ! current minute of simulation
          integer :: idall
          integer :: istp
          integer :: iy400,id400
          integer :: iy100,id100
          integer :: iy004,id004
          integer :: iy001,id001
          integer :: jmon
    
          logical :: leap
    
          idall = kstep   / ktspd
    
          iy400 = idall   / ny400d          ! segment [of 400 years]
          id400 = mod(idall,ny400d)
    
          if (id400 <= ny100d) then         ! century year is leap year
             iy100 =         0              ! century in segment [0]
             id100 =     id400
             iy004 =     id100 / ny004d     ! tetrade in century [0..24]
             id004 = mod(id100 , ny004d)
             leap  = (id004 <= ny001d)
             if (leap) then
                iy001 =     0               ! year in tetrade [0]
                id001 = id004
             else
                iy001 =    (id004-1)/ny001d ! year in tetrade [1,2,3]
                id001 = mod(id004-1, ny001d)
             endif
          else                              ! century year is not leap year
             iy100 =    (id400-1)/ny100d    ! century in segment [1,2,3]
             id100 = mod(id400-1, ny100d)
             if (id100 < ny004d-1) then
                iy004 = 0                   ! tetrade in century [0]
                id004 = id100
                leap  = .false.
                iy001 =     id004/ny001d    ! year in tetrade [1,2,3]
                id001 = mod(id004,ny001d)
             else
                iy004 = (id100+1)/ny004d    ! tetrade in century [1..24]
                id004 = mod(id100+1,ny004d)
                leap  = (id004 <= ny001d)
                if (leap) then
                   iy001 =     0            ! year in tetrade [0]
                   id001 = id004
                else
                   iy001 =    (id004-1)/ny001d
                   id001 = mod(id004-1, ny001d)
                endif
             endif
          endif
    
          iyea  = iy400 * 400 + iy100 * 100 + iy004 * 4 + iy001
    
          monaccu(0) = mondays(0)
          monaccu(1) = mondays(1)
          monaccu(2) = mondays(1) + mondays(2)
          if (leap) monaccu(2) = monaccu(2) + 1
          do jmon = 3 , 12
             monaccu(jmon) = monaccu(jmon-1) + mondays(jmon)
          enddo
          imon = 1
          id001 = id001 + 1
          do while (id001 > monaccu(imon))
             imon = imon + 1
          enddo
          iday = id001 - monaccu(imon-1)
    
          istp = mod(kstep,ktspd)
          imin = (istp * 1440) / ktspd
          ihou = imin / 60
          imin = mod(imin,60)
    
          kdatim(1) = iyea
          kdatim(2) = imon
          kdatim(3) = iday
          kdatim(4) = ihou
          kdatim(5) = imin
          kdatim(6) = mod(kstep/ktspd+5,7) ! day of week
          if (leap) then
             kdatim(7) = 1
          else
             kdatim(7) = 0
          endif
    
          return
          end subroutine step2cal
    
    !     ===================
    !     SUBROUTINE CAL2STEP
    !     ===================
    
          subroutine cal2step(kstep,ktspd,kyea,kmon,kday,khou,kmin)
          use calmod
          implicit none
          integer, intent(OUT) :: kstep ! time step since simulation start
          integer, intent(IN ) :: ktspd ! time steps per day
          integer, intent(IN ) :: kyea  ! current year   of simulation
          integer, intent(IN ) :: kmon  ! current month  of simulation
          integer, intent(IN ) :: kday  ! current day    of simulation
          integer, intent(IN ) :: khou  ! current hour   of simulation
          integer, intent(IN ) :: kmin  ! current minute of simulation
    
          integer :: idall
          integer :: ilp
          integer :: iy400,id400
          integer :: iy100,id100
          integer :: iy004,id004
          integer :: jmon
    
          logical :: leap
    
          if (n_days_per_year /= 365) then ! simplified calendar
             kstep = ktspd * (kyea    * n_days_per_year  &
                           + (kmon-1) * n_days_per_month &
                           +  kday-1)
          return
          endif
          iy400 = kyea   /  400    ! segment [400]
          id400 = mod(kyea ,400)   ! year in segment [0..399]
          iy100 = id400   / 100    ! century [0,1,2,3]
          id100 = mod(id400,100)   ! year in century [0..99]
          iy004 = id100   /   4    ! tetrade [0..24]
          id004 = mod(id100,  4)   ! year in tetrade [0,1,2,3]
    
          leap  = (id004 == 0 .and. (id100 /= 0 .or. id400 == 0))
    
          ilp = -1
          if (id004 > 0) ilp = ilp + 1
          if (iy100 > 0 .and. id100 == 0 ) ilp = ilp + 1
    
          monaccu(0) = mondays(0)
          monaccu(1) = mondays(1)
          monaccu(2) = mondays(1) + mondays(2)
          if (leap) monaccu(2) = monaccu(2) + 1
          do jmon = 3 , 12
             monaccu(jmon) = monaccu(jmon-1) + mondays(jmon)
          enddo
    
          idall = iy400 * ny400d + iy100 * ny100d + iy004 * ny004d &
                + id004 * ny001d + monaccu(kmon-1)+ kday + ilp
          kstep = ktspd * idall + (ktspd * (khou * 60 + kmin)) / 1440
    
          return
          end subroutine cal2step
    
    !     =====================
    !     SUBROUTINE STEP2CAL30
    !     =====================
    
          subroutine step2cal30(kstep,ktspd,kdatim)
          use calmod
          implicit none
          integer, intent(IN ) :: kstep     ! time step since simulation start
          integer, intent(IN ) :: ktspd     ! time steps per day
          integer, intent(OUT) :: kdatim(7) ! year,month,day,hour,min,weekday,leapyear
    
          integer :: iyea  ! current year   of simulation
          integer :: imon  ! current month  of simulation
          integer :: iday  ! current day    of simulation
          integer :: ihou  ! current hour   of simulation
          integer :: imin  ! current minute of simulation
          integer :: idall
          integer :: istp
    
          idall = kstep / ktspd
          iyea  = idall / n_days_per_year
          idall = mod(idall,n_days_per_year)
          imon  = idall / n_days_per_month + 1
          iday  = mod(idall,n_days_per_month) + 1
          istp  = mod(kstep,ktspd)
          imin  = (istp * solar_day) / (ktspd * 60)
          ihou  = imin / 60
          imin  = mod(imin,60)
    
          kdatim(1) = iyea
          kdatim(2) = imon
          kdatim(3) = iday
          kdatim(4) = ihou
          kdatim(5) = imin
          kdatim(6) = 0 ! day of week
          kdatim(7) = 0 ! leap year
    
          return
          end subroutine step2cal30
    
    !     =================
    !     SUBROUTINE NTOMIN
    !     =================
    
           subroutine ntomin(kstep,kmin,khou,kday,kmon,kyea)
           use calmod
           implicit none
    
           integer, intent(in ) :: kstep
           integer, intent(out) :: kmin,khou,kday,kmon,kyea
           integer :: idatim(7)
    
           if (n_days_per_year == 365) then
              call step2cal(kstep,ntspd,idatim)
           else
              call step2cal30(kstep,ntspd,idatim)
           endif
           kyea = idatim(1)
           kmon = idatim(2)
           kday = idatim(3)
           khou = idatim(4)
           kmin = idatim(5)
           return
           end
    
    !     =================
    !     SUBROUTINE NTODAT
    !     =================
    
          subroutine ntodat(istep,datch)
          character(len=18) datch
          character(len=3) mona(12)
          data mona /'Jan','Feb','Mar','Apr','May','Jun',                   &
         &           'Jul','Aug','Sep','Oct','Nov','Dec'/
          call ntomin(istep,imin,ihou,iday,imon,iyea)
          write (datch,20030) iday,mona(imon),iyea,ihou,imin
    20030 format(i2,'-',a3,'-',i4.4,2x,i2,':',i2.2)
          end
    
    
    !     =================
    !     SUBROUTINE DTODAT
    !     =================
    
          subroutine dtodat(id,datch)
          integer :: id(6)
          character(len=18) datch
          character(len=3) mona(12)
          data mona /'Jan','Feb','Mar','Apr','May','Jun',                   &
         &           'Jul','Aug','Sep','Oct','Nov','Dec'/
          write (datch,20030) id(3),mona(id(2)),id(1),id(4),id(5)
    20030 format(i2,'-',a3,'-',i4.4,2x,i2,':',i2.2)
          end
    
    
    !     =================
    !     SUBROUTINE MOMINT
    !     =================
    
    !     Compute month indices and weights for time interpolation from
    !     monthly mean data to current timestep
    
          subroutine momint(kperp,kstep,kmona,kmonb,pweight)
          use calmod
          implicit none
          integer, intent(in ) :: kperp   ! perpetual mode ?
          integer, intent(in ) :: kstep   ! target step
          integer, intent(out) :: kmona   ! current month (1-12)
          integer, intent(out) :: kmonb   ! next or previous month (0-13)
          real   , intent(out) :: pweight ! interpolation weight
    
          integer :: idatim(7) ! date time array
          integer :: iday
          integer :: ihour
          integer :: imin
          integer :: jmonb  ! next or previous month (1-12)
    
          real    :: zday   ! fractional day (including hour & minute)
          real    :: zdpma  ! days per month a
          real    :: zdpmb  ! days per month b
          real    :: zmeda  ! median day of the month a
          real    :: zmedb  ! median day of the month b
    
    !     convert time step to date / time
    
          idatim(:) = 0
          if (kperp > 0) then                     ! perpetual date
             call yday2mmdd(kperp,idatim(2),idatim(3))
          else if (n_days_per_year == 365) then   ! real calendar
             call step2cal(kstep,ntspd,idatim)
          else                                    ! simple calendar
             call step2cal30(kstep,ntspd,idatim)
          endif
    
          kmona = idatim(2)
          iday  = idatim(3)
          ihour = idatim(4)
          imin  = idatim(5)
    
    !     set fractional day
    
          zday = iday + ((ihour * 60.0 + imin) * 60.0) / solar_day
    
    !     compute median of month a
    
          zdpma = n_days_per_month
          if (n_days_per_year == 365) then
             zdpma = mondays(kmona)
             if (kmona == 2) zdpma = zdpma + idatim(7) ! leap year
          endif
          zmeda = 0.5 * (zdpma + 1.0) ! median day a
    
    !     define neighbour month
    
          if (zday > zmeda) then
             kmonb = kmona + 1 !     next month (maybe 13)
          else
             kmonb = kmona - 1 ! previous month (maybe  0)
          endif
    
    !     compute median of month b
    
          zdpmb = n_days_per_month
          if (n_days_per_year == 365) then
             jmonb = mod(kmonb+11,12) + 1 ! convert month (0-13) -> (1-12)
             zdpmb = mondays(jmonb)
             if (jmonb == 2) zdpmb = zdpmb + idatim(7) ! leap year
          endif
          zmedb = 0.5 * (zdpmb + 1.0) ! median day b
    
    !     compute weight
    
          pweight = abs(zday - zmeda) / (zmeda + zmedb - 1.0)
    
          return
          end subroutine momint