/* Siconos is a program dedicated to modeling, simulation and control * of non smooth dynamical systems. * * Copyright 2021 INRIA. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "MatrixIntegrator.hpp" #include "SiconosAlgebra.hpp" #include "FirstOrderLinearTIDS.hpp" #include "EventDriven.hpp" #include "SubPluggedObject.hpp" #include "LsodarOSI.hpp" #include "TimeDiscretisation.hpp" #include "NonSmoothDynamicalSystem.hpp" #include "EventsManager.hpp" //#define DEBUG_WHERE_MESSAGES // #define DEBUG_NOCOLOR // #define DEBUG_STDOUT // #define DEBUG_MESSAGES #include "siconos_debug.h" MatrixIntegrator::MatrixIntegrator(const DynamicalSystem& ds, const NonSmoothDynamicalSystem& nsds, const TimeDiscretisation & td, SP::SiconosMatrix E): _E(E) { commonInit(ds, nsds, td); _mat.reset(new SimpleMatrix(*E)); _mat->zero(); } MatrixIntegrator::MatrixIntegrator(const DynamicalSystem& ds, const NonSmoothDynamicalSystem& nsds, const TimeDiscretisation & td, SP::PluggedObject plugin, const unsigned int p): _plugin(plugin) { commonInit(ds, nsds, td); unsigned int n = ds.n(); _mat.reset(new SimpleMatrix(n, p, 0)); _spo.reset(new SubPluggedObject(*_plugin, n, p)); std::static_pointer_cast(_DS)->setPluginB(_spo); _isConst = false; } MatrixIntegrator::MatrixIntegrator(const DynamicalSystem& ds, const NonSmoothDynamicalSystem& nsds, const TimeDiscretisation & td) { unsigned int n = ds.n(); _mat.reset(new SimpleMatrix(n, n, 0)); commonInit(ds, nsds, td); } void MatrixIntegrator::commonInit(const DynamicalSystem& ds, const NonSmoothDynamicalSystem& nsds, const TimeDiscretisation & td) { _TD.reset(new TimeDiscretisation(td)); DEBUG_EXPR(ds.display();); Type::Siconos dsType = Type::value(ds); if(dsType == Type::FirstOrderLinearTIDS) { _DS.reset(new FirstOrderLinearTIDS(static_cast(ds))); _isConst = _TD->hConst(); } else if(dsType == Type::FirstOrderLinearDS) { const FirstOrderLinearDS& cfolds = static_cast(ds); _DS.reset(new FirstOrderLinearDS(cfolds)); // std::static_pointer_cast(_DS)->zeroPlugin(); if(cfolds.getPluginA()->isPlugged()) { std::static_pointer_cast(_DS)->setPluginA(cfolds.getPluginA()); } _isConst = (_TD->hConst()) && !(cfolds.getPluginA()->isPlugged()) ? true : false; } _DS->setNumber(9999999); DEBUG_EXPR(_DS->display();); // integration stuff _nsds.reset(new NonSmoothDynamicalSystem(nsds.t0(), nsds.finalT())); _OSI.reset(new LsodarOSI()); _nsds->insertDynamicalSystem(_DS); _sim.reset(new EventDriven(_nsds, _TD, 0)); _sim->associate(_OSI, _DS); _sim->setName("Matrix integrator simulation"); //change tolerance _OSI->setTol(1, 10 * MACHINE_PREC, 5 * MACHINE_PREC); } void MatrixIntegrator::integrate() { DEBUG_BEGIN("MatrixIntegrator::integrate()\n"); SiconosVector& x0 = *_DS->x0(); SiconosVector& x = *_DS->x(); SP::SiconosVector Ecol = static_cast(*_DS).b(); if(!Ecol && _E) { Ecol.reset(new SiconosVector(_DS->n(), 0)); static_cast(*_DS).setbPtr(Ecol); } unsigned int p = _mat->size(1); for(unsigned int i = 0; i < p; i++) { x0.zero(); if(_E) _E->getCol(i, *Ecol); else if(_plugin) _spo->setIndex(i); else x0(i) = 1; //Reset LsodarOSI //_OSI->setIsInitialized(false); _DS->resetToInitialState(); _sim->setIstate(1); _sim->advanceToEvent(); _mat->setCol(i, x); } _sim->processEvents(); //_DS->resetToInitialState(); DEBUG_EXPR(_mat->display();); DEBUG_EXPR(_DS->display();); DEBUG_END("MatrixIntegrator::integrate()\n"); }