22 #include <LbmLib/include/nodes/BoundaryNode.hpp>
23 #include <LbmLib/include/nodes/PhysicalNode.hpp>
24 #include <LbmLib/include/GlobalSimulationParameters.hpp>
25 #include <LbmLib/include/solver/BoundaryAbstractSolver.hpp>
26 #include <LbmLib/include/solver/CDESolver/SchnakenbergD2Q5u.hpp>
28 #include <UtilLib/include/Exception.hpp>
29 #include <UtilLib/include/Log.hpp>
38 const double gamma = 800.0;
45 static std::random_device rd;
46 static std::mt19937 gen(rd());
47 static std::uniform_real_distribution<> dis(-0.01, 0.01);
48 double temp = 0.2 * (1.0 + dis(gen));
49 for (
auto d : cdeDirIter_) {
50 distributions_[d] = temp;
53 for (
auto d : cdeDirIter_) {
54 distributions_[d] = 0.0;
57 deltaT = 20.0 / Parameters.getIterations();
62 for (
auto d : distributions_) {
63 (*stream) <<
'\t' << d;
73 for (
auto d : cdeDirIter_) {
74 (*stream) >> distributions_[d];
79 assert(dir > T && dir < NE);
80 return distributions_[dir];
84 for (
auto &it: this->distributions_) {
90 return std::accumulate(distributions_.begin(), distributions_.end(), 0.0);
96 const double C =
getC();
102 const double w0 = C / 3.0;
103 const double w1 = C / 6.0;
104 const double tauI = 1.0 /
getTau();
109 temp[E] = w1 * (1.0 + ux * 3.0);
110 temp[N] = w1 * (1.0 + uy * 3.0);
111 temp[W] = w1 * (1.0 + (-ux) * 3.0);
112 temp[S] = w1 * (1.0 + (-uy) * 3.0);
114 const std::string schnakenbergD2Q5v =
"SchnakenbergD2Q5v";
116 double reaktionTerm = deltaT * gamma * (a - C + C * C * Cv) / 3.0;
117 double reaktionTermR = deltaT * gamma * (a - C + C * C * Cv) / 6.0;
122 distributions_[T] = distributions_[T] - distributions_[T] * tauI + temp[T] *
124 distributions_[E] = distributions_[E] - distributions_[E] * tauI + temp[E] *
125 tauI + reaktionTermR;
126 distributions_[N] = distributions_[N] - distributions_[N] * tauI + temp[N] *
127 tauI + reaktionTermR;
128 distributions_[W] = distributions_[W] - distributions_[W] * tauI + temp[W] *
129 tauI + reaktionTermR;
130 distributions_[S] = distributions_[S] - distributions_[S] * tauI + temp[S] *
131 tauI + reaktionTermR;
145 const double C =
getC();
150 const double w1 = C / 6.0;
157 return w1 * (1.0 + u * 3.0);
160 return w1 * (1.0 + v * 3.0);
163 return w1 * (1.0 + (-u) * 3.0);
166 return w1 * (1.0 + (-v) * 3.0);
171 "you want to get a inverse direction of a Direction that does not exist");
178 std::swap(distributions_[getInverseDirection(W)],
181 std::swap(distributions_[getInverseDirection(S)],
186 void SchnakenbergD2Q5u::localSwap() {
187 std::swap(distributions_[E], distributions_[W]);
188 std::swap(distributions_[N], distributions_[S]);
194 for (
auto d : cdeDirIter_) {
200 getDomainIdentifier()) ) {
207 std::array<Direction, 4> dir {{NE, NW, SW, SE}
213 getDomainIdentifier()) {
220 LOG(UtilLib::logINFO) <<
221 "the default initialisation failed. Therefore the node was reinitialised from the diagonal directions";
225 "The cde solver failed to reinitialise the node, this might be due to a stange geometry");
227 sumC /=
static_cast<double>(counter);
228 for (
auto d : cdeDirIter_) {
229 distributions_[d] = sumC / 4.0;
234 const std::string SchnakenbergD2Q5u::name =
"SchnakenbergD2Q5u";
241 distributions_(std::array<double,
virtual double getC() const
getC Calculates the concentration on this node
solver::CDEAbstractSolver & getCDESolverSlow(const std::string &name) const
getCDESolverSlow Getter method for the cde Solver
virtual void advect()
advect The advect step of the LBM
The Base class for all CDESolver implementations This classes uses the recursive template idiom to au...
virtual double calculateEquilibrium(const Direction &dir)
calculateEquilibrium calculates the equilibirum for direction dir
size_t solverID_
solverID_ The ID of the solver instance. Coincides with the index in the vector PhysicalNode::cdeSolv...
virtual void collide()
collide The collision step of the LBM
PhysicalNode * getPhysicalNeighbour(const Direction &d) const
getPhysicalNeighbour Getter method to access the Physical Neighbour
const nodes::PhysicalNode * physicalNode_
physicalNode_ The physical Node which owns this solver
The CDEDirectionsIteratorD2Q5 class Provides methods to handle the Directions. Use the Function Direc...
T x
x the value in x direction
virtual double & accessDistribution(const Direction &dir)=0
accessDistribution Access to the distribution
unsigned int getDomainIdentifier() const
getter for the Domain Identifier of this node
virtual double getC() const =0
getC Calculates the concentration on this node
const Field< double > & getVelocity() const
getVelocity Returns the current velocity of the fluid
double getTau() const
getTau Getter method for the tau parameter
const solver::FluidSolver & getFluidSolver() const
getFluidSolver Const getter method for the fluid Solver
int getXPos() const
getXPos Getter for the X position
BoundaryNode * getBoundaryNeighbour(const Direction &d) const
getBoundaryNeighbour Getter method to access the Boundary Neighbour
virtual void writeSolver(std::ostream *const stream)
writes the solver to the stream
int getYPos() const
getYPos Getter for the Y position
solver::CDEAbstractSolver & getCDESolver(size_t id) const
getCDESolver Getter method for the cde Solver
virtual void reinitialise()
reinitialise this solver as the corresponding physical node has switched domain
virtual void rescaleDistributions(const double factor)
Rescales all distributions by a factor.
virtual void initSolver()
initSolver Use this to initalise the solver
T y
y the value in y direction
virtual double & accessDistribution(const Direction &dir)
accessDistribution Access to the distribution
virtual void loadSolver(std::stringstream *const stream)
loads the solver from the stream