41 "model_part_name":"PLEASE_CHOOSE_MODEL_PART_NAME",
42 "variable_name": "PLEASE_PRESCRIBE_VARIABLE_NAME",
45 "gravity_direction": 1,
46 "out_of_plane_direction": 2,
47 "pressure_tension_cut_off" : 0.0,
53 rParameters[
"variable_name"];
54 rParameters[
"model_part_name"];
56 mIsFixedProvided = rParameters.
Has(
"is_fixed");
61 mVariableName = rParameters[
"variable_name"].
GetString();
65 mIsFixed = rParameters[
"is_fixed"].
GetBool();
66 mIsSeepage = rParameters[
"is_seepage"].
GetBool();
67 mGravityDirection = rParameters[
"gravity_direction"].
GetInt();
68 mOutOfPlaneDirection = rParameters[
"out_of_plane_direction"].
GetInt();
69 if (mGravityDirection == mOutOfPlaneDirection)
70 KRATOS_ERROR <<
"Gravity direction cannot be the same as Out-of-Plane directions"
74 mHorizontalDirection = 0;
76 if (
i!=mGravityDirection &&
i!=mOutOfPlaneDirection) mHorizontalDirection =
i;
78 mPressureTensionCutOff = rParameters[
"pressure_tension_cut_off"].
GetDouble();
103 const double pressure = CalculatePressure(rNode);
105 if (pressure < PORE_PRESSURE_SIGN_FACTOR * mPressureTensionCutOff) {
106 rNode.FastGetSolutionStepValue(var) = pressure;
107 if (mIsFixed) rNode.Fix(var);
112 rNode.FastGetSolutionStepValue(var) = std::min(pressure,PORE_PRESSURE_SIGN_FACTOR * mPressureTensionCutOff);
113 if (mIsFixed) rNode.Fix(var);
114 else if (mIsFixedProvided) rNode.Free(var);
122 std::string
Info()
const override
124 return "ApplyConstantInterpolateLinePressureProcess";
130 std::string mVariableName;
132 bool mIsFixedProvided;
134 unsigned int mGravityDirection;
135 unsigned int mOutOfPlaneDirection;
136 unsigned int mHorizontalDirection;
137 std::vector< Node * > mBoundaryNodes;
138 double mPressureTensionCutOff;
140 double CalculatePressure(
const Node &rNode)
143 std::vector< Node* > TopBoundaryNodes;
144 FindTopBoundaryNodes(rNode, TopBoundaryNodes);
146 double CoordinateTop;
147 CalculateBoundaryPressure(rNode, TopBoundaryNodes, PressureTop, CoordinateTop);
150 std::vector< Node* > BottomBoundaryNodes;
151 FindBottomBoundaryNodes(rNode, BottomBoundaryNodes);
152 double PressureBottom;
153 double CoordinateBottom;
154 CalculateBoundaryPressure(rNode, BottomBoundaryNodes, PressureBottom, CoordinateBottom,
true);
157 if (std::abs(CoordinateTop - CoordinateBottom) >
TINY) {
158 const double slopeP = (PressureTop - PressureBottom) / (CoordinateTop - CoordinateBottom);
159 return slopeP * (rNode.
Coordinates()[mGravityDirection] - CoordinateBottom ) + PressureBottom;
161 return PressureBottom;
165 void CalculateBoundaryPressure(
const Node &rNode,
166 const std::vector< Node*> &BoundaryNodes,
169 bool isBottom=
false )
172 std::vector< Node*> LeftBoundaryNodes;
173 FindLeftBoundaryNodes(rNode, BoundaryNodes, LeftBoundaryNodes);
175 std::vector< Node*> RightBoundaryNodes;
176 FindRightBoundaryNodes(rNode, BoundaryNodes, RightBoundaryNodes);
178 if (!LeftBoundaryNodes.empty() && !RightBoundaryNodes.empty()) {
179 const Node *LeftNode = FindClosestNodeOnBoundaryNodes(rNode, LeftBoundaryNodes, isBottom);
180 const Node *RightNode = FindClosestNodeOnBoundaryNodes(rNode, RightBoundaryNodes, isBottom);
182 InterpolateBoundaryPressure(rNode, LeftNode, RightNode,
pressure, coordinate);
185 }
else if (!LeftBoundaryNodes.empty()) {
186 InterpolateBoundaryPressureWithOneContainer(rNode, LeftBoundaryNodes,
pressure, coordinate);
189 }
else if (!RightBoundaryNodes.empty()) {
190 InterpolateBoundaryPressureWithOneContainer(rNode, RightBoundaryNodes,
pressure, coordinate);
194 KRATOS_ERROR <<
"There is not enough points around interpolation, node Id" << rNode.Id() << std::endl;
199 void InterpolateBoundaryPressureWithOneContainer(
const Node &rNode,
200 const std::vector< Node*> &BoundaryNodes,
204 std::vector< Node*> FoundNodes;
205 FindTwoClosestNodeOnBoundaryNodes(rNode, BoundaryNodes, FoundNodes);
207 const Variable<double> &var = KratosComponents< Variable<double> >::Get(mVariableName);
209 const double &pressureLeft = FoundNodes[0]->FastGetSolutionStepValue(var);
211 noalias(CoordinatesLeft) = FoundNodes[0]->Coordinates();
213 const double &pressureRight = FoundNodes[1]->FastGetSolutionStepValue(var);
215 noalias(CoordinatesRight) = FoundNodes[1]->Coordinates();
218 if (std::abs(CoordinatesRight[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]) >
TINY) {
219 const double slopeP = (pressureRight - pressureLeft) / (CoordinatesRight[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]);
220 pressure = slopeP * (rNode.Coordinates()[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]) + pressureLeft;
222 const double slopeY = (CoordinatesRight[mGravityDirection] - CoordinatesLeft[mGravityDirection]) / (CoordinatesRight[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]);
223 coordinate = slopeY * (rNode.Coordinates()[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]) + CoordinatesLeft[mGravityDirection];
226 coordinate = CoordinatesLeft[mGravityDirection];
230 void InterpolateBoundaryPressure(
const Node &rNode,
231 const Node *LeftNode,
232 const Node *RightNode,
236 const Variable<double> &var = KratosComponents< Variable<double> >::Get(mVariableName);
238 const double &pressureLeft = LeftNode->FastGetSolutionStepValue(var);
240 noalias(CoordinatesLeft) = LeftNode->Coordinates();
242 const double &pressureRight = RightNode->FastGetSolutionStepValue(var);
244 noalias(CoordinatesRight) = RightNode->Coordinates();
247 if (std::abs(CoordinatesRight[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]) >
TINY) {
248 const double slopeP = (pressureRight - pressureLeft) / (CoordinatesRight[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]);
249 pressure = slopeP * (rNode.Coordinates()[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]) + pressureLeft;
251 const double slopeY = (CoordinatesRight[mGravityDirection] - CoordinatesLeft[mGravityDirection]) / (CoordinatesRight[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]);
252 coordinate = slopeY * (rNode.Coordinates()[mHorizontalDirection] - CoordinatesLeft[mHorizontalDirection]) + CoordinatesLeft[mGravityDirection];
255 coordinate = CoordinatesLeft[mGravityDirection];
259 void FindTwoClosestNodeOnBoundaryNodes(
const Node &rNode,
260 const std::vector< Node*> &BoundaryNodes,
261 std::vector< Node*> &FoundNodes)
263 const double HorizontalCoordinate = rNode.Coordinates()[mHorizontalDirection];
264 FoundNodes.resize(2);
266 unsigned int nFound = 0;
267 double horizontalDistanceClosest_1 =
LARGE;
268 for (
unsigned int i = 0;
i < BoundaryNodes.size(); ++
i) {
270 noalias(CoordinatesBoundary) = BoundaryNodes[
i]->Coordinates();
272 if (std::abs(CoordinatesBoundary[mHorizontalDirection] - HorizontalCoordinate) <= horizontalDistanceClosest_1) {
273 horizontalDistanceClosest_1 = std::abs(CoordinatesBoundary[mHorizontalDirection] - HorizontalCoordinate);
274 FoundNodes[0] = BoundaryNodes[
i];
279 double horizontalDistanceClosest_2 =
LARGE;
280 for (
unsigned int i = 0;
i < BoundaryNodes.size(); ++
i) {
282 noalias(CoordinatesBoundary) = BoundaryNodes[
i]->Coordinates();
284 if (std::abs(CoordinatesBoundary[mHorizontalDirection] - HorizontalCoordinate) <= horizontalDistanceClosest_2 &&
285 std::abs(CoordinatesBoundary[mHorizontalDirection] - HorizontalCoordinate) > horizontalDistanceClosest_1) {
286 horizontalDistanceClosest_2 = std::abs(CoordinatesBoundary[mHorizontalDirection] - HorizontalCoordinate);
287 FoundNodes[1] = BoundaryNodes[
i];
292 KRATOS_ERROR_IF(nFound < 2) <<
"Not enough points for interpolation: Coordinates"<< rNode.Coordinates() << std::endl;
296 Node* FindClosestNodeOnBoundaryNodes(
const Node &rNode,
297 const std::vector< Node* > &BoundaryNodes,
300 const double HorizontalCoordinate = rNode.Coordinates()[mHorizontalDirection];
302 std::vector< Node*> FoundNodes;
304 double horizontalDistance =
LARGE;
305 for (
unsigned int i = 0;
i < BoundaryNodes.size(); ++
i) {
306 if (std::abs(BoundaryNodes[
i]->Coordinates()[mHorizontalDirection] - HorizontalCoordinate) <= horizontalDistance) {
307 horizontalDistance = std::abs(BoundaryNodes[
i]->Coordinates()[mHorizontalDirection] - HorizontalCoordinate);
308 FoundNodes.push_back(BoundaryNodes[
i]);
313 double height =
LARGE;
314 for (
unsigned int i = 0;
i < FoundNodes.size(); ++
i) {
315 if (FoundNodes[
i]->Coordinates()[mGravityDirection] < height) {
316 pNode = FoundNodes[
i];
317 height = FoundNodes[
i]->Coordinates()[mGravityDirection];
321 double height = -
LARGE;
322 for (
unsigned int i = 0;
i < FoundNodes.size(); ++
i) {
323 if (FoundNodes[
i]->Coordinates()[mGravityDirection] > height) {
324 pNode = FoundNodes[
i];
325 height = FoundNodes[
i]->Coordinates()[mGravityDirection];
333 void FindTopBoundaryNodes(
const Node &rNode,
334 std::vector< Node* > &TopBoundaryNodes)
336 for (
unsigned int i = 0;
i < mBoundaryNodes.size(); ++
i) {
337 if (mBoundaryNodes[
i]->Coordinates()[mGravityDirection] >= rNode.Coordinates()[mGravityDirection]) {
339 TopBoundaryNodes.push_back(mBoundaryNodes[
i]);
344 void FindBottomBoundaryNodes(
const Node &rNode,
345 std::vector< Node*> &BottomBoundaryNodes)
347 for (
unsigned int i = 0;
i < mBoundaryNodes.size(); ++
i) {
348 if (mBoundaryNodes[
i]->Coordinates()[mGravityDirection] <= rNode.Coordinates()[mGravityDirection]) {
350 BottomBoundaryNodes.push_back(mBoundaryNodes[
i]);
355 void FindLeftBoundaryNodes(
const Node &rNode,
356 const std::vector< Node*> &BoundaryNodes,
357 std::vector< Node*> &LeftBoundaryNodes)
359 for (
unsigned int i = 0;
i < BoundaryNodes.size(); ++
i) {
360 if (BoundaryNodes[
i]->Coordinates()[mHorizontalDirection] <= rNode.Coordinates()[mHorizontalDirection]) {
362 LeftBoundaryNodes.push_back(BoundaryNodes[
i]);
367 void FindRightBoundaryNodes(
const Node &rNode,
368 const std::vector< Node*> &BoundaryNodes,
369 std::vector< Node*> &RightBoundaryNodes)
371 for (
unsigned int i = 0;
i < BoundaryNodes.size(); ++
i) {
372 if (BoundaryNodes[
i]->Coordinates()[mHorizontalDirection] >= rNode.Coordinates()[mHorizontalDirection]) {
374 RightBoundaryNodes.push_back(BoundaryNodes[
i]);
386 MaxNodeID = std::max<int>(MaxNodeID, rNode.Id());
394 void FindBoundaryNodes()
398 std::vector<int> BoundaryNodes;
400 FillListOfBoundaryNodesFast(BoundaryNodes);
401 mBoundaryNodes.resize(BoundaryNodes.size());
403 unsigned int iPosition = 0;
405 const int Id = rNode.Id();
406 for (unsigned int j = 0; j < BoundaryNodes.size(); ++j) {
407 if (Id == BoundaryNodes[j]) {
408 mBoundaryNodes[iPosition++] = &rNode;
416 void FillListOfBoundaryNodesFast(std::vector<int> &BoundaryNodes)
418 const int ID_UNDEFINED = -1;
419 const int N_ELEMENT = 10;
421 std::vector<std::vector<int>> ELementsOfNodes;
422 std::vector<int> ELementsOfNodesSize;
424 int MaxNodeID = GetMaxNodeID();
426 ELementsOfNodes.resize(MaxNodeID);
427 ELementsOfNodesSize.resize(MaxNodeID);
429 for (
unsigned int i=0;
i < ELementsOfNodes.size(); ++
i) {
430 ELementsOfNodes[
i].resize(N_ELEMENT);
431 ELementsOfNodesSize[
i] = 0;
432 std::fill(ELementsOfNodes[
i].begin(), ELementsOfNodes[
i].
end(), ID_UNDEFINED);
435 const unsigned int nElements = mrModelPart.NumberOfElements();
436 ModelPart::ElementsContainerType::iterator it_begin_elements = mrModelPart.ElementsBegin();
438 for (
unsigned int i=0;
i < nElements; ++
i) {
439 ModelPart::ElementsContainerType::iterator pElemIt = it_begin_elements +
i;
440 for (
unsigned int iPoint=0; iPoint < pElemIt->GetGeometry().PointsNumber(); ++iPoint) {
441 int NodeID = pElemIt->GetGeometry()[iPoint].Id();
442 int ElementId = pElemIt->Id();
444 int index = NodeID-1;
445 ELementsOfNodesSize[index]++;
446 if (ELementsOfNodesSize[index] > N_ELEMENT-1) {
447 ELementsOfNodes[index].push_back(ElementId);
449 ELementsOfNodes[index][ELementsOfNodesSize[index]-1] = ElementId;
454 for (
unsigned int i=0;
i < nElements; ++
i) {
455 ModelPart::ElementsContainerType::iterator pElemIt = it_begin_elements +
i;
457 int nEdges = pElemIt->GetGeometry().EdgesNumber();
458 for (
int iEdge = 0; iEdge < nEdges; ++iEdge) {
459 const unsigned int nPoints = pElemIt->GetGeometry().GenerateEdges()[iEdge].PointsNumber();
460 std::vector<int> FaceID(nPoints);
461 for (
unsigned int iPoint = 0; iPoint < nPoints; ++iPoint) {
462 FaceID[iPoint] = pElemIt->GetGeometry().GenerateEdges()[iEdge].GetPoint(iPoint).Id();
465 if (!IsMoreThanOneElementWithThisEdgeFast(FaceID, ELementsOfNodes, ELementsOfNodesSize)) {
467 for (
unsigned int iPoint = 0; iPoint < nPoints; ++iPoint) {
468 auto it = std::find(BoundaryNodes.begin(), BoundaryNodes.end(), FaceID[iPoint]);
469 if (it == BoundaryNodes.end()) {
470 BoundaryNodes.push_back(FaceID[iPoint]);
478 <<
"No boundary node is found for interpolate line pressure process" << std::endl;
482 bool IsMoreThanOneElementWithThisEdgeFast(
const std::vector<int> &FaceID,
483 const std::vector<std::vector<int>> &ELementsOfNodes,
484 const std::vector<int> &ELementsOfNodesSize)
487 const int ID_UNDEFINED = -1;
488 int nMaxElements = 0;
489 for (
unsigned int iPoint = 0; iPoint < FaceID.size(); ++iPoint) {
490 int NodeID = FaceID[iPoint];
491 int index = NodeID-1;
492 nMaxElements += ELementsOfNodesSize[index];
495 if (nMaxElements > 0) {
496 std::vector<vector<int>> ElementIDs;
497 ElementIDs.resize(FaceID.size());
498 for (
unsigned int i=0;
i<ElementIDs.size(); ++
i) {
499 ElementIDs[
i].resize(nMaxElements);
500 std::fill(ElementIDs[
i].begin(), ElementIDs[
i].
end(), ID_UNDEFINED);
503 for (
unsigned int iPoint = 0; iPoint < FaceID.size(); ++iPoint) {
504 int NodeID = FaceID[iPoint];
505 int index = NodeID-1;
506 for (
int i=0;
i < ELementsOfNodesSize[index]; ++
i) {
507 int iElementID = ELementsOfNodes[index][
i];
508 ElementIDs[iPoint][
i] = iElementID;
512 std::vector<int> SharedElementIDs;
513 for (
unsigned int iPoint = 0; iPoint < FaceID.size(); ++iPoint) {
514 for (
unsigned int i=0;
i < ElementIDs[iPoint].size(); ++
i) {
515 int iElementID = ElementIDs[iPoint][
i];
517 if (iElementID !=ID_UNDEFINED) {
518 for (
unsigned int iPointInner = 0; iPointInner < FaceID.size(); ++iPointInner) {
519 if (iPointInner != iPoint) {
521 for (
unsigned int j = 0;
j < ElementIDs[iPointInner].size(); ++
j) {
522 if (ElementIDs[iPointInner][
j]==iElementID) found =
true;
529 std::vector<int>::iterator it = std::find(SharedElementIDs.begin(), SharedElementIDs.end(), iElementID);
530 if (it == SharedElementIDs.end()) {
531 SharedElementIDs.push_back(iElementID);
537 return SharedElementIDs.size() > 1;
554 rOStream << std::endl;
Definition: apply_constant_interpolate_line_pressure_process.hpp:26
~ApplyConstantInterpolateLinePressureProcess() override=default
ApplyConstantInterpolateLinePressureProcess & operator=(const ApplyConstantInterpolateLinePressureProcess &)=delete
std::string Info() const override
Turn back information as a string.
Definition: apply_constant_interpolate_line_pressure_process.hpp:122
void ExecuteInitialize() override
Definition: apply_constant_interpolate_line_pressure_process.hpp:96
ApplyConstantInterpolateLinePressureProcess & operator=(ApplyConstantInterpolateLinePressureProcess &&)=delete
void Execute() override
Execute method is used to execute the ApplyConstantInterpolateLinePressureProcess algorithms.
Definition: apply_constant_interpolate_line_pressure_process.hpp:90
KRATOS_CLASS_POINTER_DEFINITION(ApplyConstantInterpolateLinePressureProcess)
ApplyConstantInterpolateLinePressureProcess(ModelPart &model_part, Parameters rParameters)
Definition: apply_constant_interpolate_line_pressure_process.hpp:32
ApplyConstantInterpolateLinePressureProcess(const ApplyConstantInterpolateLinePressureProcess &)=delete
ApplyConstantInterpolateLinePressureProcess(ApplyConstantInterpolateLinePressureProcess &&)=delete
KratosComponents class encapsulates a lookup table for a family of classes in a generic way.
Definition: kratos_components.h:49
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class defines the node.
Definition: node.h:65
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
double GetDouble() const
This method returns the double contained in the current Parameter.
Definition: kratos_parameters.cpp:657
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
void ValidateAndAssignDefaults(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing match the form prescribed by th...
Definition: kratos_parameters.cpp:1306
std::string GetString() const
This method returns the string contained in the current Parameter.
Definition: kratos_parameters.cpp:684
bool Has(const std::string &rEntry) const
This method checks if the Parameter contains a certain entry.
Definition: kratos_parameters.cpp:520
bool GetBool() const
This method returns the boolean contained in the current Parameter.
Definition: kratos_parameters.cpp:675
CoordinatesArrayType const & Coordinates() const
Definition: point.h:215
The base class for all processes in Kratos.
Definition: process.h:49
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: process.h:204
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: process.h:210
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
end
Definition: DEM_benchmarks.py:180
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
constexpr SizeType N_DIM_3D
Definition: geo_mechanics_application_constants.h:25
void block_for_each(TIterator itBegin, TIterator itEnd, TFunction &&rFunction)
Execute a functor on all items of a range in parallel.
Definition: parallel_utilities.h:299
constexpr double LARGE
Definition: geo_mechanics_application_constants.h:31
array_1d< double, 3 > Vector3
Definition: variables.cpp:26
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
std::ostream & operator<<(std::ostream &rOStream, const ApplyConstantInterpolateLinePressureProcess &rThis)
output stream function
Definition: apply_constant_interpolate_line_pressure_process.hpp:550
std::istream & operator>>(std::istream &rIStream, ApplyConstantInterpolateLinePressureProcess &rThis)
input stream function
constexpr double TINY
Definition: geo_mechanics_application_constants.h:30
model_part
Definition: face_heat.py:14
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17
float pressure
Definition: test_pureconvectionsolver_benchmarking.py:101