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