-
Notifications
You must be signed in to change notification settings - Fork 0
/
lecsm.hpp
397 lines (337 loc) · 12.3 KB
/
lecsm.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
386
387
388
389
390
391
392
393
394
395
396
397
/**
* \file lecsm.hpp
* \brief LECSM solver header file
* \author Alp Dener <[email protected]>
* \version 1.0
*/
#pragma once
#include <vector>
#include "./1D_mesh_tools.hpp"
#include "../Quasi1DEuler/inner_prod_vector.hpp"
#include "../krylov.hpp"
using namespace std;
// =====================================================================
/*!
* \class LECSM
* \brief 2D linear elastic computational structural analysis solver
*/
class LECSM {
public:
/*
* \brief empty constructor
*/
LECSM() {}
/*!
* \brief class constructor
* \param[in] nnp - number of nodes in the domain
* \param[in] x - vector of x coordinates
* \param[in] y - vector of y coordinates
*/
LECSM(int nnp) :
area_(nnp, 0.0),
xCoords_(nnp, 0.0),
yCoords_(nnp, 0.0),
res_(3*nnp, 0.0),
u_(3*nnp, 0.0),
P_(nnp, 0.0) { nnp_ = nnp; }
/*!
* \brief default destructor
*/
~LECSM() {}
/*!
* \brief returns a vector x coordinates for each node
* \returns xCoords_ member value
*/
InnerProdVector & get_x() { return xCoords_; }
/*!
* \brief returns a vector y coordinates for each node
* \returns yCoords_ member value
*/
InnerProdVector & get_y() { return yCoords_; }
/*!
* \brief returns a vector areas at each node
* \returns area_ member value
*/
InnerProdVector & get_area() { return area_; }
/*!
* \brief returns the CSM residual vector
* \returns res_ member value
*/
InnerProdVector & get_res() { return res_; }
/*!
* \brief returns the CSM displacement vector
* \returns u_ member value
*/
InnerProdVector & get_u() { return u_; }
/*!
* \brief sets the material properties for the CSM solver
* \param[in] E - young's modulus
* \param[in] t - 2D beam thickness
* \param[in] w - nozzle fixed width
* \param[in] h - nozzle max height (at y_coord = 0)
*/
void set_material(double E, double t, double w, double h) {
E_ = E; t_ = t; w_ = w; h_ = h;}
/*!
* \brief updates the CSM mesh with displacements
* \param[in] u_csm - vector of displacements (3*nnp)
*/
void set_u(const InnerProdVector & u_csm) { u_ = u_csm; }
/*!
* \brief sets the pressure values at each node
* \param[in] press - vector of pressure values (nnp)
*/
void set_press(const InnerProdVector & press) { P_ = press; }
/*!
* \brief generates the initial problem mesh
* \param[in] x - vector of node x coordinates
* \param[in] y - vector of node y coordinates
*/
void GenerateMesh(const InnerProdVector & x, const InnerProdVector & y);
/*!
* \brief resets the solver coordinates to the nodal coordinates of the geometry
*/
void ResetCoords();
/*!
* \brief sets the solver coordinates to the given x and y vectors
*/
void set_coords(const InnerProdVector & x, const InnerProdVector & y);
/*!
* \brief updates the geometry with the coordinates stored in the solver
*/
void UpdateMesh();
/*!
* \brief set the nodal boundary conditions (displacements and forcing)
* \param[in] BCtype - type of BC (displacement or forcing)
* \param[in] BYval - value of BC
*/
void SetBoundaryConds(const InnerProdVector & BCtype, const InnerProdVector & BCval);
/*!
* \brief initializes the global vectors used in the solver
* \param[out] G - global prescribed displacements vector
* \param[out] F - global prescribed nodal forcing
*/
void InitGlobalVecs(vector<double>& G, vector<double>& F);
/*!
* \brief calculates the global stiffness matrix and associated vectors
* \param[in] gm - global equation number mapping
* \param[out] G - global prescribed displacements vector
* \param[out] F - global prescribed nodal forcing
* \param[out] K - global stiffness matrix
*/
void GetStiff(vector< vector< vector<int> > >& gm,
vector<double>& G, vector<double>& F,
vector< vector<double> >& K);
/*!
* \brief calculates stiffness matrix and rhs vectors for arbitrary types
* \param[in] x - nodal x coordinates (assumes linear elements!!!)
* \param[in] y - nodal y coordinates (assumes linear elements!!!)
* \param[in] gm - global equation number mapping
* \param[out] G - global prescribed displacements vector
* \param[out] F - global prescribed nodal forcing
* \param[out] K - global stiffness matrix
*/
template <typename type>
void GetStiff(const vector<type>& x, const vector<type>& y,
vector< vector< vector<int> > >& gm,
vector<type>& G, vector<type>& F,
vector< vector<type> >& K);
/*!
* \brief preconditions the input vector with the diagonal of the system stiffness matrix
* \param[in] in - un-preconditioned vector
* \param[out] v_csm - preconditioned vector
*/
void Precondition(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief calculates the (dS/du)*vector product
* \param[in] in - multiplied vector (3*num_nodes)
* \param[out] out - resultant vector (3*num_nodes)
*/
void Calc_dSdu_Product(const InnerProdVector& in, InnerProdVector& out);
/*!
* \brief calculates the (dA/du)*vector product
* \param[in] in - multiplied vector (3*num_nodes)
* \param[out] out - resultant vector (num_nodes)
*/
void Calc_dAdu_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief calculates the [(dA/du)^T]*vector product
* \param[in] in - multiplied vector (num_nodes)
* \param[out] out - resultant vector (3*num_nodes)
*/
void CalcTrans_dAdu_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief calculates the (dy/dA)*vector product
* \param[in] in - multiplied vector (num_nodes)
* \param[out] out - resultant vector (num_nodes)
*/
void Calc_dydA_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief product for FD derivative residual w.r.t nodal coordinates
* \param[in] in - multiplied vector (num_nodes)
* \param[out] out - resultant vector (3*num_nodes)
*/
void CalcFD_dSdy_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief directional deriviative of residual with respect to y coordinates
* \param[in] in - multiplied vector (num_nodes)
* \param[out] out - resultant vector (3*num_nodes)
*/
void CalcCmplx_dSdy_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief transpose product for FD derivative residual w.r.t nodal coordinates
* \param[in] in - multiplied vector (num_nodes)
* \param[out] out - resultant vector (num_nodes)
*/
void CalcTransFD_dSdy_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief transpose product for FD derivative residual w.r.t nodal coordinates
* \param[in] in - multiplied vector (num_nodes)
* \param[out] out - resultant vector (num_nodes)
*/
void CalcTransCmplx_dSdy_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief calculates the (dS/dp)*vector product
* \param[in] in - multiplied vector (num_nodes)
* \param[out] out - resultant vector (3*num_nodes)
*/
void Calc_dSdp_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief calculates the [(dS/dp)^T]*vector product
* \param[in] in - multiplied vector (3*num_nodes)
* \param[out] out - resultant vector (num_nodes)
*/
void CalcTrans_dSdp_Product(InnerProdVector& in, InnerProdVector& out);
/*!
* \brief calculates the displaced coordinates and nozzle area
*/
void CalcCoordsAndArea();
/*!
* \brief calculates the CSM residual based on displacements in u_
*/
void CalcResidual();
/*!
* \brief calculates the CSM residual based on displacements in u_
* \param[in] x - vector of nodal x coordinates
* \param[in] y - vector of nodal y coordinates
* \param[out] res - CSM residual, Ku - f
*/
template <typename type>
void CalcResidual(const vector<type>& x, const vector<type>& y,
vector<type>& res);
/*!
* \brief inspects the solver mesh
*/
void InspectMesh() {
geom_.InspectElements();
}
/*!
* \brief solves the CSM problem for a given forcing vector using MINRES
* \param[in] rhs - prescribed right-hand-side vector for the system
* \param[in] max_iter - maximum number of iterations permitted
* \param[in] tol - relative residual tolerance desired
* \result nodal displacements are calculated and saved to u_
* \returns number of matrix-vector products
*/
int SolveFor(InnerProdVector & rhs, const int & max_iter = 1000,
const double & tol = 1e-6);
/*!
* \brief independent solution of a CSM problem using conjugate gradient
*/
void Solve(bool info=false);
/*!
* \brief vector product with the diagonal terms of the stiffness matrix
* \param[in] in - multiplied vector (3*num_nodes)
* \param[out] out - resultant vector (3*num_nodes)
*/
void StiffDiagProduct(const InnerProdVector & in, InnerProdVector & out);
private:
InnerProdVector area_;
InnerProdVector xCoords_;
InnerProdVector yCoords_;
InnerProdVector res_;
InnerProdVector u_;
InnerProdVector P_;
vector< vector<double> > K_;
int nnp_;
double E_, w_, t_, h_;
Mesh geom_;
};
// ======================================================================
/*!
* \class StiffnessVectorProduct
* \brief specialization of matrix-vector product for lecsm
*/
class StiffnessVectorProduct :
public kona::MatrixVectorProduct<InnerProdVector> {
public:
/*!
* \brief default constructor
* \param[in] solver - a linear elasticity solver (defines product)
* \param[in] geom - 1D Mesh object corresponding to solver
*/
StiffnessVectorProduct(LECSM& solver, Mesh& geom);
~StiffnessVectorProduct() {} ///< class destructor
/*!
* \brief operator that defines the Stiffness-Matrix-Vector product
* \param[in] u - vector that is being multiplied by K
* \param[out] v - vector that is the result of the product
*/
void operator()(const InnerProdVector & u, InnerProdVector & v);
private:
int nnp_; // number of nodes in mesh
int ndof_; // number of degrees of freedom (size of matrix)
vector< vector< vector<int> > > gm_; // global equation number mapping
vector< vector<double> > K_; // stiffness matrix
vector<double> u_dof_; // used to store reduced (dof only) input vector
vector<double> v_dof_; // used to store reduced (dof only) output vector
};
// ======================================================================
/*!
* \class DiagonalPrecond
* \brief specialization of preconditioner for lecsm
*/
class DiagonalPrecond :
public kona::Preconditioner<InnerProdVector> {
public:
/*!
* \brief default constructor
* \param[in] solver - a linear elasticity solver (defines product)
* \param[in] geom - 1D Mesh object corresponding to solver
*/
DiagonalPrecond(LECSM& solver, Mesh& geom);
~DiagonalPrecond() {} ///< class destructor
void operator()(InnerProdVector & u, InnerProdVector & v);
private:
int nnp_; // number of nodes in mesh
int ndof_; // number of degrees of freedom (size of matrix)
vector< vector< vector<int> > > gm_; // global equation number mapping
vector<double> Kdiag_; // stiffness matrix diagonal
vector<double> u_dof_; // used to store reduced (dof only) input vector
vector<double> v_dof_; // used to store reduced (dof only) output vector
};
// ======================================================================
/*!
* \class GaussSeidelPrecond
* \brief specialization of preconditioner for lecsm
*/
class GaussSeidelPrecond :
public kona::Preconditioner<InnerProdVector> {
public:
/*!
* \brief default constructor
* \param[in] solver - a linear elasticity solver (defines product)
* \param[in] geom - 1D Mesh object corresponding to solver
*/
GaussSeidelPrecond(LECSM& solver, Mesh& geom);
~GaussSeidelPrecond() {} ///< class destructor
void operator()(InnerProdVector & u, InnerProdVector & v);
private:
int nnp_; // number of nodes in mesh
int ndof_; // number of degrees of freedom (size of matrix)
int max_iters_;
vector< vector< vector<int> > > gm_; // global equation number mapping
vector< vector<double> > K_; // stiffness matrix
vector<double> u_dof_; // used to store reduced (dof only) input vector
vector<double> v_dof_; // used to store reduced (dof only) output vector
};