FSI: OpenFOAM with MBDyn

Hi, I’m new to preCICE.
I’m trying to reproduce the validation case’s results in the literature (using preCICE v1.5.2 & OpenFOAM v5.x & MBDyn v1.7.3).

Validation case in literature: flexible cantilever beam is attached to a rigid square columns in a current

part of precice-config.xml(displacment)

    <coupling-scheme:serial-implicit>
        <participants first="Fluid_Solver" second="Structure_Solver" />
        <max-time value="10" />
        <timestep-length value="0.001" />
        <exchange data="Force" from="Fluid_Solver" mesh="Structure_Nodes" to="Structure_Solver" />
        <exchange data="Displacement" from="Structure_Solver" mesh="Structure_Nodes" to="Fluid_Solver" />
        <max-iterations value="10"/>
        <relative-convergence-measure limit="1.0e-4" data="Displacement" mesh="Structure_Nodes" />
        <relative-convergence-measure limit="1.0e-4" data="Force" mesh="Structure_Nodes" />
        <extrapolation-order value="2" />

       <post-processing:IQN-IMVJ>
            <data name="Displacement" mesh="Structure_Nodes"/>
            <preconditioner type="residual-sum"/>
            <initial-relaxation value="0.1"/>
            <max-used-iterations value="1"/>
            <timesteps-reused value="1"/>
       </post-processing:IQN-IMVJ>
    </coupling-scheme:serial-implicit>
</solver-interface>

adapter for MBDyn writed base on existing code in github(MBDyn adapter for preCICE)

Here is adapter—displacment

while (self.interface.is_coupling_ongoing()):
        if (self.interface.is_action_required(precice.action_write_iteration_checkpoint())):
            self.interface.fulfilled_action(precice.action_write_iteration_checkpoint())

        if self.dim == 2:
            f = np.zeros((self.nnodes,3))
            f[:,:self.dim] = np.reshape(self.force,(-1,self.dim))
        else:
            f = np.reshape(self.force,(-1,3))
        self.mbd.setForces(f)
        if self.mbd.solve(False):
            break
        displacements = self.mbd.getDisplacements()
        self.interface.write_block_vector_data(self.displacementsID, self.nnodes, self.nodeVertexIDs, np.ravel(displacements))
        self.interface.advance(self.dt)
        self.interface.read_block_vector_data(self.forceID, self.nnodes, self.nodeVertexIDs, self.force)
        if (self.interface.is_action_required(precice.action_read_iteration_checkpoint())): # i.e. not yet converged
            self.interface.fulfilled_action(precice.action_read_iteration_checkpoint())
        else:
            previousDisplacements = displacements.copy()
	        t += self.dt
            if self.mbd.solve(True):
                break
    self.mbd.finalize()

The tip displacement get from preCICE watchpoint and .mov file(output from MBDyn):

adapter— DisplacementDelta

while (self.interface.is_coupling_ongoing()):
        if (self.interface.is_action_required(precice.action_write_iteration_checkpoint())):
            self.interface.fulfilled_action(precice.action_write_iteration_checkpoint())

        if self.dim == 2:
            f = np.zeros((self.nnodes,3))
            f[:,:self.dim] = np.reshape(self.force,(-1,self.dim))
        else:
            f = np.reshape(self.force,(-1,3))
        self.mbd.setForces(f)
        if self.mbd.solve(False):
            break
        displacements = self.mbd.getDisplacements()
        relDisplacements = displacements - previousDisplacements
        if self.dim == 2:
	        relDisplacements = relDisplacements[:,:self.dim]		
        self.interface.write_block_vector_data(self.displacementsID, self.nnodes, self.nodeVertexIDs, np.ravel(relDisplacements))
        self.interface.advance(self.dt)
        self.interface.read_block_vector_data(self.forceID, self.nnodes, self.nodeVertexIDs, self.force)
        if (self.interface.is_action_required(precice.action_read_iteration_checkpoint())): # i.e. not yet converged
            self.interface.fulfilled_action(precice.action_read_iteration_checkpoint())
        else:
            previousDisplacements = displacements.copy()
        	t += self.dt
            if self.mbd.solve(True):
                break
    self.mbd.finalize()

Tip displacement get from preCICE watchpoint and .mov file(output from MBDyn):

It seems something wrong when using DisplacementDelta(but the code in github used DisplacementDelta)

@Z0sK I am not sure how the MBDyn adapter performs, this is an adapter that not many people have used until now.

If I understand correctly, you have issues in both, as there is this background oscillation in the graph (the peaks should stay at the same level after a while).

I also see that in the case of DisplacementDeltas the preCICE-watchpoint is of much smaller magnitude than the .mov, but probably that one is the Displacement, not the delta.

What exactly is the problem you want to focus on?

Thanks for reply!!!
Sorry I didn’t state clearly.

I know current result is incorrect (also I don’t know why) , and I am not sure if what I understand is correct.(:frowning_face:):
There are two modes of displacement transmission in openfoam adapter.
Mode — Displacment: The difference between the position of the node at a certain moment and the initial position

Assuming the position of a node in the structure solver is x at time t, and initial position is x0 (t = 0) ,so:
displacement = x - x0

Mode — DisplacmentDelta: The difference between the position of the node at a certain moment and the position of the previous time step

Assuming the position of a node in the structure solver is xt at time t, and position of previous time step is xt-dt (t = 0) ,so:
displacementDelta = xt - xt-dt

I want to know if I understand correctly firstly :sob:

Yes, sounds correct.

1 Like

Improtant here is to remember that the two participants can also subcycle: one participant can do multiple time steps in each coupling time window. In that case, the delta should refer to the previous coupling time window and applied only once per time window.

Checkpointing is also important when subcycling: checkpoints always need to be stored once per time window.

To be safe, it is helpful to start with solver time steps equal to the coupling time window.

Thanks a lot ! :wink:

OK,I got it. Now,I have ideas to deal the incorrect results, and I will continue to update under this post if I encounter new problems or new progress, so that you can improve the adapter for MBDyn

1 Like