Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapter precice 3.1 with 3D support and "point load" #26

Open
wants to merge 29 commits into
base: develop
Choose a base branch
from

Conversation

efirvida
Copy link

@efirvida efirvida commented Jul 16, 2024

Sorry If I dont follow the source style here, my point was to quick develop a solution when it works, we can do it well. This also can keep the code more clean, to discuss over it. Also I have to say that I'm learing preCICE and FenicsX at the same time, so maybe the solution here will be simple and I can't notice it.

I post a first version of the adapter on the preCICE Disource because at that point I have where I call a scaling problem in the flap tutorial, having similar results but with 1 to100 diference in the result.

Then I create a simple static beam problem comparing the results of CaluliX and FenicsX and here I notice the problem, I was integrating the load over the surface, instead of on a DoF as Calculix does, which was confirmed by BenjaminRodenberg in the discourse. This is the example that I put on the test folder. So I update my the flap tutorial based on the lessons learned here.

This also guided by this other thread on FeniscX forum, about mapping the loads over DoFs. But I still having problems validting the flap tutorial. Considering that the FenicsX dos'nt have a PointSource as the legacy version, I use another approach of modifiying directly the vector value as:

LOAD_POINT = (4.9490529e-02, -1.4846031e-01, 1.5000000e02)
LOAD = np.array([10.0, 0, 0])

def point(x):
    return (
        np.isclose(x[0], LOAD_POINT[0])
        & np.isclose(x[1], LOAD_POINT[1])
        & np.isclose(x[2], LOAD_POINT[2])
    )

# https://bleyerj.github.io/comet-fenicsx/tours/dynamics/elastodynamics_newmark/elastodynamics_newmark.html
point_dof = fem.locate_dofs_geometrical(V, point)[0]
point_dofs = np.arange(point_dof * dim, (point_dof + 1) * dim)

b_func = fem.Function(V)
b_func.x.array[:] = 0
b = b_func.vector
with b.localForm() as b_local:
    b_local.set(0)

for i, j in enumerate(point_dofs.tolist()):
    b[j] = LOAD[i]
b.assemble()

Which works for a single point, but I'm missing somthing here, and I dont know if is on the preCICE side or in the implementation of the flap tutorial. Rigth now I can confirm that the adapter can handle 2D and 3D problems, but without good results.

  1. https://fenicsproject.discourse.group/t/improve-mapping-data-on-a-function-by-coordinates/14911/9
  2. https://precice.discourse.group/t/fsi-with-fenicsx-and-precice-3/1966

@precice-bot
Copy link

This pull request has been mentioned on preCICE Forum on Discourse. There might be relevant details there:

https://precice.discourse.group/t/fsi-with-fenicsx-and-precice-3/1966/3

@efirvida
Copy link
Author

I finally made it work, at least the perpendicular flap tutorial, To do it I added a LinearDiscreteProblem that puts the load directly on the DoFs and also maintains the code clean.

flap-x-displacement-tip

I added two more examples the turek-heron, and a turbine-tower, right now I'm running them to see what happens. I'm having problems by running the turbine-tower in parallel from the OpenFOAM side, but I don't know how to diagnose what happen

@precice-bot
Copy link

This pull request has been mentioned on preCICE Forum on Discourse. There might be relevant details there:

https://precice.discourse.group/t/openfoam-crash-running-in-parallel-with-my-custon-dolfinx-adapter/2043/1

@efirvida efirvida changed the title Adapter precice 3.1 with 3D suppoint and "point load" Adapter precice 3.1 with 3D support and "point load" Jul 30, 2024
Copy link
Member

@IshaanDesai IshaanDesai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution and apologies for the delay in reviewing. Even if the total number of new files is large, as a first step I looked at the adapter files, so the folder fenicsxprecice. I see that you have broadly stuck to the existing adapter class structure, by having a Config class, an Adapter class, and a class to manage the state for checkpointing. To me it seems like this could have potentially been accommodated in the existing adapter structure. What was the reason to completely discard the existing adapter and write a new one?

Contents of the file fenicsxprecice/solvers.py is related to the numerical solvers. Such code typically goes in the application files, as it is not directly related to coupling.

Apart from the adapter files, there are a lot of files related to different simulation setups. Ideally such simulation setups are added to the precice/tutorials repository, rather than the adapter repository. Once we start to converge on the adapter contribution, we can move the case files to the tutorials repository.

@efirvida
Copy link
Author

efirvida commented Aug 5, 2024

@IshaanDesai thanks for your quick review. Yes, I use the original adapter structure, because first I tried to use the original on my FSI by doing the small modifications. As I'm new on preCICE and DOLFINx, I began to modify the code in place to do some reverse engineering, until I reached good results, and I removed a lot of code that I didn't understand to keep my version as clean as possible with the minimum needs to perform an FSI, as you can see the API on this version is a lot simpler than the original.

I know that I put a lot of tutorials that do not belong here, as de solver.py, but I think it is easier to have all things together in one place to test/review before moving/merge and put all in the right place. But OK I did some cleaning

