Line data Source code
1 : // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 : // SPDX-License-Identifier: Apache-2.0
3 :
4 : #ifndef PALACE_MODELS_WAVE_PORT_OPERATOR_HPP
5 : #define PALACE_MODELS_WAVE_PORT_OPERATOR_HPP
6 :
7 : #include <complex>
8 : #include <map>
9 : #include <memory>
10 : #include <unordered_map>
11 : #include <mfem.hpp>
12 : #include "fem/fespace.hpp"
13 : #include "fem/gridfunction.hpp"
14 : #include "fem/mesh.hpp"
15 : #include "linalg/eps.hpp"
16 : #include "linalg/ksp.hpp"
17 : #include "linalg/operator.hpp"
18 : #include "linalg/vector.hpp"
19 :
20 : namespace palace
21 : {
22 :
23 : class IoData;
24 : class MaterialOperator;
25 : class MaterialPropertyCoefficient;
26 : class SumVectorCoefficient;
27 :
28 : namespace config
29 : {
30 :
31 : struct WavePortData;
32 : struct SolverData;
33 :
34 : } // namespace config
35 :
36 : //
37 : // Helper class for wave port boundaries in a model.
38 : //
39 : class WavePortData
40 : {
41 : public:
42 : // Reference to material property data (not owned).
43 : const MaterialOperator &mat_op;
44 :
45 : // Wave port properties.
46 : int mode_idx;
47 : double d_offset;
48 : int excitation;
49 : bool active;
50 : std::complex<double> kn0;
51 : double omega0;
52 : mfem::Vector port_normal;
53 :
54 : private:
55 : // List of all boundary attributes making up this port boundary.
56 : mfem::Array<int> attr_list;
57 :
58 : // SubMesh data structures to define finite element spaces and grid functions on the
59 : // SubMesh corresponding to this port boundary.
60 : std::unique_ptr<Mesh> port_mesh;
61 : std::unique_ptr<mfem::FiniteElementCollection> port_nd_fec, port_h1_fec;
62 : std::unique_ptr<FiniteElementSpace> port_nd_fespace, port_h1_fespace;
63 : std::unique_ptr<mfem::ParTransferMap> port_nd_transfer, port_h1_transfer;
64 : std::unordered_map<int, int> submesh_parent_elems;
65 : mfem::Array<int> port_dbc_tdof_list;
66 : double mu_eps_max;
67 :
68 : // Operator storage for repeated boundary mode eigenvalue problem solves.
69 : std::unique_ptr<mfem::HypreParMatrix> Atnr, Atni, Antr, Anti, Annr, Anni;
70 : std::unique_ptr<ComplexOperator> opB;
71 : ComplexVector v0, e0;
72 :
73 : // Eigenvalue solver for boundary modes.
74 : MPI_Comm port_comm;
75 : int port_root;
76 : std::unique_ptr<EigenvalueSolver> eigen;
77 : std::unique_ptr<ComplexKspSolver> ksp;
78 :
79 : // Grid functions storing the last computed electric field mode on the port, and stored
80 : // objects for computing functions of the port modes for use as an excitation or in
81 : // postprocessing.
82 : std::unique_ptr<GridFunction> port_E0t, port_E0n, port_S0t, port_E;
83 : std::unique_ptr<mfem::LinearForm> port_sr, port_si;
84 :
85 : public:
86 : WavePortData(const config::WavePortData &data, const config::SolverData &solver,
87 : const MaterialOperator &mat_op, mfem::ParFiniteElementSpace &nd_fespace,
88 : mfem::ParFiniteElementSpace &h1_fespace, const mfem::Array<int> &dbc_attr);
89 : ~WavePortData();
90 :
91 0 : [[nodiscard]] constexpr bool HasExcitation() const { return excitation != 0; }
92 :
93 0 : const auto &GetAttrList() const { return attr_list; }
94 :
95 : void Initialize(double omega);
96 :
97 : HYPRE_BigInt GlobalTrueNDSize() const { return port_nd_fespace->GlobalTrueVSize(); }
98 : HYPRE_BigInt GlobalTrueH1Size() const { return port_h1_fespace->GlobalTrueVSize(); }
99 :
100 : std::unique_ptr<mfem::VectorCoefficient> GetModeExcitationCoefficientReal() const;
101 : std::unique_ptr<mfem::VectorCoefficient> GetModeExcitationCoefficientImag() const;
102 :
103 : std::unique_ptr<mfem::VectorCoefficient> GetModeFieldCoefficientReal() const;
104 : std::unique_ptr<mfem::VectorCoefficient> GetModeFieldCoefficientImag() const;
105 :
106 : std::complex<double> GetCharacteristicImpedance() const
107 : {
108 : MFEM_ABORT("GetImpedance is not yet implemented for wave port boundaries!");
109 : return 0.0;
110 : }
111 :
112 : double GetExcitationPower() const;
113 : std::complex<double> GetExcitationVoltage() const
114 : {
115 : MFEM_ABORT("GetExcitationVoltage is not yet implemented for wave port boundaries!");
116 : return 0.0;
117 : }
118 :
119 : std::complex<double> GetPower(GridFunction &E, GridFunction &B) const;
120 : std::complex<double> GetSParameter(GridFunction &E) const;
121 : std::complex<double> GetVoltage(GridFunction &E) const
122 : {
123 : MFEM_ABORT("GetVoltage is not yet implemented for wave port boundaries!");
124 : return 0.0;
125 : }
126 : };
127 :
128 : //
129 : // A class handling wave port boundaries and their postprocessing.
130 : //
131 0 : class WavePortOperator
132 : {
133 : private:
134 : // Mapping from port index to data structure containing port information.
135 : std::map<int, WavePortData> ports;
136 :
137 : // Flag which forces no printing during WavePortData::Print().
138 : bool suppress_output;
139 : double fc, kc;
140 :
141 : void SetUpBoundaryProperties(const IoData &iodata, const MaterialOperator &mat_op,
142 : mfem::ParFiniteElementSpace &nd_fespace,
143 : mfem::ParFiniteElementSpace &h1_fespace);
144 : void PrintBoundaryInfo(const IoData &iodata, const mfem::ParMesh &mesh);
145 :
146 : // Compute boundary modes for all wave port boundaries at the specified frequency.
147 : void Initialize(double omega);
148 :
149 : public:
150 : WavePortOperator(const IoData &iodata, const MaterialOperator &mat_op,
151 : mfem::ParFiniteElementSpace &nd_fespace,
152 : mfem::ParFiniteElementSpace &h1_fespace);
153 :
154 : // Access data structures for the wave port with the given index.
155 : const WavePortData &GetPort(int idx) const;
156 : auto begin() const { return ports.begin(); }
157 : auto end() const { return ports.end(); }
158 : auto rbegin() const { return ports.rbegin(); }
159 : auto rend() const { return ports.rend(); }
160 : auto Size() const { return ports.size(); }
161 :
162 : // Enable or suppress all outputs (log printing and fields to disk).
163 0 : void SetSuppressOutput(bool suppress) { suppress_output = suppress; }
164 :
165 : // Returns array of wave port attributes.
166 : mfem::Array<int> GetAttrList() const;
167 :
168 : // Add contributions to system matrix from wave ports.
169 : void AddExtraSystemBdrCoefficients(double omega, MaterialPropertyCoefficient &fbr,
170 : MaterialPropertyCoefficient &fbi);
171 :
172 : // Add contributions to the right-hand side source term vector for an incident field at
173 : // excited port boundaries.
174 : void AddExcitationBdrCoefficients(int excitation_idx, double omega,
175 : SumVectorCoefficient &fbr, SumVectorCoefficient &fbi);
176 : };
177 :
178 : } // namespace palace
179 :
180 : #endif // PALACE_MODELS_WAVE_PORT_OPERATOR_HPP
|