7 #include "NumericalApproximation.h" 14 HapkeAtm2::HapkeAtm2(Pvl &pvl, PhotoModel &pmodel) : AtmosModel(pvl, pmodel) {
63 double f1munot, f1mmunot;
64 double xmunot, ymunot;
73 if(p_atmosTau == 0.0) {
85 p_wha2 = 0.5 * p_atmosWha;
104 p_f1m = log(2.0) - p_em * p_e1 + p_e1_2;
105 p_f2m = -1.0 * (p_f1m + p_em * p_e2 - 1.0);
106 p_f3m = -1.0 * (p_f2m + p_em * p_e3 - 0.5);
107 p_g12 = (p_atmosTau * p_e1 * p_e2 + p_f1m + p_f2m) * 0.5;
108 p_g13 = (p_atmosTau * p_e1 * p_e3 + p_f1m + p_f3m) * (1.0 / 3.0);
122 p_f1 = Eulgam() + log(p_atmosTau) + p_e * p_e1;
123 p_f2 = p_f1 + p_e * p_e2 - 1.0;
124 p_f3 = p_f2 + p_e * p_e3 - 0.5;
126 p_g12p = (p_atmosTau * (p_e1 - p_g11p) + p_em * (p_f1 + p_f2)) * 0.25;
127 p_g13p = (p_atmosTau * (0.5 * p_e1 - p_g12p) + p_em * (p_f1 + p_f3)) * 0.2;
130 p_x0 = p_wha2 * (1.0 + p_wha2 * p_g12);
131 p_y0 = p_wha2 * (p_e2 + p_wha2 * p_g12p);
134 p_delta = (1.0 - (p_x0 + p_y0) - (1.0 - p_atmosWha) / (1.0 - (p_x0 - p_y0))) / (p_atmosWha * (0.5 - p_e3));
137 p_alpha0 = 1.0 + p_wha2 * p_g12 + p_delta * (0.5 - p_e3);
138 p_alpha1 = 0.5 + p_wha2 * p_g13 + p_delta * ((1.0 / 3.0) - p_e4);
139 p_beta0 = p_e2 + p_wha2 * p_g12p + p_delta * (0.5 - p_e3);
140 p_beta1 = p_e3 + p_wha2 * p_g13p + p_delta * ((1.0 / 3.0) - p_e4);
143 if(p_atmosWha == 1.0) {
145 p_f4m = -1.0 * (p_f3m + p_em * p_e4 - (1.0 / 3.0));
146 p_g14 = (p_atmosTau * p_e1 * p_e4 + p_f1m + p_f4m) * 0.25;
147 p_f4 = p_f3 + p_e * p_e4 - (1.0 / 3.0);
148 p_g14p = (p_atmosTau * (0.5 * p_e1 - p_g13p) + p_em * (p_f1 + p_f4)) * (1.0 / 6.0);
149 p_alpha2 = (1.0 / 3.0) + p_wha2 * p_g14 + p_delta * (0.25 - p_e5);
150 p_beta2 = p_e4 + p_wha2 * p_g14p + p_delta * (0.25 - p_e5);
151 p_fixcon = (p_beta0 * p_atmosTau - p_alpha1 + p_beta1) /
152 ((p_alpha1 + p_beta1) * p_atmosTau + 2.0 * (p_alpha2 + p_beta2));
156 p_gammax = p_wha2 * p_beta0;
157 p_gammay = 1.0 - p_wha2 * p_alpha0;
166 p_sbar = 1.0 - ((2.0 - p_atmosWha * p_alpha0) * p_alpha1 + p_atmosWha * p_beta0 * p_beta1) + p_atmosHahgsb;
168 SetOldTau(p_atmosTau);
169 SetOldWha(p_atmosWha);
174 munot = cos((
PI / 180.0) * incidence);
175 maxval = max(1.0e-30, hpsq1 + munot * munot);
177 munotp = max(munotp, p_atmosTau / 69.0);
178 mu = cos((
PI / 180.0) * p_emission);
179 maxval = max(1.0e-30, hpsq1 + mu * mu);
181 mup = max(mup, p_atmosTau / 69.0);
184 maxval = max(1.0e-30, munotp);
185 xx = -p_atmosTau / maxval;
194 p_emunot = exp(-p_atmosTau / munotp);
197 maxval = max(1.0e-30, mup);
198 xx = -p_atmosTau / maxval;
206 emu = exp(-p_atmosTau / mup);
211 if(fabs(xx - 1.0) < 1.0e-10) {
213 f1mmunot = xx * (log(1.0 + 1.0 / xx) - p_e1 * p_emunot +
AtmosModel::En(1, p_atmosTau * (1.0 + 1.0 / xx)));
216 f1munot = xx * (log(xx / (1.0 - xx)) + p_e1 / p_emunot +
AtmosModel::Ei(p_atmosTau * (1.0 / xx - 1.0)));
217 f1mmunot = xx * (log(1.0 + 1.0 / xx) - p_e1 * p_emunot +
AtmosModel::En(1, p_atmosTau * (1.0 + 1.0 / xx)));
220 std::string msg =
"Negative length of planetary curvature ";
221 msg +=
"encountered";
226 if(fabs(xx - 1.0) < 1.0e-10) {
228 f1mmu = xx * (log(1.0 + 1.0 / xx) - p_e1 * emu +
AtmosModel::En(1, p_atmosTau * (1.0 + 1.0 / xx)));
231 f1mu = xx * (log(xx / (1.0 - xx)) + p_e1 / emu +
AtmosModel::Ei(p_atmosTau * (1.0 / xx - 1.0)));
232 f1mmu = xx * (log(1.0 + 1.0 / xx) - p_e1 * emu +
AtmosModel::En(1, p_atmosTau * (1.0 + 1.0 / xx)));
235 std::string msg =
"Negative length of planetary curvature ";
236 msg +=
"encountered";
240 xmunot = 1.0 + p_wha2 * f1mmunot + p_delta * munotp * (1.0 - p_emunot);
241 ymunot = p_emunot * (1.0 + p_wha2 * f1munot) + p_delta * munotp * (1.0 - p_emunot);
242 xmu = 1.0 + p_wha2 * f1mmu + p_delta * mup * (1.0 - emu);
243 ymu = emu * (1.0 + p_wha2 * f1mu) + p_delta * mup * (1.0 - emu);
246 if(p_atmosWha == 1.0) {
247 fix = p_fixcon * munotp * (xmunot + ymunot);
248 xmunot = xmunot + fix;
249 ymunot = ymunot + fix;
250 fix = p_fixcon * mup * (xmu + ymu);
261 p_atmosAtmSwitch = 1;
263 p_atmosInc = incidence;
264 p_atmosMunot = cos((
PI / 180.0) * incidence);
265 p_atmosSini = sin((
PI / 180.0) * incidence);
267 gmunot = p_gammax * xmunot + p_gammay * ymunot + hahgt *
AtmosWha() / 360.0;
268 p_atmosInc = p_emission;
269 p_atmosMunot = cos((
PI / 180.0) * p_emission);
270 p_atmosSini = sin((
PI / 180.0) * p_emission);
272 gmu = p_gammax * xmu + p_gammay * ymu + hahgt *
AtmosWha() / 360.0;
275 gmunot = p_gammax * xmunot + p_gammay * ymunot + hahgt;
277 gmu = p_gammax * xmu + p_gammay * ymu + hahgt;
282 phasefn = (1.0 - p_atmosHga * p_atmosHga) / pow(1.0 + 2.0 * p_atmosHga *
283 cos((
PI / 180.0) * phase) + p_atmosHga * p_atmosHga, 1.5);
284 p_pstd = 0.25 * p_atmosWha * munotp / (munotp + mup) * ((xmunot * xmu - ymunot * ymu) +
285 (phasefn - 1.0) * (1.0 - emu * p_emunot));
297 p_atmosAtmSwitch = 3;
299 p_atmosInc = incidence;
300 p_atmosMunot = cos((
PI / 180.0) * incidence);
301 p_atmosSini = sin((
PI / 180.0) * incidence);
303 hahgt0 = hahgt0 *
AtmosWha() * p_atmosMunot / (360.0 * p_atmosSini);
307 p_trans0 = (p_emunot + hahgt0) * emu;
316 p_atmosAtmSwitch = 1;
319 hahgt = .5 * (p_gammax * xmunot + p_gammay * ymunot - p_emunot) + hahgt *
324 p_transs = (p_emunot + hahgt) * emu;
static double G11Prime(double tau)
Perform Chandra and Van de Hulst's series approximation for the g'11 function needed in second order ...
double p_atmosHnorm
Atmospheric shell thickness normalized to planet radius.
double p_trans0
Transmission of surface reflected light through the atmosphere with no scatterings in the atmosphere...
NumericalApproximation p_atmosHahgt0Spline
Spline object for the atmospheric Hahg0 Table. Properties are set in GenerateHahgTables().
Indicates that Romberg's method will integrate the function OutrFunc2Bint()
bool p_atmosEstTau
Estimate optical depth tau using shadows.
NumericalApproximation p_atmosHahgtSpline
Spline object for the atmospheric Hahg Table. Properties are set in GenerateHahgTables().
const double PI
The mathematical constant PI.
bool TauOrWhaChanged() const
Checks whether tau or wha have changed.
double p_trans
Transmission of surface reflected light through the atmosphere overall.
Isotropic atmos scattering model.
void GenerateHahgTablesShadow()
This method is a modified version of the GenerateHahgTables method and is used solely for shadow mode...
double Evaluate(const double a, const ExtrapType &etype=ThrowError)
Calculates interpolated or extrapolated value of tabulated data set for given domain value...
double p_sbar
Illumination of the ground by the sky.
static double En(unsigned int n, double x)
This routine evaluates the generalized exponential integral, En(x).
double RombergsMethod(AtmosModel *am, IntegFunc sub, double a, double b)
This variation on the NumericalApproximation method integrates a specified AtmosModel function rather...
void Reset()
Resets the state of the object.
#define _FILEINFO_
Macro for the filename and line number.
A type of error that cannot be classified as any of the other error types.
virtual void AtmosModelAlgorithm(double phase, double incidence, double emission)
Henyey-Greenstein atmos scattering in the 1st approximation.
Container for cube-like labels.
static double Ei(double x)
This routine computes the exponential integral, Ei(x).
double p_transs
Transmission of light that must be subtracted from the flat surface model to get the shadow model...
double p_pstd
Pure atmospheric-scattering term.
IntegFunc
This enum defines function to be integrated by Romberg's method.
Namespace for ISIS/Bullet specific routines.
double AtmosWha() const
Return atmospheric Wha value.
Evaluate() attempts to extrapolate if a is outside of the domain. This is only valid for NumericalApp...
This class extends Isis::NumericalApproximation.
void GenerateHahgTables()
This method computes the values of the atmospheric Hahg and Hahg0 tables and sets the properties of t...