22 #include <LbmLib/include/geometry/Connection.hpp>
23 #include <LbmLib/include/nodes/BoundaryNode.hpp>
24 #include <LbmLib/include/nodes/GeometryNode.hpp>
25 #include <LbmLib/include/nodes/PhysicalNode.hpp>
27 #include <LbmLib/include/Constants.hpp>
29 #include <UtilLib/include/Log.hpp>
52 std::shared_ptr<nodes::GeometryNode>
const p1,
53 std::shared_ptr<nodes::GeometryNode>
const p2,
54 const std::map<std::string, std::vector<std::string> > connectionType,
55 unsigned int domainId) : points_(std::make_pair(p1, p2)),
56 connectionType_(connectionType),
57 domainIdentifier_(domainId)
112 return (y2 - y1) / (x2 - x1);
123 double getAxisIntercept(
128 return y1 - (y2 - y1) / (x2 - x1) * x1;
138 double getAxisIntercept(
146 Field<double> Connection::calculateVelocity(
const nodes::BoundaryNode& bNode) {
147 const double l = getDistance(*points_.first,bNode);
148 const double L = getDistance(*points_.second, *points_.first);
149 const double vx1 = this->points_.first->getXVelocity();
150 const double vy1 = this->points_.first->getYVelocity();
151 const double vx2 = this->points_.second->getXVelocity();
152 const double vy2 = this->points_.second->getYVelocity();
153 const double vx = (vx2-vx1) * l/L + vx1;
154 const double vy = (vy2-vy1) * l/L + vy1;
155 assert(std::isfinite(l));
156 assert(std::isfinite(L));
157 assert(std::isfinite(vx1));
158 assert(std::isfinite(vy1));
159 assert(std::isfinite(vx2));
160 assert(std::isfinite(vy2));
161 assert(std::isfinite(vx));
162 assert(std::isfinite(vy));
171 (*stream) << points_.first->getId() <<
'\t' << points_.second->getId() <<
172 '\t' << domainIdentifier_;
173 for (
const auto& bSolver : connectionType_) {
174 for (
const auto& cdeSolver : bSolver.second) {
175 (*stream) <<
'\t' << bSolver.first <<
'\t' << cdeSolver;
184 std::unordered_set<nodes::BoundaryNode *> &boundaryNodes) {
185 assert(newBoundaryNode !=
nullptr);
186 assert(physicalNode !=
nullptr);
188 getInverseDirection(d));
191 if (old ==
nullptr) {
193 assert(std::isfinite(ftemp.
x));
194 assert(std::isfinite(ftemp.
y));
196 #pragma omp critical // boundaryNodes is not thread safe
198 boundaryNodes.insert(newBoundaryNode);
201 }
else if (getSquaredDistance(*physicalNode,
203 getSquaredDistance(*physicalNode, *old)) {
205 Field<double> ftemp = calculateVelocity(*newBoundaryNode);
206 assert(std::isfinite(ftemp.x));
207 assert(std::isfinite(ftemp.y));
210 #pragma omp critical // boundaryNodes is not thread safe
212 boundaryNodes.insert(newBoundaryNode);
214 #pragma omp critical // boundaryNodes is not thread safe
216 boundaryNodes.erase(old);
220 delete newBoundaryNode;
225 std::unordered_set<nodes::BoundaryNode *> &boundaryNodes) {
226 assert(std::isfinite(this->points_.first->getXPos()));
227 assert(std::isfinite(this->points_.first->getYPos()));
228 assert(std::isfinite(this->points_.second->getXPos()));
229 assert(std::isfinite(this->points_.second->getYPos()));
230 double maxX = std::max(this->points_.first->getXPos(), this->points_.second->getXPos());
231 double maxY = std::max(this->points_.first->getYPos(), this->points_.second->getYPos());
232 double minX = std::min(this->points_.first->getXPos(), this->points_.second->getXPos());
233 double minY = std::min(this->points_.first->getYPos(), this->points_.second->getYPos());
236 double m = getGradient(points_.first->getXPos(),
237 points_.second->getXPos(),
238 points_.first->getYPos(), points_.second->getYPos());
241 double n = getAxisIntercept(
242 points_.first->getXPos(),
243 points_.second->getXPos(),
244 points_.first->getYPos(), points_.second->getYPos());
246 if (std::isfinite(m)) {
248 for (
int i = std::ceil(minX); i <= std::floor(maxX); i++) {
251 if (points_.first->getXPos() < points_.second->getXPos()) {
256 this->domainIdentifier_);
270 this->domainIdentifier_);
274 physicalNodes[std::floor(getYPos(m, i, n))][i];
276 physicalNodes[std::ceil(getYPos(m, i, n))][i];
278 this->insertBoundaryNode(bpS, fluidS, S, boundaryNodes);
279 this->insertBoundaryNode(bpN, fluidN, N, boundaryNodes);
283 for (
int i = std::ceil(minY); i <= std::floor(maxY); i++) {
286 if (points_.first->getYPos() > points_.second->getYPos()) {
290 n), i, connectionType_,
294 n), i, connectionType_,
295 this->domainIdentifier_);
300 n), i, connectionType_,
301 this->domainIdentifier_);
304 n), i, connectionType_,
308 physicalNodes[i][std::floor(getXPos(m, i, n))];
310 physicalNodes[i][std::ceil(getXPos(m, i, n))];
312 this->insertBoundaryNode(bpW, fluidW, W, boundaryNodes);
313 this->insertBoundaryNode(bpE, fluidE, E, boundaryNodes);
316 std::stringstream message;
317 message << std::setprecision(12);
318 message <<
"This can only happen if something went wrong with the perturbation of the connection. ";
319 message <<
"p1.x="<<points_.first->getXPos()<<
", p1.y="<<points_.first->getYPos();
320 message <<
", p2.x="<<points_.second->getXPos()<<
", p2.y="<<points_.second->getYPos();
322 lbm_fail(message.str().c_str());
326 std::pair<const std::shared_ptr<nodes::GeometryNode>,
327 const std::shared_ptr<nodes::GeometryNode> >
Connection::
334 static std::random_device rd;
336 static std::mt19937 gen(seed);
337 static std::uniform_real_distribution<> dis(-PERTURBATION, PERTURBATION);
339 if (std::abs(points_.first->getXPos() - points_.second->getXPos()) <
341 std::stringstream message;
342 message << std::setprecision(12)
343 <<
"Perturbation of Connection ("
344 << this->points_.first->getId() <<
"->" << this->points_.second->getId()<<
") "
345 <<
"(" << this->points_.first->getXPos() <<
"," << this->points_.first->getYPos() <<
")"
347 <<
"(" << this->points_.second->getXPos() <<
"," << this->points_.second->getYPos() <<
") "
350 while(std::abs(temprand) < 5.0*EPSILON) {
353 points_.first->setPos(
354 points_.first->getXPos() + temprand,
355 points_.first->getYPos());
356 message <<
"(" << this->points_.first->getXPos() <<
"," << this->points_.first->getYPos() <<
")"
358 <<
"(" << this->points_.second->getXPos() <<
"," << this->points_.second->getYPos() <<
") ";
360 LOG(UtilLib::logINFO) << message.str().c_str();
363 if (std::abs(points_.first->getYPos() - points_.second->getYPos()) <
365 std::stringstream message;
366 message << std::setprecision(12)
367 <<
"Perturbation of Connection ("
368 << this->points_.first->getId() <<
"->" << this->points_.second->getId()<<
") "
369 <<
"(" << this->points_.first->getXPos() <<
"," << this->points_.first->getYPos() <<
")"
371 <<
"(" << this->points_.second->getXPos() <<
"," << this->points_.second->getYPos() <<
") "
374 while(std::abs(temprand) < 5.0*EPSILON) {
377 points_.first->setPos(
378 points_.first->getXPos(),
379 points_.first->getYPos() + temprand);
380 message <<
"(" << this->points_.first->getXPos() <<
"," << this->points_.first->getYPos() <<
")"
382 <<
"(" << this->points_.second->getXPos() <<
"," << this->points_.second->getYPos() <<
") ";
385 LOG(UtilLib::logINFO) << message.str().c_str();
390 return std::sqrt((this->points_.first->getXPos() - this->points_.second->getXPos()) *
391 (this->points_.first->getXPos() - this->points_.second->getXPos()) +
392 (this->points_.first->getYPos() - this->points_.second->getYPos()) *
393 (this->points_.first->getYPos() - this->points_.second->getYPos()));
397 return this->domainIdentifier_;
401 return this->connectionType_;
406 this->domainIdentifier_ = domainIdentifier;
void setDomainIdentifier(const unsigned int domainIdentifier)
Setter for the domainIdentifier_.
virtual void setVelocity(Field< double > velocity)
setVelocity Set the velocity
void writeConnection(std::ofstream *const stream)
writes the connection ot the stream
const std::map< std::string, std::vector< std::string > > getBoundaryConditionDescriptor() const
Getter for the boundary condition descriptor.
unsigned int getDomainIdentifier() const
Getter for the domainID on the left side of this connection.
void perturbConnection()
perturbConnection makes sure that the connection has a slope not near to 0 or infinitive ...
class representing a physical node
T x
x the value in x direction
~Connection()
~Connection non-virutal Destructor
double getLength() const
Compute the length of the connection.
Connection(std::shared_ptr< nodes::GeometryNode > const p1, std::shared_ptr< nodes::GeometryNode > const p2, const std::map< std::string, std::vector< std::string > > connectionType, unsigned int domainId)
Connection A simple connection connecting two geometry nodes.
std::pair< std::shared_ptr< nodes::GeometryNode > const, std::shared_ptr< nodes::GeometryNode > const > getGeometryNodes() const
getGeometryNodes Getter method for the geometry nodes defining this connection
BoundaryNode * getBoundaryNeighbour(const Direction &d) const
getBoundaryNeighbour Getter method to access the Boundary Neighbour
class representing a boundary node
void generateBoundaryNodes(const std::vector< std::vector< nodes::PhysicalNode * > > &physicalNode, std::unordered_set< nodes::BoundaryNode * > &boundaryNodes)
generateBoundaryNodes Calculates all possible boundary points defined by this connection, generates and connects them accordingly
T y
y the value in y direction
void setPhysicalNeighbours(PhysicalNode *const physicalNode, const Direction &dir)
setPhysicalNeighbours Sets the corresponding Physical neighbours of this node