G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsDynamicRK4.hpp
Go to the documentation of this file.
1
14#pragma once
15
16namespace gismo
17{
18template <class T, bool _NL>
19template <bool _nonlinear>
20typename std::enable_if<(_nonlinear==false), gsStatus>::type
21gsDynamicRK4<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
91template <class T, bool _NL>
92template <bool _nonlinear>
93typename std::enable_if<(_nonlinear==true), gsStatus>::type
94gsDynamicRK4<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()))
155 else
156 return gsStatus::Success;
157}
158
159template <class T, bool _NL>
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
169template <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
181template <class T, bool _NL>
182void 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
Performs the arc length method to solve a nonlinear system of equations.
Definition gsDynamicRK4.h:34
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
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
#define index_t
Definition gsConfig.h:32
#define gsInfo
Definition gsDebug.h:43
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.