Пример #1
0
def calc_detrainment_entrainment(
        zi: gtscript.Field[DTYPE_FLOAT], xlamue: gtscript.Field[DTYPE_FLOAT],
        xlamud: gtscript.Field[DTYPE_FLOAT],
        ecko2: gtscript.Field[DTYPE_FLOAT], ctro2: gtscript.Field[DTYPE_FLOAT],
        eta: gtscript.Field[DTYPE_FLOAT], xmbp: gtscript.Field[DTYPE_FLOAT],
        kb: gtscript.Field[int], ktcon: gtscript.Field[int],
        cnvflg: gtscript.Field[int], index_k: gtscript.Field[int],
        dellae2: gtscript.Field[DTYPE_FLOAT]):
    with computation(PARALLEL), interval(1, -1):
        if cnvflg and (index_k < ktcon):
            dz = zi[0, 0, 0] - zi[0, 0, -1]
            aup = 1.0 if index_k > kb else 0.0

            dv1q = 0.5 * (ecko2[0, 0, 0] + ecko2[0, 0, -1])
            dv2q = 0.5 * (ctro2[0, 0, 0] + ctro2[0, 0, -1])

            tem = 0.5 * (xlamue[0, 0, 0] + xlamue[0, 0, -1])
            tem1 = 0.5 * (xlamud[0, 0, 0] + xlamud[0, 0, 0])

            dellae2 = dellae2 + (
                aup * tem1 * eta[0, 0, -1] * dv1q  # detrainment from updraft
                - aup * tem * eta[0, 0, -1] *
                dv2q  # entrainment into up and downdraft
            ) * dz * xmbp

            if index_k == kb:
                dellae2 = dellae2 - eta * ctro2 * xmbp
    with computation(FORWARD), interval(0, 1):
        if cnvflg and (kb == 1):
            dellae2 = dellae2 - eta * ctro2 * xmbp
Пример #2
0
def set_work_arrays(
        qtr: gtscript.Field[DTYPE_FLOAT], xmb: gtscript.Field[DTYPE_FLOAT],
        delp: gtscript.Field[DTYPE_FLOAT], kmax: gtscript.Field[int],
        kb: gtscript.Field[int], cnvflg: gtscript.Field[int],
        index_k: gtscript.Field[int], qaero: gtscript.Field[DTYPE_FLOAT],
        xmbp: gtscript.Field[DTYPE_FLOAT], ctro2: gtscript.Field[DTYPE_FLOAT],
        ecko2: gtscript.Field[DTYPE_FLOAT]):
    with computation(PARALLEL), interval(...):
        qaero = set_qaero(qtr, kmax, index_k)
        xmbp = set_xmbp(xmb, delp)
    with computation(PARALLEL), interval(...):
        ctro2 = set_ctro2(qaero, kmax, index_k)
        ecko2 = set_ecko2(ctro2, cnvflg, kb, index_k)
Пример #3
0
def calc_ecko2_chem_c_dellae2(
        zi: gtscript.Field[DTYPE_FLOAT],
        xlamue: gtscript.Field[DTYPE_FLOAT],
        xlamud: gtscript.Field[DTYPE_FLOAT],
        ctro2: gtscript.Field[DTYPE_FLOAT],
        c0t: gtscript.Field[DTYPE_FLOAT],
        eta: gtscript.Field[DTYPE_FLOAT],
        xmbp: gtscript.Field[DTYPE_FLOAT],
        kb: gtscript.Field[int],
        ktcon: gtscript.Field[int],
        cnvflg: gtscript.Field[int],
        index_k: gtscript.Field[int],
        ecko2: gtscript.Field[DTYPE_FLOAT],
        chem_c: gtscript.Field[DTYPE_FLOAT],
        # chem_pw: gtscript.Field[DTYPE_FLOAT],
        dellae2: gtscript.Field[DTYPE_FLOAT],
        *,
        fscav: float):
    with computation(FORWARD), interval(1, -1):
        if cnvflg and (index_k > kb) and (index_k < ktcon):
            dz = zi[0, 0, 0] - zi[0, 0, -1]
            tem = 0.5 * (xlamue[0, 0, 0] + xlamue[0, 0, -1]) * dz
            tem1 = 0.25 * (xlamud[0, 0, 0] + xlamud[0, 0, 0]) * dz
            factor = 1.0 + tem - tem1

            # if conserved (not scavenging) then
            ecko2 = ((1.0 - tem1) * ecko2[0, 0, -1] + 0.5 * tem *
                     (ctro2[0, 0, 0] + ctro2[0, 0, -1])) / factor
            #    how much will be scavenged
            #    this choice was used in GF, and is also described in a
            #    successful implementation into CESM in GRL (Yu et al. 2019),
            #    it uses dimesnsionless scavenging coefficients (fscav),
            #    but includes henry coeffs with gas phase chemistry
            #    fraction fscav is going into liquid
            chem_c = escav * fscav * ecko2
            # of that part is going into rain out (chem_pw)
            tem2 = chem_c / (1.0 + c0t * dz)
            # chem_pw = c0t * dz * tem2 * eta # etah
            ecko2 = tem2 + ecko2 - chem_c
    with computation(PARALLEL), interval(0, -1):
        if index_k >= ktcon:
            ecko2 = ctro2
        if cnvflg and (index_k == ktcon):
            # for the subsidence term already is considered
            dellae2 = eta[0, 0, -1] * ecko2[0, 0, -1] * xmbp
