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