PDE.h

00001 #ifndef gridripper_amr1d_PDE_h
00002 #define gridripper_amr1d_PDE_h
00003 
00004 #include <gridripper/config.h>
00005 #include <gridripper/tvalarray.h>
00006 #include <gridripper/tvector.h>
00007 #include "FieldWrapper.h"
00008 #include "GridFunction.h"
00009 #include <map>
00010 #include <string>
00011 #include <gridripper/math/Integrator1D.h>
00012 
00013 namespace gridripper { namespace amr1d {
00014 
00015 class Grad;
00016 class Grid;
00017 
00018 using namespace std;
00019 using namespace gridripper::math;
00020 
00028 class PDE
00029 {
00030 public:
00031     enum {LEFT = 1, RIGHT = 2};
00032 
00033     static const double EPSILON;
00034 //
00035 // Abstract classes and arrays
00036 //
00037 
00041     class DensityQuantity
00042     {
00043     private:
00044         const PDE* that;
00045     public:
00046         DensityQuantity(const PDE* eq): that(eq) { }
00047         virtual ~DensityQuantity() { }
00048         virtual GReal_t density(GReal_t t, GReal_t x,
00049                                 const tvalarray<GReal_t>& f) const =0;
00050         virtual GReal_t flow(GReal_t t, GReal_t x,
00051                              const tvalarray<GReal_t>& f) const =0;
00052         virtual DensityQuantity* cloneDensityQuantity() const =0;
00053         const PDE& getPDE() const {
00054             return *that;
00055         }
00056     };
00057 
00058     class PhysicalQuantity
00059     {
00060     private:
00061         const PDE* that;
00062         tvalarray<string> nameAndFormats;
00063     public:
00070         PhysicalQuantity(const PDE* eq, const string& name);
00071 
00081         PhysicalQuantity(const PDE* eq, const string& name,
00082                          const string& format, const string& headerFormat);
00083 
00084         virtual ~PhysicalQuantity() { }
00085         virtual GReal_t eval(const Grid& g, GReal_t dt)
00086             throw(IllegalArgumentException&) =0;
00087         string getQuantityName() const {
00088             return nameAndFormats[0];
00089         }
00090         string getFormat() const {
00091             return nameAndFormats[1];
00092         }
00093         string getHeaderFormat() const {
00094             return nameAndFormats[2];
00095         }
00096         virtual PhysicalQuantity* clonePhysicalQuantity() const =0;
00097         const PDE& getPDE() const {
00098             return *that;
00099         }
00100     };
00101 
00102     class PhysicalQuantityArray: public tvalarray<PhysicalQuantity*>
00103     {
00104     public:
00105         PhysicalQuantityArray();
00106         PhysicalQuantityArray(int n);
00107         PhysicalQuantityArray(const PhysicalQuantityArray& o);
00108         PhysicalQuantityArray& operator =(const PhysicalQuantityArray& q);
00109         ~PhysicalQuantityArray();
00110     };
00111 
00112     class MarkerQuantity
00113     {
00114     private:
00115         const PDE* that;
00116     public:
00117         MarkerQuantity(const PDE* eq): that(eq) { }
00118         virtual ~MarkerQuantity() { }
00119         virtual string getQuantityName() const =0;
00120         virtual GReal_t eval(GReal_t t) =0;
00121         virtual MarkerQuantity* cloneMarkerQuantity() const =0;
00122         const PDE& getPDE() const {
00123             return *that;
00124         }
00125     };
00126 
00127     class MarkerQuantityArray: public tvalarray<MarkerQuantity*>
00128     {
00129     public:
00130         MarkerQuantityArray();
00131         MarkerQuantityArray(int n);
00132         MarkerQuantityArray(const MarkerQuantityArray& o);
00133         MarkerQuantityArray& operator =(const MarkerQuantityArray& q);
00134         ~MarkerQuantityArray();
00135     };
00136 
00137 private:
00138 
00139     int numComponents;
00140 
00141     int numIndependentComponents;
00142 
00143     tvalarray<string> coordinateLabels;
00144 
00145     tvalarray<string> timeFormats;
00146 
00147     string* componentNames;
00148 
00149     string* physicalComponentNames;
00150 
00151     const string* constraintNames;
00152 
00153     map<string, int> componentIndices;
00154 
00155     map<string, int> gridFunctionIndices;
00156 
00157     tvector<GridFunction*> gridFunctions;
00158 
00159     tvalarray<GReal_t> defaultSigmaArray;
00160 
00161     const DensityQuantity* theEnergy;
00162 
00163     bool energySet;
00164 
00165 protected:
00166     PDE(int nc, int nindep, const string* compnames,
00167         const string* constrnames, const string* coordlabels);
00168 
00169 public:
00170     virtual ~PDE();
00171 
00176     virtual GReal_t getMinX() const =0;
00177 
00182     virtual GReal_t getMaxX() const =0;
00183 
00190     virtual void evalConstrainedComponents(Grid& g, int i,
00191                                           FieldWrapper& f) =0;
00192 
00200     virtual void setNonevolvingComponents(Grid& g, Grad& d) {
00201     }
00202 
00208     virtual int getNumConstraintEqs() const {
00209         return 0;
00210     }
00211 
00220     virtual void evalConstraintEqs(const Grid& g, int i, const GReal_t* F,
00221                           GReal_t* lhs, GReal_t* rhs) const;
00222 
00235     int doEval(GReal_t* dF, GReal_t t,
00236                const GReal_t* F, GReal_t* tmp,
00237                const Grid& g, int i, Grad& d, GReal_t dt);
00238 //
00239 // Overridable methods
00240 //
00241 
00255     virtual int eval(GReal_t* dF, GReal_t t, GReal_t x,
00256                      const GReal_t* F, const GReal_t* Fx,
00257                      const Grid& g, int i, Grad& d, GReal_t dt) =0;
00258 
00264     virtual bool isScalable() const {
00265         return false;
00266     }
00267 
00274     virtual GReal_t calcScaleFactor(const Grid* g) const {
00275         return 1.0;
00276     }
00277 
00278     virtual FieldWrapper* createField(int level) const =0;
00279 
00280     virtual PhysicalQuantityArray getPhysicalQuantities() const;
00281 
00282     virtual MarkerQuantityArray getMarkerQuantities() const;
00283 
00289     virtual GReal_t getPhysicalMinX() const {
00290         return getMinX();
00291     }
00292 
00298     virtual GReal_t getPhysicalMaxX() const {
00299         return getMaxX();
00300     }
00301 
00307     virtual bool isXPeriodic() const {
00308         return false;
00309     }
00310 
00316     virtual bool canBeExtended(int where) const;
00317 
00324     virtual void mirrorLeft(GReal_t x, FieldWrapper& f) const {
00325     }
00326 
00334     virtual void mirrorRight(GReal_t x, FieldWrapper& f) const;
00335 
00342     virtual void getExtendedField(const Grid& g, int i, FieldWrapper& f) const;
00343 
00351     virtual bool hasExtendedRefinedFieldData(const Grid& g, int i) const;
00352 
00359     virtual void getExtendedRefinedField(const Grid& g, int i, FieldWrapper& f)
00360         const;
00361 
00367     virtual string getPhysicalComponentName(int k) const {
00368         return physicalComponentNames[k];
00369     }
00370 
00379     virtual void getFieldWrapper(GReal_t t, GReal_t x, GReal_t* f) const {
00380     }
00381 
00386     int getNumGridFunctions() const {
00387         return gridFunctions.size();
00388     }
00389 
00395     const GridFunction& getGridFunction(int i) const {
00396         return *gridFunctions[i];
00397     }
00398 
00408     virtual GReal_t calcBestDeltaT(const Grid& g, int i, const FieldWrapper& F,
00409                                    GReal_t dt0, GReal_t dt) const {
00410         return dt;
00411     }
00412 
00426     virtual const double* getComponentSigmaArray() const {
00427         return (const double*)defaultSigmaArray;
00428     }
00429 
00430 //
00431 // Non-overridable methods
00432 //
00433 public:
00434 
00439     string getTimeLabel() const {
00440         return coordinateLabels[0];
00441     }
00442 
00447     string getTimeFormat() const {
00448         return timeFormats[0];
00449     }
00450 
00455     string getTimeLabelFormat() const {
00456         return timeFormats[1];
00457     }
00458 
00463     string getXcoordLabel() const {
00464         return coordinateLabels[1];
00465     }
00466 
00471     int getNumComponents() const {
00472         return numComponents;
00473     }
00474 
00479     int getNumIndependentComponents() const {
00480         return numIndependentComponents;
00481     }
00482 
00488     string getComponentName(int k) const {
00489         return componentNames[k];
00490     }
00491 
00497     int getComponentIndex(const string& name) const;
00498 
00504     int getGridFunctionIndex(const string& name) const;
00505 
00511     string getConstraintName(int k) const {
00512         return constraintNames[k];
00513     }
00514 
00515     double constraintError(Grid& g, int i);
00516 
00517     const DensityQuantity& energy() const {
00518         return *theEnergy;
00519     }
00520 
00521 protected:
00522     void setEnergy(const DensityQuantity& e);
00523 
00528     void addGridFunction(GridFunction* f);
00529 
00530 //
00531 // Implementations
00532 //
00533 public:
00534 
00535     class ZeroDensity: public PDE::DensityQuantity {
00536     public:
00537         ZeroDensity(const PDE* pde): PDE::DensityQuantity(pde) { }
00538         GReal_t density(GReal_t T, GReal_t R, const tvalarray<GReal_t>& F)
00539                 const {
00540             return 0;
00541         }
00542         GReal_t flow(GReal_t T, GReal_t R, const tvalarray<GReal_t>& F) const {
00543             return 0;
00544         }
00545         PDE::DensityQuantity* cloneDensityQuantity() const {
00546             return new ZeroDensity(&getPDE());
00547         }
00548     };
00549 
00550     class FiniteIntegral: public PhysicalQuantity
00551     {
00552     private:
00553         const DensityQuantity* q;
00554     public:
00563         FiniteIntegral(const PDE* eq, const string& name,
00564                        const DensityQuantity& q);
00565 
00576         FiniteIntegral(const PDE* eq, const string& name,
00577                        const string& format, const string& headerFormat,
00578                        const DensityQuantity& q);
00579 
00580         virtual ~FiniteIntegral();
00581 
00582         GReal_t integrate(const Grid& g, GReal_t xmin, GReal_t xmax);
00583     protected:
00584         const DensityQuantity& getDensityQuantity() const {
00585             return *q;
00586         }
00587     };
00588 
00589     class TotalIntegral: public FiniteIntegral
00590     {
00591     public:
00600         TotalIntegral(const PDE* eq, const string& name,
00601                       const DensityQuantity& q);
00602 
00613         TotalIntegral(const PDE* eq, const string& name,
00614                       const string& format, const string& headerFormat,
00615                       const DensityQuantity& q);
00616 
00617         virtual PhysicalQuantity* clonePhysicalQuantity() const;
00618 
00619         virtual GReal_t eval(const Grid& g, GReal_t dt)
00620                 throw(IllegalArgumentException&) {
00621             return integrate(g, getPDE().getPhysicalMinX(),
00622                              getPDE().getPhysicalMaxX());
00623         }
00624     };
00625 
00626     class FiniteX0Integral: public FiniteIntegral
00627     {
00628     protected:
00629         GReal_t xminvalue;
00630         GReal_t x0value;
00631     public:
00642         FiniteX0Integral(const PDE* eq, const string& name,
00643                          const DensityQuantity& q,
00644                          GReal_t xmin, GReal_t x0);
00645 
00658         FiniteX0Integral(const PDE* eq, const string& name,
00659                          const string& format, const string& headerFormat,
00660                          const DensityQuantity& q,
00661                          GReal_t xmin, GReal_t x0);
00662 
00663         virtual PhysicalQuantity* clonePhysicalQuantity() const;
00664 
00665         GReal_t eval(const Grid& g, GReal_t dt)
00666                 throw(IllegalArgumentException&) {
00667             return integrate(g, xminvalue, x0value);
00668         }
00669     };
00670 
00671     class TotalX0Integral;
00672 
00673     class TimeIntegral: public PhysicalQuantity
00674     {
00675     private:
00676         PhysicalQuantity* q;
00677     protected:
00678         IntegratorIncremental1D* integrator;
00679 
00691         TimeIntegral(const PDE* eq, const string& name,
00692                      const string& format, const string& headerFormat,
00693                      PhysicalQuantity& q, const IntegratorIncremental1D& integ);
00694     public:
00703         TimeIntegral(const PDE* eq, const string& name, PhysicalQuantity& q);
00704 
00705         virtual ~TimeIntegral();
00706         virtual PhysicalQuantity* clonePhysicalQuantity() const;
00707         virtual GReal_t eval(const Grid& g, GReal_t dt)
00708             throw(IllegalArgumentException&);
00709     };
00710 
00711     class X0Flow: public PhysicalQuantity
00712     {
00713     private:
00714         const DensityQuantity* q;
00715     protected:
00716         GReal_t x0value;
00717         IntegratorIncremental1D* integrator;
00718 
00730         X0Flow(const PDE* eq, const string& name,
00731                const string& format, const string& headerFormat,
00732                const DensityQuantity& q,
00733                GReal_t x0, const IntegratorIncremental1D& integ);
00734     public:
00744         X0Flow(const PDE* eq, const string& name, const DensityQuantity& q,
00745                GReal_t x0);
00746 
00747         virtual ~X0Flow();
00748         PhysicalQuantity* clonePhysicalQuantity() const;
00749         GReal_t eval(const Grid& g, GReal_t dt)
00750             throw(IllegalArgumentException&);
00751         const IntegratorIncremental1D& getIntegrator() const {
00752             return *integrator;
00753         }
00754         friend class TotalX0Integral; // must be friend to be able to access
00755                                       // the protected constructor
00756     };
00757 
00758     class TotalX0Integral: public FiniteX0Integral
00759     {
00760     protected:
00761         X0Flow flow1;
00762         X0Flow flow2;
00763 
00778         TotalX0Integral(const PDE* eq, const string& name,
00779                         const string& format, const string& headerFormat,
00780                         const DensityQuantity& q,
00781                         GReal_t xmin, GReal_t x0,
00782                         const X0Flow& f1,
00783                         const X0Flow& f2);
00784     public:
00796         TotalX0Integral(const PDE* eq, const string& name,
00797                         const DensityQuantity& q, GReal_t xmin, GReal_t x0);
00798         virtual PhysicalQuantity* clonePhysicalQuantity() const;
00799         GReal_t integrate(const Grid& g) {
00800             return FiniteIntegral::integrate(g, xminvalue, x0value);
00801         }
00802         GReal_t eval(const Grid& g, GReal_t dt)
00803             throw(IllegalArgumentException&);
00804     };
00805 
00806 private:
00807     GReal_t flow(const DensityQuantity& q, const Grid& g, double t, double x0,
00808                  tvalarray<GReal_t>& F) const;
00809 
00810     static tvalarray<string> splitNameFormats(const string& name);
00811 
00812     class ComponentGridFunction: public GridFunction {
00813     private:
00814         int componentIndex;
00815     public:
00816         ComponentGridFunction(const PDE& pde, int k):
00817                 GridFunction(pde.getComponentName(k)) {
00818             componentIndex = k;
00819         }
00820         GReal_t eval(GReal_t t, GReal_t x, const tvalarray<GReal_t>& F) const {
00821             return F[componentIndex];
00822         }
00823     };
00824     class EnergyGridFunction: public GridFunction {
00825     private:
00826         const DensityQuantity* energy;
00827     public:
00828         EnergyGridFunction(const DensityQuantity* e): GridFunction("energy") {
00829             energy = e;
00830         }
00831         GReal_t eval(GReal_t t, GReal_t x, const tvalarray<GReal_t>& F) const {
00832             return energy->density(t, x, F);
00833         };
00834     };
00835 };
00836 
00837 } } // namespace gridripper::amr1d
00838 
00839 #endif /* gridripper_amr1d_PDE_h */

Generated on Wed Jun 17 18:46:47 2009 for GridRipper by  doxygen 1.5.6