Trigen PFEM refine
Variables Needed and their meaning
The following 4 variables need to be defined in order to perform the re-meshing using "Trigen PFEM refine":
By default, only the elements of the fluid are re-created. Therefore, you have to mark all the nodes of the elements you are passing to the mesher as "IS_FLUID". All the nodes that might be added during adaptive the refinement (see add_nodes argument of the function ReGenerateMesh) have IS_FLUID=1.0 by default.
IS_STRUCTURE switch is necessary to distinguish such parts of the domain as walls etc. Mesher treats the elements whose nodes have non-zero IS_STRUCTURE flag in a different way. The elements that have all nodes with IS_STRUCTURE=1.0 are automatically removed from the mesh.
IS_BOUNDARY is necessary to determine the boundaries, that include free surfaces, and boundaries between the fluid anb the structure (i.e. between the fluid and the wall).
IS_FREE_SURFACE is a flag that is set on the free-surfaces to 1.0 and 0.0 elsewhere.
if any of these variables are not added in your application, an error will be thrown.
Input of the function
For re-meshing using "Trigen PFEM refine" you need to execute one single function ReGenerateMesh. The function is defined as follows:
ReGenerateMesh (ModelPart& ThisModelPart , Element const& rReferenceElement, Condition const& rReferenceBoundaryCondition, NodeEraseProcess& node_erase, bool rem_nodes = true, bool add_nodes=true, double my_alpha = 1.4, double h_factor=0.5)
We shall have a closer look at each argument one has to pass to the function.
1. ModelPart& ThisModelPart:
this is the model part you would like to re-mesh. see (Link to model_part for its meaning)
2. Element const& rReferenceElement:
is the name (of type string) of the element that has to be re-created, e.g. if you are using standard incompressible fluid element of Kratos, you have to pass "Fluid2D" as an argument.
3. Condition const& rReferenceBoundaryCondition:
is the name of condition that is to be re-created. If you are not using any condition (such as Face Pressure, or any of your custom-defined condition), just pass "Condition2D". Otherwise the name of you condition (e.g. "FacePressure2D")
4. NodeEraseProcess& node_erase:
the function re-generate permits one to control the mesh quality. For this reason some nodes that cause mesh distortion (e.g. get too close to one another) can to be removed from the mesh. The "Trigen Mesh refine" identifies those nodes automatically, but to remove those nodes from the database, one needs to use the NodeEraseProcess, which is a standard process of Kratos. Therefore, you should create this process beforehand, and then pass it to the ReGenerateMesh function as an argument. See the example section to undesrtand exactly how to implement this.
5. bool rem_nodes:
is the switch used to allow derefinement, i.e. nodes removal. If you shall like to remove the nodes that come too close (see the h_factor explanation for an exact meaning of "too close"), you have to pass "True" here. If you do not want any node to be removed, pass "False". By default the switch is activated as "True".
6. bool add_nodes :
is a smiliar switch, now permitting refinement, i.e. adding nodes. Pass "True" or "False" depending on weather you would like to refine your mesh or not.
7. double my_alpha = 1.4:
is a alpha shape parameter, that defines a geomertrical criterion for recognition of the free surfaces. Values between 1.4 and 1.7 are usually used. For details see "Alpha Shape Method"
8. double h_factor = 0.5:
if you decide to control the mesh quality, you shouldnt allow nodes to approach each other "too much". This "too much" is defined as the fraction of the original length of the elemental edge e. If you set the h_factor to 0.5 all the nodes that find themselves closer to the given one than 0.5*e will be removed
Brief description of the algorithm
Trigen PFEM refine performs the re-meshing in 3 major steps.
Step 1 consists in identification and erasing (in case the bool erase_nodes is activated as "True") of the nodes that come too close to each other. A binary tree search is performed in order to find all the nodes that lie within h_factor*e radius around the given node. e is approximately equal to the initial inter-nodal distance of the undeformed mesh, that is stored before the beginning of the simulation. The nodes that lie within this radius will be removed.
Step 2 consists in the free surface identification and removal of the distorted elements. This is done using the alpha-shape techniques. The radius of the circles containing three nodes of an element are compared with an average element size. The final domain boundary and the preliminary mesh of the domain interior is created at this step.
Step 3 consists in the refinement of the mesh generated at Step 2 in case bool add_nodes is activated as "True". If wants to perform the "user-defined" adaptive refinement, one has to pass the desired element size to the mesher. This is done by prescribing the corresponding NODAL_H (that is roughly the average of the height lengths of the elements in the patch around the given node). Then the mesher will intent to create an element whose volume will be as close as possible to the equidistant triangle of the volume 0.5*(1.5*prescribed_h*1.5*prescribed_h), where prescibed_h=0.333(NODAL_H1+NODAL_H2+NODAL_H3), NODAL_Hi being the NODAL_H of the elements' nodes.
How to use it
We shall now illustrate which steps need to be taken in order to use the Meshing Interface. This is done in the python script.
First of all you need to import Meshing application and the interface:
applications_interface.Import_MeshingApplication = True
from KratosMeshingApplication import *
Then you must create a mesher (we give an example of using the TriGenPFEMModeler):
Mesher = TriGenPFEMModeler()
To execute the ReMesh function, you need to
Mesher.ReGenerateMesh("TestElement2D", "Condition2D", model_part, node_erase_process, remove_nodes, add_nodes, alpha_shape, h_factor)
TestElement2D is the name of your element, you wish to regenerate (can be e.g. Fluid2D)
Condition2D is the name of condition in case it exists
node_erase_process: is a process that permits you to erase nodes in case FLAG remove_nodes is set to TRUE in this case you need to create it prior to passing to this function by doing "node_erase_process = NodeEraseProcess(model_part)
add_nodes is a flag that should be set to TRUE in case you want to perform adaptive refinement
alpha_shape is a parameter (usually around 1.5) for free-surface detection
h_factor is the coefficient that serves as a criterion for identification of excessively close nodes (ratio between permissible internodal distance A and the element size: h_factor=A/h) "
Common Usage Errors
A very common error is not setting the IS_FLUID flag to 1.0 for the nodes of the model part that you pass for re-meshing. Then all the elements will be deleted. Do (in python):
for node in model_part_for_remeshing.Nodes: node.SetSolutionStepValue(IS_FLUID, 0, 1.0)
to make sure it is set.
Another error results, when the element name you pass to ReGenerateMesh does not coincide with the one inside the original *.elem file of your model.
This error can even beat ERROR n1 as to the frequency that it occurs. When you are using the TrigenPFEMRefine in conjunction with some application (say IncompressibleFluidApplication), do not forget to add the MeshingApplication to the application interface.
applications_interface.Import_MeshingApplication = True
If you are assigning manually the desired element size (by prescribing NODAL_H), make sure that the bool add_nodes switch of the ReGenerateMesh function is set to True. Otherwise alpha shape will delete the elements and now new ones will be created.
- Description of the Validation Example
Validation example is provided inside: adaptive_mesher2d.gid folder. This example performs refinement and de-refinement in a sequence of circular areas withing a rectangular domain. The analytical solution of the DISPLACEMENT_X is initially prescribed to all existing nodes at the beginning. Then the mesher adds and removes nodes, and the difference between the prescribed value and the value that results when the new node is inserted (and therefore interpolation is performed) is checked. Once this difference exceeds the prescribed tolerance (10E-8), an error is thrown if you are running an example in the benchamarking mode.
Next we show the snapshots of refinement:
- File to be looked at to get an example of use