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
19 #include "TimeStepping.hpp"
20
21 #include "TimeSteppingDirectProjection.hpp"
22 #include "LagrangianDS.hpp"
23 #include "NewtonEulerDS.hpp"
24 #include "NewtonEuler1DR.hpp"
25 #include "OneStepIntegrator.hpp"
26 #include "NonSmoothLaw.hpp"
27 #include "NewtonEulerR.hpp"
28 #include "NonSmoothDynamicalSystem.hpp"
29 #include "OneStepNSProblem.hpp"
30 #include "MoreauJeanOSI.hpp"
31
32 static CheckSolverFPtr checkSolverOutputProjectOnConstraints = nullptr;
33 // #define DEBUG_NOCOLOR
34 // #define DEBUG_STDOUT
35 // #define DEBUG_MESSAGES
36 #include "siconos_debug.h"
37 //#define CORRECTIONSVELOCITIES
TimeSteppingDirectProjection(SP::NonSmoothDynamicalSystem nsds,SP::TimeDiscretisation td,SP::OneStepIntegrator osi,SP::OneStepNSProblem osnspb_velo,SP::OneStepNSProblem osnspb_pos,unsigned int level)38 TimeSteppingDirectProjection::TimeSteppingDirectProjection(
39 SP::NonSmoothDynamicalSystem nsds,
40 SP::TimeDiscretisation td,
41 SP::OneStepIntegrator osi,
42 SP::OneStepNSProblem osnspb_velo,
43 SP::OneStepNSProblem osnspb_pos,
44 unsigned int level)
45 : TimeStepping(nsds,td, osi, osnspb_velo)
46 {
47
48 //if (Type::value(osi) != Type::MoreauJeanDirectProjectionOSI)
49 OSI::TYPES typeOSI;
50 typeOSI = (osi)->getType();
51 if(typeOSI != OSI::MOREAUDIRECTPROJECTIONOSI)
52 THROW_EXCEPTION("TimeSteppingDirectProjection::TimeSteppingDirectProjection. wrong type of OneStepIntegrator");
53
54 (*_allNSProblems).resize(SICONOS_NB_OSNSP_TSP);
55 insertNonSmoothProblem(osnspb_pos, SICONOS_OSNSP_TS_POS);
56
57 _indexSetLevelForProjection = level;
58 _constraintTol = 1e-04;
59 _constraintTolUnilateral = 1e-08;
60 _projectionMaxIteration = 10;
61 _doProj = 1;
62 _doOnlyProj = 0;
63 _maxViolationUnilateral = 0.0;
64 _maxViolationEquality = 0.0;
65
66 }
67
68 // --- Destructor ---
~TimeSteppingDirectProjection()69 TimeSteppingDirectProjection::~TimeSteppingDirectProjection()
70 {
71 }
72
initOSNS()73 void TimeSteppingDirectProjection::initOSNS()
74 {
75 TimeStepping::initOSNS();
76
77 (*_allNSProblems)[SICONOS_OSNSP_TS_POS]->setIndexSetLevel(_indexSetLevelForProjection);
78 (*_allNSProblems)[SICONOS_OSNSP_TS_POS]->setInputOutputLevel(0);
79
80 (*_allNSProblems)[SICONOS_OSNSP_TS_VELOCITY]->setIndexSetLevel(1);
81 (*_allNSProblems)[SICONOS_OSNSP_TS_VELOCITY]->setInputOutputLevel(1);
82 }
83
nextStep()84 void TimeSteppingDirectProjection::nextStep()
85 {
86 TimeStepping::nextStep();
87
88
89 // Zeroing Lambda Muliplier of indexSet()
90
91 SP::InteractionsGraph indexSet = _nsds->topology()->indexSet(0);
92 InteractionsGraph::VIterator ui, uiend;
93 for(std::tie(ui, uiend) = indexSet->vertices(); ui != uiend; ++ui)
94 {
95 SP::Interaction inter = indexSet->bundle(*ui);
96 inter->lambda(0)->zero();
97 }
98
99 }
100
advanceToEvent()101 void TimeSteppingDirectProjection::advanceToEvent()
102 {
103
104 initialize();
105
106 /** First step, Solve the standard velocity formulation.*/
107
108 DEBUG_BEGIN("TimeStepping::newtonSolve\n");
109
110 if(!_doOnlyProj)
111 TimeStepping::newtonSolve(_newtonTolerance, _newtonMaxIteration);
112 else
113 updateInteractions();
114
115 DEBUG_EXPR_WE(std::cout << "TimeStepping::newtonSolve end : Number of iterations=" << getNewtonNbIterations() << "\n";
116 std::cout << " : newtonResiduDSMax=" << newtonResiduDSMax() << "\n";
117 std::cout << " : newtonResiduYMax=" << newtonResiduYMax() << "\n";
118 std::cout << " : newtonResiduRMax=" << newtonResiduRMax() << "\n";
119 );
120
121 if(!_doProj)
122 return;
123 int info = 0;
124
125 /** Second step, Perform the projection on constraints.*/
126
127 DEBUG_PRINT("TimeSteppingDirectProjection::newtonSolve begin projection:\n");
128
129 SP::DynamicalSystemsGraph dsGraph = _nsds->dynamicalSystems();
130
131
132 #ifdef TSPROJ_CORRECTIONVELOCITIES
133 for(DynamicalSystemsGraph::VIterator vi = dsGraph->begin(); vi != dsGraph->end(); ++vi)
134 {
135 SP::DynamicalSystem ds = dsGraph->bundle(*vi);
136 Type::Siconos dsType = Type::value(*ds);
137 if(dsType != Type::NewtonEulerDS)
138 THROW_EXCEPTION("TS:: - ds is not from NewtonEulerDS.");
139 SP::NewtonEulerDS neds = std::static_pointer_cast<NewtonEulerDS>(ds);
140 *(neds->deltaq()) = *(neds->q());
141 }
142 #endif
143
144 bool runningProjection = false;
145 _nbProjectionIteration = 0;
146 // for (InteractionsIterator it = allInteractions->begin(); it != allInteractions->end(); it++){
147 // double criteria = (*it)->relation()->y(0)->getValue(0);
148 // if (Type::value(*((*it)->nonSmoothLaw())) == Type::NewtonImpactFrictionNSL ||
149 // Type::value(*((*it)->nonSmoothLaw())) == Type::NewtonImpactNSL){
150 // SP::NewtonEuler1DR ri = std::static_pointer_cast<NewtonEuler1DR> ((*it)->relation());
151 // if (criteria < -1e-7){
152 // ri->_isOnContact=true;
153 // }else{
154 // ri->_isOnContact=false;
155 // }
156 // }
157 // if (criteria < -_constraintTol)
158 // runningNewton=true;
159 // }
160 if(_nsds->topology()->numberOfIndexSet() > _indexSetLevelForProjection)
161 computeCriteria(&runningProjection);
162 // Zeroing Lambda Muliplier of indexSet()
163
164 SP::InteractionsGraph indexSet = _nsds->topology()->indexSet(0);
165 InteractionsGraph::VIterator ui, uiend;
166 for(std::tie(ui, uiend) = indexSet->vertices(); ui != uiend; ++ui)
167 {
168 SP::Interaction inter = indexSet->bundle(*ui);
169 inter->lambda(0)->zero();
170 }
171 _nsds->updateInput(nextTime(),0);
172
173 //Store the q vector of each DS.
174
175 for(DynamicalSystemsGraph::VIterator aVi2 = dsGraph->begin(); aVi2 != dsGraph->end(); ++aVi2)
176 {
177 SP::DynamicalSystem ds = dsGraph->bundle(*aVi2);
178 Type::Siconos dsType = Type::value(*ds);
179 VectorOfVectors& workVectors = *dsGraph->properties(*aVi2).workVectors;
180 if(dsType == Type::NewtonEulerDS)
181 {
182 SP::NewtonEulerDS neds = std::static_pointer_cast<NewtonEulerDS>(ds);
183 *workVectors[MoreauJeanOSI::QTMP] = *neds->q();
184 }
185 else if(dsType == Type::LagrangianDS || dsType == Type::LagrangianLinearTIDS)
186 {
187 SP::LagrangianDS d = std::static_pointer_cast<LagrangianDS> (ds);
188 *workVectors[MoreauJeanOSI::QTMP] = * d->q();
189
190 }
191 else
192 THROW_EXCEPTION("TimeSteppingDirectProjection::advanceToEvent() :: - Ds is not from NewtonEulerDS neither from LagrangianDS.");
193 }
194
195 while(runningProjection && _nbProjectionIteration < _projectionMaxIteration)
196 {
197 _nbProjectionIteration++;
198 DEBUG_PRINTF("TimeSteppingDirectProjection projection step = %d\n", _nbProjectionIteration);
199
200 SP::InteractionsGraph indexSet = _nsds->topology()->indexSet(0);
201 InteractionsGraph::VIterator ui, uiend;
202 for(std::tie(ui, uiend) = indexSet->vertices(); ui != uiend; ++ui)
203 {
204 SP::Interaction inter = indexSet->bundle(*ui);
205 inter->lambda(0)->zero();
206 }
207 _nsds->updateInput(nextTime(),0);
208 info = 0;
209
210 DEBUG_PRINT("TimeSteppingProjectOnConstraint compute OSNSP.\n");
211
212 info = computeOneStepNSProblem(SICONOS_OSNSP_TS_POS);
213
214 DEBUG_PRINTF("IndexSet0->size() = %i\n", (int)_nsds->topology()->indexSet(0)->size());
215 DEBUG_PRINTF("IndexSet1->size() = %i\n", (int)_nsds->topology()->indexSet(1)->size());
216 DEBUG_EXPR(oneStepNSProblem(SICONOS_OSNSP_TS_POS)->display());
217
218
219 if(info && _warnOnNonConvergence)
220 {
221 std::cout << "[kernel] TimeSteppingDirectProjection::advanceToEvent() project on constraints. solver failed." <<std::endl ;
222 }
223 _nsds->updateInput(nextTime(),0);
224
225 DEBUG_EXPR_WE(std ::cout << "After update input" << std::endl;
226 SP::InteractionsGraph indexSet1 = _nsds->topology()->indexSet(1);
227 std ::cout << "lamda(1) in IndexSet1" << std::endl;
228 for(std::tie(ui, uiend) = indexSet1->vertices(); ui != uiend; ++ui)
229 {
230 SP::Interaction inter = indexSet1->bundle(*ui);
231 inter->lambda(1)->display();
232 }
233 SP::InteractionsGraph indexSet0 = _nsds->topology()->indexSet(0);
234 std ::cout << "lamda(0) in indexSet0" << std::endl;
235 for(std::tie(ui, uiend) = indexSet0->vertices(); ui != uiend; ++ui)
236 {
237 SP::Interaction inter = indexSet0->bundle(*ui);
238 inter->lambda(0)->display();
239 }
240 );
241
242 // This part should be in MoreauJeanOSIProjectOnConstraintsOS::updateState(level =0)
243 for(DynamicalSystemsGraph::VIterator aVi2 = dsGraph->begin(); aVi2 != dsGraph->end(); ++aVi2)
244 {
245 SP::DynamicalSystem ds = dsGraph->bundle(*aVi2);
246 VectorOfVectors& workVectors = *dsGraph->properties(*aVi2).workVectors;
247
248 Type::Siconos dsType = Type::value(*ds);
249 if(dsType == Type::NewtonEulerDS)
250 {
251 SP::NewtonEulerDS neds = std::static_pointer_cast<NewtonEulerDS>(ds);
252 SP::SiconosVector q = neds->q();
253 SP::SiconosVector qtmp = workVectors[MoreauJeanOSI::QTMP];
254
255 DEBUG_EXPR_WE(std ::cout << "qtmp before update " << std::endl;
256 qtmp->display();
257 std ::cout << "p(0) before update " << std::endl;
258 neds->p(0)->display();
259 );
260
261 if(neds->p(0))
262 {
263 //*q = * qtmp + *neds->p(0);
264 *q += *neds->p(0); // Why it works like that and not with the previous line ?
265 }
266
267 DEBUG_EXPR_WE(std ::cout << "q after update " << std::endl;
268 q->display(););
269
270 neds->normalizeq();
271 neds->computeT();
272 }
273 else if(dsType == Type::LagrangianDS || dsType == Type::LagrangianLinearTIDS)
274 {
275 SP::LagrangianDS d = std::static_pointer_cast<LagrangianDS> (ds);
276 SP::SiconosVector q = d->q();
277 SP::SiconosVector qtmp = workVectors[MoreauJeanOSI::QTMP];
278
279 if(d->p(0))
280 {
281 //*q = * qtmp + *d->p(0);
282 *q += *d->p(0);
283 }
284 }
285 else
286 THROW_EXCEPTION("TimeSteppingDirectProjection::advanceToEvent() :: - Ds is not from NewtonEulerDS neither from LagrangianDS.");
287
288 }
289
290 computeCriteria(&runningProjection);
291
292 //cout<<"|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| Z:"<<endl;
293 //(*_allNSProblems)[SICONOS_OSNSP_TS_POS]->display();
294 //(std::static_pointer_cast<LinearOSNS>((*_allNSProblems)[SICONOS_OSNSP_TS_POS]))->z()->display();
295
296 DEBUG_EXPR_WE(std::cout << "TimeSteppingDirectProjection::Projection end : Number of iterations=" << _nbProjectionIteration << "\n";
297 std ::cout << "After update state in position" << std::endl;
298 std ::cout << "lamda(1) in IndexSet1" << std::endl;
299 SP::InteractionsGraph indexSet1 = _nsds->topology()->indexSet(1);
300 SP::InteractionsGraph indexSet0 = _nsds->topology()->indexSet(0);
301
302 for(std::tie(ui, uiend) = indexSet1->vertices(); ui != uiend; ++ui)
303 {
304 SP::Interaction inter = indexSet1->bundle(*ui);
305 inter->lambda(1)->display();
306 }
307 std ::cout << "lamda(0) in indexSet0" << std::endl;
308 for(std::tie(ui, uiend) = indexSet0->vertices(); ui != uiend; ++ui)
309 {
310 SP::Interaction inter = indexSet0->bundle(*ui);
311 inter->lambda(0)->display();
312 }
313 std ::cout << "y(1) in IndexSet1" << std::endl; for(std::tie(ui, uiend) = indexSet1->vertices(); ui != uiend; ++ui)
314 {
315 SP::Interaction inter = indexSet1->bundle(*ui);
316 inter->y(1)->display();
317 }
318 std ::cout << "y(0) in indexSet0" << std::endl;
319 for(std::tie(ui, uiend) = indexSet0->vertices(); ui != uiend; ++ui)
320 {
321 SP::Interaction inter = indexSet0->bundle(*ui);
322 inter->y(0)->display();
323 }
324 );
325
326
327 //cout<<"during projection before normalizing of q:\n";
328 //for (InteractionsIterator it = allInteractions->begin(); it != allInteractions->end(); it++)
329 //{
330 // (*it)->relation()->computeh(getTkp1());
331 //}
332 }// end while(runningProjection && _nbProjectionIteration < _projectionMaxIteration)
333
334 // We update forces to start the Newton Loop the next tiem step with a correct value in swap
335 for(DynamicalSystemsGraph::VIterator aVi2 = dsGraph->begin(); aVi2 != dsGraph->end(); ++aVi2)
336 {
337 SP::DynamicalSystem ds = dsGraph->bundle(*aVi2);
338 Type::Siconos dsType = Type::value(*ds);
339 if(dsType == Type::NewtonEulerDS)
340 {
341 SP::NewtonEulerDS neds = std::static_pointer_cast<NewtonEulerDS>(ds);
342 double time = nextTime();
343 neds->computeForces(time, neds->q(), neds->twist());
344 }
345 else if(dsType == Type::LagrangianDS)
346 {
347 SP::LagrangianDS d = std::static_pointer_cast<LagrangianDS> (ds);
348 double time = nextTime();
349 d->computeForces(time, d->q(), d->velocity());
350 }
351 else if(dsType == Type::LagrangianLinearTIDS)
352 {
353 }
354 else
355 THROW_EXCEPTION("TimeSteppingCombinedProjection::advanceToEvent() - Ds is not from NewtonEulerDS neither from LagrangianDS.");
356 }
357
358
359
360
361
362
363
364 if(_nbProjectionIteration == _projectionMaxIteration && _warnOnNonConvergence)
365 {
366 std::cout << "[kernel] TimeSteppingDirectProjection::advanceToEvent() Max number of projection iterations reached (" << _nbProjectionIteration << ")" <<std::endl ;
367 printf("[kernel] max criteria equality = %e.\n", _maxViolationEquality);
368 printf("[kernel] max criteria unilateral = %e.\n", _maxViolationUnilateral);
369 }
370
371
372 DEBUG_END("TimeSteppingDirectProjection::newtonSolve()\n");
373
374 return;
375 //#ifdef TSPROJ_CORRECTIONVELOCITIES
376 // /*The following reduces the velocity because the position step increase the energy of the system. This formulation works only with simple systems.To activate it, comment the next line.*/
377
378 // for(DynamicalSystemsGraph::VIterator vi = dsGraph->begin(); vi != dsGraph->end(); ++vi)
379 // {
380 // SP::DynamicalSystem ds = dsGraph->bundle(*vi);
381 // Type::Siconos dsType = Type::value(*ds);
382 // if(dsType !=Type::NewtonEulerDS)
383 // THROW_EXCEPTION("TS:: - ds is not from NewtonEulerDS.");
384 // // SP::SiconosVector dotq = neds->dotq();
385 // // SP::SiconosVector q = neds->q();
386 // // SP::SiconosVector qold = neds->qMemory()->getSiconosVector(0);
387 // // double h = timeStep();
388 // // dotq->setValue(3,(q->getValue(3)-qold->getValue(3))/h);
389 // // dotq->setValue(4,(q->getValue(4)-qold->getValue(4))/h);
390 // // dotq->setValue(5,(q->getValue(5)-qold->getValue(5))/h);
391 // // dotq->setValue(6,(q->getValue(6)-qold->getValue(6))/h);
392
393 // /*compute the new velocity seeing the work of fext*/
394 // SP::NewtonEulerDS neds = std::static_pointer_cast<NewtonEulerDS>(ds);
395 // *(neds->deltaq())-=*(neds->q());
396 // DEBUG_EXPR(printf("TSProj NewtonSolve :deltaq:");
397 // (neds->deltaq())->display(););
398 // //continue;
399 // double n2q=neds->deltaq()->norm2();
400 // double n2=0.0;
401 // if(neds->fExt())
402 // n2=neds->fExt()->norm2();
403 // if(n2 > 1e-7 && n2q > 1e-14)
404 // {
405 // //if (n2q < 1e-14)
406 // // continue;
407
408 // SP::SiconosVector FextNorm(new SiconosVector(3));
409 // FextNorm->setValue(0,neds->fExt()->getValue(0));
410 // FextNorm->setValue(1,neds->fExt()->getValue(1));
411 // FextNorm->setValue(2,neds->fExt()->getValue(2));
412 // DEBUG_EXPR_WE(
413 // std::cout<<"TimeSteppingDirectProjection::newtonSolve deltaQ :\n";
414 // neds->deltaq()->display();
415 // std::cout<<"TimeSteppingDirectProjection::newtonSolve Fext :\n";
416 // FextNorm->display();
417 // );
418
419 // (*FextNorm)*=(1./n2);
420 // /*work of external forces.*/
421 // double workFext= neds->fExt()->getValue(0) * neds->deltaq()->getValue(0)+
422 // neds->fExt()->getValue(1) * neds->deltaq()->getValue(1)+
423 // neds->fExt()->getValue(2) * neds->deltaq()->getValue(2);
424 // //workFext*=2.0;
425 // double VkFNorm=FextNorm->getValue(0)*neds->velocity()->getValue(0)+
426 // FextNorm->getValue(1)*neds->velocity()->getValue(1)+
427 // FextNorm->getValue(2)*neds->velocity()->getValue(2);
428 // double VkcFNorm =VkFNorm;
429 // VkcFNorm= VkFNorm*VkFNorm - 2*fabs(workFext)/(neds->massValue());
430 // if(VkcFNorm >0)
431 // {
432 // if(VkFNorm>0)
433 // VkcFNorm=sqrt(VkcFNorm);
434 // else
435 // VkcFNorm=-sqrt(VkcFNorm);
436 // }
437 // else
438 // VkcFNorm=0;
439 // // if (VkFNorm >= 0 && workFext >0){
440 // // ;//VkcFNorm=sqrt (2*workFext/(neds->massValue())+VkFNorm*VkFNorm);
441 // // }else if (VkFNorm <= 0 && workFext < 0){
442 // // ;//VkcFNorm=-sqrt (fabs(2*workFext/(neds->massValue())+VkFNorm*VkFNorm));
443 // // }else if (VkFNorm > 0 && workFext <0){
444 // // VkcFNorm= VkFNorm*VkFNorm + 2*workFext/(neds->massValue());
445 // // if (VkcFNorm >0)
446 // // VkcFNorm=sqrt(VkcFNorm);
447 // // else
448 // // VkcFNorm=0;
449 // // }else if (VkFNorm < 0 && workFext > 0){
450 // // VkcFNorm= VkFNorm*VkFNorm - 2*workFext/(neds->massValue());
451 // // if (VkcFNorm >0)
452 // // VkcFNorm=-sqrt(VkcFNorm);
453 // // else
454 // // VkcFNorm=0;
455 // // }
456 // DEBUG_EXPR_WE(
457 // printf("TimeSteppingDirectProjection::newtonSolve velocity before update(prevComp=%e, newComp=%e)\n",VkFNorm,VkcFNorm);
458 // printf("VELOCITY1 ");
459 // neds->velocity()->display();
460 // );
461 // neds->velocity()->setValue(0,neds->velocity()->getValue(0)+(VkcFNorm - VkFNorm)*FextNorm->getValue(0));
462 // neds->velocity()->setValue(1,neds->velocity()->getValue(1)+(VkcFNorm - VkFNorm)*FextNorm->getValue(1));
463 // neds->velocity()->setValue(2,neds->velocity()->getValue(2)+(VkcFNorm - VkFNorm)*FextNorm->getValue(2));
464 // DEBUG_EXPR_WE(
465 // std::cout<<"TimeSteppingDirectProjection::newtonSolve velocity updated\n";
466 // printf("VELOCITY2 ");
467 // neds->velocity()->display();
468 // )
469 // }
470 // SP::SiconosMatrix T = neds->T();
471 // SP::SiconosVector dotq = neds->dotq();
472 // prod(*T,*neds->velocity(),*dotq,true);
473 // if(!_allNSProblems->empty())
474 // {
475 // for(unsigned int level = _levelMinForOutput;
476 // level < _levelMaxForOutput;
477 // level++)
478 // updateOutput(level);
479 // }
480 // }
481 //#endif
482
483 }
484
computeCriteria(bool * runningProjection)485 void TimeSteppingDirectProjection::computeCriteria(bool * runningProjection)
486 {
487
488 SP::InteractionsGraph indexSet = _nsds->topology()->indexSet(_indexSetLevelForProjection);
489 InteractionsGraph::VIterator aVi, viend;
490
491 double maxViolationEquality = -1e24;
492 double minViolationEquality = +1e24;
493 double maxViolationUnilateral = -1e24;
494 //double minViolationUnilateral = +1e24;
495
496 *runningProjection = false;
497
498 for(std::tie(aVi, viend) = indexSet->vertices();
499 aVi != viend; ++aVi)
500 {
501 SP::Interaction inter = indexSet->bundle(*aVi);
502 inter->computeOutput(getTkp1(), 0);
503 inter->relation()->computeJach(getTkp1(), *inter);
504
505 if(Type::value(*(inter->nonSmoothLaw())) == Type::NewtonImpactFrictionNSL ||
506 Type::value(*(inter->nonSmoothLaw())) == Type::NewtonImpactNSL)
507 {
508 double criteria = std::max(0.0, - inter->y(0)->getValue(0));
509 DEBUG_PRINTF("Unilateral inter->y(0)->getValue(0) %e.\n", inter->y(0)->getValue(0));
510 if(criteria > maxViolationUnilateral) maxViolationUnilateral = criteria;
511 //if (criteria < minViolationUnilateral) minViolationUnilateral=criteria;
512 if(maxViolationUnilateral > _constraintTolUnilateral)
513 {
514 *runningProjection = true;
515
516 DEBUG_PRINTF("TSProj newton criteria unilateral true %e.\n", criteria);
517 }
518 }
519 else
520 {
521 DEBUG_PRINTF("Equality inter->y(0)->normInf() %e.\n", inter->y(0)->normInf());
522 if(inter->y(0)->normInf() > maxViolationEquality) maxViolationEquality = inter->y(0)->normInf() ;
523 if(inter->y(0)->normInf() < minViolationEquality) minViolationEquality = inter->y(0)->normInf() ;
524 if(inter->y(0)->normInf() > _constraintTol)
525 {
526 *runningProjection = true;
527 DEBUG_PRINTF("TSProj newton criteria equality true %e.\n", inter->y(0)->normInf());
528 }
529 }
530 _maxViolationUnilateral = maxViolationUnilateral;
531 _maxViolationEquality = maxViolationEquality;
532 }
533
534 DEBUG_PRINT("TSProj newton min/max criteria projection\n");
535 DEBUG_EXPR(std::cout << " runningProjection " << std::boolalpha << *runningProjection << std::endl;);
536 DEBUG_PRINTF(" min criteria equality = %e.\n", minViolationEquality);
537 DEBUG_PRINTF(" max criteria equality = %e.\n", maxViolationEquality);
538 DEBUG_PRINTF(" max criteria unilateral = %e.\n", maxViolationUnilateral);
539 //DEBUG_PRINTF(" min criteria unilateral = %e.\n",minViolationUnilateral);
540
541 }
542
543
544
newtonSolve(double criterion,unsigned int maxStep)545 void TimeSteppingDirectProjection::newtonSolve(double criterion, unsigned int maxStep)
546 {
547 bool isNewtonConverge = false;
548 _newtonNbIterations = 0; // number of Newton iterations
549 int info = 0;
550 //cout<<"||||||||||||||||||||||||||||||| ||||||||||||||||||||||||||||||| BEGIN NEWTON IT "<<endl;
551 bool isLinear = _nsds->isLinear();
552 SP::InteractionsGraph indexSet = _nsds->topology()->indexSet(0);
553 initializeNewtonLoop();
554
555 if((_newtonOptions == SICONOS_TS_LINEAR || _newtonOptions == SICONOS_TS_LINEAR_IMPLICIT)
556 || isLinear)
557 {
558 _newtonNbIterations++;
559 prepareNewtonIteration();
560 computeFreeState();
561 // updateOutput(0);
562 // updateIndexSets();
563 if(!_allNSProblems->empty() && indexSet->size()>0)
564 info = computeOneStepNSProblem(SICONOS_OSNSP_TS_VELOCITY);
565 // Check output from solver (convergence or not ...)
566 if(!checkSolverOutputProjectOnConstraints)
567 DefaultCheckSolverOutput(info);
568 else
569 checkSolverOutputProjectOnConstraints(info, this);
570
571 update();
572
573 //isNewtonConverge = newtonCheckConvergence(criterion);
574 if(!_allNSProblems->empty() && indexSet->size()>0)
575 saveYandLambdaInOldVariables();
576 }
577
578 else if(_newtonOptions == SICONOS_TS_NONLINEAR)
579 {
580 while((!isNewtonConverge) && (_newtonNbIterations < maxStep) && (!info))
581 {
582 _newtonNbIterations++;
583 prepareNewtonIteration();
584 computeFreeState();
585 // updateOutput(0);
586 // updateIndexSets();
587
588 // if there is not any Interaction at
589 // the beginning of the simulation _allNSProblems may not be
590 // empty here (check with SpaceFilter and one disk not on
591 // the ground : MultiBodyTest::t2)
592
593 // if((*_allNSProblems)[SICONOS_OSNSP_TS_VELOCITY]->simulation())
594 // is also relevant here.
595 if(!_allNSProblems->empty() && indexSet->size()>0)
596 {
597 info = computeOneStepNSProblem(SICONOS_OSNSP_TS_VELOCITY);
598 }
599 // Check output from solver (convergence or not ...)
600 if(!checkSolverOutputProjectOnConstraints)
601 DefaultCheckSolverOutput(info);
602 else
603 checkSolverOutputProjectOnConstraints(info, this);
604
605 updateInput();
606 updateState();
607 isNewtonConverge = newtonCheckConvergence(criterion);
608 if(!isNewtonConverge && !info)
609 {
610 updateOutput();
611 if(!_allNSProblems->empty() && indexSet->size()>0)
612 saveYandLambdaInOldVariables();
613 }
614 }
615 if(!isNewtonConverge)
616 {
617 if(_warnOnNonConvergence)
618 {
619 std::cout << "TimeStepping::newtonSolve -- Newton process stopped: max. number of steps (" << maxStep << ") reached." <<std::endl ;
620 }
621 }
622 else if(info && _warnOnNonConvergence)
623 {
624 std::cout << "TimeStepping::newtonSolve -- Newton process stopped: solver failed." <<std::endl ;
625 }
626 // else
627 // std::cout << "TimeStepping::newtonSolve succed nbit="<<_newtonNbIterations<<"maxStep="<<maxStep<<endl;
628 }
629 else
630 THROW_EXCEPTION("TimeStepping::NewtonSolve failed. Unknown newtonOptions: " + std::to_string(_newtonOptions));
631 }
632