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 NewtonEulerDS.hpp 20 */ 21 22 #ifndef NEWTONEULERNLDS_H 23 #define NEWTONEULERNLDS_H 24 25 #include "DynamicalSystem.hpp" 26 #include "SecondOrderDS.hpp" 27 #include "BoundaryCondition.hpp" 28 29 /** Pointer to function for plug-in. */ 30 typedef void (*FInt_NE)(double t, double* q, double* v, double *f, unsigned int size_z, double* z); 31 typedef void (*FExt_NE)(double t, double* f, unsigned int size_z, double *z); 32 33 void computeT(SP::SiconosVector q, SP::SimpleMatrix T); 34 #include "RotationQuaternion.hpp" 35 36 37 /** Compute the force and moment vectors applied to a body with state 38 * q from a force vector at a given position. */ 39 void computeExtForceAtPos(SP::SiconosVector q, bool isMextExpressedInInertialFrame, 40 SP::SiconosVector force, bool forceAbsRef, 41 SP::SiconosVector pos, bool posAbsRef, 42 SP::SiconosVector fExt, SP::SiconosVector mExt, 43 bool accumulate); 44 45 /** NewtonEuler non linear dynamical systems 46 47 The equations of motion in the Newton-Euler formalism can be stated as 48 49 \rst 50 51 .. math:: 52 :nowrap: 53 54 \verbatim 55 \left\{\begin{array}{rcl} 56 M \\dot v + F_{int}(q,v, \Omega, t)&=& F_{ext}(t), \ \ 57 I \dot \Omega + \Omega \wedge I\Omega + M_{int}(q,v, \Omega, t) &=& M_{ext}(t), \ \ 58 \dot q &=& T(q) [ v, \Omega] \ \ 59 \dot R &=& R \tilde \Omega,\quad R^{-1}=R^T,\quad \det(R)=1 . 60 \end{array}\right. 61 \endverbatim 62 \endrst 63 64 with 65 <ul> 66 <li> \f$x_G,v_G\f$ position and velocity of the center of mass expressed in a inertial frame of 67 reference (world frame) </li> 68 <li> \f$\Omega\f$ angular velocity vector expressed in the body-fixed frame (frame attached to the object) </li> 69 <li> \f$R\f$ rotation matrix form the inertial frame to the body-fixed frame \f$R^{-1}=R^T, \det(R)=1\f$, i.e \f$ R\in SO^+(3)\f$ </li> 70 <li> \f$M=m\,I_{3\times 3}\f$ diagonal mass matrix with \f$m \in \mathbb{R}\f$ the scalar mass </li> 71 <li> \f$I\f$ constant inertia matrix </li> 72 <li> \f$F_{ext}\f$ and \f$ M_{ext}\f$ are the external applied forces and moment </li> 73 </ul> 74 75 76 In the current implementation, \f$R\f$ is parametrized by a unit quaternion. 77 78 */ 79 class NewtonEulerDS : public SecondOrderDS 80 { 81 protected: 82 /* serialization hooks */ 83 ACCEPT_SERIALIZATION(NewtonEulerDS); 84 85 /** Common code for constructors 86 * should be replaced in C++11 by delegating constructors 87 */ 88 void _init(); 89 90 // -- MEMBERS -- 91 92 /** _twist contains the twist of the Newton Euler dynamical system. 93 * _twist[0:2] : \f$v_G \in \RR^3 \f$ velocity of the center of mass in 94 * the inertial frame of reference (world frame). 95 * _twist[3:5] : \f$\Omega\in\RR^3\f$ angular velocity expressed in the body-fixed frame 96 */ 97 SP::SiconosVector _twist; 98 99 /** Initial twist */ 100 SP::SiconosVector _twist0; 101 102 /** _q contains the representation of the system 103 * In the current implementation, we have 104 * _q[0:2] : the coordinates of the center of mass expressed 105 * in the inertial frame of reference (world frame) 106 * _q[3:6] : an unit quaternion representing the orientation of the solid. 107 * This unit quaternion encodes the rotation mapping from the inertial frame of reference 108 * to the body-fixed frame 109 */ 110 SP::SiconosVector _q; 111 112 /** Dimension of _q, is not necessary equal to _ndof. In our case, _qDim = 7 and _ndof =6*/ 113 unsigned int _qDim; 114 115 /** The time derivative of \f$q\f$, \f$\dot q\f$*/ 116 SP::SiconosVector _dotq; 117 118 /** _acceleration contains the time derivative of the twist 119 */ 120 SP::SiconosVector _acceleration; 121 122 /** Memory vectors that stores the values within the time--step */ 123 SiconosMemory _twistMemory; 124 SiconosMemory _qMemory; 125 SiconosMemory _forcesMemory; 126 SiconosMemory _dotqMemory; 127 128 /** Inertial matrix 129 */ 130 SP::SiconosMatrix _I; 131 132 /** Scalar mass of the system 133 */ 134 double _scalarMass; 135 136 /** Matrix depending on the parametrization of the orientation 137 * \f$v = T(q) \dot q\f$ 138 */ 139 SP::SimpleMatrix _T; 140 141 /** Time derivative of T. 142 * 143 * \f$\dot v = \dot T(q) \dot q + T(q) \ddot q\f$ 144 */ 145 SP::SimpleMatrix _Tdot; 146 147 /** external forces of the system */ 148 SP::SiconosVector _fExt; 149 150 /** boolean if _fext is constant (set thanks to setFExtPtr for instance) 151 * false by default */ 152 bool _hasConstantFExt; 153 154 /** internal forces of the system */ 155 SP::SiconosVector _fInt; 156 157 /** external moment expressed in the inertial frame */ 158 SP::SiconosVector _mExt; 159 160 /** boolean if _mext is constant (set thanks to setMExtPtr for instance) 161 * false by default */ 162 bool _hasConstantMExt; 163 164 /** if true, we assume that mExt is given in inertial frame (default false) */ 165 bool _isMextExpressedInInertialFrame; 166 167 /** external moment expressed in the body-fixed frame */ 168 // SP::SiconosVector _mExtBodyFrame; 169 170 /** internal moment of the forces */ 171 SP::SiconosVector _mInt; 172 173 /** jacobian_q FInt w.r.t q*/ 174 SP::SimpleMatrix _jacobianFIntq; 175 176 /** jacobian_twist FInt w.r.t the twist*/ 177 SP::SimpleMatrix _jacobianFInttwist; 178 179 /** jacobian_q MInt w.r.t q */ 180 SP::SimpleMatrix _jacobianMIntq; 181 182 /** jacobian_twist MInt w.r.t the twist*/ 183 SP::SimpleMatrix _jacobianMInttwist; 184 185 /** jacobian_q MExt w.r.t q*/ 186 SP::SimpleMatrix _jacobianMExtq; 187 188 /** gyroscpical moment */ 189 SP::SiconosVector _mGyr; 190 191 /** jacobian_twist of mGyr w.r.t the twist*/ 192 SP::SimpleMatrix _jacobianMGyrtwist; 193 194 /** wrench (q,twist,t)= [ fExt - fInt ; mExtBodyFrame - mGyr - mInt ]^T */ 195 196 SP::SiconosVector _wrench; 197 198 /** jacobian_q forces*/ 199 SP::SimpleMatrix _jacobianWrenchq; 200 201 /** jacobian_{twist} forces*/ 202 SP::SimpleMatrix _jacobianWrenchTwist; 203 204 205 /** if true, we set the gyroscopic forces equal to 0 (default false) **/ 206 bool _nullifyMGyr; 207 208 /** If true, we compute the missing Jacobian by forward finite difference */ 209 bool _computeJacobianFIntqByFD; 210 211 /** If true, we compute the missing Jacobian by forward finite difference */ 212 bool _computeJacobianFInttwistByFD; 213 214 /** If true, we compute the missing Jacobian by forward finite difference */ 215 bool _computeJacobianMIntqByFD; 216 217 /** If true, we compute the missing Jacobian by forward finite difference */ 218 bool _computeJacobianMInttwistByFD; 219 220 /** value of the step in finite difference */ 221 double _epsilonFD; 222 223 /** Plugin to compute strength of external forces */ 224 SP::PluggedObject _pluginFExt; 225 226 /** Plugin to compute the external moment expressed in the inertial frame */ 227 SP::PluggedObject _pluginMExt; 228 229 /** Plugin to compute strength of internal forces */ 230 SP::PluggedObject _pluginFInt; 231 232 /** Plugin to compute moments of internal forces */ 233 SP::PluggedObject _pluginMInt; 234 235 /** The following code is commented because the jacobian of _mInt and _fInt 236 * are not yet used by the numerical scheme. 237 * Will be needed by a fully implicit scheme for instance. 238 */ 239 /** jacobian_q */ 240 // SP::SimpleMatrix _jacobianqmInt; 241 /** jacobian_{qDot} */ 242 // SP::SimpleMatrix _jacobianqDotmInt; 243 244 /** NewtonEulerDS plug-in to compute \f$\nabla_qF_{Int}(\dot q, q, t)\f$, id = "jacobianFIntq" 245 * @param time : current time 246 * @param sizeOfq : size of vector q 247 * @param q : pointer to the first element of q 248 * @param twist : pointer to the first element of twist 249 * @param[in,out] jacob : pointer to the first element of the jacobian 250 * @param size of vector z 251 * @param[in,out] z : a vector of user-defined parameters 252 */ 253 SP::PluggedObject _pluginJacqFInt; 254 255 /** NewtonEulerDS plug-in to compute \f$\nabla_{\dot q}F_{Int}(\dot q, q, t)\f$, id = "jacobianFIntTwist" 256 * @param time : current time 257 * @param sizeOfq : size of vector q 258 * @param q : pointer to the first element of q 259 * @param twist : pointer to the first element of twist 260 * @param[in,out] jacob : pointer to the first element of the jacobian 261 * @param size of vector z 262 * @param[in,out] z : a vector of user-defined parameters 263 */ 264 SP::PluggedObject _pluginJactwistFInt; 265 266 /** NewtonEulerDS plug-in to compute \f$\nabla_qM_{Int}(\dot q, q, t)\f$, id = "jacobianMInttwist" 267 * @param time : current time 268 * @param sizeOfq : size of vector q 269 * @param q : pointer to the first element of q 270 * @param twist : pointer to the first element of twist 271 * @param[in,out] jacob : pointer to the first element of the jacobian 272 * @param size of vector z 273 * @param[in,out] z : a vector of user-defined parameters 274 */ 275 SP::PluggedObject _pluginJacqMInt; 276 277 278 /** NewtonEulerDS plug-in to compute \f$\nabla_{\dot q}M_{Int}(\dot q, q, t)\f$, id = "jacobianMInttwist" 279 * @param time : current time 280 * @param sizeOfq : size of vector q 281 * @param q : pointer to the first element of q 282 * @param twist : pointer to the first element of twist 283 * @param[in,out] jacob : pointer to the first element of the jacobian 284 * @param size of vector z 285 * @param[in,out] z : a vector of user-defined parameters 286 */ 287 SP::PluggedObject _pluginJactwistMInt; 288 289 290 291 enum NewtonEulerDSRhsMatrices {jacobianXBloc00, jacobianXBloc01, jacobianXBloc10, jacobianXBloc11, zeroMatrix, zeroMatrixqDim, numberOfRhsMatrices}; 292 293 /** A container of matrices to save matrices that are involed in first order from of 294 * NewtonEulerDS system values (jacobianXBloc10, jacobianXBloc11, zeroMatrix, idMatrix) 295 * No get-set functions at the time. Only used as a protected member.*/ 296 VectorOfSMatrices _rhsMatrices; 297 298 299 300 /** Default constructor 301 */ 302 NewtonEulerDS(); 303 304 /** build all _plugin... PluggedObject */ 305 void _zeroPlugin(); 306 307 public: 308 309 // === CONSTRUCTORS - DESTRUCTOR === 310 311 /** constructor from a minimum set of data 312 * \param position initial coordinates of this DynamicalSystem 313 * \param twist initial twist of this DynamicalSystem 314 * \param mass the mass 315 * \param inertia the inertia matrix 316 */ 317 NewtonEulerDS(SP::SiconosVector position, 318 SP::SiconosVector twist, 319 double mass, 320 SP::SiconosMatrix inertia); 321 322 /** destructor */ 323 virtual ~NewtonEulerDS(); 324 325 /*! @name Right-hand side computation */ 326 //@{ 327 328 /** reset the state to the initial state */ 329 void resetToInitialState(); 330 331 /** allocate (if needed) and compute rhs and its jacobian. 332 * \param time of initialization 333 */ 334 void initRhs(double time) ; 335 336 /** set nonsmooth input to zero 337 * \param level input-level to be initialized. 338 */ 339 void initializeNonSmoothInput(unsigned int level) ; 340 341 /** update right-hand side for the current state 342 * \param time of interest 343 */ 344 virtual void computeRhs(double time); 345 346 /** update \f$\nabla_x rhs\f$ for the current state 347 * \param time of interest 348 */ 349 virtual void computeJacobianRhsx(double time); 350 351 /** reset non-smooth part of the rhs (i.e. p), for all 'levels' */ 352 void resetAllNonSmoothParts(); 353 354 /** set nonsmooth part of the rhs (i.e. p) to zero for a given level 355 * \param level 356 */ 357 void resetNonSmoothPart(unsigned int level); 358 359 // -- forces -- 360 /** get forces 361 * \return pointer on a SiconosVector 362 */ forces() const363 inline SP::SiconosVector forces() const 364 { 365 return _wrench; 366 } 367 368 // -- Jacobian Forces w.r.t q -- 369 370 371 /** get JacobianqForces 372 * \return pointer on a SiconosMatrix 373 */ jacobianqForces() const374 inline SP::SiconosMatrix jacobianqForces() const 375 { 376 return _jacobianWrenchq; 377 } 378 379 /** get JacobianvForces 380 * \return pointer on a SiconosMatrix 381 */ jacobianvForces() const382 inline SP::SiconosMatrix jacobianvForces() const 383 { 384 return _jacobianWrenchTwist; 385 } 386 387 ///@} 388 389 /*! @name Attributes access 390 @{ */ 391 392 393 /** Returns dimension of vector q */ getqDim() const394 virtual inline unsigned int getqDim() const 395 { 396 return _qDim; 397 } 398 399 // -- q -- 400 401 /** get q (pointer link) 402 * \return pointer on a SiconosVector 403 */ q() const404 inline SP::SiconosVector q() const 405 { 406 return _q; 407 } 408 409 /** set value of generalized coordinates vector (copy) 410 * \param newValue 411 */ 412 virtual void setQ(const SiconosVector& newValue); 413 414 /** set value of generalized coordinates vector (pointer link) 415 * \param newPtr 416 */ 417 virtual void setQPtr(SP::SiconosVector newPtr); 418 419 /** set initial state (copy) 420 * \param newValue 421 */ 422 void setQ0(const SiconosVector& newValue); 423 424 /** set initial state (pointer link) 425 * \param newPtr 426 */ 427 void setQ0Ptr(SP::SiconosVector newPtr); 428 429 // -- twist -- 430 431 /** get twist 432 * \return pointer on a SiconosVector 433 */ twist() const434 inline SP::SiconosVector twist() const 435 { 436 return _twist; 437 } 438 439 /** get twist 440 * \return pointer on a SiconosVector 441 * this accessor is left to get a uniform access to velocity. 442 * This should be removed with MechanicalDS class 443 */ velocity() const444 inline SP::SiconosVector velocity() const 445 { 446 return _twist; 447 } 448 twist0() const449 inline SP::SiconosVector twist0() const 450 { 451 return _twist0; 452 } 453 velocity0() const454 inline SP::SiconosVector velocity0 455 () const 456 { 457 return _twist0; 458 } 459 /** set velocity (copy) 460 * \param newValue 461 */ 462 void setVelocity(const SiconosVector& newValue); 463 464 /** set velocity (pointer link) 465 * \param newPtr 466 */ 467 void setVelocityPtr(SP::SiconosVector newPtr) ; 468 469 /** set initial velocity (copy) 470 * \param newValue 471 */ 472 void setVelocity0(const SiconosVector& newValue); 473 474 /** set initial velocity (pointer link) 475 * \param newPtr 476 */ 477 void setVelocity0Ptr(SP::SiconosVector newPtr) ; 478 479 /** get acceleration (pointer link) 480 * \return pointer on a SiconosVector 481 */ acceleration() const482 SP::SiconosVector acceleration() const 483 { 484 return _acceleration; 485 }; 486 487 /** default function to compute the mass 488 */ computeMass()489 virtual void computeMass() {}; 490 491 /** function to compute the mass 492 * \param position value used to evaluate the mass matrix 493 */ computeMass(SP::SiconosVector position)494 virtual void computeMass(SP::SiconosVector position) {}; 495 496 /** Get the linear velocity in the absolute (inertial) or relative 497 * (body) frame of reference. 498 * \param absoluteRef If true, velocity is returned in the inertial 499 * frame, otherwise velocity is returned in the 500 * body frame. 501 * \return A SiconosVector of size 3 containing the linear velocity 502 * of this dynamical system. 503 */ 504 SP::SiconosVector linearVelocity(bool absoluteRef) const; 505 506 /** Fill a SiconosVector with the linear velocity in the absolute 507 * (inertial) or relative (body) frame of reference. 508 * \param absoluteRef If true, velocity is returned in the inertial 509 * frame, otherwise velocity is returned in the 510 * body frame. 511 * \param v A SiconosVector of size 3 to receive the linear velocity. 512 */ 513 void linearVelocity(bool absoluteRef, SiconosVector &v) const; 514 515 /** Get the angular velocity in the absolute (inertial) or relative 516 * (body) frame of reference. 517 * \param absoluteRef If true, velocity is returned in the inertial 518 * frame, otherwise velocity is returned in the 519 * body frame. 520 * \return A SiconosVector of size 3 containing the angular velocity 521 * of this dynamical system. 522 */ 523 SP::SiconosVector angularVelocity(bool absoluteRef) const; 524 525 /** Fill a SiconosVector with the angular velocity in the absolute 526 * (inertial) or relative (body) frame of reference. 527 * \param absoluteRef If true, velocity is returned in the inertial 528 * frame, otherwise velocity is returned in the 529 * body frame. 530 * \param w A SiconosVector of size 3 to receive the angular velocity. 531 */ 532 void angularVelocity(bool absoluteRef, SiconosVector &w) const; 533 534 // -- p -- 535 536 537 538 539 // -- Mass -- 540 541 /** get mass value 542 * \return a double 543 */ scalarMass() const544 inline double scalarMass() const 545 { 546 return _scalarMass; 547 }; 548 549 /** Modify the scalar mass */ setScalarMass(double mass)550 void setScalarMass(double mass) 551 { 552 _scalarMass = mass; 553 updateMassMatrix(); 554 }; 555 556 /* Get the inertia matrix 557 * \return a SP::SimpleMatrix 558 */ inertia()559 SP::SiconosMatrix inertia() 560 { 561 return _I; 562 }; 563 564 /* Modify the inertia matrix (pointer link) 565 \param newInertia the new inertia matrix 566 */ setInertia(SP::SiconosMatrix newInertia)567 void setInertia(SP::SiconosMatrix newInertia) 568 { 569 _I = newInertia; 570 updateMassMatrix(); 571 } 572 573 /* Modify the inertia matrix. 574 \param ix x component 575 \param iy y component 576 \param iz z component 577 */ 578 void setInertia(double ix, double iy, double iz); 579 580 /** to be called after scalar mass or inertia matrix have changed */ 581 void updateMassMatrix(); 582 583 // -- Fext -- 584 /** get fExt 585 * \return pointer on a plugged vector 586 */ fExt() const587 inline SP::SiconosVector fExt() const 588 { 589 return _fExt; 590 } 591 592 /** set fExt to pointer newPtr 593 * \param newPtr a SP to a Simple vector 594 */ setFExtPtr(SP::SiconosVector newPtr)595 inline void setFExtPtr(SP::SiconosVector newPtr) 596 { 597 _fExt = newPtr; 598 _hasConstantFExt = true; 599 } 600 601 /** set mExt to pointer newPtr 602 * \param newPtr a SP to a Simple vector 603 */ setMExtPtr(SP::SiconosVector newPtr)604 inline void setMExtPtr(SP::SiconosVector newPtr) 605 { 606 _mExt = newPtr; 607 _hasConstantMExt = true; 608 } 609 610 /** get mGyr 611 * \return pointer on a plugged vector 612 */ mGyr() const613 inline SP::SiconosVector mGyr() const 614 { 615 return _mGyr; 616 } 617 T()618 inline SP::SimpleMatrix T() 619 { 620 return _T; 621 } Tdot()622 inline SP::SimpleMatrix Tdot() 623 { 624 assert(_Tdot); 625 return _Tdot; 626 } 627 dotq()628 inline SP::SiconosVector dotq() 629 { 630 return _dotq; 631 } 632 633 /** @} end of members access group. */ 634 635 /*! @name Memory vectors management */ 636 //@{ 637 638 /** get all the values of the state vector q stored in memory 639 * \return a memory 640 */ qMemory()641 inline const SiconosMemory& qMemory() 642 { 643 return _qMemory; 644 } 645 646 647 /** get all the values of the state vector twist stored in memory 648 * \return a memory 649 */ twistMemory()650 inline const SiconosMemory& twistMemory() 651 { 652 return _twistMemory; 653 } 654 /** get all the values of the state vector twist stored in memory 655 * \return a memory 656 */ velocityMemory()657 inline const SiconosMemory& velocityMemory() 658 { 659 return _twistMemory; 660 } 661 662 /** initialize the SiconosMemory objects with a positive size. 663 * \param steps the size of the SiconosMemory (i) 664 */ 665 void initMemory(unsigned int steps); 666 667 /** push the current values of x, q and r in the stored previous values 668 * xMemory, qMemory, rMemory, 669 * \todo Modify the function swapIn Memory with the new Object Memory 670 */ 671 void swapInMemory(); 672 forcesMemory()673 inline const SiconosMemory& forcesMemory() 674 { 675 return _forcesMemory; 676 } 677 dotqMemory()678 inline const SiconosMemory& dotqMemory() 679 { 680 return _dotqMemory; 681 } 682 683 684 /** @} end of memory group. */ 685 686 /*! @name Miscellaneous public methods */ 687 //@{ 688 689 /** To compute the kinetic energy 690 */ 691 double computeKineticEnergy(); 692 693 // --- miscellaneous --- 694 695 /** print the data to the screen 696 */ 697 void display(bool brief = true) const; 698 699 // inline SP::SiconosMatrix jacobianZFL() const { return jacobianZFL; } 700 setIsMextExpressedInInertialFrame(bool value)701 inline void setIsMextExpressedInInertialFrame(bool value) 702 { 703 _isMextExpressedInInertialFrame= value; 704 if(!_jacobianMExtq) 705 _jacobianMExtq.reset(new SimpleMatrix(3, _qDim)); 706 if(!_jacobianWrenchq) 707 _jacobianWrenchq.reset(new SimpleMatrix(_ndof, _qDim)); 708 } 709 setNullifyMGyr(bool value)710 inline void setNullifyMGyr(bool value) 711 { 712 _nullifyMGyr = value; 713 } 714 715 virtual void normalizeq(); 716 717 /** Allocate memory for the lu factorization of the mass of the system. 718 Useful for some integrators with system inversion involving the mass 719 */ 720 void init_inverse_mass(); 721 722 /** Update the content of the lu factorization of the mass of the system, 723 if required. 724 */ 725 void update_inverse_mass(); 726 727 //@} 728 729 730 /*! @name Plugins management */ 731 732 //@{ 733 setComputeJacobianFIntqByFD(bool value)734 inline void setComputeJacobianFIntqByFD(bool value) 735 { 736 _computeJacobianFIntqByFD=value; 737 } setComputeJacobianFIntvByFD(bool value)738 inline void setComputeJacobianFIntvByFD(bool value) 739 { 740 _computeJacobianFInttwistByFD=value; 741 } setComputeJacobianMIntqByFD(bool value)742 inline void setComputeJacobianMIntqByFD(bool value) 743 { 744 _computeJacobianMIntqByFD=value; 745 } setComputeJacobianMIntvByFD(bool value)746 inline void setComputeJacobianMIntvByFD(bool value) 747 { 748 _computeJacobianMInttwistByFD=value; 749 } 750 751 752 /** allow to set a specified function to compute _fExt 753 * \param pluginPath the complete path to the plugin 754 * \param functionName the name of the function to use in this plugin 755 */ setComputeFExtFunction(const std::string & pluginPath,const std::string & functionName)756 void setComputeFExtFunction(const std::string& pluginPath, const std::string& functionName) 757 { 758 _pluginFExt->setComputeFunction(pluginPath, functionName); 759 if(!_fExt) 760 _fExt.reset(new SiconosVector(3, 0)); 761 _hasConstantFExt = false; 762 } 763 /** allow to set a specified function to compute _mExt 764 * \param pluginPath the complete path to the plugin 765 * \param functionName the name of the function to use in this plugin 766 */ setComputeMExtFunction(const std::string & pluginPath,const std::string & functionName)767 void setComputeMExtFunction(const std::string& pluginPath, const std::string& functionName) 768 { 769 _pluginMExt->setComputeFunction(pluginPath, functionName); 770 if(!_mExt) 771 _mExt.reset(new SiconosVector(3, 0)); 772 _hasConstantMExt = false; 773 } 774 775 /** set a specified function to compute _fExt 776 * \param fct a pointer on the plugin function 777 */ setComputeFExtFunction(FExt_NE fct)778 void setComputeFExtFunction(FExt_NE fct) 779 { 780 _pluginFExt->setComputeFunction((void*)fct); 781 if(!_fExt) 782 _fExt.reset(new SiconosVector(3, 0)); 783 _hasConstantFExt = false; 784 } 785 786 /** set a specified function to compute _mExt 787 * \param fct a pointer on the plugin function 788 */ setComputeMExtFunction(FExt_NE fct)789 void setComputeMExtFunction(FExt_NE fct) 790 { 791 _pluginMExt->setComputeFunction((void*)fct); 792 if(!_mExt) 793 _mExt.reset(new SiconosVector(3, 0)); 794 _hasConstantMExt = false; 795 } 796 797 /** allow to set a specified function to compute _fInt 798 * \param pluginPath the complete path to the plugin 799 * \param functionName the name of the function to use in this plugin 800 */ setComputeFIntFunction(const std::string & pluginPath,const std::string & functionName)801 void setComputeFIntFunction(const std::string& pluginPath, const std::string& functionName) 802 { 803 _pluginFInt->setComputeFunction(pluginPath, functionName); 804 if(!_fInt) 805 _fInt.reset(new SiconosVector(3, 0)); 806 } 807 /** allow to set a specified function to compute _mInt 808 * \param pluginPath the complete path to the plugin 809 * \param functionName the name of the function to use in this plugin 810 */ setComputeMIntFunction(const std::string & pluginPath,const std::string & functionName)811 void setComputeMIntFunction(const std::string& pluginPath, const std::string& functionName) 812 { 813 _pluginMInt->setComputeFunction(pluginPath, functionName); 814 if(!_mInt) 815 _mInt.reset(new SiconosVector(3, 0)); 816 } 817 818 /** set a specified function to compute _fInt 819 * \param fct a pointer on the plugin function 820 */ setComputeFIntFunction(FInt_NE fct)821 void setComputeFIntFunction(FInt_NE fct) 822 { 823 _pluginFInt->setComputeFunction((void*)fct); 824 if(!_fInt) 825 _fInt.reset(new SiconosVector(3, 0)); 826 } 827 828 /** set a specified function to compute _mInt 829 * \param fct a pointer on the plugin function 830 */ setComputeMIntFunction(FInt_NE fct)831 void setComputeMIntFunction(FInt_NE fct) 832 { 833 _pluginMInt->setComputeFunction((void*)fct); 834 if(!_mInt) 835 _mInt.reset(new SiconosVector(3, 0)); 836 } 837 838 /** allow to set a specified function to compute the jacobian w.r.t q of the internal forces 839 * \param pluginPath std::string : the complete path to the plugin 840 * \param functionName std::string : the name of the function to use in this plugin 841 */ 842 void setComputeJacobianFIntqFunction(const std::string& pluginPath, const std::string& functionName); 843 844 /** allow to set a specified function to compute the jacobian following v of the internal forces w.r.t. 845 * \param pluginPath std::string : the complete path to the plugin 846 * \param functionName std::string : the name of the function to use in this plugin 847 */ 848 void setComputeJacobianFIntvFunction(const std::string& pluginPath, const std::string& functionName); 849 850 /** set a specified function to compute jacobian following q of the FInt 851 * \param fct a pointer on the plugin function 852 */ 853 void setComputeJacobianFIntqFunction(FInt_NE fct); 854 855 /** set a specified function to compute jacobian following v of the FInt 856 * \param fct a pointer on the plugin function 857 */ 858 void setComputeJacobianFIntvFunction(FInt_NE fct); 859 860 /** allow to set a specified function to compute the jacobian w.r.t q of the internal forces 861 * \param pluginPath std::string : the complete path to the plugin 862 * \param functionName std::string : the name of the function to use in this plugin 863 */ 864 void setComputeJacobianMIntqFunction(const std::string& pluginPath, const std::string& functionName); 865 /** allow to set a specified function to compute the jacobian following v of the internal forces w.r.t. 866 * \param pluginPath std::string : the complete path to the plugin 867 * \param functionName std::string : the name of the function to use in this plugin 868 */ 869 void setComputeJacobianMIntvFunction(const std::string& pluginPath, const std::string& functionName); 870 871 /** set a specified function to compute jacobian following q of the FInt 872 * \param fct a pointer on the plugin function 873 */ 874 void setComputeJacobianMIntqFunction(FInt_NE fct); 875 876 /** set a specified function to compute jacobian following v of the FInt 877 * \param fct a pointer on the plugin function 878 */ 879 void setComputeJacobianMIntvFunction(FInt_NE fct); 880 881 /** function to compute the external forces 882 * \param time the current time 883 */ 884 virtual void computeFExt(double time); 885 886 /** default function to compute the external forces 887 * \param time the current time 888 * \param fExt the computed external force (in-out param) 889 */ 890 virtual void computeFExt(double time, SP::SiconosVector fExt); 891 892 /** function to compute the external moments 893 * The external moments are expressed by default in the body frame, since the Euler equation for 894 * Omega is written in the body--fixed frame. 895 * Nevertheless, if _isMextExpressedInInertialFrame) is set to true, we assume that 896 * the external moment is given in the inertial frame and we perform the rotation afterwards 897 * \param time the current time 898 * \param mExt the computed external moment (in-out param) 899 */ 900 virtual void computeMExt(double time, SP::SiconosVector mExt); 901 902 virtual void computeMExt(double time); 903 904 /** Adds a force/torque impulse to a body's FExt and MExt vectors in 905 * either absolute (inertial) or relative (body) frame. Modifies 906 * contents of _fExt and _mExt! Therefore these must have been set 907 * as constant vectors using setFExtPtr and setMExtPtr prior to 908 * calling this function. Adjustments to _mExt will take into 909 * account the value of _isMextExpressedInInertialFrame. 910 * \param force A force vector to be added. 911 * \param forceAbsRef If true, force is in inertial frame, otherwise 912 * it is in body frame. 913 * \param pos A position at which force should be applied. If nullptr, 914 * the center of mass is assumed. 915 * \param posAbsRef If true, pos is in inertial frame, otherwise it 916 * is in body frame. 917 */ 918 void addExtForceAtPos(SP::SiconosVector force, bool forceAbsRef, 919 SP::SiconosVector pos = SP::SiconosVector(), 920 bool posAbsRef = false); 921 922 void computeJacobianMExtqExpressedInInertialFrameByFD(double time, SP::SiconosVector q); 923 void computeJacobianMExtqExpressedInInertialFrame(double time, SP::SiconosVector q); 924 925 /** default function to compute the internal forces 926 * \param time the current time 927 */ 928 // void computeFInt(double time); 929 930 /** function to compute the internal forces 931 * \param time the current time 932 * \param q 933 * \param v 934 */ 935 void computeFInt(double time, SP::SiconosVector q, SP::SiconosVector v); 936 937 /** default function to compute the internal forces 938 * \param time the current time 939 * \param q 940 * \param v 941 * \param fInt the computed internal force vector 942 */ 943 virtual void computeFInt(double time, SP::SiconosVector q, SP::SiconosVector v, SP::SiconosVector fInt); 944 945 /** default function to compute the internal moments 946 * \param time the current time 947 * \param q 948 * \param v 949 */ 950 void computeMInt(double time, SP::SiconosVector q, SP::SiconosVector v); 951 952 /** default function to compute the internal moments 953 * \param time the current time 954 * \param q 955 * \param v 956 * \param mInt the computed internal moment vector 957 */ 958 virtual void computeMInt(double time, SP::SiconosVector q, SP::SiconosVector v, SP::SiconosVector mInt); 959 960 /**default function to update the plugins functions using a new time: 961 * \param time the current time 962 */ updatePlugins(double time)963 virtual void updatePlugins(double time) {}; 964 965 /** Allocate memory for forces and its jacobian. 966 */ 967 void init_forces(); 968 969 /** Default function to compute forces 970 * \param time double, the current time 971 */ 972 virtual void computeForces(double time); 973 974 /** function to compute forces with some specific values for q and twist (ie not those of the current state). 975 * \param time double : the current time 976 * \param q SP::SiconosVector: pointers on q 977 * \param twist SP::SiconosVector: pointers on twist 978 */ 979 virtual void computeForces(double time, 980 SP::SiconosVector q, 981 SP::SiconosVector twist); 982 983 /** Default function to compute the jacobian w.r.t. q of forces 984 * \param time double, the current time 985 */ 986 virtual void computeJacobianqForces(double time); 987 988 /** Default function to compute the jacobian w.r.t. v of forces 989 * \param time double, the current time 990 */ 991 virtual void computeJacobianvForces(double time); 992 993 994 /** function to compute gyroscopic forces with some specific values for q and twist (ie not those of the current state). 995 * \param twist SP::SiconosVector: pointers on twist vector 996 */ 997 virtual void computeMGyr(SP::SiconosVector twist); 998 999 /** function to compute gyroscopic forces with some specific values for q and twist (ie not those of the current state). 1000 * \param twist pointer to twist vector 1001 * \param mGyr pointer to gyroscopic forces 1002 */ 1003 virtual void computeMGyr(SP::SiconosVector twist, SP::SiconosVector mGyr); 1004 1005 1006 /** Default function to compute the jacobian following q of mGyr 1007 * \param time the current time 1008 */ 1009 virtual void computeJacobianMGyrtwist(double time); 1010 1011 /** Default function to compute the jacobian following q of mGyr 1012 * by forward finite difference 1013 * \param time the current time 1014 * \param q current state 1015 * \param twist pointer to twist vector 1016 */ 1017 virtual void computeJacobianMGyrtwistByFD(double time, SP::SiconosVector q, SP::SiconosVector twist); 1018 1019 // /** Default function to compute the jacobian following v of mGyr 1020 // * \param time the current time 1021 // */ 1022 // virtual void computeJacobianvForces(double time); 1023 1024 /** To compute the jacobian w.r.t q of the internal forces 1025 * \param time double : the current time 1026 */ 1027 void computeJacobianFIntq(double time); 1028 1029 /** To compute the jacobian w.r.t v of the internal forces 1030 * \param time double : the current time 1031 */ 1032 void computeJacobianFIntv(double time); 1033 1034 /** To compute the jacobian w.r.t q of the internal forces 1035 * \param time double 1036 * \param position SP::SiconosVector 1037 * \param twist SP::SiconosVector 1038 */ 1039 virtual void computeJacobianFIntq(double time, 1040 SP::SiconosVector position, 1041 SP::SiconosVector twist); 1042 /** To compute the jacobian w.r.t q of the internal forces 1043 * by forward finite difference 1044 * \param time double 1045 * \param position SP::SiconosVector 1046 * \param twist SP::SiconosVector 1047 */ 1048 void computeJacobianFIntqByFD(double time, 1049 SP::SiconosVector position, 1050 SP::SiconosVector twist); 1051 1052 1053 /** To compute the jacobian w.r.t. v of the internal forces 1054 * \param time double: the current time 1055 * \param position SP::SiconosVector 1056 * \param twist SP::SiconosVector 1057 */ 1058 virtual void computeJacobianFIntv(double time, 1059 SP::SiconosVector position, 1060 SP::SiconosVector twist); 1061 1062 /** To compute the jacobian w.r.t v of the internal forces 1063 * by forward finite difference 1064 * \param time double 1065 * \param position SP::SiconosVector 1066 * \param twist SP::SiconosVector 1067 */ 1068 void computeJacobianFIntvByFD(double time, 1069 SP::SiconosVector position, 1070 SP::SiconosVector twist); 1071 1072 1073 /** To compute the jacobian w.r.t q of the internal forces 1074 * \param time double : the current time 1075 */ 1076 virtual void computeJacobianMIntq(double time); 1077 1078 /** To compute the jacobian w.r.t v of the internal forces 1079 * \param time double : the current time 1080 */ 1081 virtual void computeJacobianMIntv(double time); 1082 1083 /** To compute the jacobian w.r.t q of the internal forces 1084 * \param time double : the current time, 1085 * \param position SP::SiconosVector 1086 * \param twist SP::SiconosVector 1087 */ 1088 virtual void computeJacobianMIntq(double time, 1089 SP::SiconosVector position, 1090 SP::SiconosVector twist); 1091 1092 /** To compute the jacobian w.r.t q of the internal moments 1093 * by forward finite difference 1094 * \param time double 1095 * \param position SP::SiconosVector 1096 * \param twist SP::SiconosVector 1097 */ 1098 void computeJacobianMIntqByFD(double time, 1099 SP::SiconosVector position, 1100 SP::SiconosVector twist); 1101 1102 1103 1104 1105 /** To compute the jacobian w.r.t. v of the internal forces 1106 * \param time double: the current time 1107 * \param position SP::SiconosVector 1108 * \param twist SP::SiconosVector 1109 */ 1110 virtual void computeJacobianMIntv(double time, 1111 SP::SiconosVector position, 1112 SP::SiconosVector twist); 1113 1114 /** To compute the jacobian w.r.t v of the internal moments 1115 * by forward finite difference 1116 * \param time double 1117 * \param position SP::SiconosVector 1118 * \param twist SP::SiconosVector 1119 */ 1120 void computeJacobianMIntvByFD(double time, 1121 SP::SiconosVector position, 1122 SP::SiconosVector twist); 1123 1124 virtual void computeT(); 1125 1126 virtual void computeTdot(); 1127 1128 //@} 1129 1130 1131 ACCEPT_STD_VISITORS(); 1132 1133 }; 1134 #endif // NEWTONEULERNLDS_H 1135