-
Notifications
You must be signed in to change notification settings - Fork 0
/
aerostruct.hpp
385 lines (311 loc) · 10.9 KB
/
aerostruct.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
/**
* \file aerostruct.hpp
* \brief header file for AeroStruct
* \author Jason Hicken <[email protected]>, Alp Dener <[email protected]>
* \version 1.0
*/
#pragma once
#include <math.h>
#include <ostream>
#include <iostream>
#include <fstream>
#include <string>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include "./Quasi1DEuler/nozzle.hpp"
#include "./Quasi1DEuler/inner_prod_vector.hpp"
#include "./Quasi1DEuler/quasi_1d_euler.hpp"
#include "./Quasi1DEuler/exact_solution.hpp"
#include "./LECSM/lecsm.hpp"
#include "./constants.hpp"
#include "./krylov.hpp"
// forward declarations
class AeroStructProduct;
class AeroStructTransposeProduct;
class AeroStructPrecond;
class AeroStructTransposePrecond;
// ======================================================================
/*!
* \class AeroStructMDA
* \brief defines a coupled aero-structural system
*/
class AeroStructMDA {
public:
/*!
* \brief empty constructor
*/
AeroStructMDA() {}
/*!
* \brief default constructor
* \param[in] euler_solver - a Quasi1DEuler solver (defines product)
*/
AeroStructMDA(int num_nodes, int order):
u_(6*num_nodes,0.0),
v_(6*num_nodes,0.0),
cfd_(num_nodes, order),
csm_(num_nodes) {
num_nodes_ = num_nodes;
order_ = order;
scale_cfd_ = 1.0;
scale_csm_ = 1.0;
}
/*!
* \brief alternative class constructor for geometries defined by a Bspline
* \param[in] num_nodes - number of nodes
* \param[in] order - order of accuracy of CFD solver
* \param[in] nozzle - BsplineNozzle the defines the area
*/
AeroStructMDA(int num_nodes, int order, Nozzle & nozzle):
u_(6*num_nodes,0.0),
v_(6*num_nodes,0.0),
cfd_(num_nodes, order),
csm_(num_nodes) {
num_nodes_ = num_nodes;
order_ = order;
scale_cfd_ = 1.0;
scale_csm_ = 1.0;
nozzle_ = &nozzle;
}
~AeroStructMDA() {} ///< class destructor
/*!
* \brief extract the MDA solution vector
*/
InnerProdVector & get_u() { return u_; }
/*!
* \brief extract the MDA residual vector
*/
InnerProdVector & get_res() { return v_; }
/*!
* \brief define the MDA solution vector
*/
void set_u(const InnerProdVector & u_new) { u_ = u_new; }
/*!
* \brief extract the pressure from the cfd solver
*/
const InnerProdVector & get_press() { return cfd_.get_press(); }
/*!
* \brief uses the MDA state in u_ to update the cfd and csm states
*/
void UpdateDisciplineStates();
/*!
* \brief defines the target pressure based on current pressure in cfd_
*/
void CopyPressIntoTarget() { cfd_.set_press_targ(cfd_.get_press()); }
/*!
* \brief set the CFD and CSM initial condition for an NK MDA solve
*/
void SetInitialCondition();
/*!
* \brief set the CFD and CSM initial condition for an NK MDA solve
*/
void SetInitialConditionIntoVec(InnerProdVector & vec);
/*!
* \brief updates the discipline geometries based on the MDA nozzle object
*/
void UpdateFromNozzle();
/*!
* \brief defines a sample Bspline-free MDA test problem
*/
void InitializeTestProb();
/*!
* \brief tests grid-dependence on the aero-structural solution
*/
void GridTest();
/*!
* \brief sets up the CFD solver for the MDA evaluation
*/
void InitializeCFD(const InnerProdVector & x_coords,
const InnerProdVector & area);
/*!
* \brief sets up the CSM solver for the MDA evaluation
*/
void InitializeCSM(const InnerProdVector & x_coords,
const InnerProdVector & y_coords,
const InnerProdVector & BCtype,
const InnerProdVector & BCval,
double E, double t, double w, double h);
/*!
* \brief calculate the system residual vector
* \result residual based on u_ is calculated and stored in v_
*/
void CalcResidual();
/*!
* \brief sets the equation scaling based on the residual res
* \param[in] res - nonlinear MDA equation residual
*/
void CalcRowScaling(const InnerProdVector & res);
/*!
* \brief applies scaling to the cfd and csm components of u
* \param[in,out] u - vector to be scaled
*/
void ScaleVector(InnerProdVector & u);
void BuildAndFactorPreconditioner();
/*!
* \brief solves the aero-structural system with a Newton Krylow algorithm
* \param[in] max_iter - maximum number of iterations permitted
* \param[in] tol - tolerance with which to solve the system
* \returns - total number of preconditioner calls
*/
int NewtonKrylov(const int & max_iter, const double & tol, bool info=false);
/*!
* \brief solves for the linearized aero-structural problem
* \param[in] max_iter - maximum number of iterations permitted
* \param[in] tol - tolerance with which to solve the system
* \param[in] rhs - the rhs of the linearized system
* \param[out] sol - the solution vector
* \returns total number of preconditioner calls
*/
int SolveLinearized(const int & max_iter, const double & tol,
const InnerProdVector & rhs,
InnerProdVector & sol);
/*!
* \brief solves for the coupled adjoint variables using a Krylov solver
* \param[in] max_iter - maximum number of iterations permitted
* \param[in] tol - tolerance with which to solve the system
* \param[in] dJdu - the rhs of the adjoint linear system
* \param[out] psi - the adjoint solution vector
* \returns total number of preconditioner calls
*/
int SolveAdjoint(const int & max_iter, const double & tol,
const InnerProdVector & dJdu,
InnerProdVector & psi);
/*!
* \brief tests the AeroStructProduct using a finite-difference approximation
* \pre the state defined in u_ must be "reasonable"
*/
void TestMDAProduct();
/*!
* \brief tests the AeroStructTransposeProduct
* \pre the state defined in u_ must be "reasonable"
*/
void TestMDATransposedProduct();
/*!
* \brief prints out nodal displacements of the system design
*/
void PrintDisplacements();
/*!
* \brief generates a .dat file for the solution, to be plotted with plot_nozzle.py
* \pre must have solved, final nodal areas assigned to the CFD solver
*/
void GetTecplot(const double & rho_ref, const double & a_ref,
const string & filename = "quasi1d.dat")
{ cfd_.WriteTecplot(rho_ref, a_ref, filename); }
// ======================================================================
// OPTIMIZATION ROUTINES
// ======================================================================
/*!
* \brief sets the number of Bspline design variables for the nozzle
*/
void SetDesignVars(int num) { num_design_ = num; }
/*!
* \brief calculates (dR/dB)*vector product
* \param[in] in - multiplied vector (num_design_)
* \param[out] out - resultant vector (6*num_nodes_)
*/
void Calc_dRdB_Product(InnerProdVector & in, InnerProdVector & out);
/*!
* \brief calculates (dR/dB)^T *vector product
* \param[in] in - multiplied vector (6*num_nodes)
* \param[out] out - resultant vector (num_design_)
*/
void CalcTrans_dRdB_Product(InnerProdVector & in, InnerProdVector & out);
/*!
* \brief calculates (dS/dB)*vector product
* \param[in] in - multiplied vector (num_design_)
* \param[out] out - resultant vector (6*num_nodes_)
*/
void Calc_dSdB_Product(InnerProdVector & in, InnerProdVector & out);
/*!
* \brief calculates (dS/dB)^T *vector product
* \param[in] in - multiplied vector (6*num_nodes_)
* \param[out] out - resultant vector (num_design_)
*/
void CalcTrans_dSdB_Product(InnerProdVector & in, InnerProdVector & out);
/*!
* \brief calculates [dR/dB; dSdB]*vector product
* \param[in] in - multiplied vector (num_design_)
* \param[out] out - resultant vector (6*num_nodes_)
*/
void AeroStructDesignProduct(InnerProdVector & in, InnerProdVector & out);
/*!
* \brief calculates [dR/dB; dSdB]^T *vector product
* \param[in] in - multiplied vector (6*num_nodes_)
* \param[out] out - resultant vector (num_design_)
*/
void AeroStructDesignTransProduct(InnerProdVector & in, InnerProdVector & out);
double CalcInverseDesign();
void CalcInverseDesigndJdQ(InnerProdVector & dJdQ);
// ======================================================================
private:
Nozzle* nozzle_; ///< used to define problem and access Nozzle routines
Quasi1DEuler cfd_; ///< used to access quasi_1d_euler matvec routines
LECSM csm_; ///< used to access linear_elastic_csm routines
double scale_cfd_; ///< used to scale linearized cfd equations
double scale_csm_; ///< used to scale linearized csm equations
double l_, h_, w_; ///< geometric domain length, height and width
double E_, t_; ///< material properties
InnerProdVector u_; ///< MDA solution vector
InnerProdVector v_; ///< MDA residual vector
int num_nodes_, order_, num_design_; ///< MDA discretization properties
double p_ref_; ///< reference pressure for dimensionalization
friend class AeroStructProduct;
friend class AeroStructTransposeProduct;
friend class AeroStructPrecond;
friend class AeroStructTransposePrecond;
};
// ======================================================================
/*!
* \class AeroStructProduct
* \brief specialization of matrix-vector product for AeroStruct
*/
class AeroStructProduct:
public kona::MatrixVectorProduct<InnerProdVector> {
public:
AeroStructProduct(AeroStructMDA * mda) { mda_ = mda; }
~AeroStructProduct() {}
void operator()(const InnerProdVector & u, InnerProdVector & v);
private:
AeroStructMDA * mda_;
};
// ======================================================================
/*!
* \class AeroStructTransposeProduct
* \brief specialization of matrix-vector product for AeroStruct
*/
class AeroStructTransposeProduct:
public kona::MatrixVectorProduct<InnerProdVector> {
public:
AeroStructTransposeProduct(AeroStructMDA * mda) { mda_ = mda; }
~AeroStructTransposeProduct() {}
void operator()(const InnerProdVector & u, InnerProdVector & v);
private:
AeroStructMDA * mda_;
};
// ======================================================================
/*!
* \class AeroStructPrecond
* \brief specialization of matrix-vector product for AeroStruct
*/
class AeroStructPrecond:
public kona::Preconditioner<InnerProdVector> {
public:
AeroStructPrecond(AeroStructMDA * mda) { mda_ = mda; }
~AeroStructPrecond() {}
void operator()(InnerProdVector & u, InnerProdVector & v);
private:
AeroStructMDA * mda_;
};
// ======================================================================
/*!
* \class AeroStructTransposePrecond
* \brief specialization of matrix-vector product for AeroStruct
*/
class AeroStructTransposePrecond:
public kona::Preconditioner<InnerProdVector> {
public:
AeroStructTransposePrecond(AeroStructMDA * mda) { mda_ = mda; }
~AeroStructTransposePrecond() {}
void operator()(InnerProdVector & u, InnerProdVector & v);
private:
AeroStructMDA * mda_;
};