RungeKutta2Solver.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/RungeKutta2Solver.h>
00026 #include <sofa/simulation/common/MechanicalVisitor.h>
00027 #include <sofa/core/ObjectFactory.h>
00028 #include <math.h>
00029 #include <iostream>
00030 using std::cerr;
00031 using std::endl;
00032
00033
00034 namespace sofa
00035 {
00036
00037 namespace component
00038 {
00039
00040 namespace odesolver
00041 {
00042
00043 using namespace core::componentmodel::behavior;
00044 using namespace sofa::defaulttype;
00045
00046 int RungeKutta2SolverClass = core::RegisterObject("A popular explicit time integrator")
00047 .add< RungeKutta2Solver >()
00048 .addAlias("RungeKutta2")
00049 ;
00050
00051 SOFA_DECL_CLASS(RungeKutta2);
00052
00053
00054 void RungeKutta2Solver::solve(double dt)
00055 {
00056
00057 MultiVector pos(this, VecId::position());
00058 MultiVector vel(this, VecId::velocity());
00059
00060
00061 MultiVector acc(this, VecId::V_DERIV);
00062 MultiVector newX(this, VecId::V_COORD);
00063 MultiVector newV(this, VecId::V_DERIV);
00064
00065 double startTime = this->getTime();
00066
00067 addSeparateGravity(dt);
00068
00069
00070 computeAcc (startTime, acc, pos, vel);
00071
00072
00073 #ifdef SOFA_NO_VMULTIOP // unoptimized version
00074 newX = pos;
00075 newX.peq(vel, dt/2.);
00076 newV = vel;
00077 newV.peq(acc, dt/2.);
00078 #else // single-operation optimization
00079 {
00080 simulation::MechanicalVMultiOpVisitor vmop;
00081 vmop.ops.resize(2);
00082 vmop.ops[0].first = (VecId)newX;
00083 vmop.ops[0].second.push_back(std::make_pair((VecId)pos,1.0));
00084 vmop.ops[0].second.push_back(std::make_pair((VecId)vel,dt/2));
00085 vmop.ops[1].first = (VecId)newV;
00086 vmop.ops[1].second.push_back(std::make_pair((VecId)vel,1.0));
00087 vmop.ops[1].second.push_back(std::make_pair((VecId)acc,dt/2));
00088 vmop.execute(this->getContext());
00089 }
00090 #endif
00091
00092
00093 computeAcc ( startTime+dt/2., acc, newX, newV);
00094
00095
00096 #ifdef SOFA_NO_VMULTIOP // unoptimized version
00097 pos.peq(newV,dt);
00098 vel.peq(acc,dt);
00099 #else // single-operation optimization
00100 {
00101 simulation::MechanicalVMultiOpVisitor vmop;
00102 vmop.ops.resize(2);
00103 vmop.ops[0].first = (VecId)pos;
00104 vmop.ops[0].second.push_back(std::make_pair((VecId)pos,1.0));
00105 vmop.ops[0].second.push_back(std::make_pair((VecId)newV,dt));
00106 vmop.ops[1].first = (VecId)vel;
00107 vmop.ops[1].second.push_back(std::make_pair((VecId)vel,1.0));
00108 vmop.ops[1].second.push_back(std::make_pair((VecId)acc,dt));
00109 vmop.execute(this->getContext());
00110 }
00111 #endif
00112 }
00113
00114
00115
00116 }
00117
00118 }
00119
00120 }
00121