Пример #4
0
def diffusion_defs(in_field: gtscript.Field[float],
                   out_field: gtscript.Field[float], *, alpha: float):
    from __externals__ import laplacian
    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL), interval(...):
        lap1 = laplacian(in_field)
        lap2 = laplacian(lap1)
        out_field = in_field - alpha * lap2
Пример #5
0
def calc_final(dellae2: gtscript.Field[DTYPE_FLOAT], kmax: gtscript.Field[int],
               ktcon: gtscript.Field[int], cnvflg: gtscript.Field[int],
               index_k: gtscript.Field[int],
               qaero: gtscript.Field[DTYPE_FLOAT], *, delt: float):
    # compute final aerosol concentrations
    with computation(PARALLEL), interval(...):
        if cnvflg and (index_k <= min(kmax, ktcon)):
            qaero = qaero + dellae2 * delt
            if qaero < 0.0:
                qaero = qamin
Пример #6
0
def diffusion_defs(in_field: gtscript.Field[float],
                   out_field: gtscript.Field[float], *, alpha: float):
    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL), interval(...):
        lap1 = (-4.0 * in_field[0, 0, 0] + in_field[-1, 0, 0] +
                in_field[1, 0, 0] + in_field[0, -1, 0] + in_field[0, 1, 0])
        lap2 = (-4.0 * lap1[0, 0, 0] + lap1[-1, 0, 0] + lap1[1, 0, 0] +
                lap1[0, -1, 0] + lap1[0, 1, 0])
        out_field = in_field - alpha * lap2
Пример #7
0
def calc_dtime_max_arr(delp: gtscript.Field[DTYPE_FLOAT],
                       ktcon: gtscript.Field[int],
                       index_k: gtscript.Field[int],
                       dtime_max_arr: gtscript.Field[DTYPE_FLOAT], *,
                       delt: float):
    with computation(FORWARD):
        with interval(0, 1):
            dtime_max_arr = delt
        with interval(1, -1):
            if index_k - 1 < ktcon:
                dtime_max_arr = min(dtime_max_arr[0, 0, -1],
                                    0.5 * delp[0, 0, -1])
            else:
                dtime_max_arr = dtime_max_arr[0, 0, -1]
Пример #8
0
def calc_mass_flux(eta: gtscript.Field[DTYPE_FLOAT],
                   xmb: gtscript.Field[DTYPE_FLOAT],
                   qaero: gtscript.Field[DTYPE_FLOAT],
                   delp: gtscript.Field[DTYPE_FLOAT], kb: gtscript.Field[int],
                   ktcon: gtscript.Field[int], cnvflg: gtscript.Field[int],
                   index_k: gtscript.Field[int],
                   flx_lo: gtscript.Field[DTYPE_FLOAT],
                   totlout: gtscript.Field[DTYPE_FLOAT],
                   clipout: gtscript.Field[DTYPE_FLOAT],
                   dellae2: gtscript.Field[DTYPE_FLOAT], *, dtime_max: float):
    with computation(PARALLEL), interval(1, -1):
        if cnvflg and (index_k - 1 < ktcon):
            tem = 0.0 if index_k - 1 < kb else eta[0, 0, -1]
            # low-order flux, upstream
            qaero_val = qaero[0, 0, 0] if tem > 0.0 else qaero[0, 0, -1]
            flx_lo = -xmb * tem * qaero_val
    # make sure low-ord fluxes don't violate positive-definiteness
    with computation(PARALLEL), interval(0, -1):
        if cnvflg and (index_k <= ktcon):
            # time step / grid spacing
            dtovdz = g * dtime_max / abs(delp)
            # total flux out
            totlout = max(0.0, flx_lo[0, 0, 1]) - min(0.0, flx_lo[0, 0, 0])
            clipout = min(1.0, qaero / max(epsil, totlout) / (1.0001 * dtovdz))
    # recompute upstream mass fluxes
    with computation(PARALLEL), interval(1, -1):
        if cnvflg and index_k - 1 <= ktcon:
            tem = 0.0 if index_k - 1 < kb else eta[0, 0, -1]
            clipout_val = clipout[0, 0, 0] if tem > 0.0 else clipout[0, 0, -1]
            flx_lo = flx_lo * clipout_val
    # a positive-definite low-order (diffusive) solution for the subsidnce fluxes
    with computation(PARALLEL), interval(0, -1):
        if cnvflg and index_k <= ktcon:
            # time step / grid spacing
            dtovdz = g * dtime_max / abs(delp)
            dellae2 = dellae2 - (flx_lo[0, 0, 1] -
                                 flx_lo[0, 0, 0]) * dtovdz / dtime_max
