GeographicLib  1.21
MagneticCircle.hpp
Go to the documentation of this file.
00001 /**
00002  * \file MagneticCircle.hpp
00003  * \brief Header for GeographicLib::MagneticCircle class
00004  *
00005  * Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed under
00006  * the MIT/X11 License.  For more information, see
00007  * http://geographiclib.sourceforge.net/
00008  **********************************************************************/
00009 
00010 #if !defined(GEOGRAPHICLIB_MAGNETICCIRCLE_HPP)
00011 #define GEOGRAPHICLIB_MAGNETICCIRCLE_HPP \
00012   "$Id: 5b3adc58d894f36ca4206864eb565541f24ff492 $"
00013 
00014 #include <string>
00015 #include <vector>
00016 #include <GeographicLib/Constants.hpp>
00017 #include <GeographicLib/CircularEngine.hpp>
00018 
00019 namespace GeographicLib {
00020 
00021   /**
00022    * \brief Geomagnetic field on a circle of latitude
00023    *
00024    * Evaluate the earth's magnetic field on a circle of constant height and
00025    * latitude.  This uses a CircleEngine to pre-evaluate the inner sum of the
00026    * spherical harmonic sum, allowing the values of the field at several
00027    * different longitudes to be evaluated rapidly.
00028    *
00029    * Use MagneticModel::Circle to create a MagneticCircle object.  (The
00030    * constructor for this class is private.)
00031    *
00032    * Example of use:
00033    * \include example-MagneticCircle.cpp
00034    *
00035    * <a href="MagneticField.1.html">MagneticField</a> is a command-line utility
00036    * providing access to the functionality of MagneticModel and MagneticCircle.
00037    **********************************************************************/
00038 
00039   class GEOGRAPHIC_EXPORT MagneticCircle {
00040   private:
00041     typedef Math::real real;
00042 
00043     real _a, _f, _lat, _h, _t, _cphi, _sphi, _t1, _dt0;
00044     bool _interpolate;
00045     CircularEngine _circ0, _circ1;
00046 
00047     MagneticCircle(real a, real f, real lat, real h, real t,
00048                    real cphi, real sphi, real t1, real dt0,
00049                    bool interpolate,
00050                    const CircularEngine& circ0, const CircularEngine& circ1)
00051       : _a(a)
00052       , _f(f)
00053       , _lat(lat)
00054       , _h(h)
00055       , _t(t)
00056       , _cphi(cphi)
00057       , _sphi(sphi)
00058       , _t1(t1)
00059       , _dt0(dt0)
00060       , _interpolate(interpolate)
00061       , _circ0(circ0)
00062       , _circ1(circ1)
00063     {}
00064 
00065     void Field(real lon, bool diffp,
00066                real& Bx, real& By, real& Bz,
00067                real& Bxt, real& Byt, real& Bzt) const throw();
00068 
00069     friend class MagneticModel; // MagneticModel calls the private constructor
00070 
00071   public:
00072 
00073     /**
00074      * A default constructor for the normal gravity.  This sets up an
00075      * uninitialized object which can be later replaced by the
00076      * MagneticModel::Circle.
00077      **********************************************************************/
00078     MagneticCircle() : _a(-1) {}
00079 
00080     /** \name Compute the magnetic field
00081      **********************************************************************/
00082     ///@{
00083     /**
00084      * Evaluate the components of the geomagnetic field at a particular
00085      * longitude.
00086      *
00087      * @param[in] lon longitude of the point (degrees).
00088      * @param[out] Bx the easterly component of the magnetic field (nanotesla).
00089      * @param[out] By the northerly component of the magnetic field (nanotesla).
00090      * @param[out] Bz the vertical (up) component of the magnetic field
00091      *   (nanotesla).
00092      **********************************************************************/
00093     void operator()(real lon, real& Bx, real& By, real& Bz) const throw() {
00094       real dummy;
00095       Field(lon, false, Bx, By, Bz, dummy, dummy, dummy);
00096     }
00097 
00098     /**
00099      * Evaluate the components of the geomagnetic field and their time
00100      * derivatives at a particular longitude.
00101      *
00102      * @param[in] lon longitude of the point (degrees).
00103      * @param[out] Bx the easterly component of the magnetic field (nanotesla).
00104      * @param[out] By the northerly component of the magnetic field (nanotesla).
00105      * @param[out] Bz the vertical (up) component of the magnetic field
00106      *   (nanotesla).
00107      * @param[out] Bxt the rate of change of \e Bx (nT/yr).
00108      * @param[out] Byt the rate of change of \e By (nT/yr).
00109      * @param[out] Bzt the rate of change of \e Bz (nT/yr).
00110      **********************************************************************/
00111     void operator()(real lon, real& Bx, real& By, real& Bz,
00112                     real& Bxt, real& Byt, real& Bzt) const throw() {
00113       Field(lon, true, Bx, By, Bz, Bxt, Byt, Bzt);
00114     }
00115     ///@}
00116 
00117     /** \name Inspector functions
00118      **********************************************************************/
00119     ///@{
00120     /**
00121      * @return true if the object has been initialized.
00122      **********************************************************************/
00123     bool Init() const throw() { return _a > 0; }
00124     /**
00125      * @return \e a the equatorial radius of the ellipsoid (meters).  This is
00126      *   the value inherited from the MagneticModel object used in the
00127      *   constructor.
00128      **********************************************************************/
00129     Math::real MajorRadius() const throw()
00130     { return Init() ? _a : Math::NaN<real>(); }
00131     /**
00132      * @return \e f the flattening of the ellipsoid.  This is the value
00133      *   inherited from the MagneticModel object used in the constructor.
00134      **********************************************************************/
00135     Math::real Flattening() const throw()
00136     { return Init() ? _f : Math::NaN<real>(); }
00137     /**
00138      * @return the latitude of the circle (degrees).
00139      **********************************************************************/
00140     Math::real Latitude() const throw()
00141     { return Init() ? _lat : Math::NaN<real>(); }
00142     /**
00143      * @return the height of the circle (meters).
00144      **********************************************************************/
00145     Math::real Height() const throw()
00146     { return Init() ? _h : Math::NaN<real>(); }
00147     /**
00148      * @return the time (fractional years).
00149      **********************************************************************/
00150     Math::real Time() const throw()
00151     { return Init() ? _t : Math::NaN<real>(); }
00152 
00153     ///@}
00154   };
00155 
00156 } // namespace GeographicLib
00157 
00158 #endif  // GEOGRAPHICLIB_MAGNETICCIRCLE_HPP