Isis 3 Programmer Reference
Anisotropic1.cpp
1 #include <cmath>
2 #include "Anisotropic1.h"
3 #include "AtmosModel.h"
4 #include "IException.h"
5 #include "IString.h"
6 
7 using std::max;
8 
9 namespace Isis {
16  Anisotropic1::Anisotropic1(Pvl &pvl, PhotoModel &pmodel) : AtmosModel(pvl, pmodel) {
17 
18  // Set default values
19  p_atmosAlpha0_0 = 0.0;
20  p_atmosAlpha1_0 = 0.0;
21  p_atmosBeta0_0 = 0.0;
22  p_atmosBeta1_0 = 0.0;
23  p_atmosDelta_0 = 0.0;
24  p_atmosDelta_1 = 0.0;
25  p_atmosDen = 0.0;
26  p_atmosE2 = 0.0;
27  p_atmosE3 = 0.0;
28  p_atmosE4 = 0.0;
29  p_atmosE5 = 0.0;
30  p_atmosFac = 0.0;
31  p_atmosP0 = 0.0;
32  p_atmosP1 = 0.0;
33  p_atmosQ0 = 0.0;
34  p_atmosQ02p02 = 0.0;
35  p_atmosQ1 = 0.0;
36  p_atmosQ12p12 = 0.0;
37  p_atmosWha2 = 0.0;
38  p_atmosWham = 0.0;
39  p_atmosX0_0 = 0.0;
40  p_atmosX0_1 = 0.0;
41  p_atmosY0_0 = 0.0;
42  p_atmosY0_1 = 0.0;
43 
44  }
45 
72  void Anisotropic1::AtmosModelAlgorithm(double phase, double incidence, double emission) {
73  double hpsq1;
74  double munot, munotp;
75  double maxval;
76  double mu, mup;
77  double xx;
78  double emunot, emu;
79  double gmunot, gmu;
80  double sum, prod;
81  double cosazss;
82  double xmunot_0, ymunot_0;
83  double xmu_0, ymu_0;
84  double xmunot_1, ymunot_1;
85  double xmu_1, ymu_1;
86  double cxx, cyy;
87  double xystuff;
88 
89  if(p_atmosBha == 0.0) {
90  p_atmosBha = 1.0e-6;
91  }
92 
93  if(p_atmosTau == 0.0) {
94  p_pstd = 0.0;
95  p_trans = 1.0;
96  p_trans0 = 1.0;
97  p_sbar = 0.0;
98  p_transs = 1.0;
99  return;
100  }
101 
102  if(p_atmosWha == 1.0) {
103  QString msg = "Anisotropic conservative case not implemented yet - WHA parameter cannot be set to 1.0";
104  msg += "This will cause negative planetary curvature to occur.";
106  }
107 
108  if(TauOrWhaChanged()) {
109  // preparation includes exponential integrals e sub 2 through 5
110  p_atmosWha2 = 0.5 * p_atmosWha;
111  p_atmosWham = 1.0 - p_atmosWha;
112  p_atmosE2 = AtmosModel::En(2, p_atmosTau);
113  p_atmosE3 = AtmosModel::En(3, p_atmosTau);
114  p_atmosE4 = AtmosModel::En(4, p_atmosTau);
115  p_atmosE5 = AtmosModel::En(5, p_atmosTau);
116  // first, get the required quantities for the axisymmetric m=0 part
117  // zeroth moments of (uncorrected) x and y times characteristic fn
118  p_atmosX0_0 = p_atmosWha2 * (1.0 + (1.0 / 3.0) * p_atmosBha *
119  p_atmosWham);
120  p_atmosY0_0 = p_atmosWha2 * (p_atmosE2 + p_atmosBha * p_atmosWham *
121  p_atmosE4);
122  // higher-order correction term for x and y
123  p_atmosDelta_0 = (1.0 - (p_atmosX0_0 + p_atmosY0_0) - (1.0 - p_atmosWha *
124  (1.0 + (1.0 / 3.0) * p_atmosBha * p_atmosWham)) / (1.0 -
125  (p_atmosX0_0 - p_atmosY0_0))) / (p_atmosWha * (0.5 - p_atmosE3 +
126  p_atmosBha * p_atmosWham * (0.25 - p_atmosE5)));
127 
128  // moments of (corrected) x and y
129  p_atmosAlpha0_0 = 1.0 + p_atmosDelta_0 * (0.5 - p_atmosE3);
130  p_atmosAlpha1_0 = 0.5 + p_atmosDelta_0 * ((1.0 / 3.0) - p_atmosE4);
132  p_atmosBeta1_0 = p_atmosE3 + p_atmosDelta_0 * ((1.0 / 3.0) - p_atmosE4);
133  // gamma will be a weighted sum of m=0 x and y functions
134  // but unlike before, call the weights q1 and p1, and we also
135  // need additional weights q0 and p0
136  p_atmosFac = 2.0 - p_atmosWha * p_atmosAlpha0_0;
137  p_atmosDen = pow(p_atmosFac, 2.0) - pow(p_atmosWha * p_atmosBeta0_0, 2.0);
138  p_atmosQ0 = p_atmosBha * p_atmosWha * p_atmosWham * (p_atmosFac *
139  p_atmosAlpha1_0 - p_atmosWha * p_atmosBeta0_0 * p_atmosBeta1_0) /
140  p_atmosDen;
141  p_atmosP0 = p_atmosBha * p_atmosWha * p_atmosWham * (-p_atmosFac *
142  p_atmosBeta1_0 - p_atmosWha * p_atmosBeta0_0 * p_atmosAlpha1_0) /
143  p_atmosDen;
146  p_atmosP1 = (2.0 * p_atmosWham * p_atmosWha * p_atmosBeta0_0) /
147  p_atmosDen;
149  // sbar is total diffuse illumination and comes from moments
150  p_sbar = 1.0 - 2.0 * (p_atmosQ1 * p_atmosAlpha1_0 + p_atmosP1 *
152  // we're not done yet! still have to calculate the m=1 portion
153  // zeroth moments of (uncorrected) x and y times characteristic fn
154  p_atmosX0_1 = 0.5 * p_atmosWha2 * p_atmosBha * (1.0 - (1.0 / 3.0));
155  p_atmosY0_1 = 0.5 * p_atmosWha2 * p_atmosBha * (p_atmosE2 - p_atmosE4);
156  // higher-order correction term for x and y
157  p_atmosDelta_1 = (1.0 - (p_atmosX0_1 + p_atmosY0_1) - (1.0 -
158  (1.0 / 3.0) * p_atmosWha * p_atmosBha) / (1.0 - (p_atmosX0_1 -
159  p_atmosY0_1))) / (p_atmosWha2 * p_atmosBha * ((0.5 - 0.25) -
160  (p_atmosE3 - p_atmosE5)));
161  // moments of (corrected) x and y are not needed for m=1, so we're done
162  SetOldTau(p_atmosTau);
163  SetOldWha(p_atmosWha);
164  }
165 
166  // correct the path lengths for planetary curvature
167  hpsq1 = pow((1.0 + p_atmosHnorm), 2.0) - 1.0;
168 
169  if(incidence == 90.0) {
170  munot = 0.0;
171  }
172  else {
173  munot = cos((PI / 180.0) * incidence);
174  }
175 
176  maxval = max(1.0e-30, hpsq1 + munot * munot);
177  munotp = p_atmosHnorm / (sqrt(maxval) - munot);
178  munotp = max(munotp, p_atmosTau / 69.0);
179  if(emission == 90.0) {
180  mu = 0.0;
181  }
182  else {
183  mu = cos((PI / 180.0) * emission);
184  }
185 
186  maxval = max(1.0e-30, hpsq1 + mu * mu);
187  mup = p_atmosHnorm / (sqrt(maxval) - mu);
188  mup = max(mup, p_atmosTau / 69.0);
189  // build the x and y functions of mu0 and mu
190  maxval = max(1.0e-30, munotp);
191  xx = -p_atmosTau / maxval;
192 
193  if(xx < -69.0) {
194  emunot = 0.0;
195  }
196  else if(xx > 69.0) {
197  emunot = 1.0e30;
198  }
199  else {
200  emunot = exp(-p_atmosTau / munotp);
201  }
202 
203  maxval = max(1.0e-30, mup);
204  xx = -p_atmosTau / maxval;
205 
206  if(xx < -69.0) {
207  emu = 0.0;
208  }
209  else if(xx > 69.0) {
210  emu = 1.0e30;
211  }
212  else {
213  emu = exp(-p_atmosTau / mup);
214  }
215 
216  // first for m=0
217  xmunot_0 = 1.0 + p_atmosDelta_0 * munotp * (1.0 - emunot);
218  ymunot_0 = emunot + p_atmosDelta_0 * munotp * (1.0 - emunot);
219  xmu_0 = 1.0 + p_atmosDelta_0 * mup * (1.0 - emu);
220  ymu_0 = emu + p_atmosDelta_0 * mup * (1.0 - emu);
221 
222  // then for m=1
223  xmunot_1 = 1.0 + p_atmosDelta_1 * munotp * (1.0 - emunot);
224  ymunot_1 = emunot + p_atmosDelta_1 * munotp * (1.0 - emunot);
225  xmu_1 = 1.0 + p_atmosDelta_1 * mup * (1.0 - emu);
226  ymu_1 = emu + p_atmosDelta_1 * mup * (1.0 - emu);
227 
228  // gamma1 functions come from x and y with m=0
229  gmunot = p_atmosP1 * xmunot_0 + p_atmosQ1 * ymunot_0;
230  gmu = p_atmosP1 * xmu_0 + p_atmosQ1 * ymu_0;
231 
232  // purely atmos term uses x and y of both orders and is complex
233  sum = munot + mu;
234  prod = munot * mu;
235  cxx = 1.0 - p_atmosQ0 * sum + (p_atmosQ02p02 - p_atmosBha *
236  p_atmosQ12p12) * prod;
237  cyy = 1.0 + p_atmosQ0 * sum + (p_atmosQ02p02 - p_atmosBha *
238  p_atmosQ12p12) * prod;
239 
240  if(phase == 90.0) {
241  cosazss = 0.0 - munot * mu;
242  }
243  else {
244  cosazss = cos((PI / 180.0) * phase) - munot * mu;
245  }
246 
247  xystuff = cxx * xmunot_0 * xmu_0 - cyy * ymunot_0 *
248  ymu_0 - p_atmosP0 * sum * (xmu_0 * ymunot_0 + ymu_0 *
249  xmunot_0) + cosazss * p_atmosBha * (xmu_1 *
250  xmunot_1 - ymu_1 * ymunot_1);
251  p_pstd = 0.25 * p_atmosWha * munotp / (munotp + mup) * xystuff;
252 
253  // xmitted surface term uses gammas from m=0
254  p_trans = gmunot * gmu;
255 
256  // finally, never-scattered term is given by pure attenuation
257  p_trans0 = emunot * emu;
258 
259  // Calculate the transmission of light that must be subtracted from a
260  // shadow. This includes direct flux and the scattered flux in the
261  // upsun half of the sky downwelling onto the surface, and the usual
262  // transmission upward. NOTE: We need to derive the analytic expression
263  // for the light from half the sky in the Legendre scattering model. Until
264  // we do so, we are setting the shadow transmission to the purely
265  // unscattered part (same as trans0). This will give a result but is
266  // not fully consistent with how the other scattering models are
267  // implemented.
268  p_transs = p_trans0;
269  }
270 }
271 
272 extern "C" Isis::AtmosModel *Anisotropic1Plugin(Isis::Pvl &pvl, Isis::PhotoModel &pmodel) {
273  return new Isis::Anisotropic1(pvl, pmodel);
274 }
double p_atmosWham
???
Definition: Anisotropic1.h:78
double p_atmosHnorm
Atmospheric shell thickness normalized to planet radius.
Definition: AtmosModel.h:283
double p_trans0
Transmission of surface reflected light through the atmosphere with no scatterings in the atmosphere...
Definition: AtmosModel.h:276
const double PI
The mathematical constant PI.
Definition: Constants.h:56
double p_atmosX0_0
???
Definition: Anisotropic1.h:79
Anisotropic1(Pvl &pvl, PhotoModel &pmodel)
Constructs an Anisotropic1 object.
bool TauOrWhaChanged() const
Checks whether tau or wha have changed.
Definition: AtmosModel.cpp:948
double p_atmosQ0
???
Definition: Anisotropic1.h:85
double p_atmosE5
???
Definition: Anisotropic1.h:70
double p_atmosE2
???
Definition: Anisotropic1.h:67
double p_atmosDelta_1
???
Definition: Anisotropic1.h:72
double p_trans
Transmission of surface reflected light through the atmosphere overall.
Definition: AtmosModel.h:275
Isotropic atmos scattering model.
Definition: AtmosModel.h:76
double p_atmosDen
???
Definition: Anisotropic1.h:84
double p_atmosBeta0_0
???
Definition: Anisotropic1.h:75
double p_sbar
Illumination of the ground by the sky.
Definition: AtmosModel.h:278
static double En(unsigned int n, double x)
This routine evaluates the generalized exponential integral, En(x).
Definition: AtmosModel.cpp:364
double p_atmosAlpha1_0
???
Definition: Anisotropic1.h:74
double p_atmosBeta1_0
???
Definition: Anisotropic1.h:76
virtual void AtmosModelAlgorithm(double phase, double incidence, double emission)
Anisotropic atmospheric scattering with P1 single-particle phase fn, in the second approximation...
double p_atmosX0_1
???
Definition: Anisotropic1.h:81
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:142
double p_atmosFac
???
Definition: Anisotropic1.h:83
double p_atmosAlpha0_0
???
Definition: Anisotropic1.h:73
double p_atmosY0_1
???
Definition: Anisotropic1.h:82
Container for cube-like labels.
Definition: Pvl.h:135
double p_atmosQ12p12
???
Definition: Anisotropic1.h:90
double p_transs
Transmission of light that must be subtracted from the flat surface model to get the shadow model...
Definition: AtmosModel.h:277
double p_pstd
Pure atmospheric-scattering term.
Definition: AtmosModel.h:274
double p_atmosP1
???
Definition: Anisotropic1.h:88
double p_atmosQ02p02
???
Definition: Anisotropic1.h:89
Isis exception class.
Definition: IException.h:107
double p_atmosE4
???
Definition: Anisotropic1.h:69
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
double p_atmosE3
???
Definition: Anisotropic1.h:68
double p_atmosWha2
???
Definition: Anisotropic1.h:77
double p_atmosP0
???
Definition: Anisotropic1.h:87
double p_atmosDelta_0
???
Definition: Anisotropic1.h:71
double p_atmosQ1
???
Definition: Anisotropic1.h:86
double p_atmosY0_0
???
Definition: Anisotropic1.h:80