Пример #9
0
def diffusion_defs(
    in_field: gtscript.Field[float],
    out_field: gtscript.Field[float],
    *,
    a1: float,
    a2: float,
    a8: float,
    a20: float,
):
    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL), interval(...):
        out_field = (a1 * in_field[0, -2, 0] + a2 * in_field[-1, -1, 0] +
                     a8 * in_field[0, -1, 0] + a2 * in_field[1, -1, 0] +
                     a1 * in_field[-2, 0, 0] + a8 * in_field[-1, 0, 0] +
                     a20 * in_field[0, 0, 0] + a8 * in_field[1, 0, 0] +
                     a1 * in_field[2, 0, 0] + a2 * in_field[-1, 1, 0] +
                     a8 * in_field[0, 1, 0] + a2 * in_field[1, 1, 0] +
                     a1 * in_field[0, 2, 0])
Пример #10
0
def heat_gt4py_3D(u_now: gtscript.Field[np.float64],
                  u_next: gtscript.Field[np.float64], *, alpha: np.float64,
                  dt: np.float64, dx: np.float64, dy: np.float64,
                  dz: np.float64):
    '''
    Definiton for the stencil in gt4py
    
    u_now -- field at the time t, as gtscript Field
    u_next -- field at the time t+dt, as gtscript Field
    alpha -- thermal diffusivity
    dt -- time step
    dx, dy, dz -- spacing in each direction
    '''

    from __externals__ import laplace_gt4py_3D
    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL):
        with interval(1, -1):
            u_next = u_now + dt * alpha * laplace_gt4py_3D(u_now, dx, dy, dz)
