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

[Core] Add Voxel Mesh Generation Modeler #12297

Merged
merged 38 commits into from
May 16, 2024
Merged

Conversation

jcotela
Copy link
Member

@jcotela jcotela commented Apr 19, 2024

📝 Description

This PR adds the Voxel Mesh Generator Modeler developed at @KratosMultiphysics/altair to the Kratos core. The modeler uses a modular approach to combine different strategies for its various steps:

  • Generation of the key planes of the underlying regular grid
  • Coloring of sets of voxels within the grid based on different criteria
  • Mesh generation (which acts on all voxels of the same color) for tetrahedra, quadrilateral and their faces.
  • ModelPart operations, which are post-process steps that can be applied after meshing and make use of the meshing data (currently used to find contacts between different sets of generated entities)

The modeler is registered in KratosCore so that it can be used through the standard factory.

Also included in the PR are C++ and Python tests for multiple meshing configurations.

🆕 Changelog

  • Add VoxelMeshGeneratorModeler

@jcotela jcotela requested a review from a team as a code owner April 19, 2024 14:46
@loumalouomega loumalouomega changed the title [core] Add Voxel Mesh Generation Modeler [Core] Add Voxel Mesh Generation Modeler Apr 19, 2024
Copy link
Member

@philbucher philbucher left a comment

Choose a reason for hiding this comment

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

Great addition!

This is pretty large for reviewing, some initial comments/observations

r_colors.AddGeometry(r_geometry, false);
}
} else{
KRATOS_ERROR << "The input_entities " << parameters["input_entities"] << " is not supported. The supported input_entities are elements and conditions" << std::endl;
Copy link
Member

Choose a reason for hiding this comment

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

missing geometries

Copy link
Member Author

Choose a reason for hiding this comment

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

updated the message

Comment on lines 45 to 55
for(auto& r_element : r_model_part.Elements()) {
Element::GeometryType& r_geometry = r_element.GetGeometry();
CheckGeometryType(r_geometry.GetGeometryType());
r_colors.AddGeometry(r_geometry, false);
}
} else if(input_entities == "conditions"){
for(auto& r_condition : r_model_part.Conditions()) {
Condition::GeometryType& r_geometry = r_condition.GetGeometry();
CheckGeometryType(r_geometry.GetGeometryType());
r_colors.AddGeometry(r_geometry, false);
}
Copy link
Member

Choose a reason for hiding this comment

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

conceptual question, should those still be allowed?
The overall goal is to move away from using elements and conditions in the input and only use geometries

Copy link
Member Author

Choose a reason for hiding this comment

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

I have nothing to say about the longer term plan, but I can tell you that we typically use this with a "traditional" mdpa file as input, so supporting elements is important for us at the moment.

Comment on lines +44 to +51
// Now we find the min and max value for the node coordinates
Vector min_v(3,std::numeric_limits<double>::max()), max_v(3, -std::numeric_limits<double>::max());
for(auto& node: GetInputModelPart().Nodes()){
double x = node.X(), y = node.Y(), z = node.Z();
min_v[0] = std::min(min_v[0], x); max_v[0] = std::max(max_v[0], x);
min_v[1] = std::min(min_v[1], y); max_v[1] = std::max(max_v[1], y);
min_v[2] = std::min(min_v[2], z); max_v[2] = std::max(max_v[2], z);
}
Copy link
Member

Choose a reason for hiding this comment

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

this can be very easily parallelized with the parallel utils

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed, but that requires a reduction to a bounding box, which we don't have at the moment. I would rather do that on a separate PR, with proper tests, rather than make this one bigger. It would also be a good candidate for a custom reduction in the sense of #12195, if we go ahead with that one.

Timer::Stop("EntityGeneration");
}

ModelPart& VoxelMeshGeneratorModeler::CreateAndGetModelPart(std::string const& FullName)
Copy link
Member

Choose a reason for hiding this comment

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

I am pretty sure the Model does the same nowadays
@sunethwarna can you confirm pls?

Copy link
Member Author

Choose a reason for hiding this comment

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

I am using the model capabilities now, but I'm leaving a helper function to check for existence of the new model part (as in that case the model method logs a warning)

return *p_current_model_part;
}

ModelPart& VoxelMeshGeneratorModeler::GetModelPart(std::string const& FullName)
Copy link
Member

Choose a reason for hiding this comment

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

same, the Model does exactly this

Copy link
Member Author

Choose a reason for hiding this comment

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

This function was not used, so I'm removing it.

kratos/modeler/voxel_mesh_generator_modeler.h Outdated Show resolved Hide resolved
///@name Serializer
///@{

friend class Serializer;
Copy link
Member

Choose a reason for hiding this comment

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

I dont see this used, is it?

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed.

Comment on lines +304 to +308
//Register Voxel Modeler modular components
RegisterVoxelMesherColoring();
RegisterVoxelMesherKeyPlaneGeneration();
RegisterVoxelMesherEntityGeneration();
RegisterVoxelMesherOperation();
Copy link
Member

Choose a reason for hiding this comment

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

