!= Sample program for gtool_historyauto/gtool5
!
! * 2010/08/26 Y.Morikawa
! * 2009/10/18 Y.Morikawa
! * 2003/08/21 M.Odaka
! * 2001/02/27 S.Takehiro
!
! Solving diffusion equation
! \[
!     du/dt = \kappa d^2 u/dx^2
! \]
! for giving values of $u$ at $x=[0,1]$.
!
program diffusion_cal2

  use gtool_historyauto                       ! Access module (ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«æŒ‡å®š)
  use dc_calendar                             ! Access module (ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«æŒ‡å®š)
  use dc_types                                ! Access module (ãƒ¢ã‚¸ãƒ¥ãƒ¼ãƒ«æŒ‡å®š)

  integer, parameter     :: nx=30             ! Grid number   (ã‚°ãƒªãƒƒãƒ‰æ•°)
  real(DP), parameter    :: dx=1.0/(nx-1)     ! Grid interval (ã‚°ãƒªãƒƒãƒ‰é–“éš”)
  type(DC_CAL)         :: cal_gre             ! Gregorian Calendar (ã‚°ãƒ¬ã‚´ãƒªã‚ªæš¦)
  type(DC_CAL)         :: cal_mars            ! Martian Calendar   (ç«æ˜Ÿã£ã½ã„æš¦)
  type(DC_CAL_DATE)    :: start_date          ! Start Date (ãƒ¢ãƒ‡ãƒ«é–‹å§‹æ—¥æ™‚)
  type(DC_CAL_DATE)    :: end_date            ! End Date   (ãƒ¢ãƒ‡ãƒ«çµ‚äº†æ—¥æ™‚)
  real(DP)             :: dt                  ! Time step    [sec] (æ™‚é–“é–“éš” [ç§’])
  real(DP)             :: curtime             ! Current time [sec] (çµŒéŽæ™‚åˆ» [ç§’])
  real(DP)             :: endtime             ! End time     [sec] (çµ‚äº†æ™‚åˆ» [ç§’])
  real(DP)             :: dsptime             ! Output interval [day] (å‡ºåŠ›é–“éš” [æ—¥])

  real(DP)             :: sec_of_year         ! Second of year (å¹´å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  real(DP)             :: day_of_year         ! Day of year    (å¹´å§‹ã‚ã‹ã‚‰ã®é€šæ—¥)
  real(DP)             :: sec_of_day          ! Second of day  (æ—¥å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  logical              :: flag_leapyear       ! Leap year      (é–å¹´)

  real(DP), dimension(nx):: x=(/(dx*(i-1),i=1,nx)/) ! X coordinate (åº§æ¨™å¤‰æ•°)
  real(DP), dimension(nx):: temp                    ! Temperature (æ¸©åº¦)
  real(DP), parameter    :: kappa=1.0e-9            ! Diffusion coefficient (ç†±æ‹¡æ•£ä¿‚æ•°)

  character(256):: date_str1, date_str2

  character(32):: cal_type
  integer:: month_in_year, day_in_month(1:12), hour_in_day, min_in_hour
  integer, pointer:: day_in_month_ptr(:) =>null()
  real(DP):: sec_in_min

  call DCCalCreate( cal_type = 'Gregorian', cal = cal_gre )
  call DCCalCreate( month_in_year = 1 , &
    &               day_in_month  = (/669/), &
    &               hour_in_day   = 24, &
    &               min_in_hour   = 1 , &
    &               sec_in_min    = 3694.0_DP, &
    &               cal           = cal_mars )
                                                    ! Set calendar
                                                    ! (æš¦è¨å®š)

  call DCCalDateCreate( year = 2000, month =  1, day = 1, &
    &                   hour =    0, min   =  0, sec = 0.0_DP, &
    &                   date = start_date )
  call DCCalDateCreate( year = 2001, month =  1, day = 1, &
    &                   hour =    0, min   =  0, sec = 0.0_DP, &
    &                   date = end_date )
                                                    ! Set date
                                                    ! (æ—¥æ™‚è¨å®š)

  curtime = DCCalConvertByUnit(  0.0_DP, 'sec', 'sec', cal = cal_mars )
                                                    ! Set initial time
                                                    ! (åˆæœŸæ™‚åˆ»è¨å®š)
  endtime = DCCalDateDifference( start_date, end_date, cal = cal_mars )
                                                    ! Set end time
                                                    ! (çµ‚äº†æ™‚åˆ»è¨å®š)
  dt      = DCCalConvertByUnit(  1.0_DP, 'day', 'sec', cal = cal_mars )
                                                    ! Set time step
                                                    ! (æ™‚é–“ã‚¹ãƒ†ãƒƒãƒ—è¨å®š)
  dsptime = 10
                                                    ! Set output interval
                                                    ! (å‡ºåŠ›é–“éš”è¨å®š)

  temp = exp(-((x-0.5)/0.1)**2)                     ! Set initial value
                                                    ! (åˆæœŸå€¤è¨å®š)

  call HistoryAutoCreate( &                         ! Create output file
    & title='Diffusion equation',                &  ! (ãƒ’ã‚¹ãƒˆãƒªãƒ¼ä½œæˆ)
    & source='Sample program of gtool_historyauto/gtool5',   &
    & institution='GFD_Dennou Club davis project',           &
    & dims=(/'x','t'/), dimsizes=(/nx,0/),                   &
    & longnames=(/'X-coordinate','time        '/),           &
    & units=(/'m  ','day'/),                                 &
    & origin=curtime, terminus=endtime, interval=dsptime,    &
    & cal=cal_mars, start_date=start_date )

  call HistoryAutoPutAxis('x',x)                    ! Output 'x' (æ¬¡å…ƒå¤‰æ•°å‡ºåŠ›)

  call HistoryAutoAddVariable( &                    ! Set output variable
    & varname='temp', dims=(/'x','t'/), &           ! (å¤‰æ•°å®šç¾©)
    & longname='temperature', units='K', xtype='double', &
    & file='diffusion_cal2.nc' )

  call HistoryAutoPut(curtime,'temp',temp)          ! Output 'temp' (å¤‰æ•°å‡ºåŠ›)

  write(6,*) "Calendars: "

  call DCCalInquire( cal_type, &
    &                month_in_year    = month_in_year, &
    &                day_in_month_ptr = day_in_month_ptr, &
    &                hour_in_day      = hour_in_day, &
    &                min_in_hour      = min_in_hour, &
    &                sec_in_min       = sec_in_min, &
    &                cal              = cal_mars )
                                        ! Inquire calendar
                                        ! (æš¦ã«é–¢ã—ã¦å•ã„åˆã‚ã›)

  write(6,*) "       Martian Cal:   month in year:  ", month_in_year
  write(6,*) "                      days in months: ", day_in_month_ptr
  write(6,*) "                      hour in day:    ", hour_in_day
  write(6,*) "                      min in hour:    ", min_in_hour
  write(6,*) "                      sec in min:     ", sec_in_min
  deallocate(day_in_month_ptr)

  call DCCalInquire( cal_type, &
    &                month_in_year    = month_in_year, &
    &                day_in_month     = day_in_month, &
    &                hour_in_day      = hour_in_day, &
    &                min_in_hour      = min_in_hour, &
    &                sec_in_min       = sec_in_min, &
    &                cal              = cal_gre )
                                        ! Inquire calendar
                                        ! (æš¦ã«é–¢ã—ã¦å•ã„åˆã‚ã›)

  write(6,*) "       Gregorian Cal: month in year:  ", month_in_year
  write(6,*) "                      days in months: ", day_in_month
  write(6,*) "                      hour in day:    ", hour_in_day
  write(6,*) "                      min in hour:    ", min_in_hour
  write(6,*) "                      sec in min:     ", sec_in_min

  write(6,*) ""

  call DCCalDateInquire( date_str1, date = start_date )
                                        ! Inquire date and set a character variable
                                        ! (æ—¥æ™‚ã‚’å•ã„åˆã‚ã›ã¦æ–‡å—åž‹å¤‰æ•°ã¸ä»£å…¥)

  write(6,*) "Start: ", trim(date_str1)
                                                    ! Display start date
                                                    ! (é–‹å§‹æ—¥æ™‚ã®è¡¨ç¤º)

  sec_of_year   = DCCalDateEvalSecOfYear( curtime, start_date, cal_mars )
                                        ! Second of year (å¹´å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  day_of_year   = DCCalDateEvalDayOfYear( curtime, start_date, cal_mars )
                                        ! Day of year    (å¹´å§‹ã‚ã‹ã‚‰ã®é€šæ—¥)
  sec_of_day    = DCCalDateEvalSecOfDay( curtime, start_date, cal_mars )
                                        ! Second of day  (æ—¥å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  flag_leapyear = DCCalDateChkLeapYear( curtime, start_date, cal_mars )
                                        ! Leap year      (é–å¹´)

  write(6,*) "       Martian Cal:   second of year: ", sec_of_year
  write(6,*) "                      day of year:    ", day_of_year
  write(6,*) "                      second of day:  ", sec_of_day
  write(6,*) "                      leap year:      ", flag_leapyear

  sec_of_year   = DCCalDateEvalSecOfYear( curtime, start_date, cal_gre )
                                        ! Second of year (å¹´å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  day_of_year   = DCCalDateEvalDayOfYear( curtime, start_date, cal_gre )
                                        ! Day of year    (å¹´å§‹ã‚ã‹ã‚‰ã®é€šæ—¥)
  sec_of_day    = DCCalDateEvalSecOfDay( curtime, start_date, cal_gre )
                                        ! Second of day  (æ—¥å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  flag_leapyear = DCCalDateChkLeapYear( curtime, start_date, cal_gre )
                                        ! Leap year      (é–å¹´)

  write(6,*) "       Gregorian Cal: second of year: ", sec_of_year
  write(6,*) "                      day of year:    ", day_of_year
  write(6,*) "                      second of day:  ", sec_of_day
  write(6,*) "                      leap year:      ", flag_leapyear

  do while ( curtime < endtime )                    ! Check termination (çµ‚äº†åˆ¤å®š)

    temp(2:nx-1) = temp(2:nx-1) &                   ! Time integration (æ™‚é–“ç©åˆ†)
      & + kappa*(temp(3:nx)-2*temp(2:nx-1)+temp(1:nx-2))/dx**2*dt

    call HistoryAutoPut(curtime,'temp',temp)             ! Output 'temp' (å¤‰æ•°å‡ºåŠ›)

    curtime = curtime + dt                          ! Progress model time (ãƒ¢ãƒ‡ãƒ«æ™‚åˆ»é€²è¡Œ)
  enddo

  call DCCalDateInquire( date_str1, curtime, start_date, cal = cal_mars )
  call DCCalDateInquire( date_str2, curtime, start_date, cal = cal_gre )
                                        ! Inquire date and set a character variable
                                        ! (æ—¥æ™‚ã‚’å•ã„åˆã‚ã›ã¦æ–‡å—åž‹å¤‰æ•°ã¸ä»£å…¥)

  write(6,*) "End:   ", trim(date_str1), " (Mars), ", trim(date_str2), " (Gregorian)"
                                                    ! Display end date (çµ‚äº†æ—¥æ™‚å‡ºåŠ›)

  sec_of_year   = DCCalDateEvalSecOfYear( curtime, start_date, cal_mars )
                                        ! Second of year (å¹´å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  day_of_year   = DCCalDateEvalDayOfYear( curtime, start_date, cal_mars )
                                        ! Day of year    (å¹´å§‹ã‚ã‹ã‚‰ã®é€šæ—¥)
  sec_of_day    = DCCalDateEvalSecOfDay( curtime, start_date, cal_mars )
                                        ! Second of day  (æ—¥å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  flag_leapyear = DCCalDateChkLeapYear( curtime, start_date, cal_mars )
                                        ! Leap year      (é–å¹´)

  write(6,*) "       Martian Cal:   second of year: ", sec_of_year
  write(6,*) "                      day of year:    ", day_of_year
  write(6,*) "                      second of day:  ", sec_of_day
  write(6,*) "                      leap year:      ", flag_leapyear

  sec_of_year   = DCCalDateEvalSecOfYear( curtime, start_date, cal_gre )
                                        ! Second of year (å¹´å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  day_of_year   = DCCalDateEvalDayOfYear( curtime, start_date, cal_gre )
                                        ! Day of year    (å¹´å§‹ã‚ã‹ã‚‰ã®é€šæ—¥)
  sec_of_day    = DCCalDateEvalSecOfDay( curtime, start_date, cal_gre )
                                        ! Second of day  (æ—¥å§‹ã‚ã‹ã‚‰ã®é€šç§’)
  flag_leapyear = DCCalDateChkLeapYear( curtime, start_date, cal_gre )
                                        ! Leap year      (é–å¹´)

  write(6,*) "       Gregorian Cal: second of year: ", sec_of_year
  write(6,*) "                      day of year:    ", day_of_year
  write(6,*) "                      second of day:  ", sec_of_day
  write(6,*) "                      leap year:      ", flag_leapyear

  call HistoryAutoClose
  stop
end program diffusion_cal2