The main part of the Adapter are the methods:

interpolation_points_in_vector_space
interface_dof

the first return the DOFs and coordinates of the interface. and then is easy to use the interface_dof to read and write data from the evaluated Function. I tried to add another tutorial on heat transfer but I've not time to do it to see if this approach also works for this kind of solution. Also, the Turek-FSI isn't working well I think because this is a nonlinear problem and I use a linear solver.

@precice-bot
Copy link

This pull request has been mentioned on preCICE Forum on Discourse. There might be relevant details there:

https://precice.discourse.group/t/how-mesh-coupling-works-for-parallel-participants/2059/1

@IshaanDesai
Copy link
Member

Yes, I use the original adapter structure, because first I tried to use the original on my FSI by doing the small modifications. As I'm new on preCICE and DOLFINx, I began to modify the code in place to do some reverse engineering, until I reached good results, and I removed a lot of code that I didn't understand to keep my version as clean as possible with the minimum needs to perform an FSI, as you can see the API on this version is a lot simpler than the original.

I understand how your reached the state you have, and that it serves the purpose of doing FSI simulations. But the original structure is intended to be for generic use and was also designed rigorously for legacy FEniCS. I am tending towards keeping the old structure and accommodating your improvements in it. Did you encounter any fundamental design problems while trying to incorporate your implementation in the current adapter? If yes, we can improve the design.

I know that I put a lot of tutorials that do not belong here, as de solver.py, but I think it is easier to have all things together in one place to test/review before moving/merge and put all in the right place. But OK I did some cleaning

This is perfectly fine for now, but just something to do at the end, just before merging.

I tried to add another tutorial on heat transfer but I've not time to do it to see if this approach also works for this kind of solution.

This would be very interesting to know. If this can be done, we could potentially just move to the new design.

Also, the Turek-FSI isn't working well I think because this is a nonlinear problem and I use a linear solver.

This is a known problem.

I would suggest the following next steps:

  1. I can help you to try to incorporate your implementation into the current adapter design. This way we can keep the design but you can also do FSI simulations.
  2. Move your simulation setups to the tutorials repository one by one.
  3. If possible, add some tests for the new functionality.

What do you think? I will, of course, assist to a large degree here.

@efirvida
Copy link
Author

efirvida commented Aug 8, 2024

I can try to adapt my implementation into the current adapter, but for this, I would need your help, I don't remember the problems in the main implementation.

I think that the main cut-off is on the initialize method where I believe the write_object is not needed here, or at least I didn't understand its function. Maybe due to the simple implementation of the read/write data methods, that I put the data directly on the Function.

And the same for the create/update_coupling_expression that I think we don't need here, at least for FSI.

Right now this version has a problem working in parallel, and I'm working on it right now, the I could try to start mergin with the current implementation. Notice that the current implementation also is for preCICE < 3, and this implementation not, so here some method changes its names and parameters.

@IshaanDesai
Copy link
Member

I can try to adapt my implementation into the current adapter, but for this, I would need your help, I don't remember the problems in the main implementation.

I can and will definitely help here.

I see that you extract the data from the function directly at the time of reading and writing. I will check how this would work with the original implementation.

Handling FEniCS Expressions was part of the original design because many times Expressions were used on the user-side. We can rethink this now.

Right now this version has a problem working in parallel, and I'm working on it right now, the I could try to start mergin with the current implementation.

I saw the Discourse post about the issue with parallel runs. Let me try to answer there, so as to not clutter this pull request too much. Thanks for agreeing to merging with the current implementation 😄 I know it feels like taking a step backwards, but in the long run we would benefit from the original design decisions.

Notice that the current implementation also is for preCICE < 3, and this implementation not, so here some method changes its names and parameters.

Thanks for pointing this out 👍

I'm cleaning the branch here to provide only de adapter aligned with the
current version class architecture.

Notice that the API have some changes due to the preCICE version, here
I'm supporting only the preCICEv3.

Tutorials and other things where moved to main branch.
as example on how to use this version of the adapter
@efirvida
Copy link
Author

efirvida commented Aug 9, 2024

I accidentally overwrote my last commit, but I believe it's not a significant issue. I modified the adapter using the current class reference to simplify the merging process.

In the current implementation, the read and write methods are much simpler because preCICE v3 does not differentiate between vectors and scalars, using the same function for both. I also removed some checks that I didn't fully understand, and I'm not certain if they were necessary.

        assert (self._coupling_type is CouplingMode.UNI_DIRECTIONAL_READ_COUPLING or
                CouplingMode.BI_DIRECTIONAL_COUPLING) 

As I mention in my last post, I'm porting the adapter to preCICEv3 so some methods change, now we have:

  • requires_initial_data instead of is_action_required
  • requires_reading_checkpoint instead of action_read_iteration_checkpoint
  • requires_writing_checkpoint instead of action_write_iteration_checkpoint

