KratosMultiphysics / Kratos

Kratos Multiphysics (A.K.A Kratos) is a framework for building parallel multi-disciplinary simulation software. Modularity, extensibility and HPC are the main objectives. Kratos has BSD license and is written in C++ with extensive Python interface.
https://kratosmultiphysics.github.io/Kratos/
Other
1.03k stars 245 forks source link

Problem with the construction of nodes in the post-processing feature in TopOpt-Application. #8906

Open PhiHo-eng opened 3 years ago

PhiHo-eng commented 3 years ago

Hi everyone,

I am still working on the reactivation of the TopologyOptimizationApplication. While the topology optimization itself is working now, I have a problem with the post processing feature, which was already implemented in the application. To create a STL file of the optimized structure a surface mesh has to be done. For this a volume mesh is made first, where elements with the density below a certain threshold are deleted. The surface of this new structure is taken for the surface mesh. Depending on the element form (tedrahedral or hexahedral) the nodes on the surface are safed in the process and with these nodes the triangles for the STL file will be defined. While creating the new nodes of the surface mesh and saving the data from the volume mesh I get this error:

Traceback (most recent call last):
  File "run_TopOpt_PostProcessing.py", line 68, in <module>
    TopologyExtractorUtilities().ExtractSurfaceMesh(extracted_volume_model_part, extracted_surface_model_part)
RuntimeError: Error: Calling the default constructor for the node ... illegal operation!!

in kratos/includes/node.h:136:Node<TDimension, TDofType>::Node(Node<TDimension, TDofType>::IndexType) [with long unsigned int TDimension = 3; TDofType = Dof; Node<TDimension, TDofType>::IndexType = long unsigned int]
   kratos/applications/TopologyOptimizationApplication/custom_utilities/topology_extractor_utilities.h:378:void TopologyExtractorUtilities::ExtractSurfaceMesh(ModelPart&, ModelPart&)

It seems, that the nodes are being built with the default constructor, which is not allowed. But I am not sure, where the default constructor is called or how I avoid using it.

This error is caused in line 315 of topology_extractor_utilities.h (if the elements are hexahedral, else it is line 285). The function to create the susrface mesh is launched in run_TopOpt_PostProcessing.py.

Does anyone have an idea and can help me with this?

Thanks in advance!

philbucher commented 3 years ago

seems like you access nodes by Id, where the Id does not exist. Then it tries to create a new one, which results in the error you get

PhiHo-eng commented 3 years ago

Does this mean, that there is a problem with nodes Id of the volume mesh? Or am I just calling them in the wrong way?

philbucher commented 3 years ago

original_nodes_order[0] contains an Id of a Node that doesn't exist in the rExtractedVolumeModelPart

PhiHo-eng commented 3 years ago

Does this mean, that the definition of the Ids in topology_extractor_utilities.h is wrong? Because the rExtractedVolumeModelPart is used to assign the Ids and therfore they should be the same or am I missing something?

philbucher commented 3 years ago

probably But hard to say without looking into the code in detail

Is it a complex model or a simple one? Maybe the nodes rExtractedVolumeModelPart are not consecutively ordered? Not sure if this is an issue but could be

PhiHo-eng commented 3 years ago

No it is a small model. It is a MMB beam with 4800 elements. With the volume mesh there are only 3000 elements left.

I tried to adjust the code, so that it is similar to the existing code in hole_cutting_utility.cpp of ChimeraApplication, but I still get the same error.

The saving and sorting of the element Id is now done in the same way as in ChimeraApplication (see topology_extractor_utilities.h). I am not sure where the error is hidden.

philbucher commented 3 years ago

hm then I also don't know

@adityaghantasala could you have a look? Since you did the Chimera

adityaghantasala commented 3 years ago

Sorry for late reply. @PhiHo-eng do you still have this problem ? Regarding usage in Chimera application, it will never come to the case where the size is 4, as we always have tetras in chimera (in 3D). https://github.com/PhiHo-eng/Kratos/blob/57450e685337055e9336b4bca7c7b4a602375aca/applications/TopologyOptimizationApplication/custom_utilities/topology_extractor_utilities.h#L306

