00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "simplesolver.h"
00010 #include <animal/value.h>
00011 #include <animal/linear.h>
00012 #include <animal/odeSolver.inl>
00013
00014 namespace animal
00015 {
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 template < class P, class V, class I, class R >
00026 SimpleSolver < P, V, I, R >::SimpleSolver ():OdeSolver < P, V,
00027 R > (), _gravity (Value < Vec >::zero ()), _useGravity (false),
00028 _exponentialDamping (0), _invMasses (0),
00029 _useExponentialDamping (false), _useMass (false), _useSingleMass (false)
00030 {
00031 }
00032 template < class P, class V, class I, class R > SimpleSolver < P,
00033 V, I, R >::~SimpleSolver ()
00034 {
00035 }
00036
00037 template < class P, class V, class I, class R >
00038 const typename SimpleSolver < P,
00039 V, I, R >::Vec & SimpleSolver < P, V, I, R >::get_gravity ()
00040 {
00041 return _gravity;
00042 }
00043
00045 template < class P, class V, class I, class R > void SimpleSolver < P,
00046 V, I, R >::set_gravity (const Vec & _newVal)
00047 {
00048 _gravity = _newVal;
00049 set_useGravity (true);
00050 }
00052 template < class P, class V, class I, class R >
00053 const bool & SimpleSolver < P, V, I, R >::get_useGravity ()
00054 {
00055 return _useGravity;
00056 }
00058 template < class P, class V, class I, class R > void SimpleSolver < P,
00059 V, I, R >::set_useGravity (const bool & _newVal)
00060 {
00061 _useGravity = _newVal;
00062 }
00064 template < class P, class V, class I, class R >
00065 const bool & SimpleSolver < P, V, I, R >::get_useExponentialDamping ()
00066 {
00067 return _useExponentialDamping;
00068 }
00070 template < class P, class V, class I, class R > void SimpleSolver < P,
00071 V, I, R >::set_useExponentialDamping (const bool & _newVal)
00072 {
00073 cerr<<"SimpleSolver::set_useExponentialDamping "<< _newVal << endl;
00074 _useExponentialDamping = _newVal;
00075 }
00077 template < class P, class V, class I, class R >
00078 const typename SimpleSolver < P,
00079 V, I, R >::Real & SimpleSolver < P, V, I, R >::get_exponentialDamping ()
00080 {
00081 return _exponentialDamping;
00082 }
00084 template < class P, class V, class I, class R > void SimpleSolver < P,
00085 V, I, R >::set_exponentialDamping (const Real & _newVal)
00086 {
00087 _exponentialDamping = _newVal;
00088 set_useExponentialDamping (true);
00089 }
00091 template < class P, class V, class I, class R > void SimpleSolver < P,
00092 V,
00093 I,
00094 R >::applyGravity (Vector & acc)
00095 {
00096 if (_useGravity)
00097 {
00098
00099 if (_useMass && !_useSingleMass)
00100 {
00101
00102 for (unsigned int i = 0; i < size (acc); ++i)
00103 if ((*_invMasses)[i] == 0)
00104 acc[i] = zero ();
00105 else v_peq(acc[i],_gravity);
00106 }
00107 else
00108 v_addall (acc, _gravity);
00109 }
00110
00111 }
00112
00114 template < class P, class V, class I, class R > void SimpleSolver < P,
00115 V,
00116 I,
00117 R >::computeAccelerations (Vector & acc, const
00118 Positions & pos, const Vector & vel)
00119 {
00120
00121 computeForces (acc, pos, vel);
00122
00123
00124 applyForces( acc, acc );
00125
00126
00127
00128 applyGravity( acc );
00129
00130 }
00131
00133 template < class P, class V, class I, class R > void SimpleSolver < P,
00134 V,
00135 I,
00136 R >::applyForces (V & acc, const V & f)
00137 {
00138 assert( size(acc)==size(f) );
00139
00140
00141
00142 if (_useMass)
00143 {
00144 if (_useSingleMass)
00145 v_eq_ab (acc, _singleInvMass, f );
00146 else
00147 for (unsigned int i = 0; i < size (acc); ++i)
00148 {
00149 v_eq_ab(acc[i], (*_invMasses)[i], f[i] );
00150 }
00151 }
00152 else
00153 {
00154 v_eq (acc, f);
00155 }
00156
00157
00158
00159
00160
00161 }
00163 template < class P, class V, class I, class R > void SimpleSolver < P,
00164 V, I, R >::solveODE (Positions & p, Vector & v, Real dt)
00165 {
00166 Parent::solveODE (p, v, dt);
00167 cerr<<"SimpleSolver::SolveODE" << endl;
00168
00169 if (_useExponentialDamping)
00170 {
00171 cerr<<"SimpleSolver::SolveODE, exponentialDamping= " << _exponentialDamping << endl;
00172 Real factor = exp (-_exponentialDamping * dt);
00173 v_teq (v, factor);
00174 }
00175 }
00177 template < class P, class V, class I, class R > void SimpleSolver < P,
00178 V, I, R >::computeForces (Vector & f, const Positions &, const Vector &)
00179 {
00180 v_assign (f, zero ());
00181 }
00183 template < class P, class V, class I, class R >
00184 const bool & SimpleSolver < P, V, I, R >::get_useMass ()
00185 {
00186 return _useMass;
00187 }
00189 template < class P, class V, class I, class R > void SimpleSolver < P,
00190 V, I, R >::set_useMass (const bool & _newVal)
00191 {
00192 _useMass = _newVal;
00193 }
00195 template < class P, class V, class I, class R >
00196 const bool & SimpleSolver < P, V, I, R >::get_useSingleMass ()
00197 {
00198 return _useSingleMass;
00199 }
00201 template < class P, class V, class I, class R > void SimpleSolver < P,
00202 V, I, R >::set_useSingleMass (const bool & _newVal)
00203 {
00204 _useSingleMass = _newVal;
00205 }
00207 template < class P, class V, class I, class R >
00208 const typename SimpleSolver < P,
00209 V, I, R >::InvMass & SimpleSolver < P, V, I, R >::get_singleInvMass ()
00210 {
00211 return _singleInvMass;
00212 }
00214 template < class P, class V, class I, class R > void SimpleSolver < P,
00215 V, I, R >::set_singleInvMass (const InvMass & _newVal)
00216 {
00217 _singleInvMass = _newVal;
00218 _useSingleMass = true;
00219 }
00221 template < class P, class V, class I, class R >
00222 const typename SimpleSolver < P,
00223 V, I, R >::InvMasses * SimpleSolver < P, V, I, R >::get_invMasses ()
00224 {
00225 return _invMasses;
00226 }
00228 template < class P, class V, class I, class R > void SimpleSolver < P,
00229 V, I, R >::set_invMasses (InvMasses * _newVal)
00230 {
00231 _invMasses = _newVal;
00232 set_useMass(true);
00233 set_useSingleMass(false);
00234 }
00235
00236
00237 }