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
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
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
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
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;
00755
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 } }
00838
00839 #endif