---
# System prepended metadata

title: '[Green line] metric fields from mo_vertical_grid.f90'
tags: [cycle22]

---

# [Greenline] Port metric fields

<!-- Add the tag for the current cycle number in the top bar -->

- Shaped by: Magdalena
- Appetite (FTEs, weeks):
- Developers: <!-- Filled in at the betting table unless someone is specifically required here -->

## Problem
<!-- The raw idea, a use case, or something we’ve seen that motivates us to work on this -->
In order to run the greenline ICON components independently of a Fortran ICON run we need to port the calculation of the precomputed vertical fields used in `Diffusion` and `SolveNonHydro`.

Those fields are precomputed in the module `mo_solve_nonhydro.f90`. Some have already been ported in the cycle 19. The goal fo this project is to port the remaining ones that are easily portable.



## Appetite
<!-- Explain how much time we want to spend and how that constrains the solution -->
Full cycle.

## Solution
<!-- The core elements we came up with, presented in a form that’s easy for people to immediately understand -->
Priority in this project are the fields used in `Diffusion` such that this granule becomes then indipendent of serialized data. 
The remaining fields for this goal are: 


### metric fields for diffusion: DiffusionMetrics
| Field             | status/ | deps                                                                          | description                                                                             |
|:----------------- | ------ | ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| mask_hdiff        |  Nikki      | done - metrics: z_mc , ddxn_z_full ) (through z_maxslp, z_maxhgtd) p_int: c_bln_avg) | computed int `prepare_zdiffu` index lists for truly horizontal diffusion (steep slopes) |
| zd_diffcoef_dsl   |   AJ - Nikki   |     done                                                                          |                                                                                         |
| zd_intcoef_dsl    |   AJ - Nikki    |      done                                                                         |                                                                                         |
| zd_vertoffset_dsl |   AJ - Nikki    |         done                                                                      |                                                                                         |
| exner_exfac       |   Nikki    |      done in solved_nonhydro                                                                          |  not used in diffusion but computed in the same place, They are all computed in the same loop in `mo_vertical_grid.f90`.                                                                                      |


























For the `zd_` fields we need the `_dsl` version of the fields, which are the same as the non `_dsl` ones but organized differently in terms of dimensions or masks instead of index lists