I also added some new properties:

  • dt: This property captures the participant's time step (dt), so it's no longer necessary to specify it separately in our problem setup.
  • interface_dof: This is the most important property, enabling us to read and write interface data. You can think of it as analogous to the PointSource in the legacy FEniCS version.
  • interface_coordinates: This property is mainly for debugging purposes. It allows us to visualize the interface interpolation points by saving them as a CSV file, which can then be plotted.

So the API change a little bit due to this new properties, and the change of the preCICE version.

Also in the initialize method I left the write_object param just to maintain compatibility, but my current implementation don't need it. And also I remove all the check on this methods because I didn't understand, and I'm not sure if they were necessary.

FinallyI include the flap tutorial again with this modification, jus to show how we can use it.

@efirvida
Copy link
Author

efirvida commented Aug 9, 2024

Also I manage to add a working heat transfer tutorial, in this commit of my main branch (which is not aligned right now with this last version). The tutorial runs until the end and change data between participants, but as I'm not an expert in heat transfer I'm sure that there are things wrong there on the FEniCSx side implementation, but it's a starting point

@IshaanDesai IshaanDesai removed the request for review from BenjaminRodenberg August 16, 2024 08:33
@IshaanDesai IshaanDesai added the breaking change A change will break backwards compatibilty label Aug 16, 2024
Copy link
Member

@IshaanDesai IshaanDesai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for refactoring your adapter design into the old design. I see now that most things in the old design are rendered unnecessary. The write function in the initialization can be removed as it no longer serves a purpose. I have some last suggestions, which I have written as comments. Once these are incorporated, we can finalize this pull request. Before merging, we should move the simulation setups to the tutorials repository. I can quickly port these once testing is done.

LICENSE Outdated
Library.
Library.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets not change the license file. Can you please keep the original file?

.gitattributes Outdated
@@ -1 +1 @@
fenicsxprecice/_version.py export-subst
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the license file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep the build and test CI, hence we need this file, and the Action to pass.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to keep this CI.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as other CI related files. Let us keep this file to keep the check.


def initialize(self, coupling_subdomain, read_function_space=None, write_object=None):
"""
Initializes the coupling and sets up the mesh where coupling happens in preCICE.
"""Initializes the coupling and sets up the mesh where coupling happens in preCICE.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Initializes the coupling and sets up the mesh where coupling happens in preCICE.
"""
Initializes the coupling and sets up the mesh where coupling happens in preCICE.

coupling_subdomain : Object of class dolfinx.cpp.mesh.SubDomain
SubDomain of mesh which is the physical coupling boundary.
read_function_space : Object of class dolfinx.functions.functionspace.FunctionSpace
coupling_subdomain : List
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
coupling_subdomain : List
coupling_subdomain : list

return self.dt

def store_checkpoint(self, states: List):
"""Defines an object of class SolverState which stores the current states of the variable and the time stamp."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Defines an object of class SolverState which stores the current states of the variable and the time stamp."""
"""
Defines an object of class SolverState which stores the current states of the variable and the time stamp.
"""


def retrieve_checkpoint(self):
"""
Resets the FEniCSx participant state to the state of the stored checkpoint.
"""Resets the FEniCSx participant state to the state of the stored checkpoint.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"""Resets the FEniCSx participant state to the state of the stored checkpoint.
"""
Resets the FEniCSx participant state to the state of the stored checkpoint.

tests/README.md Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets try to preserve the testing infrastructure as much as possible. I understand that tests related to old functionality are no longer relevant, but modifying existing tests to test the new functionality would be really helpful in catching potential bugs.

Copy link
Member

@BenjaminRodenberg BenjaminRodenberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for all the work and the updates! I don't want to interfere too much here. Just two small comments on versioneer-related files. I would try to not mix these changes into the PR because it's not really related.

For some background: We are using versioneer in this repository to synchronize git-tags and the version numbers used in the setup.py respectively returned by fenicsxadapter.__version__.

versioneer.py Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert the changes in this file? I think no changes should be necessary here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is generated by versioneer. Please revert the changes.

Revert changes on code style and formatting to make
precice#26 easier to review.
@BenjaminRodenberg
Copy link
Member

BenjaminRodenberg commented Nov 26, 2024

To make this PR a bit easier to review and manage I reverted some changes in fc02757. This should reduce the diff to some degree. @efirvida: If this interferes with your work, feel free to simply revert that commit (git revert fc02757). We can also use a different branch than develop to continue working on this PR.

I think we should generally try to factor some things out from this PR. Otherwise it is just too big. Some points that are part of this PR which we could factor out are minor changes like adding braces around asserts and some documentation updates. We should also try to fix the testing here in this PR in order to make sure we do not break anything. Additionally, this would also reduce the diff (currently there are many deletions due to the removal of the testing).

@steffenger
Copy link

https://github.com/efirvida/fenicsx-adapter/blob/develop/fenicsxprecice/fenicsxprecice.py#L84 This version of the adapter only supports surface coupling now, right? It think it should be possible to make it more general with an additional argument in the initialization of the adapter.
best regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change A change will break backwards compatibilty
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants