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/coupler.hpp"
9 : #include "issm-precice/confreader.hpp"
10 : #include "issm-precice/issm.hpp"
11 :
12 : #include "classes/classes.h"
13 : #include "shared/Enum/EnumDefinitions.h"
14 :
15 : #include "mpi.h"
16 :
17 : #include <array>
18 : #include <functional>
19 : #include <string>
20 : #include <unordered_map>
21 : #include <vector>
22 :
23 : namespace ipc
24 : {
25 :
26 : /*
27 : * Coupling adapter for ISSM.
28 : * Coordinates data exchange between ISSM and preCICE.
29 : */
30 : class Adapter
31 : {
32 : public:
33 : /**
34 : * Create an adapter for coupling.
35 : * @param config The configuration of the adapter.
36 : * @param model The ISSM model to use.
37 : * @param coupler The coupling interface.
38 : * @param comm
39 : */
40 : Adapter(const Config& config, std::unique_ptr<IIssm>&& model, std::unique_ptr<ICoupler>&& coupler, MPI_Comm comm);
41 :
42 : /**
43 : * Set up the mesh and communication.
44 : * @returns The maximum length of the first time step.
45 : */
46 : void initialize();
47 :
48 : /**
49 : * Initialize the data.
50 : * May need to run computation in ISSM to get initial values for some variables.
51 : */
52 : void initialize_data();
53 :
54 : /**
55 : * Check if final time of coupling is reached.
56 : * @returns true if more coupling time steps are required.
57 : */
58 : bool is_coupling_ongoing() const;
59 :
60 : /**
61 : * Get the time to be computed.
62 : * Checks both model and coupler.
63 : */
64 : double get_time_step() const;
65 :
66 : /**
67 : * Read data from preCICE and set it in ISSM.
68 : * @param dt Length of time step for time interpolation of data.
69 : */
70 : void read_data(double dt);
71 :
72 : /**
73 : * Run the ISSM simulation for one time step.
74 : * ISSM may require subcycling, i.e., smaller time steps than coupling,
75 : * for stability.
76 : * @param dt Length of the time step to simulate.
77 : */
78 : void solve(double dt);
79 :
80 : /**
81 : * Get data from ISSM and write it to preCICE.
82 : */
83 : void write_data();
84 :
85 : /**
86 : * Complete a coupling time step.
87 : * Exchanges data between participants.
88 : * Data must be written before a call to this function.
89 : * @param dt Length of the time step.
90 : */
91 : void advance(double dt);
92 :
93 8 : MPI_Comm get_mpi_comm() const {
94 8 : return m_comm;
95 : }
96 :
97 : private:
98 : // set up the mesh: extract relevant vertex IDs and calculate coordinates for
99 : // preCICE
100 : void setup_mesh();
101 :
102 : // read data from preCICE and set in ISSM
103 : void read_all_data(double dt);
104 : void read_data(const VariableDefinition& var, double dt, std::function<void(double*)> map_func = nullptr);
105 :
106 : // get data from ISSM and write to preCICE
107 : void write_all_data(bool initialize = false);
108 : void write_data(const VariableDefinition& var, std::function<void(double*)> map_func = nullptr);
109 :
110 : private:
111 : std::unordered_map<definitions, std::function<void(double*)>> m_map_functions;
112 : std::vector<Vertex> m_vertices;
113 : std::vector<VariableDefinition> m_variables;
114 : std::unique_ptr<IIssm> m_issm;
115 : std::unique_ptr<ICoupler> m_coupler;
116 : MPI_Comm m_comm;
117 : };
118 :
119 : /**
120 : * Run the coupling loop.
121 : * @param adapter issm-precice Adapter to use for coupling.
122 : */
123 : void run_coupling(Adapter& adapter);
124 :
125 : } // namespace ipc
|