Skip to content
Snippets Groups Projects
zooms.rst 16 KiB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
**************
Embedded zooms
**************

.. todo::



.. contents::
   :local:

Overview
========

.. figure:: _static/VORTEX_anim_sst2.gif
   :width: 200px
   :align: left


AGRIF (Adaptive Grid Refinement In Fortran) is a library that allows the 
seamless space and time refinement over rectangular regions in NEMO.  
Refinement factors can be odd or even (usually lower than 5 to maintain 
stability).  Interaction between grids is "two-way" in the sense that the 
parent grid feeds the child grid open boundaries and the child grid provides 
volume/area weighted averages of prognostic variables once a given number of 
time steps are completed. This page provide guidelines for how to use AGRIF in 
NEMO. For a more technical description of the library itself, please refer to 
AGRIF_.

Compilation
===========

Activating AGRIF requires one to append the cpp key ``key_agrif`` at 
compilation time:

.. code-block:: sh

   ./makenemo [...] add_key 'key_agrif'

Although this is transparent to users, the way the code is processed during 
compilation is different from the standard NEMO case: a preprocessing stage (the so 
called ``conv`` program) translates the actual code such that saved arrays may 
be switched in memory space from one domain to another. 

To avoid compilation issues, it is recommended that you run 
``./makenemo clean`` on your configuration the first time you activate
``key_agrif`` if you have previously compiled the configuration. 

Definition of the grid hierarchy
================================

Setting up the nested grid location
-----------------------------------
An additional text file :file:`AGRIF_FixedGrids.in` is required at run time.
This is where the grid hierarchy is defined. An example of such a file, 
taken from the ``VORTEX`` test case, is given below:

.. code-block:: sh

 1
 22 41 22 41 3 3 3 
 0 

The first line indicates the number of zooms (``1``). The second line contains the 
start and end indices in both directions on the parent grid
(``imin=22 imax=41 jmin=22 jmax=41``) followed by the space and time refinement 
factors (``rx=3 ry=3 rt=3``). Each spatial and refinement factor can be chosen 
independently (hence one can have a spatial refinement of 3 and a temporal 
refinement of 2 for example, even though cfl constraints generally require 
these to be the same). The last line is the number of child grids nested in the 
refined region, i.e. 0 in this particular case. 

The user can find a more complex example in the ``AGRIF_DEMO`` reference 
configuration directory.

How do I retrieve the exact zoom positioning over the parent grid?
--------------------------------------------------------------------
The first/last parent tracer cells inside the zoom (at "T-points" in a C-grid 
context) will be replaced by volume weighted averages of the child grid 
values and are given by the following formulae:

* Along the i-dimension:

``ist  = imin + nbghost_w`` 

``iend = imax + nbghost_w - 1``

* Similarly, in the j-dimension:

``jst  = jmin + nbghost_s`` 

``jend = jmax + nbghost_s - 1``

The above formulae makes use of ``nbghost_w`` and ``nbghost_s``, the number of 
ghost cells along the western/southern boundaries, which depends on the 
boundary type. The locations of the edges of the zoom, as defined by 
``imin, imax, etc...``, are set excluding the parent ghost cells. The figure 
below displays (in the i-dimension) the positioning of two telescoping grids 
in a closed domain.

.. figure:: _static/agrif_grid_position_closed_cropped.png
   :align: left

   ..

Closed domains have ``nghost_w = 1`` and ``nghost_s = 1`` (there are lines/rows 
of masked points on closed domain edges). Global grids will have 
``nghost_w = 0`` and ``nghost_s = 1`` (the western boundary is cyclic, the 
southern boundary over Antarctica is closed). AGRIF grids have, by default, 
``nghost_w = nbghost_s = 4`` (as shown in the figure above). One of these ghost 
points is masked as required in NEMO. This number, which is not a user defined 
parameter, comes from the maximum order of the spatial schemes in the code. A 
4th order scheme requires at least 2 unmasked ghost points per time step. 
Prather advection as used in the sea-ice model requires 3 ghosts points, which 
explains the chosen value. 

