Line data Source code
1 : // SPDX-FileCopyrightText: 2024 Daniel Abele <daniel.abele@dlr.de>
2 : //
3 : // SPDX-License-Identifier: BSD-3-Clause
4 :
5 : #pragma once
6 :
7 : #include "issm-precice/config.hpp"
8 : #include "issm-precice/confreader.hpp"
9 : #include "issm-precice/mesh.hpp"
10 : #include "mpi.h"
11 : #include <filesystem>
12 : #include <memory>
13 : #include <ranges>
14 : #include <string>
15 : #include <vector>
16 : #include <span>
17 :
18 : class FemModel;
19 :
20 : namespace ipc
21 : {
22 :
23 : struct NoopDeleter
24 : {
25 118 : void operator()(FemModel*) { }
26 : };
27 :
28 : /**
29 : * Unique ptr to own an ISSM FemModel object.
30 : * Deleter does not do anything because FemModel causes a segfault on deletion.
31 : */
32 : using FemModelPtr = std::unique_ptr<FemModel, NoopDeleter>;
33 :
34 : /**
35 : * Create an ISSM FemModel by loading the specified model.
36 : * @param root_path Directory where the model files are stored.
37 : * @param model_name Name of the model to load.
38 : * @param comm MPI communicator to use by ISSM.
39 : */
40 : FemModelPtr make_fem_model(const std::filesystem::path& root_path, const std::string& model_name, MPI_Comm comm);
41 :
42 : /**
43 : * Get the ISSM input id of the given name.
44 : */
45 : definitions issm_input_id(const std::string& input_name);
46 :
47 : /**
48 : * Get the name of the ISSM input.
49 : */
50 : const char* issm_input_name(definitions input_id);
51 :
52 : /**
53 : * Get the ISSM input that stores depth averaged values for the specified input.
54 : */
55 : definitions depth_average_input(definitions input_id);
56 :
57 : /**
58 : * Abstract interface for ISSM used for coupling.
59 : */
60 : class IIssm
61 : {
62 : public:
63 : /**
64 : * Virtual destructor.
65 : */
66 : virtual ~IIssm();
67 :
68 : /**
69 : * Get the vertices of the coupled interface mesh.
70 : * @param with_connectivity True if mesh connectivity is required.
71 : * Warning: mesh connectivity also implies ghost vertices in distributed meshes, this breaks RBF mapping methods.
72 : * @returns Vertices of the ISSM mesh and the elements they belong to.
73 : */
74 : virtual Mesh get_vertices(bool with_connectivity) const = 0;
75 :
76 : /**
77 : * Maximum length of next time step allowed by the model (e.g. for numeric stability).
78 : * The adapter may choose to make larger time steps, ISSM will then do smaller time steps internally.
79 : */
80 : virtual double get_max_time_step() const = 0;
81 :
82 : /**
83 : * Set the specified input for the vertices.
84 : * @param input Input to set.
85 : * @param vertices Vertices and corresponding Element to set the values for.
86 : * @param values Values to set.
87 : */
88 : virtual void
89 : set_input(definitions input, const std::vector<Vertex>& vertices, std::span<const double> values) = 0;
90 :
91 : /**
92 : * Set the specified constraints for the vertices.
93 : * @param input Input to set.
94 : * @param vertices Vertices and corresponding Element to set the values for.
95 : * @param values Values to set.
96 : */
97 : virtual void
98 : set_constraints(definitions input, const std::vector<Vertex>& vertices, std::span<const double> values) = 0;
99 :
100 : /**
101 : * Extrude the specified input.
102 : * Values of the input are copied from base (or surface, depending on the used coupling interface)
103 : * to the other layers of a 3D ISSM model. No effect on 2D ISSM models.
104 : * @param input Input to extrude.
105 : * @param vertices Vertices to extrude.
106 : */
107 : virtual void extrude(definitions input, const std::vector<Vertex>& vertices) = 0;
108 :
109 : /**
110 : * Compute valid initial values for the input.
111 : * For most inputs, this does nothing since the input has valid values in
112 : * the ISSM model setup. Some inputs are not required to be have correct initial values as they are
113 : * computed by ISSM without initial state. For these inputs, this function does the necessary computation that
114 : * would normally happen only during the simulation.
115 : * @param input Input to initialize.
116 : */
117 : virtual void initialize(definitions input) = 0;
118 :
119 : /**
120 : * Get the specified input for the vertices.
121 : * @param input Input to get.
122 : * @param vertices Vertices and corresponding Element to get the values for.
123 : * @param[out] values Vector to store the values in. Will be overwritten by the function.
124 : */
125 : virtual void
126 : get_input(definitions input, const std::vector<Vertex>& vertices, std::span<double> values) const = 0;
127 :
128 : /**
129 : * Run depth averaging for the specified input.
130 : * Computes the average of an input over all the layers of a 3D ISSM model and stores it
131 : * in a specific input that depends on the argument input. For every supported input there is one
132 : * corresponding average input.
133 : * @param input Input to depth average.
134 : * @param vertices vertices to depth average.
135 : * @returns Input where the depth averaged values are stored.
136 : */
137 : virtual definitions depth_average(definitions input, const std::vector<Vertex>& vertices) = 0;
138 :
139 : /**
140 : * Advance the simulation by a certain time increment.
141 : * Internally, simulation may do multiple time steps.
142 : * @param dt length of the time increment.
143 : */
144 : virtual void solve(double dt) = 0;
145 : };
146 :
147 : /**
148 : * Concretization of the IIssm interface.
149 : * Gives access to ISSM model data required for coupling.
150 : */
151 : class Issm : public IIssm
152 : {
153 : public:
154 : /**
155 : * Initialize ISSM by loading a model.
156 : * @param root_path Path to directory that stores the model.
157 : * @param model_name Name of the model.
158 : * @param mesh Definition of the coupling interface mesh.
159 : * @param comm MPI communicator to used by ISSM.
160 : */
161 : Issm(
162 : const std::filesystem::path& root_path,
163 : const std::string& model_name,
164 : const MeshConfig& mesh,
165 : MPI_Comm comm);
166 :
167 : /**
168 : * @copydoc IIssm::get_vertices()
169 : */
170 : Mesh get_vertices(bool with_connectivity) const override;
171 :
172 : /**
173 : * Like IIssm::get_vertices(), but for a dynamic coupling mesh instead of the initial one.
174 : * Mainly for testing.
175 : */
176 : Mesh get_vertices(const MeshConfig& mesh, bool with_connectivity) const;
177 :
178 : /**
179 : * @copydoc IIssm::get_time_step()
180 : */
181 : double get_max_time_step() const override;
182 :
183 : /**
184 : * @copydoc IIssm::initialize()
185 : */
186 : void initialize(definitions input) override;
187 :
188 : /**
189 : * @copydoc IIssm:set_input()
190 : */
191 : void set_input(definitions input, const std::vector<Vertex>& vertices, std::span<const double> values) override;
192 :
193 : /**
194 : * @copydoc IIssm:set_constraints()
195 : */
196 : virtual void
197 : set_constraints(definitions input, const std::vector<Vertex>& vertices, std::span<const double> values) override;
198 :
199 : /**
200 : * @copydoc IIssm:extrude()
201 : */
202 : void extrude(definitions input, const std::vector<Vertex>& vertices) override;
203 :
204 : /**
205 : * @copydoc IIssm:get_input()
206 : */
207 : void get_input(definitions input, const std::vector<Vertex>& vertices, std::span<double> values) const override;
208 :
209 : /**
210 : * @copydoc IIssm:depth_average()
211 : */
212 : definitions depth_average(definitions input, const std::vector<Vertex>& vertices) override;
213 :
214 : /**
215 : * @copydoc IIssm:solve()
216 : */
217 : void solve(double dt) override;
218 :
219 : /**
220 : * Override the time step set in ISSM setup.
221 : * Disable override (i.e. use value from setup) by setting negative value.
222 : */
223 : void set_time_step_override(double dt);
224 :
225 : /**
226 : * Override the output frequency set in ISSM setup.
227 : * Disable output entirely by setting frequency to 0.
228 : * Disable override (i.e. use value from setup) by setting negative value.
229 : */
230 : void set_output_frequency_override(int f);
231 :
232 : /**
233 : * Get the current simulation time.
234 : */
235 : double get_time() const;
236 :
237 : /**
238 : * Get the current simulation step.
239 : */
240 : int get_step() const;
241 :
242 : private:
243 : bool try_set_constraint_value(const Vertex&, definitions input, double value) const;
244 : std::vector<double> synchronize_ghosts(const std::vector<Vertex>& vertices, std::span<const double> values) const;
245 :
246 : private:
247 : FemModelPtr m_model;
248 : MeshConfig m_coupling_mesh_config;
249 : Mesh m_connected_mesh; //includes ghost vertices and edges (e.g. for Lin. Cell Interp. mapping)
250 : Mesh m_unique_mesh; //omits ghost vertices and edges (e.g. for RBF mapping)
251 : bool m_initialized_stress_balance;
252 : double m_initial_dt; //time step configured in the ISSM setup, saved here because it may be overriden during sim
253 : double m_dt_override = -1.0; //negative means no override
254 : int m_output_frequency_override = -1; //negative means no override
255 : };
256 : } // namespace ipc
|