Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding new hydraulic utilities #12280

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
a075d84
adding new hydraulic utilities
uxuech Apr 15, 2024
6007772
adding new utilities
uxuech Apr 15, 2024
7d7b8bd
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
a0b2af2
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
0a8402b
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
9f96dc7
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
5e79e67
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
81f16ae
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
bbf06c2
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
98d6752
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
80aa392
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
6382364
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
b80f85b
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
f264f67
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
8dc0dd7
Update applications/FluidDynamicsHydraulicsApplication/tests/test_hyd…
uxuech Apr 16, 2024
6072d3c
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
8c7eb05
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
505343e
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
5c3777f
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
b3d4ef1
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
f4e55a9
Update applications/FluidDynamicsHydraulicsApplication/custom_utiliti…
uxuech Apr 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,26 @@ void AddCustomUtilitiesToPython(pybind11::module& m)
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, avoid all the non-necessary changes in the format as these complicate very much differentiating the new additions.

namespace py = pybind11;
py::class_<HydraulicFluidAuxiliaryUtilities>(m, "HydraulicFluidAuxiliaryUtilities")
.def_static("CalculateWettedPetimeter", [](ModelPart &rModelPart, const Flags &rSkinFlag, const Variable<double> &rDistanceVariable, const bool IsHistorical){return HydraulicFluidAuxiliaryUtilities::CalculateWettedPetimeter(rModelPart, rSkinFlag, rDistanceVariable, IsHistorical);})
.def_static("CalculateWettedArea", [](ModelPart &rModelPart, const Flags &rSkinFlag, const Variable<double> &rDistanceVariable, const bool IsHistorical){return HydraulicFluidAuxiliaryUtilities::CalculateWettedArea(rModelPart, rSkinFlag, rDistanceVariable, IsHistorical);})
.def_static("InitialWaterDepth", [](ModelPart &rModelPart){return HydraulicFluidAuxiliaryUtilities::InitialWaterDepth(rModelPart);})
.def_static("SetInletVelocity", [](ModelPart &rModelPart, double InletVelocity, const Variable<double> &rDistanceVariable){return HydraulicFluidAuxiliaryUtilities::SetInletVelocity(rModelPart, InletVelocity, rDistanceVariable);})
.def_static("FreeInlet", [](ModelPart &rModelPart){return HydraulicFluidAuxiliaryUtilities::FreeInlet(rModelPart);})
.def_static("SetInletFreeSurface", [](ModelPart &rModelPart, const Flags &rSkinFlag, const Variable<double> &rDistanceVariable){return HydraulicFluidAuxiliaryUtilities::SetInletFreeSurface(rModelPart, rSkinFlag, rDistanceVariable);});
.def_static("CalculateWettedPetimeter", [](ModelPart &rModelPart, const Flags &rSkinFlag, const Variable<double> &rDistanceVariable, const bool IsHistorical)
{ return HydraulicFluidAuxiliaryUtilities::CalculateWettedPetimeter(rModelPart, rSkinFlag, rDistanceVariable, IsHistorical); })
.def_static("CalculateWettedArea", [](ModelPart &rModelPart, const Flags &rSkinFlag, const Variable<double> &rDistanceVariable, const bool IsHistorical)
{ return HydraulicFluidAuxiliaryUtilities::CalculateWettedArea(rModelPart, rSkinFlag, rDistanceVariable, IsHistorical); })
.def_static("InitialWaterDepth", [](ModelPart &rModelPart)
{ return HydraulicFluidAuxiliaryUtilities::InitialWaterDepth(rModelPart); })
.def_static("SetInletVelocity", [](ModelPart &rModelPart, double InletVelocity, const Variable<double> &rDistanceVariable)
{ return HydraulicFluidAuxiliaryUtilities::SetInletVelocity(rModelPart, InletVelocity, rDistanceVariable); })
.def_static("FreeInlet", [](ModelPart &rModelPart)
{ return HydraulicFluidAuxiliaryUtilities::FreeInlet(rModelPart); })
.def_static("SetInletFreeSurface", [](ModelPart &rModelPart, const Flags &rSkinFlag, const Variable<double> &rDistanceVariable)
{ return HydraulicFluidAuxiliaryUtilities::SetInletFreeSurface(rModelPart, rSkinFlag, rDistanceVariable); })
.def_static("FixCornerNodeVelocity", [](ModelPart &rModelPart, double MaximumAngle)
{ return HydraulicFluidAuxiliaryUtilities::FixCornerNodeVelocity(rModelPart, MaximumAngle); })
.def_static("TurnOffGravityOnAirElements", [](ModelPart &rModelPart)
{ return HydraulicFluidAuxiliaryUtilities::TurnOffGravityOnAirElements(rModelPart); })
.def_static("MaximumWaterDepthChange", [](ModelPart &rModelPart)
{ return HydraulicFluidAuxiliaryUtilities::MaximumWaterDepthChange(rModelPart); })
.def_static("CalculateArtificialViscosity", [](ModelPart &rModelPart, double LimiterCoefficient)
{ return HydraulicFluidAuxiliaryUtilities::CalculateArtificialViscosity(rModelPart, LimiterCoefficient); });
}

} // namespace Kratos::Python
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,141 @@ void HydraulicFluidAuxiliaryUtilities::SetInletFreeSurface(ModelPart &rModelPart
if (rNode.Is(rSkinFlag)){
double inlet_dist = rNode.GetValue(rDistanceVariable);
rNode.FastGetSolutionStepValue(DISTANCE) = inlet_dist;
rNode.Fix(DISTANCE);
// The distance is fixed in the water nodes since the inlet has velocity.
if (inlet_dist<0.0){
rNode.Fix(DISTANCE);
}
}
});
}