So I did not encounter any problem there.

On an another note, look at the following processes

kratos/processes/skin_detection_process.h

or

kratos/processes/sub_model_part_skin_detection_process.h

If you can use them use them and delete the implementations in the TopOptApp. In fact, the above implementation is based on the same implementation as in the TopOptApp. Some time ago Vicente moved them to core.

Irrespective of that, do you know if the error is because its trying to create a node with ID = 0 , or some other number ?

PhiHo-eng commented 3 years ago

Hi @adityaghantasala, Thanks for your reply. Yes I still have the problem, but I narrowed it down, so that I was able to see that the model itself, where the densities below a certain threshold are deleted, is constructed in a non correct manner or the nodes are not properly initiated.

So you think that I should replace topology_extractor_utilities.h with the skin_detection_process.h?

adityaghantasala commented 3 years ago

So you think that I should replace topology_extractor_utilities.h with the skin_detection_process.h?

When possible yes, then the utility, since its in the core, is some how future proof.

Yes I still have the problem, but I narrowed it down, so that I was able to see that the model itself, where the densities below a certain threshold are deleted, is constructed in a non correct manner or the nodes are not properly initiated.

Sounds good so you know the problem now.

PhiHo-eng commented 3 years ago

It seems that the function for erasing the elements below a certain threshhold causes problems! Is therre a similar function in the core which I could use?

loumalouomega commented 3 years ago

It seems that the function for erasing the elements below a certain threshhold causes problems! Is therre a similar function in the core which I could use?

To do what?, remove old elements?

PhiHo-eng commented 3 years ago

Yes to remove elements with a propertiy (density) below a certain threshold. It seems that the code I use in topology_extractor_utilities.h erases the right elements but it errases all the nodes in my modelpart. Therefore as a result I get a modelpart with only elements and no nodes and this is why Kratos gives me the error if I want to use this modelpart.

loumalouomega commented 3 years ago

Strange, when you remove elements, nodes are preserved

loumalouomega commented 3 years ago

Strange, when you remove elements, nodes are preserved

I saw the code, can be improved greatly (and yes, it removes the nodes because reason)

PhiHo-eng commented 3 years ago

I think this erases all the nodes: topology_extractor_utilities.h But it shoould only erase the nodes of the erased elements.

loumalouomega commented 3 years ago

I think this erases all the nodes: topology_extractor_utilities.h But it shoould only erase the nodes of the erased elements.

Should erase the "orphan nodes"?

loumalouomega commented 3 years ago

I mean the nodes not belonging to any element

PhiHo-eng commented 3 years ago

Exactly!

PhiHo-eng commented 3 years ago

But it erases alll the nodes in the modelpart

loumalouomega commented 3 years ago

But it erases alll the nodes in the modelpart

The code is very prone to be improved, and in a relatively easy maner

PhiHo-eng commented 3 years ago

I agree! Do you have any suggestions of how to do that with this example?

loumalouomega commented 3 years ago

I agree! Do you have any suggestions of how to do that with this example?

// Assuming you already have removed the elements that are not OK
// The following code is not in parallel, this is just and example
// The unodered_set with all the Ok nodes
std::unorderd_set<std::size_t> index_ok_nodes;
for (auto& r_elem : r_model_part.Elements()) {
    for (auto& r_node : r_elem.GetGeometry()) {
        index_ok_nodes.insert(r_node.Id());
    }
}

// Set flags in nodes
for (auto& r_node : r_model_part.Nodes()) {
    if (index_ok_nodes.find(r_node.Id()) == index_ok_nodes.end()) {
        r_node.Set(TO_ERASE);
    }
}

// Remove elements
r_model_part.RemoveNodesFromAllLevels(TO_ERASE);

i was writing the code

PhiHo-eng commented 3 years ago

Thank you, I think this solved the porbelm. At least the problem with the erased nodes seems to be solved. Now I have to check if the following tasks are working alright.

Thank you in the meantime! This was a great help!