Пример #11
0
def sfc_sice_defs(ps: DT_F, t1: DT_F, q1: DT_F, sfcemis: DT_F, dlwflx: DT_F,
                  sfcnsw: DT_F, sfcdsw: DT_F, srflag: DT_F, cm: DT_F, ch: DT_F,
                  prsl1: DT_F, prslki: DT_F, islimsk: DT_I, wind: DT_F,
                  flag_iter: DT_I, hice: DT_F, fice: DT_F, tice: DT_F,
                  weasd: DT_F, tskin: DT_F, tprcp: DT_F, stc0: DT_F,
                  stc1: DT_F, ep: DT_F, snwdph: DT_F, qsurf: DT_F, cmm: DT_F,
                  chh: DT_F, evap: DT_F, hflx: DT_F, gflux: DT_F, snowmt: DT_F,
                  *, delt: float, cimin: float):
    """This file contains the GFS thermodynamics surface ice model.
   
    =====================================================================
    description:                                                        
   
    usage:                                                              
   
   
    program history log:                                                
           2005  --  xingren wu created  from original progtm and added 
                       two-layer ice model                              
           200x  -- sarah lu    added flag_iter                         
      oct  2006  -- h. wei      added cmm and chh to output             
           2007  -- x. wu modified for mom4 coupling (i.e. cpldice)     
                                      (not used anymore)                
           2007  -- s. moorthi micellaneous changes                     
      may  2009  -- y.-t. hou   modified to include surface emissivity  
                       effect on lw radiation. replaced the confusing   
                       slrad with sfc net sw sfcnsw (dn-up). reformatted
                       the code and add program documentation block.    
      sep  2009 -- s. moorthi removed rcl, changed pressure units and   
                       further optimized                                
      jan  2015 -- x. wu change "cimin = 0.15" for both                 
                       uncoupled and coupled case                       
      jul  2020 -- ETH-students port to gt4py
   
   
    ====================  definition of variables  ==================== 
   
    inputs:                                                       size  
       ps       - real, surface pressure                            im
       t1       - real, surface layer mean temperature ( k )        im
       q1       - real, surface layer mean specific humidity        im
       sfcemis  - real, sfc lw emissivity ( fraction )              im
       dlwflx   - real, total sky sfc downward lw flux ( w/m**2 )   im
       sfcnsw   - real, total sky sfc netsw flx into ground(w/m**2) im
       sfcdsw   - real, total sky sfc downward sw flux ( w/m**2 )   im
       srflag   - real, snow/rain fraction for precipitation        im
       cm       - real, surface exchange coeff for momentum (m/s)   im
       ch       - real, surface exchange coeff heat & moisture(m/s) im
       prsl1    - real, surface layer mean pressure                 im
       prslki   - real,                                             im
       islimsk  - integer, sea/land/ice mask (=0/1/2)               im
       wind     - real,                                             im
       flag_iter- logical,                                          im
       delt     - real, time interval (second)                      1
       cimin    - real, minimum ice fraction                        1

    input/outputs:
       hice     - real, sea-ice thickness                           im
       fice     - real, sea-ice concentration                       im
       tice     - real, sea-ice surface temperature                 im
       weasd    - real, water equivalent accumulated snow depth (mm)im
       tskin    - real, ground surface skin temperature ( k )       im
       tprcp    - real, total precipitation                         im
       stc0     - real, soil temp (k), 1. layer                     im
       stc1     - real, soil temp (k), 2nd layer                    im
       ep       - real, potential evaporation                       im

    outputs:
       snwdph   - real, water equivalent snow depth (mm)            im
       qsurf    - real, specific humidity at sfc                    im
       snowmt   - real, snow melt (m)                               im
       gflux    - real, soil heat flux (w/m**2)                     im
       cmm      - real, surface exchange coeff for momentum(m/s)    im
       chh      - real, surface exchange coeff heat&moisture (m/s)  im  
       evap     - real, evaperation from latent heat flux           im  
       hflx     - real, sensible heat flux                          im  
                                                                        
    =====================================================================
    """

    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL), interval(...):

        FLOAT_EPS = 1.0e-8

        # sfc_sice constants
        EPS = RD / RV
        EPSM1 = RD / RV - 1.0
        RVRDM1 = RV / RD - 1.0
        ELOCP = HVAP / CP
        HIMAX = 8.0  # maximum ice thickness allowed
        HIMIN = 0.1  # minimum ice thickness required
        HSMAX = 2.0  # maximum snow depth allowed
        TIMIN = 173.0  # minimum temperature allowed for snow/ice
        ALBFW = 0.06  # albedo for lead
        DSI = 1.0 / 0.33

        #  --- ...  set flag for sea-ice
        flag = (islimsk == 2) and flag_iter

        if flag_iter and (islimsk < 2):
            hice = 0.0
            fice = 0.0

        if flag:
            if srflag > 0.0:
                ep = ep * (1.0 - srflag)
                weasd = weasd + 1.0e3 * tprcp * srflag
                tprcp = tprcp * (1.0 - srflag)

            #  --- ...  initialize variables. all units are supposedly m.k.s. unless specified
            #           psurf is in pascals, wind is wind speed, theta1 is adiabatic surface
            #           temp from level 1, rho is density, qs1 is sat. hum. at level1 and qss
            #           is sat. hum. at surface
            #           convert slrad to the civilized unit from langley minute-1 k-4

            #         dlwflx has been given a negative sign for downward longwave
            #         sfcnsw is the net shortwave flux (direction: dn-up)

            q0 = max(q1, FLOAT_EPS)
            theta1 = t1 * prslki
            rho = prsl1 / (RD * t1 * (1.0 + RVRDM1 * q0))
            qs1 = fpvs_fn(t1)
            qs1 = max(EPS * qs1 / (prsl1 + EPSM1 * qs1), FLOAT_EPS)
            q0 = min(qs1, q0)

            if fice < cimin:
                #  print("warning: ice fraction is low:", fice)
                # fice = cimin
                tice = TGICE
                tskin = TGICE
                #  print('fix ice fraction: reset it to:', fice)

            fice = max(fice, cimin)

            ffw = 1.0 - fice
            qssi = fpvs_fn(tice)
            qssw = fpvs_fn(TGICE)
            qssi = EPS * qssi / (ps + EPSM1 * qssi)
            qssw = EPS * qssw / (ps + EPSM1 * qssw)

            #  --- ...  snow depth in water equivalent is converted from mm to m unit

            snowd = weasd * 0.001

            #  --- ...  when snow depth is less than 1 mm, a patchy snow is assumed and
            #           soil is allowed to interact with the atmosphere.
            #           we should eventually move to a linear combination of soil and
            #           snow under the condition of patchy snow.

            #  --- ...  rcp = rho CP ch v

            cmm = cm * wind
            chh = rho * ch * wind
            rch = chh * CP

            #  --- ...  sensible and latent heat flux over open water & sea ice

            evapi = ELOCP * rch * (qssi - q0)
            evapw = ELOCP * rch * (qssw - q0)

            snetw = sfcdsw * (1.0 - ALBFW)
            snetw = min(3.0 * sfcnsw / (1.0 + 2.0 * ffw), snetw)
            sneti = (sfcnsw - ffw * snetw) / fice

            t12 = tice * tice
            t14 = t12 * t12

            #  --- ...  hfi = net non-solar and upir heat flux @ ice surface

            hfi = -dlwflx + sfcemis * SBC * t14 + evapi + rch * (tice - theta1)
            hfd = (4.0 * sfcemis * SBC * tice * t12 +
                   (1.0 + ELOCP * EPS * HVAP * qs1 / (RD * t12)) * rch)

            t12 = TGICE * TGICE
            t14 = t12 * t12

            #  --- ...  hfw = net heat flux @ water surface (within ice)

            focn = 2.0  # heat flux from ocean - should be from ocn model
            snof = 0.0  # snowfall rate - snow accumulates in gbphys

            hice = max(min(hice, HIMAX), HIMIN)
            snowd = min(snowd, HSMAX)

            if snowd > 2.0 * hice:
                #  print('warning: too much snow :', snowd[i])
                snowd = hice + hice
                #  print('fix: decrease snow depth to:', snowd[i])

            # run the 3-layer ice model
            snowd, hice, stc0, stc1, tice, snof, snowmt, gflux = ice3lay(
                fice,
                hfi,
                hfd,
                sneti,
                focn,
                delt,
                snowd,
                hice,
                stc0,
                stc1,
                tice,
                snof,
                snowmt,
                gflux,
            )

            if tice < TIMIN:
                #  print('warning: snow/ice temperature is too low:', tice, ' i=', i)
                tice = TIMIN
                #  print('fix snow/ice temperature: reset it to:', TIMIN)

            if stc0 < TIMIN:
                #  print('warning: layer 1 ice temp is too low:', stsice[i, 0], ' i=', i)
                stc0 = TIMIN
                #  print('fix layer 1 ice temp: reset it to:', TIMIN)

            if stc1 < TIMIN:
                #  print('warning: layer 2 ice temp is too low:', stsice[i, 1], 'i=', i)
                stc1 = TIMIN
                #  print('fix layer 2 ice temp: reset it to:', TIMIN)

            tskin = tice * fice + TGICE * ffw
            stc0 = min(stc0, T0C)
            stc1 = min(stc1, T0C)

            #  --- ...  calculate sensible heat flux (& evap over sea ice)

            hflxi = rch * (tice - theta1)
            hflxw = rch * (TGICE - theta1)
            hflx = fice * hflxi + ffw * hflxw
            evap = fice * evapi + ffw * evapw

            #  --- ...  the rest of the output

            qsurf = q1 + evap / (ELOCP * rch)

            #  --- ...  convert snow depth back to mm of water equivalent

            weasd = snowd * 1000.0
            snwdph = weasd * DSI  # snow depth in mm

            hflx = hflx / rho * 1.0 / CP
            evap = evap / rho * 1.0 / HVAP
