123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897 |
-
-
-
-
-
-
- #include "EMEarth1D.h"
- #include "FieldPoints.h"
- #include "WireAntenna.h"
- #include "PolygonalWireAntenna.h"
-
- #ifdef LEMMAUSEOMP
- #include "omp.h"
- #endif
-
- namespace Lemma {
-
- std::ostream &operator << (std::ostream &stream, const EMEarth1D &ob) {
- stream << ob.Serialize() << "\n";
- return stream;
- }
-
- #ifdef KIHALEE_EM1D
-
-
- extern "C" { void em1dcall_(int &itype,
- int &ipol,
- int &nlay,
- int &nfreq,
- int &nfield,
- int &nres,
- int &jtype,
- int &jgamma,
- double &acc,
- double *dep,
- std::complex<double> *sig,
- double *susl,
- double *sush,
- double *sustau,
- double *susalp,
- double *eprl,
- double *eprh,
- double *eprtau,
- double *epralp,
- double &finit,
- double &flimit,
- double &dlimit,
- double &lfinc,
- double &tx,
- double &ty,
- double &tz,
- double *rxx,
- double *rxy,
- double *rxz,
- std::complex<double> *ex,
- std::complex<double> *ey,
- std::complex<double> *ez,
- std::complex<double> *hx,
- std::complex<double> *hy,
- std::complex<double> *hz );
- }
- #endif
-
-
-
-
- EMEarth1D::EMEarth1D( const ctor_key& key ) : LemmaObject( key ),
- Dipole(nullptr), Earth(nullptr), Receivers(nullptr), Antenna(nullptr),
- FieldsToCalculate(BOTH), HankelType(ANDERSON801), icalcinner(0), icalc(0)
-
-
-
- {
- }
-
- EMEarth1D::~EMEarth1D() {
- }
-
- std::shared_ptr<EMEarth1D> EMEarth1D::NewSP() {
- return std::make_shared<EMEarth1D>(ctor_key());
- }
-
- YAML::Node EMEarth1D::Serialize() const {
- YAML::Node node = LemmaObject::Serialize();
- node["FieldsToCalculate"] = enum2String(FieldsToCalculate);
- node["HankelType"] = enum2String(HankelType);
-
- if (Earth != nullptr) node["Earth"] = Earth->Serialize();
-
- if (Antenna != nullptr) node["Antenna"] = Antenna->Serialize();
- node.SetTag( this->GetName() );
- return node;
- }
-
-
-
-
-
-
- inline std::string EMEarth1D::GetName ( ) const {
- return CName;
- }
-
-
- void EMEarth1D::AttachDipoleSource( std::shared_ptr<DipoleSource> dipoleptr) {
- Dipole = dipoleptr;
- }
-
- void EMEarth1D::AttachLayeredEarthEM( std::shared_ptr<LayeredEarthEM> earthptr) {
- Earth = earthptr;
- }
-
- void EMEarth1D::AttachFieldPoints( std::shared_ptr<FieldPoints> recptr) {
-
- Receivers = recptr;
- if (Receivers == nullptr) {
- std::cout << "nullptr Receivers in emearth1d.cpp " << std::endl;
- return;
- }
-
-
-
- if (Dipole != nullptr) {
- switch (FieldsToCalculate) {
- case E:
- Receivers->SetNumberOfBinsE(Dipole->GetNumberOfFrequencies());
- break;
- case H:
- Receivers->SetNumberOfBinsH(Dipole->GetNumberOfFrequencies());
- break;
- case BOTH:
- Receivers->SetNumberOfBinsE(Dipole->GetNumberOfFrequencies());
- Receivers->SetNumberOfBinsH(Dipole->GetNumberOfFrequencies());
- break;
- }
- } else if (Antenna != nullptr) {
- switch (FieldsToCalculate) {
- case E:
- Receivers->SetNumberOfBinsE(Antenna->GetNumberOfFrequencies());
- break;
- case H:
- Receivers->SetNumberOfBinsH(Antenna->GetNumberOfFrequencies());
- break;
- case BOTH:
- Receivers->SetNumberOfBinsE(Antenna->GetNumberOfFrequencies());
- Receivers->SetNumberOfBinsH(Antenna->GetNumberOfFrequencies());
- break;
- }
- }
- }
-
- void EMEarth1D::AttachWireAntenna(std::shared_ptr<WireAntenna> antennae) {
- this->Antenna = antennae;
- }
-
- void EMEarth1D::SetFieldsToCalculate(const FIELDCALCULATIONS &calc) {
- FieldsToCalculate = calc;
- }
-
- void EMEarth1D::SetHankelTransformMethod( const HANKELTRANSFORMTYPE &type) {
- HankelType = type;
- }
-
- void EMEarth1D::Query() {
- std::cout << "EmEarth1D::Query()" << std::endl;
-
- std::cout << "Dipole " << Dipole;
- if (Dipole) std::cout << *Dipole << std::endl;
-
- std::cout << "Earth " << Earth;
- if (Earth) std::cout << *Earth << std::endl;
-
- std::cout << "Receivers " << Earth;
- if (Earth) std::cout << *Receivers << std::endl;
-
- std::cout << "Antenna " << Earth;
- if (Antenna) std::cout << *Antenna << std::endl;
-
- std::cout << "icalc " << icalc << std::endl;
-
- std::cout << "icalcinner " << icalcinner << std::endl;
- }
-
-
-
- void EMEarth1D::CalculateWireAntennaFields(bool progressbar) {
-
- #ifdef HAVE_BOOST_PROGRESS
- boost::progress_display *disp;
- #endif
-
- if (Earth == nullptr) {
- throw NullEarth();
- }
- if (Receivers == nullptr) {
- throw NullReceivers();
- }
- if (Antenna == nullptr) {
- throw NullAntenna();
- }
- if (Dipole != nullptr) {
- throw DipoleSourceSpecifiedForWireAntennaCalc();
- }
-
- Receivers->ClearFields();
-
-
- switch(FieldsToCalculate) {
- case E:
- if (Receivers->NumberOfBinsE != Antenna->GetNumberOfFrequencies())
- Receivers->SetNumberOfBinsE(Antenna->GetNumberOfFrequencies());
- break;
- case H:
- if (Receivers->NumberOfBinsH != Antenna->GetNumberOfFrequencies())
- Receivers->SetNumberOfBinsH(Antenna->GetNumberOfFrequencies());
- break;
- case BOTH:
- if (Receivers->NumberOfBinsH != Antenna->GetNumberOfFrequencies())
- Receivers->SetNumberOfBinsH(Antenna->GetNumberOfFrequencies());
- if (Receivers->NumberOfBinsE != Antenna->GetNumberOfFrequencies())
- Receivers->SetNumberOfBinsE(Antenna->GetNumberOfFrequencies());
- break;
- }
-
- if (Antenna->GetName() == std::string("PolygonalWireAntenna") || Antenna->GetName() == std::string("TEMTransmitter") ) {
- icalc += 1;
-
- if (Antenna->IsHorizontallyPlanar() && ( HankelType == ANDERSON801 || HankelType== FHTKEY201 )) {
- #ifdef HAVE_BOOST_PROGRESS
- if (progressbar) {
- disp = new boost::progress_display( Receivers->GetNumberOfPoints()*Antenna->GetNumberOfFrequencies() );
- }
- #endif
- for (int ifreq=0; ifreq<Antenna->GetNumberOfFrequencies();++ifreq) {
- Real wavef = 2.*PI* Antenna->GetFrequency(ifreq);
- #ifdef LEMMAUSEOMP
- #pragma omp parallel
- {
- #endif
- auto Hankel = HankelTransformFactory::NewSP( HankelType );
- #ifdef LEMMAUSEOMP
- #pragma omp for schedule(static, 1)
- #endif
- for (int irec=0; irec<Receivers->GetNumberOfPoints(); ++irec) {
- auto AntCopy = static_cast<PolygonalWireAntenna*>(Antenna.get())->ClonePA();
- SolveLaggedTxRxPair(irec, Hankel.get(), wavef, ifreq, AntCopy.get());
- #ifdef HAVE_BOOST_PROGRESS
- if (progressbar) ++(*disp);
- #endif
- }
- #pragma omp barrier
- #ifdef LEMMAUSEOMP
- }
- #endif
- }
- } else
- if (Receivers->GetNumberOfPoints() > Antenna->GetNumberOfFrequencies()) {
-
-
-
- #ifdef HAVE_BOOST_PROGRESS
- if (progressbar) {
- disp = new boost::progress_display( Receivers->GetNumberOfPoints()*Antenna->GetNumberOfFrequencies() );
- }
- #endif
-
-
- #ifdef LEMMAUSEOMP
- #pragma omp parallel
- #endif
- {
-
-
- auto AntCopy = static_cast<PolygonalWireAntenna*>(Antenna.get())->ClonePA();
-
- std::shared_ptr<HankelTransform> Hankel;
- switch (HankelType) {
- case ANDERSON801:
- Hankel = FHTAnderson801::NewSP();
- break;
- case CHAVE:
- Hankel = GQChave::NewSP();
- break;
- case FHTKEY201:
- Hankel = FHTKey201::NewSP();
- break;
- case FHTKEY101:
- Hankel = FHTKey101::NewSP();
- break;
- case FHTKEY51:
- Hankel = FHTKey51::NewSP();
- break;
- case QWEKEY:
- Hankel = QWEKey::NewSP();
- break;
- default:
- std::cerr << "Hankel transform cannot be created\n";
- exit(EXIT_FAILURE);
- }
-
-
- #ifdef LEMMAUSEOMP
- #pragma omp for schedule(static, 1)
- #endif
- for (int irec=0; irec<Receivers->GetNumberOfPoints(); ++irec) {
- if (!Receivers->GetMask(irec)) {
- AntCopy->ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
- for (int idip=0; idip<AntCopy->GetNumberOfDipoles(); ++idip) {
- auto tDipole = AntCopy->GetDipoleSource(idip);
-
-
-
- for (int ifreq=0; ifreq<tDipole->GetNumberOfFrequencies();
- ++ifreq) {
-
- Real wavef = tDipole->GetAngularFrequency(ifreq) *
- std::sqrt(MU0*EPSILON0);
- SolveSingleTxRxPair(irec, Hankel.get(), wavef, ifreq, tDipole.get());
- }
- }
- }
-
-
-
- #ifdef HAVE_BOOST_PROGRESS
- if (progressbar) ++(*disp);
- #endif
- }
- }
- } else if (Antenna->GetNumberOfFrequencies() > 8) {
-
-
- for (int irec=0; irec<Receivers->GetNumberOfPoints(); ++irec) {
- if (!Receivers->GetMask(irec)) {
- static_cast<PolygonalWireAntenna*>(Antenna.get())->ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
- #ifdef LEMMAUSEOMP
- #pragma omp parallel
- #endif
- {
-
- std::shared_ptr<HankelTransform> Hankel;
- switch (HankelType) {
- case ANDERSON801:
- Hankel = FHTAnderson801::NewSP();
- break;
- case CHAVE:
- Hankel = GQChave::NewSP();
- break;
- case FHTKEY201:
- Hankel = FHTKey201::NewSP();
- break;
- case FHTKEY101:
- Hankel = FHTKey101::NewSP();
- break;
- case FHTKEY51:
- Hankel = FHTKey51::NewSP();
- break;
- case QWEKEY:
- Hankel = QWEKey::NewSP();
- break;
- default:
- std::cerr << "Hankel transform cannot be created\n";
- exit(EXIT_FAILURE);
- }
- #ifdef LEMMAUSEOMP
- #pragma omp for schedule(static, 1)
- #endif
- for (int ifreq=0; ifreq<Antenna->GetNumberOfFrequencies(); ++ifreq) {
- for (int idip=0; idip<Antenna->GetNumberOfDipoles(); ++idip) {
- auto tDipole = Antenna->GetDipoleSource(idip);
-
- Real wavef = tDipole->GetAngularFrequency(ifreq) *
- std::sqrt(MU0*EPSILON0);
- SolveSingleTxRxPair(irec, Hankel.get(), wavef, ifreq, tDipole.get());
- }
- }
- }
- }
- #ifdef HAVE_BOOST_PROGRESS
-
-
-
- #endif
- }
-
- }
- else {
-
- for (int irec=0; irec<Receivers->GetNumberOfPoints(); ++irec) {
- if (!Receivers->GetMask(irec)) {
-
- static_cast<PolygonalWireAntenna*>(Antenna.get())->ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
-
-
-
-
-
-
-
-
- #ifdef LEMMAUSEOMP
- #pragma omp parallel
- #endif
- {
- std::shared_ptr<HankelTransform> Hankel;
- switch (HankelType) {
- case ANDERSON801:
- Hankel = FHTAnderson801::NewSP();
- break;
- case CHAVE:
- Hankel = GQChave::NewSP();
- break;
- case FHTKEY201:
- Hankel = FHTKey201::NewSP();
- break;
- case FHTKEY101:
- Hankel = FHTKey101::NewSP();
- break;
- case FHTKEY51:
- Hankel = FHTKey51::NewSP();
- break;
- case QWEKEY:
- Hankel = QWEKey::NewSP();
- break;
- default:
- std::cerr << "Hankel transform cannot be created\n";
- exit(EXIT_FAILURE);
- }
- for (int ifreq=0; ifreq<Antenna->GetNumberOfFrequencies(); ++ifreq) {
- #ifdef LEMMAUSEOMP
- #pragma omp for schedule(static, 1)
- #endif
- for (int idip=0; idip<Antenna->GetNumberOfDipoles(); ++idip) {
-
-
-
-
- auto tDipole = Antenna->GetDipoleSource(idip);
-
- Real wavef = tDipole->GetAngularFrequency(ifreq) *
- std::sqrt(MU0*EPSILON0);
- SolveSingleTxRxPair(irec, Hankel.get(), wavef, ifreq, tDipole.get());
- }
- }
- }
- }
- #ifdef HAVE_BOOST_PROGRESS
-
-
-
- #endif
- }
- }
- } else {
- std::cerr << "Lemma with WireAntenna class is currently broken"
- << " fix or use PolygonalWireAntenna\n" << std::endl;
- exit(EXIT_FAILURE);
-
-
-
- for (int idip=0; idip<Antenna->GetNumberOfDipoles(); ++idip) {
- this->Dipole = Antenna->GetDipoleSource(idip);
- MakeCalc3();
-
- }
- this->Dipole = nullptr;
- }
-
- #ifdef HAVE_BOOST_PROGRESS
- if (progressbar) {
- delete disp;
- }
- #endif
- }
-
- #ifdef KIHALEE_EM1D
- void EMEarth1D::MakeCalc() {
-
- int itype;
- switch (this->Dipole->GetDipoleSourceType()) {
- case (GROUNDEDELECTRICDIPOLE) :
- itype = 1;
- break;
- case (MAGNETICDIPOLE) :
- itype = 2;
- break;
- case (UNGROUNDEDELECTRICDIPOLE) :
- std::cerr << "Fortran routine cannot calculate ungrounded"
- "electric dipole\n";
- default:
- throw NonValidDipoleType();
- }
-
- int ipol ;
- Vector3r Pol = this->Dipole->GetPolarisation();
- if (std::abs(Pol[0]-1) < 1e-5) {
- ipol = 1;
- } else if (std::abs(Pol[1]-1) < 1e-5) {
- ipol = 2;
- } else if (std::abs(Pol[2]-1) < 1e-5) {
- ipol = 3;
- } else {
- std::cerr << "Fortran routine cannot calculate arbitrary "
- "dipole polarisation, set to x, y, or z\n";
- }
-
- int nlay = Earth->GetNumberOfNonAirLayers();
-
- if (nlay > MAXLAYERS) {
- std::cerr << "FORTRAN CODE CAN ONLY HANDLE " << MAXLAYERS
- << " LAYERS\n";
- throw EarthModelWithMoreThanMaxLayers();
- }
-
- int nfreq = 1;
-
- int nfield;
- switch (FieldsToCalculate) {
- case E:
- nfield = 1;
- break;
- case H:
- nfield = 2;
- break;
- case BOTH:
- nfield = 3;
- break;
- default:
- throw 7;
- }
-
- int nres = Receivers->GetNumberOfPoints();
- int jtype = 3;
-
-
-
-
-
- int jgamma = 0;
-
-
- double acc = 0.;
-
-
-
-
-
- double *dep = new double[MAXLAYERS];
- dep[0] = 0.;
- for (int ilay=1; ilay<Earth->GetNumberOfLayers(); ++ilay) {
- dep[ilay] = dep[ilay-1] + Earth->GetLayerThickness(ilay);
-
- }
-
- std::complex<double> *sig = new std::complex<double> [MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- sig[ilay-1] = (std::complex<double>)(Earth->GetLayerConductivity(ilay));
- }
-
-
-
-
-
-
-
- double *susl = new double[MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- susl[ilay-1] = Earth->GetLayerLowFreqSusceptibility(ilay);
- }
-
- double *sush = new double[MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- sush[ilay-1] = Earth->GetLayerHighFreqSusceptibility(ilay);
- }
-
- double *sustau = new double[MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- sustau[ilay-1] = Earth->GetLayerTauSusceptibility(ilay);
- }
-
- double *susalp = new double[MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- susalp[ilay-1] = Earth->GetLayerBreathSusceptibility(ilay);
- }
-
- double *eprl = new double[MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- eprl[ilay-1] = Earth->GetLayerLowFreqPermitivity(ilay);
- }
-
- double *eprh = new double[MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- eprh[ilay-1] = Earth->GetLayerHighFreqPermitivity(ilay);
- }
-
- double *eprtau = new double[MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- eprtau[ilay-1] = Earth->GetLayerTauPermitivity(ilay);
- }
-
- double *epralp = new double[MAXLAYERS];
- for (int ilay=1; ilay<=nlay; ++ilay) {
- epralp[ilay-1] = Earth->GetLayerBreathPermitivity(ilay);
- }
-
-
- double finit = Dipole->GetFrequency(0);
- double flimit = Dipole->GetFrequency(0);
- double dlimit = Dipole->GetFrequency(0);
- double lfinc(1);
-
-
- double txx = Dipole->GetLocation(0);
- double txy = Dipole->GetLocation(1);
- double txz = Dipole->GetLocation(2);
-
-
-
-
- const int MAXREC = 15;
- double *rxx = new double [MAXREC];
- double *rxy = new double [MAXREC];
- double *rxz = new double [MAXREC];
-
- std::complex<double> *ex = new std::complex<double>[MAXREC];
- std::complex<double> *ey = new std::complex<double>[MAXREC];
- std::complex<double> *ez = new std::complex<double>[MAXREC];
-
- std::complex<double> *hx = new std::complex<double>[MAXREC];
- std::complex<double> *hy = new std::complex<double>[MAXREC];
- std::complex<double> *hz = new std::complex<double>[MAXREC];
-
- int nres2 = MAXREC;
- int ii=0;
-
- for (ii=0; ii<nres-MAXREC; ii+=MAXREC) {
-
- for (int ir=0; ir<MAXREC; ++ir) {
-
- rxx[ir] = Receivers->GetLocation(ii+ir)[0];
- rxy[ir] = Receivers->GetLocation(ii+ir)[1];
- rxz[ir] = Receivers->GetLocation(ii+ir)[2];
- }
-
- em1dcall_(itype, ipol, nlay, nfreq, nfield, nres2, jtype,
- jgamma, acc, dep, sig, susl, sush, sustau, susalp,
- eprl, eprh, eprtau, epralp, finit, flimit, dlimit,
- lfinc, txx, txy, txz, rxx, rxy, rxz, ex, ey, ez,
- hx, hy, hz);
-
-
- for (int ir=0; ir<MAXREC; ++ir) {
-
- ex[ir] *= Dipole->GetMoment();
- ey[ir] *= Dipole->GetMoment();
- ez[ir] *= Dipole->GetMoment();
-
- hx[ir] *= Dipole->GetMoment();
- hy[ir] *= Dipole->GetMoment();
- hz[ir] *= Dipole->GetMoment();
-
-
- this->Receivers->AppendEfield(0, ii+ir, (Complex)(ex[ir]),
- (Complex)(ey[ir]),
- (Complex)(ez[ir]) );
- this->Receivers->AppendHfield(0, ii+ir, (Complex)(hx[ir]),
- (Complex)(hy[ir]),
- (Complex)(hz[ir]) );
- }
- }
-
-
- nres2 = 0;
-
- for (int ir=0; ir<nres-ii; ++ir) {
- rxx[ir] = Receivers->GetLocation(ii+ir)[0];
- rxy[ir] = Receivers->GetLocation(ii+ir)[1];
- rxz[ir] = Receivers->GetLocation(ii+ir)[2];
- ++nres2;
- }
-
- em1dcall_(itype, ipol, nlay, nfreq, nfield, nres2, jtype,
- jgamma, acc, dep, sig, susl, sush, sustau, susalp,
- eprl, eprh, eprtau, epralp, finit, flimit, dlimit,
- lfinc, txx, txy, txz, rxx, rxy, rxz, ex, ey, ez,
- hx, hy, hz);
-
-
- for (int ir=0; ir<nres-ii; ++ir) {
-
- ex[ir] *= Dipole->GetMoment();
- ey[ir] *= Dipole->GetMoment();
- ez[ir] *= Dipole->GetMoment();
-
- hx[ir] *= Dipole->GetMoment();
- hy[ir] *= Dipole->GetMoment();
- hz[ir] *= Dipole->GetMoment();
-
-
- this->Receivers->AppendEfield(0, ii+ir, (Complex)(ex[ir]),
- (Complex)(ey[ir]),
- (Complex)(ez[ir]) );
- this->Receivers->AppendHfield(0, ii+ir, (Complex)(hx[ir]),
- (Complex)(hy[ir]),
- (Complex)(hz[ir]) );
-
- }
-
- delete [] sig;
- delete [] dep;
-
-
-
-
- delete [] susl;
- delete [] sush;
- delete [] susalp;
- delete [] sustau;
-
- delete [] eprl;
- delete [] eprh;
- delete [] epralp;
- delete [] eprtau;
-
- delete [] rxx;
- delete [] rxy;
- delete [] rxz;
-
- delete [] ex;
- delete [] ey;
- delete [] ez;
-
- delete [] hx;
- delete [] hy;
- delete [] hz;
-
- }
- #endif
-
-
- void EMEarth1D::SolveSingleTxRxPair (const int &irec, HankelTransform *Hankel, const Real &wavef, const int &ifreq,
- DipoleSource *tDipole) {
- ++icalcinner;
- Real rho = (Receivers->GetLocation(irec).head<2>() - tDipole->GetLocation().head<2>()).norm();
- tDipole->SetKernels(ifreq, FieldsToCalculate, Receivers, irec, Earth);
- Hankel->ComputeRelated( rho, tDipole->GetKernelManager() );
- tDipole->UpdateFields( ifreq, Hankel, wavef );
- }
-
-
-
-
-
-
-
-
-
-
- void EMEarth1D::SolveLaggedTxRxPair(const int &irec, HankelTransform* Hankel,
- const Real &wavef, const int &ifreq, PolygonalWireAntenna* antenna) {
-
- antenna->ApproximateWithElectricDipoles(Receivers->GetLocation(irec));
-
-
- Real rhomin = 1e9;
- Real rhomax = 1e-9;
- for (int idip=0; idip<antenna->GetNumberOfDipoles(); ++idip) {
- auto tDipole = antenna->GetDipoleSource(idip);
- Real rho = (Receivers->GetLocation(irec).head<2>() - tDipole->GetLocation().head<2>()).norm();
- rhomin = std::min(rhomin, rho);
- rhomax = std::max(rhomax, rho);
- }
-
-
-
- int nlag = 1;
- Real lrho ( 1.01* rhomax );
- while ( lrho > rhomin ) {
- nlag += 1;
- lrho *= Hankel->GetABSER();
- }
-
-
- auto tDipole = antenna->GetDipoleSource(0);
- tDipole->SetKernels(ifreq, FieldsToCalculate, Receivers, irec, Earth);
-
-
- Hankel->ComputeLaggedRelated( 1.01* rhomax, nlag, tDipole->GetKernelManager() );
-
-
-
-
-
- for (int idip=0; idip<antenna->GetNumberOfDipoles(); ++idip) {
-
- auto tDipole = antenna->GetDipoleSource(idip);
- tDipole->SetKernels(ifreq, FieldsToCalculate, Receivers, irec, Earth);
-
- Real rho = (Receivers->GetLocation(irec).head<2>() - tDipole->GetLocation().head<2>()).norm();
-
- Hankel->SetLaggedArg( rho );
- tDipole->UpdateFields( ifreq, Hankel, wavef );
- }
-
-
- }
-
-
-
-
- void EMEarth1D::MakeCalc3() {
-
- if ( Dipole == nullptr ) throw NullDipoleSource();
-
- if (Earth == nullptr) throw NullEarth();
-
- if (Receivers == nullptr) throw NullReceivers();
-
- #ifdef LEMMAUSEOMP
- #pragma omp parallel
- #endif
- {
- #ifdef LEMMAUSEOMP
- int tid = omp_get_thread_num();
- int nthreads = omp_get_num_threads();
- #else
- int tid=0;
- int nthreads=1;
- #endif
- auto tDipole = Dipole->Clone();
- std::shared_ptr<HankelTransform> Hankel;
- switch (HankelType) {
- case ANDERSON801:
- Hankel = FHTAnderson801::NewSP();
- break;
- case CHAVE:
- Hankel = GQChave::NewSP();
- break;
- case FHTKEY201:
- Hankel = FHTKey201::NewSP();
- break;
- case FHTKEY101:
- Hankel = FHTKey101::NewSP();
- break;
- case FHTKEY51:
- Hankel = FHTKey51::NewSP();
- break;
- case QWEKEY:
- Hankel = QWEKey::NewSP();
- break;
- default:
- std::cerr << "Hankel transform cannot be created\n";
- exit(EXIT_FAILURE);
- }
- if ( tDipole->GetNumberOfFrequencies() < Receivers->GetNumberOfPoints() ) {
- for (int ifreq=0; ifreq<tDipole->GetNumberOfFrequencies(); ++ifreq) {
-
- Real wavef = tDipole->GetAngularFrequency(ifreq) * std::sqrt(MU0*EPSILON0);
- for (int irec=tid; irec<Receivers->GetNumberOfPoints(); irec+=nthreads) {
- SolveSingleTxRxPair(irec, Hankel.get(), wavef, ifreq, tDipole.get());
- }
- }
- } else {
- for (int irec=0; irec<Receivers->GetNumberOfPoints(); ++irec) {
- for (int ifreq=tid; ifreq<tDipole->GetNumberOfFrequencies(); ifreq+=nthreads) {
-
- Real wavef = tDipole->GetAngularFrequency(ifreq) * std::sqrt(MU0*EPSILON0);
- SolveSingleTxRxPair(irec, Hankel.get(), wavef, ifreq, tDipole.get());
- }
- }
- }
- }
- }
-
- NullReceivers::NullReceivers() :
- runtime_error("nullptr RECEIVERS") {}
-
- NullAntenna::NullAntenna() :
- runtime_error("nullptr ANTENNA") {}
-
- NullInstrument::NullInstrument(LemmaObject* ptr) :
- runtime_error("nullptr INSTRUMENT") {
- std::cout << "Thrown by instance of "
- << ptr->GetName() << std::endl;
- }
-
- DipoleSourceSpecifiedForWireAntennaCalc::
- DipoleSourceSpecifiedForWireAntennaCalc() :
- runtime_error("DIPOLE SOURCE SPECIFIED FOR WIRE ANTENNA CALC"){}
-
- }
|