How to use the projection between no matching meshes
The mapping algorithm
The necessity to work with different meshes lead us to the definition of a projection algorithm.
The operation of passing information between non matching meshes needs two different ingredients:
- A searching algorithm to identify the neighbor nodes of a given element; - A mapping function that pass the information from an element to a point contained in the same;
The actual neighbor search algorithm used for the mapping is a kd tree data structure.
The transmission of data between non matching meshes is performed by the direct interpolation between the nodal values of the origin and the destination mesh. Given an origin_model_part and a destination_model_part, for each node of the destination mesh, we find out in which element of the origin mesh it is contained. Once the element is identified, a simple finite element interpolation with the shape functions of the element of the origin_model_part is performed. Finally the value of the variable in the new point is given.
Defining two GiD models
The first step to use the projection algorithm is to have two non matching meshes. Two models have to be constructed separately in GiD. The old problem type format has to be used. All the files of one model have to be copied inside the other model. Every time we perform a projection we will refer to the two models with the adjective origin or destination in order to differentiate them. For instance we suppose to have two models origin.gid and destination.gid. We calculate both inside GiD and then copy the files contained inside destination.gid, to the origin.gid folder.
The structure of the python file
The mapping algorithm is included in the MeshingApplication that we have to insert in order to use it:
#importing applications import applications_interface ... applications_interface.Import_MeshingApplication = True applications_interface.ImportApplications(kernel, kratos_applications_path)
from KratosIncompressibleFluidApplication import * from KratosMeshingApplication import * meshing_application = KratosR1MeshingApplication() kernel.AddApplication(meshing_application)
#loading meshing application kernel.InitializeApplication(meshing_application);
Defining two ModelParts
We have say kratos to creaate two model parts by typing:
#defining the two model part: origin_model_part and destination_model_part origin_model_part = ModelPart("OriginFluidPart"); destination_model_part = ModelPart("DestinationFluidPart");
Reading data from multiple files
We have now to read the files of both origin.gid and destination.gid models (all inside origin.gid)
#reading the origin model part gid_io = GidIO("origin",gid_mode_flag, use_multifile, deformed_print_flag, write_conditions ) gid_io.ReadModelPart(origin_model_part) print origin_model_part print "origin model read correctly"
#reading the destination model part data_io = DatafileIO("destination") data_io.ReadModelPart(destination_model_part) print destination_model_part print "destination model read correctly"
Creating a MeshTransfer object
Before the initialization of the solver we have to create an object of the class MeshTransfer that is the class of the projection algorithm.
origin_solver = ... destination_solver = ... AAA = MeshTransfer()
Calling the projection function
Two are the possible interpolations.
Interpolation of the whole model part
for step in range(0,nsteps): if(step > 3): origin_solver.Solve(..) AAA.DirectModelPartInterpolation(origin_model_part,destination_model_part); destination_solver.Solve(...)
This is a very expensive procedure implying the interpolation of the whole model part.
Interpolation of one or more variables
This second interpolation is recommended if only the values of some variables are needed.
for step in range(0,nsteps): if(step > 3): origin_solver.Solve(..) AAA.DirectVariableModelPartInterpolation(origin_model_part,destination_model_part, VARIABLE); destination_solver.Solve(...)
Writing results in multiple files
A change in the output file names has to be performed in order to differentiate the two models. The function 'ChangeOutputName of the GiDIO has to be used.
##a change in the output name is needed!!!! res_name1 = str("Origin_Mesh") res_name2 = str("Destination_Mesh") gid_io.ChangeOutputName(res_name1) gid_io.InitializeMesh( Time ); gid_io.WriteMesh(origin_model_part.GetMesh() ) gid_io.FinalizeMesh(); gid_io.InitializeResults( Time, origin_model_part.GetMesh() ) gid_io.WriteNodalResults(VELOCITY,origin_model_part.Nodes,Time,0) gid_io.WriteNodalResults(PRESSURE,origin_model_part.Nodes,Time,0) ... gid_io.Flush() gid_io.FinalizeResults()
gid_io.ChangeOutputName(res_name2) gid_io.InitializeMesh( Time ); gid_io.WriteMesh(destination_model_part.GetMesh() ) gid_io.FinalizeMesh(); gid_io.InitializeResults( Time, destination_model_part.GetMesh() ) gid_io.WriteNodalResults(VELOCITY,destination_model_part.Nodes,Time,0) gid_io.WriteNodalResults(PRESSURE,destination_model_part.Nodes,Time,0) ... gid_io.FinalizeResults()
In case of using an application with a pre-formatted output mode, pfem application for instance, no initialization of the results is needed:
res_name1 = str("Mesh_fixed") res_name2 = str("Mesh_pfem") gid_io.ChangeOutputName(res_name1) gid_io.InitializeMesh( Time ); gid_io.WriteMesh(origin_model_part.GetMesh() ) gid_io.FinalizeMesh(); gid_io.InitializeResults( Time, origin_model_part.GetMesh() ) gid_io.WriteNodalResults(VELOCITY,origin_model_part.Nodes,Time,0) gid_io.WriteNodalResults(PRESSURE,origin_model_part.Nodes,Time,0) gid_io.ChangeOutputName(res_name2) gid_io.Flush() gid_io.FinalizeResults()
The present algorithm work for 2D and 3D problems but not for spatial 2D problems.
For any problem please contact Antonia Larese (Who are we).
See Moving_Sphere.gid (ProjectionTest_3D_benchmarking.py) and Moving_Circle.gid (ProjectionTest_2D_benchmarking.py)(test examples of the MeshingApplication ~/kratos/application/MeshingApplication/test_exemples/) for a 3d and 2d example respectively.