Line data Source code
1 : // Copyright (C) 2023 Helmut Schmidt University
2 : // This file is part of the Mamico project. For conditions of distribution
3 : // and use, please see the copyright notice in Mamico's main folder
4 :
5 : #pragma once
6 :
7 : namespace coupling {
8 : namespace interface {
9 : class PintableMacroSolver;
10 : class PintableMacroSolverState;
11 : } // namespace interface
12 : } // namespace coupling
13 :
14 : #include <memory>
15 :
16 : /**
17 : * Interface for a macroscopic solver who supports parallel-in-time coupled simulations. This requires:
18 : * - The macro solver can be switched between *supervising mode* and *coupling mode*
19 : * - In supervising mode, the macro solver runs everywhere (incl inner MD cells)
20 : * - In coupling mode, the macro solver runs only on the CFD domain (outer MD cells and outside MaMiCo)
21 : * - Parameterization of the solver (e.g. viscosity, relaxation time) can differ between supervising and coupling mode
22 : * - The macro solver can output / return a full state object, containing all data describing the CFD state on this ranks subdomain
23 : * - In supervising mode, the macro solver can be non-zero-initialised to a given state (thus it can not be analytical)
24 : * - Simulation state instances can perform the arithmetic operations addition, subtraction, copy assignment
25 : *
26 : * All macroscopic solvers which want to support PinT have to implement this interface.
27 : *
28 : * @author Piet Jarmatz
29 : */
30 116 : class coupling::interface::PintableMacroSolver {
31 : public:
32 : using State = PintableMacroSolverState;
33 : enum class Mode { supervising, coupling };
34 :
35 116 : virtual ~PintableMacroSolver() {}
36 :
37 : /** This method should return all information that is required to define the full state of CFD on the subdomain of this rank */
38 : virtual std::unique_ptr<State> getState() = 0;
39 :
40 : /** This method fully reset / initialize the CFD solver to the given state */
41 : virtual void setState(const std::unique_ptr<State>&, int cycle = 0) = 0;
42 :
43 : /** This advances the macroSolver by one time step, starting from the given state */
44 : virtual std::unique_ptr<State> operator()(const std::unique_ptr<State>&, int cycle = 0) = 0;
45 :
46 : /** returns either Mode.supervising or Mode.coupling */
47 : virtual Mode getMode() const = 0;
48 :
49 : /** assuming this is called on a PintableMacroSolver in coupling mode, this creates a new supervisor instance and returnes it */
50 : virtual std::unique_ptr<PintableMacroSolver> getSupervisor(int num_cycles, double visc_multiplier = 1) const = 0;
51 :
52 : /** this is expected to print information about the mode and type of this solver object to os */
53 : virtual void print(std::ostream& os) const = 0;
54 :
55 : /** Useful to test if a solver behaves as expected, similar to a "det(state)":
56 : * should return a single numeric value that characterises the state object, by computing the mean flow velocity */
57 0 : virtual double get_avg_vel(const std::unique_ptr<State>& state) const { return 0; }
58 : friend std::ostream& operator<<(std::ostream& os, const coupling::interface::PintableMacroSolver& s) {
59 : s.print(os);
60 : return os;
61 : }
62 : };
63 :
64 : /**
65 : * Interface for state instances
66 : */
67 5868 : class coupling::interface::PintableMacroSolverState {
68 : public:
69 : using State = PintableMacroSolverState;
70 :
71 : virtual std::unique_ptr<State> clone() const = 0;
72 :
73 192 : virtual ~PintableMacroSolverState() {}
74 :
75 : /** For MPI communication, size of a State object must be known */
76 : virtual int getSizeBytes() const = 0; //
77 :
78 : /** For Parareal algorithm, it must be possible to add states. This is expected to operate element-wise */
79 : virtual std::unique_ptr<State> operator+(const State&) = 0;
80 :
81 : /** For Parareal algorithm, it must be possible to substract states. This is expected to operate element-wise */
82 : virtual std::unique_ptr<State> operator-(const State&) = 0;
83 :
84 52 : friend bool operator==(const State& lhs, const State& rhs) { return lhs.__equals__(rhs); }
85 :
86 : /** For MPI communication, raw pointer of the underlying data is needed */
87 : virtual double* getData() = 0;
88 :
89 : /** For MPI communication, raw pointer of the underlying data is needed */
90 : virtual const double* getData() const = 0;
91 :
92 : /** this is expected to print information about the type of this state object to os */
93 : virtual void print(std::ostream& os) const = 0;
94 :
95 0 : friend std::ostream& operator<<(std::ostream& os, const coupling::interface::PintableMacroSolverState& s) {
96 0 : s.print(os);
97 0 : return os;
98 : }
99 :
100 : protected:
101 : /** For tests, it must be possible to compare states. This is expected to operate element-wise */
102 : virtual bool __equals__(const State&) const = 0;
103 : };
|