G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsDynamicImplicitEuler.hpp
Go to the documentation of this file.
1
14#pragma once
15
16#include <gsSolver/gsGMRes.h>
17#include <gsSolver/gsMatrixOp.h>
18#include <gsSolver/gsBlockOp.h>
19
20namespace gismo
21{
22
23template <class T, bool _NL>
24template <bool _nonlinear>
25typename std::enable_if<(_nonlinear==false), gsStatus>::type
26gsDynamicImplicitEuler<T,_NL>::_step_impl(const T t, const T dt, gsVector<T> & U, gsVector<T> & V, gsVector<T> & A) const
27{
28 gsVector<T> Uold = U;
29 gsVector<T> Vold = V;
30 gsVector<T> Aold = A;
31
32 index_t N = U.rows();
33 gsVector<T> sol(2*N);
34 sol.topRows(N) = U;
35 sol.bottomRows(N) = V;
36
37 typename gsBlockOp<>::Ptr Amat;
38
39 Amat=gsBlockOp<>::make(2,2);
40 gsGMRes<T> gmres(Amat);
41
42 gsSparseMatrix<T> eye(N,N);
43 eye.setIdentity();
44
45 gsVector<T> F;
46 gsSparseMatrix<T> M, C, K;
47 gsSparseMatrix<T> Minv;
48
49 // Computed at t=t0+dt
50 this->_computeMass(t+dt,M);
51 this->_computeForce(t+dt,F);
52 this->_computeDamping(U,t+dt,C);
53 this->_computeJacobian(U,t,K);
54
55 // top-left
56 Amat->addOperator(0,0,gsIdentityOp<T>::make(N) );
57 // top-right
58 Amat->addOperator(0,1,makeMatrixOp( -dt*eye ) );
59 // bottom-left
60 Amat->addOperator(1,0,makeMatrixOp( dt*K ) );
61 // bottom-right
62 Amat->addOperator(1,1,makeMatrixOp( M + dt*C ) );
63
64 gsVector<T> rhs(2*N);
65 rhs.topRows(N) = U;
66 rhs.bottomRows(N) = dt*F + M*V;
67
68 gsMatrix<T> tmpsol;
69 gmres.solve(rhs,tmpsol);
70
71 U = tmpsol.topRows(N);
72 V = tmpsol.bottomRows(N);
73 this->_initOutput();
74 this->_stepOutput(0,sol.norm(),0.);
75
76 return gsStatus::Success;
77}
78
79
80template <class T, bool _NL>
81template <bool _nonlinear>
82typename std::enable_if<(_nonlinear==true), gsStatus>::type
83gsDynamicImplicitEuler<T,_NL>::_step_impl(const T t, const T dt, gsVector<T> & U, gsVector<T> & V, gsVector<T> & A) const
84{
85 gsVector<T> Uold = U;
86 gsVector<T> Vold = V;
87 gsVector<T> Aold = A;
88
89 index_t N = U.rows();
90 gsVector<T> sol(2*N);
91 sol.topRows(N) = U;
92 sol.bottomRows(N) = V;
93
94 gsMatrix<T> dsol;
95
96 typename gsBlockOp<>::Ptr Amat;
97
98 Amat=gsBlockOp<>::make(2,2);
99 gsGMRes<T> gmres(Amat);
100
101 gsSparseMatrix<T> eye(N,N);
102 eye.setIdentity();
103
104 gsVector<T> R;
105 gsSparseMatrix<T> M, C, K;
106
107 // Computed at t=t0+dt
108 this->_computeMass(t+dt,M);
109 this->_computeDamping(U,t+dt,C);
110 this->_computeResidual(U,t+dt,R);
111
112 gsVector<T> rhs(2*N);
113 rhs.topRows(N) = - dt * V; // same as below, but U-Uold=0
114 rhs.bottomRows(N) = dt * C * V + dt*(-R); // same as below, but V-Vold=0
115
116 T tolU = m_options.getReal("TolU");
117 T tolF = m_options.getReal("TolF");
118 T updateNorm = 10.0*tolU;
119 T residualNorm = rhs.norm();
120 T residualNorm0 = (residualNorm!=0) ? residualNorm : 1;
121 T solnorm, dsolnorm;
122 this->_initOutput();
123 for (index_t numIterations = 0; numIterations < m_options.getInt("MaxIter"); ++numIterations)
124 {
125 // TODO: Quasi newton
126 if ((!m_options.getSwitch("Quasi")) || ((numIterations==0) || (numIterations % m_options.getInt("QuasiIterations") == 0)))
127 {
128 // Computed at t=t0+dt
129 this->_computeDamping(U,t+dt,C);
130 this->_computeJacobian(U,t+dt,K);
131 }
132
133 Amat->addOperator(0,0,gsIdentityOp<T>::make(N) );
134 Amat->addOperator(0,1,makeMatrixOp(-dt*eye) );
135 Amat->addOperator(1,0,makeMatrixOp(dt*K) );
136 Amat->addOperator(1,1,makeMatrixOp(M + dt*C) );
137
138 rhs.topRows(N) = U - Uold - dt * V;
139 rhs.bottomRows(N) = M*(V - Vold) + dt * C * V + dt*(-R);
140
141 gmres.solve(-rhs,dsol);
142 sol += dsol;
143
144 solnorm = sol.norm();
145 dsolnorm = dsol.norm();
146 updateNorm = (solnorm != 0) ? dsolnorm / solnorm : dsolnorm;
147
148 U = sol.topRows(N);
149 V = sol.bottomRows(N);
150
151 this->_computeResidual(U,t,R);
152 residualNorm = rhs.norm() / residualNorm0;
153
154 this->_stepOutput(numIterations,residualNorm,updateNorm);
155
156 if ( (updateNorm<tolU && residualNorm<tolF) )
157 {
158 return gsStatus::Success;
159 }
160 }
161
162 gsInfo<<"maximum iterations reached. Solution did not converge\n";
164}
165
166template <class T, bool _NL>
168 gsVector<T> & U, gsVector<T> & V,
169 gsVector<T> & A) const
170{
172 status = _step_impl<_NL>(t,dt,U,V,A);
173 return status;
174}
175
176template <class T, bool _NL>
178{
179 if (m_options.getSwitch("Verbose"))
180 {
181 gsInfo<<"\t";
182 gsInfo<<std::setw(4)<<std::left<<"It.";
183 gsInfo<<std::setw(17)<<std::left<<"|R|/|R0|";
184 gsInfo<<std::setw(17)<<std::left<<"|dU|/|U0|"<<"\n";
185 }
186}
187
188template <class T, bool _NL>
189void gsDynamicImplicitEuler<T,_NL>::_stepOutput(const index_t it, const T resnorm, const T updatenorm) const
190{
191 if (m_options.getSwitch("Verbose"))
192 {
193 gsInfo<<"\t";
194 gsInfo<<std::setw(4)<<std::left<<it;
195 gsInfo<<std::setw(17)<<std::left<<resnorm;
196 gsInfo<<std::setw(17)<<std::left<<updatenorm<<"\n";
197 }
198}
199
200} // namespace gismo
static uPtr make(index_t nRows, index_t nCols)
Make function returning a smart pointer.
Definition gsBlockOp.h:60
memory::shared_ptr< gsBlockOp< T > > Ptr
Shared pointer for gsBlockOp.
Definition gsBlockOp.h:48
Performs the arc length method to solve a nonlinear system of equations.
Definition gsDynamicImplicitEuler.h:34
gsStatus _step(const T t, const T dt, gsVector< T > &U, gsVector< T > &V, gsVector< T > &A) const override
Initialize the ALM.
Definition gsDynamicImplicitEuler.hpp:167
static uPtr make(index_t dim)
Make function returning a smart pointer.
Definition gsLinearOperator.h:132
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Simple class create a block preconditioner structure.
#define index_t
Definition gsConfig.h:32
#define gsInfo
Definition gsDebug.h:43
Preconditioned iterative solver using the generalized minimal residual method.
Simple adapter classes to use matrices or linear solvers as gsLinearOperators.
The G+Smo namespace, containing all definitions for the library.
gsStatus
Definition gsStructuralAnalysisTypes.h:21
@ Success
Successful.
@ NotConverged
Step did not converge.
@ NotStarted
ALM has not started yet.