.. hint:: 

   It is possible to set a zoom exactly on the edge of a closed parent domain. 
   Just set ``imin = 1`` to set it on the western edge and/or ``imax = Ni0glo - 1`` 
   to set it on the eastern edge. Same convention in the ``j`` dimension.



Dealing with periodic boundaries
--------------------------------
If a parent grid has cyclic east-west boundaries or a North-Fold, it is 
possible to define zooms across the i or j boundaries (as shown in the figure 
below): 

.. figure:: _static/AGRIF_cyclic_bdys.png
   :align: left

   ..


Crossing an east-west boundary requires setting ``imin < 0``, while crossing the 
North-Fold needs ``jmax > Nj0glo``. 

.. hint:: 

   It is possible to have a cyclic east-west zoom (e.g. a circumpolar grid), 
   by setting ``imin = 1`` and ``imax = Ni0glo+1``.

.. note:: 

   Only a T-point pivot (``l_NFold = .T.`` and ``c_NFtype = “T”``) is currently 
   supported by AGRIF if one aims at setting a zoom crossing the North-Fold.


Overlapping grids
-----------------

Rectangular regions must be defined so that they are connected to a single 
parent grid. Let's take as an example the following :file:`AGRIF_FixedGrids.in` in 
the ``VORTEX`` test case: 

.. code-block:: sh

 2
 22 41 22 41 3 3 3
 14 33  8 27 3 3 3 
 0
 0 


.. figure:: _static/VORTEX_anim_sst4.gif
   :width: 200px
   :align: left


This will technically "work" as shown by the animation and the code does not 
complain about such a situation. Nevertheless, this should be avoided because, in the current 
implementation, grids only exchange data with their parent and not between themselves.

Nested zoom size
----------------
From the above formulae, one can get the nested grid size according to:

``Ni0glo = (imax-imin)*rx + nbghost_w + nbghost_e`` 

``Nj0glo = (jmax-jmin)*ry + nbghost_s + nbghost_n`` 

where the number of ghost cells refer to the child grid (i.e. 
``nbghost_w=nbghost_e=nbghost_s=nbghost_n=4`` in the standard case).

Mesh preprocessing
==================

Once the :file:`AGRIF_FixedGrids.in` is ready, one has to create a consistent 
set of meshes for the whole nested system. This step ensures that cell volumes 
agree at the grid interfaces. Volume matching, as well as child bathymetry 
interpolation from an external database is ensured by the ``DOMAINcfg`` tool 
located in ``/tools/DOMAINcfg/``.

Compilation
-----------
To compile the ``DOMAINcfg`` tool for AGRIF zooms, you need to add 
``key_agrif`` (to do so, edit the ``/tools/DOMAINcfg/cpp_DOMAINcfg.fcm`` file). 
Then, compile:

.. code-block:: sh

   ./maketools [...] -n DOMAINcfg


Creating child meshes
---------------------
Copy your :file:`AGRIF_FixedGrids.in` file in your run directory, duplicate 
pairs of :file:`*_namelist_cfg/` :file:`*_namelist_ref` files for each grid 
and edit them with the expected domain sizes. Alternatively, a python script 
can be used to automatically fill child namelists with the expected sizes from 
the :file:`AGRIF_FixedGrids.in` file:

.. code-block:: sh

   ./make_namelist.py namelist_cfg


Specific to the use of AGRIF, two additional namelist options are available for 
setting your child grid bathymetry, e.g. through the ``nn_bathy`` parameter:

.. code-block:: fortran

   nn_bathy    =    1      ! = 0 compute analyticaly
                           ! = 1 read the bathymetry file
                           ! = 2 compute from external bathymetry
                           ! = 3 compute from parent



Setting ``nn_bathy=2`` creates a child bathymetry from an external bathymetry 
database. The database must be stored as a regular (longitude, latitude) array 
with the following information required:

.. code-block:: fortran

   cn_topo = 'GEBCO_2020.nc'
   cn_bath = 'elevation'
   cn_lon = 'lon'
   cn_lat = 'lat'
   rn_scale = -1


