Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Secure .gov websites use HTTPS
A lock ( ) or https:// means you’ve safely connected to the .gov website. Share sensitive information only on official, secure websites.

Isis 3 Programmer Reference
Isotropic2.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include <cmath>
8#include "AtmosModel.h"
9#include "Isotropic2.h"
10#include "Pvl.h"
11#include "PvlGroup.h"
12#include "IException.h"
13#include "IString.h"
14
15using std::min;
16using std::max;
17
18namespace Isis {
19 Isotropic2::Isotropic2(Pvl &pvl, PhotoModel &pmodel) : AtmosModel(pvl, pmodel) {
20 }
21
62
63 void Isotropic2::AtmosModelAlgorithm(double phase, double incidence,
64 double emission) {
65 double xx;
66 double fix;
67 double hpsq1;
68 double munot, munotp;
69 double mu, mup;
70 double emu, emunot;
71 double f1munot, f1mmunot, f1mmu, f1mu;
72 double xmunot, ymunot;
73 double xmu, ymu;
74 double gmu, gmunot;
75 double maxval;
76
77 if(p_atmosTau == 0.0) {
78 p_pstd = 0.0;
79 p_trans = 1.0;
80 p_trans0 = 1.0;
81 p_sbar = 0.0;
82 p_transs = 1.0;
83 return;
84 }
85
86 if(TauOrWhaChanged()) {
87 // preparation includes exponential integrals p_e sub 2 through 4
88 p_wha2 = 0.5 * p_atmosWha;
89 p_e1 = AtmosModel::En(1, p_atmosTau);
90 p_e1_2 = AtmosModel::En(1, 2.0 * p_atmosTau);
91 p_e2 = AtmosModel::En(2, p_atmosTau);
92 p_e3 = AtmosModel::En(3, p_atmosTau);
93 p_e4 = AtmosModel::En(4, p_atmosTau);
94
95 // chandra's gmn functions require fm and fn at mu=-1
96 xx = -p_atmosTau;
97 if(xx < -69.0) {
98 p_em = 0.0;
99 }
100 else if(xx > 69.0) {
101 p_em = 1.0e30;
102 }
103 else {
104 p_em = exp(xx);
105 }
106 p_f1m = log(2.0) - p_em * p_e1 + p_e1_2;
107 p_f2m = -1.0 * (p_f1m + p_em * p_e2 - 1.0);
108 p_f3m = -1.0 * (p_f2m + p_em * p_e3 - 0.5);
109 p_g12 = (p_atmosTau * p_e1 * p_e2 + p_f1m + p_f2m) * 0.5;
110 p_g13 = (p_atmosTau * p_e1 * p_e3 + p_f1m + p_f3m) * (1.0 / 3.0);
111
112 // chandra's g'mn functions require g'11 and f at mu=1
113 xx = p_atmosTau;
114 if(xx < -69.0) {
115 p_e = 0.0;
116 }
117 else if(xx > 69.0) {
118 p_e = 1.0e30;
119 }
120 else {
121 p_e = exp(xx);
122 }
123
124 p_f1 = Eulgam() + log(p_atmosTau) + p_e * p_e1;
125 p_f2 = p_f1 + p_e * p_e2 - 1.0;
126 p_f3 = p_f2 + p_e * p_e3 - 0.5;
127 p_g11p = AtmosModel::G11Prime(p_atmosTau);
128 p_g12p = (p_atmosTau * (p_e1 - p_g11p) + p_em * (p_f1 + p_f2)) * 0.25;
129 p_g13p = (p_atmosTau * (0.5 * p_e1 - p_g12p) + p_em * (p_f1 + p_f3)) * 0.2;
130
131 // zeroth moments of (uncorrected) x and y times characteristic fn
132 p_x0 = p_wha2 * (1.0 + p_wha2 * p_g12);
133 p_y0 = p_wha2 * (p_e2 + p_wha2 * p_g12p);
134
135 // higher-order correction term for x and y
136 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
138 // moments of (corrected) x and y
139 p_alpha0 = 1.0 + p_wha2 * p_g12 + p_delta * (0.5 - p_e3);
140 p_alpha1 = 0.5 + p_wha2 * p_g13 + p_delta * ((1.0 / 3.0) - p_e4);
141 p_beta0 = p_e2 + p_wha2 * p_g12p + p_delta * (0.5 - p_e3);
142 p_beta1 = p_e3 + p_wha2 * p_g13p + p_delta * ((1.0 / 3.0) - p_e4);
143
144 // prepare to find correct mixture of x and y in conservative case
145 if(p_atmosWha == 1.0) {
146 p_e5 = AtmosModel::En(5, p_atmosTau);
147 p_f4m = -1.0 * (p_f3m + p_em * p_e4 - (1.0 / 3.0));
148 p_g14 = (p_atmosTau * p_e1 * p_e4 + p_f1m + p_f4m) * 0.25;
149 p_f4 = p_f3 + p_e * p_e4 - (1.0 / 3.0);
150 p_g14p = (p_atmosTau * (0.5 * p_e1 - p_g13p) + p_em * (p_f1 + p_f4)) * (1.0 / 6.0);
151 p_alpha2 = (1.0 / 3.0) + p_wha2 * p_g14 + p_delta * (0.25 - p_e5);
152 p_beta2 = p_e4 + p_wha2 * p_g14p + p_delta * (0.25 - p_e5);
153 p_fixcon = (p_beta0 * p_atmosTau - p_alpha1 + p_beta1) / ((p_alpha1 + p_beta1) * p_atmosTau + 2.0 * (p_alpha2 + p_beta2));
154 }
155
156 // gamma will be a weighted sum of x and y functions
157 p_gammax = p_wha2 * p_beta0;
158 p_gammay = 1.0 - p_wha2 * p_alpha0;
159
160 // sbar is total diffuse illumination and comes from moments
161 p_sbar = 1.0 - ((2.0 - p_atmosWha * p_alpha0) * p_alpha1 + p_atmosWha * p_beta0 * p_beta1);
162
163 SetOldTau(p_atmosTau);
164 SetOldWha(p_atmosWha);
165 }
166
167 // correct the path lengths for planetary curvature
168 hpsq1 = pow((1.0 + p_atmosHnorm), 2.0) - 1.0;
169 munot = cos((PI / 180.0) * incidence);
170 maxval = max(1.0e-30, hpsq1 + munot * munot);
171 munotp = p_atmosHnorm / (sqrt(maxval) - munot);
172 munotp = max(munotp, p_atmosTau / 69.0);
173 mu = cos((PI / 180.0) * emission);
174 maxval = max(1.0e-30, hpsq1 + mu * mu);
175 mup = p_atmosHnorm / (sqrt(maxval) - mu);
176 mup = max(mup, p_atmosTau / 69.0);
177
178 // build the x and y functions of mu0 and mu
179 xx = -p_atmosTau / max(munotp, 1.0e-30);
180 if(xx < -69.0) {
181 emunot = 0.0;
182 }
183 else if(xx > 69.0) {
184 emunot = 1.0e30;
185 }
186 else {
187 emunot = exp(-p_atmosTau / munotp);
188 }
189
190 xx = -p_atmosTau / max(mup, 1.0e-30);
191 if(xx < -69.0) {
192 emu = 0.0;
193 }
194 else if(xx > 69.0) {
195 emu = 1.0e30;
196 }
197 else {
198 emu = exp(-p_atmosTau / mup);
199 }
200
201 // in the second approximation the x and y include the p_f1 function
202 xx = munotp;
203 if(fabs(xx - 1.0) < 1.0e-10) {
204 f1munot = p_f1;
205 f1mmunot = xx * (log(1.0 + 1.0 / xx) - p_e1 * emunot +
206 AtmosModel::En(1, p_atmosTau * (1.0 + 1.0 / xx)));
207 }
208 else if(xx > 0.0) {
209 f1munot = xx * (log(xx / (1.0 - xx)) + p_e1 / emunot +
210 AtmosModel::Ei(p_atmosTau * (1.0 / xx - 1.0)));
211 f1mmunot = xx * (log(1.0 + 1.0 / xx) - p_e1 * emunot +
212 AtmosModel::En(1, p_atmosTau * (1.0 + 1.0 / xx)));
213 }
214 else {
215 std::string msg = "Negative length of planetary curvature ";
216 msg += "encountered";
217 throw IException(IException::Unknown, msg, _FILEINFO_);
218 }
219
220 xx = mup;
221 if(fabs(xx - 1.0) < 1.0e-10) {
222 f1mu = p_f1;
223 f1mmu = xx * (log(1.0 + 1.0 / xx) - p_e1 * emu + AtmosModel::En(1, p_atmosTau * (1.0 + 1.0 / xx)));
224 }
225 else if(xx > 0.0) {
226 f1mu = xx * (log(xx / (1.0 - xx)) + p_e1 / emu + AtmosModel::Ei(p_atmosTau * (1.0 / xx - 1.0)));
227 f1mmu = xx * (log(1.0 + 1.0 / xx) - p_e1 * emu + AtmosModel::En(1, p_atmosTau * (1.0 + 1.0 / xx)));
228 }
229 else {
230 std::string msg = "Negative length of planetary curvature encountered";
231 throw IException(IException::Unknown, msg, _FILEINFO_);
232 }
233
234 xmunot = 1.0 + p_wha2 * f1mmunot + p_delta * munotp * (1.0 - emunot);
235 ymunot = emunot * (1.0 + p_wha2 * f1munot) + p_delta * munotp * (1.0 - emunot);
236 xmu = 1.0 + p_wha2 * f1mmu + p_delta * mup * (1.0 - emu);
237 ymu = emu * (1.0 + p_wha2 * f1mu) + p_delta * mup * (1.0 - emu);
238
239 // mix the x and y as required in the conservative case
240 if(p_atmosWha == 1.0) {
241 fix = p_fixcon * munotp * (xmunot + ymunot);
242 xmunot = xmunot + fix;
243 ymunot = ymunot + fix;
244 fix = p_fixcon * mup * (xmu + ymu);
245 xmu = xmu + fix;
246 ymu = ymu + fix;
247 }
248
249 // gamma1 functions come from x and y
250 gmunot = p_gammax * xmunot + p_gammay * ymunot;
251 gmu = p_gammax * xmu + p_gammay * ymu;
252
253 // purely atmos term uses x and y, xmitted surface term uses gammas
254 p_pstd = 0.25 * p_atmosWha * munotp / (munotp + mup) * (xmunot * xmu - ymunot * ymu);
255 p_trans = gmunot * gmu;
256
257 // finally, never-scattered term is given by pure attenuation
258 p_trans0 = emunot * emu;
259
260 // Calculate the transmission of light that must be subtracted from a shadow.
261 // This includes direct flux and the scattered flux in the upsun half of the
262 // sky downwelling onto the surface, and the usual transmission upward.
263 p_transs = (emunot + 0.5 * (p_gammax * xmunot + p_gammay * ymunot - emunot)) * emu;
264 }
265}
266
267extern "C" Isis::AtmosModel *Isotropic2Plugin(Isis::Pvl &pvl, Isis::PhotoModel &pmodel) {
268 return new Isis::Isotropic2(pvl, pmodel);
269}
Isotropic atmos scattering model.
Definition AtmosModel.h:60
double p_trans
Transmission of surface reflected light through the atmosphere overall.
Definition AtmosModel.h:259
static double En(unsigned int n, double x)
This routine evaluates the generalized exponential integral, En(x).
double p_atmosHnorm
Atmospheric shell thickness normalized to planet radius.
Definition AtmosModel.h:267
double p_sbar
Illumination of the ground by the sky.
Definition AtmosModel.h:262
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_transs
Transmission of light that must be subtracted from the flat surface model to get the shadow model.
Definition AtmosModel.h:261
static double Ei(double x)
This routine computes the exponential integral, Ei(x).
double p_pstd
Pure atmospheric-scattering term.
Definition AtmosModel.h:258
double p_trans0
Transmission of surface reflected light through the atmosphere with no scatterings in the atmosphere.
Definition AtmosModel.h:260
bool TauOrWhaChanged() const
Checks whether tau or wha have changed.
virtual void AtmosModelAlgorithm(double phase, double incidence, double emission)
Isotropic atmospheric scattering in the first approximation The model for scattering for a general,...
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16