8 #include "AtmosModel.h"
9 #include "NumericalAtmosApprox.h"
10 #include "NumericalApproximation.h"
11 #include "IException.h"
59 double trap[maxits+1];
70 for(
int i = 0; i < maxits; i++) {
73 trap[i] = RefineExtendedTrap(am, sub, a, b, trap[i], i + 1);
75 interp.
AddData(5, &h[i-4], &trap[i-4]);
76 ss = interp.
Evaluate(0.0, NumericalApproximation::Extrapolate);
80 if(fabs(dss) <= epsilon * fabs(ss))
return ss;
81 if(fabs(dss) <= epsilon2)
return ss;
95 "NumericalAtmosApprox::RombergsMethod() - Caught the following error: ",
99 "NumericalAtmosApprox::RombergsMethod() - Failed to converge in "
100 +
IString(maxits) +
" iterations.",
136 double NumericalAtmosApprox::RefineExtendedTrap(
AtmosModel *am,
IntegFunc sub,
double a,
double b,
double s,
unsigned int n) {
144 if(sub == InnerFunction) {
145 begin = InrFunc2Bint(am, a);
146 end = InrFunc2Bint(am, b);
149 begin = OutrFunc2Bint(am, a);
150 end = OutrFunc2Bint(am, b);
152 return (0.5 * (b - a) * (begin + end));
156 double delta, tnm, x, sum;
157 it = (int)(pow(2.0, (
double)(n - 2)));
159 delta = (b - a) / tnm;
162 for(
int i = 0; i < it; i++) {
163 if(sub == InnerFunction) {
164 sum = sum + InrFunc2Bint(am, x);
167 sum = sum + OutrFunc2Bint(am, x);
171 return (0.5 * (s + (b - a) * sum / tnm));
177 "NumericalAtmosApprox::RefineExtendedTrap() - Caught the following error: ",
201 double NumericalAtmosApprox::OutrFunc2Bint(
AtmosModel *am,
double phi) {
204 sub = NumericalAtmosApprox::InnerFunction;
206 am->p_atmosPhi = phi;
207 am->p_atmosCosphi = cos((
PI / 180.0) * phi);
217 "NumericalAtmosApprox::OutrFunc2Bint() - Caught the following error: ",
250 double NumericalAtmosApprox::InrFunc2Bint(
AtmosModel *am,
double mu) {
264 ema = acos(mu) * (180.0 /
PI);
265 sine = sin(ema * (
PI / 180.0));
266 if((am->p_atmosAtmSwitch == 0) || (am->p_atmosAtmSwitch == 2)) {
267 alpha = am->p_atmosSini * sine * am->p_atmosCosphi +
268 am->p_atmosMunot * mu;
271 alpha = am->p_atmosSini * sine * am->p_atmosCosphi -
272 am->p_atmosMunot * mu;
274 phase = acos(alpha) * (180.0 /
PI);
277 if(am->p_atmosAtmSwitch == 0) {
279 result = mu * am->p_atmosPM->
CalcSurfAlbedo(phase, am->p_atmosInc, ema);
283 xx = -am->
AtmosTau() / max(am->p_atmosMunot, 1.0e-30);
293 xx = -am->
AtmosTau() / max(mu, 1.0e-30);
304 if(mu == am->p_atmosMunot) {
305 tfac = am->
AtmosTau() * emunot / (am->p_atmosMunot * am->p_atmosMunot);
308 tfac = (emunot - emu) / (am->p_atmosMunot - mu);
310 if(am->p_atmosAtmSwitch == 1) {
311 result = mu * (phasefn - 1.0) * tfac;
313 else if(am->p_atmosAtmSwitch == 2) {
314 result = am->p_atmosMunot * mu * (phasefn - 1.0) * (1.0 - emunot * emu) / (am->p_atmosMunot + mu);
316 else if(am->p_atmosAtmSwitch == 3) {
317 result = -sine * am->p_atmosCosphi * (phasefn - 1.0) * tfac;
320 string msg =
"NumericalAtmosApprox::InrFunc2Bint() - Invalid value of atmospheric ";
321 msg +=
"switch used as argument to this function";
322 throw IException(IException::Programmer, msg, _FILEINFO_);