Is this really necessary? Usually this is done generic, why does the VoxelMesher require different treatment?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure if I understand you correctly but the only special treatment the VoxelMesher gets in terms of the registry is that it uses its own factory class. This is due to historical reasons (it started as a monolithic class and we eventually made the different components modular. The json input format that was already in use at that point is not compatible with what the standard Kratos factory expects, so we made our own factory class to parse the existing json)

Copy link
Member Author

Choose a reason for hiding this comment

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

Just to clarify, this Factory is for internal use within the modeler (it is used to instantiate the requested components on demand). The modeler itself is registered using the same approach as for other C++ modelers, with the usual kratos factory class.

Copy link
Member

@loumalouomega loumalouomega left a comment

Choose a reason for hiding this comment

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

A lot of code could be moved to source files, I will take a look later

@loumalouomega
Copy link
Member

I don't know how, but I broke CentOS after 3be5c90 after just changing the headers¿?

@jcotela
Copy link
Member Author

jcotela commented May 8, 2024

I think that I found the issue with the Centos7 CI, it turns out that the way some array_1d were being initialized from zero_vector was triggering an error if BOOST_UBLAS_TYPE_CHECK is enabled (I believe that this is implied by the -Wignored-qualifiers compiler flag? That macro is not defined in normal FullDebug builds)

@loumalouomega please let the CI run for this change before merging master, to see if we fixed the issue.

Copy link
Member

@roigcarlo roigcarlo left a comment

Choose a reason for hiding this comment

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

Mostly pedantic comments from my part, and some remarks about #pragma omp in some places, but in general 👍

kratos/modeler/internals/cartesian_mesh_colors.h Outdated Show resolved Hide resolved
keep_merging = false;
if(r_i_partition.size()>3){
// The first one and the last one cannot be removed or moved.
for (int i = 1; i+1 < (int) r_i_partition.size()-1; ++i) { //This is to ensure we don't remove the last one nor the first one so i+1 is the end - 1
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
for (int i = 1; i+1 < (int) r_i_partition.size()-1; ++i) { //This is to ensure we don't remove the last one nor the first one so i+1 is the end - 1
for (int i = 1; i+1 < static_cast<int>(r_i_partition.size()-1); ++i) { //This is to ensure we don't remove the last one nor the first one so i+1 is the end - 1

(or std::size_t i if not going to parallelize)

Same with all the dynamic cast in the file

return I + J * mElementCenterCoordinates[0].size() + K * mElementCenterCoordinates[1].size() * mElementCenterCoordinates[0].size();
}
public:
CartesianMeshColors(): mTolerance(1e-12), mMinPoint(0.00, 0.00, 0.00), mMaxPoint(0.00, 0.00, 0.00){}
Copy link
Member

Choose a reason for hiding this comment

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

Why double .00 instead of 0.0?

Happens in several places.

mNodalCoordinates[1] = rNodalYCoordinates;
mNodalCoordinates[2] = rNodalZCoordinates;

for(int i = 0 ; i < 3 ; i++){
Copy link
Member

Choose a reason for hiding this comment

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

I would use std::size_t to keep it consistent.

Same with the other loops in the file.


namespace Kratos
{
using SizeType = std::size_t;
Copy link
Member

Choose a reason for hiding this comment

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

std::size_t is being used directly in the file in most of the cases. Unless the implementation for some code is not dependent on the size I would just remove this.

kratos/modeler/voxel_mesh_generator_modeler.cpp Outdated Show resolved Hide resolved
Comment on lines 45 to 46
typedef std::size_t SizeType;
typedef std::size_t IndexType;
Copy link
Member

Choose a reason for hiding this comment

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

Not used (that I've seen)

{
using namespace Kratos;

WriteCubeSkinMeshMdpaFile();
Copy link
Member

Choose a reason for hiding this comment

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

Please remove file after test has finished (for all the tests).

const int cell_color = parameters["cell_color"].GetInt();
KRATOS_INFO("Modeler") << "Finding contacts for " << r_skin_part.FullName() << " model part" << std::endl;

block_for_each(r_skin_part.Conditions(),[&](Condition& rCondition) {
Copy link
Member

Choose a reason for hiding this comment

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

@roigcarlo @jcotela the critical is called here

@jcotela
Copy link
Member Author

jcotela commented May 14, 2024

I think we have addressed all review comments. Feel free to add some more.

@jcotela
Copy link
Member Author

jcotela commented May 15, 2024

@roigcarlo I have removed the active pragma omp (replaced them by IndexPartitions) but I have left the ones that were commented out. I would like to keep them as a reminder of places were we disabled parallelism, since it might still be possible to make them parallel in the future. We will address those in a separate PR.

Copy link
Member

@loumalouomega loumalouomega left a comment

Choose a reason for hiding this comment

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

I think this is ready to goI

@roigcarlo
Copy link
Member

👍 from my side as well.

@jcotela jcotela merged commit 94a3e3b into master May 16, 2024
11 checks passed
@jcotela jcotela deleted the feature/voxel-mesh-modeler branch May 16, 2024 09:23
@jcotela jcotela mentioned this pull request May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

4 participants