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