Skip to content

Commit 1952b2c

Browse files
authored
Merge pull request #9 from tjhei/lla-external-mesh-deform
external mesh deformation base class
2 parents 8b28c4a + 3694cfe commit 1952b2c

File tree

10 files changed

+1669
-0
lines changed

10 files changed

+1669
-0
lines changed
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
/*
2+
Copyright (C) 2011 - 2024 by the authors of the ASPECT code.
3+
4+
This file is part of ASPECT.
5+
6+
ASPECT is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation; either version 2, or (at your option)
9+
any later version.
10+
11+
ASPECT is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with ASPECT; see the file LICENSE. If not see
18+
<http://www.gnu.org/licenses/>.
19+
*/
20+
21+
22+
#ifndef _aspect_mesh_deformation_external_tool_interface_h
23+
#define _aspect_mesh_deformation_external_tool_interface_h
24+
25+
#include <aspect/mesh_deformation/interface.h>
26+
27+
28+
namespace aspect
29+
{
30+
namespace MeshDeformation
31+
{
32+
/**
33+
* This class provides some support for writing classes derived
34+
* from MeshDeformation::Interface when implementing surface
35+
* deformation models that are based on external tools such as
36+
* Fastscape, Landlab, OpenLEM, etc. The primary complication of
37+
* interacting with these external tools is that they generally
38+
* use their own discretization of surface processes, using a mesh
39+
* that, in most cases, will be different from the one used by
40+
* ASPECT. (Of course, ASPECT's use is a *volume* mesh, whereas
41+
* surface processes use *surface* meshes. ASPECT's own surface
42+
* diffusion, for example, works on the surface faces of ASPECT's
43+
* mesh, but in general, external tools use a mesh that is
44+
* *entirely unrelated* to the surface cells of ASPECT's volume
45+
* mesh.) In these cases, one needs to implement transfer
46+
* operations to take ASPECT's solution and interpolate it to the
47+
* external tool's mesh, run some surface evolution steps, and
48+
* then interpolate back to the surface nodes of ASPECT's
49+
* mesh. These interpolation operations are difficult to implement
50+
* in their own right, but are made particularly cumbersome in
51+
* parallel because then, the points at which the external tool
52+
* wants to know the solution on any given MPI process will, in
53+
* general, not be located on that part of ASPECT's mesh that is
54+
* owned by that MPI process. As a consequence, implementing the
55+
* interpolation requires finding the MPI process that owns the
56+
* cell on which that point is located, and then communication
57+
* back and forth.
58+
*
59+
* @sect3{Helper functions}
60+
*
61+
* This class implements the interpolation functionality for
62+
* derived classes to use. It works through a two-stage approach:
63+
* First, derived classes declare at which points they require
64+
* ASPECT's solution to be evaluated, via the
65+
* set_evaluation_points() function. This function then finds
66+
* which process owns the cell around this point, and sets up
67+
* communication structures that will make later evaluation
68+
* efficient. Second, this class provides the
69+
* evaluate_aspect_variables_at_points() function that uses these
70+
* communication structures to evaluate ASPECT's current solution
71+
* at the points previously set. The class also provides the
72+
* interpolate_vertical_velocities_to_surface_points() function
73+
* that takes a set of (vertical) velocity values at these points
74+
* and uses them to interpolate the information back onto ASPECT's
75+
* mesh.
76+
*
77+
* All three of these functions are `protected` member functions
78+
* of this class, ready to be called by derived classes.
79+
*
80+
*
81+
* @sect3{A high-level function}
82+
*
83+
* All classes derived from Interface need to implement the
84+
* Interface::compute_velocity_constraints_on_boundary()
85+
* function. Because the basic outline of this function looks
86+
* essentially the same for all external tools, this class also
87+
* provides a high-level implementation of this function is also
88+
* provided as part of this class. In essence, it looks as
89+
* follows (pseudo-code), relying on the
90+
* `compute_updated_velocities_at_points()` function that gets
91+
* ASPECT's solution at the evaluation points and returns velocity
92+
* vectors at all of these evaluation points:
93+
* @code
94+
* // Interpolate ASPECT's solution at evaluation points:
95+
* aspect_surface_velocities = evaluate_aspect_variables_at_points();
96+
*
97+
* // Call derive class's method to compute updated velocities:
98+
* external_surface_velocities = compute_updated_velocities_at_points(aspect_surface_velocities);
99+
*
100+
* // Turn the result into the constraints that
101+
* // compute_velocity_constraints_on_boundary is supposed
102+
* // to return.
103+
* @endcode
104+
*/
105+
template <int dim>
106+
class ExternalToolInterface : public Interface<dim>, public SimulatorAccess<dim>
107+
{
108+
public:
109+
/**
110+
* Main routine handling the mesh deformation
111+
*/
112+
virtual
113+
void
114+
compute_velocity_constraints_on_boundary(const DoFHandler<dim> &mesh_deformation_dof_handler,
115+
AffineConstraints<double> &mesh_velocity_constraints,
116+
const std::set<types::boundary_id> &boundary_ids) const override;
117+
118+
/**
119+
* Given all solution variables at each surface point, compute velocities at these points.
120+
*
121+
* This needs to be implemented by the derived class and implement the "surface evolution".
122+
*/
123+
virtual
124+
std::vector<Tensor<1,dim>>
125+
compute_updated_velocities_at_points (const std::vector<std::vector<double>> &current_solution_at_points) const = 0;
126+
127+
128+
protected:
129+
// Helper functions to be used in derived classes:
130+
131+
/**
132+
* Declare at which points the external tool driven by a class
133+
* derived from the current one needs to evaluate the ASPECT
134+
* solution. Each process will call this function with the points
135+
* it needs. Different processes will, in general, provide
136+
* distinct sets of points.
137+
*
138+
* The points provided here are given in the undeformed
139+
* configuration that corresponds to the initial mesh. For
140+
* example, if the mesh describes a box geometry, then the
141+
* points should like in the $x$-$y$-plane that forms the top
142+
* surface, rather than on the currently deformed top surface
143+
* that describes the current elevation map.
144+
*
145+
* @note This function sets up communication structures that
146+
* encode, among other things, which process owns which
147+
* points. This information becomes outdated when the
148+
* ASPECT mesh changes for mesh refinement. As a
149+
* consequence, the current function sets up a process that
150+
* invalidates the communication structures upon mesh
151+
* refinement. Derived classes therefore have to set up
152+
* their own code to call set_evaluation_points() again when
153+
* the ASPECT mesh changes, or perhaps simply check whether
154+
* the information needs to be updated in an overload of the
155+
* update() function called at the beginning of each time
156+
* step.
157+
*/
158+
void
159+
set_evaluation_points (const std::vector<Point<dim>> &evaluation_points);
160+
161+
/**
162+
* Return the value of the ASPECT solution at the set of points
163+
* previously set via set_evaluation_points().
164+
*
165+
* For each point, the return object contains a vector with as
166+
* many components as there are ASPECT solution components.
167+
*/
168+
std::vector<std::vector<double>>
169+
evaluate_aspect_variables_at_points () const;
170+
171+
/**
172+
* Interpolate from velocities given in the evaluation points
173+
* to ASPECT velocities on the surface in form of a finite
174+
* element field.
175+
*
176+
* The @p velocities, which are typically vertical, were previously
177+
* computed by the external tool and belong to the current process.
178+
* The Output is a (global) finite element field vector that in
179+
* the velocity components of surface nodes corresponds to an
180+
* interpolation of the velocities provided.
181+
*
182+
* The output of this function can then be used as input for a
183+
* function that implements the
184+
* compute_velocity_constraints_on_boundary() function of the
185+
* base class.
186+
*/
187+
LinearAlgebra::Vector
188+
interpolate_external_velocities_to_surface_support_points (const std::vector<Tensor<1,dim>> &velocities) const;
189+
190+
/**
191+
* The list of evaluation points owned by the current process. These are the points where the
192+
* external tool will receive the ASPECT solution values and return the updated velocities.
193+
*/
194+
std::vector<Point<dim>> evaluation_points;
195+
196+
/**
197+
* deal.II RemotePointEvaluation object used to do point evaluation in the evaluation points.
198+
*/
199+
std::unique_ptr<Utilities::MPI::RemotePointEvaluation<dim, dim>> remote_point_evaluator;
200+
201+
/**
202+
* A struct to map between DoF indices and evaluation points
203+
*/
204+
struct DofToEvalPointData
205+
{
206+
types::global_dof_index dof_index;
207+
unsigned int evaluation_point_index;
208+
unsigned int component;
209+
};
210+
211+
/**
212+
* A vector to store a map between Dof indices and evaluation points.
213+
*
214+
* The map will contain an entry for each DoF on the surface of the ASPECT mesh and contains
215+
* the index of the evaluation point that is closest to the DoF. As each support point has
216+
* several components (x,y,z velocity), the map contains one entry for each component.
217+
*
218+
* In a parallel computation, this map only contains entries for evaluation points owned by the
219+
* current process. Note that the DoF indices are not necessarily locally owned.
220+
*
221+
* This map is used in interpolate_external_velocities_to_surface_support_points() to copy
222+
* external velocities to each surface DoF from the closest evaluation point.
223+
*/
224+
std::vector<DofToEvalPointData> map_dof_to_eval_point;
225+
};
226+
}
227+
}
228+
229+
#endif

0 commit comments

Comments
 (0)