void HydraulicFluidAuxiliaryUtilities::TurnOffGravityOnAirElements(ModelPart &rModelPart){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you turn it on when an element changes back from air to water?

block_for_each(rModelPart.Elements(), [](Element &rElement){
auto &r_geom = rElement.GetGeometry();
Vector distances = ZeroVector(r_geom.PointsNumber());
Vector gravity = ZeroVector(3);
uxuech marked this conversation as resolved.
Show resolved Hide resolved
for (unsigned int i_nodes = 0; i_nodes < r_geom.PointsNumber(); i_nodes++){
distances[i_nodes] = r_geom[i_nodes].FastGetSolutionStepValue(DISTANCE);
}
uxuech marked this conversation as resolved.
Show resolved Hide resolved
if (FluidAuxiliaryUtilities::IsPositive(distances)){
for (unsigned int i_nodes = 0; i_nodes < r_geom.PointsNumber(); i_nodes++)
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please be consistent in the formatting, you either put the { in the same line or in a new one.

r_geom[i_nodes].FastGetSolutionStepValue(BODY_FORCE) = gravity;
}
}
});
}

void HydraulicFluidAuxiliaryUtilities::FixCornerNodeVelocity(ModelPart &rModelPart, double MaximumAngle)
uxuech marked this conversation as resolved.
Show resolved Hide resolved
{
// Obtain for each condition each neighbor condition
block_for_each(rModelPart.Nodes(), [&](NodeType &rNode){ rNode.SetValue(AUX_INDEX, 0); });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's a method in the variable utils for doing this.

ModelPart::ConditionsContainerType &r_cond = rModelPart.Conditions();
uxuech marked this conversation as resolved.
Show resolved Hide resolved
double angle_corner_rad = MaximumAngle / 180.0 * 3.14159; //
uxuech marked this conversation as resolved.
Show resolved Hide resolved
double acceptable_cos = cos(angle_corner_rad);
double max_height = block_for_each<MaxReduction<double>>(rModelPart.Nodes(), [&](NodeType &rNode){return rNode.Z();});
Comment on lines +338 to +339
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think both can be const.


block_for_each(rModelPart.Nodes(),[&](NodeType &rNode){
if(rNode.Z() >=max_height){
rNode.Set(MARKER,true);
}
});
for (ModelPart::ConditionsContainerType::iterator cond_it = r_cond.begin(); cond_it != r_cond.end(); cond_it++)
uxuech marked this conversation as resolved.
Show resolved Hide resolved
{
// reference for area normal of the face
const array_1d<double, 3> &face_normal = cond_it->GetValue(NORMAL);
uxuech marked this conversation as resolved.
Show resolved Hide resolved
double An = norm_2(face_normal);
uxuech marked this conversation as resolved.
Show resolved Hide resolved
const GlobalPointersVector<Condition> &neighb = cond_it->GetValue(NEIGHBOUR_CONDITIONS);
uxuech marked this conversation as resolved.
Show resolved Hide resolved
const GeometryType &r_geom = cond_it->GetGeometry();
uxuech marked this conversation as resolved.
Show resolved Hide resolved
auto edgelist = r_geom.GenerateEdges();
for (unsigned int c_itr = 0; c_itr < neighb.size(); c_itr++){
auto rCondition = neighb[c_itr];
const array_1d<double, 3> &face_neig_normal = rCondition.GetValue(NORMAL);
uxuech marked this conversation as resolved.
Show resolved Hide resolved
double cos_angle = 1 / (An * norm_2(face_neig_normal)) * inner_prod(face_normal, face_neig_normal);
uxuech marked this conversation as resolved.
Show resolved Hide resolved
auto &r_geom_neig = rCondition.GetGeometry();
uxuech marked this conversation as resolved.
Show resolved Hide resolved
auto edgelist_neig = r_geom_neig.GenerateEdges();
array_1d<double, 2> ids_neig;
array_1d<double, 2> ids_cond;
Comment on lines +360 to +361
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
array_1d<double, 2> ids_neig;
array_1d<double, 2> ids_cond;
array_1d<double, 2> ids_neig;
array_1d<double, 2> ids_cond;

Allocate these two outside the loop.

if (cos_angle < acceptable_cos){
for (IndexType edge = 0; edge < edgelist.size(); edge++){
for (IndexType i = 0; i < edgelist[edge].size(); i++){
ids_cond[i] = edgelist[edge][i].Id();
}
std::sort(ids_cond.begin(), ids_cond.end());
for (IndexType edge_neg = 0; edge_neg < edgelist_neig.size(); edge_neg++){
for (IndexType i = 0; i < edgelist_neig[edge_neg].size(); i++){
ids_neig[i] = edgelist_neig[edge_neg][i].Id();
}
std::sort(ids_neig.begin(), ids_neig.end());
if (ids_cond == ids_neig){
for (IndexType i = 0; i < edgelist[edge].size(); i++){
double repeated = edgelist[edge][i].GetValue(AUX_INDEX);
repeated += 1;
edgelist[edge][i].SetValue(AUX_INDEX, repeated);
Comment on lines +375 to +377
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can avoid the get/set by directly using the get with += 1.

}
}
}
}
}
}
}
block_for_each(rModelPart.Nodes(),[&](NodeType &rNode){
if (rNode.GetValue(AUX_INDEX)*0.5>=3 && rNode.Is(MARKER)){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (rNode.GetValue(AUX_INDEX)*0.5>=3 && rNode.Is(MARKER)){
if (rNode.GetValue(AUX_INDEX)*0.5>=3 && rNode.Is(MARKER)){

Why this?

Vector veloctiy = ZeroVector(3);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allocate the vector outside the loop.

rNode.FastGetSolutionStepValue(VELOCITY) = veloctiy;
rNode.Fix(VELOCITY_X);
rNode.Fix(VELOCITY_Y);
rNode.Fix(VELOCITY_Z);
double value= rNode.GetValue(AUX_INDEX);
rNode.SetValue(AUX_INDEX,value*0.5);
Comment on lines +392 to +393
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment, you can avoid the get/set.

}
else{
rNode.SetValue(AUX_INDEX,0.0);
}
});
}

bool HydraulicFluidAuxiliaryUtilities::MaximumWaterDepthChange(const ModelPart &rModelPart){
// make sure the Ids of the Nodes start with one
const double &min_Z = block_for_each<MinReduction<double>>(rModelPart.Nodes(), [&](const auto &rNode){ return rNode.Z(); });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why taking a reference in here?

//TODO: Try to create a min reduction with a pointer to avoid this second loop
bool maximum_water_depth_change = false;
block_for_each(rModelPart.Nodes(), [&](const Node &rNode){
if (std::abs(rNode.Z() - min_Z) < 1.0e-10 && !maximum_water_depth_change){
const double inlet_phi = rNode.GetValue(AUX_DISTANCE);
const double domain_phi = rNode.FastGetSolutionStepValue(DISTANCE);
if (std::abs(domain_phi) > std::abs(inlet_phi)){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you want to check this? Shouldn't you check that the absolute value of the difference is below a threshold?

maximum_water_depth_change=true;
}
}});
return maximum_water_depth_change;
}

void HydraulicFluidAuxiliaryUtilities::CalculateArtificialViscosity(ModelPart &rModelPart, double LimiterCoefficient)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the style guide for the arguments.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides, I just realized that MaximumArtificialViscosity would be a much convenient variable name for this magnitude. As far as I understand, this is not a limiting coefficient but a viscosity.

{
const auto &r_process_info = rModelPart.GetProcessInfo();
block_for_each(rModelPart.Elements(), [&](Element &rElement){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please respect indentation in this loop? It would ease quite a lot going through the code inside the block_for_each...

double artificial_viscosity;
rElement.Calculate(ARTIFICIAL_DYNAMIC_VISCOSITY,artificial_viscosity ,r_process_info);
if (artificial_viscosity > LimiterCoefficient){
artificial_viscosity = LimiterCoefficient;
}
double neg_nodes = 0.0;
double pos_nodes=0.0;
uxuech marked this conversation as resolved.
Show resolved Hide resolved
for (auto &r_node : rElement.GetGeometry()){
uxuech marked this conversation as resolved.
Show resolved Hide resolved
double distance = r_node.FastGetSolutionStepValue(DISTANCE);
uxuech marked this conversation as resolved.
Show resolved Hide resolved
if (distance > 0){
pos_nodes += 1;
}
else{
neg_nodes += 1;
}
}
if (neg_nodes > 0 && pos_nodes > 0){
artificial_viscosity = 0.0;
}
rElement.SetValue(ARTIFICIAL_DYNAMIC_VISCOSITY, artificial_viscosity);
});
}

} // namespace Kratos
} // namespace Kratos
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ class KRATOS_API(FLUID_DYNAMICS_HYDRAULICS_APPLICATION) HydraulicFluidAuxiliaryU
using PointsArrayType = typename GeometryType::PointsArrayType;

