EulerSolver.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <sofa/component/odesolver/EulerSolver.h>
00026 #include <sofa/simulation/common/MechanicalVisitor.h>
00027 #include <sofa/core/ObjectFactory.h>
00028 #include <math.h>
00029 #include <iostream>
00030
00031 using std::cerr;
00032 using std::endl;
00033
00034 namespace sofa
00035 {
00036
00037 namespace component
00038 {
00039
00040 namespace odesolver
00041 {
00042
00043 using namespace sofa::defaulttype;
00044 using namespace core::componentmodel::behavior;
00045
00046 int EulerSolverClass = core::RegisterObject("A simple explicit time integrator")
00047 .add< EulerSolver >()
00048 .addAlias("Euler")
00049 ;
00050
00051 SOFA_DECL_CLASS(Euler);
00052
00053 EulerSolver::EulerSolver()
00054 : symplectic( initData( &symplectic, true, "symplectic", "If true, the velocities are updated before the velocities and the method is symplectic (more robust). If false, the positions are updated before the velocities (standard Euler, less robust).") )
00055 {}
00056
00057 void EulerSolver::solve(double dt)
00058 {
00059 MultiVector pos(this, VecId::position());
00060 MultiVector vel(this, VecId::velocity());
00061 MultiVector acc(this, VecId::dx());
00062 MultiVector f(this, VecId::force());
00063 bool printLog = f_printLog.getValue();
00064
00065 if( printLog )
00066 {
00067 cerr<<"EulerSolver, dt = "<< dt <<endl;
00068 cerr<<"EulerSolver, initial x = "<< pos <<endl;
00069 cerr<<"EulerSolver, initial v = "<< vel <<endl;
00070 }
00071
00072 addSeparateGravity(dt);
00073 computeForce(f);
00074 accFromF(acc, f);
00075 projectResponse(acc);
00076
00077
00078 #ifdef SOFA_NO_VMULTIOP // unoptimized version
00079 if( symplectic.getValue() )
00080 {
00081 vel.peq(acc,dt);
00082 pos.peq(vel,dt);
00083 }
00084 else
00085 {
00086 pos.peq(vel,dt);
00087 vel.peq(acc,dt);
00088 }
00089 #else // single-operation optimization
00090 {
00091 simulation::MechanicalVMultiOpVisitor vmop;
00092 vmop.ops.resize(2);
00093
00094 int op_vel = (symplectic.getValue()?0:1);
00095 int op_pos = (symplectic.getValue()?1:0);
00096 vmop.ops[op_vel].first = (VecId)vel;
00097 vmop.ops[op_vel].second.push_back(std::make_pair((VecId)vel,1.0));
00098 vmop.ops[op_vel].second.push_back(std::make_pair((VecId)acc,dt));
00099 vmop.ops[op_pos].first = (VecId)pos;
00100 vmop.ops[op_pos].second.push_back(std::make_pair((VecId)pos,1.0));
00101 vmop.ops[op_pos].second.push_back(std::make_pair((VecId)vel,dt));
00102 vmop.execute(this->getContext());
00103 }
00104 #endif
00105
00106 if( printLog )
00107 {
00108 cerr<<"EulerSolver, acceleration = "<< acc <<endl;
00109 cerr<<"EulerSolver, final x = "<< pos <<endl;
00110 cerr<<"EulerSolver, final v = "<< vel <<endl;
00111 }
00112 }
00113
00114 }
00115
00116 }
00117
00118 }
00119