KGEq.h

00001 #ifndef gridripper_phys_minkowski_kg_moncrief_KGEq_h
00002 #define gridripper_phys_minkowski_kg_moncrief_KGEq_h
00003 
00004 #include <gridripper/amr1d/PDE.h>
00005 #include <gridripper/Parameters.h>
00006 #include <gridripper/lang/IllegalArgumentException.h>
00007 
00008 namespace gridripper { namespace phys { namespace minkowski { namespace kg {
00009 namespace moncrief {
00010 
00011 using namespace gridripper;
00012 using namespace gridripper::util;
00013 using namespace gridripper::amr1d;
00014 using namespace std;
00015 
00024 class KGEq: public PDE
00025 {
00026 public:
00027     enum {I_f = 0,
00028           I_fT = 1,
00029           I_fR = 2,
00030           NUM_INDEP_COMPS = 2,
00031           NUM_COMPS = NUM_INDEP_COMPS + 1};
00032 
00033     // Field bits:
00034     static const int F_f;
00035     static const int F_fT;
00036     static const int F_fR;
00037 
00038     static const string COMPNAMES[NUM_COMPS];
00039 
00040     static const string CONSTRAINT_NAMES[1];
00041 
00042 private:
00043     static const double EPSILON;
00044 
00045     GReal_t kappa;
00046 
00047     GReal_t kappaSq;
00048 
00049     GReal_t mass;
00050 
00051     GReal_t massSq;
00052 
00054     GReal_t Rmax;
00055 
00056     GReal_t R0;
00057 
00058     tvalarray<GReal_t> df;
00059 
00060     class Energy: public DensityQuantity {
00061     private:
00062         const KGEq& pde;
00063     public:
00064         Energy(const KGEq* p): DensityQuantity(p), pde(*p) { }
00065         GReal_t density(GReal_t T, GReal_t R, const tvalarray<GReal_t>& F)
00066                         const;
00067         GReal_t flow(GReal_t T, GReal_t R, const tvalarray<GReal_t>& F)
00068                      const;
00069         DensityQuantity* cloneDensityQuantity() const {
00070             return new Energy(&pde);
00071         }
00072     } theEnergy;
00073 
00074 public:
00075     KGEq(const Parameters* p) throw(IllegalArgumentException&);
00076 
00077     GReal_t getMinX() const {
00078         return 0;
00079     }
00080 
00081     GReal_t getMaxX() const {
00082         return Rmax;
00083     }
00084 
00085     GReal_t getPhysicalMaxX() const {
00086         return 1;
00087     }
00088 
00089     GReal_t getR0() const {
00090         return R0;
00091     }
00092 
00093     int eval(GReal_t* dF, GReal_t T, GReal_t R,
00094              const GReal_t* F, const GReal_t* FR,
00095              const Grid& g, int i, Grad& d, GReal_t dT);
00096 
00097     void evalConstrainedComponents(Grid& g, int i, FieldWrapper& fw);
00098 
00099     FieldWrapper* createField(int level) const;
00100 
00105     bool canBeExtended(int where) const {
00106         return where == LEFT
00107             || where == RIGHT; // zeros beyond right edge in
00108 //                             // P. Csizmadia, IJMPD15 (2006) 107
00109     }
00110 
00111     void mirrorLeft(GReal_t R, FieldWrapper& f) const {
00112         GReal_t* v = f.data();
00113         v[I_f]  = -v[I_f];
00114         v[I_fT] = -v[I_fT];
00115     }
00116 
00117     void mirrorRight(GReal_t R, FieldWrapper& f) const {
00118         // zeros beyond right edge in P. Csizmadia, IJMPD15 (2006) 107
00119         GReal_t* v = f.data();
00120         v[I_f]  = -v[I_f];
00121         v[I_fT] = -v[I_fT];
00122     }
00123 
00131     bool hasExtendedRefinedFieldData(const Grid& g, int i) const;
00132 
00140     void getGridField(GReal_t T, GReal_t R, tvalarray<GReal_t>& f) const {
00141         if(R > EPSILON && R <= 1 - EPSILON) {
00142             GReal_t c = 2*R/(1 - R*R);
00143             f[I_f] *= c;
00144             if(f.size() > 1) {
00145                 f[I_fT] *= c;
00146             }
00147         } else {
00148             f[I_f] = 0;
00149             if(I_fT < f.size()) {
00150                 f[I_fT] = 0;
00151             }
00152         }
00153     }
00154 
00155     PhysicalQuantityArray getPhysicalQuantities() const;
00156 };
00157 
00158 } } } } } // namespace gridripper::phys::minkowski::kg::moncrief;
00159 
00160 #endif /* gridripper_phys_minkowski_kg_moncrief_KGEq_h */