v0.16.0
Loading...
Searching...
No Matches
ArcLengthTools.hpp
Go to the documentation of this file.
1/** \file ArcLengthTools.cpp
2 * \ingroup arc_length_control
3 *
4 * Implementation of arc-length control method
5 *
6 * FIXME: Some variables not comply with naming convention, need to be fixed.
7 *
8 */
9
10#ifndef __ARC_LENGTH_TOOLS_HPP__
11 #define __ARC_LENGTH_TOOLS_HPP__
12
13/**
14 * \brief Store variables for ArcLength analysis
15 *
16 * \ingroup arc_length_control
17
18 The constrain function if given by
19 \f[
20 r_\lambda = f_\lambda(\mathbf{x},\lambda) - s^2
21 \f]
22 where \f$f_\lambda(\mathbf{x},\lambda)\f$ is some constrain function, which has
23 general form given by
24 \f[
25 f_\lambda(\mathbf{x},\lambda) = \alpha f(\Delta\mathbf{x}) +
26 \beta^2 \Delta\lambda^2 \| \mathbf{F}_{\lambda} \|^2
27 \f]
28 where for example \f$f(\mathbf{x})=\|\Delta\mathbf{x}\|^2\f$ is some user
29 defined
30 function evaluating
31 increments vector of degrees of freedom \f$\Delta\mathbf{x}\f$. The increment
32 vector is
33 \f[
34 \Delta \mathbf{x} = \mathbf{x}-\mathbf{x}_0
35 \f]
36 and
37 \f[
38 \Delta \lambda = \lambda-\lambda_0.
39 \f]
40
41 For convenience we assume that
42 \f[
43 \frac{\partial f}{\partial \mathbf{x}}\Delta \mathbf{x}
44 =
45 \textrm{d}\mathbf{b} \Delta \mathbf{x},
46 \f]
47 as result linearised constrain equation takes form
48 \f[
49 \textrm{d}\mathbf{b} \delta \Delta x +
50 D \delta \Delta\lambda - r_{\lambda} = 0
51 \f]
52 where
53 \f[
54 D = 2\beta^2 \Delta\lambda \| \mathbf{F}_{\lambda} \|^2.
55 \f]
56
57 User need to implement functions calculating \f$f(\mathbf{x},\lambda)\f$, i.e.
58 function
59 \f$f(\|\Delta\mathbf{x}\|^2)\f$ and its derivative,
60 \f$\textrm{d}\mathbf{b}\f$.
61
62 */
64
65 virtual ~ArcLengthCtx() = default;
66
68
69 double s; ///< arc length radius
70 double beta; ///< force scaling factor
71 double alpha; ///< displacement scaling factor
72
73 SmartPetscObj<Vec> ghosTdLambda;
74 double dLambda; ///< increment of load factor
75 SmartPetscObj<Vec> ghostDiag;
76 double dIag; ///< diagonal value
77
78 double dx2; ///< inner_prod(dX,dX)
79 double F_lambda2; ///< inner_prod(F_lambda,F_lambda);
80 double res_lambda; ///< f_lambda - s
81 SmartPetscObj<Vec> F_lambda; ///< F_lambda reference load vector
82 SmartPetscObj<Vec>
83 db; ///< db derivative of f(dx*dx), i.e. db = d[ f(dx*dx) ]/dx
84 SmartPetscObj<Vec> xLambda; ///< solution of eq. K*xLambda = F_lambda
85 SmartPetscObj<Vec> x0; ///< displacement vector at beginning of step
86 SmartPetscObj<Vec> dx; ///< dx = x-x0
87
88 /**
89 * \brief set arc radius
90 */
91 MoFEMErrorCode setS(double s);
92
93 /**
94 * \brief set parameters controlling arc-length equations
95 * alpha controls off diagonal therms
96 * beta controls diagonal therm
97 */
98 MoFEMErrorCode setAlphaBeta(double alpha, double beta);
99
100 ArcLengthCtx(MoFEM::Interface &m_field, const std::string &problem_name,
101 const std::string &field_name = "LAMBDA");
102
103 /** \brief Get global index of load factor
104 */
106 return arcDofRawPtr->getPetscGlobalDofIdx();
107 };
108
109 /** \brief Get local index of load factor
110 */
111 DofIdx getPetscLocalDofIdx() { return arcDofRawPtr->getPetscLocalDofIdx(); };
112
113 /** \brief Get value of load factor
114 */
115 FieldData &getFieldData() { return arcDofRawPtr->getFieldData(); }
116
117 /** \brief Get proc owning lambda dof
118 */
119 int getPart() { return arcDofRawPtr->getPart(); };
120
121private:
122 NumeredDofEntity *arcDofRawPtr;
123};
124
125 #ifdef __SNESCTX_HPP__
126
127/**
128 * \brief It is ctx structure passed to SNES solver
129 * \ingroup arc_length_control
130 */
131struct ArcLengthSnesCtx : public SnesCtx {
132 ArcLengthCtx *arcPtrRaw;
133
134 ArcLengthSnesCtx(MoFEM::Interface &m_field, const std::string &problem_name,
135 ArcLengthCtx *arc_ptr_raw)
136 : SnesCtx(m_field, problem_name), arcPtrRaw(arc_ptr_raw) {}
137
138 ArcLengthSnesCtx(MoFEM::Interface &m_field, const std::string &problem_name,
139 boost::shared_ptr<ArcLengthCtx> arc_ptr)
140 : SnesCtx(m_field, problem_name), arcPtrRaw(arc_ptr.get()),
141 arcPtr(arc_ptr) {}
142
143private:
144 boost::shared_ptr<ArcLengthCtx> arcPtr;
145};
146
147 #endif //__SNESCTX_HPP__
148
149 #ifdef __TSCTX_HPP__
150
151/**
152 * \brief It is ctx structure passed to SNES solver
153 * \ingroup arc_length_control
154 */
155struct ArcLengthTsCtx : public TsCtx {
156 ArcLengthCtx *arcPtrRaw;
157
158 /// \deprecated use constructor with shared ptr
159 DEPRECATED ArcLengthTsCtx(MoFEM::Interface &m_field,
160 const std::string &problem_name,
161 ArcLengthCtx *arc_ptr_raw)
162 : TsCtx(m_field, problem_name), arcPtrRaw(arc_ptr_raw) {}
163
164 ArcLengthTsCtx(MoFEM::Interface &m_field, const std::string &problem_name,
165 boost::shared_ptr<ArcLengthCtx> arc_ptr)
166 : TsCtx(m_field, problem_name), arcPtrRaw(arc_ptr.get()),
167 arcPtr(arc_ptr) {}
168
169private:
170 boost::shared_ptr<ArcLengthCtx> arcPtr;
171};
172
173 #endif // __TSCTX_HPP__
174
175/** \brief shell matrix for arc-length method
176 *
177 * \ingroup arc_length_control
178
179 Shell matrix which has structure:
180 \f[
181 \left[
182 \begin{array}{cc}
183 \mathbf{K} & -\mathbf{F}_\lambda \\
184 \textrm{d}\mathbf{b} & D
185 \end{array}
186 \right]
187 \left\{
188 \begin{array}{c}
189 \delta \Delta \mathbf{x} \\
190 \delta \Delta \lambda
191 \end{array}
192 \right\}
193 =
194 \left[
195 \begin{array}{c}
196 -\mathbf{f}_\textrm{int} \\
197 -r_\lambda
198 \end{array}
199 \right]
200 \f]
201
202 */
204
205 SmartPetscObj<Mat> Aij;
207 ArcLengthCtx *arcPtrRaw; // this is for back compatibility
208
209 ArcLengthMatShell(Mat aij, boost::shared_ptr<ArcLengthCtx> arc_ptr,
210 string problem_name);
211 virtual ~ArcLengthMatShell() = default;
212
213 /// \deprecated use constructor with shared_ptr
214 DEPRECATED ArcLengthMatShell(Mat aij, ArcLengthCtx *arc_ptr_raw,
215 string problem_name);
216
217 MoFEMErrorCode setLambda(Vec ksp_x, double *lambda, ScatterMode scattermode);
218 friend MoFEMErrorCode ArcLengthMatMultShellOp(Mat A, Vec x, Vec f);
219
220private:
221 boost::shared_ptr<ArcLengthCtx> arcPtr;
222};
223
224/**
225 * mult operator for Arc Length Shell Mat
226 */
227MoFEMErrorCode ArcLengthMatMultShellOp(Mat A, Vec x, Vec f);
228
229/**
230 * \brief structure for Arc Length pre-conditioner
231 * \ingroup arc_length_control
232 */
234
235 SmartPetscObj<KSP> kSP;
236 SmartPetscObj<PC> pC;
237 SmartPetscObj<Mat> shellAij;
238 SmartPetscObj<Mat> Aij;
239
240 PCArcLengthCtx(Mat shell_Aij, Mat aij,
241 boost::shared_ptr<ArcLengthCtx> arc_ptr);
242
243 PCArcLengthCtx(PC pc, Mat shell_Aij, Mat aij,
244 boost::shared_ptr<ArcLengthCtx> arc_ptr);
245
246 ArcLengthCtx *arcPtrRaw; // this is for back compatibility
247
248 /// \deprecated use with shared_ptr
249 DEPRECATED PCArcLengthCtx(Mat shell_Aij, Mat aij, ArcLengthCtx *arc_ptr_raw);
250 /// \deprecated use with shared_ptr
251 DEPRECATED PCArcLengthCtx(PC pc, Mat shell_Aij, Mat aij,
252 ArcLengthCtx *arc_ptr_raw);
253
254 friend MoFEMErrorCode PCApplyArcLength(PC pc, Vec pc_f, Vec pc_x);
255 friend MoFEMErrorCode PCSetupArcLength(PC pc);
256
257private:
258 boost::shared_ptr<ArcLengthCtx> arcPtr;
259};
260
261/**
262 * apply operator for Arc Length pre-conditioner
263 * solves K*pc_x = pc_f
264 * solves K*xLambda = -dF_lambda
265 * solves ddlambda = ( res_lambda - db*xLambda )/( diag + db*pc_x )
266 * calculate pc_x = pc_x + ddlambda*xLambda
267 */
268MoFEMErrorCode PCApplyArcLength(PC pc, Vec pc_f, Vec pc_x);
269
270/**
271 * set up structure for Arc Length pre-conditioner
272
273 * it sets pre-conditioner for matrix K
274 */
275MoFEMErrorCode PCSetupArcLength(PC pc);
276
277/**
278 * \brief Zero F_lambda
279 *
280 */
281struct ZeroFLmabda : public FEMethod {
282
283 boost::shared_ptr<ArcLengthCtx> arcPtr;
284
285 ZeroFLmabda(boost::shared_ptr<ArcLengthCtx> arc_ptr);
286
287 MoFEMErrorCode preProcess();
288};
289
290 #ifdef __DIRICHLET_HPP__
291
292/**
293 * \brief Assemble F_lambda into the right hand side
294 *
295 * postProcess - assembly F_lambda
296 *
297 */
298struct AssembleFlambda : public FEMethod {
299
300 boost::shared_ptr<ArcLengthCtx> arcPtr;
301
302 AssembleFlambda(boost::shared_ptr<ArcLengthCtx> arc_ptr,
303 boost::shared_ptr<DirichletDisplacementBc> bc =
304 boost::shared_ptr<DirichletDisplacementBc>());
305
306 MoFEMErrorCode preProcess();
307 MoFEMErrorCode operator()();
308 MoFEMErrorCode postProcess();
309
310 inline void pushDirichletBC(boost::shared_ptr<DirichletDisplacementBc> bc) {
311 bCs.push_back(bc);
312 }
313
314private:
315 std::vector<boost::shared_ptr<DirichletDisplacementBc>> bCs;
316};
317
318 #endif
319
320/**
321 * |brief Simple arc-length control of force
322 *
323 * This is added for testing, it simply control force, i.e.
324 *
325 * \f[
326 * \lambda = s
327 * \f]
328 *
329 * Constructor takes one argument,
330 * @param arc_ptr Pointer to arc-length CTX.
331 */
333
334 boost::shared_ptr<ArcLengthCtx> arcPtr;
335 const bool aSsemble;
336
337 SimpleArcLengthControl(boost::shared_ptr<ArcLengthCtx> &arc_ptr,
338 const bool assemble = false);
340
341 MoFEMErrorCode preProcess();
342 MoFEMErrorCode operator()();
343 MoFEMErrorCode postProcess();
344
345 /** \brief Calculate internal lambda
346 */
347 double calculateLambdaInt();
348
349 /** \brief Calculate db
350 */
351 MoFEMErrorCode calculateDb();
352
353 MoFEMErrorCode calculateDxAndDlambda(Vec x);
354};
355
356/** \brief Implementation of spherical arc-length method
357 * \ingroup arc_length_control
358
359 \f[
360 \alpha \| \Delta\mathbf{x} \|^2
361 + \Delta\lambda^2 \beta^2 \| \mathbf{F}_\lambda \|^2
362 = s^2
363 \f]
364
365 This is particular implementation of ArcLength control, i.e. spherical arc
366 length control. If beta is set to 0 and alpha is non-zero it is cylindrical
367 arc-length control. Works well with general problem with non-linear
368 geometry. It not guarantee dissipative loading path in case of physical
369 nonlinearities.
370
371 */
373
374 ArcLengthCtx *arcPtrRaw; // this is for back compatibility
375
376 /// \deprecated use constructor with shared_ptr
378
379 SphericalArcLengthControl(boost::shared_ptr<ArcLengthCtx> &arc_ptr);
381
382 MoFEMErrorCode preProcess();
383 MoFEMErrorCode operator()();
384 MoFEMErrorCode postProcess();
385
386 /** \brief Calculate f_lambda(dx,lambda)
387
388 \f[
389 f_\lambda(\Delta\mathbf{x},\lambda) =
390 \alpha \| \Delta\mathbf{x} \|^2
391 + \Delta\lambda^2 \beta^2 \| \mathbf{F}_\lambda \|^2
392 \f]
393
394 */
395 virtual double calculateLambdaInt();
396
397 /** \brief Calculate db
398
399 \f[
400 \textrm{d}\mathbf{b} = 2 \alpha \Delta\mathbf{x}
401 \f]
402
403 */
404 virtual MoFEMErrorCode calculateDb();
405 virtual MoFEMErrorCode calculateDxAndDlambda(Vec x);
406 virtual MoFEMErrorCode calculateInitDlambda(double *dlambda);
407 virtual MoFEMErrorCode setDlambdaToX(Vec x, double dlambda);
408
409private:
410 boost::shared_ptr<ArcLengthCtx> arcPtr;
411};
412
413#endif // __ARC_LENGTH_TOOLS_HPP__
414
415/**
416 \defgroup arc_length_control Arc-Length control
417 \ingroup user_modules
418**/
#define DEPRECATED
Definition definitions.h:17
static double lambda
constexpr AssemblyType A
constexpr auto field_name
Store variables for ArcLength analysis.
double s
arc length radius
SmartPetscObj< Vec > xLambda
solution of eq. K*xLambda = F_lambda
double res_lambda
f_lambda - s
DofIdx getPetscLocalDofIdx()
Get local index of load factor.
NumeredDofEntity * arcDofRawPtr
MoFEMErrorCode setAlphaBeta(double alpha, double beta)
set parameters controlling arc-length equations alpha controls off diagonal therms beta controls diag...
double alpha
displacement scaling factor
MoFEMErrorCode setS(double s)
set arc radius
double F_lambda2
inner_prod(F_lambda,F_lambda);
SmartPetscObj< Vec > dx
dx = x-x0
double dIag
diagonal value
double dx2
inner_prod(dX,dX)
virtual ~ArcLengthCtx()=default
FieldData & getFieldData()
Get value of load factor.
MoFEM::Interface & mField
SmartPetscObj< Vec > F_lambda
F_lambda reference load vector.
SmartPetscObj< Vec > ghostDiag
SmartPetscObj< Vec > ghosTdLambda
double dLambda
increment of load factor
double beta
force scaling factor
int getPart()
Get proc owning lambda dof.
SmartPetscObj< Vec > db
db derivative of f(dx*dx), i.e. db = d[ f(dx*dx) ]/dx
DofIdx getPetscGlobalDofIdx()
Get global index of load factor.
SmartPetscObj< Vec > x0
displacement vector at beginning of step
shell matrix for arc-length method
boost::shared_ptr< ArcLengthCtx > arcPtr
friend MoFEMErrorCode ArcLengthMatMultShellOp(Mat A, Vec x, Vec f)
SmartPetscObj< Mat > Aij
ArcLengthCtx * arcPtrRaw
MoFEMErrorCode setLambda(Vec ksp_x, double *lambda, ScatterMode scattermode)
virtual ~ArcLengthMatShell()=default
Deprecated interface functions.
structure for Arc Length pre-conditioner
SmartPetscObj< Mat > Aij
ArcLengthCtx * arcPtrRaw
friend MoFEMErrorCode PCApplyArcLength(PC pc, Vec pc_f, Vec pc_x)
SmartPetscObj< KSP > kSP
boost::shared_ptr< ArcLengthCtx > arcPtr
friend MoFEMErrorCode PCSetupArcLength(PC pc)
SmartPetscObj< Mat > shellAij
SmartPetscObj< PC > pC
MoFEMErrorCode preProcess()
MoFEMErrorCode calculateDb()
Calculate db.
MoFEMErrorCode operator()()
double calculateLambdaInt()
Calculate internal lambda.
MoFEMErrorCode calculateDxAndDlambda(Vec x)
MoFEMErrorCode postProcess()
boost::shared_ptr< ArcLengthCtx > arcPtr
Implementation of spherical arc-length method.
virtual MoFEMErrorCode calculateDxAndDlambda(Vec x)
boost::shared_ptr< ArcLengthCtx > arcPtr
virtual MoFEMErrorCode calculateDb()
Calculate db.
virtual double calculateLambdaInt()
Calculate f_lambda(dx,lambda)
virtual MoFEMErrorCode calculateInitDlambda(double *dlambda)
virtual MoFEMErrorCode setDlambdaToX(Vec x, double dlambda)
Zero F_lambda.
MoFEMErrorCode preProcess()
boost::shared_ptr< ArcLengthCtx > arcPtr
MoFEMErrorCode PCApplyArcLength(PC pc, Vec pc_f, Vec pc_x)
MoFEMErrorCode ArcLengthMatMultShellOp(Mat A, Vec x, Vec f)
MoFEMErrorCode PCSetupArcLength(PC pc)