1 /** @file gsStaticDR.cpp
2 
3     @brief Static solver using the Dynamic Relaxation method
4 
5     This file is part of the G+Smo library.
6 
7     This Source Code Form is subject to the terms of the Mozilla Public
8     License, v. 2.0. If a copy of the MPL was not distributed with this
9     file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11     Author(s): H.M. Verhelst (2019-..., TU Delft)
12 */
13 
14 #include <gismo.h>
15 #include <gsStructuralAnalysis/gsStaticBase.h>
16 
17 namespace gismo
18 {
19 
20 /**
21  * @brief Static solver using the Dynamic Relaxation method
22  *
23  * @tparam     T     coefficient type
24  *
25  * \ingroup gsStaticBase
26  */
27 template <class T>
28 class gsStaticDR : public gsStaticBase<T>
29 {
30 protected:
31 
32     typedef gsStaticBase<T> Base;
33 
34     typedef std::function<gsVector<T>(gsVector<T> const &)   >  Residual_t;
35     typedef std::function<gsVector<T>(gsVector<T> const &, T)>  ALResidual_t;
36 
37 public:
38 
39     /**
40      * @brief      Constructor
41      *
42      * @param[in]  M         Lumped mass matrix (as vector)
43      * @param[in]  F         External forcing vector
44      * @param[in]  Residual  The residual
45      */
gsStaticDR(const gsVector<T> & M,const gsVector<T> & F,const Residual_t & Residual)46     gsStaticDR( const gsVector<T> & M, // lumped
47                 const gsVector<T> & F,
48                 const Residual_t &Residual
49                )
50     :
51     m_mass(M),
52     m_forcing(F),
53     m_residualFun(Residual),
54     m_ALresidualFun(nullptr)
55     {
56         this->_init();
57     }
58 
59 
60     /**
61      * @brief      Constructs a new instance.
62      *
63      * @param[in]  M         Lumped mass matrix (as vector)
64      * @param[in]  F         External forcing vector
65      * @param[in]  Residual  The residual as arc-length object
66      */
gsStaticDR(const gsVector<T> & M,const gsVector<T> & F,const ALResidual_t & ALResidual)67     gsStaticDR( const gsVector<T>   & M, // lumped
68                 const gsVector<T>   & F,
69                 const ALResidual_t  & ALResidual
70                )
71     :
72     m_mass(M),
73     m_forcing(F),
74     m_ALresidualFun(ALResidual)
75     {
76         m_L = 1.0;
77         m_residualFun = [this](gsVector<T> const & x)
78         {
79             return m_ALresidualFun(x,m_L);
80         };
81         this->_init();
82     }
83 
84 /// gsStaticBase base functions
85 public:
86     /// See \ref gsStaticBase
87     void solve();
88     /// See \ref gsStaticBase
89     void initialize();
90 
91     /// See \ref gsStaticBase
92     void initOutput();
93     /// See \ref gsStaticBase
94     void stepOutput(index_t k);
95 
96     /// See \ref gsStaticBase
97     void defaultOptions();
98     /// See \ref gsStaticBase
99     void getOptions();
100 
101     /// See \ref gsStaticBase
setOptions(gsOptionList & options)102     void setOptions(gsOptionList & options) {m_options.update(options,gsOptionList::addIfUnknown); }
103 
104 public:
105     /// Returns the kinetic energy
kineticEnergy()106     T kineticEnergy() const { return m_Ek; }
107     /// Returns the kinetic energy in all steps
energies()108     gsVector<T> energies() const { return gsAsVector<T>(m_Eks); }
109     /// Returns the kinetic energy relative to the first iteration
relEnergies()110     gsVector<T> relEnergies() const { return gsAsVector<T>(m_Eks)/m_Ek0; }
111     /// Returns the velocity
velocities()112     gsVector<T> velocities() const {return m_v;}
113 
114 protected:
115     /// Performs an iteration
116     void _iteration();
117     /// Identifies a peak
118     void _peak();
119     /// Starts the method
120     void _start();
121     /// Initializes the method
122     void _init();
123 
124 public:
125     //// Perform a step back
_stepBack()126     void _stepBack()
127     {
128         m_U -= m_DeltaU;
129     }
130 
131     /// Start over again
_reset()132     void _reset()
133     {
134         _start();
135     }
136 
137     /// Return the residual norm
residualNorm()138     T residualNorm() const { return m_R.norm(); }
139 
140 protected:
141     const gsVector<T> m_mass;
142     const gsVector<T> m_forcing;
143     Residual_t m_residualFun;
144     const ALResidual_t m_ALresidualFun;
145 
146     // Solution
147     using Base::m_U;
148     using Base::m_DeltaU;
149     using Base::m_deltaU;
150 
151     using Base::m_L;
152     using Base::m_DeltaL;
153     using Base::m_deltaL;
154 
155     // Iterations
156     using Base::m_numIterations;
157     using Base::m_maxIterations;
158 
159     // Residuals
160     using Base::m_R;
161 
162     // Tolerances
163     using Base::m_converged;
164     using Base::m_tolF;
165     using Base::m_tolU;
166     T m_tolE;
167 
168     // Residual norms
169     using Base::m_residual;
170     using Base::m_residualIni;
171     using Base::m_residualOld;
172 
173     // Options
174     using Base::m_options;
175     using Base::m_verbose;
176 
177     // DoFs
178     using Base::m_dofs;
179 
180     // Headstart
181     using Base::m_headstart;
182 
183     // Velocities
184     gsVector<T> m_v;                // (class-specific)
185     gsVector<T> m_massInv, m_damp;  // (class-specific)
186 
187     // Coefficients
188     T m_dt, m_alpha, m_c;           // (class-specific)
189 
190     // Kinetic energy
191     T m_Ek, m_Ek_prev, m_Ek0;       // (class-specific)
192     mutable std::vector<T> m_Eks;   // (class-specific)
193 };
194 
195 } //namespace
196 
197 
198 #ifndef GISMO_BUILD_LIB
199 #include GISMO_HPP_HEADER(gsStaticDR.hpp)
200 #endif