Skip to main content
1 of 2
milancurcic
  • 5k
  • 1
  • 29
  • 41

I calculate surface visibility from WRF output using a calculation that I adapted from DTC's Unified Post Processor, specifically from their Fortran routine found in UPPV2.2/src/unipost/CALVIS.f. The calculation is based on hydrometeor mixing ratios, and air temperature and pressure, all from the lowest model layer. The documentation in the original code reads:

This routine computes horizontal visibility at the
surface or lowest model layer, from qc, qr, qi, and qs.  
qv--water vapor mixing ratio (kg/kg)
qc--cloud water mixing ratio (kg/kg)
qr--rain water mixing ratio  (kg/kg)
qi--cloud ice mixing ratio   (kg/kg)
qs--snow mixing ratio        (kg/kg)
tt--temperature              (k)
pp--pressure                 (Pa)

If iice=0:
   qprc=qr     qrain=qr and qclw=qc if T>0C
   qcld=qc          =0          =0  if T<0C
               qsnow=qs and qclice=qc  if T<0C
                    =0            =0   if T>0C
If iice=1:
   qprc=qr+qs   qrain=qr and qclw=qc
   qcld=qc+qi   qsnow=qs and qclice=qc

Independent of the above definitions, the scheme can use different
assumptions of the state of hydrometeors:
     meth='d': qprc is all frozen if T<0, liquid if T>0
     meth='b': Bocchieri scheme used to determine whether qprc
        is rain or snow. A temperature assumption is used to
        determine whether qcld is liquid or frozen.
     meth='r': Uses the four mixing ratios qrain, qsnow, qclw,
        and qclice

The routine uses the following
expressions for extinction coefficient, beta (in km**-1),
with C being the mass concentration (in g/m**3):

   cloud water:  beta = 144.7 * C ** (0.8800)
   rain water:   beta =  2.24 * C ** (0.7500)
   cloud ice:    beta = 327.8 * C ** (1.0000)
   snow:         beta = 10.36 * C ** (0.7776)

These expressions were obtained from the following sources:

   for cloud water: from Kunkel (1984)
   for rainwater: from M-P dist'n, with No=8e6 m**-4 and
      rho_w=1000 kg/m**3
   for cloud ice: assume randomly oriented plates which follow
      mass-diameter relationship from Rutledge and Hobbs (1983)
   for snow: from Stallabrass (1985), assuming beta = -ln(.02)/vis

The extinction coefficient for each water species present is
calculated, and then all applicable betas are summed to yield
a single beta. Then the following relationship is used to
determine visibility (in km), where epsilon is the threshhold
of contrast, usually taken to be .02:

   vis = -ln(epsilon)/beta      [found in Kunkel (1984)]

I have adapted the code from this routine to a Python function below, which you can use for your purposes:

def calculate_visibility(qv,qc,qr,qi,qs,T,p):
    """
    Calculates visibility based on the UPP algorithm.

    See documentation in UPPV2.2/src/unipost/CALVIS.f for the description of
    input arguments and references.
    """
    Rd = 287.
    COEFLC = 144.7
    COEFLP = 2.24
    COEFFC = 327.8
    COEFFP = 10.36
    EXPLC  = 0.88
    EXPLP  = 0.75
    EXPFC  = 1.
    EXPFP  = 0.7776

    Tv   = T * (1+0.61*qv) # Virtual temperature

    rhoa = p/(Rd*Tv) # Air density [kg m^-3]
    rhow = 1e3       # Water density [kg m^-3]
    rhoi = 0.917e3   # Ice density [kg m^-3]

    vovmd = (1+qv)/rhoa + (qc+qr)/rhow + (qi+qs)/rhoi

    conc_lc = 1e3*qc/vovmd
    conc_lp = 1e3*qr/vovmd
    conc_fc = 1e3*qi/vovmd
    conc_fp = 1e3*qs/vovmd

    # Make sure all concentrations are positive
    conc_lc[conc_lc < 0] = 0
    conc_lp[conc_lp < 0] = 0
    conc_fc[conc_fc < 0] = 0
    conc_fp[conc_fp < 0] = 0

    betav = COEFFC*conc_fc**EXPFC\
          + COEFFP*conc_fp**EXPFP\
          + COEFLC*conc_lc**EXPLC\
          + COEFLP*conc_lp**EXPLP+1E-10

    vis = -np.log(0.02)/betav # Visibility [km]
    vis[vis > 24.135] = 24.135

    return vis
milancurcic
  • 5k
  • 1
  • 29
  • 41