Next: 10 Modifications to the
Up: 2 Source Code Reference
Previous: 8 Major cpl6 Modules
  Contents
Subsections
This section provides guidance to understanding the cpl6 main program
which coordinates the transfer of data between components in CCSM3.
9.1 Variable Naming Conventions
A variable naming convention has been adopted to help organize and identify
the literally hundreds of state and flux fields managed by the Coupler.
Understanding this naming convention will aid understanding the
main code and pseudo-code below.
Model state variables are denoted Sx, where x denotes the corresponding
component model:
- * Sa =
- atm state variables, e.g. atm wind velocity
- * Si =
- ice state variables, e.g. ice temperature
- * Sl =
- lnd state variables, e.g. lnd albedo
- * So =
- ocn state variables, e.g. ocn SST
- * Ss =
- all surface states merged together, e.g. global surface temperature
Next, a suffix _x indicates what model grid the states reside on:
- * Sa_a:
- atm states on atm grid
- * Sa_o:
- atm states on ocn grid
Input flux means fluxes given by the Coupler to a model. Output flux means
fluxes computed within a model and given to the Coupler. All input fluxes
for one model were either computed by the Coupler or were the output flux of
another model. In general, a given flux field between any two component
models may have been computed in one of three places: within either of the
two models or within the Coupler.
One function of the Coupler is to gather, merge, sum, and/or time-average
the various component flux fields from various sources and form a set of
complete input fluxes for each component model. This gathering and merging
process will generally involve mapping flux fields between various model
grids and combining like fields from several grids onto one grid. A
summation might be required, e.g., net heat flux = solar + latent + sensible
+ longwave. Also, for some flux fields the Coupler might be required to form
time-averaged quantities. Thus component fluxes are mapped, merged, summed,
and/or time-averaged by the Coupler in order to form complete input fluxes
for the models.
Flux fields are denoted Fxyz, where xy denotes the two model between which a
quantity is being fluxed, and z denotes the model which computed the flux
(i.e. it is an output flux of model z).
Component fluxes that are gathered, merged, summed, and/or time-averaged to
form the complete input fluxes are:
- * Faia =
- atm/ice flux, computed by atm, e.g. precipitation
- * Faii =
- atm/ice flux, computed by ice, e.g. sensible heat flux
- * Fala =
- atm/lnd flux, computed by atm, e.g. precipitation
- * Fall =
- atm/lnd flux, computed by lnd, e.g. sensible heat flux
- * Faoc =
- atm/ocn flux, computed by cpl, e.g. momentum flux
- * Faoa =
- atm/ocn flux, computed by atm, e.g. precipitation
- * Fioo =
- ice/ocn flux, computed by ocn, e.g. ice formed within the ocn
- * Fioi =
- ice/ocn flux, computed by ice, e.g. penetrating shortwave radiation
- * Flol =
- lnd/ocn flux, computed by lnd, e.g. river runoff
Complete input fluxes (an "a" prefix denotes a daily average):
- * Faxx =
- all atm input fluxes: a map/merge/sum of: Faoc, Faii, Fall
- * Flxx =
- all lnd input fluxes: a map/merge/sum of: Fala
- * Foxx =
- all ocn input fluxes: a map/merge/sum of: Faoc, Faoa, Fioi, Flol
- * aFoxx =
- a time average of: Foxx
- * Fixx =
- all ice input fluxes: a map/merge/sum of: Faia, Fioo
Finally, just like the state variables above, a suffix _x indicates what
model grid the fluxes reside on:
- * Faoa_a:
- atm/ocn fluxes, computed by the atm, on the atm grid
- * Faoa_o:
- atm/ocn fluxes, computed by the atm, on the ocn grid
Mapping between domains is implemented by matrix multiplies. Generally there
are different maps for state fields vs. flux fields, as state fields maps are
generally smoother (e.g. bilinear) whereas flux field maps must be conservative
(e.g.. area averaging, aka Riemann sum integrals). In the case of mapping between
identical domains, the map would be the identity map. The necessary mapping
matrices are:
- * map_Fa2i:
- map for fluxes, atm -> ice
- * map_Sa2i:
- map for states, atm -> ice
- * map_Fa2l:
- map for fluxes, atm -> lnd
- * map_Sa2l:
- map for states, atm -> lnd
- * map_Fa2o:
- map for fluxes, atm -> ocn
- * map_Sa2o:
- map for states, atm -> ocn
- * map_Fi2a:
- map for fluxes, ice -> atm
- * map_Si2a:
- map for states, ice -> atm
etc.
The Coupler declares several instances of the BUNDLE and CONTRACT
datatypes and they also follow a naming convention. Bundles have names similar to the map's
but with an extra postfix to identify which grid the data is on. For example:
- * bun_Sa2c_a:
- State data from the atmosphere on the atmosphere grid.
- * bun_Sa2c_o:
- State data from the atmosphere on the ocean grid.
- * bun_Fa2c_a:
- Flux data from the atmosphere on the atmosphere grid.
- * bun_Fa2c_o:
- Flux data from the atmosphere on the ocean grid.
The bun_Sa2c_o bundle contains the bun_Sa2c_a data after it has been mapped
(interpolated) onto the ocean grid.
The names of Contracts also contain a direction but, since the BUNDLE in the
CONTRACT contains both State and Flux data, an ``X'' is used in the name.
- * con_Xa2c:
- The atmosphere-to-coupler CONTRACT.
- * con_Xc2a:
- The coupler-to-atmosphere CONTRACT.
- * con_Xi2c:
- The ice-to-coupler CONTRACT.
- * con_Xc2i:
- The coupler-to-ice CONTRACT.
9.2 Scientific Assumptions in main
The code of the cpl6 main fixes many of the assumptions and scientific
requirements of CCSM3. This section describes which assumptions/requirements
have been ``hard-coded'' into CCSM3's coupler. However, because of
the modular structure of the cpl6 code, it is straightforward to
remove most of these assumptions and allow alternate configurations
of CCSM3 components.
The total number of components is fixed at 6 corresponding to the
number of components in CCSM3: the Coupler itself, and
models of the atmosphere, land, river runoff, sea ice and ocean. However the
number of separate executables is limited to 5 because in CCSM3 the land and
river runoff are contained in the same model, CLM.
This assumption is in both main and the cpl_comm_mod module
which contains public data members with parallel programming information
for only 5 components and a method to initialize them.
Since the river model runs on a different grid, the Coupler establishes
a separate contract for the one-way exchange of information from the
river model to the Coupler and the river model is treated as a sixth component.
But in the MPI view of CCSM, the land and river models are on the same
processors and share the same MPI communicator.
9.2.2 Number of Grids
The Coupler main assumes there are only 3 different grids however the
size and type of each grid may change. The atmosphere and land models
are assumed to share the same grid and the ocean and sea ice models
are also assumed to share the same grid (but different from the
atmosphere-land). The river model's grid is the third grid
in the CCSM3 Coupler.
The Coupler code is configured for a particular time coordination scheme.
Model time coordination involves two communication intervals, with the
longer interval being an integer multiple of the shorter interval. The
atmosphere, ice, and land models communicate once per short interval while the
ocean model communicates once per long interval. Also, one day (24 hours) is
an integer multiple of the longer communication interval. Typically the longer
interval is exactly one day, while the shorter interval is several hours or
less. While this configuration is hard-coded within the Coupler, its modular
design facilitates code modifications to implement alternate configurations. A
variety of time coordination schemes can be, and have been, implemented by
rearranging subroutine calls at the highest level (within the main program),
requiring a minimal amount of code modifications or new code.
9.2.4 Data Pathways through the Coupler
The Coupler code allows only certain data pathways between models.
We define a ``pathway'' as the sequence of operations performed on data sent
from a component model to the Coupler on it's way to another model.
An example is shown in Figure 2. Figure 2
shows what happens to the BUNDLE
Figure 2:
The pathway of data from the atmosphere model through the coupler.
Note that not all operations are shown
|
of data from the atmosphere after it enters the coupler. The number of pathway's and the
sequence of events in each is fixed in a given release of the Coupler. Indeed the code in
the integration loop of the Coupler's main consists mostly of calls to cpl6 routines to
route data through these pathway's.
Some pathways are not implemented in the current release of the Coupler. There is no path
directly from the land model to the ocean model (although there is a path from the river model
to the ocean model.) Pathways which do exist have only certain operations. For example in
the path between the ice and the ocean model, there is no mapping because it is assumed
that the ice and ocean models are on the same grid (Section 9.2.2).
To understand the details of the Coupler's functionality, it is useful to have a
basic understanding of the Coupler main's source code. To that end,
pseudo-code for main is shown below. If one wishes to modify the Coupler source code, it
is strongly recommended that one first study this section in conjunction with
studying the source code file, main.F90. This should provide a good overview of
how the Coupler works; a necessary pre-requisite for successful code
modification.
In the pseudocode below, code from the Coupler is in typewriter
font. Comments about the code are in italics and summaries representing sections
of code are in [ALL CAPS].
PROGRAM main
[INITIALIZE TIMERS]
Initialize MPI and get local MPI communicator
call cpl_interface_init(cpl_fields_cplname,local_comm)
Read the Coupler namelist
call cpl_control_readNList()
Get simulation start date
call restart_readDate(cDate)
Initialize the Coupler infobuffers in each Contract
call cpl_infobuf_init(con_Xa2c%infobuf)
[INITIALIZE OTHER INFOBUFFERS]
Initialize receiving Contract with atmosphere
call cpl_interface_contractInit(con_Xa2c,cpl_fields_cplname, &
cpl_fields_atmname,cpl_fields_a2c_fields,bunname="Xa2c_a", &
decomp=cpl_control_decomp_a)
Initialize sending Contract with atmosphere
call cpl_interface_contractInit(con_Xc2a,cpl_fields_cplname, &
cpl_fields_atmname,cpl_fields_c2a_fields,bunname="Xc2a_a", &
decomp=cpl_control_decomp_a)
dom_a = con_Xa2c%domain Make sure domains are identical
con_Xc2a%domain = dom_a
[INITIALIZE CONTRACTS WITH ICE AND OCEAN MODEL]
[INITIALIZE SPECIAL DOMAIN CONTRACT WITH LAND MODEL.
DETERMINE IF COUPLER SHOULD SEND LAND DOMAIN.]
Initialize inter-domain area fractions
call frac_init(map_Fo2a,dom_a,dom_i,dom_l,dom_o)
[IF REQUESTED, DETERMINE LAND DOMAIN AND SEND TO LAND MODEL]
[INITIALIZE CONTRACTS WITH LAND AND RIVER MODEL]
[CHECK THAT LAND AND ATMOSPHERE DOMAINS ARE CONSISTENT]
[CHECK THAT ICE AND OCEAN DOMAINS ARE CONSISTENT]
call data_bundleInit() Initialize Coupler bundles
call data_mapInit() Initialize Coupler maps for interpolation
call history_avbundleInit() Initialize history buffers
[SET VALUES FOR INITIAL INFOBUFFER]
Send infobuffer to atmosphere
call cpl_interface_infobufSend(cpl_fields_atmname,
con_Xc2a%infobuf%ibuf,con_Xc2a%infobuf%rbuf)
[SEND INFOBUFFERS TO OCEAN, ICE, LAND AND RIVER MODELS]
[VERIFY ACCEPTABLE COUPLING INTERVALS.]
[CHECK FOR DEAD COMPONENTS.]
date = shr_date_initCDate(cDate,ncpl_a) Initalize model start date
call cpl_control_init(date) and control flags
call cpl_control_update(date)
[RESET BUNDLE DOMAINS AREAS TO MAP FILES AREAS]
Receive initial condition data from atmosphere
call cpl_interface_contractRecv(cpl_fields_atmname,con_Xa2c)
Multiply received data by normalized area
call cpl_bundle_mult(con_Xa2c%bundle,bun_areafact_a,'comp2cpl', &
bunlist=cpl_fields_a2c_fluxes)
[RECEIVE INITIAL DATA FROM ICE, LAND, RIVER AND OCEAN MODELS]
call restart_read(date) Read restart
[PROCESS (SPLIT INTO BUNDLES AND MAP) INITIAL CONDITION DATA]
[IF REQUESTED, SEND ALBEDO TO ATMOSPHERE AND GET NEW INITIAL DATA]
DO WHILE ( .not. cpl_control_stopNow ) Main integration loop
DO n=0,ncpl_a Loop over number of atmosphere communications per day
Send message to ocean
if(mod(n-1,ncpl_a/ncpl_o) == 0 ) then If time to talk to ocean
if (.not. cpl_control_lagOcn) then
multiply sent data by normalized area
call cpl_bundle_mult(con_Xc2o%bundle,bun_areafact_o, &
'cpl2comp',bunlist=cpl_fields_c2o_fluxes)
Send the data
call cpl_interface_contractSend(cpl_fields_ocnname,con_Xc2o)
multiply sent data by inverse of normalized area
call cpl_bundle_mult(con_Xc2o%bundle,bun_areafact_o, &
'comp2cpl', bunlist=cpl_fields_c2o_fluxes)
endif
call cpl_bundle_zero(bun_Xc2oPSUM_o) zero out the partial sum
endif
if (mod(n-1,ncpl_a/ncpl_l) == 0 ) then
[SEND DATA TO LAND MODEL]
Map atmosphere states (from initial receive or previous step) to ocean grid
call cpl_map_bun(bun_Sa2c_a,bun_Sa2c_o,map_Sa2o,mvector=a2ovector)
Map atmosphere fluxes to ocean grid)
call cpl_map_bun(bun_Fa2c_a,bun_Fa2c_o,map_Fa2o,mvector=a2ovector)
[IF REQUESTED, FORCE BALANCE THE FRESH WATER FLUX]
Correct the a2o vector mapping near north pole
call cpl_map_npfix(bun_Sa2c_a,bun_Sa2c_o,'Sa_u','Sa_v')
[SEND DATA TO ICE MODEL]
Compute net solar flux into ocean.
call flux_solar(bun_Fa2c_o, bun_oalbedo_o, bun_aoflux_o )
call merge_ocn() merge ocean inputs
Form time average of ocean inputs
call cpl_bundle_accum(bun_Xc2oSNAP_o,outbun=bun_Xc2oPSUM_o)
[DO DIAGNOSTICS]
call flux_albo(date,bun_oalbedo_o) Compute ocean albedos. (Sec. 16.3.3)
Compute atmosphere/ocean fluxes. (Sec. 16.2)
call flux_atmOcn(con_Xo2c%bundle,bun_Sa2c_o,cpl_control_dead_ao,
bun_aoflux_o )
if (mod(n-1,ncpl_a/ncpl_i) == 0 ) then
[RECEIVE DATA FROM ICE MODEL]
If requested, add diurnal cycle to ice albedo. (Sec. 16.3.2)
call flux_albi(date,con_Xi2c%bundle)
Split received ice data into states and fluxes
call cpl_bundle_split(con_Xi2c%bundle,bun_Si2c_i,bun_Fi2c_i)
Map ice and ocean states to atmosphere grid
call cpl_map_bun(bun_Si2c_i,bun_Si2c_a,map_So2a, &
bun_frac_i,'ifrac',bun_frac_a,'ifrac',oi2avector)
call cpl_map_bun(bun_So2c_o,bun_So2c_a,map_So2a, &
bun_frac_o,'afrac',bun_frac_a,'ofrac',oi2avector)
[MAP ICE AND OCEAN FLUXES TO ATMOSPHERE GRID]
if (mod(n-1,ncpl_a/ncpl_l) == 0 ) then
[RECEIVE DATA FROM LAND MODEL]
if (mod(n,ncpl_a/ncpl_r) == 0 ) then
[RECEIVE DATA FROM RIVER MODEL]
call merge_atm(fix_So2c_a) Merge atmosphere state and flux fields
if (mod(n-1,ncpl_a/ncpl_a) == 0 ) then
[SEND DATA TO ATMOSPHERE MODEL]
Map river model data to ocean grid
call cpl_map_bun(con_Xr2c%bundle,bun_Xr2c_o,map_Xr2o,mvector=r2ovector)
call history_write(date) Create and/or update history files
call history_avwrite(date)
if (mod(n,ncpl_a/ncpl_o) == 0 ) then
[RECEIVE DATA FROM OCEAN]
if (mod(n-1,ncpl_a/ncpl_a) == 0 ) then
[RECEIVE DATA FROM ATMOSPHERE]
call shr_date_adv1step(date) Advance date and update control flags
call shr_date_getCDate(date,cDate,sec)
call shr_date_getYMD(date,year,month,day,sec)
call cpl_control_update(date)
END DO
call timeCheck(date,.false.,.true. ) Verify time coordination
END DO WHILE End of main integration loop
call history_avwrite(date) Write last history file
Send final message to atmosphere
call cpl_interface_contractSend(cpl_fields_atmname,con_Xc2a)
[SEND FINAL MESSAGE TO ICE, LAND AND OCEAN MODELS]
call cpl_interface_finalize(cpl_fields_cplname) Disconnect from MPI
STOP/END OF PROGRAM
With the pseudocode, the *_field definitions in
cpl_fields_mod.F90, and the BUNDLE initializations in data_mod.F90,
one can determine how the attribute names in a BUNDLE are used to route data
through pathways. Consider the incoming atmosphere bundle shown in
Fig. 2. The BUNDLE in Con_Xa2c%bundle is initialized using the
cpl_fields_a2c_fields string while bun_Sa2c_a is initialized with the
cpl_fields_a2c_states substring and bun_Fa2c_a is initialized with the
cpl_fields_a2c_fluxes substring. The call to cpl_bundle_split copies
the data in Con_Xa2c%bundle into bun_Sa2c_a or bun_Fa2c_a according to
the matching attribute names. Since, by construction, *_fields is the union of
*_states and *_fluxes, the split is exact.
Attribute name matching is also used the move data through the Fa2o mapping call shown in Fig. 2.
This call will automatically map all the fields in
bun_Fa2c_a which have the same names as the fields in the output BUNDLE bun_Fa2c_o.
Since bun_Fa2c_o is also initialized with cpl_fields_a2c_fluxes (in data_mod.F90),
the entire contents of bun_Fa2c_a are mapped to the ocean grid.
Finally, attribute name matching is used to ``gather'' data for passing out to a component model
using cpl_bundle_gather. Note that
this does not mean ``gather'' in the MPI sense of gathering distributed data to a single processor.
It means gathering data from several BUNDLES with the same attribute name into one outgoing
BUNDLE. For example, cpl_fields_a2c_states and cpl_fields_c2i_states both
contain an attribute called ``Sa_u''. Since the same name appears in both the Con_Xa2c%bundle,
bun_Sa2c_o, and Con_Xc2i%bundle, this ensures that the data contained in the ``Sa_u'' slot
in the Con_Xa2c%bundle, the atmosphere's zonal wind field, will be mapped to the ice/ocean
grid with the correct mapping and sent to the ice model.
Next: 10 Modifications to the
Up: 2 Source Code Reference
Previous: 8 Major cpl6 Modules
  Contents
cesm.ucar.edu