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