KerrHiggs.h

00001 #ifndef gridripper_phys_gr_fixmp_kerrhiggs_KerrHiggs_h
00002 #define gridripper_phys_gr_fixmp_kerrhiggs_KerrHiggs_h
00003 
00004 
00005 #include <gridripper/Parameters.h>
00006 #include <gridripper/amr1d/PDE.h>
00007 #include <gridripper/lang/IllegalArgumentException.h>
00008 #include <gridripper/multipole/ScalarFieldMP.h>
00009 
00010 #include <time.h>
00011 
00012 namespace gridripper { namespace phys { namespace gr { namespace fixmp {
00013 namespace kerrhiggs {
00014 
00015 
00016 using namespace gridripper;
00017 using namespace gridripper::multipole;
00018 using namespace std;
00019 
00020 
00084 class KerrHiggs: public PDE
00085 {
00086 public:
00087 
00089     static const GReal_t EPSILON;
00090 
00092     enum { ind_f=0, ind_ft=1, ind_frh=2 };
00093 
00095     const int maxOrder;
00101     const int arraySize;
00102 
00104     const int I_f;      // <- ind_f*arraySize
00105     const int I_ft;     // <- ind_ft*arraySize
00106     const int I_frh;    // <- ind_frh*arraySize
00108     static const int NUM_INDEP_COMPS=2;
00110     static const int NUM_CONSTRAINTS=1;
00112     static const int NUM_COMPS=NUM_INDEP_COMPS+NUM_CONSTRAINTS;
00113 
00115     static const string COMP_NAMES[NUM_COMPS];
00116     static const string CONSTRAINT_NAMES[NUM_CONSTRAINTS];
00117     static const string COORD_LABELS[2];
00118 
00119 private:
00120 
00122     tvalarray<GReal_t> df;
00123 
00125     tvector< FieldComponents<GReal_t> > fieldat;
00126 
00128     GReal_t M;          // <- mass
00129     GReal_t a;          // <- angular momentum per mass
00130     GReal_t e;          // <- charge
00131     bool isMinkowski;
00132 
00134     GReal_t lambda;    // <- self coupling constant
00135     GReal_t Phi0;      // <- equilibrium field value
00136     // (field mass=2*sqrt(lambda)*Phi0)
00138     bool selfInteraction;
00144     bool allmassive;
00145     // The field is f=(Phi-Phi0)*r in the simulation if selfinteration 
00146     // is on, otherwise f=Phi*r.
00148     GReal_t q;
00149 
00151     GReal_t minrh;
00152     GReal_t maxrh;
00154     GReal_t minrhIntq;
00155     GReal_t maxrhIntq;
00156 
00158     mutable GReal_t r;
00159     mutable GReal_t Delta;
00160     mutable ScalarFieldMP<GComplex_t> Sigma;
00161     mutable ScalarFieldMP<GComplex_t> Gamma;
00162     mutable GComplex_t H2S2SigmaSigma;
00163     mutable GComplex_t H2S2GammaGamma;
00164     mutable GComplex_t scale;
00165     mutable ScalarFieldMP<GComplex_t> scaledSigma;
00166     mutable ScalarFieldMP<GComplex_t> scaledGamma;
00167     ScalarFieldMP<GComplex_t> Y00;
00168     GReal_t neumannTolerance;
00169     mutable GReal_t drhdr;
00170     mutable GReal_t d2rhdr2;
00171     mutable GReal_t dphihdr;
00172     mutable GReal_t d2phihdr2;
00173     mutable ScalarFieldMP<GComplex_t> physf;
00174     mutable ScalarFieldMP<GComplex_t> physft;
00175     mutable ScalarFieldMP<GComplex_t> physfr;
00176     mutable ScalarFieldMP<GComplex_t> physfperSigma;
00177 
00178     /* Start time. */
00179     GReal_t t0;
00181     GReal_t rh0;
00182 
00184     bool isSommerfeld;
00185 
00187     int exclude;
00188 
00190     GReal_t Theta;
00191     tvector< tvector< tvector<GReal_t> > > coeffstorage1;
00192     tvector< tvector< tvector<GReal_t> > > coeffstorage2;
00193 
00194 public:
00195 
00197     class CoordTransf
00198     {
00199         private:
00201             const bool isMinkowski;
00203             const bool isSchwarzschild;
00205             const bool isRotating;
00207             const GReal_t horizono;
00209             const GReal_t horizoni;
00211             const GReal_t surfacegravityo;
00213             const GReal_t surfacegravityi;
00215             const GReal_t specangmom;
00223             const int transformedR;
00229             const int transformedPhi;
00235             const int rstarTableDiscretization;
00237             const GReal_t newtonraphsonTolerance;
00239             const int newtonraphsonMaxIteration;
00241             tvector<GReal_t> invrstarTable;
00243             const GReal_t rstarMin;
00244             const GReal_t rstarMax;
00245             const GReal_t rstarStep;
00246         public:
00248             long double calc_rstar(const long double r);
00249             GReal_t calc_invrstar_newtonraphson(const GReal_t rstar) throw(IllegalArgumentException&);
00250             GReal_t calc_invrstar(const GReal_t rstar);
00252             GReal_t calc_phitilde(const GReal_t r, const GReal_t phi);
00253             GReal_t calc_invphitilde(const GReal_t r, const GReal_t phitilde);
00254         public:
00256             CoordTransf(const GReal_t MArg, const GReal_t aArg, const GReal_t eArg, 
00257                         const int transformedRArg, const int transformedPhiArg, 
00258                         const GReal_t minrhArg, const GReal_t maxrhArg, 
00259                         const int rstarTableDiscretizationArg, 
00260                         const GReal_t newtonraphsonToleranceArg, 
00261                         const int newtonraphsonMaxIterationArg);
00262             ~CoordTransf() {  }
00264             GReal_t calc_rh(const GReal_t r);
00265             GReal_t calc_r(const GReal_t rh);
00266             GReal_t calc_drhdr(const GReal_t r);
00267             GReal_t calc_d2rhdr2(const GReal_t r);
00269             GReal_t calc_phih(const GReal_t r, const GReal_t phi);
00270             GReal_t calc_phi(const GReal_t r, const GReal_t phih);
00271             GReal_t calc_dphihdr(const GReal_t r);
00272             GReal_t calc_d2phihdr2(const GReal_t r);
00273     };
00275     CoordTransf* coordTransf;
00277     static inline ScalarFieldMP<GComplex_t> partial_phih(const ScalarFieldMP<GComplex_t>& field)
00278     {
00279         return partial_phi(field);
00280     }
00281     static inline ScalarFieldMP<GComplex_t> Sqr_partial_phih(const ScalarFieldMP<GComplex_t>& field)
00282     {
00283         return Sqr_partial_phi(field);
00284     }
00285 
00286     KerrHiggs(const Parameters* p, const int maxorder, const int arraysize) throw(IllegalArgumentException&);
00287 
00288     ~KerrHiggs();
00289 
00290     GReal_t getMinX() const;
00291     GReal_t getMaxX() const;
00292     GReal_t getPhysicalMinX() const;
00293     GReal_t getPhysicalMaxX() const;
00294     bool isXPeriodic() const;
00295 
00310     int eval(GReal_t* dF, GReal_t t, GReal_t rh,
00311              const GReal_t* F, const GReal_t* F_rh,
00312              const Grid& G, int i, Grad& d, GReal_t dt);
00313 
00323     void evalConstrainedComponents(Grid& G, int i, FieldWrapper& v);
00324 
00333     void setNonevolvingComponents(Grid& G, Grad& d);
00334 
00335     FieldWrapper* createField(int level) const;
00336 
00337     GReal_t energyDensity(GReal_t t, GReal_t rh,
00338                           const tvalarray<GReal_t>& F) const;
00339 
00340     GReal_t energyFlow(GReal_t t, GReal_t rh,
00341                        const tvalarray<GReal_t>& F) const;
00342 
00343     // Limited to [0,theta]x[0,2pi[.
00344     GReal_t energyFlowLimited(GReal_t t, GReal_t rh, GReal_t theta, 
00345                        tvector< tvector< tvector<GReal_t> > > *coeffstorage, 
00346                        const tvalarray<GReal_t>& F) const;
00347 
00348     GReal_t angmomDensity(GReal_t t, GReal_t rh,
00349                           const tvalarray<GReal_t>& F) const;
00350 
00351     GReal_t angmomFlow(GReal_t t, GReal_t rh,
00352                        const tvalarray<GReal_t>& F) const;
00353 
00354     // Limited to [0,theta]x[0,2pi[.
00355     GReal_t angmomFlowLimited(GReal_t t, GReal_t rh, GReal_t theta, 
00356                        tvector< tvector< tvector<GReal_t> > > *coeffstorage, 
00357                        const tvalarray<GReal_t>& F) const;
00358 
00365     bool canBeExtended(int where) const;
00366 
00368     void mirrorLeft(GReal_t rh, FieldWrapper& f) const;
00369 
00371     void mirrorRight(GReal_t rh, FieldWrapper& f) const;
00372 
00380     bool hasExtendedRefinedFieldData(const Grid& G, int i) const;
00381 
00383     class Energy: public DensityQuantity {
00384     private:
00385         const KerrHiggs& pde;
00386     public:
00387         Energy(const KerrHiggs* p): DensityQuantity(p), pde(*p) { }
00388         GReal_t density(GReal_t t, GReal_t rh, const tvalarray<GReal_t>& F)
00389                         const {
00390             return pde.energyDensity(t, rh, F);
00391         }
00392         GReal_t flow(GReal_t t, GReal_t rh, const tvalarray<GReal_t>& F) const {
00393             return pde.energyFlow(t, rh, F);
00394         }
00395         DensityQuantity* cloneDensityQuantity() const {
00396             return new Energy(&pde);
00397         }
00398     };
00399     Energy theEnergy;
00400 
00402     class EnergyFlowLimited: public DensityQuantity {
00403     private:
00404         const KerrHiggs& pde;
00405         GReal_t theta;
00406         tvector< tvector< tvector<GReal_t> > > *coeffstorage;
00407     public:
00408         EnergyFlowLimited(const KerrHiggs* p, GReal_t Theta, tvector< tvector< tvector<GReal_t> > > *Coeffstorage): DensityQuantity(p), pde(*p), theta(Theta), coeffstorage(Coeffstorage) { }
00409         GReal_t density(GReal_t t, GReal_t rh, const tvalarray<GReal_t>& F)
00410                         const {
00411             return 0.0;
00412         }
00413         GReal_t flow(GReal_t t, GReal_t rh, const tvalarray<GReal_t>& F) const {
00414             return pde.energyFlowLimited(t, rh, theta, coeffstorage, F);
00415         }
00416         DensityQuantity* cloneDensityQuantity() const {
00417             return new EnergyFlowLimited(&pde, theta, coeffstorage);
00418         }
00419         GReal_t getTheta() const { return theta; }
00420         void setTheta(GReal_t Theta)
00421         {
00422             if ( coeffstorage!=NULL )
00423             {
00424                 if ( coeffstorage->size() )
00425                     throw IllegalArgumentException("Cannot change theta after initialized coefficient table!", "gridripper_phys_gr_fixmp_kerrhiggs::KerrHiggs::EnergyFlowLimited::setTheta");
00426             }
00427             theta=Theta;
00428         }
00429     };
00430     EnergyFlowLimited theEnergyFlowLimited1, theEnergyFlowLimited2;
00431 
00433     class Angmom: public DensityQuantity {
00434     private:
00435         const KerrHiggs& pde;
00436     public:
00437         Angmom(const KerrHiggs* p): DensityQuantity(p), pde(*p) { }
00438         GReal_t density(GReal_t t, GReal_t rh, const tvalarray<GReal_t>& F)
00439                         const {
00440             return pde.angmomDensity(t, rh, F);
00441         }
00442         GReal_t flow(GReal_t t, GReal_t rh, const tvalarray<GReal_t>& F)
00443                      const {
00444             return pde.angmomFlow(t, rh, F);
00445         }
00446         DensityQuantity* cloneDensityQuantity() const {
00447             return new Angmom(&pde);
00448         }
00449     };
00450     Angmom theAngmom;
00451 
00453     class AngmomFlowLimited: public DensityQuantity {
00454     private:
00455         const KerrHiggs& pde;
00456         GReal_t theta;
00457         tvector< tvector< tvector<GReal_t> > > *coeffstorage;
00458     public:
00459         AngmomFlowLimited(const KerrHiggs* p, GReal_t Theta, tvector< tvector< tvector<GReal_t> > > *Coeffstorage): DensityQuantity(p), pde(*p), theta(Theta), coeffstorage(Coeffstorage) { }
00460         GReal_t density(GReal_t t, GReal_t rh, const tvalarray<GReal_t>& F)
00461                         const {
00462             return 0.0;
00463         }
00464         GReal_t flow(GReal_t t, GReal_t rh, const tvalarray<GReal_t>& F)
00465                      const {
00466             return pde.angmomFlowLimited(t, rh, theta, coeffstorage, F);
00467         }
00468         DensityQuantity* cloneDensityQuantity() const {
00469             return new AngmomFlowLimited(&pde, theta, coeffstorage);
00470         }
00471         GReal_t getTheta() const { return theta; }
00472         void setTheta(GReal_t Theta)
00473         {
00474             if ( coeffstorage!=NULL )
00475             {
00476                 if ( coeffstorage->size() )
00477                     throw IllegalArgumentException("Cannot change theta after initialized coefficient table!", "gridripper_phys_gr_fixmp_kerrhiggs::KerrHiggs::AngmomFlowLimited::setTheta");
00478             }
00479             theta=Theta;
00480         }
00481     };
00482     AngmomFlowLimited theAngmomFlowLimited1, theAngmomFlowLimited2;
00483 
00485     PhysicalQuantityArray getPhysicalQuantities() const;
00486 
00488     class IntqBorder : public MarkerQuantity
00489     {
00490         private:
00491             const GReal_t position;
00492         public:
00493             IntqBorder(const PDE* eq, GReal_t positionarg)
00494              : MarkerQuantity(eq), position(positionarg)
00495             {  }
00496             ~IntqBorder() {  }
00497             std::string getQuantityName() const { return "IntqBorder"; }
00498             GReal_t eval(GReal_t t);
00499             MarkerQuantity* cloneMarkerQuantity() const
00500             { return new IntqBorder(&getPDE(), position); }
00501     };
00502 
00512     class Lightray : public MarkerQuantity
00513     {
00514         private:
00515             const PDE* eq;
00516             const GReal_t M;
00517             const GReal_t a;
00518             const GReal_t e;
00519             const GReal_t r0;
00520             const int direction;
00521             bool firststep;
00522             GReal_t r;
00523             GReal_t tprev;
00524         public:
00525             Lightray(const PDE* eqarg, GReal_t Marg, GReal_t aarg, GReal_t earg, GReal_t rh0arg, int directionarg)
00526              : MarkerQuantity(eqarg), eq(eqarg), M(Marg), a(aarg), e(earg), r0(((KerrHiggs*)eq)->coordTransf->calc_r(rh0arg)), direction(directionarg), firststep(true)
00527             {  }
00528             ~Lightray() {  }
00529             std::string getQuantityName() const { return "Lightray"; }
00530             GReal_t eval(GReal_t t);
00532             GReal_t rightside(GReal_t r) const;
00533             MarkerQuantity* cloneMarkerQuantity() const
00534             { return new Lightray(&getPDE(), M, a, e, ((KerrHiggs*)eq)->coordTransf->calc_rh(r0), direction); }
00535     };
00536 
00538     MarkerQuantityArray getMarkerQuantities() const;
00539 
00540 private:
00541 
00543     static tvector<string> componentNames(int maxOrder);
00544     static tvector<string> constraintNames(int maxOrder);
00545 
00546 };
00547 
00548 
00549 } } } } } // namespace gridripper::phys::gr::fixmp::kerrhiggs
00550 
00551 
00552 #endif /* gridripper_phys_gr_fixmp_kerrhiggs_KerrHiggs_h */