Ignore:
Timestamp:
05/29/19 20:33:00 (5 years ago)
Author:
jisesh
Message:

devel: moved DYSL into compute_caldyn_solver.F90,compute_theta.F90 and compute_NH_geopot.F90

Location:
codes/icosagcm/devel/Python/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • codes/icosagcm/devel/Python/src/kernels_caldyn_NH.jin

    r876 r878  
    1010{%- endmacro %} 
    1111 
    12 KERNEL(compute_NH_geopot) 
    13   tau2_g=tau*tau/g 
    14   g2=g*g 
    15   gm2 = 1./g2 
    16   vreff = Treff*cpp/preff*kappa 
    17   gamma = 1./(1.-kappa) 
    18      
    19   BARRIER 
    20  
    21   ! compute Phi_star 
    22   SEQUENCE_C1 
    23     BODY('1,llm+1') 
    24       Phi_star_il(CELL) = Phi_il(CELL) + tau*g2*(W_il(CELL)/m_il(CELL)-tau) 
    25     END_BLOCK 
    26   END_BLOCK 
    27  
    28   ! Newton-Raphson iteration : Phi_il contains current guess value 
    29   DO iter=1,2 ! 2 iterations should be enough 
    30     ! Compute pressure, A_ik 
    31     SELECT CASE(caldyn_thermo) 
    32     CASE(thermo_theta) 
    33       {% call() compute_p_and_Aik() %} 
    34         X_ij = (cpp/preff)*kappa*theta(CELL)*rho_ij 
    35         p_ik(CELL) = preff*(X_ij**gamma) 
    36         c2_mik = gamma*p_ik(CELL)/(rho_ij*m_ik(CELL)) ! c^2 = gamma*R*T = gamma*p/rho 
    37       {% endcall %} 
    38     CASE(thermo_entropy) 
    39       {% call() compute_p_and_Aik() %} 
    40         X_ij = log(vreff*rho_ij) + theta(CELL)/cpp 
    41         p_ik(CELL) = preff*exp(X_ij*gamma) 
    42         c2_mik = gamma*p_ik(CELL)/(rho_ij*m_ik(CELL)) ! c^2 = gamma*R*T = gamma*p/rho 
    43       {% endcall %} 
    44     CASE DEFAULT 
    45         PRINT *, 'caldyn_thermo not supported by compute_NH_geopot', caldyn_thermo 
    46         STOP 
    47     END SELECT 
    48      
    49     ! NB : A(1), A(llm), R(1), R(llm+1) = 0 => x(l)=0 at l=1,llm+1 => flat, rigid top and bottom 
    50     ! Solve -A(l-1)x(l-1) + B(l)x(l) - A(l)x(l+1) = R(l) using Thomas algorithm 
    51  
    52     SEQUENCE_C1 
    53       ! Compute residual R_il and B_il 
    54       PROLOGUE(1) 
    55         ! bottom interface l=1 
    56         ml_g2 = gm2*m_il(CELL)  
    57         B_il(CELL) = A_ik(CELL) + ml_g2 + tau2_g*rho_bot 
    58         R_il(CELL) = ml_g2*( Phi_il(CELL)-Phi_star_il(CELL))  & 
    59                   + tau2_g*( p_ik(CELL)-pbot+rho_bot*(Phi_il(CELL)-PHI_BOT(HIDX(CELL))) ) 
    60       END_BLOCK 
    61       BODY('2,llm') 
    62         ! inner interfaces 
    63         ml_g2 = gm2*m_il(CELL)  
    64         B_il(CELL) = A_ik(CELL)+A_ik(DOWN(CELL)) + ml_g2 
    65         R_il(CELL) = ml_g2*( Phi_il(CELL)-Phi_star_il(CELL))  & 
    66                   + tau2_g*(p_ik(CELL)-p_ik(DOWN(CELL))) 
    67         ! consistency check : if Wil=0 and initial state is in hydrostatic balance 
    68         ! then Phi_star_il(CELL) = Phi_il(CELL) - tau^2*g^2 
    69         ! and residual = tau^2*(ml+(1/g)dl_pi)=0 
    70       END_BLOCK 
    71       EPILOGUE('llm+1') 
    72         ! top interface l=llm+1 
    73         ml_g2 = gm2*m_il(CELL)  
    74         B_il(CELL) = A_ik(DOWN(CELL)) + ml_g2 
    75         R_il(CELL) = ml_g2*( Phi_il(CELL)-Phi_star_il(CELL))  & 
    76                   + tau2_g*( ptop-p_ik(DOWN(CELL)) ) 
    77       END_BLOCK 
    78       ! 
    79       ! Forward sweep : 
    80       ! C(0)=0, C(l) = -A(l) / (B(l)+A(l-1)C(l-1)),  
    81       ! D(0)=0, D(l) = (R(l)+A(l-1)D(l-1)) / (B(l)+A(l-1)C(l-1)) 
    82       PROLOGUE(1) 
    83         X_ij = 1./B_il(CELL) 
    84         C_ik(CELL) = -A_ik(CELL) * X_ij  
    85         D_il(CELL) =  R_il(CELL) * X_ij 
    86       END_BLOCK 
    87       BODY('2,llm') 
    88         X_ij = 1./( B_il(CELL) + A_ik(DOWN(CELL))*C_ik(DOWN(CELL)) ) 
    89         C_ik(CELL) = -A_ik(CELL) * X_ij  
    90         D_il(CELL) =  (R_il(CELL)+A_ik(DOWN(CELL))*D_il(DOWN(CELL))) * X_ij 
    91       END_BLOCK 
    92       EPILOGUE('llm+1') 
    93         X_ij = 1./( B_il(CELL) + A_ik(DOWN(CELL))*C_ik(DOWN(CELL)) ) 
    94         D_il(CELL) =  (R_il(CELL)+A_ik(DOWN(CELL))*D_il(DOWN(CELL))) * X_ij 
    95         ! Back substitution : 
    96         ! x(i) = D(i)-C(i)x(i+1), x(llm+1)=0 
    97         ! + Newton-Raphson update 
    98         ! top interface l=llm+1 
    99         x_il(CELL) = D_il(CELL) 
    100         Phi_il(CELL) = Phi_il(CELL) - x_il(CELL) 
    101       END_BLOCK 
    102       BODY('llm,1,-1') 
    103         ! Back substitution at lower interfaces 
    104         x_il(CELL) = D_il(CELL) - C_ik(CELL)*x_il(UP(CELL)) 
    105         Phi_il(CELL) = Phi_il(CELL) - x_il(CELL) 
    106       END_BLOCK 
    107     END_BLOCK 
    108  
    109     IF(debug_hevi_solver) THEN 
    110        PRINT *, '[hevi_solver] A,B', iter, MAXVAL(ABS(A_ik)),MAXVAL(ABS(B_il)) 
    111        PRINT *, '[hevi_solver] C,D', iter, MAXVAL(ABS(C_ik)),MAXVAL(ABS(D_il)) 
    112        DO l=1,llm+1 
    113           WRITE(*,'(A,I2.1,I3.2,E9.2)') '[hevi_solver] x_il', iter,l, MAXVAL(ABS(x_il(l,:))) 
    114        END DO 
    115        DO l=1,llm+1 
    116           WRITE(*,'(A,I2.1,I3.2,E9.2)') '[hevi_solver] R_il', iter,l, MAXVAL(ABS(R_il(l,:)))  
    117        END DO 
    118     END IF 
    119  
    120   END DO ! Newton-Raphson 
    121  
    122   BARRIER 
    123  
    124   debug_hevi_solver=.FALSE. 
    125 END_BLOCK 
    126  
    12712KERNEL(caldyn_mil) 
    12813  FORALL_CELLS_EXT('1', 'llm+1') 
     
    13116       CST_IF(IS_INNER_INTERFACE, m_il(CELL) = .5*(rhodz(CELL)+rhodz(DOWN(CELL))) ) 
    13217       CST_IF(IS_TOP_INTERFACE,   m_il(CELL) = .5*rhodz(DOWN(CELL))               ) 
    133     END_BLOCK 
    134   END_BLOCK 
    135 END_BLOCK 
    136  
    137 KERNEL(caldyn_solver) 
    138   !  
    139   ! Compute pressure (pres) and Exner function (pk) 
    140   ! kappa = R/Cp 
    141   ! 1-kappa = Cv/Cp 
    142   ! Cp/Cv = 1/(1-kappa) 
    143   gamma    = 1./(1.-kappa) 
    144   vreff    = Rd*Treff/preff ! reference specific volume 
    145   Cvd      = 1./(cpp-Rd) 
    146   Rd_preff = kappa*cpp/preff 
    147   FORALL_CELLS_EXT() 
    148     SELECT CASE(caldyn_thermo) 
    149     CASE(thermo_theta) 
    150       ON_PRIMAL 
    151         rho_ij = 1./(geopot(UP(CELL))-geopot(CELL)) 
    152         rho_ij = rho_ij*g*rhodz(CELL) 
    153         X_ij = Rd_preff*theta(CELL,1)*rho_ij 
    154         ! kappa.theta.rho = p/exner 
    155         ! => X = (p/p0)/(exner/Cp) 
    156         !      = (p/p0)^(1-kappa) 
    157         pres(CELL) = preff*(X_ij**gamma)  ! pressure 
    158         ! Compute Exner function (needed by compute_caldyn_fast) 
    159         ! other formulae possible if exponentiation is slow 
    160         pk(CELL)   = cpp*((pres(CELL)/preff)**kappa) ! Exner 
    161       END_BLOCK 
    162     CASE(thermo_entropy) 
    163       ON_PRIMAL 
    164         rho_ij = 1./(geopot(UP(CELL))-geopot(CELL)) 
    165         rho_ij = rho_ij*g*rhodz(CELL) 
    166         T_ij = Treff*exp( (theta(CELL,1)+Rd*log(vreff*rho_ij))*Cvd ) 
    167         pres(CELL) = rho_ij*Rd*T_ij 
    168         pk(CELL)   = T_ij 
    169       END_BLOCK 
    170     CASE DEFAULT 
    171       STOP 
    172     END SELECT 
    173   END_BLOCK 
    174  
    175   ! We need a barrier here because we compute pres above and do a vertical difference below 
    176   BARRIER 
    177  
    178   FORALL_CELLS_EXT('1', 'llm+1') 
    179     ON_PRIMAL 
    180       CST_IFTHEN(IS_BOTTOM_LEVEL) 
    181         ! Lower BC 
    182         dW(CELL)   = (1./g)*(pbot-rho_bot*(geopot(CELL)-PHI_BOT(HIDX(CELL)))-pres(CELL)) - m_il(CELL) 
    183       CST_ELSEIF(IS_TOP_INTERFACE) 
    184         ! Top BC 
    185         dW(CELL)   = (1./g)*(pres(DOWN(CELL))-ptop) - m_il(CELL) 
    186       CST_ELSE 
    187         dW(CELL)   = (1./g)*(pres(DOWN(CELL))-pres(CELL)) - m_il(CELL) 
    188       CST_ENDIF 
    189       W(CELL)    = W(CELL)+tau*dW(CELL) ! update W 
    190       dPhi(CELL) = g*g*W(CELL)/m_il(CELL) 
    191     END_BLOCK 
    192   END_BLOCK 
    193  
    194   ! We need a barrier here because we update W above and do a vertical average below 
    195   BARRIER 
    196  
    197   FORALL_CELLS_EXT() 
    198     ON_PRIMAL 
    199       ! compute du = -0.5*g^2.grad(w^2) 
    200       berni(CELL) = (-.25*g*g)*((W(CELL)/m_il(CELL))**2 + (W(UP(CELL))/m_il(UP(CELL)))**2 ) 
    201     END_BLOCK 
    202   END_BLOCK 
    203   FORALL_CELLS_EXT() 
    204     ON_EDGES 
    205       du(EDGE) = SIGN*(berni(CELL1)-berni(CELL2)) 
    20618    END_BLOCK 
    20719  END_BLOCK 
  • codes/icosagcm/devel/Python/src/kernels_caldyn_hevi.jin

    r876 r878  
    9696END_BLOCK 
    9797 
    98 KERNEL(theta) 
    99   IF(caldyn_eta==eta_mass) THEN ! Compute mass 
    100     ! FIXME : here mass_col is computed from rhodz 
    101     ! so that the DOFs are the same whatever caldyn_eta 
    102     ! in DYNAMICO mass_col is prognosed rather than rhodz 
    103     SEQUENCE_C1 
    104       PROLOGUE(0) 
    105         mass_col(HIDX(CELL))=0. 
    106       END_BLOCK 
    107       BODY('1,llm') 
    108           mass_col(HIDX(CELL)) = mass_col(HIDX(CELL)) + rhodz(CELL) 
    109       END_BLOCK 
    110     END_BLOCK 
    111     FORALL_CELLS_EXT() 
    112       ON_PRIMAL 
    113         ! FIXME : formula below (used in DYNAMICO) is for dak, dbk based on pressure rather than mass 
    114         !        m = mass_dak(CELL)+(mass_col(HIDX(CELL))*g+ptop)*mass_dbk(CELL) 
    115         !        rhodz(CELL) = m/g 
    116         rhodz(CELL) = mass_dak(CELL) + mass_col(HIDX(CELL))*mass_dbk(CELL) 
    117       END_BLOCK 
    118     END_BLOCK 
    119   END IF 
    120   DO iq=1,nqdyn 
    121     FORALL_CELLS_EXT() 
    122       ON_PRIMAL 
    123         theta(CELL,iq) = theta_rhodz(CELL,iq)/rhodz(CELL) 
    124       END_BLOCK 
    125     END_BLOCK 
    126   END DO 
    127 END_BLOCK 
    12898 
Note: See TracChangeset for help on using the changeset viewer.