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