icedb  version 0.5.1
Snow particle scattering database API
Namespaces | Classes | Typedefs | Functions
icedb::refract Namespace Reference

Namespaces

 boost
 
 implementations
 The raw dielectric providers implementations.
 

Classes

struct  provider_s
 
struct  requirement_s
 

Typedefs

typedef std::shared_ptr< const requirement_srequirement_p
 
typedef std::shared_ptr< provider_sprovider_mp
 
typedef std::shared_ptr< const provider_sprovider_p
 
typedef std::multimap< int, provider_pprovider_collection_type
 
typedef std::shared_ptr< const provider_collection_typeall_providers_p
 
typedef std::shared_ptr< provider_collection_typeall_providers_mp
 
typedef std::function< void(double, std::complex< double > &)> refractFunction_freqonly_t
 
typedef std::function< void(double, double, std::complex< double > &)> refractFunction_freq_temp_t
 

Functions

all_providers_p listAllProviders ()
 
all_providers_p listAllProviders (const std::string &subst)
 
void enumProvider (provider_p p, std::ostream &out)
 
void enumProviders (all_providers_p p, std::ostream &out)
 
void enumSubstances (std::ostream &out)
 
provider_p findProviderByName (const std::string &providerName)
 
provider_p findProvider (const std::string &subst, bool haveFreq, bool haveTemp, const std::string &start)
 
all_providers_p findProviders (const std::string &subst, bool haveFreq, bool haveTemp)
 
void prepRefract (provider_p prov, const std::string &inFreqUnits, refractFunction_freqonly_t &res)
 
void prepRefract (provider_p prov, const std::string &inFreqUnits, const std::string &inTempUnits, refractFunction_freq_temp_t &res)
 
void bruggeman (std::complex< double > Ma, std::complex< double > Mb, double fa, std::complex< double > &Mres)
 
void debyeDry (std::complex< double > Ma, std::complex< double > Mb, double fa, std::complex< double > &Mres)
 
void maxwellGarnettSpheres (std::complex< double > Ma, std::complex< double > Mb, double fa, std::complex< double > &Mres)
 
void maxwellGarnettEllipsoids (std::complex< double > Ma, std::complex< double > Mb, double fa, std::complex< double > &Mres)
 
void sihvola (std::complex< double > Ma, std::complex< double > Mb, double fa, double nu, std::complex< double > &Mres)
 
std::complex< double > mToE (std::complex< double > m)
 m to e converters More...
 
void mToE (std::complex< double > m, std::complex< double > &e)
 
std::complex< double > eToM (std::complex< double > e)
 
void eToM (std::complex< double > e, std::complex< double > &m)
 
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)
 

Typedef Documentation

◆ all_providers_mp

Definition at line 57 of file refract.hpp.

◆ all_providers_p

Definition at line 56 of file refract.hpp.

◆ provider_collection_type

Definition at line 55 of file refract.hpp.

◆ provider_mp

typedef std::shared_ptr<provider_s> icedb::refract::provider_mp

Definition at line 27 of file refract.hpp.

◆ provider_p

typedef std::shared_ptr<const provider_s> icedb::refract::provider_p

Definition at line 29 of file refract.hpp.

◆ refractFunction_freq_temp_t

typedef std::function<void(double, double, std::complex<double>&)> icedb::refract::refractFunction_freq_temp_t

Definition at line 60 of file refract.hpp.

◆ refractFunction_freqonly_t

typedef std::function<void(double, std::complex<double>&)> icedb::refract::refractFunction_freqonly_t

Definition at line 59 of file refract.hpp.

◆ requirement_p

typedef std::shared_ptr<const requirement_s> icedb::refract::requirement_p

Definition at line 16 of file refract.hpp.

Function Documentation

◆ bruggeman()

void icedb::refract::bruggeman ( std::complex< double >  Ma,
std::complex< double >  Mb,
double  fa,
std::complex< double > &  Mres 
)

Definition at line 353 of file refract.cpp.

