SolverSet createSolverEulerImplicitEulerImplicit(odesolver::EulerImplicitSolver& solver1, odesolver::EulerImplicitSolver& solver2) { odesolver::EulerImplicitSolver::SPtr solver = sofa::core::objectmodel::New<odesolver::EulerImplicitSolver>(); solver->f_rayleighStiffness.setValue( solver1.f_rayleighStiffness.getValue() < solver2.f_rayleighStiffness.getValue() ? solver1.f_rayleighStiffness.getValue() : solver2.f_rayleighStiffness.getValue() ); solver->f_rayleighMass.setValue( solver1.f_rayleighMass.getValue() < solver2.f_rayleighMass.getValue() ? solver1.f_rayleighMass.getValue() : solver2.f_rayleighMass.getValue() ); solver->f_velocityDamping.setValue( solver1.f_velocityDamping.getValue() > solver2.f_velocityDamping.getValue() ? solver1.f_velocityDamping.getValue() : solver2.f_velocityDamping.getValue()); return SolverSet(solver, createLinearSolver(&solver1, &solver2), createConstraintSolver(&solver1, &solver2)); }
Solution run_test(ODE& ode, TimeDisc& timeDisc, const unsigned num_timesteps) { using ODE_ = ODE; using ODET = ODETraits<ODE>; Solution sol; const int process_id = 0; NumLib::TimeDiscretizedODESystem<ODE_::ODETag, NLTag> ode_sys(process_id, ode, timeDisc); auto linear_solver = createLinearSolver(); auto conv_crit = std::make_unique<NumLib::ConvergenceCriterionDeltaX>( _tol, boost::none, MathLib::VecNormType::NORM2); auto nonlinear_solver = std::make_unique<NLSolver>(*linear_solver, _maxiter); NumLib::TimeLoopSingleODE<NLTag> loop(ode_sys, std::move(linear_solver), std::move(nonlinear_solver), std::move(conv_crit)); const double t0 = ODET::t0; const double t_end = ODET::t_end; const double delta_t = (num_timesteps == 0) ? -1.0 : ((t_end-t0) / num_timesteps); DBUG("Running test with %u timesteps of size %g s.", num_timesteps, delta_t); // initial condition GlobalVector x0(ode.getMatrixSpecifications(process_id).nrows); ODET::setIC(x0); sol.ts.push_back(t0); sol.solutions.push_back(x0); auto cb = [&sol](const double t, GlobalVector const& x) { sol.ts.push_back(t); sol.solutions.push_back(x); }; if (num_timesteps > 0) { EXPECT_TRUE(loop.loop(t0, x0, t_end, delta_t, cb)); } for (auto& x : sol.solutions) MathLib::LinAlg::setLocalAccessibleVector(x); return sol; }
SolverSet createSolverEulerImplicitRungeKutta4(odesolver::EulerImplicitSolver& solver1, odesolver::RungeKutta4Solver& solver2) { return SolverSet(copySolver<odesolver::EulerImplicitSolver>(solver1), createLinearSolver(&solver1, NULL), createConstraintSolver(&solver1, &solver2)); }
SolverSet createSolverStaticSolver(odesolver::StaticSolver& solver1, odesolver::StaticSolver& solver2) { return SolverSet(copySolver<odesolver::StaticSolver>(solver1), createLinearSolver(&solver1, &solver2), createConstraintSolver(&solver1, &solver2)); }