using ModifiedShapeFunctionsFactoryType = std::function<ModifiedShapeFunctions::UniquePointer(const GeometryType::Pointer, const Vector&)>;
struct NodeConditionDataStruct
{
NodeType Node; // Condition normal
double CornerNode; // Gauss point shape functions values
};
Comment on lines +55 to +59
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is used nowhere...


///@}
///@name Static Operations
Expand Down Expand Up @@ -116,18 +121,45 @@ class KRATOS_API(FLUID_DYNAMICS_HYDRAULICS_APPLICATION) HydraulicFluidAuxiliaryU
* @param rDistancesVariable Variable name of the inlet distance.
*/
static void SetInletFreeSurface(ModelPart &rModelPart, const Flags &rSkinFlag, const Variable<double> &rDistanceVariable);


///@}
/**
* @brief For all elements that are completly air the gravity is turned off.
* @param rModelPart FluidModelPart
*/
static void TurnOffGravityOnAirElements(ModelPart &rModelPart);

/**
* @brief Fixing the velocity to corner nodes in the skin modelpart.
* @param rModelPart FluidModelPart
* @param MaximumAngle Minimum angle for considering corner.
*/

static void FixCornerNodeVelocity(ModelPart &rModelPart, double MaximumAngle);
uxuech marked this conversation as resolved.
Show resolved Hide resolved

private :
/**
* @brief The maximum water depth at the inlet is adjusted based on the maximum depth within the entire domain.
* If the water depth at the inlet is less than the maximum depth across the domain, the inlet water depth is adjusted to match its maximum depth.
* @param rModelPart Inlet Model Part

*/
static bool MaximumWaterDepthChange(const ModelPart &rModelPart);
/**
* @brief Calculate the artificial viscosity which is proportional to the maximum velocity gradient
* @param rModelPart Fluid Model Part
* @param LimiterCoefficient a coefficient to limit the maximum artificial viscosity
*

*/
static void CalculateArtificialViscosity(ModelPart &rModelPart, double LimiterCoefficient);
uxuech marked this conversation as resolved.
Show resolved Hide resolved
///@}

private:
struct EdgeDataContainer
{
NodeType::Pointer pNodeI = nullptr;
NodeType::Pointer pNodeJ = nullptr;
SizeType NumberOfRepetitions = 0;
};
};

}; // namespace Kratos
}; // namespace Kratos
uxuech marked this conversation as resolved.
Show resolved Hide resolved
}
Loading
Loading