References eToM(), ICEDB_log, icedb::logging::ICEDB_LOG_DEBUG_2, mToE(), and icedb::zeros::secantMethod().

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  }
STL namespace.
U secantMethod(const T &f, U guess_a, U guess_b, double eps=0.000001, size_t maxIter=50)
Definition: zeros.hpp:17
void eToM(std::complex< double > e, std::complex< double > &m)
Definition: refract.cpp:489
void mToE(std::complex< double > m, std::complex< double > &e)
Definition: refract.cpp:480
#define ICEDB_log(c, p, x)
Definition: logging.hpp:45
Here is the call graph for this function:

◆ debyeDry()

void icedb::refract::debyeDry ( std::complex< double >  Ma,
std::complex< double >  Mb,
double  fa,
std::complex< double > &  Mres 
)

Definition at line 383 of file refract.cpp.

References eToM(), ICEDB_log, icedb::logging::ICEDB_LOG_DEBUG_2, and mToE().

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  }
STL namespace.
void eToM(std::complex< double > e, std::complex< double > &m)
Definition: refract.cpp:489
void mToE(std::complex< double > m, std::complex< double > &e)
Definition: refract.cpp:480
#define ICEDB_log(c, p, x)
Definition: logging.hpp:45
Here is the call graph for this function:

◆ enumProvider()

void icedb::refract::enumProvider ( provider_p  p,
std::ostream &  out 
)

Definition at line 158 of file refract.cpp.

References ICEDB_throw, and icedb::error::xNullPointer.

Referenced by enumProviders(), and main().

158  {
159  if (!p) ICEDB_throw(error::error_types::xNullPointer)
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  }
#define ICEDB_throw(x)
Definition: error.hpp:88
Here is the caller graph for this function:

◆ enumProviders()

void icedb::refract::enumProviders ( all_providers_p  p,
std::ostream &  out 
)

Definition at line 175 of file refract.cpp.

References enumProvider(), ICEDB_throw, and icedb::error::xNullPointer.

Referenced by main().

175  {
176  if (!p) ICEDB_throw(error::error_types::xNullPointer)
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  }
void enumProvider(provider_p p, std::ostream &out)
Definition: refract.cpp:158
#define ICEDB_throw(x)
Definition: error.hpp:88
Here is the call graph for this function:
Here is the caller graph for this function:

◆ enumSubstances()

void icedb::refract::enumSubstances ( std::ostream &  out)

Definition at line 184 of file refract.cpp.

References listAllProviders(), and icedb::refract::implementations::substs.

Referenced by main().

184  {
186  out << "Substances:" << std::endl;
187  for (const auto &i : implementations::substs)
188  out << "\t" << i << std::endl;
189  }
all_providers_p listAllProviders(const std::string &subst)
Definition: refract.cpp:150
std::set< std::string > substs
Definition: refract.cpp:20
Here is the call graph for this function:
Here is the caller graph for this function:

◆ eToM() [1/2]

std::complex< double > icedb::refract::eToM ( std::complex< double >  e)

Definition at line 485 of file refract.cpp.

Referenced by bruggeman(), debyeDry(), eToM(), maxwellGarnettEllipsoids(), maxwellGarnettSpheres(), and sihvola().

486  {
487  return sqrt(e);
488  }
Here is the caller graph for this function:

◆ eToM() [2/2]

void icedb::refract::eToM ( std::complex< double >  e,
std::complex< double > &  m 
)

Definition at line 489 of file refract.cpp.

References eToM().

490  {
491  m = eToM(e);
492  }
void eToM(std::complex< double > e, std::complex< double > &m)
Definition: refract.cpp:489
Here is the call graph for this function:

◆ findProvider()

provider_p icedb::refract::findProvider ( const std::string &  subst,
bool  haveFreq,
bool  haveTemp,
const std::string &  start 
)

Definition at line 202 of file refract.cpp.

References icedb::refract::implementations::_init(), icedb::refract::implementations::allProvidersSet, ICEDB_throw, icedb::refract::implementations::providersByName, icedb::refract::implementations::providersSet, and icedb::error::xBadFunctionMap.

