Commit cb1622cd authored by niklas.baumgarten's avatar niklas.baumgarten
Browse files

Template Based Sample Generator

parent 266a8c90
...@@ -20,7 +20,6 @@ protected: ...@@ -20,7 +20,6 @@ protected:
public: public:
explicit IStochasticTransportAssemble(IStochasticTransportProblem *problem) : explicit IStochasticTransportAssemble(IStochasticTransportProblem *problem) :
problem(problem) { problem(problem) {
InfoEntries problemEntries = problem->GetInfoEntries();
}; };
void DrawSample(const SampleID &id) { void DrawSample(const SampleID &id) {
......
#include "IStochasticProblem.hpp" #include "IStochasticProblem.hpp"
#include "generators/CirculantEmbedding.hpp" #include "generators/CirculantEmbedding.hpp"
#include "generators/HybridFluxGenerator.hpp" #include "generators/HybridFluxGenerator.hpp"
\ No newline at end of file
SampleGenerator *IStochasticProblem::createGenerator(GeneratorName genName,
Meshes &meshes) {
if (genName == "DummyGenerator")
return new DummyGenerator(meshes);
// if (genName == "UniformRandomNumberGenerator")
// return new UniformRandomNumberGenerator(meshes);
// if (genName == "NormalRandomNumberGenerator")
// return new NormalRandomNumberGenerator(meshes);
if (genName == "CirculantEmbedding")
return new MultilevelCirculantEmbedding(meshes);
if (genName == "HybridFluxGenerator")
return new MultilevelHybridFluxGenerator(meshes);
Exit("Generator not implemented")
}
...@@ -3,52 +3,76 @@ ...@@ -3,52 +3,76 @@
#include "Algebra.hpp" #include "Algebra.hpp"
#include "basics/Sample.hpp" #include "basics/Sample.hpp"
#include "generators/SampleGenerator.hpp"
#include "basics/Utilities.hpp" #include "basics/Utilities.hpp"
#include "generators/CirculantEmbedding.hpp"
//#include "generators/HybridFluxGenerator.hpp"
#include "generators/SampleGenerator.hpp"
typedef std::string GeneratorName;
typedef std::vector<GeneratorName> GeneratorNames; typedef std::vector<std::string> GeneratorNames;
typedef std::map<GeneratorName, SampleGenerator *> SampleGenerators; class SampleGeneratorContainer {
void init(Meshes &meshes) {
scalarGenerator = new ScalarDummy(meshes);
complexGenerator = new ComplexDummy(meshes);
vectorFieldGenerator = new VectorFieldDummy(meshes);
tensorGenerator = new TensorDummy(meshes);
scalarSequence1DGenerator = new ScalarSequence1DDummy(meshes);
complexSequence1DGenerator = new ComplexSequence1DDummy(meshes);
scalarSequence2DGenerator = new ScalarSequence2DGenerator(meshes);
complexSequence2DGenerator = new ComplexSequence2DGenerator(meshes);
}
public:
SampleGenerator<Scalar> *scalarGenerator;
SampleGenerator<Complex> *complexGenerator;
SampleGenerator<VectorField> *vectorFieldGenerator;
SampleGenerator<Tensor> *tensorGenerator;
SampleGenerator<ScalarSequence1D> *scalarSequence1DGenerator;
SampleGenerator<ComplexSequence1D> *complexSequence1DGenerator;
SampleGenerator<ScalarSequence2D> *scalarSequence2DGenerator;
SampleGenerator<ComplexSequence2D> *complexSequence2DGenerator;
SampleGeneratorContainer(GeneratorNames names, Meshes &meshes) {
init(meshes);
for (auto const &genName: names) {
if (genName == "CirculantEmbedding")
tensorGenerator = new MultilevelCirculantEmbedding(meshes);
// if (genName == "HybridFluxGenerator")
// new MultilevelHybridFluxGenerator(meshes);
}
}
void DrawSample(const SampleID &id) {
scalarGenerator->DrawSample(id);
complexGenerator->DrawSample(id);
vectorFieldGenerator->DrawSample(id);
tensorGenerator->DrawSample(id);
scalarSequence1DGenerator->DrawSample(id);
complexSequence1DGenerator->DrawSample(id);
scalarSequence2DGenerator->DrawSample(id);
complexSequence2DGenerator->DrawSample(id);
}
};
class IStochasticProblem { class IStochasticProblem {
private: private:
int verbose = 1; int verbose = 1;
InfoEntries entries;
GeneratorNames genNames; GeneratorNames genNames;
SampleGenerator *createGenerator(GeneratorName genName, Meshes &meshes);
protected: protected:
SampleGenerators generators; SampleGeneratorContainer genContainer;
public: public:
IStochasticProblem(GeneratorNames genNames, Meshes &meshes) : genNames(genNames) { IStochasticProblem(Meshes &meshes, GeneratorNames genNames) :
genNames(genNames), genContainer(genNames, meshes) {
config.get("ProblemVerbose", verbose); config.get("ProblemVerbose", verbose);
for (auto &name : genNames) {
entries.push_back(InfoEntry("Generator", name));
generators[name] = createGenerator(name, meshes);
}
} }
virtual ~IStochasticProblem() {
for (auto &gen: generators) {
delete gen.second;
}
generators.clear();
};
void DrawSample(const SampleID &id) { void DrawSample(const SampleID &id) {
for (auto &gen : generators) genContainer.DrawSample(id);
gen.second->DrawSample(id);
}
InfoEntries GetInfoEntries() {
return entries;
} }
virtual void PrintInfo() const { virtual void PrintInfo() const {
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
class IStochasticEllipticProblem : public IStochasticProblem { class IStochasticEllipticProblem : public IStochasticProblem {
public: public:
IStochasticEllipticProblem(GeneratorNames genNames, Meshes &meshes) IStochasticEllipticProblem(Meshes &meshes, GeneratorNames genNames = {})
: IStochasticProblem(genNames, meshes) {} : IStochasticProblem(meshes, genNames) {}
virtual Scalar Solution(const Point &x) const = 0; virtual Scalar Solution(const Point &x) const = 0;
...@@ -21,8 +21,7 @@ public: ...@@ -21,8 +21,7 @@ public:
class StochasticLaplace1D : public IStochasticEllipticProblem { class StochasticLaplace1D : public IStochasticEllipticProblem {
public: public:
StochasticLaplace1D(Meshes &meshes) : StochasticLaplace1D(Meshes &meshes) :
IStochasticEllipticProblem(GeneratorNames{"CirculantEmbedding"}, IStochasticEllipticProblem(meshes, GeneratorNames{"CirculantEmbedding"}) {};
meshes) {};
Scalar Solution(const Point &x) const override { Scalar Solution(const Point &x) const override {
return 1 - x[0]; return 1 - x[0];
...@@ -37,8 +36,7 @@ public: ...@@ -37,8 +36,7 @@ public:
} }
Tensor Permeability(const cell &c) const override { Tensor Permeability(const cell &c) const override {
return this->generators.find("CirculantEmbedding")-> return this->genContainer.tensorGenerator->EvalSample(c);
second->EvalTensorSample(c);
} }
string Name() const override { return "StochasticLaplace1D"; } string Name() const override { return "StochasticLaplace1D"; }
...@@ -46,9 +44,7 @@ public: ...@@ -46,9 +44,7 @@ public:
class Laplace1D : public IStochasticEllipticProblem { class Laplace1D : public IStochasticEllipticProblem {
public: public:
Laplace1D(Meshes &meshes) : Laplace1D(Meshes &meshes) : IStochasticEllipticProblem(meshes) {};
IStochasticEllipticProblem(GeneratorNames{"DummyGenerator"},
meshes) {};
Scalar Solution(const Point &x) const override { Scalar Solution(const Point &x) const override {
return 1 - x[0]; return 1 - x[0];
...@@ -72,8 +68,7 @@ public: ...@@ -72,8 +68,7 @@ public:
class StochasticLaplace2D : public IStochasticEllipticProblem { class StochasticLaplace2D : public IStochasticEllipticProblem {
public: public:
StochasticLaplace2D(Meshes &meshes) : StochasticLaplace2D(Meshes &meshes) :
IStochasticEllipticProblem(GeneratorNames{"CirculantEmbedding"}, IStochasticEllipticProblem(meshes, GeneratorNames{"CirculantEmbedding"}) {}
meshes) {}
Scalar Solution(const Point &x) const override { Scalar Solution(const Point &x) const override {
return -x[1]; return -x[1];
...@@ -86,8 +81,7 @@ public: ...@@ -86,8 +81,7 @@ public:
Scalar Load(const Point &x) const override { return 0.0; } Scalar Load(const Point &x) const override { return 0.0; }
Tensor Permeability(const cell &c) const override { Tensor Permeability(const cell &c) const override {
return this->generators.find("CirculantEmbedding")-> return this->genContainer.tensorGenerator->EvalSample(c);
second->EvalTensorSample(c);
} }
string Name() const override { return "StochasticLaplace2D"; } string Name() const override { return "StochasticLaplace2D"; }
...@@ -95,9 +89,7 @@ public: ...@@ -95,9 +89,7 @@ public:
class Laplace2D : public IStochasticEllipticProblem { class Laplace2D : public IStochasticEllipticProblem {
public: public:
Laplace2D(Meshes &meshes) : Laplace2D(Meshes &meshes) : IStochasticEllipticProblem(meshes) {}
IStochasticEllipticProblem(GeneratorNames{"DummyGenerator"},
meshes) {}
Scalar Solution(const Point &x) const override { Scalar Solution(const Point &x) const override {
return -x[1]; return -x[1];
......
...@@ -37,8 +37,8 @@ protected: ...@@ -37,8 +37,8 @@ protected:
double reaction = 1.0; double reaction = 1.0;
public: public:
IStochasticReactionProblem(GeneratorNames genNames, Meshes &meshes) : IStochasticReactionProblem(Meshes &meshes, GeneratorNames genNames={}) :
IStochasticProblem(genNames, meshes) { IStochasticProblem(meshes, genNames) {
config.get("Diffusion", diffusion); config.get("Diffusion", diffusion);
config.get("Convection", convection); config.get("Convection", convection);
config.get("Reaction", reaction); config.get("Reaction", reaction);
...@@ -111,7 +111,7 @@ class ExponentialReaction2D : public IStochasticReactionProblem { ...@@ -111,7 +111,7 @@ class ExponentialReaction2D : public IStochasticReactionProblem {
public: public:
ExponentialReaction2D(Meshes &meshes) : ExponentialReaction2D(Meshes &meshes) :
IStochasticReactionProblem(GeneratorNames{}, meshes) {}; IStochasticReactionProblem(meshes) {};
Scalar Concentration(double t, const Point &x) const override { Scalar Concentration(double t, const Point &x) const override {
return u0(x); return u0(x);
...@@ -142,7 +142,7 @@ private: ...@@ -142,7 +142,7 @@ private:
double r1 = 0.0; double r1 = 0.0;
public: public:
LogisticReaction2D(Meshes &meshes) : LogisticReaction2D(Meshes &meshes) :
IStochasticReactionProblem(GeneratorNames{}, meshes) { IStochasticReactionProblem(meshes) {
config.get("Reaction0", r0); config.get("Reaction0", r0);
config.get("Reaction1", r1); config.get("Reaction1", r1);
} }
......
...@@ -9,8 +9,8 @@ private: ...@@ -9,8 +9,8 @@ private:
bool rhs = true; bool rhs = true;
public: public:
IStochasticTransportProblem(GeneratorNames genNames, Meshes &meshes) IStochasticTransportProblem(Meshes &meshes, GeneratorNames genNames = {})
: IStochasticProblem(genNames, meshes) {} : IStochasticProblem(meshes, genNames) {}
bool RHS() const { return rhs; } bool RHS() const { return rhs; }
...@@ -30,8 +30,7 @@ public: ...@@ -30,8 +30,7 @@ public:
class StochasticPollution1D : public IStochasticTransportProblem { class StochasticPollution1D : public IStochasticTransportProblem {
public: public:
StochasticPollution1D(Meshes &meshes) : StochasticPollution1D(Meshes &meshes) :
IStochasticTransportProblem(GeneratorNames{"HybridFluxGenerator"}, IStochasticTransportProblem(meshes, GeneratorNames{"HybridFluxGenerator"}) {}
meshes) {}
Scalar Solution(double t, const Point &x) const override { Scalar Solution(double t, const Point &x) const override {
if (abs(1.0 * t - x[0] + 0.5) > 0.06251) return 0.0; if (abs(1.0 * t - x[0] + 0.5) > 0.06251) return 0.0;
...@@ -39,14 +38,12 @@ public: ...@@ -39,14 +38,12 @@ public:
} }
VectorField CellFlux(const cell &c, const Point &x) const override { VectorField CellFlux(const cell &c, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.vectorFieldGenerator->EvalSample(c);
second->EvalVectorFieldSample(c);
} }
Scalar FaceNormalFlux(const cell &c, int face, const VectorField &N, Scalar FaceNormalFlux(const cell &c, int face, const VectorField &N,
const Point &x) const override { const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.scalarGenerator->EvalSample(face, c);
second->EvalScalarSample(face, c);
} }
string Name() const override { return "StochasticPollution1D"; } string Name() const override { return "StochasticPollution1D"; }
...@@ -59,8 +56,7 @@ private: ...@@ -59,8 +56,7 @@ private:
public: public:
StochasticPollutionCosHat1D(Meshes &meshes) : StochasticPollutionCosHat1D(Meshes &meshes) :
IStochasticTransportProblem(GeneratorNames{"HybridFluxGenerator"}, IStochasticTransportProblem(meshes, GeneratorNames{"HybridFluxGenerator"}) {}
meshes) {}
Scalar Solution(double t, const Point &x) const override { Scalar Solution(double t, const Point &x) const override {
Point midPoint = Point(0.2, 0.0); Point midPoint = Point(0.2, 0.0);
...@@ -71,14 +67,12 @@ public: ...@@ -71,14 +67,12 @@ public:
} }
VectorField CellFlux(const cell &c, const Point &x) const override { VectorField CellFlux(const cell &c, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.vectorFieldGenerator->EvalSample(c);
second->EvalVectorFieldSample(c);
} }
Scalar FaceNormalFlux(const cell &c, int face, Scalar FaceNormalFlux(const cell &c, int face,
const VectorField &N, const Point &x) const override { const VectorField &N, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.scalarGenerator->EvalSample(face, c);
second->EvalScalarSample(face, c);
} }
string Name() const override { return "StochasticPollutionCosHat1D"; } string Name() const override { return "StochasticPollutionCosHat1D"; }
...@@ -90,8 +84,7 @@ private: ...@@ -90,8 +84,7 @@ private:
public: public:
StochasticPollution2D(Meshes &meshes) : StochasticPollution2D(Meshes &meshes) :
IStochasticTransportProblem(GeneratorNames{"HybridFluxGenerator"}, IStochasticTransportProblem(meshes, GeneratorNames{"HybridFluxGenerator"}) {}
meshes) {}
Scalar Solution(double t, const Point &x) const override { Scalar Solution(double t, const Point &x) const override {
if ((abs(1 - x[1] - 1.5 * d) < d / 2) && (abs(0.5 - x[0]) < 3 * d)) if ((abs(1 - x[1] - 1.5 * d) < d / 2) && (abs(0.5 - x[0]) < 3 * d))
...@@ -100,14 +93,12 @@ public: ...@@ -100,14 +93,12 @@ public:
} }
VectorField CellFlux(const cell &c, const Point &x) const override { VectorField CellFlux(const cell &c, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.vectorFieldGenerator->EvalSample(c);
second->EvalVectorFieldSample(c);
} }
Scalar FaceNormalFlux(const cell &c, int face, Scalar FaceNormalFlux(const cell &c, int face,
const VectorField &N, const Point &x) const override { const VectorField &N, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.scalarGenerator->EvalSample(face, c);
second->EvalScalarSample(face, c);
} }
string Name() const override { return "StochasticPollution2D"; } string Name() const override { return "StochasticPollution2D"; }
...@@ -118,7 +109,7 @@ class CircleWave2D : public IStochasticTransportProblem { ...@@ -118,7 +109,7 @@ class CircleWave2D : public IStochasticTransportProblem {
double cc = 0.5; double cc = 0.5;
public: public:
explicit CircleWave2D(Meshes &meshes) : explicit CircleWave2D(Meshes &meshes) :
IStochasticTransportProblem(GeneratorNames{"DummyGenerator"}, meshes) { IStochasticTransportProblem(meshes) {
} }
double Solution(double t, const Point &x) const override { double Solution(double t, const Point &x) const override {
...@@ -154,8 +145,7 @@ private: ...@@ -154,8 +145,7 @@ private:
public: public:
StochasticPollutionCosHat2D(Meshes &meshes) : StochasticPollutionCosHat2D(Meshes &meshes) :
IStochasticTransportProblem(GeneratorNames{"HybridFluxGenerator1D"}, IStochasticTransportProblem(meshes, GeneratorNames{"HybridFluxGenerator1D"}) {}
meshes) {}
double Solution(double t, const Point &x) const override { double Solution(double t, const Point &x) const override {
Point midPoint = Point(0.5, 0.8); Point midPoint = Point(0.5, 0.8);
...@@ -166,14 +156,12 @@ public: ...@@ -166,14 +156,12 @@ public:
} }
VectorField CellFlux(const cell &c, const Point &x) const override { VectorField CellFlux(const cell &c, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.vectorFieldGenerator->EvalSample(c);
second->EvalVectorFieldSample(c);
} }
Scalar FaceNormalFlux(const cell &c, int face, Scalar FaceNormalFlux(const cell &c, int face,
const VectorField &N, const Point &x) const override { const VectorField &N, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.scalarGenerator->EvalSample(face, c);
second->EvalScalarSample(face, c);
} }
string Name() const override { return "StochasticPollutionCosHat2D"; } string Name() const override { return "StochasticPollutionCosHat2D"; }
...@@ -198,8 +186,7 @@ private: ...@@ -198,8 +186,7 @@ private:
public: public:
StochasticPollutionMollifiedBar2D(Meshes &meshes) : StochasticPollutionMollifiedBar2D(Meshes &meshes) :
IStochasticTransportProblem(GeneratorNames{"HybridFluxGenerator"}, IStochasticTransportProblem(meshes, GeneratorNames{"HybridFluxGenerator"}) {}
meshes) {}
Scalar Solution(double t, const Point &x) const override { Scalar Solution(double t, const Point &x) const override {
if (abs(midPoint[0] - x[0]) <= 0.5 * xl && if (abs(midPoint[0] - x[0]) <= 0.5 * xl &&
...@@ -219,14 +206,12 @@ public: ...@@ -219,14 +206,12 @@ public:
} }
VectorField CellFlux(const cell &c, const Point &x) const override { VectorField CellFlux(const cell &c, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.vectorFieldGenerator->EvalSample(c);
second->EvalVectorFieldSample(c);
} }
Scalar FaceNormalFlux(const cell &c, int face, Scalar FaceNormalFlux(const cell &c, int face,
const VectorField &N, const Point &x) const override { const VectorField &N, const Point &x) const override {
return this->generators.find("HybridFluxGenerator")-> return this->genContainer.scalarGenerator->EvalSample(face, c);
second->EvalScalarSample(face, c);
} }
string Name() const override { return "StochasticPollutionMollifiedBar2D"; } string Name() const override { return "StochasticPollutionMollifiedBar2D"; }
...@@ -235,8 +220,8 @@ public: ...@@ -235,8 +220,8 @@ public:
class StochasticInitialConditionsTransport1D : public IStochasticTransportProblem { class StochasticInitialConditionsTransport1D : public IStochasticTransportProblem {
public: public:
StochasticInitialConditionsTransport1D(Meshes &meshes) : StochasticInitialConditionsTransport1D(Meshes &meshes) :
IStochasticTransportProblem(GeneratorNames{"NormalDistributionGenerator"}, IStochasticTransportProblem(meshes,
meshes) {} GeneratorNames{"NormalDistributionGenerator"}) {}
Scalar Solution(double t, const Point &x) const override { Scalar Solution(double t, const Point &x) const override {
if (abs(1.0 * t - x[0] + 0.5) > 0.06251) return 0.0; if (abs(1.0 * t - x[0] + 0.5) > 0.06251) return 0.0;
...@@ -266,8 +251,7 @@ public: ...@@ -266,8 +251,7 @@ public:
mu(VectorField(0.5, 0.5, 0.0)), mu(VectorField(0.5, 0.5, 0.0)),
sigma(Tensor()), sigma(Tensor()),
vectorField(VectorField(1 / sqrt(2), 1 / sqrt(2), 0)), vectorField(VectorField(1 / sqrt(2), 1 / sqrt(2), 0)),
IStochasticTransportProblem(GeneratorNames{"DummyGenerator"}, IStochasticTransportProblem(meshes) {
meshes) {
sigma[0][0] = 0.01; sigma[0][0] = 0.01;
sigma[0][1] = 0.0; sigma[0][1] = 0.0;
sigma[1][0] = 0.0; sigma[1][0] = 0.0;
...@@ -304,8 +288,7 @@ private: ...@@ -304,8 +288,7 @@ private:
public: public:
StochasticGaussHat2D(Meshes &meshes) : StochasticGaussHat2D(Meshes &meshes) :
vectorField(VectorField(1 / sqrt(2), 1 / sqrt(2), 0)), vectorField(VectorField(1 / sqrt(2), 1 / sqrt(2), 0)),
IStochasticTransportProblem(GeneratorNames{"DummyGenerator"}, IStochasticTransportProblem(meshes) {}
meshes) {}
Scalar Solution(double t, const Point &x) const override { Scalar Solution(double t, const Point &x) const override {
// Todo 2D Gaussfunction for t = 0 // Todo 2D Gaussfunction for t = 0
......
...@@ -52,14 +52,14 @@ void CirculantEmbedding1D::generateCoarseSample(const SampleID &id, ...@@ -52,14 +52,14 @@ void CirculantEmbedding1D::generateCoarseSample(const SampleID &id,
fineSample = nullptr; fineSample = nullptr;
} }
ComplexField1D CirculantEmbedding1D::generateField(const SampleID &id) { ComplexSequence1D CirculantEmbedding1D::generateField(const SampleID &id) {
generator.DrawSample(id); generator.DrawSample(id);
ComplexField1D normalDist = generator.EvalComplexField1DSample(); ComplexSequence1D normalDist = generator.EvalSample();
ComplexField1D Xf; ComplexSequence1D Xf;
fineComplexField.clear(); fineComplexField.clear();
Xf.resize(numberOfCellsEmbedded); Xf.resize(numberOfCellsEmbedded);