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/tutorial_02_CDESolverD2Q5_R.hpp>
27 #include <UtilLib/include/Exception.hpp>
28 #include <UtilLib/include/Log.hpp>
39 const double gamma = 100.0;
41 const double deltaT = 1.0e-4;
45 static std::random_device rd;
46 static std::mt19937 gen(rd());
47 static std::uniform_real_distribution<> dis(-0.01, 0.01);
50 for (
auto d : cdeDirIter_) {
51 distributions_[d] = 0.0;
55 for (
auto d : cdeDirIter_) {
56 distributions_[d] = (1.0 + dis(gen))/5.0;
63 for (
auto d : distributions_) {
64 (*stream) <<
'\t' << d;
74 for (
auto d : cdeDirIter_) {
75 (*stream) >> distributions_[d];
80 assert(dir > T && dir < NE);
81 return distributions_[dir];
85 for (
auto &it: this->distributions_) {
91 return std::accumulate(distributions_.begin(), distributions_.end(), 0.0);
96 const double R = this->
getC();
100 return gamma * (a - R + R * R * L);
110 const double C =
getC();
116 const double w0 = C / 3.0;
117 const double w1 = C / 6.0;
118 const double tauI = 1.0 /
getTau();
123 temp[E] = w1 * (1.0 + ux * 3.0);
124 temp[N] = w1 * (1.0 + uy * 3.0);
125 temp[W] = w1 * (1.0 + (-ux) * 3.0);
126 temp[S] = w1 * (1.0 + (-uy) * 3.0);
128 const double reactionTerm = this->
reaction();
129 const double reactionTerm_ZERO = deltaT*reactionTerm / 3.0;
130 const double reactionTerm_OTHERS = deltaT*reactionTerm / 6.0;
132 distributions_[T] = distributions_[T] - distributions_[T] * tauI + temp[T] * tauI + reactionTerm_ZERO;
133 distributions_[E] = distributions_[E] - distributions_[E] * tauI + temp[E] * tauI + reactionTerm_OTHERS;
134 distributions_[N] = distributions_[N] - distributions_[N] * tauI + temp[N] * tauI + reactionTerm_OTHERS;
135 distributions_[W] = distributions_[W] - distributions_[W] * tauI + temp[W] * tauI + reactionTerm_OTHERS;
136 distributions_[S] = distributions_[S] - distributions_[S] * tauI + temp[S] * tauI + reactionTerm_OTHERS;
143 const double C =
getC();
148 const double w1 = C / 6.0;
155 return w1 * (1.0 + u * 3.0);
158 return w1 * (1.0 + v * 3.0);
161 return w1 * (1.0 + (-u) * 3.0);
164 return w1 * (1.0 + (-v) * 3.0);
169 "you want to get a inverse direction of a Direction that does not exist");
176 std::swap(distributions_[getInverseDirection(W)],
179 std::swap(distributions_[getInverseDirection(S)],
184 void tutorial_02_CDESolverD2Q5_R::localSwap() {
185 std::swap(distributions_[E], distributions_[W]);
186 std::swap(distributions_[N], distributions_[S]);
196 std::array<Direction, 4> dir1 {{E, N, W, S}};
197 for (
auto d : dir1) {
209 std::array<Direction, 4> dir2 {{NE, NW, SW, SE}};
210 for (
auto d : dir2) {
221 std::stringstream message;
222 message << std::setprecision(12);
223 message <<
"Default initialisation on PhysicalNode ";
225 message <<
" failed. Therefore the node was reinitialised from the diagonal directions";
226 LOG(UtilLib::logINFO) << message.str().c_str();
233 std::stringstream message;
234 message << std::setprecision(12)
235 <<
"Initialization on PhysicalNode "
237 <<
" failed at time "
238 << Parameters.getCurrentIteration()
239 <<
". Therefore the node was initialized with all neighbors {E,N,W,S}, ignoring their domainID."
241 for (
auto d : dir1) {
247 LOG(UtilLib::logINFO) << message.str().c_str();
250 sumC /=
static_cast<double>(counter);
251 for (
auto d : cdeDirIter_) {
252 this->distributions_[d] = sumC / 5.0;
257 const std::string tutorial_02_CDESolverD2Q5_R::name =
"tutorial_02_CDESolverD2Q5_R";
263 tutorial_02_CDESolverD2Q5_R::tutorial_02_CDESolverD2Q5_R() :
BaseCDESolver(),
264 distributions_(std::array<double,
virtual double calculateEquilibrium(const Direction &dir)
calculateEquilibrium calculates the equilibirum for direction dir
solver::CDEAbstractSolver & getCDESolverSlow(const std::string &name) const
getCDESolverSlow Getter method for the cde Solver
The Base class for all CDESolver implementations This classes uses the recursive template idiom to au...
size_t solverID_
solverID_ The ID of the solver instance. Coincides with the index in the vector PhysicalNode::cdeSolv...
virtual void advect()
advect The advect step of the LBM
PhysicalNode * getPhysicalNeighbour(const Direction &d) const
getPhysicalNeighbour Getter method to access the Physical Neighbour
virtual void reinitialise()
reinitialise this solver as the corresponding physical node has switched domain
const nodes::PhysicalNode * physicalNode_
physicalNode_ The physical Node which owns this solver
virtual void collide()
collide The collision step of the LBM
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
virtual double & accessDistribution(const Direction &dir)
accessDistribution Access to the distribution
unsigned int getDomainIdentifier() const
getter for the Domain Identifier of this node
virtual double getC() const
getC Calculates the concentration on this node
virtual void rescaleDistributions(const double factor)
Rescales all distributions by a factor.
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
virtual void writeSolver(std::ostream *const stream)
writes the solver to the stream
virtual void loadSolver(std::stringstream *const stream)
loads the solver from the stream
BoundaryNode * getBoundaryNeighbour(const Direction &d) const
getBoundaryNeighbour Getter method to access the Boundary Neighbour
int getYPos() const
getYPos Getter for the Y position
const double reaction(void) const
reaction The reaction term of the tutorial_02_CDESolverD2Q5_R solver is implemented here...
solver::CDEAbstractSolver & getCDESolver(size_t id) const
getCDESolver Getter method for the cde Solver
virtual void initSolver()
initSolver Use this to initalise the solver
T y
y the value in y direction