203  {
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  }
std::map< std::string, provider_mp > providersByName
Definition: refract.cpp:19
#define ICEDB_throw(x)
Definition: error.hpp:88
std::shared_ptr< const provider_s > provider_p
Definition: refract.hpp:29
std::map< std::string, all_providers_mp > providersSet
Definition: refract.cpp:18
std::shared_ptr< provider_collection_type > all_providers_mp
Definition: refract.hpp:57
all_providers_mp allProvidersSet
Definition: refract.cpp:17
Here is the call graph for this function:

◆ findProviderByName()

provider_p icedb::refract::findProviderByName ( const std::string &  providerName)

Definition at line 191 of file refract.cpp.

References icedb::refract::implementations::_init(), icedb::refract::implementations::allProvidersSet, and icedb::refract::implementations::providersByName.

Referenced by main().

191  {
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  }
std::map< std::string, provider_mp > providersByName
Definition: refract.cpp:19
std::shared_ptr< const provider_s > provider_p
Definition: refract.hpp:29
all_providers_mp allProvidersSet
Definition: refract.cpp:17
Here is the call graph for this function:
Here is the caller graph for this function:

◆ findProviders()

all_providers_p icedb::refract::findProviders ( const std::string &  subst,
bool  haveFreq,
bool  haveTemp 
)

Definition at line 236 of file refract.cpp.

References icedb::refract::implementations::_init(), icedb::refract::implementations::allProvidersSet, ICEDB_throw, icedb::refract::implementations::providersByName, icedb::refract::implementations::providersSet, and icedb::error::xBadFunctionMap.

Referenced by main().

237  {
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  }
std::map< std::string, provider_mp > providersByName
Definition: refract.cpp:19
#define ICEDB_throw(x)
Definition: error.hpp:88
std::shared_ptr< const provider_collection_type > all_providers_p
Definition: refract.hpp:56
std::shared_ptr< const provider_s > provider_p
Definition: refract.hpp:29
std::multimap< int, provider_p > provider_collection_type
Definition: refract.hpp:55
std::map< std::string, all_providers_mp > providersSet
Definition: refract.cpp:18
std::shared_ptr< provider_collection_type > all_providers_mp
Definition: refract.hpp:57
all_providers_mp allProvidersSet
Definition: refract.cpp:17
Here is the call graph for this function:
Here is the caller graph for this function:

◆ guessTemp()

double icedb::refract::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 at line 494 of file refract.cpp.

References icedb::zeros::secantMethod().

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  }
STL namespace.
U secantMethod(const T &f, U guess_a, U guess_b, double eps=0.000001, size_t maxIter=50)
Definition: zeros.hpp:17
Here is the call graph for this function:

◆ listAllProviders() [1/2]

all_providers_p icedb::refract::listAllProviders ( )

Definition at line 145 of file refract.cpp.

References icedb::refract::implementations::_init(), and icedb::refract::implementations::allProvidersSet.

Referenced by enumSubstances(), and main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ listAllProviders() [2/2]

all_providers_p icedb::refract::listAllProviders ( const std::string &  subst)

Definition at line 150 of file refract.cpp.

References icedb::refract::implementations::_init(), icedb::refract::implementations::allProvidersSet, and icedb::refract::implementations::providersSet.

150  {
151  all_providers_p emptyres;
154  if (!implementations::providersSet.count(subst)) return emptyres;
156  return pss;
157  }
std::shared_ptr< const provider_collection_type > all_providers_p
Definition: refract.hpp:56
std::map< std::string, all_providers_mp > providersSet
Definition: refract.cpp:18
all_providers_mp allProvidersSet
Definition: refract.cpp:17
Here is the call graph for this function:

◆ maxwellGarnettEllipsoids()

void icedb::refract::maxwellGarnettEllipsoids ( std::complex< double >  Ma,
std::complex< double >  Mb,
double  fa,
std::complex< double > &  Mres 
)

Definition at line 422 of file refract.cpp.

References eToM(), ICEDB_log, icedb::logging::ICEDB_LOG_DEBUG_2, and mToE().

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  }
STL namespace.
void eToM(std::complex< double > e, std::complex< double > &m)
Definition: refract.cpp:489
void mToE(std::complex< double > m, std::complex< double > &e)
Definition: refract.cpp:480
#define ICEDB_log(c, p, x)
Definition: logging.hpp:45
Here is the call graph for this function:

