96 constexpr
double tan30 = 0.5773502691896;
100 constexpr
double hmE = 120.0;
120 NeQuickIonoNavData ::
123 idf{
false,
false,
false,
false,
false}
137 s <<
"****************************************************************"
138 <<
"************" << endl
139 <<
"Ionospheric correction data"
148 const ios::fmtflags oldFlags = s.flags();
150 s.setf(ios::fixed, ios::floatfield);
151 s.setf(ios::right, ios::adjustfield);
152 s.setf(ios::uppercase);
156 s <<
" TIMES OF INTEREST"
161 s.setf(ios::scientific, ios::floatfield);
166 <<
" NEQUICK IONO PARAMETERS" << endl
167 <<
"Parameter Value" << endl
168 <<
"a_i0 " << setw(16) <<
ai[0] <<
" sfu" << endl
169 <<
"a_i1 " << setw(16) <<
ai[1] <<
" sfu/degree" << endl
170 <<
"a_i2 " << setw(16) <<
ai[2] <<
" sfu/degree**2" << endl
172 <<
"IDF region 1 " << setw(16) <<
idf[0] << endl
173 <<
"IDF region 2 " << setw(16) <<
idf[1] << endl
174 <<
"IDF region 3 " << setw(16) <<
idf[2] << endl
175 <<
"IDF region 4 " << setw(16) <<
idf[3] << endl
176 <<
"IDF region 5 " << setw(16) <<
idf[4] << endl;
189 double tec =
getTEC(when, rxgeo, svgeo);
219 double modip_u = modip.
stModip(rxgeo);
229 DEBUGTRACE(
"pPosition->latitude.rad=" << scientific << debugAngle.
rad());
230 DEBUGTRACE(
"pPosition->latitude.degree=" << scientific << debugAngle.
deg());
231 DEBUGTRACE(
"pPosition->latitude.sin=" << scientific << debugAngle.
sin());
232 DEBUGTRACE(
"pPosition->latitude.cos=" << scientific << debugAngle.
cos());
234 DEBUGTRACE(
"pPosition->longitude.rad=" << scientific << debugAngle.
rad());
235 DEBUGTRACE(
"pPosition->longitude.degree=" << scientific << debugAngle.
deg());
236 DEBUGTRACE(
"pPosition->longitude.sin=" << scientific << debugAngle.
sin());
237 DEBUGTRACE(
"pPosition->longitude.cos=" << scientific << debugAngle.
cos());
238 DEBUGTRACE(
"pPosition->height()=" << scientific << (rxgeo.
height() / 1000.0));
239 DEBUGTRACE(
"pPosition->radius_km()=" << scientific << (rxgeo.
radius() / 1000.0));
240 DEBUGTRACE(
"# pContext->modip_degree=" << scientific << modip_u);
252 rxgeo, svgeo, modip, modip_u, ccir, civ,
268 double azu =
ai[0] +
ai[1]*modip_u +
ai[2]*modip_u*modip_u;
291 DEBUGTRACE(
"height_km=" << setprecision(15) << dist);
293 double modip_u = modip.
stModip(current);
297 DEBUGTRACE(
"electron density=" << setprecision(15) << scientific
299 return electronDensity;
310 DEBUGTRACE(
"height_km=" << setprecision(15) << dist);
317 return electronDensity;
339 : fXeff(effSolarZenithAngle(
pos,when)),
346 DEBUGTRACE(
"solar_12_month_running_mean_of_2800_MHZ_noise_flux=" << az);
373 double phi =
pos.geodeticLatitude();
374 double lambda =
pos.longitude();
376 DEBUGTRACE(
"# pSolar_activity->effective_ionisation_level_sfu="
377 << scientific << az);
378 double ee =
neExp(0.3 * phi);
379 double seasp = (seas * (ee-1))/(ee+1);
380 double term1 = (1.112-0.019*seasp);
381 double term2 = sqrt(az);
382 double term3 = pow(
cos(
fXeff), 0.6);
387 ffoE = sqrt(term1*term1*term2*term3 + 0.49);
427 fAzr(
std::numeric_limits<double>::quiet_NaN()),
428 ffoE(
std::numeric_limits<double>::quiet_NaN()),
429 fNmE(
std::numeric_limits<double>::quiet_NaN()),
430 fBEtop(
std::numeric_limits<double>::quiet_NaN()),
431 fA{std::numeric_limits<double>::quiet_NaN(),
432 std::numeric_limits<double>::quiet_NaN(),
433 std::numeric_limits<double>::quiet_NaN()},
434 ffoF1(std::numeric_limits<double>::quiet_NaN()),
435 fNmF1(std::numeric_limits<double>::quiet_NaN()),
436 fhmF1(std::numeric_limits<double>::quiet_NaN()),
437 fB1top(std::numeric_limits<double>::quiet_NaN()),
438 fB1bot(std::numeric_limits<double>::quiet_NaN()),
439 ffoF2(std::numeric_limits<double>::quiet_NaN()),
440 fNmF2(std::numeric_limits<double>::quiet_NaN()),
441 fhmF2(std::numeric_limits<double>::quiet_NaN()),
442 fB2bot(std::numeric_limits<double>::quiet_NaN()),
443 fM3000F2(std::numeric_limits<double>::quiet_NaN()),
444 fH0(std::numeric_limits<double>::quiet_NaN()),
462 double dy = 30.5 * whenUTC.
month - 15;
464 double t = dy + (18.0-whenUTC.
getUTHour())/24.0;
466 double am = (0.9856 * t - 3.289) *
DEG2RAD;
467 double al = am + (1.916*
sin(am) + 0.020*
sin(2*am) + 282.634) *
477 double phiRad =
pos.geodeticLatitude() *
DEG2RAD;
478 double lambda =
pos.longitude();
481 double lt = when.
getUTHour() + (lambda / 15.0);
483 double cosX=
sin(phiRad) *
sin(deltaSun) +
494 static const double x0 = 86.23292796211615;
495 Angle x = solarZenithAngle(
pos, when);
496 double exp2 =
neExp(12*(x.
deg()-x0));
514 const unsigned Q[] {12,12,9,5,2,1,1,1,1};
515 const int K[] {-12, 12, 36, 54, 64, 68, 70, 72, 74};
518 const unsigned R[] {7,8,6,3,2,1,1};
519 const int H[] {-7,7,23,35,41,45,47};
520 double modip_uRad = modip_u *
DEG2RAD;
521 double phiRad =
pos.geodeticLatitude() *
DEG2RAD;
523 DEBUGTRACE(
"lambdaRad = " << scientific << lambdaRad);
524 DEBUGTRACE(
"lat.rad = " << scientific << phiRad);
525 DEBUGTRACE(
"lat.deg = " << scientific <<
pos.geodeticLatitude());
530 M[k] = M[k-1] *
sin(modip_uRad);
536 P[n] =
P[n-1] *
cos(phiRad);
537 S[n-1] =
sin(n * lambdaRad);
538 C[n-1] =
cos(n * lambdaRad);
539 DEBUGTRACE(
"lambda[" << n <<
"]=" << scientific << (n*lambdaRad));
540 DEBUGTRACE(
"S[" << n <<
"]=" << scientific << S[n]);
541 DEBUGTRACE(
"C[" << n <<
"]=" << scientific << C[n]);
548 ffoF2 += ccir.getCF2(k) * M[k];
549 DEBUGTRACE(
"CF2[" << k <<
"]=" << scientific << ccir.getCF2(k)
550 <<
" M[" << k <<
"]=" << M[k] <<
" parameter=" << ffoF2);
555 for (
unsigned k=0; k<Q[n]; k++)
557 ffoF2 += (ccir.getCF2(K[n]+2*k) * C[n-1] +
558 ccir.getCF2(K[n]+2*k+1) * S[n-1]) * M[k] *
P[n];
559 DEBUGTRACE(
"M[" << k <<
"]=" << scientific << M[k]
560 <<
" lat_coeff=" <<
P[n]
561 <<
" Fourier_coeff[" << (K[n]+2*k) <<
"]="
562 << ccir.getCF2(K[n]+2*k)
563 <<
" C[" << (n-1) <<
"]=" << C[n-1]
564 <<
" Fourier_coeff[" << (K[n]+2*k+1) <<
"]="
565 << ccir.getCF2(K[n]+2*k+1)
566 <<
" S[" << (n-1) <<
"]=" << S[n-1]
567 <<
" parameter=" << ffoF2);
576 fM3000F2 += ccir.getCM3(k) * M[k];
577 DEBUGTRACE(
"CM3[" << k <<
"]=" << scientific << ccir.getCM3(k)
578 <<
" M[" << k <<
"]=" << M[k] <<
" parameter="
584 for (
unsigned k=0; k<R[n]; k++)
586 fM3000F2 += (ccir.getCM3(H[n]+2*k) * C[n-1] +
587 ccir.getCM3(H[n]+2*k+1) * S[n-1]) * M[k] *
P[n];
588 DEBUGTRACE(
"M[" << k <<
"]=" << scientific << M[k]
589 <<
" lat_coeff=" <<
P[n]
590 <<
" Fourier_coeff[" << (H[n]+2*k) <<
"]="
591 << ccir.getCM3(H[n]+2*k)
592 <<
" C[" << (n-1) <<
"]=" << C[n-1]
593 <<
" Fourier_coeff[" << (H[n]+2*k+1) <<
"]="
594 << ccir.getCM3(H[n]+2*k+1)
595 <<
" S[" << (n-1) <<
"]=" << S[n-1]
596 <<
" parameter=" << fM3000F2);
609 double cfRatio = ffoF2 / ffoE;
610 double eTerm =
neExp(20*(cfRatio-1.75));
611 double rho = (cfRatio*eTerm + 1.75) / (eTerm + 1);
614 (0.253/(rho-1.215))-0.012);
615 fhmF2 = ((1490 * M * sqrt((0.0196*M*M+1)/(1.2967*M*M-1))) /
617 fhmF1 = (fhmF2+
hmE) / 2.0;
626 fB2bot = ((0.385*fNmF2) /
627 (0.01*exp(-3.467+0.857*
log(ffoF2*ffoF2) +
628 2.02 *
log(fM3000F2))));
629 fB1top = 0.3 * (fhmF2-fhmF1);
630 fB1bot = 0.5 * (fhmF1 -
hmE);
642 DEBUGTRACE(
"# pSolar_activity->effective_sun_spot_count=" << scientific << fAzr);
651 ka = 6.705 - 0.014*fAzr - 0.008*fhmF2;
660 ka = -7.77 + 0.097*ka*ka + 0.153*fNmF2;
666 double kb =
neExp(ka-2);
667 kb = (ka * kb + 2) / (1 + kb);
669 k = (8 * k + kb) / (1 + k);
670 double Ha = k * fB2bot;
671 double x = (Ha - 150.0) / 100.0;
672 double v = (0.041163*x - 0.183981)*x + 1.424472;
677 DEBUGTRACE(
"top-side thickness parameter = " << fH0);
687 double A3a = 0, A2a = 0;
697 A3a = 4.0 * (fNmE - epstein(fA[0],fhmF2,fB2bot,
hmE));
705 for (
unsigned i = 0; i < 5; i++)
707 A2a = 4.0 * (fNmF1 - epstein(fA[0],fhmF2,fB2bot,fhmF1) -
708 epstein(A3a,
hmE,fBEtop,fhmF1));
709 double tmp =
neExp(A2a - 0.80 * fNmF1);
710 A2a = (A2a * tmp + 0.80 * fNmF1) / (1+tmp);
711 A3a = 4.0 * (fNmE - epstein(A2a,fhmF1,fB1bot,
hmE) -
712 epstein(fA[0],fhmF2,fB2bot,
hmE));
717 double tmp =
neExp(60.0*(A3a-0.005));
719 fA[2] = (A3a * tmp + 0.05) / (1+tmp);
729 if ((
pos.height() / 1000.0) <= fhmF2)
731 rv = electronDensityBottom(
pos);
735 rv = electronDensityTop(
pos);
737 DEBUGTRACE(
"electron density=" << scientific << rv);
746 static constexpr
double g = 0.125;
747 static constexpr
double r = 100;
748 double h =
pos.height() / 1000.0;
749 double deltah = h - fhmF2;
750 double z = deltah / (fH0*(1+(r*g*deltah)/(r*fH0+g*deltah)));
751 double ea =
neExp(z);
759 rv = 4 * fNmF2 * ea / ((1+ea)*(1+ea));
769 double h =
pos.height() / 1000.0;
770 double BE = (h >
hmE) ? fBEtop :
BEbot;
771 double BF1 = (h > fhmF1) ? fB1top : fB1bot;
774 double t2 = exp(10/(1+fabs(mh-fhmF2)));
776 alpha[0] = (mh - fhmF2) / fB2bot;
777 alpha[1] = (mh - fhmF1) / BF1 * t2;
778 alpha[2] = (mh -
hmE) / BE * t2;
782 for (
unsigned i = 0; i < 3; i++)
784 if (fabs(alpha[i]) > 25)
790 s[i] = fA[i] * ea[i]/((1+ea[i])*(1+ea[i]));
796 rv = s[0] + s[1] + s[2];
801 ds[0] = fabs(alpha[0]) > 25 ? 0
802 : (1/fB2bot)*((1-ea[0])/(1+ea[0]));
803 ds[1] = fabs(alpha[1]) > 25 ? 0
804 : (1/BF1)*((1-ea[1])/(1+ea[1]));
805 ds[2] = fabs(alpha[2]) > 25 ? 0
806 : (1/BE)*((1-ea[2])/(1+ea[2]));
807 double sumNum = s[0]*ds[0]+s[1]*ds[1]+s[2]*ds[2];
808 double sumDenom = s[0]+s[1]+s[2];
809 double BC = 1 - 10*sumNum/sumDenom;
810 double z = (h-100)/10;
829 double h2 = sv.
height() / 1000.0;
832 integHeights.push_back(h1);
833 if ((ha > h1) && (ha < h2))
835 integHeights.push_back(ha);
838 if ((hb > h1) && (hb < h2))
840 integHeights.push_back(hb);
843 integHeights.push_back(h2);
848 if (intThresh.empty())
863 double rp = Pp.
radius() / 1000.0;
871 double r2 = sv.
radius() / 1000.0;
872 double s1 = sqrt(fabs(r1*r1 - rp*rp));
873 double sa = sqrt(fabs(ip1*ip1 - rp*rp));
874 double sb = sqrt(fabs(ip2*ip2 - rp*rp));
875 double s2 = sqrt(fabs(r2*r2 - rp*rp));
878 integHeights.push_back(s1);
879 if ((sa > s1) && (sa < s2))
881 integHeights.push_back(sa);
884 if ((sb > s1) && (sb < s2))
886 integHeights.push_back(sb);
889 integHeights.push_back(s2);
894 if (intThresh.empty())
907 DEBUGTRACE(
"integHeights.size() = " << integHeights.size());
908 DEBUGTRACE(
"intThresh.size() = " << intThresh.size());
915 const MODIP& modip,
double modipSta,
CCIR& ccirData,
916 const CivilTime& when,
double azu,
double tolerance,
917 bool vertical,
unsigned recursionLevel)
922 DEBUGTRACE(
"pResult(1) = " << scientific << rv);
928 static const double wi[] = {
929 0.022935322010529224963732008058970,
930 0.063092092629978553290700663189204,
931 0.104790010322250183839876322541518,
932 0.140653259715525918745189590510238,
933 0.169004726639267902826583426598550,
934 0.190350578064785409913256402421014,
935 0.204432940075298892414161999234649,
936 0.209482141084727828012999174891714,
937 0.204432940075298892414161999234649,
938 0.190350578064785409913256402421014,
939 0.169004726639267902826583426598550,
940 0.140653259715525918745189590510238,
941 0.104790010322250183839876322541518,
942 0.063092092629978553290700663189204,
943 0.022935322010529224963732008058970
946 static const double wig[] = {
947 0.129484966168869693270611432679082,
948 0.279705391489276667901467771423780,
949 0.381830050505118944950369775488975,
950 0.417959183673469387755102040816327,
951 0.381830050505118944950369775488975,
952 0.279705391489276667901467771423780,
953 0.129484966168869693270611432679082
957 static const double xi[] = {
958 -0.991455371120812639206854697526329,
959 -0.949107912342758524526189684047851,
960 -0.864864423359769072789712788640926,
961 -0.741531185599394439863864773280788,
962 -0.586087235467691130294144838258730,
963 -0.405845151377397166906606412076961,
964 -0.207784955007898467600689403773245,
966 0.207784955007898467600689403773245,
967 0.405845151377397166906606412076961,
968 0.586087235467691130294144838258730,
969 0.741531185599394439863864773280788,
970 0.864864423359769072789712788640926,
971 0.949107912342758524526189684047851,
972 0.991455371120812639206854697526329
975 double h2 = (heightPt2 - heightPt1) / 2.0;
977 double hh = (heightPt2 + heightPt1) / 2.0;
987 for (
unsigned i = 0; i < 15; i++)
989 double x = h2 * xi[i] + hh;
994 y =
getVED(x, rxgeo, svgeo, modipSta, ccirData, when, azu);
998 y =
getSED(x, rxgeo, svgeo, modip, ccirData, when, azu);
1005 intg +=
y * wig[gind++];
1012 if (((fabs(intk - intg) / intk) <= tolerance) ||
1013 (fabs(intk - intg) <= tolerance))
1016 DEBUGTRACE(
"pResult(2) = " << scientific << intk);
1022 DEBUGTRACE(
"pResult(3) = " << scientific << intk);
1030 modip, modipSta, ccirData, when, azu,
1031 tolerance, vertical, recursionLevel+1);
1032 DEBUGTRACE(
"pResult(4) = " << scientific << rv);
1034 modip, modipSta, ccirData, when, azu,
1035 tolerance, vertical, recursionLevel+1);
1036 DEBUGTRACE(
"pResult(5) = " << scientific << rv);