Пример #12
0
def copy_defs(src: gtscript.Field["dtype"], dst: gtscript.Field["dtype"]):
    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL), interval(...):
        dst = src
Пример #13
0
def sfc_sice_p2_defs(
    q1: DT_F,
    islimsk: DT_I,
    flag_iter: DT_I,
    fice: DT_F,
    tice: DT_F,
    tskin: DT_F,
    stc0: DT_F,
    stc1: DT_F,
    qsurf: DT_F,
    evap: DT_F,
    hflx: DT_F,
    # new variables:
    ffw: DT_F,
    theta1: DT_F,
    rch: DT_F,
    evapi: DT_F,
    evapw: DT_F,
    rho: DT_F,
):

    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL), interval(...):

        hflxi = INIT_VALUE
        hflxw = INIT_VALUE

        #  --- ...  set flag for sea-ice

        flag = (islimsk == 2) and flag_iter
        if flag:
            if tice < TIMIN:
                # print('warning: snow/ice temperature is too low:', tice, ' i=', i)
                tice = TIMIN
                # print('fix snow/ice temperature: reset it to:', TIMIN)

            if stc0 < TIMIN:
                # print('warning: layer 1 ice temp is too low:', stsice[i, 0], ' i=', i)
                stc0 = TIMIN
                # print('fix layer 1 ice temp: reset it to:', TIMIN)

            if stc1 < TIMIN:
                # print('warning: layer 2 ice temp is too low:', stsice[i, 1], 'i=', i)
                stc1 = TIMIN
                # print('fix layer 2 ice temp: reset it to:', TIMIN)

            tskin = tice * fice + TGICE * ffw
            stc0 = T0C if T0C < stc0 else stc0
            stc1 = T0C if T0C < stc1 else stc1

            #  --- ...  calculate sensible heat flux (& evap over sea ice)

            hflxi = rch * (tice - theta1)
            hflxw = rch * (TGICE - theta1)
            hflx = fice * hflxi + ffw * hflxw
            evap = fice * evapi + ffw * evapw

            #  --- ...  the rest of the output

            qsurf = q1 + evap / (ELOCP * rch)

            hflx = hflx / rho * 1. / CP
            evap = evap / rho * 1. / HVAP