◆ maxwellGarnettSpheres()

void icedb::refract::maxwellGarnettSpheres ( std::complex< double >  Ma,
std::complex< double >  Mb,
double  fa,
std::complex< double > &  Mres 
)

Definition at line 403 of file refract.cpp.

References eToM(), ICEDB_log, icedb::logging::ICEDB_LOG_DEBUG_2, and mToE().

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  }
STL namespace.
void eToM(std::complex< double > e, std::complex< double > &m)
Definition: refract.cpp:489
void mToE(std::complex< double > m, std::complex< double > &e)
Definition: refract.cpp:480
#define ICEDB_log(c, p, x)
Definition: logging.hpp:45
Here is the call graph for this function:

◆ mToE() [1/2]

std::complex< double > icedb::refract::mToE ( std::complex< double >  m)

m to e converters

Definition at line 476 of file refract.cpp.

Referenced by bruggeman(), debyeDry(), maxwellGarnettEllipsoids(), maxwellGarnettSpheres(), mToE(), and sihvola().

477  {
478  return m * m;
479  }
Here is the caller graph for this function:

◆ mToE() [2/2]

void icedb::refract::mToE ( std::complex< double >  m,
std::complex< double > &  e 
)

Definition at line 480 of file refract.cpp.

References mToE().

481  {
482  e = mToE(m);
483  }
void mToE(std::complex< double > m, std::complex< double > &e)
Definition: refract.cpp:480
Here is the call graph for this function:

◆ prepRefract() [1/2]

void icedb::refract::prepRefract ( provider_p  prov,
const std::string &  inFreqUnits,
refractFunction_freqonly_t res 
)

Translation function exists to ensure that the units are passed as expected.

Definition at line 268 of file refract.cpp.

References icedb::refract::provider_s::FREQ, icedb::units::conv_spec::generate(), ICEDB_throw, icedb::error::xBadFunctionMap, and icedb::error::xBadInput.

Referenced by main().

269  {
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  }
#define ICEDB_throw(x)
Definition: error.hpp:88
std::shared_ptr< const converter > converter_p
Definition: units.hpp:16
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepRefract() [2/2]

void icedb::refract::prepRefract ( provider_p  prov,
const std::string &  inFreqUnits,
const std::string &  inTempUnits,
refractFunction_freq_temp_t res 
)

Translation function exists to ensure that the units are passed as expected.

Definition at line 302 of file refract.cpp.

References icedb::refract::provider_s::FREQTEMP, icedb::units::converter::generate(), icedb::units::conv_spec::generate(), ICEDB_throw, icedb::error::xBadFunctionMap, and icedb::error::xBadInput.

304  {
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  }
#define ICEDB_throw(x)
Definition: error.hpp:88
std::shared_ptr< const converter > converter_p
Definition: units.hpp:16
Here is the call graph for this function:

◆ sihvola()

void icedb::refract::sihvola ( std::complex< double >  Ma,
std::complex< double >  Mb,
double  fa,
double  nu,
std::complex< double > &  Mres 
)

Formula is: (e_eff - eb) / (e_eff + 2eb + v(e_eff - eb)) - fa (ea-eb)/(ea+2eb+v(e_eff-eb) = 0 This formula has no analytic solution. It is also complex-valued. Its derivative is hard to calculate. Because of this, I will be using the complex secant method to find the zeros. This is also why the other mixing formulas do not call this code.

Definition at line 443 of file refract.cpp.

References eToM(), ICEDB_log, icedb::logging::ICEDB_LOG_DEBUG_2, mToE(), and icedb::zeros::secantMethod().

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  }
STL namespace.
U secantMethod(const T &f, U guess_a, U guess_b, double eps=0.000001, size_t maxIter=50)
Definition: zeros.hpp:17
void eToM(std::complex< double > e, std::complex< double > &m)
Definition: refract.cpp:489
void mToE(std::complex< double > m, std::complex< double > &e)
Definition: refract.cpp:480
#define ICEDB_log(c, p, x)
Definition: logging.hpp:45
Here is the call graph for this function: