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

Implement VectorTools::interpolate_to_finer/coarser_mesh(). #16734

Merged
merged 3 commits into from Mar 9, 2024

Conversation

bangerth
Copy link
Member

@bangerth bangerth commented Mar 8, 2024

I mentioned this on the elements forum: I'm in need of a function that can interpolate between coarse and fine DoFHandler objects not only on a single process, but indeed in parallel where the partitioning of the two meshes may not geometrically match. This is difficult to implement, but as @kronbichler and @peterrum mentioned, they have already provided this kind of functionality in the form of the MGTwoLevelTransfer class :-)

This patch makes use of this to implement the functions needed. The majority of the code in fact is due to the limitation that MGTwoLevelTransfer can only deal with parallel::distributed::Vector objects (see #16684). I decided that I was more interested in getting something to work for now than to make it super efficient, and so I just go with this limitation and copy data back and forth between the user-side vector types and the internally required parallel::distributed::Vector objects.

Copy link
Member

@kronbichler kronbichler left a comment

Choose a reason for hiding this comment

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

I think this looks good, apart from some small comments.

I have an additional question: I think we can also address some of

* Compute the interpolation of a the @p dof1-function @p u1 to a @p
* dof2-function @p u2. @p dof1 and @p dof2 need to be DoFHandlers based on
* the same triangulation.
*
* If the elements @p fe1 and @p fe2 are either both continuous or both
* discontinuous then this interpolation is the usual point interpolation.
* The same is true if @p fe1 is a continuous and @p fe2 is a discontinuous
* finite element. For the case that @p fe1 is a discontinuous and @p fe2 is
* a continuous finite element there is no point interpolation defined at
* the discontinuities. Therefore the mean value is taken at the DoF values
* on the discontinuities.
*
* Note that for continuous elements on grids with hanging nodes (i.e.
* locally refined grids) this function does not give the expected output.
* Indeed, the resulting output vector does not necessarily respect
* continuity requirements at hanging nodes: if, for example, you are
* interpolating a Q2 field to a Q1 field, then at hanging nodes the output
* field will have the function value of the input field, which however is
* not usually the mean value of the two adjacent nodes. It is thus not part
* of the Q1 function space on the whole triangulation, although it is of
* course Q1 on each cell.
*
* For this case (continuous elements on grids with hanging nodes), please
* use the @p interpolate() function with an additional AffineConstraints
* object as argument, see below, or make the field conforming yourself
* by calling the @p distribute function of your hanging node constraints
* object.
*/
template <int dim, int spacedim, class InVector, class OutVector>
void
interpolate(const DoFHandler<dim, spacedim> &dof1,
const InVector &u1,
const DoFHandler<dim, spacedim> &dof2,
OutVector &u2);
and similar functions in FETools with this infrastructure. This does not need to happen now, but I think it is good to have this in mind, to simplify life for users in this regard in the near future.

// p::d::Vector type:
LAVector my_u_coarse;
InterpolateBetweenMeshes::create_vector(dof_handler_coarse, my_u_coarse);
my_u_coarse.update_ghost_values();
Copy link
Member

Choose a reason for hiding this comment

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

You don't need this, do you?

Suggested change
my_u_coarse.update_ghost_values();

Copy link
Member Author

Choose a reason for hiding this comment

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

You're right, I don't!

// of the source vector
LAVector my_u_fine;
InterpolateBetweenMeshes::create_vector(dof_handler_fine, my_u_fine);
my_u_fine.update_ghost_values();
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
my_u_fine.update_ghost_values();

Comment on lines +1187 to +1189
Assert(GridTools::have_same_coarse_mesh(dof_handler_fine,
dof_handler_coarse),
ExcMessage("The two DoF handlers must represent triangulations that "
"have the same coarse meshes"));
Copy link
Member

Choose a reason for hiding this comment

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

@bangerth
Copy link
Member Author

bangerth commented Mar 9, 2024

@kronbichler I removed the two lines. For the functions in FETools: Good grief, they look exactly like the functions in VectorTools. I had not remembered that we have this stuff twice. I'll leave a couple links in a separate PR (#16743).

@kronbichler kronbichler merged commit 8b73392 into dealii:master Mar 9, 2024
16 checks passed
@bangerth bangerth deleted the mesh-transfer branch March 10, 2024 00:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants