Scheduled Downtime
On Tuesday 24 October 2023 @ 5pm MT the forums will be in read only mode in preparation for the downtime. On Wednesday 25 October 2023 @ 5am MT, this website will be down for maintenance and expected to return online later in the morning.
Normal Operations
The forums are back online with normal operations. If you notice any issues or errors related to the forums, please reach out to help@ucar.edu

adding heating in CAM4 fv dynamical core

Dear Users,

I have used CAM3 for a while now and as part of my work, I added
additional heating sources to the tropics
to test the effects on things like MJO, Indian Monsoon, and El Nino.
I recently have switched to CAM4 running
fv dynamics. I have been running into problems trying to transfer my
technique that I used in CAM3 eul dynamics
to CAM4 fv dynamics.

The method I used in CAM3 is that I changed code in the routine
p_d_coupling in dp_coupling.F90. In this routine,
I added my heating terms to the temperature tendency variable, t2,
in p_d_coupling. It worked well to include the
additional heating here so that the heating would also feed back
into the dynamics.

Now, in CAM4 (using fv), I cant figure out how to do this same
procedure. In the routine p_d_coupling in CAM4
with fv dynamics, there is no tendency term, t2, to add my heating
to. In fact, the same code in CAM3 that says:

t2(lons(i),k,lats(i)) = phys_tend(lchnk)%dTdt (i,k) (CAM3 eul)

now, in CAM4 says:

ptxy (lons(i),lats(i),k) = phys_state(lchnk)%t(i,k) (CAM4 fv)

So, in CAM4 fv, it sets the temperature variable equal to the actual
temperature (phys_STATE%t). In CAM3, it sets
the temperature TENDENCY variable t2 equal to the tendency
(phys_TEND%dTdt). In CAM3, the tendency
t2 (with my added heating terms included) gets passed directly to
the dynamics. I cant seem to do that for CAM4.

So my question lies in the best way to add the heating into CAM4.
CAM4 doesnt pass the tendencies in and out
of p_d_coupling and then in and out of the dynamics routines. It
passes the variable themselves but not the tendency
of these variables. Because of this, is it better to add the heating
somewhere else or is there a way to still do it
in the routine p_d_coupling?

Finally, on a slightly related note, if you compare the calling
sequence in stepon.F90 for both eul and fv dynamics, it seems
as if the one in stepon.F90 for eul calls them in the following order:

d_p_coupling
physpkg
p_d_coupling
dynamics (in the form of subroutine dynpkg)


While in stepon.F90 for fv dynamics, it calls them in the following order:

dynamics (in the form of subroutine dyn_run)
d_p_coupling
physpkg
p_d_coupling

So, does the fv dynamics actually implement the dynamics from the
previous time step at the beginning of the next time step?

I hope you can help me figure all this out. I sure do appreciate any
insight you could send my way. Ive been messing with this for
a while now,

Thank-you,

Cara-Lyn
 

eaton

CSEG and Liaisons
The best place to add heating tendencies is from the physics package. Then you don't need to know the details of how the state is updated for the dycore. That is the responsibility of the p_d_coupling routine which is dycore specific. The Eulerian dycore has tendencies passed to it, while the FV dycore gets an updated state. By adding your heating tendencies as part of the physics package they are applied correctly to either dycore. You might want to add them right at the end of tphysac since those are the final additions to the global physics tendencies before p_d_coupling is called, so that will match what you did for the Eulerian dycore by making the modifications directly in p_d_coupling.

The basic scheme for adding a tendency to the physics is to have a subroutine call which returns the ptend variable with the desired tendencies, and then call physics_update which applies the tendencies to the state, and updates the global tendencies.

The issue of the different calling sequence for the FV dynamics seems to be historical rather than necessary. From a practical standpoint the main effect of this difference is a one timestep offset in the timestamp for output history fields. So for the Eulerian dycore the first timesample written to the history file, labeled nstep=0, only has the adjustments from the tphysbc physics applied to the initial conditions. For the FV dycore the nstep=0 output has a dynamics step in addition to the tphysbc tendencies.
 

eaton

CSEG and Liaisons
To apply a temperature tendency that is read in from a dataset there are
roughly three steps: 1) read the data from the file and store it in arrays
that use the physics data structure; 2) set the tendency terms for dry
static energy in the physics_ptend data structure; and 3) apply the
tendency by invoking the physics_update method.

The best way to implement the above steps is to use the existing CAM
utility code which is used to read and interpolate the CAM boundary
datasets. These utilities are found in the module tracer_data (in the
chemistry/utils/ directory). Also in that directory are several modules
that are specialized for reading the CAM boundary datasets. For example
see prescribed_aero.F90. These modules can be studied for examples of how
the tracer_data module is used.

