1 /* Siconos is a program dedicated to modeling, simulation and control
2  * of non smooth dynamical systems.
3  *
4  * Copyright 2021 INRIA.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17 */
18 
19 /*! \file DynamicalSystem.hpp
20   \brief Abstract class - General interface for all Dynamical Systems.
21 */
22 
23 #ifndef DynamicalSystem_H
24 #define DynamicalSystem_H
25 
26 #include "SiconosPointers.hpp"
27 #include "SiconosFwd.hpp"
28 
29 #include "SSLH.hpp"
30 #include "SiconosException.hpp"
31 
32 #include "SiconosVector.hpp"
33 #include "SimpleMatrix.hpp"
34 #include "SiconosMemory.hpp"
35 #include "DynamicalSystemTypes.hpp"
36 #include "PluggedObject.hpp"
37 #include "PluginTypes.hpp"
38 #include "SiconosVisitor.hpp"
39 
40 #include <iostream>
41 /** Abstract interface to Dynamical Systems
42 
43 This class is used to describe dynamical systems of the form :
44 
45 \f$ g(\dot x, x, t, z) = 0\f$
46 
47 where
48 
49 - \f$ x \in R^{n} \f$ is the state.
50 - \f$ z \in R^{zSize}\f$ is a vector of arbitrary algebraic
51   variables, some sort of discret state.  For example, z may be used
52   to set some perturbation parameters, to control the system (z
53   set by actuators) and so on.
54 - \f$ g : R^{n} \times R  \to  R^{n}   \f$ .
55 
56 By default, the DynamicalSystem is considered to be an Initial Value
57 Problem (IVP) and the initial conditions are given by
58 
59 \f$x(t_0)=x_0\f$
60 
61 Under some specific conditions, the system can be written as:
62 
63 \f$\dot x = rhs(x, t, z)\f$
64 
65 In that case, \f$ \nabla_{\dot x} g \f$ must be invertible.
66 
67 */
68 
69 class DynamicalSystem
70 {
71 
72 public:
73   /** List of indices used to save tmp work vectors
74    * The last value is the size of the present list, so you HAVE to leave it at the end position.
75    */
76   enum DSWorkVectorId {local_buffer, freeresidu, free, acce_memory, acce_like, sizeWorkV};
77 
78 private:
79   /* serialization hooks */
80   ACCEPT_SERIALIZATION(DynamicalSystem);
81 
82   /** used to set ds number */
83   static size_t __count;
84 
85 protected:
86 
87   /** An id number for the DynamicalSystem */
88   size_t _number;
89 
90   /** the dimension of the system (\e ie size of the state vector x) */
91   unsigned int _n;
92 
93   /** initial state of the system */
94   SP::SiconosVector _x0;
95 
96   /** the input vector due to the non-smooth law \f$ r \in R^{n}\f$
97    * (multiplier, force, ...)
98    * \remark V.A. 17/09/2011 :
99    * This should be a VectorOfVectors as for _x when higher relative degree
100    * systems will be simulated
101    */
102   SP::SiconosVector _r;
103 
104   /** state of the system,
105    *  \f$  x \in R^{n}\f$ - With _x[0]=\f$ x \f$ , _x[1]= \f$ \dot{x} \f$ . */
106   VectorOfVectors _x;
107 
108   /** jacobian according to x of the right-hand side (\f$ rhs = \dot x =
109       f(x,t) + r \f$) */
110   SP::SiconosMatrix _jacxRhs;
111 
112   /** Arbitrary algebraic values vector, z, discrete state of the
113       system. */
114   SP::SiconosVector _z;
115 
116   /** the  previous state vectors stored in memory
117    */
118   SiconosMemory _xMemory;
119 
120   /** number of previous states stored in memory */
121   unsigned int _stepsInMemory;
122 
123   // ===== CONSTRUCTORS =====
124 
125   /** default constructor */
126   DynamicalSystem();
127 
128   /** minimal constructor, from state dimension
129       result in \f$ \dot x = r \f$
130    *  \param dimension size of the system (n)
131    */
132   DynamicalSystem(unsigned int dimension);
133 
134   /** Copy constructor
135    * \param ds the DynamicalSystem to copy
136    */
137   DynamicalSystem(const DynamicalSystem & ds);
138 
139   /** Initialize all PluggedObject whether they are used or not.
140    */
141   virtual void _zeroPlugin() = 0;
142 
143   /** Common code for constructors
144       should be replaced in C++11 by delegating constructors
145    */
146   void _init();
147 
148 public:
149 
150   /** destructor */
~DynamicalSystem()151   virtual ~DynamicalSystem() {};
152 
153   /*! @name Right-hand side computation */
154   //@{
155 
156   /** allocate (if needed)  and compute rhs and its jacobian.
157    * \param time of initialization
158    */
159   virtual void initRhs(double time) = 0 ;
160 
161   /** set nonsmooth input to zero
162    *  \param level input-level to be initialized.
163    */
164   virtual void initializeNonSmoothInput(unsigned int level) = 0;
165 
166   /** compute all component of the dynamical system, for the current state.
167    *  \param time current time (the one used to update ds component)
168    */
169   void update(double time);
170 
171   /** update right-hand side for the current state
172    *  \param time of interest
173    */
174   virtual void computeRhs(double time) = 0;
175 
176   /** update \f$\nabla_x rhs\f$ for the current state
177    *  \param time of interest
178    */
179   virtual void computeJacobianRhsx(double time) = 0;
180 
181   /** reset nonsmooth part of the rhs, for all 'levels' */
182   virtual void resetAllNonSmoothParts() = 0;
183 
184   /** set nonsmooth part of the rhs to zero for a given level
185    * \param level
186    */
187   virtual void resetNonSmoothPart(unsigned int level) = 0;
188 
189   ///@}
190 
191   /*! @name Attributes access
192 
193     For each 'Member' : \n
194     - Member() returns a pointer to the object
195     - getMember() a copy of the object
196     - setMember() set the content of Member with a copy
197     - setMemberPtr() set a pointer link to Member
198 
199     @{ */
200 
201   /** returns the id of the dynamical system */
number() const202   inline size_t number() const
203   {
204     return _number;
205   }
206 
207   /** set the id of the DynamicalSystem
208    *  \return the previous value of number
209    */
setNumber(size_t new_number)210   inline size_t setNumber(size_t new_number)
211   {
212     size_t old_n = _number;
213     _number = new_number;
214     return old_n;
215   }
216 
217   /** returns the size of the vector state x */
n() const218   inline unsigned int n() const
219   {
220     return _n;
221   }
222 
223   /** returns the dimension of the system
224       (depends on system type, e.g. n for first order,
225       ndof for Lagrangian).
226    */
dimension() const227   virtual inline unsigned int dimension() const
228   {
229     return _n;
230   };
231 
232   /** returns a pointer to the initial state vector */
x0() const233   inline SP::SiconosVector x0() const
234   {
235     return _x0;
236   };
237 
238   /** get a copy of the initial state vector */
getX0() const239   inline const SiconosVector getX0() const
240   {
241     return *_x0;
242   }
243 
244   /** set initial state (copy)
245    *  \param newValue input vector to copy
246    */
247   void setX0(const SiconosVector& newValue);
248 
249   /** set initial state (pointer link)
250    *  \param newPtr vector (pointer) to set x0
251    */
252   void setX0Ptr(SP::SiconosVector newPtr);
253 
254   /** returns a pointer to the state vector \f$ x \f$
255    *  \return SP::SiconosVector
256    */
x() const257   inline SP::SiconosVector x() const
258   {
259     return _x[0];
260   }
261 
262   /** get a copy of the current state vector \f$ x \f$
263    * \return SiconosVector
264    */
getx() const265   inline const SiconosVector& getx() const
266   {
267     return *(_x[0]);
268   }
269 
270   /** set content of current state vector \f$ x \f$
271    *  \param newValue SiconosVector
272    */
273   void setX(const SiconosVector& newValue);
274 
275   /** set state vector \f$ x \f$ (pointer link)
276    *  \param newPtr SP::SiconosVector
277    */
278   void setXPtr(SP::SiconosVector newPtr);
279 
280   /** returns a pointer to r vector (input due to nonsmooth behavior)
281    *  \return SP::SiconosVector
282    */
r() const283   inline SP::SiconosVector r() const
284   {
285     return _r;
286   }
287 
288   /** get a copy of r vector (input due to nonsmooth behavior)
289    *  \return a SiconosVector
290    */
getR() const291   inline const SiconosVector getR() const
292   {
293     return *_r;
294   }
295 
296   /** set r vector (input due to nonsmooth behavior) content (copy)
297    *  \param newValue SiconosVector
298    */
299   void setR(const SiconosVector& newValue );
300 
301   /** set r vector (input due to nonsmooth behavior) (pointer link)
302    *  \param newPtr SP::SiconosVector newPtr
303    */
304   void setRPtr(SP::SiconosVector newPtr);
305 
306   /** returns a pointer to the right-hand side vector, (i.e. \f$ \dot x \f$)
307    *  \return SP::SiconosVector
308    */
rhs() const309   inline SP::SiconosVector rhs() const
310   {
311     return _x[1];
312   }
313 
314   /** get a copy of the right-hand side vector, (i.e. \f$ \dot x \f$)
315    *  \return SiconosVector
316    */
getRhs() const317   inline SiconosVector& getRhs() const
318   {
319     return *(_x[1]);
320   }
321 
322   /** set the value of the right-hand side, \f$ \dot x \f$
323    *  \param newValue SiconosVector
324    */
325   virtual void setRhs(const SiconosVector& newValue);
326 
327   /** set right-hand side, \f$ \dot x \f$ (pointer link)
328    *  \param newPtr SP::SiconosVector
329    */
330   virtual void setRhsPtr(SP::SiconosVector newPtr);
331 
332   /** returns a pointer to \f$\nabla_x rhs()\f$
333    *  \return SP::SiconosMatrix
334    */
jacobianRhsx() const335   inline SP::SiconosMatrix jacobianRhsx() const
336   {
337     return _jacxRhs;
338   }
339 
340   /** set the value of \f$\nabla_x rhs()\f$$
341    *  \param newValue SiconosMatrix
342    */
343   void setJacobianRhsx(const SiconosMatrix& newValue);
344 
345   /** set \f$\nabla_x rhs()\f$, pointer link
346    *  \param newPtr SP::SiconosMatrix
347    */
348   void setJacobianRhsxPtr(SP::SiconosMatrix newPtr);
349 
350   /** returns a pointer to \f$ z \f$, the vector of algebraic parameters.
351    *  \return SP::SiconosVector
352    */
z() const353   inline SP::SiconosVector z() const
354   {
355     return _z;
356   }
357 
358   /** get a copy of \f$ z \f$, the vector of algebraic parameters.
359    * \return a SiconosVector
360    */
getz() const361   inline const SiconosVector& getz() const
362   {
363     return *_z;
364   }
365 
366   /** set the value of \f$ z \f$ (copy)
367    *  \param newValue SiconosVector
368    */
369   void setz(const SiconosVector& newValue) ;
370 
371   /** set \f$ z \f$ (pointer link)
372    *  \param newPtr SP::SiconosVector
373    */
374   void setzPtr(SP::SiconosVector newPtr);
375 
376   /** @} end of members access group. */
377 
378   /*! @name Memory vectors management  */
379   //@{
380 
381   /** get all the values of the state vector x stored in a SiconosMemory object
382    * (not const due to LinearSMC::actuate)
383    *  \return a reference to the SiconosMemory object
384    */
xMemory()385   inline SiconosMemory& xMemory()
386   {
387     return _xMemory;
388   }
389 
390   /** get all the values of the state vector x stored in a SiconosMemory object
391    *  \return a const reference to the SiconosMemory object
392    */
xMemory() const393   inline const SiconosMemory& xMemory() const
394   {
395     return _xMemory;
396   }
397 
398   /** returns the number of step saved in memory for state vector
399    *  \return int
400    */
stepsInMemory() const401   inline unsigned int stepsInMemory() const
402   {
403     return _stepsInMemory;
404   }
405 
406   /** set number of steps to be saved
407    *  \param steps
408    */
setStepsInMemory(unsigned int steps)409   inline void setStepsInMemory(unsigned int steps)
410   {
411     _stepsInMemory = steps;
412   }
413 
414   /** initialize the SiconosMemory objects: reserve memory for i vectors in memory and reset all to zero.
415    *  \param steps the size of the SiconosMemory (i)
416    */
417   virtual void initMemory(unsigned int steps);
418 
419   /** push the current values of x and r in memory (index 0 of memory is the last inserted vector)
420    *  xMemory and rMemory,
421    */
422   virtual void swapInMemory() = 0;
423 
424   //@}
425 
426   /*! @name Plugins management  */
427   //@{
428   /** call all plugged functions for the current state
429    * \param time  the current time
430    */
431   virtual void updatePlugins(double time) = 0;
432 
433   ///@}
434 
435   /*! @name Miscellaneous public methods */
436   //@{
437 
438   /** reset the global DynamicSystem counter (for ids)
439    *  \return the previous value of count
440    */
resetCount(size_t new_count=0)441   static inline size_t resetCount(size_t new_count=0)
442   {
443     size_t old_count = __count;
444     __count = new_count;
445     return old_count;
446   };
447 
448   /** reset the state x() to the initial state x0 */
449   virtual void resetToInitialState();
450 
451   /** True if the system is linear.
452    * \return a boolean
453    */
isLinear()454   virtual bool isLinear()
455   {
456     return false;
457   };
458 
459   /** print the data of the dynamical system on the standard output
460    */
461   virtual void display(bool brief = true) const = 0;
462 
463   ///@}
464 
465   //visitors hook
466   VIRTUAL_ACCEPT_VISITORS(DynamicalSystem);
467 
468 };
469 
470 
471 #endif // DynamicalSystem_H
472