Пример #14
0
def sfc_sice_defs(
        ps: DT_F,
        t1: DT_F,
        q1: DT_F,
        sfcemis: DT_F,
        dlwflx: DT_F,
        sfcnsw: DT_F,
        sfcdsw: DT_F,
        srflag: DT_F,
        cm: DT_F,
        ch: DT_F,
        prsl1: DT_F,
        prslki: DT_F,
        islimsk: DT_I,
        wind: DT_F,
        flag_iter: DT_I,
        hice: DT_F,
        fice: DT_F,
        tice: DT_F,
        weasd: DT_F,
        tskin: DT_F,
        tprcp: DT_F,
        stc0: DT_F,
        stc1: DT_F,
        ep: DT_F,
        snwdph: DT_F,
        qsurf: DT_F,
        cmm: DT_F,
        chh: DT_F,
        evap: DT_F,
        hflx: DT_F,
        gflux: DT_F,
        snowmt: DT_F,
        # new variables
        hfi: DT_F,
        hfd: DT_F,
        sneti: DT_F,
        focn: DT_F,
        snof: DT_F,
        # new variables for second part
        ffw: DT_F,
        theta1: DT_F,
        rch: DT_F,
        evapi: DT_F,
        evapw: DT_F,
        rho: DT_F,
        *,
        delt: float,
        cimin: float):
    """This file contains the GFS thermodynamics surface ice model.
   
    =====================================================================
    description:                                                        
   
    usage:                                                              
   
   
    program history log:                                                
           2005  --  xingren wu created  from original progtm and added 
                       two-layer ice model                              
           200x  -- sarah lu    added flag_iter                         
      oct  2006  -- h. wei      added cmm and chh to output             
           2007  -- x. wu modified for mom4 coupling (i.e. cpldice)     
                                      (not used anymore)                
           2007  -- s. moorthi micellaneous changes                     
      may  2009  -- y.-t. hou   modified to include surface emissivity  
                       effect on lw radiation. replaced the confusing   
                       slrad with sfc net sw sfcnsw (dn-up). reformatted
                       the code and add program documentation block.    
      sep  2009 -- s. moorthi removed rcl, changed pressure units and   
                       further optimized                                
      jan  2015 -- x. wu change "cimin = 0.15" for both                 
                       uncoupled and coupled case                       
      jul  2020 -- ETH-students port to gt4py
   
   
    ====================  definition of variables  ==================== 
   
    inputs:                                                       size  
       ps       - real, surface pressure                            im
       t1       - real, surface layer mean temperature ( k )        im
       q1       - real, surface layer mean specific humidity        im
       sfcemis  - real, sfc lw emissivity ( fraction )              im
       dlwflx   - real, total sky sfc downward lw flux ( w/m**2 )   im
       sfcnsw   - real, total sky sfc netsw flx into ground(w/m**2) im
       sfcdsw   - real, total sky sfc downward sw flux ( w/m**2 )   im
       srflag   - real, snow/rain fraction for precipitation        im
       cm       - real, surface exchange coeff for momentum (m/s)   im
       ch       - real, surface exchange coeff heat & moisture(m/s) im
       prsl1    - real, surface layer mean pressure                 im
       prslki   - real,                                             im
       islimsk  - integer, sea/land/ice mask (=0/1/2)               im
       wind     - real,                                             im
       flag_iter- logical,                                          im
       delt     - real, time interval (second)                      1
       cimin    - real, minimum ice fraction                        1

    input/outputs:
       hice     - real, sea-ice thickness                           im
       fice     - real, sea-ice concentration                       im
       tice     - real, sea-ice surface temperature                 im
       weasd    - real, water equivalent accumulated snow depth (mm)im
       tskin    - real, ground surface skin temperature ( k )       im
       tprcp    - real, total precipitation                         im
       stc0     - real, soil temp (k), 1. layer                     im
       stc1     - real, soil temp (k), 2nd layer                    im
       ep       - real, potential evaporation                       im

    outputs:
       snwdph   - real, water equivalent snow depth (mm)            im
       qsurf    - real, specific humidity at sfc                    im
       snowmt   - real, snow melt (m)                               im
       gflux    - real, soil heat flux (w/m**2)                     im
       cmm      - real, surface exchange coeff for momentum(m/s)    im
       chh      - real, surface exchange coeff heat&moisture (m/s)  im  
       evap     - real, evaperation from latent heat flux           im  
       hflx     - real, sensible heat flux                          im  
                                                                        
    =====================================================================
    """

    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL), interval(...):

        # arrays
        # TODO - only initialize the arrays which are defined in an if-statement
        q0 = INIT_VALUE
        #         theta1  = INIT_VALUE
        #         rho     = INIT_VALUE
        #         ffw     = INIT_VALUE
        #         snowd   = INIT_VALUE
        #         rch     = INIT_VALUE
        #         evapi   = INIT_VALUE
        #         evapw   = INIT_VALUE
        #         sneti   = INIT_VALUE
        snetw = INIT_VALUE
        t12 = INIT_VALUE
        t14 = INIT_VALUE
        #         hfi     = INIT_VALUE
        #         hfd     = INIT_VALUE
        #         focn    = INIT_VALUE
        #         snof    = INIT_VALUE
        #         hflxi   = INIT_VALUE
        #         hflxw   = INIT_VALUE

        #  --- ...  set flag for sea-ice

        flag = (islimsk == 2) and flag_iter

        if flag_iter and (islimsk < 2):
            hice = 0.
            fice = 0.

        qs1 = fpvs_fn(t1)
        if flag:
            if srflag > 0.:
                ep = ep * (1. - srflag)
                weasd = weasd + 1.e3 * tprcp * srflag
                tprcp = tprcp * (1. - srflag)

    #  --- ...  initialize variables. all units are supposedly m.k.s. unless specified
    #           psurf is in pascals, wind is wind speed, theta1 is adiabatic surface
    #           temp from level 1, rho is density, qs1 is sat. hum. at level1 and qss
    #           is sat. hum. at surface
    #           convert slrad to the civilized unit from langley minute-1 k-4

    #         dlwflx has been given a negative sign for downward longwave
    #         sfcnsw is the net shortwave flux (direction: dn-up)

            q0 = q1 if q1 > 1.0e-8 else 1.0e-8
            theta1 = t1 * prslki
            rho = prsl1 / (RD * t1 * (1. + RVRDM1 * q0))

            qs1 = EPS * qs1 / (prsl1 + EPSM1 * qs1)
            qs1 = qs1 if qs1 > 1.e-8 else 1.e-8
            q0 = qs1 if qs1 < q0 else q0

            if fice < cimin:
                # print("warning: ice fraction is low:", fice)
                #fice = cimin
                tice = TGICE
                tskin = TGICE
                # print('fix ice fraction: reset it to:', fice)

            fice = fice if fice > cimin else cimin

        qssi = fpvs_fn(tice)
        qssw = fpvs_fn(TGICE)
        if flag:
            ffw = 1. - fice
            qssi = EPS * qssi / (ps + EPSM1 * qssi)
            qssw = EPS * qssw / (ps + EPSM1 * qssw)

            #  --- ...  snow depth in water equivalent is converted from mm to m unit

            weasd = weasd * 0.001

            #  --- ...  when snow depth is less than 1 mm, a patchy snow is assumed and
            #           soil is allowed to interact with the atmosphere.
            #           we should eventually move to a linear combination of soil and
            #           snow under the condition of patchy snow.

            #  --- ...  rcp = rho CP ch v

            cmm = cm * wind
            chh = rho * ch * wind
            rch = chh * CP

            #  --- ...  sensible and latent heat flux over open water & sea ice

            evapi = ELOCP * rch * (qssi - q0)
            evapw = ELOCP * rch * (qssw - q0)

            snetw = sfcdsw * (1. - ALBFW)
            t12 = 3. * sfcnsw / (1. + 2. * ffw)
            snetw = t12 if t12 < snetw else snetw
            sneti = (sfcnsw - ffw * snetw) / fice

            t12 = tice * tice
            t14 = t12 * t12

            #  --- ...  hfi = net non-solar and upir heat flux @ ice surface

            hfi = -dlwflx + sfcemis * SBC * t14 + evapi + \
                    rch * (tice - theta1)
            hfd = 4. * sfcemis * SBC * tice * t12 + \
                    (1. + ELOCP * EPS * HVAP * qs1 / (RD * t12)) * rch

            t12 = TGICE * TGICE
            t14 = t12 * t12

            #  --- ...  hfw = net heat flux @ water surface (within ice)

            focn = 2.  # heat flux from ocean - should be from ocn model
            snof = 0.  # snowfall rate - snow accumulates in gbphys

            # hice = np.maximum(np.minimum(hice, HIMAX), HIMIN)
            hice = HIMAX if HIMAX < hice else hice
            hice = HIMIN if HIMIN > hice else hice
            weasd = HSMAX if HSMAX < weasd else weasd

            if weasd > 2. * hice:
                # print('warning: too much snow :', snowd[i])
                weasd = hice + hice