``rn_scale=+-1`` is a multiplicative factor for negative (``rn_scale=-1``) or 
positive (``rn_scale=1``) bathymetry values in input file. Interpolation is 
performed using a median average and a "lake-filling" algorithm removes 
any small wet domains not connected to the zoom edges. One can simply use the 
parent bathymetry as the bathymetry source by setting ``nn_bathy=3``. One can 
still read a bathymetry file over the child domain by setting ``nn_bathy=1`` 
as long as it exactly corresponds to the expected domain size and position. 
This can be used to re-run the tool after hand editing the coastline for example.  

.. hint:: 

   At this stage, you can change the vertical grid definition in 
   each zoom (only ``ln_zps`` grid types are fully functional though) which 
   requires setting ``ln_vert_remap=T`` in the ``namagrif`` namelist block. 
   This also requires setting ``ln_dept_mid=T`` in ALL namelists, vertical 
   remapping being only compatible with a mid-cell location of T-points.
 

Then, run the executable (eventually on multiple cores):

.. code-block:: sh

   mpirun -np [...] ./make_domain_cfg.exe 


This creates an updated ``domain_cfg.nc`` root mesh and all the child meshes 
``1_domain_cfg.nc``, ``2_domain_cfg.nc``, etc...

.. hint:: 

   Even with the same vertical grid, a child domain may need fewer vertical 
   levels than ``jpkglo``. Check your ``*_ocean.output`` which gives you the
   maximum number of levels required. Adjust the number of levels 
   (``jpkglo`` only, leaving ``jpkdta`` unchanged) in the namelists, and 
   re-run ``DOMAINcfg`` a second time.

You may take as an example the ``AGRIF_DEMO`` case located in the 
``/tool/DOMAINcfg/cfgs/AGRIF_DEMO`` directory. This particular case 
illustrates a vertical coordinate change for the last zoom level.

Running the multigrid system
============================

Input files
-----------

Each child grid expects to read its own namelist so that different numerical 
choices can be made (these should be stored in the form :file:`1_namelist_cfg`, 
:file:`2_namelist_cfg`, etc... according to their rank in the grid hierarchy). 

Copy the mesh files obtained in the preprocessing step above in your run directory. 
Note that variable names in child namelists should not contain the grid prefixes which 
are added at run time. Hence, reading for example the child mesh ``1_domain_cfg.nc`` requires 
setting in your namelist:

.. code-block:: fortran

   !-----------------------------------------------------------------------
   &namcfg        !   parameters of the configuration                      
   !-----------------------------------------------------------------------
   ln_read_cfg = .true.              !  (=T) read the domain configuration file
      cn_domcfg = "domain_cfg.nc"    ! domain configuration filename
   /

The same applies to interpolation weights, restarts, runoffs files, etc... if any. 
Namelists could be at the end pretty much similar for all grids.

.. note:: 

   The land/sea mask and the vertical grid of the parent grid might have 
   been modified over the nest(s) area(s) by the ``DOMAINcfg`` tool 
   (because of the volume matching). Therefore, make sure that your input files are consistent.

.. note:: 

   To ensure that child time parameters agree with the chosen temporal refinement, 
   ``nn_it000``, ``nn_itend`` and ``rn_Dt`` (e.g. first and last time steps and the time 
   step increment in the namelist) are all overwritten at run time according to 
   the parent values and the time refinement factor ``rt``.

Ouput files
-----------

Outputs are produced as for single grid experiments, thanks to the XIOS_ library. 
Definitions in your ``file_def_nemo-XXX.xml`` file will lead to a set of Netcdf files but 
with the grid prefix. The only change required by the user is the addition of a 
``context_nemo.xml`` file for each grid in ``iodef.xml``:

