Using participants without mesh, on multi participant configuration

Hi Im creating a custom “solver” its not really a solver, that I want to use it something like man in the middle between FSI model. The Idea is for example, introduce reactive conditions to the model tha are not computed from any of the participants in the FSI configuration but they results are influeced by this forces For example simulate a emergency stop condition, or model the reaction torque of a drive train in a rotatory machine. At this point I have crated a dummy solver just to take the forces from the Fluid domain and write them to the Solid domain, like a proxy.

My custom solver looks like this, I dont know if it will work, I’m starting now, but basically at this point is to map the forces from Fluid to Solid without doing nothing, the computations with that forces will come later:



import numpy as np
import precice
from precice import (
    action_read_iteration_checkpoint,
    action_write_iteration_checkpoint,
)

configuration_file_name = "../precice-config.xml"


# ----------------- #
#  solver settings  #
# ----------------- #

participant_name = "Reactive"
mesh_in = "Fluid-Mesh"
mesh_out = "Solid-Mesh"
# ---------------------

print("Configure preCICE...")
solver_process_index = 0
solver_process_size = 1
interface = precice.Interface(
    participant_name,
    configuration_file_name,
    solver_process_index,
    solver_process_size,
)
dimensions = interface.get_dimensions()
mesh_in_id = interface.get_mesh_id(mesh_in)
mesh_out_id = interface.get_mesh_id(mesh_out)
print("preCICE configured...")

forces_in_id = interface.get_data_id("Force", mesh_in_id)
forces_out_id = interface.get_data_id("Force", mesh_out_id)

precice_dt = interface.initialize()
interface.initialize_data()
vertex_in_ids, grid_in = interface.get_mesh_vertices_and_ids(mesh_in_id)
vertex_out_ids, grid_out = interface.get_mesh_vertices_and_ids(mesh_out_id)

forces = interface.read_block_vector_data(forces_in_id, vertex_in_ids)

while interface.is_coupling_ongoing():
    if interface.is_action_required(precice.action_write_iteration_checkpoint()):
        interface.mark_action_fulfilled(precice.action_write_iteration_checkpoint())

    if interface.is_read_data_available():
        forces = interface.read_block_vector_data(forces_in_id, vertex_in_ids)

    if interface.is_write_data_required(precice_dt):
        interface.write_block_vector_data(forces_out_id, vertex_out_ids, forces)

    precice_dt = interface.advance(precice_dt)

    if interface.is_action_required(precice.action_read_iteration_checkpoint()):
        interface.mark_action_fulfilled(precice.action_read_iteration_checkpoint())

print("Exiting SolidSolver")

interface.finalize()

And my precice-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<precice-configuration>
  <log>
    <sink type="stream" output="stdout"  filter= "(%Severity% > debug) or (%Severity% >= trace and %Module% contains SolverInterfaceImpl)"  enabled="true" />   
  </log>

  <solver-interface dimensions="3" experimental="true">
    <data:vector name="Force" />
    <data:vector name="Displacement" />

    <mesh name="Fluid-Mesh">
      <use-data name="Force" />
      <use-data name="Displacement" />
    </mesh>

    <mesh name="Solid-Mesh">
      <use-data name="Force" />
      <use-data name="Displacement" />
    </mesh>

    <participant name="Fluid">
      <use-mesh name="Fluid-Mesh" provide="yes" />
      <use-mesh name="Solid-Mesh" from="Solid" />

      <read-data name="Displacement" mesh="Fluid-Mesh" />
      <write-data name="Force" mesh="Fluid-Mesh" />
    </participant>
    
    <participant name="Reactive">
      <use-mesh name="Fluid-Mesh" from="Fluid" />
      <use-mesh name="Solid-Mesh" from="Solid" />

      <read-data name="Force" mesh="Fluid-Mesh" />
      <write-data name="Force" mesh="Solid-Mesh" />
    </participant>

    <participant name="Solid">
      <use-mesh name="Solid-Mesh" provide="yes" />
      <use-mesh name="Fluid-Mesh" from="Reactive" />
      <write-data name="Displacement" mesh="Solid-Mesh" />
      <read-data name="Force" mesh="Solid-Mesh" />
    </participant>

    <m2n:sockets from="Fluid" to="Reactive" exchange-directory=".." />
    <m2n:sockets from="Reactive" to="Solid" exchange-directory=".." />
    <m2n:sockets from="Solid" to="Fluid" exchange-directory=".." />

    <coupling-scheme:multi>
      <time-window-size value="0.01" />
      <max-time value="3" />
      <max-iterations value="10" />

      <participant name="Fluid" control="yes" />
      <participant name="Reactive" />
      <participant name="Solid" />

      <exchange data="Force" mesh="Fluid-Mesh" from="Fluid" to="Reactive" />
      <exchange data="Force" mesh="Fluid-Mesh" from="Reactive" to="Solid" />
      <exchange data="Displacement" mesh="Fluid-Mesh" from="Solid" to="Fluid" />
      <relative-convergence-measure limit="5e-3" data="Displacement" mesh="Fluid-Mesh" />
    </coupling-scheme:multi>
  </solver-interface>
</precice-configuration>

I’m using the perpendicular-flap example to test, so the Solid, and Fluid participants are OpenFoam, and CalculiX. I’m sure that there are a lot of wrong things here, but this is my first time writing a precice confing and also a solver.

But as you can see, my solver don’t provide a mesh, I’t will only do forces manipulation to the forces computed to the fluid domain before the Solid computations. So first of all, I thinks this is a case for serial computation. But I’m really lost here on how to proceed with this

Hi,

If I understand correctly, your solver-in-the-middle “Reactive” maps between the Fluid mesh to the Solid mesh and does some fancy things there.

First, make “Reactive” the controller as it is the central participant in this instance. This allows you to run the other solvers using MPI for bigger cases.
Example: Multiple perpendicular flaps | preCICE - The Coupling Library

Second, add the missing parts of the direct mesh access. I recommend reading the following documentation (v3 changed API names and arguments, but not how the method works):

I am unsure if data initialization will work in your case.

Best
Frédéric

Thanks for your answer I take a look to this info and give a feedback in the feature