FEniCS-preCICE: implicit coupling with multiple fields in checkpoint

Hi,

I am trying to run a FSI simulation using FEniCS for the solid participant. My code is inspired from the perpendicular flap tutorial (Perpendicular flap | preCICE - The Coupling Library). In this example, only one field (u_n) has to be stored in checkpoints (precice.store_checkpoint(u_n, t, n) and u_cp, t_cp, n_cp = precice.retrieve_checkpoint()).

I my simulation, I need to store 3 fields. I followed this issue: https://github.com/precice/tutorials/issues/50 by using tuples:

state = (u_old, sig_old, p)
precice.store_checkpoint(state, t, n)

However, I have the following error:

my_u = user_u.copy()
AttributeError: 'tuple' object has no attribute 'copy'

This commit https://github.com/precice/fenics-adapter/commit/61c8e2a613f47d79d03eb786f7446f691d9da2bb mentions a fix in the adapter to take into account the use of tuples in solver state, in order to have multiple fields in solver state.

In which preCICE version this fix is available? I am using preCICE v2.5.0.

Thank you for your help :wink:

Hi @lucas_menez,

The issue / feature request that you are mentioning is unfortunately still open. At the moment you can only store a single field in the adapter. I currently do not have the time to dig deep into the implementation of the fenics-adapter and develop this feature thoroughly (including tests etc.), but you could try to start from the error that you have shown above and implement the feature on your own (A pull request would be highly appreciated! I can also help here.). The problematic line is actually this one: fenics-adapter/fenicsprecice/fenicsprecice.py at 6c8d7be8153b8bc2c573a23985dfd3836dd1a8fb · precice/fenics-adapter · GitHub. But there are some more places that have to be changed down the road. But it should not be too hard.

Another possibility: You can also just implement your own checkpointing (independent from the adapter) in your solver instead of using precice.store_checkpoing and precice.retreive_checkpoint. In the end you just need a place where you can be sure that state = (u_old, sig_old, p) is safe. At the moment the adapter offers this for you - but only for a single field.

Be careful: FEniCS sometimes updates variables in a pointer-like fashion. This was the main motivation to provide the store_checkpoint and retreive_checkpoint functions: That the user does not have to worry about these technicalities. It’s not too complicated (compared to FEM it’s pretty much a no-brainer), but these issues are sometimes hard to debug and annoying. Inside of store_checkpoint I, therefore, explicitly create a copy (user_u.copy()) to make sure FEniCS cannot mess around with the checkpointed values.

Note on preCICE v2.5.0: The fenics-adapter is not maintained anymore for preCICE v2. Is it possible for you to upgrade to preCICE v3?

Greetings,
Benjamin

1 Like

Thank you very much for your quick answer!

I think I’ll go for the second option since I’m almost at the end of my PhD.

Unfortunately I also no longer have the time to update my code for the new release of preCICE v3, mainly for the in-house fluid solver where I had to develop my own adapter. But I’m going to talk about it in my research team for future work.

Thank you again for your help!

Lucas

No problem and I totally understand. I’m also getting close to the PhD finish line and don’t want to open new boxes :smirk:

For option two: If you prototype the approach in one of our tutorials (e.g. tutorials/perpendicular-flap/solid-fenics/solid.py at master · precice/tutorials · GitHub), you could push this to a branch. This has some advantages

  1. we can help you, if needed
  2. we can use this as a template, when it comes to the real implementation,
  3. other users can also use this as a template.

In tutorials/perpendicular-flap/solid-fenics/solid.py the following (which is somehow close to what you need) would break:

precice.store_checkpoint((u_n, u_n) t, n)

Doing this :

precice.store_checkpoint((u_n, u_n) t, n)

requires to modify the adapter to take into account tuples, right?

For option two, I need to call markActionFulfilled. I can find this part in the fenicsx adapter (e.g. self._interface.mark_action_fulfilled(self.action_write_iteration_checkpoint())) or dealii adapter (e.g. precice.markActionFulfilled(precice::constants::actionWriteIterationCheckpoint());) for example, but not in the fenics adapter (just after self._checkpoint = SolverState(my_u, t, n)). How this action is managed in the fenics adapter?

Hi,

that’s one of the preCICE v2 / v3 breaking changes: We removed markActionFulfilled in preCICE v3. Meaning: If you are using v2, just follow the approach from the fenicsxadapter (which has not been updated to v3 yet). Do the following:

if precice.is_action.required(precice.action_write_iteration_checkpoint()):
    # do your own checkpointing
    precice.mark_action_fulfilled(precice.action_write_iteration_checkpoint())

(I hope the syntax is fine. I’ve become a bit rusty with preCICE v2, but the python bindings help(...) and documentation should get you on the right path)

See our porting guide. It should also help you backporting from v3 examples to v2. Not the way we intended it to be used, but if it is useful for you I’m happy :smirk:

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.