void Simulation::computeLevelsForInputAndOutput(SP::Interaction inter, bool init) { DEBUG_PRINT("Simulation::computeLevelsForInputAndOutput(SP::Interaction inter, bool init)\n"); /** \warning. We test only for the first Dynamical of the interaction. * we assume that the osi(s) are consistent for one interaction */ SP::InteractionsGraph indexSet0 = model()->nonSmoothDynamicalSystem()->topology()->indexSet(0); SP::DynamicalSystem ds = indexSet0->properties(indexSet0->descriptor(inter)).source; // Note FP : we should probably connect osi and graph before, in simulation->initialize? DSOSIConstIterator it = _osiMap.find(ds); SP::OneStepIntegrator osi = it->second; if (!osi) RuntimeException::selfThrow("Simulation::computeLevelsForInputAndOutput osi does not exists"); indexSet0->properties(indexSet0->descriptor(inter)).osi = osi; std11::shared_ptr<SetupLevels> setupLevels; setupLevels.reset(new SetupLevels(shared_from_this(), inter, ds)); osi->accept(*(setupLevels.get())); if (!init) // We are not computing the levels at the initialization { SP::Topology topo = model()->nonSmoothDynamicalSystem()->topology(); unsigned int indxSize = topo->indexSetsSize(); assert (_numberOfIndexSets >0); if ((indxSize == LEVELMAX) || (indxSize < _numberOfIndexSets )) { topo->indexSetsResize(_numberOfIndexSets); // Init if the size has changed for (unsigned int i = indxSize; i < topo->indexSetsSize(); i++) // ++i ??? topo->resetIndexSetPtr(i); } } }
void Simulation::computeLevelsForInputAndOutput() { DEBUG_PRINT("Simulation::computeLevelsForInputAndOutput()\n"); SP::Topology topo = model()->nonSmoothDynamicalSystem()->topology(); InteractionsGraph::VIterator ui, uiend; SP::InteractionsGraph indexSet0 = topo->indexSet0(); for (std11::tie(ui, uiend) = indexSet0->vertices(); ui != uiend; ++ui) { computeLevelsForInputAndOutput(indexSet0->bundle(*ui), true); } unsigned int indxSize = topo->indexSetsSize(); if ((indxSize == LEVELMAX) || (indxSize < _numberOfIndexSets )) { topo->indexSetsResize(_numberOfIndexSets ); // Init if the size has changed for (unsigned int i = indxSize; i < topo->indexSetsSize(); i++) // ++i ??? topo->resetIndexSetPtr(i); } DEBUG_PRINTF("_numberOfIndexSets =%d\n", _numberOfIndexSets); DEBUG_PRINTF("_levelMinForInput =%d\n", _levelMinForInput); DEBUG_PRINTF("_levelMaxForInput =%d\n", _levelMaxForInput); DEBUG_PRINTF("_levelMinForOutput =%d\n", _levelMinForInput); DEBUG_PRINTF("_levelMaxForOutput =%d\n", _levelMaxForInput); }
void EventDriven::initOSNS() { assert(_nsds); assert(_nsds->topology()); // for all Interactions in indexSet[i-1], compute y[i-1] and // update the indexSet[i] // Note that interactions set may be empty. InteractionsGraph::VIterator ui, uiend; SP::Topology topo = _nsds->topology(); // === update all index sets === updateIndexSets(); initOSIRhs(); if (!_allNSProblems->empty()) // ie if at least a non smooth problem has been built. { OSI::TYPES osiType = (*_allOSI->begin())->getType(); if (osiType == OSI::LSODAROSI || osiType == OSI::HEM5OSI) //EventDriven associated with LsodarOSI OSI { } else if (osiType == OSI::NEWMARKALPHAOSI) // EventDriven associated with NewMarkAlpha { if (_allNSProblems->size() != 3) RuntimeException::selfThrow (" EventDriven::initialize, \n an EventDriven simulation associated with NewMarkAlphaOSI must have three non smooth problems.\n Here, there are " + _allNSProblems->size()); // Initialize OSNSP at position level (*_allNSProblems)[SICONOS_OSNSP_ED_SMOOTH_POS]->setInputOutputLevel(2); (*_allNSProblems)[SICONOS_OSNSP_ED_SMOOTH_POS]->setIndexSetLevel(2); (*_allNSProblems)[SICONOS_OSNSP_ED_SMOOTH_POS]->initialize(shared_from_this()); } else { RuntimeException::selfThrow(" EventDriven::initialize, OSI not yet implemented."); } if (!((*_allNSProblems)[SICONOS_OSNSP_ED_IMPACT])) /* ie if the impact problem does not * exist */ RuntimeException::selfThrow ("EventDriven::initialize, an EventDriven simulation must have an 'impact' non smooth problem."); if (!((*_allNSProblems)[SICONOS_OSNSP_ED_SMOOTH_ACC])) /* ie if the acceleration-level problem * does not exist */ RuntimeException::selfThrow ("EventDriven::initialize, an EventDriven simulation must have an 'acceleration' non smooth problem."); // Initialize OSNSP for impact problem and at the acceleration level // WARNING: only for Lagrangian systems - To be reviewed for other ones. (*_allNSProblems)[SICONOS_OSNSP_ED_IMPACT]->setInputOutputLevel(1); (*_allNSProblems)[SICONOS_OSNSP_ED_IMPACT]->setIndexSetLevel(1); (*_allNSProblems)[SICONOS_OSNSP_ED_IMPACT]->initialize(shared_from_this()); (*_allNSProblems)[SICONOS_OSNSP_ED_SMOOTH_ACC]->setInputOutputLevel(2); (*_allNSProblems)[SICONOS_OSNSP_ED_SMOOTH_ACC]->setIndexSetLevel(2); (*_allNSProblems)[SICONOS_OSNSP_ED_SMOOTH_ACC]->initialize(shared_from_this()); // // Detect NonSmoothEvent at the beginning of the simulation if( topo->indexSetsSize() > 1) { SP::InteractionsGraph indexSet1 = _nsds->topology()->indexSet(1); if (indexSet1->size() != 0) // There is one non-smooth event to be added { _eventsManager->scheduleNonSmoothEvent(*this, _eventsManager->startingTime(), false); }; } } }
void EventDriven::updateIndexSet(unsigned int i) { assert(_nsds); assert(_nsds->topology()); SP::Topology topo = _nsds->topology(); assert(i < topo->indexSetsSize() && "EventDriven::updateIndexSet(i), indexSets[i] does not exist."); // IndexSets[0] must not be updated in simulation, since it belongs to Topology. assert(i > 0 && "EventDriven::updateIndexSet(i=0), indexSets[0] cannot be updated."); // For all Interactions in indexSet[i-1], compute y[i-1] and // update the indexSet[i]. SP::InteractionsGraph indexSet1 = topo->indexSet(1); SP::InteractionsGraph indexSet2 = topo->indexSet(2); assert(_indexSet0); assert(indexSet1); assert(indexSet2); // DEBUG_PRINTF("update indexSets start : indexSet0 size : %ld\n", indexSet0->size()); // DEBUG_PRINTF("update IndexSets start : indexSet1 size : %ld\n", indexSet1->size()); // DEBUG_PRINTF("update IndexSets start : indexSet2 size : %ld\n", indexSet2->size()); InteractionsGraph::VIterator uibegin, uipend, uip; std11::tie(uibegin, uipend) = _indexSet0->vertices(); // loop over all vertices of the indexSet[i-1] for (uip = uibegin; uip != uipend; ++uip) { SP::Interaction inter = _indexSet0->bundle(*uip); if (i == 1) // IndexSet[1] { // if indexSet[1]=>getYRef(0): output y // if indexSet[2]=>getYRef(1): output ydot double y = inter->getYRef(0); // output to define the IndexSets at this Interaction if (y < -_TOL_ED) // y[0] < 0 { inter->display(); cout << "y = " << y << " < -_TOL_ED = " << -_TOL_ED <<endl; RuntimeException::selfThrow("EventDriven::updateIndexSet, output of level 0 must be positive!!! "); } // 1 - If the Interaction is not yet in the set if (!indexSet1->is_vertex(inter)) // Interaction is not yet in the indexSet[i] { if (fabs(y) <= _TOL_ED) { // vertex and edges insertions indexSet1->copy_vertex(inter, *_indexSet0); } } else // if the Interaction was already in the set { if (fabs(y) > _TOL_ED) { indexSet1->remove_vertex(inter); // remove the Interaction from IndexSet[1] inter->lambda(1)->zero(); // reset the lambda[1] to zero } } } else if (i == 2) // IndexSet[2] { if (indexSet1->is_vertex(inter)) // Interaction is in the indexSet[1] { double y = inter->getYRef(1); // output of level 1 at this Interaction if (!indexSet2->is_vertex(inter)) // Interaction is not yet in the indexSet[2] { if (fabs(y) <= _TOL_ED) { // vertex and edges insertions indexSet2->copy_vertex(inter, *_indexSet0); } } else // if the Interaction was already in the set { if (fabs(y) > _TOL_ED) { indexSet2->remove_vertex(inter); // remove the Interaction from IndexSet[1] inter->lambda(2)->zero(); // reset the lambda[i] to zero } } } else // Interaction is not in the indexSet[1] { if (indexSet2->is_vertex(inter)) // Interaction is in the indexSet[2] { indexSet2->remove_vertex(inter); // remove the Interaction from IndexSet[2] inter->lambda(2)->zero(); // reset the lambda[i] to zero } } } else { RuntimeException::selfThrow("EventDriven::updateIndexSet, IndexSet[i > 2] doesn't exist"); } } // DEBUG_PRINTF("update indexSets end : indexSet0 size : %ld\n", indexSet0->size()); // DEBUG_PRINTF("update IndexSets end : indexSet1 size : %ld\n", indexSet1->size()); // DEBUG_PRINTF("update IndexSets end : indexSet2 size : %ld\n", indexSet2->size()); }
void TimeStepping::updateIndexSet(unsigned int i) { // To update IndexSet i: add or remove Interactions from // this set, depending on y values. // boost::default_color_type is used to organize update in InteractionsGraph: // - white_color : undiscovered vertex (Interaction) // - gray_color : discovered vertex (Interaction) but searching descendants // - black_color : discovered vertex (Interaction) together with the descendants assert(_nsds); assert(_nsds->topology()); SP::Topology topo = _nsds->topology(); assert(i < topo->indexSetsSize() && "TimeStepping::updateIndexSet(i), indexSets[i] does not exist."); // IndexSets[0] must not be updated in simulation, since it belongs to Topology. assert(i > 0 && "TimeStepping::updateIndexSet(i=0), indexSets[0] cannot be updated."); // For all Interactions in indexSet[i-1], compute y[i-1] and // update the indexSet[i]. SP::InteractionsGraph indexSet0 = topo->indexSet(0); SP::InteractionsGraph indexSet1 = topo->indexSet(1); assert(indexSet0); assert(indexSet1); DynamicalSystemsGraph& DSG0= *nonSmoothDynamicalSystem()->dynamicalSystems(); topo->setHasChanged(false); DEBUG_PRINTF("TimeStepping::updateIndexSet(unsigned int i). update indexSets start : indexSet0 size : %ld\n", indexSet0->size()); DEBUG_PRINTF("TimeStepping::updateIndexSet(unsigned int i). update IndexSets start : indexSet1 size : %ld\n", indexSet1->size()); // Check indexSet1 InteractionsGraph::VIterator ui1, ui1end, v1next; std11::tie(ui1, ui1end) = indexSet1->vertices(); //Remove interactions from the indexSet1 for (v1next = ui1; ui1 != ui1end; ui1 = v1next) { ++v1next; SP::Interaction inter1 = indexSet1->bundle(*ui1); if (indexSet0->is_vertex(inter1)) { InteractionsGraph::VDescriptor inter1_descr0 = indexSet0->descriptor(inter1); assert((indexSet0->color(inter1_descr0) == boost::white_color)); indexSet0->color(inter1_descr0) = boost::gray_color; if (Type::value(*(inter1->nonSmoothLaw())) != Type::EqualityConditionNSL) { // We assume that the integrator of the ds1 drive the update of the index set //SP::OneStepIntegrator Osi = indexSet1->properties(*ui1).osi; SP::DynamicalSystem ds1 = indexSet1->properties(*ui1).source; OneStepIntegrator& osi = *DSG0.properties(DSG0.descriptor(ds1)).osi; //if(predictorDeactivate(inter1,i)) if (osi.removeInteractionFromIndexSet(inter1, i)) { // Interaction is not active // ui1 becomes invalid indexSet0->color(inter1_descr0) = boost::black_color; indexSet1->eraseProperties(*ui1); InteractionsGraph::OEIterator oei, oeiend; for (std11::tie(oei, oeiend) = indexSet1->out_edges(*ui1); oei != oeiend; ++oei) { InteractionsGraph::EDescriptor ed1, ed2; std11::tie(ed1, ed2) = indexSet1->edges(indexSet1->source(*oei), indexSet1->target(*oei)); if (ed2 != ed1) { indexSet1->eraseProperties(ed1); indexSet1->eraseProperties(ed2); } else { indexSet1->eraseProperties(ed1); } } indexSet1->remove_vertex(inter1); /* \warning V.A. 25/05/2012 : Multiplier lambda are only set to zero if they are removed from the IndexSet*/ inter1->lambda(1)->zero(); topo->setHasChanged(true); } } } else { // Interaction is not in indexSet0 anymore. // ui1 becomes invalid indexSet1->eraseProperties(*ui1); InteractionsGraph::OEIterator oei, oeiend; for (std11::tie(oei, oeiend) = indexSet1->out_edges(*ui1); oei != oeiend; ++oei) { InteractionsGraph::EDescriptor ed1, ed2; std11::tie(ed1, ed2) = indexSet1->edges(indexSet1->source(*oei), indexSet1->target(*oei)); if (ed2 != ed1) { indexSet1->eraseProperties(ed1); indexSet1->eraseProperties(ed2); } else { indexSet1->eraseProperties(ed1); } } indexSet1->remove_vertex(inter1); topo->setHasChanged(true); } } // indexSet0\indexSet1 scan InteractionsGraph::VIterator ui0, ui0end; //Add interaction in indexSet1 for (std11::tie(ui0, ui0end) = indexSet0->vertices(); ui0 != ui0end; ++ui0) { if (indexSet0->color(*ui0) == boost::black_color) { // reset indexSet0->color(*ui0) = boost::white_color ; } else { if (indexSet0->color(*ui0) == boost::gray_color) { // reset indexSet0->color(*ui0) = boost::white_color; assert(indexSet1->is_vertex(indexSet0->bundle(*ui0))); /*assert( { !predictorDeactivate(indexSet0->bundle(*ui0),i) || Type::value(*(indexSet0->bundle(*ui0)->nonSmoothLaw())) == Type::EqualityConditionNSL ; });*/ } else { assert(indexSet0->color(*ui0) == boost::white_color); SP::Interaction inter0 = indexSet0->bundle(*ui0); assert(!indexSet1->is_vertex(inter0)); bool activate = true; if (Type::value(*(inter0->nonSmoothLaw())) != Type::EqualityConditionNSL && Type::value(*(inter0->nonSmoothLaw())) != Type::RelayNSL) { //SP::OneStepIntegrator Osi = indexSet0->properties(*ui0).osi; // We assume that the integrator of the ds1 drive the update of the index set SP::DynamicalSystem ds1 = indexSet1->properties(*ui0).source; OneStepIntegrator& osi = *DSG0.properties(DSG0.descriptor(ds1)).osi; activate = osi.addInteractionInIndexSet(inter0, i); } if (activate) { assert(!indexSet1->is_vertex(inter0)); // vertex and edges insertion in indexSet1 indexSet1->copy_vertex(inter0, *indexSet0); topo->setHasChanged(true); assert(indexSet1->is_vertex(inter0)); } } } } assert(indexSet1->size() <= indexSet0->size()); DEBUG_PRINTF("TimeStepping::updateIndexSet(unsigned int i). update indexSets end : indexSet0 size : %ld\n", indexSet0->size()); DEBUG_PRINTF("TimeStepping::updateIndexSet(unsigned int i). update IndexSets end : indexSet1 size : %ld\n", indexSet1->size()); }