source: codes/icosagcm/devel/Python/src/kernels_caldyn_hydro.jin @ 615

Last change on this file since 615 was 615, checked in by dubos, 6 years ago

devel/unstructured : import Python layer from HEAT

File size: 3.2 KB
Line 
1#define THECELL {{ thecell }}
2
3{# ---------------- macro to generate code computing pressure top-down ---------------
4   formula = formula to compute 'gravitational' mass
5   = rhodz (dry) rhodz*theta (boussinesq) rhodz*(1+qv) (moist)         #}
6
7#define BALANCE(formula) {% call(thecell) balance() %} formula {% endcall %}
8{% macro balance() %} {% set formula=caller %}
9SEQUENCE_EXT
10  PROLOGUE(llm)
11    pk(CELL) = ptop + .5*g*{{ formula('CELL') }}
12  END_BLOCK
13  BODY('llm-1,1,-1')
14    pk(CELL) = pk(UP(CELL)) + (.5*g)*({{ formula('CELL') }}+{{ formula('UP(CELL)') }})
15  END_BLOCK
16  IF(caldyn_eta == eta_lag) THEN
17    EPILOGUE(1)
18      ps(HIDX(CELL)) = pk(CELL) + .5*g*{{ formula('CELL') }}
19    END_BLOCK
20  END IF
21END_BLOCK
22{%- endmacro %}
23
24{# ------------ macro to generate code computing geopotential bottom-up --------------
25   var = variable to be stored in pk(CELL)
26   caller() computes gv = g*v where v = specific volume
27   details depend on caldyn_thermo #}
28
29#define GEOPOT(var) {% call geopot(var) %}
30{% macro geopot(var) %} {% set formula=caller %}
31  SEQUENCE_EXT
32    BODY('1,llm')
33      p_ik = pk(CELL)
34      {{ formula() }}
35      pk(CELL) = {{ var }}
36      geopot(UP(CELL)) = geopot(CELL) + gv*rhodz(CELL)
37    END_BLOCK
38  END_BLOCK
39{%- endmacro %}
40
41#define END_GEOPOT {% endcall %}
42
43KERNEL(compute_geopot)
44  SELECT CASE(caldyn_thermo)
45  CASE(thermo_boussinesq)
46    ! use hydrostatic balance with theta*rhodz to find pk (=Lagrange multiplier=pressure)
47    BALANCE( theta(THECELL,1)*rhodz(THECELL) )
48    ! now pk contains the Lagrange multiplier (pressure)
49    ! specific volume 1 = dphi/g/rhodz
50    SEQUENCE_EXT
51      BODY('1,llm')
52        geopot(UP(CELL)) = geopot(CELL) + g*rhodz(CELL)
53      END_BLOCK
54    END_BLOCK
55  CASE(thermo_theta)
56    BALANCE( rhodz(THECELL) )
57    GEOPOT('exner_ik')
58      exner_ik = cpp * (p_ik/preff) ** kappa
59      gv = (g*kappa)*theta(CELL,1)*exner_ik/p_ik
60    END_GEOPOT
61  CASE(thermo_entropy)
62    BALANCE( rhodz(THECELL) )
63    GEOPOT('temp_ik')
64      temp_ik = Treff*exp((theta(CELL,1) + Rd*log(p_ik/preff))/cpp)
65      gv = (g*Rd)*temp_ik/p_ik   ! specific volume v = Rd*T/p
66    END_GEOPOT
67  CASE(thermo_moist)
68    BALANCE( rhodz(THECELL)*(1.+theta(THECELL,2)) )
69    GEOPOT('temp_ik')
70      qv = theta(CELL,2) ! water vaper mixing ratio = mv/md
71      Rmix = Rd+qv*Rv
72      chi = ( theta(CELL,1) + Rmix*log(p_ik/preff) ) / (cpp + qv*cppv) ! log(T/Treff)
73      temp_ik = Treff*exp(chi)
74      ! specific volume v = R*T/p
75      ! R = (Rd + qv.Rv)/(1+qv)
76      gv = g*Rmix*temp_ik/(p_ik*(1+qv))
77    END_GEOPOT
78  END SELECT
79END_BLOCK
80
81KERNEL(caldyn_slow_hydro)
82  FORALL_CELLS_EXT()
83    ON_EDGES
84      uu = .5*(rhodz(CELL1)+rhodz(CELL2))*u(EDGE)
85      hflux(EDGE) = uu*LE_DE
86    END_BLOCK
87  END_BLOCK
88
89  FORALL_CELLS()
90    ON_PRIMAL
91      ke=0.d0
92      FORALL_EDGES
93        ke = ke + LE_DE*u(EDGE)**2
94      END_BLOCK
95      BERNI(CELL)=ke*(.25/AI)
96    END_BLOCK
97  END_BLOCK
98  IF(zero) THEN
99    FORALL_CELLS()
100      ON_EDGES
101        du(EDGE) = SIGN*(berni(CELL1)-berni(CELL2)) ! minus gradient
102      END_BLOCK
103    END_BLOCK
104  ELSE
105    FORALL_CELLS()
106      ON_EDGES
107        du(EDGE) = du(EDGE) + SIGN*(berni(CELL1)-berni(CELL2)) ! minus gradient
108      END_BLOCK
109    END_BLOCK
110  END IF
111
112END_BLOCK
Note: See TracBrowser for help on using the repository browser.