---
# System prepended metadata

title: Graupel in GT4Py
tags: [cycle 15, cycle 16]

---

# Graupel in GT4Py

- Shaped by: Anurag
- Appetite: full cycle
- Developers: Chia Rui 
- Support: Niki


## Goals
Port the sedimentation and/or transfer rate calculations while learning GT4Py.

Try to get the structure of the scheme ready in this cycle. Full implementation and verification can be done in the following cycle. 


## Appetite
Entire cycle for Chia Rui. 

## Solution
- [x] Chia Rui has a refactored and verified Fortran version of the scheme that aim to port. Use the implementation by David (of the original code) as the starting point. 
    - [ ] ~~Split the code into 3 blocks: (i) sedimentation (ii) transfer rate calculations, (iii) update the prognostics.~~
    - [x] The sedimentation cannot be extracted from the graupel scheme to become a standalone piece of code because it is partially implicit. The entire scheme has to be put in one scan operator. Give adoptability priority over the performance.

- [ ] Some concerns about code structure, readability, and performance.
    - [ ] Some input or output variables only has (i,j) indices (CellDim) in the Fortran code, but scan_operator along the k axis requires that all variables are either a constant or have KDim. 
    - [ ] Make tuning parameters constants.

          FORTRAN CODE:
          graupel_setup (tune_zceff_min, tune_v0snow, tune_zvz0i, tune_mu_rain, tune_rain_n0_factor, tune_icesedi_exp)
            IF (PRESENT(tune_zceff_min)) THEN
              M_ceff_min = tune_zceff_min
            ELSE
              M_ceff_min = 0.075_wp     ! COSMO default
            ENDIF
          
          PYTHON CODE:
          class GraupelGlobalConstants(FrozenNamespace):
              GrConst_ceff_min = 0.075
              GrConst_v0snow = 20.0
              GrConst_vz0i = 1.25
              GrConst_mu_rain = 0.0 
              GrConst_rain_n0_factor = 1.0
              GrConst_icesedi_exp = 0.33
              
          graupel_const : Final = GraupelGlobalConstants()
          
    - [ ] The function Make_normalized is ignored.

          #ifdef _OPENACC
          ! GPU code can't flush to zero double precision denormals
          ! So to avoid CPU-GPU differences we'll do it manually
          FUNCTION make_normalized(v)
            !$ACC ROUTINE SEQ
            REAL(wp) :: v, make_normalized

            IF (ABS(v) <= 2.225073858507201e-308_wp) THEN
              make_normalized = 0.0_wp
            ELSE
              make_normalized = v
            END IF
          END FUNCTION
          #else
          FUNCTION make_normalized(v)
            REAL(wp) :: v, make_normalized
            make_normalized = v
          END FUNCTION
          #endif
    - [ ] Super long list of type declaration in scan operator.
    - [ ] Recursion depth limit. Users need to manually set the limit in the code.
    - [ ] Long compilation time.

## Next task
- [ ] Prepare a test to ensure this piece of code produce the same result as the Fortran version in the next cycle.


## Rabbit holes 

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