/* This file is part of Lemma, a geophysical modelling and inversion API */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** @file @author Trevor Irons @date 12/02/2009 @version $Id: emearth1d.h 266 2015-04-01 03:24:00Z tirons $ **/ #ifndef __EMEARTH1D_H #define __EMEARTH1D_H #include "dipolesource.h" #include "layeredearthem.h" #include "receiverpoints.h" #include "WireAntenna.h" #include "PolygonalWireAntenna.h" #include "kernelem1dspec.h" #include "kernelem1dmanager.h" #include "hankeltransformgaussianquadrature.h" #include "hankeltransformhankel2.h" #include "FHTKey.h" #include "FHTKey51.h" #include "FHTKey101.h" #include "QWEKey.h" #include "CubicSplineInterpolator.h" #ifdef HAVEBOOSTPROGRESS #include "boost/progress.hpp" #endif namespace Lemma { // ======================================================================= // Class: EmEarth1D /// \brief Implimentation of 1D EM solution. /// \details We've done a lot of different things. // ======================================================================= class EMEarth1D : public LemmaObject { friend std::ostream &operator<<(std::ostream &stream, const EMEarth1D &ob); public: //friend class KernelEm1D; // ==================== LIFECYCLE =========================== /** * Returns pointer to new EMEarth1D. Location is * initialized to (0,0,0) type and polarization are * initialized to nonworking values that will throw * exceptions if used. */ static EMEarth1D* New(); /** * @copybrief LemmaObject::Delete() * @copydetails LemmaObject::Delete() */ void Delete(); /** stream debugging info to std::out */ void Query(); #ifdef HAVE_YAMLCPP /** YAML Serializing method */ YAML::Node Serialize() const; //static EMEarth1D* DeSerialize(const YAML::Node& node); #endif // ==================== OPERATORS =========================== // ==================== OPERATIONS =========================== /// Calculates the field(s) due to an ungrounded dipole source /// Calls FORTRAN library em1d (em1dnew.for) #ifdef COMPILE_FORTRAN void MakeCalc(); #endif /** C++ wrapper for em1dnew.for, serial */ void MakeCalc3(); /** Calculates the field(s) due to a wire antennae */ void CalculateWireAntennaFields(bool progressbar=false); // ==================== ACCESS =========================== /** Attaches an antennae */ void AttachWireAntenna(WireAntenna *antennae); /** Attaches a dipole for calculation */ void AttachDipoleSource(DipoleSource *dipole); /** Attaches a layered earth model for calculation */ void AttachLayeredEarthEM(LayeredEarthEM *Earth); /** Attaches a set of receiver points for calculation */ void AttachReceiverPoints(ReceiverPoints *Receivers); /** Sets the fields that are calcultated, E,H or BOTH */ void SetFieldsToCalculate(const FIELDCALCULATIONS &calc); /** Sets the method to use to evaluate the Hankel integral, */ void SetHankelTransformMethod(const HANKELTRANSFORMTYPE &type); // ==================== INQUIRY =========================== protected: // ==================== LIFECYCLE =========================== /** Default protected constructor. */ EMEarth1D (const std::string& name); #ifdef HAVE_YAMLCPP /** Default protected constructor. */ EMEarth1D (const YAML::Node& node); #endif /** Default protected constructor. */ ~EMEarth1D (); /** * @copybrief LemmaObject::Release() * @copydetails LemmaObject::Release() */ void Release(); // ==================== OPERATIONS =========================== /** Used internally, this is the innermost loop of the MakeCalc3, * and CalculateWireAntennaField routines. */ void SolveSingleTxRxPair(const int &irec, HankelTransform *Hankel, const Real &wavef, const int &ifreq, DipoleSource *tDipole); /** Used internally, this is the innermost loop of the MakeCalc3, * and CalculateWireAntennaField routines. */ void SolveLaggedTxRxPair(const int &irec, Hankel2* Hankel, const Real &wavef, const int &ifreq, PolygonalWireAntenna* antenna); /** Removes all connections */ void DetachAll(); // ==================== DATA MEMBERS =========================== /** Computes field due to dipole */ DipoleSource* Dipole; /** Earth model (Cole-cole) */ LayeredEarthEM* Earth; /** Receiver points */ ReceiverPoints* Receivers; /** Wire antennae tx */ WireAntenna* Antenna; /** What fields are wanted */ FIELDCALCULATIONS FieldsToCalculate; /** The type of Hankel transform to use, default to digital * filtering */ HANKELTRANSFORMTYPE HankelType; /** Counter for number of caclulations made */ int icalcinner; /** Counter for number of caclulations made */ int icalc; }; // ----- end of class EMEarth1D ----- ///////////////////////////////////////// // Exception classes /** If a Receivers Class is NULL valued, throw this. */ class NullReceivers : public std::runtime_error { /** Thrown when Receivers pointer is NULL */ public: NullReceivers(); }; /** If an Antenna is NULL valued, throw this error. */ class NullAntenna : public std::runtime_error { /** Thrown when an antenna pointer is NULL */ public: NullAntenna(); }; /** If an Instrument is NULL valued, throw this error. */ class NullInstrument : public std::runtime_error { /** thrown when an instrument pointer is NULL. * @param[in] ptr is a pointer to the class throwing the exception. */ public: NullInstrument(LemmaObject* ptr); }; /** If a dipole source is specified, but a method calling a wire antenna is * called, throw this. */ class DipoleSourceSpecifiedForWireAntennaCalc : public std::runtime_error { /** Thrown when a dipole source is specified when a wire antenna is * expected */ public: DipoleSourceSpecifiedForWireAntennaCalc(); }; } // Namespace Lemma #endif // __EMEARTH1D_H