G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsStaticDR.hpp
1 
14 #include <typeinfo>
15 #pragma once
16 
17 namespace gismo
18 {
19 
20 template <class T>
22 {
23  Base::defaultOptions();
24  m_options.addReal("damping","damping factor",1.0);
25  m_options.addReal("alpha","mass coefficient",2.0);
26  m_options.addReal("tolE","Kinetic energy tolerance",1e-6);
27  m_options.addInt("ResetIt","Reset rate of velocities if damping is zero",-1);
28 }
29 
30 template <class T>
32 {
33  Base::getOptions();
34  m_c = m_options.getReal("damping");
35  m_alpha = m_options.getReal("alpha");
36  m_tolE = m_options.getReal("tolE");
37  m_resetIterations = m_options.getInt("ResetIt");
38 }
39 
40 template <class T>
42 {
43  gsInfo<<"\t";
44  gsInfo<<std::setw(4)<<std::left<<"It.";
45  gsInfo<<std::setw(17)<<std::left<<"|R|";
46  gsInfo<<std::setw(17)<<std::left<<"|R|/|R0|";
47  gsInfo<<std::setw(17)<<std::left<<" Ek";
48  gsInfo<<std::setw(17)<<std::left<<" Ek/Ek0";
49  gsInfo<<std::setw(17)<<std::left<<"|dU|";
50  gsInfo<<std::setw(17)<<std::left<<"|dU|/|DU|";
51  gsInfo<<std::setw(17)<<std::left<<"|dU|/|U+DU|";
52  gsInfo<<std::setw(17)<<std::left<<"|dV|";
53  gsInfo<<"\n";
54 }
55 
56 template <class T>
58 {
59  gsInfo<<"\t";
60  gsInfo<<std::setw(4)<<std::left<<k;
61  gsInfo<<std::setw(17)<<std::left<<m_residual;
62  gsInfo<<std::setw(17)<<std::left<<m_residual/m_residualIni;
63  gsInfo<<std::setw(17)<<std::left<<m_Ek;
64  gsInfo<<std::setw(17)<<std::left<<m_Ek/m_Ek0;
65  gsInfo<<std::setw(17)<<std::left<<m_deltaU.norm();
66  gsInfo<<std::setw(17)<<std::left<<m_deltaU.norm()/m_DeltaU.norm();
67  gsInfo<<std::setw(17)<<std::left<<m_deltaU.norm()/(m_U+m_DeltaU).norm();
68  gsInfo<<std::setw(17)<<std::left<<m_v.norm();
69  gsInfo<<"\n";
70 }
71 
72 template <class T>
74 {
75  // try
76  // {
77  _solve();
78  m_status = gsStatus::Success;
79  // }
80  // catch (int errorCode)
81  // {
82  // if (errorCode==1)
83  // m_status = gsStatus::NotConverged;
84  // else if (errorCode==2)
85  // m_status = gsStatus::AssemblyError;
86  // else if (errorCode==3)
87  // m_status = gsStatus::SolverError;
88  // else
89  // m_status = gsStatus::OtherError;
90  // }
91  // catch (...)
92  // {
93  // m_status = gsStatus::OtherError;
94  // }
95  return m_status;
96 }
97 
98 template <class T>
100 {
101  m_Eks.clear();
102  m_Eks.reserve(m_maxIterations);
103 
104  if (m_verbose) initOutput();
105 
106  _start(); // initializes m_Ek, etc
107 
108  m_Ek0 = m_Ek;
109  m_Eks.push_back(m_Ek);
110 
111  if (m_verbose != 0) stepOutput(0);
112  index_t resetIt = 0;
113  for (m_numIterations=1; m_numIterations!=m_maxIterations; m_numIterations++, resetIt++)
114  {
115  _iteration();
116  if ((m_c==0 && m_Ek_prev > m_Ek) || resetIt==m_resetIterations)// || (m_Ek/m_Ek_prev > 1/m_tolE && m_Ek_prev!=0))
117  {
118  resetIt = 0;
119  _peak();
120  }
121 
122  if (m_verbose!=0)
123  if (m_numIterations % m_verbose == 0 || m_verbose==-1 ) stepOutput(m_numIterations);
124 
125  m_Eks.push_back(m_Ek);
126 
127  m_residualOld = m_residual;
128 
129  if (m_residual/m_residualIni < m_tolF && m_Ek/m_Ek0 < m_tolE && m_deltaU.norm()/m_DeltaU.norm() < m_tolU)
130  {
131  m_U += m_DeltaU;
132  gsDebug <<"Converged: \n";
133  gsDebug <<"\t |R|/|R0| = "<<m_residual/m_residualIni<<" < tolF = "<<m_tolF<<"\n";
134  gsDebug <<"\t |E|/|E0| = "<<m_Ek/m_Ek0 <<" < tolE = "<<m_tolE<<"\n";
135  gsDebug <<"\t |U|/|U0| = "<<m_deltaU.norm()/m_DeltaU.norm()<<" < tolF = "<<m_tolU<<"\n";
136  break;
137  }
138  if (m_numIterations==m_maxIterations-1)
139  {
140  m_U += m_DeltaU;
141  gsInfo<<"Maximum iterations reached. Solution did not converge\n";
142  throw 1;
143  }
144  }
145  gsInfo<<"\n";
146 };
147 
148 template <class T>
150 {
151  this->reset();
152  getOptions();
153  m_massInv *= 1./m_alpha;
154  m_damp = m_c * m_mass;
155 }
156 
157 template <class T>
159 {
160  m_dofs = m_mass.rows();
161  m_massInv = m_mass.array().inverse();
162  m_Ek = m_Ek0 = 0.0;
163  // resets m_U, m_DeltaU, m_deltaU, m_R, m_L, m_DeltaL, m_deltaL and m_headstart
164  Base::reset();
165  m_v.setZero(m_dofs);
166  m_status = gsStatus::NotStarted;
167 }
168 
169 template <class T>
171 {
172  this->reset();
173  m_dt = 1.0;
174  defaultOptions();
175 }
176 
177 template <class T>
179 {
180  gsVector<T> resVec;
181  if (!m_residualFun(U, resVec))
182  throw 2;
183  return resVec;
184 }
185 
186 template <class T>
188 {
189  m_Ek_prev = m_Ek;
190  m_R = _computeResidual(m_U+m_DeltaU) - m_damp.cwiseProduct(m_v);
191  m_residual = m_R.norm();
192 //----------------------------------------------------------------------------------
193  m_v += m_dt * m_massInv.cwiseProduct(m_R); // Velocities at t+dt/2
194  m_deltaU = m_dt * m_v; // Velocities at t+dt
195 //----------------------------------------------------------------------------------
196  // m_deltaU = m_deltaU + m_dt*m_dt*m_massInv*m_R;
197  // m_v = m_deltaU/m_dt;
198 //----------------------------------------------------------------------------------
199 
200  m_DeltaU += m_deltaU; // Velocities at t+dt
201  m_Ek = m_v.transpose() * m_mass.cwiseProduct(m_v);
202 }
203 
204 template <class T>
206 {
207  m_R = _computeResidual(m_U+m_DeltaU)- m_damp.cwiseProduct(m_v);
208  m_deltaU = - 1.5 * m_dt * m_v + m_dt*m_dt / 2. * m_massInv.cwiseProduct(m_R);
209  m_DeltaU += m_deltaU;
210 
211  m_v.setZero();
212  m_Ek = 0.0;
213  // m_v = 0.5 * m_dt * m_massInv * m_R; // Velocities at dt/2
214 }
215 
216 template <class T>
218 {
219  m_v.setZero();
220 
221 //----------------------------------------------------------------------------------
222  // Define residual measures:
223  // m_residual = current residual
224  // m_residualIni = residual on m_U
225  // m_residualOld = residual in previous step
226  if (!m_headstart) // no headstart
227  {
228  // We can reset the update to ensure we properly restart
229  m_DeltaU.setZero(m_dofs);
230  // Compute current residual and its norm
231  m_R = _computeResidual(m_U);
232  // m_residual = m_R.norm();
233  m_residual = m_forcing.norm();
234  // If the residual is 0 (e.g. with purely displacment loading), we set it to 1 to allow divisions
235  if (m_residual==0) m_residual=1;
236  // All residual norms are equal
237  m_residualIni = m_residualOld = m_residual;
238  }
239  else
240  {
241  // Compute current residual and its norm
242  m_R = _computeResidual(m_U + m_DeltaU);
243  // m_residual = m_R.norm();
244  m_residual = m_forcing.norm();
245  // If the residual is 0 (e.g. with purely displacment loading), we set it to 1 to allow divisions
246  if (m_residual==0) m_residual=1;
247  // The previous step residual is the same as the residual
248  m_residualOld = m_residual;
249  // Residual0 is the residual without m_DeltaU
250  m_residualIni = _computeResidual(m_U).norm();
251  // If the residual is 0 (e.g. with purely displacment loading), we set it to 1 to allow divisions
252  if (m_residualIni==0) m_residualIni=1;
253 
254  // Now we can reset the headstart
255  m_headstart = false;
256  }
257 
258 //----------------------------------------------------------------------------------
259  // m_R = _computeResidual(m_U+m_DeltaU);
260  m_deltaU = 0.5*m_dt*m_dt*m_massInv.cwiseProduct(m_R);
261  m_v = m_deltaU/m_dt;
262 //----------------------------------------------------------------------------------
263 
264  m_DeltaU += m_deltaU;
265 
266  m_Ek = m_v.transpose() * m_mass.cwiseProduct(m_v);
267 }
268 
269 } // namespace gismo
void getOptions() override
See gsStaticBase.
Definition: gsStaticDR.hpp:31
#define gsDebug
Definition: gsDebug.h:61
void initialize() override
See gsStaticBase.
Definition: gsStaticDR.hpp:149
gsStatus solve() override
gsStaticBase base functions
Definition: gsStaticDR.hpp:73
#define index_t
Definition: gsConfig.h:32
gsStatus
Definition: gsStructuralAnalysisTypes.h:20
void _start()
Starts the method.
Definition: gsStaticDR.hpp:217
void reset() override
See gsStaticBase.
Definition: gsStaticDR.hpp:158
#define gsInfo
Definition: gsDebug.h:43
Static solver using the Dynamic Relaxation method.
Definition: gsStaticDR.h:27
void _solve()
See solve()
Definition: gsStaticDR.hpp:99
void _iteration()
Performs an iteration.
Definition: gsStaticDR.hpp:187
void _peak()
Identifies a peak.
Definition: gsStaticDR.hpp:205
void _init()
Initializes the method.
Definition: gsStaticDR.hpp:170
ALM has not started yet.
void initOutput() override
See gsStaticBase.
Definition: gsStaticDR.hpp:41
void stepOutput(index_t k) override
See gsStaticBase.
Definition: gsStaticDR.hpp:57
void defaultOptions() override
See gsStaticBase.
Definition: gsStaticDR.hpp:21