.. code-block:: fortran

   <!-- ============================================================================================ -->
   <!-- NEMO  CONTEXT add and suppress the components you need                                       -->
   <!-- ============================================================================================ -->

  <context id="nemo" src="./context_nemo.xml"/>       <!--  ROOT       -->e
  <context id="1_nemo" src="./1_context_nemo.xml"/>   <!--  GRD1       -->
  <context id="2_nemo" src="./2_context_nemo.xml"/>   <!--  GRD2       -->
  </simulation>

Then, duplicate ``context_nemo.xml`` files accordingly and edit the id name ``1_nemo``, 
etc... in each of them.

.. hint:: 

   It is possible to output different variables on each grid. Simply copy ``file_def_nemo-XXX.xml`` 
   as ``1_file_def_nemo-XXX.xml`` for example and change the file name in ``1_context_nemo.xml``.


Namelist options specific to AGRIF
----------------------------------

Specific to AGRIF is the following namelist block: 


.. code-block:: fortran

   !-----------------------------------------------------------------------
   &namagrif      !  AGRIF zoom                                            ("key_agrif")
   !-----------------------------------------------------------------------  
   ln_agrif_2way   = .true.  !  activate two way nesting
   ln_init_chfrpar = .false. !  initialize child grids from parent
   ln_vert_remap   = .false. !  use vertical remapping
   ln_spc_dyn      = .false. !  use 0 as special value for dynamics
   ln_chk_bathy    = .true.  !  =T  check the parent bathymetry
   rn_sponge_tra   = 0.002   !  coefficient for tracer   sponge layer []
   rn_sponge_dyn   = 0.002   !  coefficient for dynamics sponge layer []
   rn_trelax_tra   = 0.01    !  inverse of relaxation time (in steps) for tracers []
   rn_trelax_dyn   = 0.01    !  inverse of relaxation time (in steps) for dynamics []
   /
   !-----------------------------------------------------------------------


Sponge/relaxation parameters (``rn_sponge_xxx``/``rn_trelax_xxx``) control the possible noise 
near grid interfaces. These are non-dimensionalized parameters and do not require, in principle, to be 
systematically adjusted to your setup. 


The following figure describes, here in one dimension, the location of the zone 
near a western child boundary and the linear decrease of the sponge/relaxation coefficient. Note that the width of the zone, in number of parent (coarse) grid points, is a parameter defined in the code (``nsponge = 2`` by default). The equation displays the aditionnal terms involved and where the namelist parameters intervene. 

.. figure:: _static/agrif_sponge.png
   :align: left

   ..



A last useful option is ``ln_init_chfrpar=T`` which skips any external 
initialization for the child grid by setting the initial state from its parent 
level.

.. note:: 
   the ``ln_vert_remap`` flag must be activated if different vertical  
   grids are used in the parent and the child grids. 

Unsupported options with AGRIF
==============================

A number of features are not compatible with the ``key_agrif`` defined. In most of 
the cases listed below it simply means that the functionality has not adapted to the 
multigrid paradigm. For example, activating icebergs would ideally require Lagrangian 
parcels being able to transit from one grid to another, which has not been implemented. 
The missing functionalities are grouped in the table below according to their use on the 
root or on the child grid.

Jérôme Chanut's avatar
Jérôme Chanut committed
============================================  =====  ======  ===========
  Option name (and flag)                          Grid        avail. in 
--------------------------------------------  -------------  -----------
Jérôme Chanut's avatar
Jérôme Chanut committed
============================================  =====  ======  ===========
Timing (``ln_timing=T``)                        No
Jérôme Chanut's avatar
Jérôme Chanut committed
Icebergs (``ln_icebergs=T``)                    No
Under ice cavities (``ln_isf=T``)               No     No
Floats (``ln_floats=T``)                        No
Stochastic param. (``ln_sto_XXX=T``)            No
Jérôme Chanut's avatar
Jérôme Chanut committed
Global volume ctl (``nn_fwb=1/2``)              No              main
Open boundaries (``ln_bdy=T``)                 Yes     No
Global heat and sal budgets (``ln_diahsb``)     No
Jérôme Chanut's avatar
Jérôme Chanut committed
============================================  =====  ======  ===========