# [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