icedb  version 0.5.1
Snow particle scattering database API
refract.cpp
Go to the documentation of this file.
1 #include <cmath>
2 #include <complex>
3 #include <valarray>
4 #include <mutex>
5 #include <set>
6 #include "../icedb/refract/refract.hpp"
7 #include "../icedb/refract/refractBase.hpp"
8 #include "../icedb/zeros.hpp"
9 #include "../icedb/units/units.hpp"
10 #include "../icedb/error.hpp"
11 #include "../icedb/logging.hpp"
12 
13 namespace icedb {
14  namespace refract {
15  namespace implementations {
16  std::mutex m_refracts;
18  std::map<std::string, all_providers_mp> providersSet;
19  std::map<std::string, provider_mp> providersByName;
20  std::set<std::string> substs;
21  void _init() {
22  std::lock_guard<std::mutex> lock(m_refracts);
23  static bool inited = false;
24  if (inited) return;
25  allProvidersSet = all_providers_mp(new provider_collection_type);
26 
27  std::shared_ptr<std::map<std::string, provider_p> > data(
28  new std::map<std::string, provider_p>);
29 
30  auto pmWaterLiebe = provider_s::generate(
31  "mWaterLiebe", "water",
32  "Liebe, H.J., Hufford, G.A. & Manabe, T. Int J Infrared Milli Waves (1991) 12: 659. doi:10.1007/BF01008897",
33  "",
35  ->addReq("spec", "GHz", 0, 1000)->addReq("temp", "K", 273.15, 373.15)->registerFunc();
36  auto pmWaterFreshMeissnerWentz = provider_s::generate(
37  "mWaterFreshMeissnerWentz", "water",
38  "T. Meissner and F. J. Wentz, \"The complex dielectric constant of pure and sea water from microwave satellite observations\", IEEE Trans. Geosci. Remote Sensing, vol. 42, no.9, pp. 1836-1849, September 2004.",
39  "For pure water (no salt)",
41  ->addReq("spec", "GHz", 0, 500)->addReq("temp", "K", 253.15, 313.15)->registerFunc();
42  auto pmIceMatzler = provider_s::generate(
43  "mIceMatzler", "ice",
44  "Thermal Microwave Radiation: Applications for Remote Sensing, "
45  "Chapter 5, Microwave dielectric properties of ice, "
46  "By Christian Matzler(2006)",
47  "",
49  ->addReq("spec", "GHz", 0, 1000)->addReq("temp", "K", 0, 273.15)->registerFunc();
50  auto pmIceWarren = provider_s::generate(
51  "mIceWarren", "ice",
52  "Stephen G. Warren, \"Optical constants of ice from the ultraviolet to the microwave, \" Appl. Opt. 23, 1206-1225 (1984)",
53  "",
55  ->addReq("spec", "GHz", 0.167, 8600)->addReq("temp", "degC", -60, -1)->registerFunc();
56  auto pmWaterHanel = provider_s::generate(
57  "mWaterHanel", "water",
58  "Tables from Thomas Hanel. Not sure which paper.", "",
60  ->addReq("spec", "um", 0.2, 30000)->registerFunc(100);
61  auto pmIceHanel = provider_s::generate(
62  "mIceHanel", "ice",
63  "Tables from Thomas Hanel. Not sure which paper.", "",
65  ->addReq("spec", "um", 0.2, 30000)->registerFunc(100);
66 
67  auto pmNaClHanel = provider_s::generate(
68  "mNaClHanel", "NaCl",
69  "Tables from Thomas Hanel. Not sure which paper.", "",
71  ->addReq("spec", "um", 0.2, 30000)->registerFunc(100);
72  auto pmSeaSaltHanel = provider_s::generate(
73  "mSeaSaltHanel", "SeaSalt",
74  "Tables from Thomas Hanel. Not sure which paper.", "",
76  ->addReq("spec", "um", 0.2, 30000)->registerFunc(100);
77  auto pmDustHanel = provider_s::generate(
78  "mDustHanel", "Dust",
79  "Tables from Thomas Hanel. Not sure which paper.", "",
81  ->addReq("spec", "um", 0.2, 300)->registerFunc(100);
82  auto pmSandOHanel = provider_s::generate(
83  "mSandOHanel", "Sand_O",
84  "Tables from Thomas Hanel. Not sure which paper.", "",
86  ->addReq("spec", "um", 0.2, 300)->registerFunc(100);
87  auto pmSandEHanel = provider_s::generate(
88  "mSandEHanel", "Sand_E",
89  "Tables from Thomas Hanel. Not sure which paper.", "",
91  ->addReq("spec", "um", 0.2, 300)->registerFunc(100);
92 
93  inited = true;
94  }
95  }
96 
98  const std::string &name, const std::string &subst,
99  const std::string &source, const std::string &notes,
100  provider_s::spt sv, void* ptr) {
101  provider_mp res(new provider_s);
102  res->name = name;
103  res->substance = subst;
104  res->source = source;
105  res->notes = notes;
106  res->speciality_function_type = sv;
107  res->specialty_pointer = ptr;
108  return res;
109  }
110  provider_mp provider_s::addReq(const std::string &name, const std::string &units,
111  double low, double high) {
112  auto res = this->shared_from_this();
113  auto newreq = requirement_s::generate(name, units, low, high);
114  reqs[name] = newreq;
115  return res;
116  }
118  provider_mp res = this->shared_from_this();
119  all_providers_mp block;
120  if (implementations::providersSet.count(substance))
121  block = implementations::providersSet.at(substance);
122  else {
124  implementations::providersSet[substance] = block;
125  }
126  block->insert(std::pair<int,provider_mp>(priority,res));
127  implementations::allProvidersSet->insert(std::pair<int, provider_mp>(priority, res));
128  implementations::providersByName[res->name] = res;
129  implementations::substs.emplace(res->substance);
130  return res;
131  }
135  const std::string &name, const std::string& units,
136  double low, double high) {
137  std::shared_ptr<requirement_s> res(new requirement_s);
138  res->parameterName = name;
139  res->parameterUnits = units;
140  res->hasValidRange = true;
141  res->validRange = std::pair<double, double>(low, high);
142  return res;
143  }
144 
149  }
150  all_providers_p listAllProviders(const std::string &subst) {
151  all_providers_p emptyres;
154  if (!implementations::providersSet.count(subst)) return emptyres;
156  return pss;
157  }
158  void enumProvider(provider_p p, std::ostream &out) {
160  .add<std::string>("Reason", "No provider was passed to this function - instead, a NULL was passed!");
161  out << "Provider:\t" << p->name << "\n"
162  << "\tSubstance:\t" << p->substance << "\n"
163  << "\tSource:\t" << p->source << "\n"
164  << "\tNotes:\t" << p->notes << "\n";
165  if (p->reqs.size()) {
166  out << "\tRequirements:\n";
167  for (const auto &r : p->reqs) {
168  out << "\t\tParameter:\t" << r.first
169  << "\t\t\tRange:\t" << r.second->validRange.first << " to "
170  << r.second->validRange.second << " "
171  << r.second->parameterUnits << "\n";
172  }
173  }
174  }
175  void enumProviders(all_providers_p p, std::ostream &out) {
177  .add<std::string>("Reason", "The pointer passed to this function was NULL!");
178  if (p->size() == 1) out << "Providers found: 1\n";
179  else out << "Providers enumerated: " << p->size() << "\n";
180  for (const auto &i : *(p.get())) {
181  enumProvider(i.second, out);
182  }
183  }
184  void enumSubstances(std::ostream &out) {
186  out << "Substances:" << std::endl;
187  for (const auto &i : implementations::substs)
188  out << "\t" << i << std::endl;
189  }
190 
191  provider_p findProviderByName(const std::string &providerName) {
192  provider_p emptyres;
195  if (implementations::providersByName.count(providerName)) {
196  provider_p cres = implementations::providersByName.at(providerName);
197  return cres;
198  }
199  return emptyres;
200  }
201 
202  provider_p findProvider(const std::string &subst,
203  bool haveFreq, bool haveTemp, const std::string & start) {
204  provider_p emptyres;
207 
208  if (implementations::providersByName.count(subst)) {
210  if ((cres->reqs.count("spec") && !haveFreq) || (cres->reqs.count("temp") && !haveTemp)) {
212  .add<std::string>("Reason", "Attempting to find the provider for a manually-"
213  "specified refractive index formula, but the retrieved formula's "
214  "requirements do not match what whas passed.")
215  .add<std::string>("Provider", subst);
216  }
217  return cres;
218  }
219 
220  if (!implementations::providersSet.count(subst)) return emptyres;
222  bool startSearch = false;
223  if (start == "") startSearch = true;
224  for (const auto &p : *(pss.get())) {
225  if (!startSearch) {
226  if (p.second->name == start) startSearch = true;
227  continue;
228  } else {
229  if (p.second->reqs.count("spec") && !haveFreq) continue;
230  if (p.second->reqs.count("temp") && !haveTemp) continue;
231  }
232  return p.second;
233  }
234  return emptyres;
235  }
236  all_providers_p findProviders(const std::string &subst,
237  bool haveFreq, bool haveTemp) {
241 
242  if (implementations::providersByName.count(subst)) {
244  if ((cres->reqs.count("spec") && !haveFreq) || (cres->reqs.count("temp") && !haveTemp)) {
246  .add<std::string>("Reason", "Attempting to find the provider for a manually-"
247  "specified refractive index formula, but the retrieved formula's "
248  "requirements do not match what was passed.")
249  .add<bool>("Have-Freq", haveFreq)
250  .add<bool>("Need-Freq", (bool) cres->reqs.count("spec"))
251  .add<bool>("Have-Temp", haveTemp)
252  .add<bool>("Need-Temp", (bool)cres->reqs.count("temp"))
253  .add<std::string>("Provider", subst);
254  }
255  res->insert(std::pair<int, provider_p>(0, cres));
256  return res;
257  }
258 
259  if (!implementations::providersSet.count(subst)) return res;
261  for (const auto &p : *(pss.get())) {
262  if (p.second->reqs.count("spec") && !haveFreq) continue;
263  if (p.second->reqs.count("temp") && !haveTemp) continue;
264  res->insert(p);
265  }
266  return res;
267  }
268  void prepRefract(provider_p prov, const std::string &inFreqUnits,
271  auto compatFunc = [](
272  units::converter_p converterFreq,
273  void* innerFunc,
274  double inSpec,
275  std::complex<double> &m) -> void {
276  // It's an ugly cast...
277  void(*transFunc)(double, std::complex<double>&) = (void(*)(double,std::complex<double>&))innerFunc;
278  if (!converterFreq)
279  transFunc(inSpec, m);
280  else {
281  transFunc(converterFreq->convert(inSpec), m);
282  }
283  };
284  units::converter_p converter;
285  if (prov->speciality_function_type != provider_s::spt::FREQ)
287  .add<std::string>("Reason", "You called the wrong prepRefract.");
288  if (!prov->reqs.count("spec"))
290  .add<std::string>("Reason", "Attempting to prepare a refractive index formula that does not "
291  "require a frequency / wavelength / wavenumber, but one was provided.");
292  std::string reqUnits = prov->reqs.at("spec")->parameterUnits;
293  if (reqUnits != inFreqUnits)
294  converter = units::conv_spec::generate(inFreqUnits, reqUnits);
295 
296  res = std::bind(compatFunc,
297  converter,
298  prov->specialty_pointer,
299  std::placeholders::_1,
300  std::placeholders::_2);
301  }
303  const std::string &inFreqUnits, const std::string &inTempUnits,
306  auto compatFunc = [](
307  units::converter_p converterFreq,
308  units::converter_p converterTemp,
309  void* innerFunc,
310  double inSpec,
311  double inTemp,
312  std::complex<double> &m) -> void {
313  // It's an ugly cast...
314  void(*transFunc)(double, double, std::complex<double>&) = (void(*)(double, double, std::complex<double>&))innerFunc;
315  if (!converterFreq && !converterTemp)
316  transFunc(inSpec, inTemp, m);
317  else if (converterFreq && !converterTemp)
318  transFunc(converterFreq->convert(inSpec), inTemp, m);
319  else if (!converterFreq && converterTemp)
320  transFunc(inSpec, converterTemp->convert(inTemp), m);
321  else transFunc(converterFreq->convert(inSpec), converterTemp->convert(inTemp), m);
322  };
323  units::converter_p converterFreq, converterTemp;
324  if (prov->speciality_function_type != provider_s::spt::FREQTEMP)
326  .add<std::string>("Reason", "You called the wrong prepRefract.");
327  if (!prov->reqs.count("spec"))
329  .add<std::string>("Reason", "Attempting to prepare a refractive index formula that does not "
330  "require a frequency / wavelength / wavenumber, but one was provided.");
331  std::string reqFreqUnits = prov->reqs.at("spec")->parameterUnits;
332  if (reqFreqUnits != inFreqUnits)
333  converterFreq = units::conv_spec::generate(inFreqUnits, reqFreqUnits);
334 
335  if (!prov->reqs.count("temp"))
337  .add<std::string>("Reason", "Attempting to prepare a refractive index formula that does not "
338  "require a temperature, but one was provided.");
339  std::string reqTempUnits = prov->reqs.at("temp")->parameterUnits;
340  if (reqTempUnits != inTempUnits)
341  converterTemp = units::converter::generate(inTempUnits, reqTempUnits);
342 
343  res = std::bind(compatFunc,
344  converterFreq,
345  converterTemp,
346  prov->specialty_pointer,
347  std::placeholders::_1,
348  std::placeholders::_2,
349  std::placeholders::_3);
350  }
351 
352 
353  void bruggeman(std::complex<double> Ma, std::complex<double> Mb,
354  double fa, std::complex<double> &Mres)
355  {
356  using namespace std;
357  complex<double> eA, eB, eRes;
358  mToE(Ma, eA);
359  mToE(Mb, eB);
360 
361  // Liu's formula is derived only for mAmbient = 1. I want a more general case to make
362  // dielectric chaining easier.
363  auto formula = [&](std::complex<double> x) -> std::complex<double>
364  {
365  // f (( eA - eE ) / (eA + 2eE) ) + (1-f) (( eB - eE ) / (eB + 2eE) ) = 0
366  using namespace std;
367  complex<double> res, pa, pb;
368  pa = complex<double>(fa, 0) * (eA - x) / (eA + (complex<double>(2., 0)*x));
369  pb = complex<double>(1. - fa, 0) * (eB - x) / (eB + (complex<double>(2., 0)*x));
370  res = pa + pb;
371  return res;
372  };
373 
374  complex<double> gA(1.0, 1.0), gB(1.55, 1.45);
375  eRes = zeros::secantMethod(formula, gA, gB);
376 
377  eToM(eRes, Mres);
379  "bruggeman code called\n\tMa " << Ma << "\n\tMb " << Mb << "\n\tfa " << fa
380  << "\n\tMres " << Mres);
381  }
382 
383  void debyeDry(std::complex<double> Ma, std::complex<double> Mb,
384  double fa, std::complex<double> &Mres)
385  {
386  using namespace std;
387  std::complex<double> eA, eB, eRes;
388  mToE(Ma, eA);
389  mToE(Mb, eB);
390 
391  complex<double> pa = fa * (eA - complex<double>(1., 0)) / (eA + complex<double>(2., 0));
392  complex<double> pb = (1. - fa) * (eB - complex<double>(1., 0)) / (eB + complex<double>(2., 0));
393 
394  complex<double> fact = pa + pb;
395  eRes = (complex<double>(2., 0) * fact + complex<double>(1., 0))
396  / (complex<double>(1., 0) - fact);
397  eToM(eRes, Mres);
399  "debyeDry code called\n\tMa " << Ma << "\n\tMb " << Mb << "\n\tfa " << fa
400  << "\n\tMres " << Mres);
401  }
402 
403  void maxwellGarnettSpheres(std::complex<double> Ma, std::complex<double> Mb,
404  double fa, std::complex<double> &Mres)
405  {
406  using namespace std;
407  std::complex<double> eA, eB, eRes;
408  mToE(Ma, eA);
409  mToE(Mb, eB);
410 
411  // Formula is:
412  // (e_eff - eb)/(e_eff+2eb) = fa * (ea - eb) / (ea + 2 eb)
413  complex<double> a = complex<double>(fa, 0) * (eA - eB) / (eA + (complex<double>(2, 0) * eB));
414  eRes = eB * (complex<double>(2, 0) * a + complex<double>(1, 0))
415  / (complex<double>(1, 0) - a);
416  eToM(eRes, Mres);
418  "maxwellGarnettSpheres code called\n\tMa " << Ma << "\n\tMb " << Mb << "\n\tfa " << fa
419  << "\n\tMres " << Mres);
420  }
421 
422  void maxwellGarnettEllipsoids(std::complex<double> Ma, std::complex<double> Mb,
423  double fa, std::complex<double> &Mres)
424  {
425  using namespace std;
426  std::complex<double> eA, eB, eRes;
427  mToE(Ma, eA);
428  mToE(Mb, eB);
429 
430  complex<double> betaA = complex<double>(2., 0)*eA / (eB - eA);
431  complex<double> betaB = ((eB / (eB - eA)) * log(eB / eA)) - complex<double>(1., 0);
432  complex<double> beta = betaA * betaB;
433 
434  complex<double> cf(fa, 0), cfc(1. - fa, 0);
435 
436  eRes = ((cfc*beta) + (cf*eA)) / (cf + (cfc*beta));
437  eToM(eRes, Mres);
439  "maxwellGarnettEllipsoids code called\n\tMa " << Ma << "\n\tMb " << Mb << "\n\tfa " << fa
440  << "\n\tMres " << Mres);
441  }
442 
443  void sihvola(std::complex<double> Ma, std::complex<double> Mb,
444  double fa, double nu, std::complex<double> &Mres)
445  {
446  using namespace std;
447  std::complex<double> eA, eB, eRes;
448  mToE(Ma, eA);
449  mToE(Mb, eB);
450 
458  auto formulaSihvola = [&](std::complex<double> x) -> std::complex<double>
459  {
460  using namespace std;
461  complex<double> res, pa, pb;
462  pa = (x - eB) / (x + (complex<double>(2.0, 0)*eB) + (complex<double>(nu, 0)*(x - eB)));
463  pb = complex<double>(fa, 0) *
464  (eA - eB) / (eA + (complex<double>(2.0, 0)*eB) + (complex<double>(nu, 0)*(x - eB)));
465  res = pa - pb;
466  return res;
467  };
468 
469  complex<double> gA(1.0, 1.0), gB(1.55, 1.45);
470  eRes = zeros::secantMethod(formulaSihvola, gA, gB);
471  eToM(eRes, Mres);
472  ICEDB_log("refract", icedb::logging::ICEDB_LOG_DEBUG_2, "sihvola code called\n\tMa " << Ma << "\n\tMb " << Mb << "\n\tfa " << fa
473  << "\n\tnu " << nu << "\n\tMres " << Mres);
474  }
475 
476  std::complex<double> mToE(std::complex<double> m)
477  {
478  return m * m;
479  }
480  void mToE(std::complex<double> m, std::complex<double> &e)
481  {
482  e = mToE(m);
483  }
484 
485  std::complex<double> eToM(std::complex<double> e)
486  {
487  return sqrt(e);
488  }
489  void eToM(std::complex<double> e, std::complex<double> &m)
490  {
491  m = eToM(e);
492  }
493 
494  double guessTemp(double freq, const std::complex<double>& m,
495  std::function<void(double freq, double temp, std::complex<double>& mres)> meth,
496  double TA, double TB)
497  {
498  using namespace std;
499  // Attempt to guess the formula using the secant method.
500  auto formulaTemp = [&](double T) -> double
501  {
502  // 0 = mRes(f,T) - m_known
503  using namespace std;
504  complex<double> mRes;
505  meth(freq, T, mRes);
506 
507  double mNorm = mRes.real() - m.real(); //norm(mRes- ms.at(0));
508 
509  return mNorm;
510  };
511 
512  double temp = 0;
513  //complex<double> gA, gB;
514  //refract::mIce(freq, TA, gA);
515  //refract::mIce(freq, TB, gB);
516  temp = zeros::secantMethod(formulaTemp, TA, TB, 0.00001);
517  return temp;
518  }
519 
520  /*
521  void MultiInclusions(
522  const std::vector<basicDielectricTransform> &funcs,
523  const std::vector<double> &fs,
524  const std::vector<std::complex<double> > &ms,
525  std::complex<double> &Mres)
526  {
527  //if (fs.size() != ms.size() + 1) RDthrow Ryan_Debug::ICEDB_LOG_ERROR::xBadInput("Array sizes are not the same");
528  //if (fs.size() != funcs.size()) RDthrow Ryan_Debug::ICEDB_LOG_ERROR::xBadInput("Array sizes are not the same");
529 
530  using namespace std;
531 
532  double fTot = 0.0;
533  double fEnv = 1.0;
534 
535  Mres = ms.at(0);
536  fTot = fs.at(0);
537 
538  // Ordering is most to least enclosed
539  for (size_t i = 1; i < funcs.size(); ++i)
540  {
541  // ms[0] is the initial refractive index (innermost material), and fs[0] is its volume fraction
542  complex<double> mA = Mres;
543  fTot += fs.at(i);
544  if (!fTot) continue;
545  funcs.at(i)(mA, ms.at(i), fs.at(i - 1) / fTot, Mres);
546  }
547  }
548  */
549 
550  /*
551  void icedb::refract::maxwellGarnett(std::complex<double> Mice, std::complex<double> Mwater,
552  std::complex<double> Mair, double fIce, double fWater, std::complex<double> &Mres)
553  {
554  using namespace std;
555  std::complex<double> Miw;
556 
557  // Ice is the inclusion in water, which is the inclusion in air
558  double frac = 0;
559  if (fWater+fIce == 0) frac = 0;
560  else frac = fIce / (fWater + fIce);
561  maxwellGarnettSpheres(Mice, Mwater, frac, Miw);
562  maxwellGarnettSpheres(Miw, Mair, fIce + fWater, Mres);
563  }
564  */
565  }
566 }
std::complex< double > eToM(std::complex< double > e)
Definition: refract.cpp:485
void mIceWarren(double f, double t, std::complex< double > &m)
Ice complex refractive index for microwave/uv.
void mWaterHanel(double lambda, std::complex< double > &m)
Water complex refractive index for ir/vis.
void mIceMatzler(double f, double t, std::complex< double > &m)
std::map< std::string, provider_mp > providersByName
Definition: refract.cpp:19
void enumSubstances(std::ostream &out)
Definition: refract.cpp:184
STL namespace.
void enumProviders(all_providers_p p, std::ostream &out)
Definition: refract.cpp:175
U secantMethod(const T &f, U guess_a, U guess_b, double eps=0.000001, size_t maxIter=50)
Definition: zeros.hpp:17
double guessTemp(double freq, const std::complex< double > &m, std::function< void(double freq, double temp, std::complex< double > &mres)> meth, double TA, double TB)
Definition: refract.cpp:494
void mNaClHanel(double lambda, std::complex< double > &m)
Sodium chloride refractive index for ir/vis.
void sihvola(std::complex< double > Ma, std::complex< double > Mb, double fa, double nu, std::complex< double > &Mres)
Definition: refract.cpp:443
void mSandEHanel(double lambda, std::complex< double > &m)
Sand E-ray refractive index for ir/vis (birefringent)
void maxwellGarnettSpheres(std::complex< double > Ma, std::complex< double > Mb, double fa, std::complex< double > &Mres)
Definition: refract.cpp:403
void enumProvider(provider_p p, std::ostream &out)
Definition: refract.cpp:158
void mSandOHanel(double lambda, std::complex< double > &m)
Sand O-ray refractvie index for ir/vis (birefringent)
all_providers_p listAllProviders()
Definition: refract.cpp:145
std::function< void(double, double, std::complex< double > &)> refractFunction_freq_temp_t
Definition: refract.hpp:60
provider_mp registerFunc(int priority=0)
Definition: refract.cpp:117
#define ICEDB_throw(x)
Definition: error.hpp:88
std::shared_ptr< const requirement_s > requirement_p
Definition: refract.hpp:16
std::shared_ptr< provider_s > provider_mp
Definition: refract.hpp:27
void prepRefract(provider_p prov, const std::string &inFreqUnits, refractFunction_freqonly_t &res)
Definition: refract.cpp:268
static requirement_p generate(const std::string &name, const std::string &units, double low, double high)
Definition: refract.cpp:134
all_providers_p findProviders(const std::string &subst, bool haveFreq, bool haveTemp)
Definition: refract.cpp:236
void maxwellGarnettEllipsoids(std::complex< double > Ma, std::complex< double > Mb, double fa, std::complex< double > &Mres)
Definition: refract.cpp:422
std::shared_ptr< const provider_collection_type > all_providers_p
Definition: refract.hpp:56
provider_mp addReq(const std::string &name, const std::string &units, double low, double high)
Definition: refract.cpp:110
static std::shared_ptr< const converter > generate(const std::string &inUnits, const std::string &outUnits)
Definition: units.cpp:77
static std::shared_ptr< const converter > generate(const std::string &inUnits, const std::string &outUnits)
Definition: units.cpp:13
provider_p findProviderByName(const std::string &providerName)
Definition: refract.cpp:191
provider_p findProvider(const std::string &subst, bool haveFreq, bool haveTemp, const std::string &start)
Definition: refract.cpp:202
void mDustHanel(double lambda, std::complex< double > &m)
Dust-like particle refractive index for ir/vis.
std::shared_ptr< const provider_s > provider_p
Definition: refract.hpp:29
void debyeDry(std::complex< double > Ma, std::complex< double > Mb, double fa, std::complex< double > &Mres)
Definition: refract.cpp:383
std::function< void(double, std::complex< double > &)> refractFunction_freqonly_t
Definition: refract.hpp:59
std::multimap< int, provider_p > provider_collection_type
Definition: refract.hpp:55
std::map< std::string, all_providers_mp > providersSet
Definition: refract.cpp:18
void mWaterLiebe(double f, double t, std::complex< double > &m)
void mWaterFreshMeissnerWentz(double f, double t, std::complex< double > &m)
void bruggeman(std::complex< double > Ma, std::complex< double > Mb, double fa, std::complex< double > &Mres)
Definition: refract.cpp:353
std::shared_ptr< provider_collection_type > all_providers_mp
Definition: refract.hpp:57
#define ICEDB_log(c, p, x)
Definition: logging.hpp:45
all_providers_mp allProvidersSet
Definition: refract.cpp:17
static provider_mp generate(const std::string &name, const std::string &subst, const std::string &source, const std::string &notes, provider_s::spt sv, void *ptr)
Definition: refract.cpp:97
void mIceHanel(double lambda, std::complex< double > &m)
Ice complex refractive index for ir/vis.
std::complex< double > mToE(std::complex< double > m)
m to e converters
Definition: refract.cpp:476
void mSeaSaltHanel(double lambda, std::complex< double > &m)
Sea salt refractive index for ir/vis.
std::shared_ptr< const converter > converter_p
Definition: units.hpp:16
std::set< std::string > substs
Definition: refract.cpp:20