### metric fields for dycore: MetricStateNonHydro
| Field                                       | state               | deps                                                                                                                     | description                                                                                     |
|:------------------------------------------- |:------------------- |:------------------------------------------------------------------------------------------------------------------------ |:----------------------------------------------------------------------------------------------- |
| ~~z_ifv~~                                       |  done                   | z_ifv = cells2verts_scalar(z_ifc,cells_aw_verts)                                                                         | [small]                                                                                         |
| wgtfacq_c,wgtfacq_c_dsl                     | Jonas/Nikki - done| metrics%z_ifc                                                                                                            |                                                                                                 |
| wgtfacq_e_dsl                               |Nikki - done  |                                                                                                                          |                                                                                                 |
| wgtfac_e                                    | Nikki -done | wgtfac_c                                                                                                                 | [small]                                                                                         |
| ~~ddxn_z_half_e~~                               |  done                   | z_ddxn_z_half_e = mo_math_gradients.f90:grad_fd_norm (z_ifc, inv_dual_edge_length)                                       | [small]:, which is a simple finite difference gradient stencil                                  |
| ~~ddxn_z_full~~                                 |  done                   | z_ddxn_z_half_e                                                                                                          | [small]                                                                                         | 
| vwind_impl_wgt                              |   Nikki -done                  | config: vwind_offctr,  metrics: z_ddxn_z_half_e,   dual_edge_length                                                      | [medium]                                                                                        |
| vwind_expl_wgt                              |      Nikki-done               | 1.0 - vwind_impl_wgt                                                                                                     | [small],  1 - vwind_impl_wgt                                                                    |
| ~~ddxt_z_full~~                                 |  done                   | z_ddxt_z_half_e  =mo_math_gradients.f90: grad_fd_tang(z_ifv, tangent_orientation, primal_edge_length)                    | [small]  again finite difference gradient                                                       |
| inv_ddqz_z_full                             |    done                 | ddqz_z_full                                                                                                              |                                                                                                 |
| ddqz_z_full_e                               |    AJ - done                | cells2edges(ddqz_z_full, c_lin_e):                                                                                       | [medium] has some special lateral boundary handling otherwise does c_line_e * ddqz_z_full(C2E)) |
| exner_exfac                                 |      Nikki-done               | config: exner_expol, metrics: ddxn_z_full, z_ifc (through z_maxslp, z_maxhgtd)                                           |                                                                                                 |
| d2dexdz2_fac1_mc                            |      Nikki-done               | metrics: theta_ref_mc, inv_ddqz_z_full                                                                                   | [small]                                                                                         |
| d2dexdz2_fac2_mc                            |       Nikki-done              | metrics: theta_ref_mc, z_mc, exner_ref_mc                                                                                | [small]                                                                                         |
| coeff2_dwdz                                 |          Nikki-done           | metrics: ddqz_z_full,z_ifc                                                                                               | [small]   very simple                                                                           |
| coeff1_dwdz                                 |           Nikki-done          | metrics: ddqz_z_full,z_ifc                                                                                               | [small]   very simple                                                                           |
| zdiff_gradp_dsl                             |     Nikki - done               | metrics: z_me, z_mc                                                                                                      | [medium] computation simple but, conditions might be a bit complicated                          |
| scalfac_dd3d                                |         Nikki-done            | vct_a,  config: divdamp_type, divdamp_trans_start, divdamp_trans_end                                                     | [medium]                                                                                        |
| kstart_dd3d                                 |       Nikki-done              | scalfac_dd3d                                                                                                             | [small] scalar on patch                                                                         |
| hmask_dd3d                                  |     Nikki - done                | refin_ctrl, grf_nudgezone_width,                                                                                         | [large]  requires understanding the refin_ctrl thing , this is actually a boolean mask...       |
| rayleigh_w                                  |    Nikki-done                 | vct_a, config: rayleigh_coeff , damp_height                                                                              | [small]                                                                                         |
| coeff_gradekin                              |   Nikki - done                 | t_patch: edge_cell_length,inv_dual_edge_length                                                                           | [small]                                                                                         | 
| pg_edgeidx_dsl                              |     Nikki - done               | metrics: z_ifc , z_me = cells2edges_scalar(z_mc)                                                                         | [medium] index list -> mask computed together with                                               |
| pg_exdist_dsl                               |  Nikki - done                  | metrics: z_ifc , z_me = cells2edges_scalar(z_mc)                                                                         | [medium] index list -> mask computed together with                                                                                        |
| bdy_halo_c (mask_prog_halo_c_dsl_low_refin in ICON) | Nikki - done- ask Magdalena  (do others first)         | refin_ctl, see below | [medium]   called metrics%mask_prog_halo_c_dsl_low_refin                                        |
| mask_prog_halo_c                            | Nikki - done - ask Magdalena  (do others first)         | refin_ctl, is the inverse of bdy_halo_c in some parts of the horizontal domain (halo region)                                   | [small]     mask from index list                                                                |
#### boundary halo masks

`bdy_halo_c`, `mask_prog_halo_c` are used in solve non hydro in the three stencils computed after the corrector step is finished. Those are the stencil that are there uniquely to save a halo exchange, we should consider to do a halo exchange instead: 
``` 
if self.grid.limited_area:
    compute_theta_and_exner(bdy_halo_c, )
    compute_exner_from_rhotheta()
update_theta_v(mask_prog_halo_c, ...)

```
1) the 2 stencils `compute_theta_and_exner` and `compute_exner_from_rhotheta` are identical except for the `compute_theta_and_exner` taking a mask, if we where to modify the mask used there such that id includes True values for the indices that lie in the horizontal bound used in `compute_exner_from_rhotheta` we can delete the second stencil.

2) the `mask_prog_halo_c` is the inverse of the `mask_prog_halo_c_dsl_low_refin` i*n the halo region* otherwise they are identical.

In the single node case the masks should be false everywhere, anyway.

## Rabbit holes
<!-- Details about the solution worth calling out to avoid problems -->

## No-gos
<!-- Anything specifically excluded from the concept: functionality or use cases we intentionally aren’t covering to fit the ## appetite or make the problem tractable -->

## Progress
<!-- Don't fill during shaping. This area is for collecting TODOs during building. As first task during building add a preliminary list of coarse-grained tasks for the project and refine them with finer-grained items when it makes sense as you work on them. -->

- [x] Task 1 ([PR#xxxx](https://github.com/GridTools/gt4py/pulls))
    - [x] Subtask A
    - [x] Subtask X
- [ ] Task 2
    - [x] Subtask H
    - [ ] Subtask J
- [ ] Discovered Task 3
    - [ ] Subtask L
    - [ ] Subtask S
- [ ] Task 4

