EulerSolver.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
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); // v += dt*g . Used if mass wants to added G separately from the other forces to v.
00073     computeForce(f);
00074     accFromF(acc, f);
00075     projectResponse(acc);
00076     
00077     // update state
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         // change order of operations depending on the sympletic flag
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 } // namespace odesolver
00115 
00116 } // namespace component
00117 
00118 } // namespace sofa
00119 

Generated on Sun Nov 23 03:42:46 2008 for Sofa by  doxygen 1.5.7.1