Documentation 6b54b78464
Loading...
Searching...
No Matches
CDiscAdjFEASolver.hpp
Go to the documentation of this file.
1/*!
2 * \file CDiscAdjFEASolver.hpp
3 * \brief Headers of the CDiscAdjFEASolver class
4 * \author R. Sanchez
5 * \version 8.5.0 "Harrier"
6 *
7 * SU2 Project Website: https://su2code.github.io
8 *
9 * The SU2 Project is maintained by the SU2 Foundation
10 * (http://su2foundation.org)
11 *
12 * Copyright 2012-2026, SU2 Contributors (cf. AUTHORS.md)
13 *
14 * SU2 is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Lesser General Public
16 * License as published by the Free Software Foundation; either
17 * version 2.1 of the License, or (at your option) any later version.
18 *
19 * SU2 is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Lesser General Public License for more details.
23 *
24 * You should have received a copy of the GNU Lesser General Public
25 * License along with SU2. If not, see <http://www.gnu.org/licenses/>.
26 */
27
28#pragma once
29
30#include "CSolver.hpp"
31#include "../variables/CDiscAdjFEABoundVariable.hpp"
32
33/*!
34 * \class CDiscAdjFEASolver
35 * \ingroup DiscAdj
36 * \brief Main class for defining the discrete adjoint solver for FE structural problems.
37 * \author R. Sanchez
38 */
39class CDiscAdjFEASolver final : public CSolver {
40private:
41 static constexpr size_t MAXNVAR = 9; /*!< \brief Max number of variables, for static arrays. */
42 unsigned short KindDirect_Solver = 0;
43 CSolver *direct_solver = nullptr;
44
45 /*!
46 * \brief A type to manage sensitivities of design variables.
47 */
48 struct SensData {
49 unsigned short size = 0;
50 su2double* val = nullptr; /*!< \brief Value of the variable. */
51 su2double* LocalSens = nullptr; /*!< \brief Local sensitivity (domain). */
52 su2double* GlobalSens = nullptr; /*!< \brief Global sensitivity (mpi). */
53 su2double* OldSens = nullptr; /*!< \brief Previous global sensitivity, used to update the total. */
54 su2double* TotalSens = nullptr; /*!< \brief Total sensitivity (integrated over time). */
55
56 su2double& operator[] (unsigned short i) { return val[i]; }
57 const su2double& operator[] (unsigned short i) const { return val[i]; }
58
59 void resize(unsigned short n) {
60 clear();
61 size = n;
62 val = new su2double[n]();
63 LocalSens = new su2double[n]();
64 GlobalSens = new su2double[n]();
65 OldSens = new su2double[n]();
66 TotalSens = new su2double[n]();
67 }
68
69 void clear() {
70 size = 0;
71 delete [] val;
72 delete [] LocalSens;
73 delete [] GlobalSens;
74 delete [] OldSens;
75 delete [] TotalSens;
76 }
77
78 void Register() {
79 for (auto i = 0u; i < size; ++i) AD::RegisterInput(val[i]);
80 }
81
82 void GetDerivative() {
83 for (auto i = 0u; i < size; ++i) LocalSens[i] = SU2_TYPE::GetDerivative(val[i]);
84
85 SU2_MPI::Allreduce(LocalSens, GlobalSens, size, MPI_DOUBLE, MPI_SUM, SU2_MPI::GetComm());
86
87 for (auto i = 0u; i < size; ++i) {
88 /*--- Update the total by subtracting the old and adding the new value.
89 * Then update the old value for the next call to this function. ---*/
90 TotalSens[i] += GlobalSens[i] - OldSens[i];
91 OldSens[i] = GlobalSens[i];
92 }
93 }
94
95 void Store() {
96 /*--- Clears the old values such that on the next time step the total is
97 * incremented instead of updated. ---*/
98 for (auto i = 0u; i < size; ++i) OldSens[i] = 0.0;
99 }
100
101 ~SensData() { clear(); }
102 };
103
104 unsigned short nMPROP = 0; /*!< \brief Number of material properties */
105 SensData E; /*!< \brief Values of the Young's Modulus. */
106 SensData Nu; /*!< \brief Values of the Poisson's ratio. */
107 SensData Rho; /*!< \brief Values of the density (for inertial effects). */
108 SensData Rho_DL; /*!< \brief Values of the density (for volume loading). */
109
110 bool de_effects = false; /*!< \brief Determines if DE effects are considered. */
111 unsigned short nEField = 0; /*!< \brief Number of electric field areas in the problem. */
112 SensData EField; /*!< \brief Array that stores the electric field as design variables. */
113
114 bool fea_dv = false; /*!< \brief Determines if the design variable we study is a FEA parameter. */
115 unsigned short nDV = 0; /*!< \brief Number of design variables in the problem. */
116 SensData DV; /*!< \brief Values of the design variables. */
117
118 CDiscAdjFEABoundVariable* nodes = nullptr; /*!< \brief The highest level in the variable hierarchy this solver can safely use. */
119
120 /*!
121 * \brief Return nodes to allow CSolver::base_nodes to be set.
122 */
123 inline CVariable* GetBaseClassPointerToNodes() override { return nodes; }
124
125 /*!
126 * \brief Read the design variables for the adjoint solver
127 */
128 void ReadDV(const CConfig *config);
129
130public:
131
132 /*!
133 * \brief Constructor of the class.
134 */
135 CDiscAdjFEASolver() = default;
136
137 /*!
138 * \overload
139 * \param[in] geometry - Geometrical definition of the problem.
140 * \param[in] config - Definition of the particular problem.
141 * \param[in] solver - Initialize the discrete adjoint solver with the corresponding direct solver.
142 * \param[in] Kind_Solver - The kind of direct solver.
143 */
144 CDiscAdjFEASolver(CGeometry *geometry, CConfig *config, CSolver* solver, unsigned short Kind_Solver, unsigned short iMesh);
145
146 /*!
147 * \brief Destructor of the class.
148 */
149 ~CDiscAdjFEASolver() override;
150
151 /*!
152 * \brief Performs the preprocessing of the adjoint AD-based solver.
153 * Registers all necessary variables on the tape. Called while tape is active.
154 * \param[in] geometry_container - The geometry container holding all grid levels.
155 * \param[in] config_container - The particular config.
156 */
157 void RegisterSolution(CGeometry *geometry, CConfig *config) override;
158
159 /*!
160 * \brief Performs the preprocessing of the adjoint AD-based solver.
161 * Registers all necessary variables that are output variables on the tape.
162 * Called while tape is active.
163 * \param[in] geometry_container - The geometry container holding all grid levels.
164 * \param[in] config_container - The particular config.
165 */
166 void RegisterOutput(CGeometry *geometry, CConfig *config) override;
167
168 /*!
169 * \brief Sets the adjoint values of the output of the flow (+turb.) iteration
170 * before evaluation of the tape.
171 * \param[in] geometry - The geometrical definition of the problem.
172 * \param[in] config - The particular config.
173 */
174 void SetAdjoint_Output(CGeometry *geometry, CConfig *config) override;
175
176 /*!
177 * \brief Sets the adjoint values of the input variables of the flow (+turb.) iteration
178 * after tape has been evaluated.
179 * \param[in] geometry - The geometrical definition of the problem.
180 * \param[in] config - The particular config.
181 */
182 void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config, bool CrossTerm) override;
183
184 /*!
185 * \brief Extract and set the geometrical sensitivity.
186 * \param[in] geometry - Geometrical definition of the problem.
187 * \param[in] config - Definition of the particular problem.
188 */
189 void SetSensitivity(CGeometry *geometry, CConfig *config, CSolver*) override;
190
191 /*!
192 * \brief Provide the total Young's modulus sensitivity
193 * \return Value of the total Young's modulus sensitivity
194 * (inviscid + viscous contribution).
195 */
196 inline su2double GetTotal_Sens_E(unsigned short iVal) const override { return E.TotalSens[iVal]; }
197
198 /*!
199 * \brief Set the total Poisson's ratio sensitivity.
200 * \return Value of the Poisson's ratio sensitivity
201 */
202 inline su2double GetTotal_Sens_Nu(unsigned short iVal) const override { return Nu.TotalSens[iVal]; }
203
204 /*!
205 * \brief Get the total sensitivity for the structural density
206 * \return Value of the structural density sensitivity
207 */
208 inline su2double GetTotal_Sens_Rho(unsigned short iVal) const override { return Rho.TotalSens[iVal]; }
209
210 /*!
211 * \brief Get the total sensitivity for the structural weight
212 * \return Value of the structural weight sensitivity
213 */
214 inline su2double GetTotal_Sens_Rho_DL(unsigned short iVal) const override { return Rho_DL.TotalSens[iVal]; }
215
216 /*!
217 * \brief A virtual member.
218 * \return Value of the sensitivity coefficient for the Electric Field in the region iEField (time averaged)
219 */
220 inline su2double GetTotal_Sens_EField(unsigned short iEField) const override { return EField.TotalSens[iEField]; }
221
222 /*!
223 * \brief A virtual member.
224 * \return Value of the total sensitivity coefficient for the FEA DV in the region iDVFEA (time averaged)
225 */
226 inline su2double GetTotal_Sens_DVFEA(unsigned short iDVFEA) const override { return DV.TotalSens[iDVFEA]; }
227
228 /*!
229 * \brief Get the value of the Young modulus from the adjoint solver
230 * \return Value of the Young modulus from the adjoint solver
231 */
232 inline su2double GetVal_Young(unsigned short iVal) const override { return E[iVal]; }
233
234 /*!
235 * \brief Get the value of the Poisson's ratio from the adjoint solver
236 * \return Value of the Poisson's ratio from the adjoint solver
237 */
238 inline su2double GetVal_Poisson(unsigned short iVal) const override { return Nu[iVal]; }
239
240 /*!
241 * \brief Get the value of the density from the adjoint solver, for inertial effects
242 * \return Value of the density from the adjoint solver
243 */
244 inline su2double GetVal_Rho(unsigned short iVal) const override { return Rho[iVal]; }
245
246 /*!
247 * \brief Get the value of the density from the adjoint solver, for dead loads
248 * \return Value of the density for dead loads, from the adjoint solver
249 */
250 inline su2double GetVal_Rho_DL(unsigned short iVal) const override { return Rho_DL[iVal]; }
251
252 /*!
253 * \brief Get the number of variables for the Electric Field from the adjoint solver
254 * \return Number of electric field variables from the adjoint solver
255 */
256 inline unsigned short GetnEField(void) const override { return nEField; }
257
258 /*!
259 * \brief Get the number of design variables from the adjoint solver,
260 * \return Number of design variables from the adjoint solver
261 */
262 inline unsigned short GetnDVFEA(void) const override { return nDV; }
263
264 /*!
265 * \brief Get the value of the Electric Field from the adjoint solver
266 * \return Pointer to the values of the Electric Field
267 */
268 inline su2double GetVal_EField(unsigned short iVal) const override { return EField[iVal]; }
269
270 /*!
271 * \brief Get the value of the design variables from the adjoint solver
272 * \return Pointer to the values of the design variables
273 */
274 inline su2double GetVal_DVFEA(unsigned short iVal) const override { return DV[iVal]; }
275
276 /*!
277 * \brief Prepare the solver for a new recording.
278 * \param[in] kind_recording - Kind of AD recording.
279 */
280 void SetRecording(CGeometry *geometry, CConfig *config) override ;
281
282 /*!
283 * \brief A virtual member.
284 * \param[in] geometry - Geometrical definition of the problem.
285 * \param[in] config - Definition of the particular problem.
286 * \param[in] reset - If true reset variables to their initial values.
287 */
288 void RegisterVariables(CGeometry *geometry,
289 CConfig *config,
290 bool reset = false) override;
291
292 /*!
293 * \brief A virtual member.
294 * \param[in] geometry - Geometrical definition of the problem.
295 * \param[in] config - Definition of the particular problem.
296 */
297 void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) override;
298
299 /*!
300 * \brief Update the dual-time derivatives.
301 * \param[in] geometry - Geometrical definition of the problem.
302 * \param[in] solver_container - Container vector with all the solutions.
303 * \param[in] config - Definition of the particular problem.
304 * \param[in] iMesh - Index of the mesh in multigrid computations.
305 * \param[in] iRKStep - Current step of the Runge-Kutta iteration.
306 * \param[in] RunTime_EqSystem - System of equations which is going to be solved.
307 * \param[in] Output - boolean to determine whether to print output.
308 */
309 void Preprocessing(CGeometry *geometry,
310 CSolver **solver_container,
311 CConfig *config,
312 unsigned short iMesh,
313 unsigned short iRKStep,
314 unsigned short RunTime_EqSystem,
315 bool Output) override;
316
317 /*!
318 * \brief Load a solution from a restart file.
319 * \param[in] geometry - Geometrical definition of the problem.
320 * \param[in] solver - Container vector with all of the solvers.
321 * \param[in] config - Definition of the particular problem.
322 * \param[in] val_iter - Current external iteration number.
323 * \param[in] val_update_geo - Flag for updating coords and grid velocity.
324 */
325 void LoadRestart(CGeometry **geometry,
326 CSolver ***solver,
327 CConfig *config,
328 int val_iter,
329 bool val_update_geo) override;
330
331};
Headers of the CSolver class which is inherited by all of the other solvers.
static Comm GetComm()
Definition mpi_structure.hpp:530
static void Allreduce(const void *sendbuf, void *recvbuf, int count, Datatype datatype, Op op, Comm comm)
Definition mpi_structure.hpp:570
Main class for defining the problem; basically this class reads the configuration file,...
Definition CConfig.hpp:64
Main class for defining the variables on the FEA boundaries for adjoint applications.
Definition CDiscAdjFEABoundVariable.hpp:40
Main class for defining the discrete adjoint solver for FE structural problems.
Definition CDiscAdjFEASolver.hpp:39
void RegisterSolution(CGeometry *geometry, CConfig *config) override
Performs the preprocessing of the adjoint AD-based solver. Registers all necessary variables on the t...
Definition CDiscAdjFEASolver.cpp:165
void RegisterOutput(CGeometry *geometry, CConfig *config) override
Performs the preprocessing of the adjoint AD-based solver. Registers all necessary variables that are...
Definition CDiscAdjFEASolver.cpp:234
void ExtractAdjoint_Solution(CGeometry *geometry, CConfig *config, bool CrossTerm) override
Sets the adjoint values of the input variables of the flow (+turb.) iteration after tape has been eva...
Definition CDiscAdjFEASolver.cpp:245
su2double GetVal_Young(unsigned short iVal) const override
Get the value of the Young modulus from the adjoint solver.
Definition CDiscAdjFEASolver.hpp:232
su2double GetVal_DVFEA(unsigned short iVal) const override
Get the value of the design variables from the adjoint solver.
Definition CDiscAdjFEASolver.hpp:274
su2double GetTotal_Sens_E(unsigned short iVal) const override
Provide the total Young's modulus sensitivity.
Definition CDiscAdjFEASolver.hpp:196
su2double GetVal_Rho(unsigned short iVal) const override
Get the value of the density from the adjoint solver, for inertial effects.
Definition CDiscAdjFEASolver.hpp:244
void LoadRestart(CGeometry **geometry, CSolver ***solver, CConfig *config, int val_iter, bool val_update_geo) override
Load a solution from a restart file.
Definition CDiscAdjFEASolver.cpp:486
~CDiscAdjFEASolver() override
Destructor of the class.
Definition CDiscAdjFEASolver.cpp:124
su2double GetTotal_Sens_DVFEA(unsigned short iDVFEA) const override
A virtual member.
Definition CDiscAdjFEASolver.hpp:226
void RegisterVariables(CGeometry *geometry, CConfig *config, bool reset=false) override
A virtual member.
Definition CDiscAdjFEASolver.cpp:184
void Preprocessing(CGeometry *geometry, CSolver **solver_container, CConfig *config, unsigned short iMesh, unsigned short iRKStep, unsigned short RunTime_EqSystem, bool Output) override
Update the dual-time derivatives.
Definition CDiscAdjFEASolver.cpp:363
CDiscAdjFEASolver()=default
Constructor of the class.
su2double GetVal_Rho_DL(unsigned short iVal) const override
Get the value of the density from the adjoint solver, for dead loads.
Definition CDiscAdjFEASolver.hpp:250
su2double GetVal_Poisson(unsigned short iVal) const override
Get the value of the Poisson's ratio from the adjoint solver.
Definition CDiscAdjFEASolver.hpp:238
void SetSensitivity(CGeometry *geometry, CConfig *config, CSolver *) override
Extract and set the geometrical sensitivity.
Definition CDiscAdjFEASolver.cpp:373
su2double GetVal_EField(unsigned short iVal) const override
Get the value of the Electric Field from the adjoint solver.
Definition CDiscAdjFEASolver.hpp:268
void ExtractAdjoint_Variables(CGeometry *geometry, CConfig *config) override
A virtual member.
Definition CDiscAdjFEASolver.cpp:302
void SetAdjoint_Output(CGeometry *geometry, CConfig *config) override
Sets the adjoint values of the output of the flow (+turb.) iteration before evaluation of the tape.
Definition CDiscAdjFEASolver.cpp:329
su2double GetTotal_Sens_Rho_DL(unsigned short iVal) const override
Get the total sensitivity for the structural weight.
Definition CDiscAdjFEASolver.hpp:214
unsigned short GetnDVFEA(void) const override
Get the number of design variables from the adjoint solver,.
Definition CDiscAdjFEASolver.hpp:262
su2double GetTotal_Sens_EField(unsigned short iEField) const override
A virtual member.
Definition CDiscAdjFEASolver.hpp:220
void SetRecording(CGeometry *geometry, CConfig *config) override
Prepare the solver for a new recording.
Definition CDiscAdjFEASolver.cpp:126
su2double GetTotal_Sens_Rho(unsigned short iVal) const override
Get the total sensitivity for the structural density.
Definition CDiscAdjFEASolver.hpp:208
unsigned short GetnEField(void) const override
Get the number of variables for the Electric Field from the adjoint solver.
Definition CDiscAdjFEASolver.hpp:256
su2double GetTotal_Sens_Nu(unsigned short iVal) const override
Set the total Poisson's ratio sensitivity.
Definition CDiscAdjFEASolver.hpp:202
Parent class for defining the geometry of the problem (complete geometry, multigrid agglomerated geom...
Definition CGeometry.hpp:75
Definition CSolver.hpp:71
Main class for defining the variables.
Definition CVariable.hpp:50
passivedouble su2double
Definition code_config.hpp:181
#define MPI_SUM
Definition mpi_structure.hpp:486
#define MPI_DOUBLE
Definition mpi_structure.hpp:484
void RegisterInput(su2double &data)
Registers the variable as an input. I.e. as a leaf of the computational graph.
Definition ad_structure.hpp:101
passivedouble GetDerivative(const su2double &data)
Get the derivative value of the datatype (needs to be implemented for each new type).
Definition datatype_structure.hpp:117