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_L.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);
97 const double L = this->
getC();
101 return gamma * (b - R * R * L);
111 const double C =
getC();
117 const double w0 = C / 3.0;
118 const double w1 = C / 6.0;
119 const double tauI = 1.0 /
getTau();
124 temp[E] = w1 * (1.0 + ux * 3.0);
125 temp[N] = w1 * (1.0 + uy * 3.0);
126 temp[W] = w1 * (1.0 + (-ux) * 3.0);
127 temp[S] = w1 * (1.0 + (-uy) * 3.0);
129 const double reactionTerm = this->
reaction();
130 const double reactionTerm_ZERO = deltaT*reactionTerm / 3.0;
131 const double reactionTerm_OTHERS = deltaT*reactionTerm / 6.0;
133 distributions_[T] = distributions_[T] - distributions_[T] * tauI + temp[T] * tauI + reactionTerm_ZERO;
134 distributions_[E] = distributions_[E] - distributions_[E] * tauI + temp[E] * tauI + reactionTerm_OTHERS;
135 distributions_[N] = distributions_[N] - distributions_[N] * tauI + temp[N] * tauI + reactionTerm_OTHERS;
136 distributions_[W] = distributions_[W] - distributions_[W] * tauI + temp[W] * tauI + reactionTerm_OTHERS;
137 distributions_[S] = distributions_[S] - distributions_[S] * tauI + temp[S] * tauI + reactionTerm_OTHERS;
144 const double C =
getC();
149 const double w1 = C / 6.0;
156 return w1 * (1.0 + u * 3.0);
159 return w1 * (1.0 + v * 3.0);
162 return w1 * (1.0 + (-u) * 3.0);
165 return w1 * (1.0 + (-v) * 3.0);
170 "you want to get a inverse direction of a Direction that does not exist");
177 std::swap(distributions_[getInverseDirection(W)],
180 std::swap(distributions_[getInverseDirection(S)],
185 void tutorial_02_CDESolverD2Q5_L::localSwap() {
186 std::swap(distributions_[E], distributions_[W]);
187 std::swap(distributions_[N], distributions_[S]);
197 std::array<Direction, 4> dir1 {{E, N, W, S}};
198 for (
auto d : dir1) {
210 std::array<Direction, 4> dir2 {{NE, NW, SW, SE}};
211 for (
auto d : dir2) {
222 std::stringstream message;
223 message << std::setprecision(12);
224 message <<
"Default initialisation on PhysicalNode ";
226 message <<
" failed. Therefore the node was reinitialised from the diagonal directions";
227 LOG(UtilLib::logINFO) << message.str().c_str();
234 std::stringstream message;
235 message << std::setprecision(12)
236 <<
"Initialization on PhysicalNode "
238 <<
" failed at time "
239 << Parameters.getCurrentIteration()
240 <<
". Therefore the node was initialized with all neighbors {E,N,W,S}, ignoring their domainID."
242 for (
auto d : dir1) {
248 LOG(UtilLib::logINFO) << message.str().c_str();
251 sumC /=
static_cast<double>(counter);
252 for (
auto d : cdeDirIter_) {
253 this->distributions_[d] = sumC / 5.0;
258 const std::string tutorial_02_CDESolverD2Q5_L::name =
"tutorial_02_CDESolverD2Q5_L";
264 tutorial_02_CDESolverD2Q5_L::tutorial_02_CDESolverD2Q5_L() :
BaseCDESolver(),
265 distributions_(std::array<double,
solver::CDEAbstractSolver & getCDESolverSlow(const std::string &name) const
getCDESolverSlow Getter method for the cde Solver
virtual void initSolver()
initSolver Use this to initalise the solver
The Base class for all CDESolver implementations This classes uses the recursive template idiom to au...
virtual void advect()
advect The advect step of the LBM
size_t solverID_
solverID_ The ID of the solver instance. Coincides with the index in the vector PhysicalNode::cdeSolv...
virtual void loadSolver(std::stringstream *const stream)
loads the solver from the stream
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
const double reaction(void) const
reaction The reaction term of the tutorial_02_CDESolverD2Q5_L solver is implemented here...
virtual void rescaleDistributions(const double factor)
Rescales all distributions by a factor.
virtual double getC() const =0
getC Calculates the concentration on this node
virtual void collide()
collide The collision step of the LBM
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 double calculateEquilibrium(const Direction &dir)
calculateEquilibrium calculates the equilibirum for direction dir
BoundaryNode * getBoundaryNeighbour(const Direction &d) const
getBoundaryNeighbour Getter method to access the Boundary Neighbour
virtual double getC() const
getC Calculates the concentration on this node
virtual void writeSolver(std::ostream *const stream)
writes the solver to the stream
int getYPos() const
getYPos Getter for the Y position
virtual void reinitialise()
reinitialise this solver as the corresponding physical node has switched domain
solver::CDEAbstractSolver & getCDESolver(size_t id) const
getCDESolver Getter method for the cde Solver
T y
y the value in y direction
virtual double & accessDistribution(const Direction &dir)
accessDistribution Access to the distribution