How to transfer nodal values between non-matching meshes
In fluid-structure interaction problems we need to transfer data between the fluid and structure sides of the interface. This can be problematic when the meshes don't match, which is the case when different mesh sizes or element types are used on each side. Kratos' FSI application includes the AdvancedNMPointsMapper utility to solve this problem, and this document outlines its use.
The first step is to ensure that both the fluid and structure sides of the interface are defined properly. There are two requisites:
- Both sides of the interface occupy the same position in space. From a practical point of view, this means that the relevant surfaces have the same coordinates in the structure and fluid model files.
- The nodes on both sides have to be identified with the IS_INTERFACE flag (with a value of 1.0).
The Python script file
Obviously, the mapper requires importing the Kratos FSI application:
... applications_interface.Import_FSIApplication = True ... applications_interface.ImportApplications(kernel, kratos_applications_path) ...
Once this is done, import the NonConformant_OneSideMap module:
And add the variables it uses to the structure and fluid model parts:
Now you can create a mapper object, which will identify the interfaces and match the conditions on both sides so the information can be transferred:
mapper = NonConformant_OneSideMap.NonConformant_OneSideMap(fluid_model_part,structure_model_part)
This mapper can be passed to the coupled solver, which will use it to update the values on one side based on the results obtained on the other:
coupled_solver = FractionalStepCouplingAitken.FractionalStepCoupling(fluid_model_part,structure_model_part,\ structure_solver,mesh_solver_ballvertex,mapper,domain_size)
If you need to explicitly perform mapping operations in your Python file, there are four different functions: two for each direction of transfer (fluid to structure or structure to fluid). One of them is used for scalar quantities and the other for vector variables. Example calls for each method are provided in the following box:
mapper.StructureToFluid_ScalarMap(POSITIVE_FACE_PRESSURE,PRESSURE) mapper.StructureToFluid_VectorMap(VELOCITY,VELOCITY) mapper.FluidToStructure_ScalarMap(PRESSURE,POSITIVE_FACE_PRESSURE) mapper.FluidToStructure_VectorMap(VELOCITY,VELOCITY)
Where the arguments are the names of the relevant variables in the origin and destination model parts, respectively.
When creating a mapper object, you have the possibility of specifying three additional parameters:
Search radius factor
While searching for candidate conditions to use as a reference for each given Gauss point in the destination mesh, the mapper will attempt to find Gauss points in a sphere centered on the condition's center of mass. A search radius factor of 1.0 means that that this sphere will be just big enough to contain the condition.
A bigger search radius factor means that more candidates will be considered while looking for a match for a given condition, which will slow down the mapping process, but it can be necessary to properly map all points in complex geometries. The default value is 2.0.
Maximum number of iterations
The maximum amount of iterations that will be done to solve the system involved in a given variable transfer. The default value is 3.
The relative tolerance for the convergence check done after each iteration. 1e-3 by default.
Some example calls to the mapper constructor are provided next:
mapper = NonConformant_OneSideMap.NonConformant_OneSideMap(fluid_model_part,structure_model_part) # Use default values mapper = NonConformant_OneSideMap.NonConformant_OneSideMap(fluid_model_part,structure_model_part,1.0,15,1e-4) # radius factor = 1.0, 15 iterations, tol = 1e-4 mapper = NonConformant_OneSideMap.NonConformant_OneSideMap(fluid_model_part,structure_model_part,search_radius_factor=1.0) # radius factor = 1.0 mapper = NonConformant_OneSideMap.NonConformant_OneSideMap(fluid_model_part,structure_model_part,it_max=10,tol=1e-2) # 10 iterations, tolerance 0.01