## 7   Pseudo-Code

To understand the details of the Coupler's functionality, it is useful to have a basic understanding of the computer code that is the Flux Coupler. To that end, pseudo-code 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.F. This should provide a good overview of how the coupler works; a necessary pre-requisite for successful code modification. The actual source code is 99.9% pure Fortran 77.

§7.1  Variable Naming Convention
§7.2  Main Program

### 7.1   Variable Naming Convention

A variable naming convention has been adopted to help organize and identify the literally hundreds of state and flux fields managed by the Flux Coupler. Understanding this naming convention is a prerequisite for understanding the pseudo-code below.

State Variables

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
Flux Fields

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. net shortwave radiation
• Faic = atm/ice flux, computed by atm, e.g. momentum flux between
• Fala = atm/lnd flux, computed by atm, e.g. net shortwave radiation
• Falc = atm/lnd flux, computed by cpl, e.g. momentum flux
• 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. net shortwave radiation
• Fioc = ice/ocn flux, computed by cpl, e.g. momentum flux
• Fioo = ice/ocn flux, computed by ocn, e.g. ice formed within the ocn
• Fioi = ice/ocn flux, computed by ice, e.g. shortwave radiation penetrating the ice
• Flol = lnd/ocn flux, computed by lnd, e.g. river runoff
Complete input fluxes (an "a" prefix denotes a daily average):
• Faxx = all atm model input fluxes: a mapping/merging/summation of: Faod, Faid, Fald, Fall
• Flxx = all lnd model input fluxes: a mapping/merging/summation of: Falc, Fala
• Foxx = all ocn model input fluxes: a mapping/merging/summation of: Faoc, Faoa, Fioi, Fioc, Flol
• aFoxx = a time average of: Foxx
• Fixx = all ice model input fluxes: a mapping/merging/summation of: Faic, Faia, Fioo, Fioc
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

### 7.2   Main Program

Notice that the Flux Coupler code is configured for a particular time coordination scheme. Model time coordination occurs within a nested loop structure. The ocean model communicates with the coupler once per outer loop iteration, while the atmosphere, ice, and land models communicate once per inner loop iteration. Typically the outer loop corresponds to one day, while the inner loop corresponds to several hours or less. While this configuration is hard-coded within the coupler, it's 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 file), requiring a minimal amount of code modifications or new code.

```      PROGRAM main

msg_atm_init  ! exchange spatial & temporal grid info with atm model
msg_ice_init  ! exchange spatial & temporal grid info with ice model
msg_lnd_init  ! exchange spatial & temporal grid info with lnd model
msg_ocn_init  ! exchange spatial & temporal grid info with ocn model

m = ncpl_a/ncpl_o  ! determine number of atm messages per ocn message

call restart ('read' , Sa_a , Faia_a , Fala_a , Faoa_a ,
&                       Sl_l ,
&                       Si_i , Fioi_i ,
&                       So_o , Fioo_o ,aFoxx_o, runoff )

while ( stop_date > current_date ) do

do n=1,ncpl_a

!--- send tavg inputs to ocn, start new tavg summation ---
if ( mod(n-1,m)=0 ) then
msg_ocn_send(aFoxx_o)
tavg-zero   (aFoxx_o)
end if

!--- prepare lnd input & send to lnd model ---
call map_a2l (  Sa_a ,  Sa_l )
call map_a2l (Fala_a ,Fala_l )
call msg_lnd_send (Fala_l , Sa_l   )

!--- deal with atm/ice fluxes (computed by cpl)  ---
call map_a2i (Sa_a ,  Sa_i )
call flux_ai (Sa_i  ,  Si_i ,Faic_i )
call map_i2a (Faic_i ,Faic_a )
call map_a2i (Faia_a ,Faia_i )

!--- deal with atm/ocn fluxes (computed by cpl) ---
call map_a2o (  Sa_a ,  Sa_o )
call flux_ao (  Sa_o ,  So_o ,Faoc_o )
call map_o2a (Faoc_o ,Faoc_a )
call map_a2o (Faoa_a ,Faoa_o )

!--- deal with atm/lnd fluxes (computed by lnd) ---
call msg_lnd_recv (Sl_l , Fall_l , runoff)
call map_l2a (Fall_l ,Fall_a )
call map_l2a (Sl_l   ,Sl_a )

!--- merge atm inputs & send to atm model ---
call mrg_atm (Faic_a ,Fall_a ,Faoc_a ,Faxx_a)
call mrg_atm (  Si_a ,  Sl_a ,  So_a ,  Ss_a)
call msg_atm_send (Faxx_a ,  Ss_a )

!--- adjust ice/ocn E~P balance over open ocn ---
if (flx_epbal.ne.0) call flux_epbal()

!--- deal with ice/ocn fluxes ---
call map_i2o (Fioi_i ,Fioi_o )
call map_o2i (Fioo_o ,Fioo_i )
call map_o2i (  So_o ,  So_i )
call flux_io (  Si_i ,  So_i ,Fioo_i ,Fioc_i )
call map_i2o (Fioc_i ,Fioc_o )

!--- merge ice inputs, send to ice ---
call mrg_ice ( Faia_i , Faic_i , Fioo_i , Fioc_i, Faoa_o , Faoc_o , Fixx_i)
call msg_ice_send ( Fixx_i )

!--- merge *instantaneous* ocn inputs ---
call mrg_ocn ( Faoa_o , Faoc_o , Fioi_o , Fioc_o, Foxx_o)

!--- make a cpl history file, do diagnostics ---
call history ()
call diagnos ()

!--- form tavg partial sum of ocn inputs ---
call tavg-sum(Foxx_o,aFoxx_o)

call msg_ice_recv (Si_i ,Fioi_i )
call msg_atm_recv (Sa_a ,Faia_a ,Fala_a ,Faoa_a)

if ( mod(n,m).eq.0 ) then
call msg_ocn_recv (So_o , Fioo_o)

!--- form tavg of ocn inputs ---
call tavg-avg(aFoxx_o,m)
end if

!--- cpl, atm, ice, lnd have advanced part of one day ---
sec = sec + 86400/ncpl_a
call control()     ! reset stop, rest, hist control flags
END DO

!--- cpl & component models have advanced one day ---
eday = eday + 1  ! increment number of elapsed days
sec  = 0
call tcheck()    ! verify time coordination
call control()   ! reset stop, rest, hist control flags

!--- make a cpl restart file ---
call restart ('write'  , Sa_a , Faia_a , Fala_a , Faoa_a ,
&                            Sl_l ,
&                            Si_i , Fioi_i ,
&                            So_o , Fioo_o ,aFoxx_o, runoff )

END DO
999 CONTINUE

!--- send final msg to models & disconnect from msg-passing ---
call msg_atmf ()
call msg_icef ()
call msg_ocnf ()
call msg_lndf ()
call msg_cpld ()

STOP - END OF PROGRAM
```

Fri 07 Aug 1998, 12:00:00