Пример #15
0
def ice3lay_defs(  #fice, flag, hfi, hfd, sneti, focn, delt, snowd, hice,
    #stc0, stc1, tice, snof, snowmt, gflux):
    islimsk: DT_I,
    flag_iter: DT_I,
    hice: DT_F,
    fice: DT_F,
    tice: DT_F,
    snowd: DT_F,
    stc0: DT_F,
    stc1: DT_F,
    gflux: DT_F,
    snowmt: DT_F,
    snwdph: DT_F,
    # new variables
    hfi: DT_F,
    hfd: DT_F,
    sneti: DT_F,
    focn: DT_F,
    snof: DT_F,
    *,
    delt: float,
):
    """three-layer sea ice vertical thermodynamics
                                                                           *
    based on:  m. winton, "a reformulated three-layer sea ice model",      *
    journal of atmospheric and oceanic technology, 2000                    *
                                                                           *
                                                                           *
          -> +---------+ <- tice - diagnostic surface temperature ( <= 0c )*
         /   |         |                                                   *
     snowd   |  snow   | <- 0-heat capacity snow layer                     *
         \   |         |                                                   *
          => +---------+                                                   *
         /   |         |                                                   *
        /    |         | <- t1 - upper 1/2 ice temperature; this layer has *
       /     |         |         a variable (t/s dependent) heat capacity  *
     hice    |...ice...|                                                   *
       \     |         |                                                   *
        \    |         | <- t2 - lower 1/2 ice temp. (fixed heat capacity) *
         \   |         |                                                   *
          -> +---------+ <- base of ice fixed at seawater freezing temp.   *
                                                                           *
    =====================  definition of variables  =====================  *
                                                                           *
    inputs:                                                         size   *
       fice     - real, sea-ice concentration                         im   *
       flag     - logical, ice mask flag                              1    *
       hfi      - real, net non-solar and heat flux @ surface(w/m^2)  im   *
       hfd      - real, heat flux derivatice @ sfc (w/m^2/deg-c)      im   *
       sneti    - real, net solar incoming at top  (w/m^2)            im   *
       focn     - real, heat flux from ocean    (w/m^2)               im   *
       delt     - real, timestep                (sec)                 1    *
                                                                           *
    input/outputs:                                                         *
       snowd    - real, surface pressure                              im   *
       hice     - real, sea-ice thickness                             im   *
       stc0     - real, temp @ midpt of ice levels (deg c), 1st layer im   *     
       stc1     - real, temp @ midpt of ice levels (deg c), 2nd layer im   *     
       tice     - real, surface temperature     (deg c)               im   *
       snof     - real, snowfall rate           (m/sec)               im   *
                                                                           *
    outputs:                                                               *
       snowmt   - real, snow melt during delt   (m)                   im   *
       gflux    - real, conductive heat flux    (w/m^2)               im   *
                                                                           *
    locals:                                                                *
       hdi      - real, ice-water interface     (m)                        *
       hsni     - real, snow-ice                (m)                        *
                                                                           *
    ====================================================================== *
    """

    from __gtscript__ import PARALLEL, computation, interval

    with computation(PARALLEL), interval(...):

        # TODO - only initialize the arrays which are defined in an if-statement
        hdi = INIT_VALUE
        ip = INIT_VALUE
        tsf = INIT_VALUE
        ai = INIT_VALUE
        k12 = INIT_VALUE
        wrk = INIT_VALUE
        a10 = INIT_VALUE
        b10 = INIT_VALUE
        a1 = INIT_VALUE
        b1 = INIT_VALUE
        c1 = INIT_VALUE
        tmelt = INIT_VALUE
        bmelt = INIT_VALUE
        h1 = INIT_VALUE
        h2 = INIT_VALUE
        dh = INIT_VALUE

        flag = (islimsk == 2) and flag_iter
        if flag:
            snowd = snowd * DWDS
            hdi = (DSDW * snowd + DIDW * hice)

            if hice < hdi:
                snowd = snowd + hice - hdi
                hice = hice + (hdi - hice) * DSDI

            snof = snof * DWDS
            tice = tice - T0C
            stc0 = stc0 - T0C if stc0 - T0C < TFI0 else TFI0
            stc1 = TFI0 if TFI0 < stc1 - T0C else stc1 - T0C  # degc

            ip = I0 * sneti  # ip +v here (in winton ip=-I0*sneti)
            if snowd > 0.:
                tsf = 0.
                ip = 0.
            else:
                tsf = TFI

            tice = tsf if tsf < tice else tice

            # compute ice temperature

            ai = hfi - sneti + ip - tice * hfd  # +v sol input here
            k12 = KI4 * KS / (KS * hice + KI4 * snowd)

            wrk = 1. / (6. * delt * 2. * KI / hice + DICI * hice)
            a10 = DICI * hice * (0.5 / delt) + \
                2. * KI / hice * (4. * delt * 2. * KI / hice + DICI * hice) * wrk
            b10 = -DI * hice * (CI * stc0 + LI * TFI / \
                    stc0) * (0.5 / delt) - ip - 2. * KI / hice * \
                    (4. * delt * 2. * KI / hice * TFW + DICI * hice * stc1) * wrk

            a1 = a10 + hfd * k12 / (k12 + hfd)
            b1 = b10 + ai * k12 / (k12 + hfd)
            c1 = DILI * TFI * (0.5 / delt) * hice

            stc0 = -((b1 * b1 - 4. * a1 * c1)**0.5 + b1) / (a1 + a1)
            tice = (k12 * stc0 - ai) / (k12 + hfd)

            if tice > tsf:
                a1 = a10 + k12
                b1 = b10 - k12 * tsf
                stc0 = -((b1 * b1 - 4. * a1 * c1)**0.5 + b1) / (a1 + a1)
                tice = tsf
                tmelt = (k12 * (stc0 - tsf) - (ai + hfd * tsf)) * delt
            else:
                tmelt = 0.
                snowd = snowd + snof * delt

            stc1 = (2. * delt * 2. * KI / hice * (stc0 + TFW + TFW) + \
                DICI * hice * stc1) * wrk
            bmelt = (focn + KI4 * (stc1 - TFW) / hice) * delt

            #  --- ...  resize the ice ...

            h1 = 0.5 * hice
            h2 = 0.5 * hice

            #  --- ...  top ...
            if tmelt <= snowd * DSLI:
                snowmt = tmelt / DSLI
                snowd = snowd - snowmt
            else:
                snowmt = snowd
                h1 = h1 - (tmelt - snowd * DSLI) / \
                        (DI * (CI - LI / stc0) * (TFI - stc0))
                snowd = 0.

        #  --- ...  and bottom

            if bmelt < 0.:
                dh = -bmelt / (DILI + DICI * (TFI - TFW))
                stc1 = (h2 * stc1 + dh * TFW) / (h2 + dh)
                h2 = h2 + dh
            else:
                h2 = h2 - bmelt / (DILI + DICI * (TFI - stc1))

        #  --- ...  if ice remains, even up 2 layers, else, pass negative energy back in snow

            hice = h1 + h2

            # begin if_hice_block
            if hice > 0.:
                if h1 > 0.5 * hice:
                    stc1 = (1. - 2. * h2 / hice) * (stc0 + LI*TFI/ \
                            (CI*stc0)) + 2. * h2 / hice * stc1

                    if stc1 > TFI:
                        hice = hice - h2 * CI * (stc1 - TFI) / (LI * delt)
                        stc1 = TFI

                else:
                    stc0 = 2.*h1/hice*(stc0 + LI*TFI/ \
                            (CI*stc0)) + (1. - 2.*h1/hice)*stc1
                    stc0 = (stc0 -
                            (stc0 * stc0 - 4.0 * TFI * LI / CI)**0.5) * 0.5

                gflux = KI4 * KS / (KS * hice + KI4 * snowd) * (stc0 - tice)

            else:
                snowd = snowd + (h1*(CI*(stc0 - TFI)\
                        - LI*(1. - TFI/stc0)) + h2*(CI*\
                        (stc1 - TFI) - LI)) / LI
                hice = snowd * DSDI if snowd * DSDI < 0. else 0.
                snowd = 0.
                stc0 = TFW
                stc1 = TFW
                gflux = 0.

            gflux = fice * gflux
            snowmt = snowmt * DSDW
            snowd = snowd * DSDW
            tice = tice + T0C
            stc0 = stc0 + T0C
            stc1 = stc1 + T0C

            #  --- ...  convert snow depth back to mm of water equivalent

            snowd = snowd * 1000.
            snwdph = snowd * DSI  # snow depth in mm
Пример #16
0
def copy_stencil(in_field: gtscript.Field[float],
                 out_field: gtscript.Field[float]):
    from __gtscript__ import computation, interval, PARALLEL

    with computation(PARALLEL), interval(...):
        out_field = in_field