Canoe
Comprehensive Atmosphere N' Ocean Engine
try_equilibrium_tp_vapor_cloud.cpp
Go to the documentation of this file.
1 // C/C++
2 #include <algorithm>
3 
4 // canoe
5 #include <air_parcel.hpp>
6 
7 // snap
8 #include "thermodynamics.hpp"
9 
10 // Calculates phase equilibrium of
11 // Vapor <=> Cloud
12 //
13 // Example phase equilibrium:
14 // H2O -> H2O(l)
15 //
17  int i, Real cv_hat,
18  bool misty) const {
19  Real xv = qfrac.w[i], xg = 1. - xv;
20  Real t = qfrac.w[IDN] / t3_[i];
21  std::vector<Real> rates(1 + cloud_index_set_[i].size(), 0.);
22 
23 #pragma omp simd reduction(+ : xg)
24  for (int n = 0; n < NCLOUD; ++n) xg += -qfrac.c[n];
25 
26  for (int n = 0; n < cloud_index_set_[i].size(); ++n) {
27  int j = cloud_index_set_[i][n];
28  Real xs = svp_func1_[i][n](qfrac, i, j) / qfrac.w[IPR];
29  Real xc = qfrac.c[j];
30 
31  if (misty) { // in a cloudy ambient environment
32  rates[0] += xs - xv / (xg + xv);
33  continue;
34  }
35 
36  // if saturation vapor pressure is larger than the total pressure
37  // evaporate all condensates
38  if (xs > 1.) {
39  rates[0] += xc;
40  rates[1 + n] = -xc;
41  continue;
42  }
43 
44  Real alpha = 0.;
45 
46  Real lv = beta_[1 + NVAPOR + j] / t - delta_[1 + NVAPOR + j];
47  if (cv_hat > 0.) alpha = (lv - 1.) / cv_hat;
48 
49  Real s1 = xs / (1. - xs);
50  Real rate = (s1 * xg - xv) / (1. + alpha * xg * lv * s1 / (1. - xs));
51 
52  // condensate at most xv vapor
53  if (rate < 0.) {
54  rates[0] += -std::min(-rate, xv);
55  rates[1 + n] = std::min(-rate, xv);
56  }
57 
58  // evaporate at most xc cloud
59  if (rate > 0.) {
60  rates[0] += std::min(rate, xc);
61  rates[1 + n] = -std::min(rate, xc);
62  }
63  }
64 
65  // scale total rate
66  if (rates[0] < 0. && std::abs(rates[0]) > xv) {
67  Real r = xv / std::abs(rates[0]);
68  for (auto& rate : rates) rate *= r;
69  }
70 
71  return rates;
72 }
Real *const w
Definition: air_parcel.hpp:36
Real *const c
cloud data
Definition: air_parcel.hpp:39
RealArrayX TryEquilibriumTP_VaporCloud(AirParcel const &qfrac, int ivapor, Real cv_hat=0., bool misty=false) const
Calculate the equilibrium mole transfer by cloud reaction vapor -> cloud.
std::array< Real, Size > beta_
Dimensionless latent heat.
std::vector< IndexSet > cloud_index_set_
cloud index set
SVPFunc1Container svp_func1_
saturation vapor pressure function: Vapor -> Cloud
std::array< Real, 1+NVAPOR > t3_
triple point temperature [K]
std::array< Real, Size > delta_
Dimensionless differences in specific heat capacity.
double min(double x1, double x2, double x3)
Definition: core.h:16
std::vector< Real > RealArrayX