! module hist_module use input_module,only: mxlen_filename use params_module,only: spval,ispval implicit none ! ! History module contains non-user input variables to control ! primary and secondary history i/o, and defines the history ! structure type "history". A global variable "h" is declared ! type(history). ! ! Contained subroutines: ! sub hist_initype: initialize a history structure ! sub hist_print : print a history structure to stdout ! sub hist_init : initialize history control variables ! ! Procedure to add a new variable to the histories: ! 1. Add declarations to the history type below. ! 2. Add initialization of the new history structure component ! in sub hist_initype in this module. ! 3. Add write of new var to stdout in hist_print in this module. ! 4. Give value to the new structure component in sub define_hist ! (in output.f). The value may come from another module ! (e.g., "use input_mod"), or an included header file. ! (Define_hist is called prior to writing each history to disk). ! 5. Add definition of the new variable to the netcdf history file ! in sub nc_define (nchist_mod.F) (long name, units, etc) ! (declare variable id at top of nchist_mod.F, e.g., idv_ut, ! and make nc call according to dimensions and data type). ! (nc_define is called when a new netcdf history file is created) ! 6. Add value to the netcdf variable in nc_wrhist (nchist_mod.F) ! using the history structure component (e.g., h%ut) defined ! in step 4 above. ! 7. Add var to case statement in sub nc_rdhist (nchist_mod.F) ! for reading the variable from the source history. ! Make a short run to write the new variable to a history, which ! can then be used as a source history in subsequent runs. ! ! History parameters: ! integer,parameter :: | iprint = 0 ! print level flag logical :: netcdf ! true if writing netcdf histories ! ! Primary history related variables (not user input): integer :: | nseries_prim, ! number of primary history time series (1-mxseries) | iseries_prim, ! index to primary history time series | nsource, ! number of source files given (0 or 1) | nfiles_prim, ! number of history output files to be written | nstep, ! total number of steps this run | ncid, ! netcdf file id (ignored if .not.netcdf) | nhist, ! number of prim histories written to current hist file | nhist_total, ! number of prim histories written during run | ioutfile, ! output(ioutfile) is current open hist file name | modeltime(4) ! current model time (day,hrs,mins,secs) ! ! Secondary history related variables (not user input): ! Primary histories can be written in up to mxseries separate ! time sequences. Secondary histories can be written in up to ! mxseries_sech time sequences. (see params.h) ! integer :: | isechist, ! secondary history flag (global 0 or 1) | nseries_sech, ! number of secondary hist time series (<=mxseries_sech) | iseries_sech, ! index to current sech time series | istep_sech, ! number of steps since beginning of sech series | nfiles_sech, ! number of history files to be written | ncidsech, ! netcdf sech file id (ignored if .not.netcdf) | nsech, ! number of sech histories written to current file | nsecsource, ! number of secsource files given (for mhd model) | nsech_total, ! number of sech histories written during run | isecout, ! secout(isecout) is current open hist file name | nfsech ! number of secondary history fields (SECFLDS) ! ! History structure type: ! type history character(len=80) :: | label ! user-defined job comment (from namelist) character(len=16) :: | model_version, ! version string (e.g., timegcm1.3) | model_name ! model name (e.g., time-gcm) character(len=16) :: | hist_type, ! 'primary' or 'secondary' | run_type, ! 'initial' or 'continuation' | host, ! host machine (getenv of 'HOST') | system, ! operating system (pre-proc macro) | logname ! user login (getenv of 'LOGNAME') character(len=24) :: | create_date, ! date history file was created | write_date ! date current history was written character(len=mxlen_filename) :: | source_file, ! source file (this run) | initial_file, ! initial file (initial run) | output_file, ! output file (from namelist read) | ncep_ncfile, ! path to ncep file | ncep_reanalysis, ! path to ncep reanalysis file | ecmwf_ncfile, ! path to ecmwf era40 file | wacxg5_ncfile, ! path to wacxg5 nudging file | gpi_ncfile, ! gpi data file | gswm_mi_di_ncfile, ! GSWM migrating diurnal data file | gswm_mi_sdi_ncfile,! GSWM migrating semi-diurnal data file | gswm_nm_di_ncfile, ! GSWM non-migrating diurnal data file | gswm_nm_sdi_ncfile ! GSWM non-migrating semi-diurnal data file integer :: | nlat, ! number of latitude grid points | nlon, ! number of longitude grid points | nlev, ! number of vertical levels | ihist, ! ihist = nth history on current file | delhmins, ! delta minutes between histories | modeltime(4), ! model time (day,hour,minute,seconds) | iter, ! iteration (# steps from 0,0,0) | year, ! 4-digit year ! | calday, ! calendar day (1-367) | day, ! calendar day (1-367) | calendar_advance, ! 0/1 | step, ! time step (seconds) | initial_year, ! initial starting year | initial_day, ! initial starting day | initial_mtime(3), ! initial starting model time | source_mtime(3), ! start time of source history | tuv_lbc_intop ! 1 (old histories), or 0 (new histories) real :: | ut, ! ut (decimal hours, from modeltime) | time, ! model time ("minutes since yyyy-m-d") | missing_value, ! missing value (usually spval) | zmtop, ! top midpoint level | zmbot, ! bottom midpoint level | zitop, ! top interface level | zibot, ! bottom interface level | p0, ! reference pressure (5.e-7 mb (or hPa)) | p0_model, ! reference pressure used in the model (5.e-4 ubars) | grav, ! gravity constant used in model | hpower, ! hemispheric power | ctpoten, ! cross-cap potential | byimf, ! by imf | f107d, ! daily f10.7 cm flux | f107a, ! 81-day average f10.7 cm flux | dtide(2), ! diurnal tide (tide2(2) from input) | sdtide(10), ! semi-diurnal tide (tide(10) from input) | colfac, ! collision factor | alfa30,e30,alfad2,ed2, ! auroral parameters from input | lbc ! lower boundary interface level logical dynamo ! if true, is dynamo history logical coupled_ccm ! if true, run was coupled with ccm integer :: nflds ! total number of fields on history character(len=16), | pointer :: fnames(:) ! pointer to field names on this history end type history ! ! Global history structure variable: type(history) :: | h, ! output histories (primary or secondary) | sh ! source history (input) ! ! Initialization values: real :: real_init = spval ! initialization value for real vars contains !------------------------------------------------------------------- subroutine hist_initype(h,istep) use input_module,only: start_year,start_day,start, | calendar_advance,source_start use params_module,only: zibot ! ! Initialize a history structure: ! type(history),intent(out) :: h integer,intent(in) :: istep ! h%model_name = ' ' h%model_version = ' ' h%logname = ' ' h%host = ' ' h%system = ' ' h%hist_type = ' ' h%run_type = ' ' h%create_date = ' ' h%write_date = ' ' h%source_file = ' ' ! set by sub output h%output_file = ' ' ! set by sub output ! ! If this is an initial run, set initial calendar time to model ! start time. Otherwise (continuation run), the initial time has ! been read by rdsource (see nchist.F) ! if (nsource > 0) then h%initial_year = start_year h%initial_day = start_day h%initial_mtime = start(:,1) h%source_mtime = source_start endif h%ihist = -1 h%delhmins = 0 h%modeltime = (/-1,-1,-1,-1/) h%nlat = 0 h%nlon = 0 h%nlev = 0 h%zmtop = 0. h%zmbot = 0. h%zitop = 0. h%zibot = 0. h%time = -1 h%iter = -1 h%year = -1 h%day = -1 h%calendar_advance = calendar_advance h%ut = real_init h%step = -1 h%gswm_mi_di_ncfile = '[none]' h%gswm_mi_sdi_ncfile = '[none]' h%gswm_nm_di_ncfile = '[none]' h%gswm_nm_sdi_ncfile = '[none]' h%gpi_ncfile = '[none]' h%ncep_ncfile = '[none]' h%ecmwf_ncfile = '[none]' h%wacxg5_ncfile = '[none]' h%nflds = ispval h%dynamo = .false. h%coupled_ccm = .false. h%tuv_lbc_intop = 0 ! this version writes "new" histories h%lbc = zibot ! ! If istep==0, h%f107, etc were defined from source history: if (istep > 0) then h%hpower = real_init h%ctpoten = real_init h%f107d = real_init h%f107a = real_init endif h%byimf = real_init h%dtide = (/real_init,real_init/) h%sdtide(:) = real_init h%colfac = real_init h%p0 = real_init h%p0_model = real_init h%grav = real_init h%alfa30 = real_init h%e30 = real_init h%alfad2 = real_init h%ed2 = real_init if (associated(h%fnames)) deallocate(h%fnames) end subroutine hist_initype !------------------------------------------------------------------- subroutine hist_print(h,rdwr,diskfile) ! ! Print info about a history structure: ! ! Args: type(history),intent(in) :: h character(len=*),intent(in) :: rdwr,diskfile ! ! Locals: integer :: i ! write(6,"(/,72('-'))") if (h%hist_type(1:3)=='pri') then if (rdwr=='WRITE') then write(6,"('Write TGCM PRIMARY HISTORY',/,'Diskfile: ',a)") | trim(diskfile) else write(6,"('Read TGCM PRIMARY HISTORY (source history)', | /,'Diskfile: ',a)") trim(diskfile) endif elseif (h%hist_type(1:3)=='sec') then if (rdwr=='WRITE') then write(6,"('Write TGCM SECONDARY HISTORY',/,'Diskfile: ',a)") | trim(diskfile) else ! don't generally read sech, but you never know.. write(6,"('Read TGCM SECONDARY HISTORY',/,'Diskfile=',a)") | trim(diskfile) write(6,"('WARNING: Why am I reading a secondary history?')") write(6,"(9x,'The model will not start from secondary ', | 'history.')") endif else write(6,"('>>> print_hist: unknown type (apparently ', | 'not primary or secondary.')") endif ! write(6,"(2x,'model_name = ',a)") trim(h%model_name) write(6,"(2x,'model_version = ',a)") trim(h%model_version) write(6,"(2x,'create_date= ',a)") trim(h%create_date) write(6,"(2x,'write_date = ',a)") trim(h%write_date) write(6,"(2x,'logname = ',a)") trim(h%logname) write(6,"(2x,'host = ',a)") trim(h%host) write(6,"(2x,'system = ',a)") trim(h%system) write(6,"(2x,'source_file = ',a)") trim(h%source_file) write(6,"(2x,'output_file = ',a)") trim(h%output_file) write(6,"(2x,'source_mtime = ',3i4)") h%source_mtime write(6,"(2x,'initial_year = ',i4)") h%initial_year write(6,"(2x,'initial_day = ',i4)") h%initial_day write(6,"(2x,'initial_mtime= ',3i4)") h%initial_mtime write(6,"(2x,'type = ',a)") trim(h%hist_type) write(6,"(2x,'ihist = ',i3, | ' (nth history on history file)')") h%ihist write(6,"(2x,'delhmins= ',i4, | ' (delta minutes between histories)')") h%delhmins write(6,"(2x,'calendar year,day = ',i4,',',i3)") h%year,h%day if (h%calendar_advance<=0) then write(6,"(4x,'(model is NOT being advanced in calendar time)')") else write(6,"(4x,'(model IS being advanced in calendar time)')") endif write(6,"(2x,'modeltime = ',i3,',',i2,',',i2,',',i2, | ' (model time day,hour,minute,seconds)')") h%modeltime if (h%time <= 1440.) then write(6,"(2x,'time = ',f10.2,' (minutes in current day)')") | h%time else write(6,"(2x,'time = ')") endif write(6,"(2x,'ut = ',f5.2,' (ut hours)')") h%ut write(6,"(2x,'step = ',i4,' (time step in seconds)')") | h%step write(6,"(2x,'iter = ',i8,' (number of steps from 0,0,0)')") | h%iter write(6,"(2x,'nlat = ',i4,' (number of latitudes)')") h%nlat write(6,"(2x,'nlon = ',i4,' (number of longitudes)')") h%nlon write(6,"(2x,'nlev = ',i4,' (number of levels)')") h%nlev write(6,"(2x,'zmtop = ',f7.3,' (top midpoint level)')") h%zmtop write(6,"(2x,'zmbot = ',f7.3,' (bottom midpoint level)')") | h%zmbot write(6,"(2x,'zitop = ',f7.3,' (top interface level)')") h%zitop write(6,"(2x,'zibot = ',f7.3,' (bottom interface level)')") | h%zibot write(6,"(2x,'dtide = ',e8.1,' ',f5.1, | ' (amp/phase of diurnal tide)')") h%dtide write(6,"(2x,'sdtide = ',5e8.1,' ',5f5.1,/, | 4x,'(amp/phase of semi-diurnal tide)')") h%sdtide write(6,"(2x,'f107d = ',f6.2,' (daily solar flux)')") h%f107d write(6,"(2x,'f107a = ',f6.2,' (average solar flux)')") h%f107a write(6,"(2x,'hpower = ',f5.2,' (Gw)')") h%hpower write(6,"(2x,'ctpoten = ',f5.2,' (Volts)')") h%ctpoten write(6,"(2x,'byimf = ',f5.2)") h%byimf if (h%alfa30 /= real_init) | write(6,"(2x,'alfa30 = ',e9.2,' (KeV) (same as alfa_sp)')") | h%alfa30 if (h%e30 /= real_init) | write(6,"(2x,'e30 = ',e9.2,' (ergs/cm2/s) (same as e_sp)')") | h%e30 if (h%alfad2 /= real_init) | write(6,"(2x,'alfad2 = ',e9.2,' (KeV)')") h%alfad2 if (h%ed2 /= real_init) | write(6,"(2x,'ed2 = ',e9.2,' (ergs/cm2/s)')") h%ed2 write(6,"(2x,'colfac = ',f5.2)") h%colfac write(6,"(2x,'p0 = ',e9.2)") h%p0 if (h%p0_model /= real_init) write(6,"(2x,'p0_model= ',e9.2)") | h%p0_model write(6,"(2x,'gswm_mi_di_ncfile = ',a)") | trim(h%gswm_mi_di_ncfile) write(6,"(2x,'gswm_mi_sdi_ncfile = ',a)") | trim(h%gswm_mi_sdi_ncfile) write(6,"(2x,'gswm_nm_di_ncfile = ',a)") | trim(h%gswm_nm_di_ncfile) write(6,"(2x,'gswm_nm_sdi_ncfile = ',a)") | trim(h%gswm_nm_sdi_ncfile) write(6,"(2x,'gpi_ncfile = ',a)") trim(h%gpi_ncfile) write(6,"(2x,'ncep_ncfile = ',a)") trim(h%ncep_ncfile) write(6,"(2x,'ecmwf_ncfile = ',a)") trim(h%ecmwf_ncfile) write(6,"(2x,'wacxg5_ncfile = ',a)") trim(h%wacxg5_ncfile) write(6,"(2x,'tuv_lbc_intop=',i3,' (if 1, then lbc of t,u,v', | ' are stored in top k slot (old histories))')") h%tuv_lbc_intop write(6,"(2x,'LBC = ',f8.2,' (lower boundary interface ', | 'level)')") h%lbc if (h%nflds > 0) | write(6,"(2x,'nflds = ',i3,' (number of model fields)')") | h%nflds ! if (associated(h%fnames)) then write(6,"(' There are ',i3,' fields on this history,', + ' as follows:')") h%nflds do i=1,h%nflds write(6,"(2x,a)",advance="NO") h%fnames(i)(1:8) if (mod(i,8)==0.or.i==h%nflds) write(6,"(' ')") enddo endif write(6,"(72('-'),/)") return end subroutine hist_print !------------------------------------------------------------------- subroutine hist_init ! ! Initialize non-input history variables, using validated namelist ! user inputs from the input module: ! (this routine is called from init module after input validation) ! use params_module,only: mxseries,mxhvols,ispval use input_module,only: start,stop,step,source,output,mkhvols, | hist,save,secsource,secstart,secstop,sechist,secsave,secout, | secflds ! ! Local: integer :: nh,nsteps,i,secs_hist,nsteps_hist,n integer(kind=8) :: secs_start(mxseries),secs_stop(mxseries) character(len=80) :: hvols(mxhvols) ! ! External: integer(kind=8),external :: mtime_to_nsec integer,external :: numfiles ! ! Number of primary history time series: nseries_prim = (size(start)-count(start==ispval))/3 ! secs_start(:) = 0 do i=1,nseries_prim secs_start(i) = mtime_to_nsec(start(:,i)) secs_stop(i) = mtime_to_nsec(stop(:,i)) enddo ! ! Total number of timesteps this run: nstep = (secs_stop(nseries_prim)-secs_start(1))/step ! ! Number of source files given (0 or 1): if (len_trim(source)==0) then nsource = 0 else nsource = 1 endif ! ! Number of primary files to be written (nfiles_prim), and ! total primary histories to be written (nhist_total): nfiles_prim = numfiles('prim',nseries_prim,nsource,0,nhist_total) ! ! Initialize for beginning of run: iseries_prim = 1 nsech = 0 iseries_sech = 1 ! ! Number of secsource files given (0 or 1): if (len_trim(secsource)==0) then nsecsource = 0 else nsecsource = 1 endif ! ! Set secondary history non-input variables: ! ! n = total number of secondary history inputs read: n = size(secstart)-count(secstart==ispval) + | size(secstop) -count(secstop==ispval) + | size(sechist) -count(sechist==ispval) + | size(secsave) -count(secsave==ispval) + | size(secflds) -count(len_trim(secflds)==0) ! ! Number of secondary history time series: nseries_sech = (size(secstart)-count(secstart==ispval))/3 ! ! isechist: secondary histories flag: ! If no secondary history inputs were read, return. isechist = 0 if (n > 0) isechist = 1 if (isechist==0) return ! ! Secondary history init: secs_start(:) = 0 secs_start(:) = 0 do i=1,nseries_sech secs_start(i) = mtime_to_nsec(secstart(:,i)) secs_stop(i) = mtime_to_nsec(secstop(:,i)) enddo ! nfsech = size(secflds)-count(len_trim(secflds)==0) nfiles_sech = numfiles('sech',nseries_sech,1,0,nsech_total) ! end subroutine hist_init !------------------------------------------------------------------- end module hist_module