G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsDynamicRK4.hpp
Go to the documentation of this file.
1 
14 #pragma once
15 
16 namespace gismo
17 {
18 template <class T, bool _NL>
19 template <bool _nonlinear>
20 typename std::enable_if<(_nonlinear==false), gsStatus>::type
21 gsDynamicRK4<T,_NL>::_step_impl(const T t, const T dt, gsVector<T> & U, gsVector<T> & V, gsVector<T> & A) const
22 {
23  /*
24  */
25  gsVector<T> Uold = U;
26  gsVector<T> Vold = V;
27  gsVector<T> Aold = A;
28 
29  index_t N = U.rows();
30  gsVector<T> sol(2*N);
31  sol.topRows(N) = Uold;
32  sol.bottomRows(N) = Vold;
33 
34  gsVector<T> F, R; //R is the residual vector, and the new _computeForce give the inline factor
35  gsSparseMatrix<T> M, Minv, C, K;
36 
37  // Computed at t=t0
38  this->_computeMass(t,M);
39  this->_computeMassInverse(M,Minv);
40  // this->_computeForce(t,F);
41  this->_computeDamping(U,t,C); //C is damping
42  this->_computeJacobian(U,t,K);
43 
44  // this->_initOutput();
45  // Initialize parameters for RK4
46  gsVector<T> k1(2*N), k2(2*N), k3(2*N), k4(2*N);
47  gsVector<T> Utmp, Vtmp;
48 
49  //Step1 (calculate k1)
50  _computeForce(t, F);
51  R = F - K * Uold;
52  k1.topRows(N) = Vold;
53  k1.bottomRows(N) = Minv * (R - C * Vold);
54 
55  //Step2 (calculate k2)
56  Utmp = Uold + dt/2. * k1.topRows(N);
57  Vtmp = Vold + dt/2. * k1.bottomRows(N);
58  _computeForce(t + dt/2.,F);
59  R = F - K * Utmp;
60  k2.topRows(N) = Vtmp;
61  k2.bottomRows(N) = Minv * ( R - C * Vtmp);
62 
63  //Step3 (calculate k3)
64  Utmp = Uold + dt/2. * k2.topRows(N);
65  Vtmp = Vold + dt/2. * k2.bottomRows(N);
66  _computeForce(t + dt/2., F);
67  R = F - K * Utmp;
68  k3.topRows(N) = Vtmp;
69  k3.bottomRows(N) = Minv * ( R - C * Vtmp);
70 
71  //Step4 (calculate k4)
72  Utmp = Uold + dt/2. * k3.topRows(N);
73  Vtmp = Vold + dt/2. * k3.bottomRows(N);
74  _computeForce(t + dt/2., F);
75  R = F - K * Utmp;
76  k4.topRows(N) = Vtmp;
77  k4.bottomRows(N) = Minv * ( R - C * Vtmp);
78 
79  sol += 1./6 * dt * (k1 + 2.*k2 + 2.*k3 + k4);
80 
81  U = std::move(sol.topRows(N)); //Use std move to update vectors to avoid unnecessary copying
82  V = std::move(sol.bottomRows(N));
83 
84  if (math::isinf(sol.norm()) || math::isnan(sol.norm()))
86  else
87  return gsStatus::Success;
88 }
89 
90 
91 template <class T, bool _NL>
92 template <bool _nonlinear>
93 typename std::enable_if<(_nonlinear==true), gsStatus>::type
94 gsDynamicRK4<T,_NL>::_step_impl(const T t, const T dt, gsVector<T> & U, gsVector<T> & V, gsVector<T> & A) const
95 {
96  /*
97  */
98  gsVector<T> Uold = U;
99  gsVector<T> Vold = V;
100  gsVector<T> Aold = A;
101 
102  index_t N = U.rows();
103  gsVector<T> sol(2*N);
104  sol.topRows(N) = Uold;
105  sol.bottomRows(N) = Vold;
106 
107  gsVector<T> F, R; //R is the residual vector, and the new _computeForce give the inline factor
108  gsSparseMatrix<T> M, Minv, C, K;
109 
110  // Computed at t=t0
111  this->_computeMass(t,M);
112  this->_computeMassInverse(M,Minv);
113  // this->_computeForce(t,F);
114  this->_computeDamping(U,t,C); //C is damping
115  this->_computeJacobian(U,t,K);
116 
117  // this->_initOutput();
118  // Initialize parameters for RK4
119  gsVector<T> k1(2*N), k2(2*N), k3(2*N), k4(2*N);
120  gsVector<T> Utmp, Vtmp;
121 
122  //Step1 (calculate k1)
123  _computeResidual(Uold, t, R);
124  k1.topRows(N) = Vold;
125  k1.bottomRows(N) = Minv * (R - C * Vold);
126 
127  //Step2 (calculate k2)
128  Utmp = Uold + dt/2. * k1.topRows(N);
129  Vtmp = Vold + dt/2. * k1.bottomRows(N);
130  _computeResidual(Utmp,t + dt/2.,R);
131  k2.topRows(N) = Vtmp;
132  k2.bottomRows(N) = Minv * ( R - C * Vtmp);
133 
134  //Step3 (calculate k3)
135  Utmp = Uold + dt/2. * k2.topRows(N);
136  Vtmp = Vold + dt/2. * k2.bottomRows(N);
137  _computeResidual(Utmp,t + dt/2.,R);
138  k3.topRows(N) = Vtmp;
139  k3.bottomRows(N) = Minv * ( R - C * Vtmp);
140 
141  //Step4 (calculate k4)
142  Utmp = Uold + dt/2. * k3.topRows(N);
143  Vtmp = Vold + dt/2. * k3.bottomRows(N);
144  _computeResidual(Utmp,t + dt/2.,R);
145  k4.topRows(N) = Vtmp;
146  k4.bottomRows(N) = Minv * ( R - C * Vtmp);
147 
148  sol += 1./6 * dt * (k1 + 2.*k2 + 2.*k3 + k4);
149 
150  U = std::move(sol.topRows(N)); //Use std move to update vectors to avoid unnecessary copying
151  V = std::move(sol.bottomRows(N));
152 
153  if (math::isinf(sol.norm()) || math::isnan(sol.norm()))
154  return gsStatus::NotConverged;
155  else
156  return gsStatus::Success;
157 }
158 
159 template <class T, bool _NL>
160 gsStatus gsDynamicRK4<T,_NL>::_step(const T t, const T dt,
161  gsVector<T> & U, gsVector<T> & V,
162  gsVector<T> & A) const
163 {
165  status = _step_impl<_NL>(t,dt,U,V,A);
166  return status;
167 }
168 
169 template <class T, bool _NL>
171 {
172  if (m_options.getSwitch("Verbose"))
173  {
174  gsInfo<<"\t";
175  gsInfo<<std::setw(4)<<std::left<<"It.";
176  gsInfo<<std::setw(17)<<std::left<<"|R|";
177  gsInfo<<"\n";
178  }
179 }
180 
181 template <class T, bool _NL>
182 void gsDynamicRK4<T,_NL>::_stepOutput(const index_t it, const T resnorm, const T updatenorm) const
183 {
184  if (m_options.getSwitch("Verbose"))
185  {
186  gsInfo<<"\t";
187  gsInfo<<std::setw(4)<<std::left<<it;
188  gsInfo<<std::setw(17)<<std::left<<resnorm;
189  gsInfo<<"\n";
190  }
191 }
192 
193 } // namespace gismo
Step did not converge.
gsStatus _step(const T t, const T dt, gsVector< T > &U, gsVector< T > &V, gsVector< T > &A) const
Initialize the ALM.
Definition: gsDynamicRK4.hpp:160
#define index_t
Definition: gsConfig.h:32
gsStatus
Definition: gsStructuralAnalysisTypes.h:20
#define gsInfo
Definition: gsDebug.h:43
Performs the arc length method to solve a nonlinear system of equations.
Definition: gsDynamicRK4.h:33
ALM has not started yet.