diff --git a/.gitignore b/.gitignore index 2c18e651e..be23dc894 100644 --- a/.gitignore +++ b/.gitignore @@ -110,4 +110,4 @@ ENV/ .spyproject # mkdocs documentation -/site +/site \ No newline at end of file diff --git a/bin/mkmf.template.nyu b/bin/mkmf.template.nyu index 406fc8e39..ac04f9269 100644 --- a/bin/mkmf.template.nyu +++ b/bin/mkmf.template.nyu @@ -3,7 +3,7 @@ # mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include CPPFLAGS = -I/usr/local/include CPPFLAGS += -I${NETCDF_INC} -FFLAGS = $(CPPFLAGS) -fpp -stack_temps -safe_cray_ptr -ftz -i-dynamic -assume byterecl -i4 -r8 +FFLAGS = $(CPPFLAGS) -fpp -stack_temps -safe_cray_ptr -ftz -i-dynamic -assume byterecl -i4 -r8 -flexiblas FFLAGS += -O2 FFLAGS += ${DEBUG} FFLAGS += -I${NETCDF_INC} -I${MPI_INC} diff --git a/exp/test_cases/MiMA/MiMA_test_case.py b/exp/test_cases/MiMA/MiMA_test_case.py index 270596744..586211935 100644 --- a/exp/test_cases/MiMA/MiMA_test_case.py +++ b/exp/test_cases/MiMA/MiMA_test_case.py @@ -19,8 +19,6 @@ # is used to load the correct compilers. The env file is always loaded from # $GFDL_BASE and not the checked out git repo. -cb.compile() # compile the source code to working directory $GFDL_WORK/codebase - # create an Experiment object to handle the configuration of model parameters # and output diagnostics exp = Experiment('mima_test_experiment', codebase=cb) @@ -174,6 +172,9 @@ }) #Lets do a run! if __name__=="__main__": + + cb.compile() # compile the source code to working directory $GFDL_WORK/codebase + exp.run(1, use_restart=False, num_cores=NCORES) for i in range(2,121): exp.run(i, num_cores=NCORES) diff --git a/exp/test_cases/ape_aquaplanet/socrates_ape_aquaplanet_T42.py b/exp/test_cases/ape_aquaplanet/socrates_ape_aquaplanet_T42.py index 1df4b3633..cc67c4e85 100644 --- a/exp/test_cases/ape_aquaplanet/socrates_ape_aquaplanet_T42.py +++ b/exp/test_cases/ape_aquaplanet/socrates_ape_aquaplanet_T42.py @@ -161,7 +161,7 @@ 'evaporation':True, 'depth': 10.0, #Depth of mixed layer used 'albedo_value': 0.38, #Albedo value used - 'do_ape_sst': True, + 'do_ape_sst' : True, }, 'qe_moist_convection_nml': { diff --git a/exp/test_cases/bucket_hydrology/bucket_model_test_case.py b/exp/test_cases/bucket_hydrology/bucket_model_test_case.py index 73431552a..85f10bb17 100644 --- a/exp/test_cases/bucket_hydrology/bucket_model_test_case.py +++ b/exp/test_cases/bucket_hydrology/bucket_model_test_case.py @@ -19,8 +19,6 @@ # is used to load the correct compilers. The env file is always loaded from # $GFDL_BASE and not the checked out git repo. -cb.compile() # compile the source code to working directory $GFDL_WORK/codebase - # create an Experiment object to handle the configuration of model parameters # and output diagnostics exp = Experiment('bucket_test_experiment', codebase=cb) @@ -179,6 +177,8 @@ #Lets do a run! if __name__=="__main__": + cb.compile() # compile the source code to working directory $GFDL_WORK/codebase + exp.run(1, use_restart=False, num_cores=NCORES) for i in range(2,121): exp.run(i, num_cores=NCORES) \ No newline at end of file diff --git a/exp/test_cases/frierson/frierson_test_case.py b/exp/test_cases/frierson/frierson_test_case.py index 6dfa83b10..6be2e58c0 100644 --- a/exp/test_cases/frierson/frierson_test_case.py +++ b/exp/test_cases/frierson/frierson_test_case.py @@ -19,8 +19,6 @@ # is used to load the correct compilers. The env file is always loaded from # $GFDL_BASE and not the checked out git repo. -cb.compile() # compile the source code to working directory $GFDL_WORK/codebase - # create an Experiment object to handle the configuration of model parameters # and output diagnostics exp = Experiment('frierson_test_experiment', codebase=cb) @@ -173,6 +171,8 @@ #Lets do a run! if __name__=="__main__": + cb.compile() # compile the source code to working directory $GFDL_WORK/codebase + exp.run(1, use_restart=False, num_cores=NCORES) for i in range(2,121): exp.run(i, num_cores=NCORES) diff --git a/exp/test_cases/realistic_continents/realistic_continents_fixed_sst_test_case.py b/exp/test_cases/realistic_continents/realistic_continents_fixed_sst_test_case.py index ef5b3d03e..23b039d2f 100644 --- a/exp/test_cases/realistic_continents/realistic_continents_fixed_sst_test_case.py +++ b/exp/test_cases/realistic_continents/realistic_continents_fixed_sst_test_case.py @@ -21,8 +21,6 @@ # is used to load the correct compilers. The env file is always loaded from # $GFDL_BASE and not the checked out git repo. -cb.compile() # compile the source code to working directory $GFDL_WORK/codebase - # create an Experiment object to handle the configuration of model parameters # and output diagnostics exp = Experiment('realistic_continents_fixed_sst_test_experiment', codebase=cb) @@ -72,6 +70,8 @@ #Lets do a run! if __name__=="__main__": + cb.compile() # compile the source code to working directory $GFDL_WORK/codebase + exp.run(1, use_restart=False, num_cores=NCORES) for i in range(2,121): exp.run(i, num_cores=NCORES) diff --git a/exp/test_cases/realistic_continents/realistic_continents_fixed_sst_wv_age_test_case.py b/exp/test_cases/realistic_continents/realistic_continents_fixed_sst_wv_age_test_case.py new file mode 100644 index 000000000..8b039c9c3 --- /dev/null +++ b/exp/test_cases/realistic_continents/realistic_continents_fixed_sst_wv_age_test_case.py @@ -0,0 +1,90 @@ +import os + +import numpy as np + +import f90nml + +from isca import IscaCodeBase, DiagTable, Experiment, Namelist, GFDL_BASE + + +NCORES = 4 +base_dir = os.path.dirname(os.path.realpath(__file__)) +# a CodeBase can be a directory on the computer, +# useful for iterative development +cb = IscaCodeBase.from_directory(GFDL_BASE) + +# or it can point to a specific git repo and commit id. +# This method should ensure future, independent, reproducibility of results. +# cb = DryCodeBase.from_repo(repo='https://github.com/isca/isca', commit='isca1.1') + +# compilation depends on computer specific settings. The $GFDL_ENV +# environment variable is used to determine which `$GFDL_BASE/src/extra/env` file +# is used to load the correct compilers. The env file is always loaded from +# $GFDL_BASE and not the checked out git repo. + +# create an Experiment object to handle the configuration of model parameters +# and output diagnostics + +# Select field table for age moment tracers +n_moments = 2 +field_table_name = f"field_table_age_{n_moments}" + + +exp = Experiment('realistic_continents_fixed_sst_wv_age_test_experiment', codebase=cb,field_table_name = field_table_name) + +#Add any input files that are necessary for a particular experiment. +exp.inputfiles = [os.path.join(GFDL_BASE,'input/land_masks/era_land_t42.nc'),os.path.join(GFDL_BASE,'input/rrtm_input_files/ozone_1990.nc'), + os.path.join(base_dir,'input/sst_clim_amip.nc'), os.path.join(base_dir,'input/siconc_clim_amip.nc')] + +#Tell model how to write diagnostics +diag = DiagTable() +diag.add_file('atmos_monthly', 30, 'days', time_units='days') + + +#Tell model which diagnostics to write +diag.add_field('dynamics', 'ps', time_avg=True) +diag.add_field('dynamics', 'bk') +diag.add_field('dynamics', 'pk') +diag.add_field('dynamics', 'zsurf') #need at least ps, pk, bk and zsurf to do vertical interpolation onto plevels from sigma +diag.add_field('atmosphere', 'precipitation', time_avg=True) +diag.add_field('mixed_layer', 't_surf', time_avg=True) +diag.add_field('dynamics', 'sphum', time_avg=True) +diag.add_field('dynamics', 'ucomp', time_avg=True) +diag.add_field('dynamics', 'vcomp', time_avg=True) +diag.add_field('dynamics', 'temp', time_avg=True) +diag.add_field('dynamics', 'vor', time_avg=True) +diag.add_field('dynamics', 'div', time_avg=True) + +# WV age moments diagnostics +for ind in range(n_moments): + name = f"sphum_age_{ind+1}" + diag.add_field('dynamics', name, time_avg=True) + +exp.diag_table = diag + + +#Empty the run directory ready to run +exp.clear_rundir() + +#Define values for the 'core' namelist +namelist_name = os.path.join(GFDL_BASE, 'exp/test_cases/realistic_continents/namelist_basefile.nml') +nml = f90nml.read(namelist_name) +exp.namelist = nml + +exp.update_namelist({ + 'mixed_layer_nml': { + 'do_qflux' : False, #Don't use the prescribed analytical formula for q-fluxes + 'do_read_sst' : True, #Read in sst values from input file + 'do_sc_sst' : True, #Do specified ssts (need both to be true) + 'sst_file' : 'sst_clim_amip', #Set name of sst input file + 'specify_sst_over_ocean_only' : True, #Make sure sst only specified in regions of ocean. + } +}) + +#Lets do a run! +if __name__=="__main__": + cb.compile() # compile the source code to working directory $GFDL_WORK/codebase + + exp.run(1, use_restart=False, num_cores=NCORES) + for i in range(2,121): + exp.run(i, num_cores=NCORES) diff --git a/exp/test_cases/realistic_continents/realistic_continents_variable_qflux_test_case.py b/exp/test_cases/realistic_continents/realistic_continents_variable_qflux_test_case.py index 522c9cf00..c1fbe97df 100644 --- a/exp/test_cases/realistic_continents/realistic_continents_variable_qflux_test_case.py +++ b/exp/test_cases/realistic_continents/realistic_continents_variable_qflux_test_case.py @@ -21,8 +21,6 @@ # is used to load the correct compilers. The env file is always loaded from # $GFDL_BASE and not the checked out git repo. -cb.compile() # compile the source code to working directory $GFDL_WORK/codebase - # create an Experiment object to handle the configuration of model parameters # and output diagnostics exp = Experiment('realistic_continents_qflux_test_experiment', codebase=cb) diff --git a/exp/test_cases/trip_test/trip_test_functions.py b/exp/test_cases/trip_test/trip_test_functions.py index b2059e4cd..28a08d4f7 100644 --- a/exp/test_cases/trip_test/trip_test_functions.py +++ b/exp/test_cases/trip_test/trip_test_functions.py @@ -193,7 +193,7 @@ def conduct_comparison_on_test_case(base_commit, later_commit, test_case_name, r else: cb = IscaCodeBase(repo=repo_to_use, commit=s) try: - cb.compile() + cb.compile(debug = False) exp = Experiment(exp_name, codebase=cb) exp.namelist = nml_use.copy() exp.diag_table = diag_use diff --git a/input/fixed_ssts/sst283.nc b/input/fixed_ssts/sst283.nc new file mode 100644 index 000000000..c265ddeba Binary files /dev/null and b/input/fixed_ssts/sst283.nc differ diff --git a/input/fixed_ssts/sst285.nc b/input/fixed_ssts/sst285.nc new file mode 100644 index 000000000..537a5068f Binary files /dev/null and b/input/fixed_ssts/sst285.nc differ diff --git a/input/fixed_ssts/sst287.nc b/input/fixed_ssts/sst287.nc new file mode 100644 index 000000000..24cfb8454 Binary files /dev/null and b/input/fixed_ssts/sst287.nc differ diff --git a/input/fixed_ssts/sst289.nc b/input/fixed_ssts/sst289.nc new file mode 100644 index 000000000..3e5d22283 Binary files /dev/null and b/input/fixed_ssts/sst289.nc differ diff --git a/input/fixed_ssts/sst291.nc b/input/fixed_ssts/sst291.nc new file mode 100644 index 000000000..111aa105e Binary files /dev/null and b/input/fixed_ssts/sst291.nc differ diff --git a/input/land_masks/era_land_t42.nc b/input/land_masks/era_land_t42.nc index e2a5664f8..2e3611190 100644 Binary files a/input/land_masks/era_land_t42.nc and b/input/land_masks/era_land_t42.nc differ diff --git a/src/atmos_column/column.F90 b/src/atmos_column/column.F90 index c059f0fdf..cf873169c 100644 --- a/src/atmos_column/column.F90 +++ b/src/atmos_column/column.F90 @@ -58,7 +58,7 @@ module column_mod !real, allocatable, dimension(:) :: lat_boundaries_global, lon_boundaries_global real :: virtual_factor, dt_real -integer :: pe, npes, num_tracers, nhum, step_number +integer :: pe, npes, num_tracers, nhum,nhum_age,nhum_sink, step_number integer :: is, ie, js, je integer :: previous, current, future @@ -109,14 +109,16 @@ module column_mod contains -subroutine column_init(Time, Time_step_in, tracer_attributes, dry_model_out, nhum_out) +subroutine column_init(Time, Time_step_in, tracer_attributes, dry_model_out, nhum_out,nhum_out_age,nhum_out_sink) type(time_type), intent(in) :: Time, Time_step_in type(tracer_type), intent(inout), dimension(:) :: tracer_attributes logical, intent(out) :: dry_model_out integer, intent(out) :: nhum_out + integer, intent(out) :: nhum_out_age + integer, intent(out) :: nhum_out_sink - integer :: unit, ierr, io, ntr, nsphum, nmix_rat, seconds, days + integer :: unit, ierr, io, ntr, nsphum,nsphum_age,nsphum_sink, nmix_rat, seconds, days !real :: del_lon, del_lat !!! NTL START HERE !real :: longitude_origin_local = 0.0 @@ -172,11 +174,15 @@ subroutine column_init(Time, Time_step_in, tracer_attributes, dry_model_out, nhu enddo nsphum = get_tracer_index(MODEL_ATMOS, 'sphum') + nsphum_age = get_tracer_index(MODEL_ATMOS, 'sphum_age') + nsphum_sink = get_tracer_index(MODEL_ATMOS, 'sphum_sink') nmix_rat = get_tracer_index(MODEL_ATMOS, 'mix_rat') if(nsphum == NO_TRACER) then if(nmix_rat == NO_TRACER) then nhum = 0 + nhum_age = 0 + nhum_sink = 0 dry_model = .true. else nhum = nmix_rat @@ -185,6 +191,8 @@ subroutine column_init(Time, Time_step_in, tracer_attributes, dry_model_out, nhu else if(nmix_rat == NO_TRACER) then nhum = nsphum + nhum_age = nsphum_age + nhum_sink = nsphum_sink dry_model = .false. else call error_mesg('column_init','sphum and mix_rat cannot both be specified as tracers at the same time', FATAL) @@ -192,6 +200,8 @@ subroutine column_init(Time, Time_step_in, tracer_attributes, dry_model_out, nhu endif dry_model_out = dry_model nhum_out = nhum + nhum_out_age = nhum_age + nhum_out_sink = nhum_sink call read_restart_or_do_coldstart(tracer_attributes) diff --git a/src/atmos_param/qe_moist_convection/qe_moist_convection.F90 b/src/atmos_param/qe_moist_convection/qe_moist_convection.F90 index 2f57b9ecf..e4f5b5e72 100644 --- a/src/atmos_param/qe_moist_convection/qe_moist_convection.F90 +++ b/src/atmos_param/qe_moist_convection/qe_moist_convection.F90 @@ -336,6 +336,7 @@ subroutine SBM_convection_scheme(dt, Tin, qin, p_full, p_half, rain, snow, & ! Calculate the precipitation rate Pq call Pq_calculation(kLZB, k_surface, qref_parcel, qin(i,j,:), & p_half(i,j,:), deltaq_parcel, Pq_parcel, dt) + ! Calculate the humidity change that would be necessary ! to balance temperature change by latent heat release call Pt_calculation(kLZB, k_surface, Tref_parcel, Tin(i,j,:), & diff --git a/src/atmos_solo/atmos_model.F90 b/src/atmos_solo/atmos_model.F90 index fe1388ce4..eb3ed2ec8 100644 --- a/src/atmos_solo/atmos_model.F90 +++ b/src/atmos_solo/atmos_model.F90 @@ -115,15 +115,11 @@ program atmos_model call constants_init call fms_init ( ) call atmos_model_init - ! ------ atmosphere integration loop ------- call mpp_clock_begin (id_loop) - do na = 1, num_atmos_calls - call atmosphere (Time) - Time = Time + Time_step_atmos if(modulo(na,memuse_interval) == 0 .and. print_memuse) then @@ -132,7 +128,6 @@ program atmos_model endif enddo - call mpp_clock_end (id_loop) ! ------ end of atmospheric time step loop ----- diff --git a/src/atmos_spectral/driver/solo/age_moments.F90 b/src/atmos_spectral/driver/solo/age_moments.F90 new file mode 100644 index 000000000..99a3a6b03 --- /dev/null +++ b/src/atmos_spectral/driver/solo/age_moments.F90 @@ -0,0 +1,29 @@ +module age_moments_mod + implicit none + public :: get_age_moments +contains + +subroutine get_age_moments(nsphum, nsphum_age, previous, grid_tracers, sink, dt_tracers) + implicit none + + integer, intent(in) :: nsphum + integer, intent(in) :: nsphum_age + integer, intent(in) :: previous + real, dimension(:,:,:,:,:), intent(in) :: grid_tracers + real, dimension(:,:,:), intent(in) :: sink + real, dimension(:,:,:,:), intent(inout) :: dt_tracers + + real :: eps_blowup + integer :: i + + eps_blowup = 1e-10 + + ! Calculates the RHS of age-moment evolution equation + do i = 2, nsphum_age + dt_tracers(:,:,:,i) = dt_tracers(:,:,:,i) + (i-1) * grid_tracers(:,:,:,previous,i-1) + sink * (grid_tracers(:,:,:,previous,i)/(eps_blowup+grid_tracers(:,:,:,previous,nsphum))) + end do + +end subroutine get_age_moments + +end module age_moments_mod + diff --git a/src/atmos_spectral/driver/solo/atmosphere.F90 b/src/atmos_spectral/driver/solo/atmosphere.F90 index 3091e1fe0..b89446714 100644 --- a/src/atmos_spectral/driver/solo/atmosphere.F90 +++ b/src/atmos_spectral/driver/solo/atmosphere.F90 @@ -85,7 +85,7 @@ module atmosphere_mod !================================================================================================================================= integer, parameter :: num_time_levels = 2 -integer :: is, ie, js, je, num_levels, num_tracers, nhum +integer :: is, ie, js, je, num_levels, num_tracers, nhum,n_age logical :: dry_model, column_model real, allocatable, dimension(:,:,:,:) :: p_half, p_full @@ -157,6 +157,9 @@ subroutine atmosphere_init(Time_init, Time, Time_step_in) call spectral_dynamics_init(Time, Time_step, tracer_attributes, dry_model, nhum) column_model = .false. #endif + +n_age = num_tracers - nhum + 1 + call get_grid_domain(is, ie, js, je) call get_num_levels(num_levels) @@ -218,8 +221,8 @@ subroutine atmosphere_init(Time_init, Time, Time_step_in) do ntr = 1,num_tracers tr_name = trim(tracer_attributes(ntr)%name) call read_data(trim(file), trim(tr_name), grid_tracers(:,:,:,nt,ntr), grid_domain, timelevel=nt) - enddo ! end loop over tracers - enddo ! end loop over time levels + enddo + enddo call read_data(trim(file), 'wg_full', wg_full, grid_domain) else previous = 1; current = 1 @@ -261,14 +264,14 @@ subroutine atmosphere_init(Time_init, Time, Time_step_in) enddo if(idealized_moist_model) then - call idealized_moist_phys_init(Time, Time_step, nhum, rad_lon_2d, rad_lat_2d, rad_lonb_2d, rad_latb_2d, tg(:,:,num_levels,current)) + call idealized_moist_phys_init(Time, Time_step, nhum,n_age, rad_lon_2d, rad_lat_2d, rad_lonb_2d, rad_latb_2d, tg(:,:,num_levels,current)) else call hs_forcing_init(get_axis_id(), Time, rad_lonb_2d, rad_latb_2d, rad_lat_2d) endif - module_is_initialized = .true. return + end subroutine atmosphere_init !================================================================================================================================= @@ -282,7 +285,6 @@ subroutine atmosphere(Time) if(.not.module_is_initialized) then call error_mesg('atmosphere','atmosphere module is not initialized',FATAL) endif - dt_ug = 0.0 dt_vg = 0.0 dt_tg = 0.0 @@ -300,6 +302,7 @@ subroutine atmosphere(Time) if(idealized_moist_model) then call idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, psg, wg_full, tg, grid_tracers, & previous, current, dt_ug, dt_vg, dt_tg, dt_tracers) + else call hs_forcing(1, ie-is+1, 1, je-js+1, delta_t, Time_next, rad_lon_2d, rad_lat_2d, & p_half(:,:,:,current ), p_full(:,:,:,current ), & @@ -328,6 +331,7 @@ subroutine atmosphere(Time) p_full(:,:,:,current), p_half(:,:,:,current), z_full(:,:,:,current)) #endif + if(dry_model) then call compute_pressures_and_heights(tg(:,:,:,future), psg(:,:,future), surf_geopotential, & z_full(:,:,:,future), z_half(:,:,:,future), p_full(:,:,:,future), p_half(:,:,:,future)) diff --git a/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 b/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 index 81963dbc6..ad5cd92e0 100644 --- a/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 +++ b/src/atmos_spectral/driver/solo/idealized_moist_phys.F90 @@ -38,6 +38,8 @@ module idealized_moist_phys_mod use diag_manager_mod, only: register_diag_field, send_data +use age_moments_mod + #ifdef COLUMN_MODEL use column_mod, only: get_num_levels, get_surf_geopotential, get_axis_id use spec_mpp_mod, only: get_grid_domain, grid_domain @@ -125,6 +127,9 @@ module idealized_moist_phys_mod logical :: do_rrtm_radiation = .false. logical :: do_socrates_radiation = .false. +! WVRT option +logical :: do_wv_age = .false. + ! MiMA uses damping logical :: do_damping = .false. @@ -144,6 +149,7 @@ module idealized_moist_phys_mod character(len=256) :: land_file_name = 'INPUT/land.nc' character(len=256) :: land_field_name = 'land_mask' + ! Add bucket logical :: bucket = .false. integer :: future @@ -155,8 +161,8 @@ module idealized_moist_phys_mod ! end Add bucket namelist / idealized_moist_phys_nml / turb, lwet_convection, do_bm, do_ras, roughness_heat, & - do_cloud_simple, do_cloud_spookie, & - two_stream_gray, do_rrtm_radiation, do_damping,& + do_wv_age, do_cloud_simple, do_cloud_spookie, & + two_stream_gray, do_rrtm_radiation ,do_damping,& mixed_layer_bc, do_simple, & roughness_moist, roughness_mom, do_virtual, & land_option, land_file_name, land_field_name, & ! options for idealised land @@ -175,6 +181,8 @@ module idealized_moist_phys_mod z_surf, & ! surface height t_surf, & ! surface temperature q_surf, & ! surface moisture + dt_sink, & + dq, & u_surf, & ! surface U wind v_surf, & ! surface V wind rough_mom, & ! momentum roughness length for surface_flux @@ -230,8 +238,10 @@ module idealized_moist_phys_mod non_diff_dt_vg, & ! merid. wind tendency except from vertical diffusion non_diff_dt_tg, & ! temperature tendency except from vertical diffusion non_diff_dt_qg, & ! moisture tendency except from vertical diffusion + non_diff_dt_age, & ! age-mass tendency except from vertical diffusion conv_dt_tg, & ! temperature tendency from convection conv_dt_qg, & ! moisture tendency from convection + sink, & ! negative moisture tendency from convection cond_dt_tg, & ! temperature tendency from condensation cond_dt_qg ! moisture tendency from condensation @@ -278,7 +288,11 @@ module idealized_moist_phys_mod id_cond_rain, & ! rain from condensation id_precip, & ! rain and snow from condensation and convection id_conv_dt_tg, & ! temperature tendency from convection - id_conv_dt_qg, & ! temperature tendency from convection + id_conv_dt_qg, & ! moisture tendency from convection + id_sink, & ! negative moisture tendency + id_dt_tracer, & ! total tendency of age-mass + id_dt_tracer_diff, & ! diffusion tendency of age-mass + id_dt_q, & ! total moisture tendency id_cond_dt_tg, & ! temperature tendency from condensation id_cond_dt_qg, & ! temperature tendency from condensation id_bucket_depth, & ! bucket depth variable for output @@ -311,7 +325,7 @@ module idealized_moist_phys_mod logical :: used, doing_edt, doing_entrain, do_strat integer, dimension(4) :: axes -integer :: is, ie, js, je, num_levels, nsphum, dt_integer +integer :: is, ie, js, je, num_levels, nsphum,nsphum_age, dt_integer real :: dt_real type(time_type) :: Time_step @@ -319,9 +333,10 @@ module idealized_moist_phys_mod contains !================================================================================================================================= -subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lon_2d, rad_lat_2d, rad_lonb_2d, rad_latb_2d, t_surf_init) +subroutine idealized_moist_phys_init(Time, Time_step_in, nhum,n_age, rad_lon_2d, rad_lat_2d, rad_lonb_2d, rad_latb_2d, t_surf_init) type(time_type), intent(in) :: Time, Time_step_in integer, intent(in) :: nhum +integer, intent(in) :: n_age real, intent(in), dimension(:,:) :: rad_lon_2d, rad_lat_2d, rad_lonb_2d, rad_latb_2d, t_surf_init integer :: io, ierr, nml_unit, stdlog_unit, seconds, days, id, jd, kd @@ -457,6 +472,13 @@ subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lon_2d, rad_l nsphum = nhum + +if(do_wv_age) then + nsphum_age = n_age +else + nsphum_age = 0 +endif + Time_step = Time_step_in call get_time(Time_step, seconds, days) dt_integer = 86400*days + seconds @@ -477,6 +499,8 @@ subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lon_2d, rad_l allocate(t_surf (is:ie, js:je)) allocate(q_surf (is:ie, js:je)); q_surf = 0.0 allocate(u_surf (is:ie, js:je)); u_surf = 0.0 +allocate(dt_sink (is:ie, js:je)); +allocate(dq (is:ie, js:je)); allocate(v_surf (is:ie, js:je)); v_surf = 0.0 allocate(rough_mom (is:ie, js:je)); rough_mom = roughness_mom allocate(rough_heat (is:ie, js:je)); rough_heat = roughness_heat @@ -526,11 +550,14 @@ subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lon_2d, rad_l allocate(non_diff_dt_vg (is:ie, js:je, num_levels)) allocate(non_diff_dt_tg (is:ie, js:je, num_levels)) allocate(non_diff_dt_qg (is:ie, js:je, num_levels)) +allocate(non_diff_dt_age (is:ie, js:je, num_levels)) allocate(net_surf_sw_down (is:ie, js:je)) allocate(surf_lw_down (is:ie, js:je)) allocate(conv_dt_tg (is:ie, js:je, num_levels)) allocate(conv_dt_qg (is:ie, js:je, num_levels)) +allocate(sink (is:ie, js:je, num_levels)) + allocate(cond_dt_tg (is:ie, js:je, num_levels)) allocate(cond_dt_qg (is:ie, js:je, num_levels)) @@ -549,7 +576,6 @@ subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lon_2d, rad_l allocate(convect (is:ie, js:je)); convect = .false. - allocate(t_ref (is:ie, js:je, num_levels)); t_ref = 0.0 allocate(q_ref (is:ie, js:je, num_levels)); q_ref = 0.0 @@ -761,6 +787,14 @@ subroutine idealized_moist_phys_init(Time, Time_step_in, nhum, rad_lon_2d, rad_l !if(lwet_convection .or. do_bm) then id_conv_dt_qg = register_diag_field(mod_name, 'dt_qg_convection', & axes(1:3), Time, 'Moisture tendency from convection','kg/kg/s') + id_sink = register_diag_field(mod_name, 'dt_sink', & + axes(1:3), Time, '(sink) negative Moisture tendency from convection','kg/kg/s') + id_dt_tracer = register_diag_field(mod_name, 'dt_tracer', & + axes(1:3), Time, 'tendency age-mass','kg/kg') + id_dt_tracer_diff = register_diag_field(mod_name, 'dt_tracer_diff', & + axes(1:3), Time, 'tendency age-mass from diffusion','kg/kg') + id_dt_q = register_diag_field(mod_name, 'dt_q', & + axes(1:3), Time, 'total moiture tendency','kg/kg/s') id_conv_dt_tg = register_diag_field(mod_name, 'dt_tg_convection', & axes(1:3), Time, 'Temperature tendency from convection','K/s') id_conv_rain = register_diag_field(mod_name, 'convection_rain', & @@ -825,6 +859,8 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps real, dimension(:,:,:,:,:), intent(in) :: grid_tracers integer, intent(in) :: previous, current real, dimension(:,:,:), intent(inout) :: dt_ug, dt_vg, dt_tg + +! dt_tracers real, dimension(:,:,:,:), intent(inout) :: dt_tracers real :: delta_t @@ -838,8 +874,10 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps real, dimension(1,1,1):: tracer, tracertnd integer :: nql, nqi, nqa ! tracer indices for stratiform clouds +logical :: flag_test + -if(current == previous) then +if(current == previous) then delta_t = dt_real else delta_t = 2*dt_real @@ -851,9 +889,14 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps endif +! rain and convective rain and precip rain = 0.0; snow = 0.0; precip = 0.0; klcls = 0 convective_rain = 0.0 +! set sink of WV to 0 +sink = 0.0 +dt_sink = 0.0 +dq = 0.0 select case(r_conv_scheme) @@ -870,14 +913,18 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps invtau_t_relaxation, t_ref, & klcls) + tg_tmp = conv_dt_tg + tg(:,:,:,previous) qg_tmp = conv_dt_qg + grid_tracers(:,:,:,previous,nsphum) -! note the delta's are returned rather than the time derivatives + + ! note the delta's are returned rather than the time derivatives conv_dt_tg = conv_dt_tg/delta_t conv_dt_qg = conv_dt_qg/delta_t depth_change_conv = rain/dens_h2o rain = rain/delta_t + + ! assign value of precip precip = rain if(id_conv_dt_qg > 0) used = send_data(id_conv_dt_qg, conv_dt_qg, Time) @@ -967,6 +1014,10 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps end select +where (conv_dt_qg < 0.0) + sink = sink + conv_dt_qg +end where + ! Add the T and q tendencies due to convection to the timestep dt_tg = dt_tg + conv_dt_tg dt_tracers(:,:,:,nsphum) = dt_tracers(:,:,:,nsphum) + conv_dt_qg @@ -989,17 +1040,26 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps depth_change_cond = rain/dens_h2o rain = rain/delta_t snow = snow/delta_t + ! update precip precip = precip + rain + snow + + where (cond_dt_qg < 0.0) + sink = sink + cond_dt_qg + end where + + ! Update Tracers and temperature dt_tg = dt_tg + cond_dt_tg dt_tracers(:,:,:,nsphum) = dt_tracers(:,:,:,nsphum) + cond_dt_qg + + if(id_cond_dt_qg > 0) used = send_data(id_cond_dt_qg, cond_dt_qg, Time) if(id_cond_dt_tg > 0) used = send_data(id_cond_dt_tg, cond_dt_tg, Time) if(id_cond_rain > 0) used = send_data(id_cond_rain, rain, Time) if(id_precip > 0) used = send_data(id_precip, precip, Time) - endif +!--------------------------------------------------------------------------------------- ! Call the simple cloud scheme in line with SPOOKIE-2 requirements ! Using start of time step variables @@ -1288,6 +1348,7 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps non_diff_dt_vg = dt_vg non_diff_dt_tg = dt_tg non_diff_dt_qg = dt_tracers(:,:,:,nsphum) + non_diff_dt_age = dt_tracers(:,:,:,2) call gcm_vert_diff_down (1, 1, & delta_t, ug(:,:,:,previous), & @@ -1329,10 +1390,19 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps call gcm_vert_diff_up (1, 1, delta_t, Tri_surf, dt_tg(:,:,:), dt_tracers(:,:,:,nsphum), dt_tracers(:,:,:,:)) + dq =( flux_q * Tri_surf%dtmass )/delta_t + + where (dq < 0.0) + dt_sink = dq + endwhere + + sink(:,:,num_levels) = sink(:,:,num_levels) + dt_sink + if(id_diff_dt_ug > 0) used = send_data(id_diff_dt_ug, dt_ug - non_diff_dt_ug, Time) if(id_diff_dt_vg > 0) used = send_data(id_diff_dt_vg, dt_vg - non_diff_dt_vg, Time) if(id_diff_dt_tg > 0) used = send_data(id_diff_dt_tg, dt_tg - non_diff_dt_tg, Time) if(id_diff_dt_qg > 0) used = send_data(id_diff_dt_qg, dt_tracers(:,:,:,nsphum) - non_diff_dt_qg, Time) + if(id_dt_tracer_diff > 0) used = send_data(id_dt_tracer_diff, dt_tracers(:,:,:,2) - non_diff_dt_age, Time) endif ! if(turb) then @@ -1373,7 +1443,7 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps bucket_depth(:,:,future ) = bucket_depth(:,:,previous) + dt_bucket bucket_depth(:,:,current) = bucket_depth(:,:,current) + robert_bucket * bucket_depth(:,:,future) * raw_bucket endif - + bucket_depth(:,:,future) = bucket_depth(:,:,future) + robert_bucket * (filt(:,:) + bucket_depth(:,:, future)) & * (raw_bucket - 1.0) @@ -1390,7 +1460,15 @@ subroutine idealized_moist_phys(Time, p_half, p_full, z_half, z_full, ug, vg, ps if(id_bucket_depth_lh > 0) used = send_data(id_bucket_depth_lh, depth_change_lh(:,:), Time) endif -! end Add bucket section + + ! Calculate Age eq. RHS + if(do_wv_age) & + call get_age_moments(nsphum,nsphum_age,previous,grid_tracers,sink,dt_tracers) + + if(id_sink > 0) used = send_data(id_sink, sink, Time) + ! Save the first moment tendency + if(id_dt_tracer > 0) used = send_data(id_dt_tracer, dt_tracers(:,:,:,2), Time) + if(id_dt_q > 0) used = send_data(id_dt_q, dt_tracers(:,:,:,nsphum), Time) end subroutine idealized_moist_phys !================================================================================================================================= @@ -1410,11 +1488,11 @@ subroutine idealized_moist_phys_end if(do_damping) call damping_driver_end #ifdef SOC_NO_COMPILE - !No need to end socrates #else if(do_socrates_radiation) call run_socrates_end #endif + end subroutine idealized_moist_phys_end !================================================================================================================================= diff --git a/src/atmos_spectral/driver/solo/mixed_layer.F90 b/src/atmos_spectral/driver/solo/mixed_layer.F90 index 051d985fe..23230a42f 100644 --- a/src/atmos_spectral/driver/solo/mixed_layer.F90 +++ b/src/atmos_spectral/driver/solo/mixed_layer.F90 @@ -100,11 +100,15 @@ module mixed_layer_mod np_cap_factor = 1., & !mj albedo_exp = 2., & !mj albedo_cntr = 45., & !mj + albedo_cntr_lon = 45., & !mj + albedo_cntr_lat = 45., & !mj albedo_wdth = 10., & !mj + albedo_wdth_lat = 10., & !mj + albedo_wdth_lon = 10., & !mj higher_albedo = 0.10, & !mj lat_glacier = 60., & !mj land_h_capacity_prefactor = 1.0 !s where(land) heat_capcity = land_h_capacity_prefactor * depth * rho_cp - +integer :: nshift !s Surface albedo options real :: land_albedo_prefactor = 1.0 !s where(land) albedo = land_albedo_prefactor * albedo_value @@ -142,7 +146,7 @@ module mixed_layer_mod trop_cap_limit, heat_cap_limit, np_cap_factor, & !mj do_qflux,do_warmpool, & !mj albedo_choice,higher_albedo,albedo_exp, & !mj - albedo_cntr,albedo_wdth,lat_glacier, & !mj + albedo_cntr,albedo_cntr_lat,albedo_cntr_lon,albedo_wdth,albedo_wdth_lat,albedo_wdth_lon,lat_glacier, & !mj do_read_sst,do_sc_sst,sst_file, & !mj land_option,slandlon,slandlat, & !mj elandlon,elandlat, & !mj @@ -161,12 +165,13 @@ module mixed_layer_mod logical :: module_is_initialized =.false. logical :: used -integer :: iter, nhum +integer :: iter, nhum, surface_p_level integer, dimension(4) :: axes integer :: & id_t_surf, & ! surface temperature id_flux_lhe, & ! latent heat flux at surface id_flux_oceanq, & ! oceanic Q flux + id_corrected_flux, & ! Corrected flux at surface (avg to 0) id_flux_t, & ! sensible heat flux at surface id_heat_cap, & ! heat capacity id_albedo, & ! mj albedo @@ -179,13 +184,14 @@ module mixed_layer_mod rad_lat_2d, & ! latitude in radians flux_lhe_anom, flux_q_total -real, allocatable, dimension(:) :: deg_lat, deg_lon +real, allocatable, dimension(:) :: deg_lat, deg_lon, deg_lon_shift real, allocatable, dimension(:,:) :: & gamma_t, & ! Used to calculate the implicit gamma_q, & ! correction to the diffusion in fn_t, & ! the lowest layer fn_q, & ! + evap_inc, & ! en_t, & ! en_q, & ! alpha_t, & ! @@ -269,12 +275,14 @@ subroutine mixed_layer_init(is, ie, js, je, num_levels, t_surf, bucket_depth, ax allocate(flux_q_total (is:ie, js:je)) allocate(deg_lat (js:je)) allocate(deg_lon (is:ie)) +allocate(deg_lon_shift (is:ie)) allocate(gamma_t (is:ie, js:je)) allocate(gamma_q (is:ie, js:je)) allocate(en_t (is:ie, js:je)) allocate(en_q (is:ie, js:je)) allocate(fn_t (is:ie, js:je)) allocate(fn_q (is:ie, js:je)) +allocate(evap_inc (is:ie, js:je)) allocate(alpha_t (is:ie, js:je)) allocate(alpha_q (is:ie, js:je)) allocate(alpha_lw (is:ie, js:je)) @@ -364,10 +372,13 @@ subroutine mixed_layer_init(is, ie, js, je, num_levels, t_surf, bucket_depth, ax axes(1:2), Time, 'latent heat flux up at surface','watts/m2') id_flux_oceanq = register_diag_field(mod_name, 'flux_oceanq', & axes(1:2), Time, 'oceanic Q-flux','watts/m2') +id_corrected_flux = register_diag_field(mod_name, 'corr_flux', & + axes(1:2), Time, 'corrected flix at surface','watts/m2') id_heat_cap = register_static_field(mod_name, 'ml_heat_cap', & axes(1:2), 'mixed layer heat capacity','joules/m^2/deg C') id_delta_t_surf = register_diag_field(mod_name, 'delta_t_surf', & axes(1:2), Time, 'change in sst','K') + if (update_albedo_from_ice) then id_albedo = register_diag_field(mod_name, 'albedo', & axes(1:2), Time, 'surface albedo', 'none') @@ -478,6 +489,23 @@ subroutine mixed_layer_init(is, ie, js, je, num_levels, t_surf, bucket_depth, ax albedo(:,j) = albedo_value + (higher_albedo-albedo_value)*& 0.5*(1+tanh((lat-albedo_cntr)/albedo_wdth)) enddo + + case (6) ! higher_albedo within the lat and lon limits + nshift = size(t_surf,1)/2 + deg_lon_shift = cshift(deg_lon, nshift) - 180.0 + do j = 1, size(t_surf,2) + do i = 1, size(t_surf,1) + lat = deg_lat(js+j-1) + lon = deg_lon_shift(is+i-1) + if (lat > albedo_cntr_lat - albedo_wdth_lat .and. lat < albedo_cntr_lat + albedo_wdth_lat) then + if (lon > albedo_cntr_lon - albedo_wdth_lon .and. lon < albedo_cntr_lon + albedo_wdth_lon) then + if (land(i,j)) then + albedo(i,j) = higher_albedo + endif + endif + endif + enddo + enddo end select albedo_initial=albedo @@ -743,8 +771,10 @@ subroutine mixed_layer ( & ! Finally calculate the increments for the lowest atmospheric layer ! Tri_surf%delta_t = fn_t + en_t * delta_t_surf -if (evaporation) Tri_surf%delta_tr(:,:,nhum) = fn_q + en_q * delta_t_surf - +if (evaporation) then + evap_inc = fn_q + en_q * delta_t_surf + Tri_surf%delta_tr(:,:,nhum) = evap_inc +endif ! ! Note: ! When using an implicit step there is not a clearly defined flux for a given timestep @@ -753,6 +783,7 @@ subroutine mixed_layer ( & if(id_flux_t > 0) used = send_data(id_flux_t, flux_t, Time_next) if(id_flux_lhe > 0) used = send_data(id_flux_lhe, HLV * flux_q_total, Time_next) if(id_flux_oceanq > 0) used = send_data(id_flux_oceanq, ocean_qflux, Time_next) +if(id_corrected_flux > 0) used = send_data(id_corrected_flux, corrected_flux, Time_next) if(id_delta_t_surf > 0) used = send_data(id_delta_t_surf, delta_t_surf, Time_next) diff --git a/src/atmos_spectral/model/spectral_dynamics.F90 b/src/atmos_spectral/model/spectral_dynamics.F90 index ab2e0b9ae..60a65b4f9 100644 --- a/src/atmos_spectral/model/spectral_dynamics.F90 +++ b/src/atmos_spectral/model/spectral_dynamics.F90 @@ -137,7 +137,7 @@ module spectral_dynamics_mod integer, allocatable, dimension(:) :: tracer_vert_advect_scheme real :: virtual_factor, dt_real -integer :: pe, npes, num_tracers, nhum, t_vert_advect_scheme, uv_vert_advect_scheme, step_number +integer :: pe, npes, num_tracers, nhum,nhum_age, t_vert_advect_scheme, uv_vert_advect_scheme, step_number real :: mean_energy_previous, mean_water_previous, mean_surf_press_previous integer :: ms, me, ns, ne, is, ie, js, je integer :: previous, current, future @@ -233,9 +233,10 @@ subroutine spectral_dynamics_init(Time, Time_step_in, tracer_attributes, dry_mod type(tracer_type), intent(inout), dimension(:) :: tracer_attributes logical, intent(out) :: dry_model_out integer, intent(out) :: nhum_out + logical, optional, intent(in), dimension(:,:) :: ocean_mask -integer :: num_total_wavenumbers, unit, k, seconds, days, ierr, io, ntr, nsphum, nmix_rat +integer :: num_total_wavenumbers, unit, k, seconds, days, ierr, io, ntr, nsphum,nsphum_age, nmix_rat logical :: south_to_north = .true. real :: ref_surf_p_implicit, robert_coeff_tracers @@ -315,7 +316,6 @@ subroutine spectral_dynamics_init(Time, Time_step_in, tracer_attributes, dry_mod call allocate_fields do ntr=1,num_tracers - call get_tracer_names(MODEL_ATMOS, ntr, tname, longname, units) tracer_attributes(ntr)%name = lowercase(tname) @@ -369,7 +369,9 @@ subroutine spectral_dynamics_init(Time, Time_step_in, tracer_attributes, dry_mod enddo + nsphum = get_tracer_index(MODEL_ATMOS, 'sphum') + nmix_rat = get_tracer_index(MODEL_ATMOS, 'mix_rat') if(nsphum == NO_TRACER) then @@ -409,11 +411,8 @@ subroutine spectral_dynamics_init(Time, Time_step_in, tracer_attributes, dry_mod enddo call read_restart_or_do_coldstart(tracer_attributes, ocean_mask) - call press_and_geopot_init(pk, bk, use_virtual_temperature, vert_difference_option) - call spectral_diagnostics_init(Time) - call every_step_diagnostics_init(Time, lon_max, lat_max, num_levels, reference_sea_level_press) if(do_water_correction .and. .not.do_mass_correction) then @@ -560,6 +559,7 @@ subroutine read_restart_or_do_coldstart(tracer_attributes, ocean_mask) call read_data(trim(file), 'psg', psg(:,:, nt), grid_domain, timelevel=nt) do ntr = 1,num_tracers tr_name = trim(tracer_attributes(ntr)%name) + call read_data(trim(file), trim(tr_name), grid_tracers(:,:,:,nt,ntr), grid_domain, timelevel=nt) if(uppercase(trim(tracer_attributes(ntr)%numerical_representation)) == 'SPECTRAL') then call read_data(trim(file), trim(tr_name)//'_real', real_part, spectral_domain, timelevel=nt) @@ -568,8 +568,9 @@ subroutine read_restart_or_do_coldstart(tracer_attributes, ocean_mask) spec_tracers(m,n,k,nt,ntr) = cmplx(real_part(m,n,k),imag_part(m,n,k)) enddo; enddo; enddo endif - enddo ! loop over tracers - enddo ! loop over time levels + enddo + enddo + call read_data(trim(file), 'vorg', vorg, grid_domain) call read_data(trim(file), 'divg', divg, grid_domain) call read_data(trim(file), 'surf_geopotential', surf_geopotential, grid_domain) @@ -1697,7 +1698,7 @@ subroutine spectral_diagnostics_init(Time) id_tr(ntr) = register_diag_field(mod_name, tname, axes_3d_full, Time, longname, units) id_utr(ntr) = register_diag_field(mod_name, trim(tname)//trim('_u'), axes_3d_full, Time, trim(longname)//trim(' x u'), trim(units)//trim(' m/s')) !Add additional diagnostics RG id_vtr(ntr) = register_diag_field(mod_name, trim(tname)//trim('_v'), axes_3d_full, Time, trim(longname)//trim(' x v'), trim(units)//trim(' m/s')) !Add additional diagnostics RG - id_wtr(ntr) = register_diag_field(mod_name, trim(tname)//trim('_w'), axes_3d_full, Time, trim(longname)//trim(' x w'), trim(units)//trim(' m/s')) !Add additional diagnostics RG + id_wtr(ntr) = register_diag_field(mod_name, trim(tname)//trim('P'), axes_3d_full, Time, trim(longname)//trim(' x w'), trim(units)//trim(' m/s')) !Add additional diagnostics RG enddo id_vort_norm = register_diag_field(mod_name, 'vort_norm', Time, 'vorticity norm', '1/(m*sec)') diff --git a/src/coupler/surface_flux.F90 b/src/coupler/surface_flux.F90 index d38850528..dd5a35915 100644 --- a/src/coupler/surface_flux.F90 +++ b/src/coupler/surface_flux.F90 @@ -693,7 +693,6 @@ subroutine surface_flux_1d ( & dtaudv_atm = -cd_m*rho*(dw_atmdv*v_dif + w_atm) endwhere endif - end subroutine surface_flux_1d ! diff --git a/src/extra/model/isca/field_table b/src/extra/model/isca/field_table index c2d63b9dd..150f59fba 100644 --- a/src/extra/model/isca/field_table +++ b/src/extra/model/isca/field_table @@ -1,10 +1,9 @@ - -"TRACER", "atmos_mod", "sphum" - "longname", "specific humidity" - "units", "kg/kg" - "numerical_representation", "grid" - "hole_filling", "off" - "advect_vert", "finite_volume_parabolic" - "robert_filter", "on" - "profile_type", "fixed", "surface_value=0.0" / - +"TRACER","atmos_mod", "sphum" +"longname", "specific humidity" +"units", "kg/kg" +"numerical_representation", "grid" +"hole_filling", "off" +"advect_vert", "finite_volume_parabolic" +"robert_filter", "on" +"profile_type", "fixed", "surface_value=0.0" +/ \ No newline at end of file diff --git a/src/extra/model/isca/field_table_age_2 b/src/extra/model/isca/field_table_age_2 new file mode 100644 index 000000000..9bef398c5 --- /dev/null +++ b/src/extra/model/isca/field_table_age_2 @@ -0,0 +1,27 @@ +"TRACER","atmos_mod", "sphum" +"longname", "specific humidity" +"units", "kg/kg" +"numerical_representation", "grid" +"hole_filling", "off" +"advect_vert", "finite_volume_parabolic" +"robert_filter", "on" +"profile_type", "fixed", "surface_value=0.0" +/ +"TRACER","atmos_mod", "sphum_age_1" +"longname", "sphum times 1-th moment " +"units", "sec (kg/kg)" +"numerical_representation", "grid" +"hole_filling", "off" +"advect_vert", "finite_volume_parabolic" +"robert_filter", "on" +"profile_type", "fixed", "surface_value=0.0" +/ +"TRACER","atmos_mod", "sphum_age_2" +"longname", "sphum times 2-th moment " +"units", "sec (kg/kg)" +"numerical_representation", "grid" +"hole_filling", "off" +"advect_vert", "finite_volume_parabolic" +"robert_filter", "on" +"profile_type", "fixed", "surface_value=0.0" +/ diff --git a/src/extra/model/isca/path_names b/src/extra/model/isca/path_names index 4b08c4edb..e92cee4d6 100644 --- a/src/extra/model/isca/path_names +++ b/src/extra/model/isca/path_names @@ -110,6 +110,7 @@ atmos_shared/vert_advection/vert_advection.F90 atmos_solo/atmos_model.F90 atmos_spectral/driver/solo/atmosphere.F90 atmos_spectral/driver/solo/idealized_moist_phys.F90 +atmos_spectral/driver/solo/age_moments.F90 atmos_spectral/driver/solo/mixed_layer.F90 atmos_spectral/init/ic_from_external_file.F90 atmos_spectral/init/jablonowski_2006.F90 diff --git a/src/extra/python/isca/__init__.py b/src/extra/python/isca/__init__.py index 83600dfc5..1cf9fb867 100644 --- a/src/extra/python/isca/__init__.py +++ b/src/extra/python/isca/__init__.py @@ -9,6 +9,7 @@ GFDL_BASE = os.environ['GFDL_BASE'] GFDL_WORK = os.environ['GFDL_WORK'] GFDL_DATA = os.environ['GFDL_DATA'] + except Exception as e: log.error('Environment variables GFDL_BASE, GFDL_WORK, GFDL_DATA must be set') raise ValueError('Environment variables GFDL_BASE, GFDL_WORK, GFDL_DATA must be set') diff --git a/src/extra/python/isca/experiment.py b/src/extra/python/isca/experiment.py index 9495bd178..79d0e99b1 100755 --- a/src/extra/python/isca/experiment.py +++ b/src/extra/python/isca/experiment.py @@ -58,7 +58,7 @@ class Experiment(Logger, EventEmitter): runfmt = 'run%04d' restartfmt = 'res%04d.tar.gz' - def __init__(self, name, codebase, safe_mode=False, workbase=GFDL_WORK, database=GFDL_DATA): + def __init__(self, name, codebase, safe_mode=False, workbase=GFDL_WORK, database=GFDL_DATA,field_table_name = "field_table"): super(Experiment, self).__init__() self.name = name self.codebase = codebase @@ -78,7 +78,9 @@ def __init__(self, name, codebase, safe_mode=False, workbase=GFDL_WORK, database self.templates = Environment(loader=FileSystemLoader(self.template_dir)) self.diag_table = DiagTable() - self.field_table_file = P(self.codebase.srcdir, 'extra', 'model', self.codebase.name, 'field_table') + + + self.field_table_file = P(self.codebase.srcdir, 'extra', 'model', self.codebase.name, field_table_name ) self.inputfiles = [] self.namelist = Namelist() diff --git a/src/extra/python/isca/templates/mkmf.template.narval.ifort b/src/extra/python/isca/templates/mkmf.template.narval.ifort new file mode 100644 index 000000000..b61da722f --- /dev/null +++ b/src/extra/python/isca/templates/mkmf.template.narval.ifort @@ -0,0 +1,37 @@ +# template for the Intel fortran compiler +# typical use with mkmf +# mkmf -t template.ifc -c"-Duse_libMPI -Duse_netCDF" path_names /usr/local/include + +# RF - this var redirects to the equivalent of /usr/ on narval. +CPPFLAGS = -I/$(EBROOTGENTOO)/include + +# RF - this only works if netcdf-fortran is loaded already +NETCDF_LIBS = `nf-config --fflags --flibs` + +# RF - this is just the default flags from the isca template + +# FFLAGS: +# -fpp: Use the fortran preprocessor +# -stack_temps: Put temporary runtime arrays on the stack, not heap. +# -safe_cray_ptr: Cray pointers don't alias other variables. +# -ftz: Denormal numbers are flushed to zero. +# -assume byterecl: Specifies the units for the OPEN statement as bytes. +# -shared-intel: Load intel libraries dynamically +# -i4: 4 byte integers +# -r8: 8 byte reals +# -g: Generate symbolic debugging info in code +# -O2: Level 2 speed optimisations +# -diag-disable 6843: +# This suppresses the warning: `warning #6843: A dummy argument with an explicit INTENT(OUT) declaration is not given an explicit value.` of which +# there are a lot of instances in the GFDL codebase. + +FFLAGS = $(CPPFLAGS) -fpp -stack_temps -safe_cray_ptr -ftz -assume byterecl -shared-intel -i4 -r8 -g -O3 -diag-disable 6843 -mcmodel large +FC = $(F90) $(NETCDF_LIBS) +LD = $(F90) $(NETCDF_LIBS) + +# RF - this is where we add the flexiblas library +LDFLAGS = -lnetcdff -lnetcdf -lmpi -shared-intel -lflexiblas +CFLAGS = -D__IFC -Wimplicit-function-declaration + +#CC = mpicc +#FFLAGS = $(CPPFLAGS) -fltconsistency -stack_temps -safe_cray_ptr -ftz -shared-intel -assume byterecl -g -O0 -i4 -r8 -check -warn -warn noerrors -debug variable_locations -inline_debug_info -traceback diff --git a/src/extra/python/scripts/copy_netcdf_attrs.py b/src/extra/python/scripts/copy_netcdf_attrs.py index bdc0899c9..370ff0ef3 100644 --- a/src/extra/python/scripts/copy_netcdf_attrs.py +++ b/src/extra/python/scripts/copy_netcdf_attrs.py @@ -3,7 +3,7 @@ import numpy as np import xarray as xr import os -from netcdftime import utime +#from netcdftime import utime from netCDF4 import Dataset, date2num import pdb diff --git a/src/extra/python/scripts/gfdl_grid_files/t85.nc b/src/extra/python/scripts/gfdl_grid_files/t85.nc new file mode 100644 index 000000000..fe919e45f Binary files /dev/null and b/src/extra/python/scripts/gfdl_grid_files/t85.nc differ diff --git a/src/path_names b/src/path_names index 929ebc18c..f53b5cc7f 100644 --- a/src/path_names +++ b/src/path_names @@ -20,6 +20,7 @@ atmos_shared/vert_advection/vert_advection.F90 atmos_solo/atmos_model.F90 atmos_spectral/driver/solo/atmosphere.F90 atmos_spectral/driver/solo/idealized_moist_phys.F90 +atmos_spectral/driver/solo/age_moments.F90 atmos_spectral/driver/solo/mixed_layer.F90 atmos_spectral/init/ic_from_external_file.F90 atmos_spectral/init/jablonowski_2006.F90