1 /* Siconos is a program dedicated to modeling, simulation and control
2  * of non smooth dynamical systems.
3  *
4  * Copyright 2021 INRIA.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17 */
18 #include "Simulation.hpp"
19 #include "EventDriven.hpp"
20 #include "DynamicalSystem.hpp"
21 #include "NonSmoothDynamicalSystem.hpp"
22 #include "Topology.hpp"
23 #include "Interaction.hpp"
24 #include "Relation.hpp"
25 #include "EventsManager.hpp"
26 #include "LagrangianDS.hpp"
27 
28 // One Step Integrators
29 #include "OneStepIntegrator.hpp"
30 
31 // One Step Non Smooth Problems
32 #include "LCP.hpp"
33 #include "QP.hpp"
34 #include "Relay.hpp"
35 #include "NonSmoothLaw.hpp"
36 #include "TypeName.hpp"
37 // for Debug
38 //#define DEBUG_BEGIN_END_ONLY
39 // #define DEBUG_NOCOLOR
40 // #define DEBUG_STDOUT
41 // #define DEBUG_MESSAGES
42 #include "siconos_debug.h"
43 #include <fstream>
44 
45 // --- Constructor with a TimeDiscretisation (and thus a NonSmoothDynamicalSystem) and an
46 // --- id ---
Simulation(SP::NonSmoothDynamicalSystem nsds,SP::TimeDiscretisation td)47 Simulation::Simulation(SP::NonSmoothDynamicalSystem nsds, SP::TimeDiscretisation td):
48   _name("unnamed"), _tinit(0.0), _tend(0.0), _tout(0.0), _T(0.0),
49   _nsds(nsds),
50   _numberOfIndexSets(0),
51   _tolerance(DEFAULT_TOLERANCE), _printStat(false),
52   _staticLevels(false),_isInitialized(false)
53 {
54   if(!td)
55     THROW_EXCEPTION("Simulation constructor - timeDiscretisation == nullptr.");
56   _useRelativeConvergenceCriterion = false;
57   _relativeConvergenceCriterionHeld = false;
58   _relativeConvergenceTol = 10e-3;
59 
60   // === indexSets will be updated during initialize() call ===
61 
62   _allOSI.reset(new OSISet());
63   _allNSProblems.reset(new OneStepNSProblems());
64   _eventsManager.reset(new EventsManager(td)); //
65   _eventsManager->updateT(_nsds->finalT());
66 
67   _nsdsChangeLogPosition = _nsds->changeLogBegin();
68 }
69 
70 
71 
72 // --- Constructor with a TimeDiscretisation (and thus a Model) and an
73 // --- id ---
Simulation(SP::TimeDiscretisation td)74 Simulation::Simulation(SP::TimeDiscretisation td):
75   _name("unnamed"), _tinit(0.0), _tend(0.0), _tout(0.0), _T(0.0),
76   _numberOfIndexSets(0),
77   _tolerance(DEFAULT_TOLERANCE), _printStat(false),
78   _staticLevels(false), _useRelativeConvergenceCriterion(false),
79   _relativeConvergenceCriterionHeld(false), _relativeConvergenceTol(10e-3),
80   _isInitialized(false)
81 
82 {
83   if(!td)
84     THROW_EXCEPTION("Simulation constructor - timeDiscretisation == nullptr.");
85   _allOSI.reset(new OSISet());
86   _allNSProblems.reset(new OneStepNSProblems());
87   _eventsManager.reset(new EventsManager(td)); //
88   _eventsManager->updateT(_nsds->finalT());
89 }
90 
91 // --- Destructor ---
~Simulation()92 Simulation::~Simulation()
93 {
94   clear();
95   // -> see shared ressources for this
96   if(statOut.is_open()) statOut.close();
97 }
98 
getTk() const99 double Simulation::getTk() const
100 {
101   return _eventsManager->getTk();
102 }
103 
getTkp1() const104 double Simulation::getTkp1() const
105 {
106   return _eventsManager->getTkp1();
107 }
108 
getTkp2() const109 double Simulation::getTkp2() const
110 {
111   return _eventsManager->getTkp2();
112 }
113 
currentTimeStep() const114 double Simulation::currentTimeStep() const
115 {
116   return _eventsManager->currentTimeStep();
117 }
118 
startingTime() const119 double Simulation::startingTime() const
120 {
121   return _eventsManager->startingTime();
122 }
123 
nextTime() const124 double Simulation::nextTime() const
125 {
126   return _eventsManager->nextTime();
127 }
128 
hasNextEvent() const129 bool Simulation::hasNextEvent() const
130 {
131   return _eventsManager->hasNextEvent();
132 }
133 
134 
135 // clear all maps to break shared_ptr cycle
clear()136 void Simulation::clear()
137 {
138   if(_allOSI)
139   {
140     _allOSI->clear();
141   }
142   if(_allNSProblems)
143   {
144     _allNSProblems->clear();
145   }
146 }
147 
148 // Getters/setters
149 
insertIntegrator(SP::OneStepIntegrator osi)150 void Simulation::insertIntegrator(SP::OneStepIntegrator osi)
151 {
152   _allOSI->insert(osi);
153 }
154 
associate(SP::OneStepIntegrator osi,SP::DynamicalSystem ds)155 void Simulation::associate(SP::OneStepIntegrator osi, SP::DynamicalSystem ds)
156 {
157   _allOSI->insert(osi);
158 
159   _OSIDSmap[osi].push_back(ds);
160 
161 }
162 
indexSet(unsigned int i)163 SP::InteractionsGraph Simulation::indexSet(unsigned int i)
164 {
165   return _nsds->topology()->indexSet(i) ;
166 }
167 
oneStepNSProblem(int Id)168 SP::OneStepNSProblem Simulation::oneStepNSProblem(int Id)
169 {
170   if(!(*_allNSProblems)[Id])
171     THROW_EXCEPTION("Simulation - oneStepNSProblem(Id) - The One Step NS Problem is not in the simulation.");
172 
173   return (*_allNSProblems)[Id];
174 }
175 
updateIndexSets()176 void Simulation::updateIndexSets()
177 {
178 
179   DEBUG_BEGIN("Simulation::updateIndexSets()\n");
180   // update I0 indices
181   unsigned int nindexsets = _nsds->topology()->indexSetsSize();
182 
183   DEBUG_PRINTF("  nindexsets = %d\n", nindexsets);
184   if(nindexsets > 1)
185   {
186     for(unsigned int i = 1; i < nindexsets ; ++i)
187     {
188       updateIndexSet(i);
189       _nsds->topology()->indexSet(i)->update_vertices_indices();
190       _nsds->topology()->indexSet(i)->update_edges_indices();
191     }
192   }
193   DEBUG_END("Simulation::updateIndexSets()\n");
194 
195 }
196 
insertNonSmoothProblem(SP::OneStepNSProblem osns,int Id)197 void Simulation::insertNonSmoothProblem(SP::OneStepNSProblem osns, int Id)
198 {
199   if(_allNSProblems->size() > (unsigned int)Id)
200   {
201     if((*_allNSProblems)[Id])
202       THROW_EXCEPTION("Simulation - insertNonSmoothProblem(osns), trying to insert a OSNSP already existing. ");
203     (*_allNSProblems)[Id] = osns;
204   }
205   else
206   {
207     _allNSProblems->resize(Id+1);
208     (*_allNSProblems)[Id] = osns;
209   }
210 }
211 
initializeOSIAssociations()212 void Simulation::initializeOSIAssociations()
213 {
214   // 1-  OneStepIntegrators initialization ===
215   // we set the simulation pointer and the graph of DS in osi
216   for(OSIIterator itosi = _allOSI->begin();
217       itosi != _allOSI->end(); ++itosi)
218   {
219     if(!(*itosi)->isInitialized())
220     {
221       DEBUG_PRINT("- 1 - set simulation pointer  and the graph of ds in osi\n");
222       (*itosi)->setSimulationPtr(shared_from_this());
223       // a subgraph has to be implemented.
224       (*itosi)->setDynamicalSystemsGraph(_nsds->topology()->dSG(0));
225     }
226   }
227 
228   // 2 - we set the osi of DS that has been defined through associate(ds,osi)
229   std::map< SP::OneStepIntegrator, std::list<SP::DynamicalSystem> >::iterator  it;
230   std::list<SP::DynamicalSystem> ::iterator  itlist;
231   for(it = _OSIDSmap.begin();  it !=_OSIDSmap.end(); ++it)
232   {
233     DEBUG_PRINT("- 2 - we set the osi of DS that has been defined through associate(ds,osi)\n");
234     for(itlist = it->second.begin();  itlist !=it->second.end(); ++itlist)
235     {
236       SP::DynamicalSystem ds =  *itlist;
237       SP::OneStepIntegrator osi =it->first;
238 
239       _nsds->topology()->setOSI(ds, osi);
240     }
241     it->second.clear();
242   }
243 }
244 
initializeNSDSChangelog()245 void Simulation::initializeNSDSChangelog()
246 {
247   // 4- we initialize new  ds and interaction
248   /* Changes to the NSDS are tracked by a changelog, making it fast
249    * for the Simulation to scan any changes it has not yet seen and
250    * initialize the associated ata structures.  It is just an
251    * optimisation over scanning the whole NSDS for new elements at
252    * each step. */
253   SP::DynamicalSystemsGraph DSG = _nsds->topology()->dSG(0);
254   NonSmoothDynamicalSystem::ChangeLog::const_iterator& itc = _nsdsChangeLogPosition.it;
255 
256   bool interactionInitialized = false;
257   itc++;
258   while(itc != _nsds->changeLog().end())
259   {
260     DEBUG_PRINT("- 3 - we initialize new  ds and interaction \n");
261     DEBUG_PRINT("The nsds has changed\n")
262     const NonSmoothDynamicalSystem::Change& change = *itc;
263     itc++;
264 
265     DEBUG_EXPR(change.display());
266     if(change.typeOfChange == NonSmoothDynamicalSystem::addDynamicalSystem)
267     {
268       SP::DynamicalSystem ds = change.ds;
269       if(!DSG->properties(DSG->descriptor(ds)).osi)
270       {
271         if(_allOSI->size() == 0)
272           THROW_EXCEPTION
273           ("Simulation::initialize - there is no osi in this Simulation !!");
274         DEBUG_PRINTF("_allOSI->size() = %lu\n", _allOSI->size());
275         SP::OneStepIntegrator osi_default = *_allOSI->begin();
276         _nsds->topology()->setOSI(ds, osi_default);
277         if(_allOSI->size() > 1)
278         {
279           std::cout << "Warning. The simulation has multiple OneStepIntegrators "
280                     "(OSI) but the DS number " << ds->number() << " is not assigned to an "
281                     "OSI. We assign the following OSI to this DS." << std::endl;
282         }
283       }
284       OneStepIntegrator& osi = *DSG->properties(DSG->descriptor(ds)).osi;
285       osi.initializeWorkVectorsForDS(getTk(),ds);
286     }
287     else if(change.typeOfChange == NonSmoothDynamicalSystem::addInteraction)
288     {
289       SP::Interaction inter = change.i;
290       initializeInteraction(getTk(), inter);
291       interactionInitialized = true;
292     }
293     else if(change.typeOfChange == NonSmoothDynamicalSystem::rmDynamicalSystem)
294     {
295       // also need to force an update in this case since indexSet1 may
296       // still have Interactions that refer to DSs that are not in graph
297       interactionInitialized = true;
298     }
299   }
300   _nsdsChangeLogPosition = _nsds->changeLogPosition();
301 
302   // (re)initialize OneStepNSProblem(s) if necessary
303   if(interactionInitialized || !_isInitialized)
304   {
305     DEBUG_PRINT("(re)Initialize OneStepNSProblem(s)\n");
306     // Initialize OneStepNSProblem(s). Depends on the type of simulation.
307     // Warning FP : must be done in any case, even if the interactions set
308     // is empty.
309     initOSNS();
310 
311     // Since initOSNS calls updateIndexSets() which resets the
312     // topology->hasChanged() flag, it must be specified explicitly.
313     // Otherwise OneStepNSProblem may fail to update its matrices.
314     _nsds->topology()->setHasChanged(true);
315   }
316 }
317 
initializeIndexSets()318 void Simulation::initializeIndexSets()
319 {
320   // 3 - we finalize the initialization of osi
321 
322   // symmetry in indexSets Do we need it ?
323   _nsds->topology()->setProperties();
324 
325   // === OneStepIntegrators initialization ===
326   for(OSIIterator itosi = _allOSI->begin();
327       itosi != _allOSI->end(); ++itosi)
328   {
329     if(!(*itosi)->isInitialized())
330     {
331       DEBUG_PRINT("- 4 - we finalize the initialization of osi\n");
332       DEBUG_PRINT("osi->initialize\n")
333       (*itosi)->initialize();
334       _numberOfIndexSets = std::max<int>((*itosi)->numberOfIndexSets(), _numberOfIndexSets);
335     }
336   }
337 
338   SP::Topology topo = _nsds->topology();
339   unsigned int indxSize = topo->indexSetsSize();
340   assert(_numberOfIndexSets >0);
341   if((indxSize == LEVELMAX) || (indxSize < _numberOfIndexSets))
342   {
343     DEBUG_PRINT("Topology : a different number of indexSets has been found \n");
344     DEBUG_PRINT("Topology :  we resize the number of index sets \n");
345     topo->indexSetsResize(_numberOfIndexSets);
346     // Init if the size has changed
347     for(unsigned int i = indxSize; i < topo->indexSetsSize(); i++)  // ++i ???
348       topo->resetIndexSetPtr(i);
349   }
350 }
351 
initialize()352 void Simulation::initialize()
353 {
354   DEBUG_BEGIN("Simulation::initialize()");
355   DEBUG_EXPR_WE(std::cout << "Simulation name :"<< name() << std::endl;);
356 
357   // 1 - Process any pending OSI->DS associations
358   initializeOSIAssociations();
359 
360   // 2 - Initialize index sets for OSIs
361   initializeIndexSets();
362 
363   // 3 - allow the InteractionManager to add/remove any interactions it wants
364   updateWorldFromDS();
365   updateInteractions();
366 
367   // 4 - initialize new ds and interactions
368   initializeNSDSChangelog();
369 
370   // 5 - First initialization of the simulation
371   if(!_isInitialized)
372   {
373     DEBUG_PRINT(" - 6 - First initialization of the simulation\n");
374     _T = _nsds->finalT();
375 
376     // === Events manager initialization ===
377     _eventsManager->initialize(_T);
378     _tinit = _eventsManager->startingTime();
379 
380     // Process events at time _tinit. Useful to save values in memories
381     // for example.  Warning: can not be called during
382     // eventsManager->initialize, because it needs the initialization of
383     // OSI, OSNS ...
384     // _eventsManager->preUpdate(*this);
385 
386     _tend =  _eventsManager->nextTime();
387 
388     // End of initialize:
389 
390     //  - all OSI and OSNS (ie DS and Interactions) states are computed
391     //  - for time _tinit and saved into memories.
392     //  - Sensors or related objects are updated for t=_tinit.
393     //  - current time of the model is equal to t1, time of the first
394     //  - event after _tinit.
395     //  - currentEvent of the simu. corresponds to _tinit and nextEvent
396     //  - to _tend.
397 
398     _isInitialized = true;
399   }
400 
401 
402   DEBUG_END("Simulation::initialize()\n");
403 }
404 
initializeInteraction(double time,SP::Interaction inter)405 void Simulation::initializeInteraction(double time, SP::Interaction inter)
406 {
407   DEBUG_BEGIN("Simulation::initializeInteraction(double time, SP::Interaction inter)\n");
408   // Get the interaction properties from the topology for initialization.
409   SP::InteractionsGraph indexSet0 = _nsds->topology()->indexSet0();
410   InteractionsGraph::VDescriptor ui = indexSet0->descriptor(inter);
411 
412   // This calls computeOutput() and initializes qMemory and q_k.
413   DynamicalSystemsGraph &DSG = *_nsds->topology()->dSG(0);
414 
415   //SP::OneStepIntegrator osi = indexSet0->properties(ui).osi;
416   SP::DynamicalSystem ds1;
417   SP::DynamicalSystem ds2;
418   // --- Get the dynamical system(s) (edge(s)) connected to the current interaction (vertex) ---
419   if(indexSet0->properties(ui).source != indexSet0->properties(ui).target)
420   {
421     DEBUG_PRINT("a two DS Interaction\n");
422     ds1 = indexSet0->properties(ui).source;
423     ds2 = indexSet0->properties(ui).target;
424   }
425   else
426   {
427     DEBUG_PRINT("a single DS Interaction\n");
428     ds1 = indexSet0->properties(ui).source;
429     ds2 = ds1;
430     // \warning this looks like some debug code, but it gets executed even with NDEBUG.
431     // may be compiler does something smarter, but still it should be rewritten. --xhub
432     InteractionsGraph::OEIterator oei, oeiend;
433     for(std::tie(oei, oeiend) = indexSet0->out_edges(ui);
434         oei != oeiend; ++oei)
435     {
436       // note : at most 4 edges
437       ds2 = indexSet0->bundle(*oei);
438       if(ds2 != ds1)
439       {
440         assert(false);
441         break;
442       }
443     }
444   }
445   assert(ds1);
446   assert(ds2);
447 
448   OneStepIntegrator& osi1 = *DSG.properties(DSG.descriptor(ds1)).osi;
449   OneStepIntegrator& osi2 = *DSG.properties(DSG.descriptor(ds2)).osi;
450 
451   InteractionProperties& i_prop = indexSet0->properties(ui);
452   if(&osi1 == &osi2)
453   {
454     osi1.initializeWorkVectorsForInteraction(*inter, i_prop,  DSG);
455     osi1.update_interaction_output(*inter, time, i_prop);
456   }
457   else
458   {
459     osi1.initializeWorkVectorsForInteraction(*inter, i_prop,  DSG);
460     osi1.update_interaction_output(*inter, time, i_prop);
461     osi2.initializeWorkVectorsForInteraction(*inter, i_prop,  DSG);
462     osi2.update_interaction_output(*inter, time, i_prop);
463   }
464   DEBUG_END("Simulation::initializeInteraction(double time, SP::Interaction inter)\n");
465 }
466 
467 
468 
computeOneStepNSProblem(int Id)469 int Simulation::computeOneStepNSProblem(int Id)
470 {
471   DEBUG_BEGIN("Simulation::computeOneStepNSProblem(int Id)\n");
472   DEBUG_PRINTF("with Id = %i\n", Id);
473 
474   if(!(*_allNSProblems)[Id])
475     THROW_EXCEPTION("Simulation - computeOneStepNSProblem, OneStepNSProblem == nullptr, Id: " + std::to_string(Id));
476 
477   // Before compute, inform all OSNSs if topology has changed
478   if(_nsds->topology()->hasChanged())
479   {
480     for(OSNSIterator itOsns = _allNSProblems->begin();
481         itOsns != _allNSProblems->end(); ++itOsns)
482     {
483       (*itOsns)->setHasBeenUpdated(false);
484     }
485   }
486 
487   int info = (*_allNSProblems)[Id]->compute(nextTime());
488 
489   DEBUG_END("Simulation::computeOneStepNSProblem(int Id)\n");
490   return info;
491 }
492 
493 
y(unsigned int level,unsigned int coor)494 SP::SiconosVector Simulation::y(unsigned int level, unsigned int coor)
495 {
496   // return output(level) (ie with y[level]) for all Interactions.
497   // assert(level>=0);
498 
499   DEBUG_BEGIN("Simulation::output(unsigned int level, unsigned int coor)\n");
500   DEBUG_PRINTF("with level = %i and coor = %i \n", level,coor);
501 
502   InteractionsGraph::VIterator ui, uiend;
503   SP::Interaction inter;
504   SP::InteractionsGraph indexSet0 = _nsds->topology()->indexSet0();
505 
506   SP::SiconosVector y(new SiconosVector(_nsds->topology()->indexSet0()->size()));
507   int i=0;
508   for(std::tie(ui, uiend) = indexSet0->vertices(); ui != uiend; ++ui)
509   {
510     inter = indexSet0->bundle(*ui);
511     assert(inter->lowerLevelForOutput() <= level);
512     assert(inter->upperLevelForOutput() >= level);
513     y->setValue(i,inter->y(level)->getValue(coor));
514     i++;
515   }
516   DEBUG_END("Simulation::output(unsigned int level, unsigned int coor)\n");
517   return y;
518 }
519 
lambda(unsigned int level,unsigned int coor)520 SP::SiconosVector Simulation::lambda(unsigned int level, unsigned int coor)
521 {
522   // return input(level) (ie with lambda[level]) for all Interactions.
523   // assert(level>=0);
524 
525   DEBUG_BEGIN("Simulation::input(unsigned int level, unsigned int coor)\n");
526   DEBUG_PRINTF("with level = %i and coor = %i \n", level,coor);
527 
528   InteractionsGraph::VIterator ui, uiend;
529   SP::Interaction inter;
530   SP::InteractionsGraph indexSet0 = _nsds->topology()->indexSet0();
531 
532   SP::SiconosVector lambda(new SiconosVector(_nsds->topology()->indexSet0()->size()));
533   int i=0;
534   for(std::tie(ui, uiend) = indexSet0->vertices(); ui != uiend; ++ui)
535   {
536     inter = indexSet0->bundle(*ui);
537     assert(inter->lowerLevelForOutput() <= level);
538     assert(inter->upperLevelForOutput() >= level);
539     lambda->setValue(i,inter->lambda(level)->getValue(coor));
540     i++;
541   }
542   DEBUG_END("Simulation::input(unsigned int level, unsigned int coor)\n");
543   return lambda;
544 }
545 
546 
run()547 void Simulation::run()
548 {
549   unsigned int count = 0; // events counter.
550 
551   std::cout << " ==== Start of " << Type::name(*this) << " simulation - This may take a while ... ====" <<std::endl;
552   while(hasNextEvent())
553   {
554     advanceToEvent();
555     processEvents();
556     count++;
557   }
558   std::cout << "===== End of " << Type::name(*this) << " simulation. " << count << " events have been processed. ==== " <<std::endl;
559 }
560 
processEvents()561 void Simulation::processEvents()
562 {
563   DEBUG_BEGIN("void Simulation::processEvents()\n");
564   _eventsManager->processEvents(*this);
565 
566   if(_eventsManager->hasNextEvent())
567   {
568     // For TimeStepping Scheme, need to update IndexSets, but not for EventDriven scheme
569     if(Type::value(*this) != Type::EventDriven)
570     {
571       updateIndexSets();
572     }
573   }
574   DEBUG_END("void Simulation::processEvents()\n");
575 }
576 
clearNSDSChangeLog()577 void Simulation::clearNSDSChangeLog()
578 {
579   _nsds->clearChangeLogTo(_nsdsChangeLogPosition);
580 }
581 
updateT(double T)582 void Simulation::updateT(double T)
583 {
584   _T = T;
585   _eventsManager->updateT(T);
586 }
587 
588 
link(SP::Interaction inter,SP::DynamicalSystem ds1,SP::DynamicalSystem ds2)589 void Simulation::link(SP::Interaction inter,
590                       SP::DynamicalSystem ds1,
591                       SP::DynamicalSystem ds2)
592 {
593   DEBUG_PRINTF("link interaction : %d\n", inter->number());
594 
595   nonSmoothDynamicalSystem()->link(inter, ds1, ds2);
596 }
597 
unlink(SP::Interaction inter)598 void Simulation::unlink(SP::Interaction inter)
599 {
600   nonSmoothDynamicalSystem()->removeInteraction(inter);
601 }
602 
updateInteractions()603 void Simulation::updateInteractions()
604 {
605   // Update interactions if a manager was provided.  Changes will be
606   // detected by Simulation::initialize() changelog code.
607   if(_interman)
608     _interman->updateInteractions(shared_from_this());
609 }
610 
updateInput(unsigned int)611 void Simulation::updateInput(unsigned int)
612 {
613   DEBUG_BEGIN("Simulation::updateInput()\n");
614   OSIIterator itOSI;
615   // 1 - compute input (lambda -> r)
616   if(!_allNSProblems->empty())
617   {
618     for(itOSI = _allOSI->begin(); itOSI != _allOSI->end() ; ++itOSI)
619       (*itOSI)->updateInput(nextTime());
620     //_nsds->updateInput(nextTime(),levelInput);
621   }
622   DEBUG_END("Simulation::updateInput()\n");
623 }
624 
updateState(unsigned int)625 void Simulation::updateState(unsigned int)
626 {
627   DEBUG_BEGIN("Simulation::updateState()\n");
628   OSIIterator itOSI;
629   // 2 - compute state for each dynamical system
630   for(itOSI = _allOSI->begin(); itOSI != _allOSI->end() ; ++itOSI)
631     (*itOSI)->updateState();
632   /*Because the dof of DS have been updated,
633     the world (CAO for example) must be updated.*/
634   updateWorldFromDS();
635 
636   DEBUG_END("Simulation::updateState()\n");
637 }
638 
updateOutput(unsigned int)639 void Simulation::updateOutput(unsigned int)
640 {
641   DEBUG_BEGIN("Simulation::updateOutput()\n");
642 
643   // 3 - compute output ( x ... -> y)
644   if(!_allNSProblems->empty())
645   {
646     OSIIterator itOSI;
647     for(itOSI = _allOSI->begin(); itOSI != _allOSI->end() ; ++itOSI)
648       (*itOSI)->updateOutput(nextTime());
649   }
650   DEBUG_END("Simulation::updateOutput()\n");
651 }
652 
653 // void Simulation::prepareIntegratorForDS(SP::OneStepIntegrator osi,
654 //                                         SP::DynamicalSystem ds,
655 //                                         SP::Model m, double time)
656 // {
657 //   assert(m && m->nonSmoothDynamicalSystem() && "Simulation::prepareIntegratorForDS requires a Model with an NSDS.");
658 
659 //   /*
660 //    * Steps to be accomplished when adding a DS to a Model and
661 //    * Simulation:
662 //    *
663 //    * 1. Add the DS to model->_nsds (Model::insertDynamicalSystem(ds))
664 //    *    (assumed done before this function is called, everything else
665 //    *    done in this function)
666 //    *
667 //    * 2. Add the OSI to simulation->_allOSI (Simulation::insertIntegrator)
668 //    *
669 //    * 3. Assign the OSI to the DS via the pointer in
670 //    *   _nsds->_topology->_DSG properties for the DS (setOSI).  Since
671 //    *   _nsds is not necessarily available yet, so take it from Model.
672 //    *
673 //    * 4. If Simulation already initialized, then DS work vectors in
674 //    *    _dynamicalSystemsGraph properties for the DS must be
675 //    *    initialized (OSI::initializeWorkVectorsForDS), otherwise it will
676 //    *    be called later during Simulation::initialize().
677 //   */
678 
679 //   // Keep OSI in the set, no effect if already present.
680 //   insertIntegrator(osi);
681 
682 //   // Associate the OSI to the DS in the topology.
683 //   m->nonSmoothDynamicalSystem()->topology()->setOSI(ds, osi);
684 
685 //   // Prepare work vectors, etc.
686 //   // If OSI has no DSG yet, assume DS will be initialized later.
687 //   // (Typically, during Simulation::initialize())
688 //   if (osi->dynamicalSystemsGraph())
689 //     osi->initializeWorkVectorsForDS(*m, time, ds);
690 // }
691