The tracer_data module makes some assumptions about the variable and
dimension names that are present in the netCDF input file. The easiest way
to create a file that fulfills these assumptions is probably to look at the
CAM boundary dataset for ozone and use it as a template for creating the
file with temperature tendencies.

Here is a very rough outline for setting up a module to read and apply the
temperature tendencies (many details are missing). It is simpler than
the CAM modules because it uses hardcoded information rather than setting
things up to allow namelist control.


Code:
module add_ttend

use shr_kind_mod,  only: r8=>shr_kind_r8
use tracer_data,   only: trfld, trfile, trcdata_init, advance_trcdata
use physics_types, only: physics_state, physics_ptend, physics_ptend_init
use ppgrid,        only: begchunk, endchunk
use physconst,     only: cpair


implicit none
private
save

public :: &
   add_ttend_init, &
   add_ttend_adv,  &
   add_ttend_run

type(trfld), pointer :: fields(:)
type(trfile)         :: file

character(len=256) :: datapath = ' '    ! absolute pathname of directory
                                        ! containing dataset
character(len=256) :: filename = ' '    ! filename of dataset
character(len=256) :: filelist = ' '
character(len=32)  :: datatype = 'SERIAL' ! controls time interpolation
logical            :: rmv_file = .false.
integer            :: cycle_yr = 0
integer            :: fixed_ymd = 0
integer            :: fixed_tod = 0
character(len=32)  :: specifier(1) = ''  ! variable to read from file

contains

subroutine add_ttend_init()

   ! This subroutine should be called from the phys_init subroutine in the 
   ! physpkg module.

    call trcdata_init(specifier, filename, filelist, datapath, fields, file, &
                      rmv_file, cycle_yr, fixed_ymd, fixed_tod, datatype )

end subroutine add_ttend_init

subroutine add_ttend_adv(state)

   ! This subroutine should be called from the advnce subroutine

   type(physics_state), intent(in) :: state(begchunk:endchunk)                 

   call advance_trcdata(fields, file, state)

end subroutine add_ttend_adv

subroutine add_ttend_run(state, ptend)

   ! This subroutine should be called from an appropriate place in tphysbc
   ! or tphysac.  A call to physics_update should follow it to apply the
   ! tendencies set here to the state.

   type(physics_state), intent(in)    :: state       ! State variables
   type(physics_ptend), intent(out)   :: ptend       ! Package tendencies

   lchnk = state%lchnk
   ncol  = state%ncol

   call physics_ptend_init(ptend)                ! Initialize ptend

   ! set flag which indicates that dry static energy tendency will be set
   ptend%name = 'add_ttend'
   ptend%ls   = .TRUE.

   ! set the dry static energy tendency using the temperature tendency data
   ptend%s(:ncol,:) = fields(1)%data(:ncol,:,lchnk) * cpair

end subroutine add_ttend_run

end module add_ttend
 

eaton

CSEG and Liaisons
The tracer_data module does not assume constant spacing on the time axis.
So it would be easy to put a zero signal into the dataset with time
coordinates at the start and end of the period where you want the zero
signal, and then to put daily time samples where you want that variability.
The tracer_data module does linear interpolation in time. The main thing
to recognize is that you need to supply the "date" and "datesec" variables
in addition to the "time" variable. From reading the code it appears that
date and datesec are the variables actually used in the time interpolation.

If the dataset is at a different spatial resolution than the model grid
then interpolation will be done. You can also create the dataset at the
same horizontal and vertical resolution that you plan to use for the
simulations. Just follow the example provided by the ozone dataset as far
as using the same variable names and attributes for the coordinate data.

The tracer_data module is very flexible with respect to the time and
spatial coordinates in the dataset. There are no sizes (dimensions) that
are hardcoded. It will read the coordinate information from the dataset
and do the necessary interpolations to the time/spatial coordinates of the
model.

I agree that the tracer_data module is difficult to understand, and
unfortunately there is no documentation other than the code itself. It's
important to write the data that is read in back out to a history file so
that you can verify the module is doing what you expect.
 

eaton

CSEG and Liaisons
1. The design of the physics parameterization interface is that a
parameterization never updates the state directly, but rather it produces
tendencies which are then applied to the state by calling physics_update.
The physics_update subroutine also accumulates the tendencies due to all
processes in the physics package. At the point in the timestep when
control is transferred back to the dynamical core, either an updated state
or a total tendency can be passed to the dycore. Which is passed depends
on which dycore is being used. The user who is adding a new process to the
physics package does not need to be concerned about this as it is part of
the infrastructure that connects the dynamics and physics packages.

The temperature is not updated directly from a temperature tendency.
Rather the parameterizations must provide a tendency of dry static energy
(units are J/kg/s), and it is the dry static energy component of the state
which is updated. Then the temperature and geopotential are updated
consistently by calling the geopotential_dse subroutine. The dry static
energy and the temperature tendencies are related by the heat capacity of
air.

