MBDyn-1.7.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
nonlin.cc
Go to the documentation of this file.
1 /* $Header: /var/cvs/mbdyn/mbdyn/mbdyn-1.0/mbdyn/base/nonlin.cc,v 1.52 2017/07/28 14:44:46 masarati Exp $ */
2 /*
3  * MBDyn (C) is a multibody analysis code.
4  * http://www.mbdyn.org
5  *
6  * Copyright (C) 1996-2017
7  *
8  * Pierangelo Masarati <masarati@aero.polimi.it>
9  * Paolo Mantegazza <mantegazza@aero.polimi.it>
10  *
11  * Dipartimento di Ingegneria Aerospaziale - Politecnico di Milano
12  * via La Masa, 34 - 20156 Milano, Italy
13  * http://www.aero.polimi.it
14  *
15  * Changing this copyright notice is forbidden.
16  *
17  * This program is free software; you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation (version 2 of the License).
20  *
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */
31 
32  /*
33  *
34  * Copyright (C) 2003-2017
35  * Giuseppe Quaranta <quaranta@aero.polimi.it>
36  *
37  * classi che implementano la risoluzione del sistema nonlineare
38  */
39 
40 #include "mbconfig.h" /* This goes first in every *.c,*.cc file */
41 
42 #include "solver.h"
43 #include "nonlin.h"
44 #ifdef USE_MPI
45 #include "mbcomm.h"
46 #include "schsolman.h"
47 #endif /* USE_MPI */
48 #include "dofown.h"
49 #include "output.h"
50 
51 #include <cmath>
52 #include <limits>
53 #include <unistd.h>
54 
55 /* NonlinearSolverTest - begin */
56 
58 {
59  NO_OP;
60 }
61 
64  const VectorHandler& Vec, bool bResidual,
65  doublereal dScaleAlgEqu, doublereal* pTestDiff)
66 {
67  DEBUGCOUTFNAME("NonlinearSolverTestNorm::MakeTest");
68 
69  doublereal dTest = 0.;
70 
71  if (pTestDiff) {
72  *pTestDiff = 0.;
73  }
74 
75 #ifdef USE_SCHUR
76  /* Only residual test is parallelized; the master node
77  * always knows the entire solution */
78  ASSERT(pS != NULL);
79  SchurSolutionManager *pSSM = dynamic_cast<SchurSolutionManager *>(pS->pGetSolutionManager());
80  if (pSSM) {
81  SchurDataManager *pSDM =
82  dynamic_cast<SchurDataManager *>(pS->pGetDataManager());
83  ASSERT(pSDM);
84 
85  integer iNumLocDofs = pSDM->HowManyDofs(SchurDataManager::LOCAL);
86  integer *pLocDofs = pSDM->GetDofsList(SchurDataManager::LOCAL);
87 
88 #if 0
89  silent_cout("NonlinearSolverTest::MakeTest("
90  << MBDynComm.Get_rank() << ") "
91  "iNumLocDofs=" << iNumLocDofs << std::endl);
92 #endif
93 
94  if (bResidual) {
95  /*
96  * Chiama la routine di comunicazione per la trasmissione
97  * del residuo delle interfacce
98  */
99  pSSM->StartExchIntRes();
100 
101  /* calcola il test per i dofs locali */
102  for (int iCnt = 0; iCnt < iNumLocDofs; iCnt++) {
103  TestOne(dTest, Vec, pLocDofs[iCnt]);
104  }
105 
106  /* collect contributions from other nodes,
107  * plus that of the interface; merge them according
108  * to the NonlinearSolverTest type */
109  pSSM->ComplExchIntRes(dTest, this);
110 
111  } else {
112  /*
113  * Chiama la routine di comunicazione per la trasmissione
114  * del residuo delle interfacce
115  */
116  pSSM->StartExchIntSol();
117 
118  /* calcola il test per i dofs locali */
119  for (int iCnt = 0; iCnt < iNumLocDofs; iCnt++) {
120  TestOne(dTest, Vec, pLocDofs[iCnt]);
121  }
122 
123  /* collect contributions from other nodes,
124  * plus that of the interface; merge them according
125  * to the NonlinearSolverTest type */
126  pSSM->ComplExchIntSol(dTest, this);
127  }
128 
129  } else
130 #endif // USE_SCHUR
131  {
132  ASSERT(Vec.iGetSize() == Size);
133  const DataManager* const pDM = pS->pGetDataManager();
134 
135  for (int iCntp1 = 1; iCntp1 <= Size; iCntp1++) {
136  const DofOrder::Order order = pDM->GetEqType(iCntp1);
137  const doublereal dCoef = order == DofOrder::DIFFERENTIAL ? 1. : dScaleAlgEqu;
138 
139  TestOne(dTest, Vec, iCntp1, dCoef);
140 
141  if (pTestDiff && order == DofOrder::DIFFERENTIAL) {
142  TestOne(*pTestDiff, Vec, iCntp1, dCoef);
143  }
144  }
145  }
146 
147  if (pTestDiff) {
148  *pTestDiff = TestPost(*pTestDiff);
149  }
150 
151  return TestPost(dTest);
152 }
153 
156 {
157  if (!std::isfinite(dRes)) {
159  }
160 
161  return dRes;
162 }
163 
164 const doublereal dOne = 1.;
165 
166 const doublereal&
168 {
170 }
171 
172 /* NonlinearSolverTest - end */
173 
174 /* NonlinearSolverTestNone - begin */
175 
178  const VectorHandler& Vec, bool bResidual,
179  doublereal* pTestDiff)
180 {
181  DEBUGCOUTFNAME("NonlinearSolverTestNone::MakeTest");
182 
183  if (pTestDiff) {
184  *pTestDiff = 0.;
185  }
186 
187  return 0.;
188 }
189 
190 void
192  const VectorHandler& Vec, const integer& iIndex, doublereal dCoef) const
193 {
194  dRes = 0.;
195 }
196 
197 void
199  const doublereal& dResNew) const
200 {
201  dResCurr = 0.;
202 }
203 
204 /* NonlinearSolverTestNone - end */
205 
206 /* NonlinearSolverTestNorm - begin */
207 
208 void
210  const VectorHandler& Vec, const integer& iIndex, doublereal dCoef) const
211 {
212  doublereal d = Vec(iIndex) * dCoef;
213 
214  dRes += d*d;
215 }
216 
217 void
219  const doublereal& dResNew) const
220 {
221  dResCurr += dResNew;
222 }
223 
226 {
227  /* va qui perche' non posso fare sqrt() su !isfinite() */
228  if (!std::isfinite(dRes)) {
230  }
231 
232  return sqrt(dRes);
233 }
234 
235 /* NonlinearSolverTestNorm - end */
236 
237 /* NonlinearSolverTestMinMax */
238 
239 void
241  const VectorHandler& Vec, const integer& iIndex, doublereal dCoef) const
242 {
243  doublereal d = fabs(Vec(iIndex)) * dCoef;
244 
245  if (!(d < dRes)) { // this will work also if d equal nan
246  dRes = d;
247  }
248 }
249 
250 void
252  const doublereal& dResNew) const
253 {
254  ASSERT(dResCurr >= 0.);
255  ASSERT(dResNew >= 0.);
256 
257  if (dResNew > dResCurr) {
258  dResCurr = dResNew;
259  }
260 }
261 
262 /* NonlinearSolverTestMinMax - end */
263 
264 /* NonlinearSolverTestScale - begin */
265 
267 : pScale(pScl)
268 {
269  NO_OP;
270 }
271 
273 {
274  NO_OP;
275 }
276 
277 void
279 {
280  pScale = pScl;
281 }
282 
283 const doublereal&
285 {
286  return pScale->operator()(iIndex);
287 }
288 
289 /* NonlinearSolverTestScale - end */
290 
291 /* NonlinearSolverTestScaleNorm - begin */
292 
293 void
295  const VectorHandler& Vec, const integer& iIndex, doublereal dCoef) const
296 {
297  doublereal d = Vec(iIndex) * (*pScale)(iIndex) * dCoef;
298 
299  dRes += d*d;
300 }
301 
302 void
304  const doublereal& dResNew) const
305 {
306  NonlinearSolverTestNorm::TestMerge(dResCurr, dResNew);
307 }
308 
309 const doublereal&
311 {
313 }
314 
315 /* NonlinearSolverTestScaleNorm - end */
316 
317 /* NonlinearSolverTestScaleMinMax - begin */
318 
319 void
321  const VectorHandler& Vec, const integer& iIndex, doublereal dCoef) const
322 {
323  doublereal d = fabs(Vec(iIndex) * (*pScale)(iIndex)) * dCoef;
324 
325  if (d > dRes) {
326  dRes = d;
327  }
328 }
329 
330 void
332  const doublereal& dResNew) const
333 {
334  NonlinearSolverTestMinMax::TestMerge(dResCurr, dResNew);
335 }
336 
337 const doublereal&
339 {
341 }
342 
343 /* NonlinearSolverTestScaleMinMax - end */
344 
345 bool
347 {
348  ASSERT(m_iFirstIndex > 0);
350  return (iIndex >= m_iFirstIndex && iIndex <= m_iLastIndex);
351 }
352 
354 : m_iFirstIndex(iFirstIndex), m_iLastIndex(iLastIndex), m_pTest(pTest)
355 {
356  NO_OP;
357 }
358 
360 {
361  delete m_pTest;
362 }
363 
364 #if 0
367  const VectorHandler& Vec, bool bResidual)
368 {
369  // return m_pTest->MakeTest(pS, Size, Vec, bResidual);
370  return NonlinearSolverTest::MakeTest(pS, Size, Vec, bResidual);
371 }
372 #endif
373 
374 void
376  const integer& iIndex, doublereal dCoef) const
377 {
378  if (bIsValid(iIndex)) {
379  m_pTest->TestOne(dRes, Vec, iIndex, dCoef);
380  }
381 }
382 
383 void
385 {
386  m_pTest->TestMerge(dResCurr, dResNew);
387 }
388 
391 {
392  return m_pTest->TestPost(dRes);
393 }
394 
395 const doublereal&
397 {
398  if (bIsValid(iIndex)) {
399  return m_pTest->dScaleCoef(iIndex);
400  }
401 
403 }
404 
405 void
407 {
408  if (iFirstIndex <= 0) {
409  silent_cerr("NonlinearSolverTestRange: invalid iFirstIndex=" << iFirstIndex << std::endl);
411  }
412 
413  if (iLastIndex <= iFirstIndex) {
414  silent_cerr("NonlinearSolverTestRange: invalid iLastIndex=" << iLastIndex << " (iFirstIndex=" << iFirstIndex << ")" << std::endl);
416  }
417 
418  m_iFirstIndex = iFirstIndex;
419  m_iLastIndex = iLastIndex;
420 }
421 
423  enum ScaleFlags eScaleFlags,
424  doublereal dScaleAlgebraic)
425 :bHonorJacRequest(bHonorJacRequest),
426  eScaleFlags(eScaleFlags),
427  dScaleAlgebraic(dScaleAlgebraic)
428 {
429 
430 }
431 
432 /* NonlinearSolver - begin */
433 
435 : NonlinearSolverOptions(options),
436 Size(0),
437 TotJac(0),
438 #ifdef USE_MPI
439 bParallel(MPI::Is_initialized()),
440 #endif /* USE_MPI */
441 pResTest(0),
442 pSolTest(0),
443 iNumCond(0),
444 dMaxCond(0.),
445 dMinCond(std::numeric_limits<doublereal>::max()),
446 dSumCond(0.)
447 #ifdef USE_EXTERNAL
448 , ExtStepType(External::ERROR)
449 #endif /* USE_EXTERNAL */
450 {
451  std::memset(dTimeCPU, 0, sizeof(dTimeCPU));
452 }
453 
454 void
456 {
457  pResTest = pr;
458  pSolTest = ps;
459 }
460 
462 {
465 }
466 
467 integer
469 {
470  return TotJac;
471 }
472 
473 bool
475  const NonlinearProblem *pNLP,
476  const VectorHandler& Vec,
477  const doublereal& dTol,
478  doublereal& dTest,
479  doublereal& dTestDiff)
480 {
481  doublereal dScaleAlgEqu;
482  const doublereal dTestScale = pNLP->TestScale(pResTest, dScaleAlgEqu);
483 
485  // f = c / dCoef
486  dScaleAlgEqu = 1.;
487  } else {
488  // f = c * dScaleAlgebraic
489  dScaleAlgEqu *= dScaleAlgebraic;
490  }
491 
492  dTest = pResTest->MakeTest(pS, Size, Vec, true, dScaleAlgEqu, &dTestDiff) * dTestScale;
493  return ((dTest < dTol) && pS->pGetDataManager()->IsConverged());
494 }
495 
496 bool
498  const VectorHandler& Vec,
499  const doublereal& dTol,
500  doublereal& dTest)
501 {
502  dTest = pSolTest->MakeTest(pS, Size, Vec);
503  return ((dTest < dTol) && pS->pGetDataManager()->IsConverged());
504 }
505 
506 #ifdef USE_EXTERNAL
507 
508 void
509 NonlinearSolver::SetExternal(const External::ExtMessage Ty)
510 {
511  ExtStepType = Ty;
512 }
513 
514 void
515 NonlinearSolver::SendExternal(void)
516 {
517  switch (ExtStepType) {
518  case (External::EMPTY):
519  External::SendNull();
520  break;
521 
522  case (External::REGULAR):
523  External::SendRegular();
524  break;
525 
526  case (External::CLOSE):
527  External::SendClose();
528  break;
529 
530  case (External::ERROR):
531  default:
532  External::SendError();
533  }
534 }
535 
536 #endif /* USE_EXTERNAL */
537 
538 /* NonlinearSolver - end */
539 
doublereal dTimeCPU[CPU_LAST_TYPE]
Definition: nonlin.h:288
bool IsConverged(void) const
Definition: dataman2.cc:2692
integer * GetDofsList(DofType who) const
virtual SolutionManager * pGetSolutionManager(void) const
Definition: solver.h:398
virtual void TestMerge(doublereal &dResCurr, const doublereal &dResNew) const
Definition: nonlin.cc:303
NonlinearSolverTestRange(NonlinearSolverTest *pTest, integer iFirstIndex=-1, integer iLastIndex=-1)
Definition: nonlin.cc:353
void ComplExchIntRes(doublereal &d, const NonlinearSolverTest *t)
enum NonlinearSolverOptions::ScaleFlags eScaleFlags
virtual void SetScale(const VectorHandler *pScl)
Definition: nonlin.cc:278
virtual void TestOne(doublereal &dRes, const VectorHandler &Vec, const integer &iIndex, doublereal dCoef) const
Definition: nonlin.cc:320
integer TotJac
Definition: nonlin.h:252
virtual ~NonlinearSolverTest(void)
Definition: nonlin.cc:57
virtual doublereal TestScale(const NonlinearSolverTest *pTest, doublereal &dAlgebraicEquations) const =0
#define MBDYN_EXCEPT_ARGS
Definition: except.h:63
#define DEBUGCOUTFNAME(fname)
Definition: myassert.h:256
doublereal dScaleAlgebraic
Definition: nonlin.h:204
virtual doublereal MakeTest(Solver *pS, const integer &Size, const VectorHandler &Vec, bool bResidual=false, doublereal dScaleAlgEqu=1., doublereal *pTestDiff=0)
Definition: nonlin.cc:63
virtual bool MakeSolTest(Solver *pS, const VectorHandler &Vec, const doublereal &dTol, doublereal &dTest)
Definition: nonlin.cc:497
virtual bool MakeResTest(Solver *pS, const NonlinearProblem *pNLP, const VectorHandler &Vec, const doublereal &dTol, doublereal &dTest, doublereal &dTestDiff)
Definition: nonlin.cc:474
NonlinearSolverTest * m_pTest
Definition: nonlin.h:170
virtual void TestOne(doublereal &dRes, const VectorHandler &Vec, const integer &iIndex, doublereal dCoef) const
Definition: nonlin.cc:240
integer Size
Definition: nonlin.h:251
virtual doublereal MakeTest(Solver *pS, integer Size, const VectorHandler &Vec, bool bResidual=false, doublereal *pTestDiff=0)
Definition: nonlin.cc:177
virtual void TestOne(doublereal &dRes, const VectorHandler &Vec, const integer &iIndex, doublereal dCoef) const
Definition: nonlin.cc:375
#define NO_OP
Definition: myassert.h:74
virtual void TestMerge(doublereal &dResCurr, const doublereal &dResNew) const
Definition: nonlin.cc:384
void StartExchIntSol(void)
virtual integer iGetSize(void) const =0
GradientExpression< UnaryExpr< FuncFabs, Expr > > fabs(const GradientExpression< Expr > &u)
Definition: gradient.h:2973
virtual ~NonlinearSolverTestRange(void)
Definition: nonlin.cc:359
virtual void TestMerge(doublereal &dResCurr, const doublereal &dResNew) const =0
bool bIsValid(const integer &iIndex) const
Definition: nonlin.cc:346
virtual integer TotalAssembledJacobian(void)
Definition: nonlin.cc:468
virtual ~NonlinearSolver(void)
Definition: nonlin.cc:461
enum @55 order
void SetRange(integer iFirstIndex, integer iLastIndex)
Definition: nonlin.cc:406
virtual const doublereal & dScaleCoef(const integer &iIndex) const
Definition: nonlin.cc:338
virtual void TestMerge(doublereal &dResCurr, const doublereal &dResNew) const
Definition: nonlin.cc:198
virtual const doublereal & dScaleCoef(const integer &iIndex) const
Definition: nonlin.cc:310
NonlinearSolverTest * pSolTest
Definition: nonlin.h:258
virtual void SetTest(NonlinearSolverTest *pr, NonlinearSolverTest *ps)
Definition: nonlin.cc:455
const doublereal Zero1
virtual doublereal TestPost(const doublereal &dRes) const
Definition: nonlin.cc:225
virtual void TestOne(doublereal &dRes, const VectorHandler &Vec, const integer &iIndex, doublereal dCoef) const
Definition: nonlin.cc:191
NonlinearSolver(const NonlinearSolverOptions &options)
Definition: nonlin.cc:434
virtual ~NonlinearSolverTestScale(void)
Definition: nonlin.cc:272
#define ASSERT(expression)
Definition: colamd.c:977
virtual const doublereal & dScaleCoef(const integer &iIndex) const
Definition: nonlin.cc:396
const doublereal dOne
Definition: nonlin.cc:164
GradientExpression< UnaryExpr< FuncSqrt, Expr > > sqrt(const GradientExpression< Expr > &u)
Definition: gradient.h:2974
NonlinearSolverOptions(bool bHonorJacRequest=false, enum ScaleFlags eScaleFlags=SCALE_ALGEBRAIC_EQUATIONS_NO, doublereal dScaleAlgebraic=1.)
Definition: nonlin.cc:422
virtual void TestOne(doublereal &dRes, const VectorHandler &Vec, const integer &iIndex, doublereal dCoef) const
Definition: nonlin.cc:294
struct option options[]
Definition: ann_in.c:46
Definition: solver.h:78
virtual const doublereal & dScaleCoef(const integer &iIndex) const
Definition: nonlin.cc:167
void StartExchIntRes(void)
integer HowManyDofs(DofType who) const
virtual doublereal TestPost(const doublereal &dRes) const
Definition: nonlin.cc:390
void ComplExchIntSol(doublereal &d, const NonlinearSolverTest *t)
virtual DataManager * pGetDataManager(void) const
Definition: solver.h:395
virtual void TestOne(doublereal &dRes, const VectorHandler &Vec, const integer &iIndex, doublereal dCoef) const =0
#define EMPTY
Definition: colamd.c:768
NonlinearSolverTestScale(const VectorHandler *pScl=0)
Definition: nonlin.cc:266
virtual void TestMerge(doublereal &dResCurr, const doublereal &dResNew) const
Definition: nonlin.cc:331
double doublereal
Definition: colamd.c:52
long int integer
Definition: colamd.c:51
virtual void TestMerge(doublereal &dResCurr, const doublereal &dResNew) const
Definition: nonlin.cc:218
NonlinearSolverTest * pResTest
Definition: nonlin.h:257
virtual const doublereal & dScaleCoef(const integer &iIndex) const
Definition: nonlin.cc:284
virtual void TestOne(doublereal &dRes, const VectorHandler &Vec, const integer &iIndex, doublereal dCoef) const
Definition: nonlin.cc:209
const VectorHandler * pScale
Definition: nonlin.h:137
#define SAFEDELETE(pnt)
Definition: mynewmem.h:710
virtual doublereal TestPost(const doublereal &dRes) const
Definition: nonlin.cc:155
virtual void TestMerge(doublereal &dResCurr, const doublereal &dResNew) const
Definition: nonlin.cc:251