PLUTO
comp_equil.c
Go to the documentation of this file.
1 /* ///////////////////////////////////////////////////////////////////// */
2 /*!
3  \file
4  \brief Compute equilibrium fractions for the H2_COOL module.
5 
6  Compute the equilibrium fractions of atomic and molecular hydrogen
7  for a given density and temperature (Collisional Excitation
8  Equlibrium or CIE).
9  This corresponds to the simultaneous solution of the three
10  rate equations
11 
12  R_HI (f,h,g) = 0
13  R_HII(f,h,g) = 0
14  R_H2 (f,h,g) = 0
15 
16  where f = X(HI), h = X(HII), g = X(H2) are the number fraction of
17  atomic, ionized and molecular hydrogen, respectively.
18  The functions R_HI, R_HII and R_H2 are given in radiat.c.
19  The previous system is reduced to a single scalar equation in either
20  f or h by using h = ci/cr*f and the normalization condition
21  g = (1-h-f)/2.
22  A maple script can be found at the end of this file.
23  The final equation is a quadratic,
24 
25  a*f^2 + b*f + c = 0
26 
27  and we have verified that the solution with the - sign is the physical
28  acceptable one since 0 <= f <= 1 for any T.
29 
30  Note that the solution for g at very large temperatures may suffer
31  from machine precision when g becomes very small (g < 1.e-19).
32  Using long double for the coefficients of the quadratic helps
33  a little bit.
34 
35  \authors A. Mignone (mignone@ph.unito.it)\n
36  B. Vaidya
37 
38  \date March 1, 2015
39 */
40 /* ///////////////////////////////////////////////////////////////////// */
41 #include "pluto.h"
42 
43 /* ********************************************************************* */
44 void CompEquil(double n, double T, double *v)
45 /*!
46  * \param [in] n the particle number density (not needed, but
47  * kept for compatibility)
48  * \param [in] T the temperature (in K) for which equilibrium must
49  * be found.
50  * \param [in,out] v an array of primitive variables.
51  * On input, only density needs to be defined.
52  * On output, fractions will be updated to the
53  * equilibrium values.
54  *
55  *********************************************************************** */
56 {
57  double cr, ci, kr1, kr2, kr3, kr4;
58  double frac_Z, st, tev;
59  long double a, b, c, qc, scrh, az;
60  long double f, h, g;
61  double krv[9];
62 
63  H2RateTables(T, krv);
64  kr1 = krv[0];
65  kr2 = krv[1];
66  kr3 = krv[2];
67  kr4 = krv[3];
68  cr = krv[4];
69  ci = krv[5];
70 
71  kr2 /= kr1;
72  kr3 /= kr1;
73  kr4 /= kr1;
74  kr1 = 1.0;
75  frac_Z = ((1.0 - H_MASS_FRAC - He_MASS_FRAC)/CONST_AZ)*(CONST_AH/H_MASS_FRAC);
76 
77  az = 0.5*CONST_AZ*frac_Z;
78 
79 /* ---------------------------------------------------
80  Solve quadratic equation for fn or hn.
81  The solution depends only on temperature and the
82  physical solution is the one with - sign.
83  --------------------------------------------------- */
84 
85  if (T < 1.e16) { /* Solve for fn */
86  qc = ci/cr;
87  scrh = -0.5*(1.0 + qc);
88  a = (long double)(scrh*(kr2 + kr3*scrh + kr4*qc) - kr1);
89  b = (long double)( 0.5*(kr2 + kr3*scrh + kr4*qc + scrh*(kr3 + 2.0*kr4*az)));
90  c = (long double)(0.5*(0.5*kr3 + kr4*az));
91 
92  /* ------------------------------------------
93  Set fn = 0.0 below T = 300 K to prevent
94  machine accuracy problems
95  ------------------------------------------ */
96 
97  if (T > 300.0){
98  if (b >= 0.0) f = -(b + sqrtl(b*b - 4.0*a*c))/(2.0*a);
99  else f = 2.0*c/(sqrtl(b*b - 4.0*a*c) - b);
100  }else{
101  f = 0.0;
102  }
103  h = qc*f;
104  g = 0.5*(1.0 - f*(1.0 + qc));
105 
106  /* -- Set g = 0 if we are close to machine accuracy -- */
107 
108 /* if ( fabs(1.0 - h - f) < 1.e-15) g = 0.0; */
109 
110  }else{ /* Solve for hn */
111 
112  qc = cr/ci;
113  scrh = -0.5*(1.0 + qc);
114  a = scrh*(kr2*qc + kr3*scrh + kr4) - kr1*qc*qc;
115  b = 0.5*(kr2*qc + kr3*scrh + kr4 + scrh*(kr3 + 2.0*kr4*az));
116  c = 0.5*(0.5*kr3 + kr4*az);
117  h = -(b + sqrtl(b*b - 4.0*a*c))/(2.0*a);
118  f = qc*h;
119  g = 0.5*(1.0 - h*(1.0 + qc));
120  }
121 
122  v[X_HI] = f;
123  v[X_HII] = h;
124  v[X_H2] = g;
125 }
126 
127 /*
128 ########################################################################
129 # CIE solution for the H2COOL cooling module.
130 # Reduce the three rate equations to one scalar equation by using
131 # the third one (h = ci/cr)*f and the normalization condition.
132 # Solve for f
133 ########################################################################
134 restart;
135 h := ci*f/cr;
136 x := h + az;
137 g := (1 - h - f)/2;
138 
139 RI := (g*(k2*f + k3*g + k4*x) + cr*h*x - f*(ci*x + k1*f));
140 
141 coeff(RI,f,2);
142 coeff(RI,f,1);
143 coeff(RI,f,0);
144 
145 ########################################################################
146 # Same as before but solve for h
147 ########################################################################
148 restart;
149 f := cr*h/ci;
150 x := h + az;
151 g := (1 - h - f)/2;
152 
153 RI := (g*(k2*f + k3*g + k4*x) + cr*h*x - f*(ci*x + k1*f));
154 
155 coeff(RI,h,2);
156 coeff(RI,h,1);
157 coeff(RI,h,0);
158 
159 ########################################################################
160 # Same as before but solve for g
161 ########################################################################
162 restart;
163 f := (1 - 2*g)/alpha; #(1 + ci/cr);
164 h := ci*f/cr;
165 x := h + az;
166 
167 RI := (g*(k2*f + k3*g + k4*x) + cr*h*x - f*(ci*x + k1*f));
168 
169 coeff(RI,g,2);
170 coeff(RI,g,1);
171 coeff(RI,g,0);
172 */
173 
174 
175 
static double a
Definition: init.c:135
tuple T
Definition: Sph_disk.py:33
static int n
Definition: analysis.c:3
#define CONST_AH
Definition: pluto.h:250
tuple scrh
Definition: configure.py:200
void CompEquil(double n, double T, double *v)
Definition: comp_equil.c:44
#define frac_Z
Definition: cooling.h:15
#define He_MASS_FRAC
Definition: pluto.h:551
#define X_HII
Definition: cooling.h:31
#define CONST_AZ
Mean atomic weight of heavy elements.
Definition: pluto.h:252
Definition: cooling.h:110
tuple c
Definition: menu.py:375
PLUTO main header file.
#define X_H2
Definition: cooling.h:30
#define H_MASS_FRAC
Definition: pluto.h:542
void H2RateTables(double, double *)
Definition: radiat.c:7