The tphysbc and tphysac subroutines are essentially drivers that invoke the
various physics "run" procedures, and apply the tendencies produced by
those procedures to the state and accumulated tendencies by calling the
physics_update subroutine. The user can add a tendency at any point in the
physics package by inserting a call to the new run procedure followed by a
call to physics_update.

2. The tracer_data module does linear interpolation in time. It is the
responsibility of the data user to convert the data to the units
of a dry static energy tendency (J/kg/s).

3. The most common problem with reading a global dataset is making sure it
is correctly distributed to the domain decomposition used in the physics
package. The best way to make this check is simply to write the data back
out to the history file.

Checking that the applied tendencies are affecting the temperature field as
expected is probably most easily done by copying the temperature field to
local variables before and after the new tendency is applied, and to use
that to compute a temperature tendency which could also be written to the
output file.

4. Good luck with this.
 
Thank you very much for the explanations again, they were very helpful.

I made all the necessary changes in my heating data file so that it can be added to the heating rate term 's' and do all necessary calls in the phys_init, advance subroutine, and the phys_run2 (after the tphysac routine call). The 'build' script ran without any problem but the 'run' script exited, the 'stderr' file was blank but the 'stdout' mentioned checking the 'cpl.log' files in the '/ptmp' directory where the 'cpl.log' file stopped at the line '(seq_mct_drv) : Initialize atm component'

I have been trying to debug it but am unsuccessful so far, may I kindly ask for some help with it?

Best,
Abheera
 
I mentioned in my previous post that the build script ran fine. It appears that the build script ran 'successfully' on my Terminal, but when I checked up the exited code mailed to me, it mentioned the following,

'./Tools/ccsm_check_lockedfiles || exit -1
source ./Tools/ccsm_getenv || exit -2

if ($BUILD_COMPLETE != "TRUE") then
echo "BUILD_COMPLETE is not TRUE"
echo "Please rebuild the model interactively via"

(... more ...)
------------------------------------------------------------

Exited with exit code 1.'

I checked up the files under the Tools directory but could not figure out what might be wrong.
 
I apologize about the previous two posts, I had written one of the variables in the usr_nl_cam file wrong, thus the run script kept stopping. As the issue is resolved, I have deleted the posts.
 
Hi,
You have shown us how to add heating to CAM's existing temperature tendency. I have been trying to replace the model temp. tendecy entirely with the observed temperature tendency, any suggestion about what a good way might be to do this? Regards,Abheera
 
Dear Eaton, I have a similar question but am not sure if I can try your above method to solve it.. Since this is the first time for me to deal with so much source codes, it will help a lot if you could tell me more technical details... Thanks in advance.I am trying to dealing with the idealized-physics CAM5 using F_IDEAL_PHYS compset in CESM1.2.2. In this configuration, physics is simplified to be a relaxation to an equilibrium temperature trefa(lat, pres), so instead of using CAM physics modules, the model simply called tphysidl.F90 to calculate the tendency of velocity and temperature.Q1: To my research interest, I hope to modify the 'trefa' to be a GCM output one. Can I do it by using your "add_ttend" module to let the model read the input Temperature nc file?About the "add_ttend" module that you suggested, there are several subroutines which have comments like "! This subroutine should be called from the phys_init subroutine in physpkg module..." or something similar to this. Does this mean I need to add a sentence in "physpkg" module to call that subroutine? Will the idealized physics model call "physpkg.f90" to calculate physics? Is that replaced by "tphysidl.f90"? Where and how should I put it? ('use' and 'call' the subroutines in add_ttend module?)I am not sure if I understand your method correctly, so if there is another way to do this, I mean to let model read in T_eq field from nc file, I will try!Q2: It may be a little bit too early to ask this, but I am wondering what if I want to change a variable, say 'trefa', from a two dimensional one (latxpres) to three dimensional (latxpresxlon)? This question is relevant to how CAM defines a variable. For instance, 'trefa' is a local variable, does this mean what I should do is to change the dimension definition just in this file and I will be all set?Thank you again for reading this lengthy staff!Best regards,Wanying 
 
Dear Eaton and Forum members, I found this post as it is related to my question posted under the general discussion (http://bb.cgd.ucar.edu/radiation-option-horizontally-nonuniform-co2-concentrations). I am looking for a way to prescribe an anomalous short wave forcing (lat,lon) at the TOA. My first idea was to change either CO2 conectrations non-uniformly or changing the solar constant non-uniformly. But maybe adding a new variable via the above described method is more feasible? I assume also the physics routine would be the place to do this? Any pointers on how to approach this problem are greatly appreciated. Thank you very muc in advance
 
Top