OOFEM 3.0
Loading...
Searching...
No Matches
staggeredsolver.C
Go to the documentation of this file.
1/*
2 *
3 * ##### ##### ###### ###### ### ###
4 * ## ## ## ## ## ## ## ### ##
5 * ## ## ## ## #### #### ## # ##
6 * ## ## ## ## ## ## ## ##
7 * ## ## ## ## ## ## ## ##
8 * ##### ##### ## ###### ## ##
9 *
10 *
11 * OOFEM : Object Oriented Finite Element Code
12 *
13 * Copyright (C) 1993 - 2025 Borek Patzak
14 *
15 *
16 *
17 * Czech Technical University, Faculty of Civil Engineering,
18 * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19 *
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License as published by the Free Software Foundation; either
23 * version 2.1 of the License, or (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 * Lesser General Public License for more details.
29 *
30 * You should have received a copy of the GNU Lesser General Public
31 * License along with this library; if not, write to the Free Software
32 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 */
34
35#include "staggeredsolver.h"
36#include "timestep.h"
37#include "classfactory.h"
38#include "exportmodulemanager.h"
39#include "engngm.h"
40#include "domain.h"
41#include "dofmanager.h"
42#include "element.h"
44#include "dof.h"
45#include "mathfem.h"
46
47namespace oofem {
48
49#define ERROR_NORM_SMALL_NUM 1.e-6
50#define MAX_REL_ERROR_BOUND 1.e20
51
53
54
55int CustomEquationNumbering :: giveDofEquationNumber(Dof* dof) const
56{
57 DofIDItem id = dof->giveDofID();
58 //printf("asking for num %d \n", (int)id);
59 if ( this->dofIdArray.contains( (int)id ) ) {
60 return prescribed ? dof->__givePrescribedEquationNumber() : dof->__giveEquationNumber();
61 } else {
62 return 0;
63 }
64}
65
66
67CustomEquationNumbering :: CustomEquationNumbering() : UnknownNumberingScheme(),
68 prescribed(false), numEqs(0), numPresEqs(0), dofIdArray(0)
69{
70}
71
72
73StaggeredSolver :: StaggeredSolver(Domain *d, EngngModel *m) : NRSolver(d, m)
74{
75 this->UnknownNumberingSchemeList.resize(0);
76}
77
78
79void
80StaggeredSolver :: initializeFrom(InputRecord &ir)
81{
82 NRSolver ::initializeFrom(ir);
83
86
87 int numDofIdGroups = idPos.giveSize()/2;
88 this->UnknownNumberingSchemeList.resize(numDofIdGroups);
89 for ( int i = 0; i < numDofIdGroups; i++ ) {
90 int sz = idPos.at(i*2 + 2) - idPos.at(i*2 + 1) + 1;
91 IntArray idList(sz);
92 for ( int j = 0; j < sz; j++) {
93 int pos = idPos.at(i*2 + 1) + j;
94 idList[j] = this->totalIdList.at(pos);
95 }
96 this->UnknownNumberingSchemeList[i].setDofIdArray(idList);
97 }
98}
99
100
101DofGrouping :: DofGrouping(const std :: vector< CustomEquationNumbering > &numberings, Domain *d):
102 stiffnessMatrixList(numberings.size()),
103 fIntList(numberings.size()),
104 fExtList(numberings.size()),
105 locArrayList(numberings.size()),
106 X(numberings.size()),
107 dX(numberings.size()),
108 ddX(numberings.size())
109{
110 for ( int dG = 0; dG < (int)numberings.size(); dG++ ) {
111 this->giveTotalLocationArray(locArrayList[dG], numberings[dG], d);
112 }
113}
114
115
116void
117DofGrouping :: giveTotalLocationArray(IntArray &condensedLocationArray, const UnknownNumberingScheme &s, Domain *d)
118{
119 IntArray nodalArray, ids, locationArray;
120 locationArray.clear();
121
122 for ( auto &dman : d->giveDofManagers() ) {
123 dman->giveCompleteLocationArray(nodalArray, s);
124 locationArray.followedBy(nodalArray);
125 }
126 for ( auto &elem : d->giveElements() ) {
127 for ( int i = 1; i <= elem->giveNumberOfInternalDofManagers(); i++ ) {
128 elem->giveInternalDofManDofIDMask(i, ids);
129 elem->giveInternalDofManager(i)->giveLocationArray(ids, nodalArray, s);
130 locationArray.followedBy(nodalArray);
131 }
132 }
133
134 IntArray nonZeroMask;
135 nonZeroMask.findNonzeros(locationArray);
136
137 condensedLocationArray.resize(nonZeroMask.giveSize());
138 for ( int i = 1; i <= nonZeroMask.giveSize(); i++ ) {
139 condensedLocationArray.at(i) = locationArray.at( nonZeroMask.at(i) );
140 }
141}
142
143
145StaggeredSolver :: solve(SparseMtrx &k, FloatArray &R, FloatArray *R0,
146 FloatArray &Xtotal, FloatArray &dXtotal, FloatArray &F,
147 const FloatArray &internalForcesEBENorm, double &l, referenceLoadInputModeType rlm,
148 int &nite, TimeStep *tStep)
149
150{
151 // residual, iteration increment of solution, total external force
152 FloatArray RHS, rhs, ddXtotal, RT;
153 double RRTtotal;
154 int neq = Xtotal.giveSize();
155 ConvergedReason status;
156 bool converged, errorOutOfRangeFlag;
157 ParallelContext *parallel_context = engngModel->giveParallelContext( this->domain->giveNumber() );
158
159 if ( engngModel->giveProblemScale() == macroScale ) {
160 OOFEM_LOG_INFO("StaggeredSolver: Iteration");
161 if ( rtolf.at(1) > 0.0 ) {
162 OOFEM_LOG_INFO(" ForceError");
163 }
164 if ( rtold.at(1) > 0.0 ) {
165 OOFEM_LOG_INFO(" DisplError");
166 }
167 OOFEM_LOG_INFO("\n----------------------------------------------------------------------------\n");
168 }
169
170 l = 1.0;
171 status = CR_UNKNOWN;
172 this->giveLinearSolver();
173
174 // compute total load R = R+R0
175 RT = R;
176 if ( R0 ) {
177 RT.add(* R0);
178 }
179
180 RRTtotal = parallel_context->localNorm(RT);
181 RRTtotal *= RRTtotal;
182
183 ddXtotal.resize(neq);
184 ddXtotal.zero();
185
186 // Fetch the matrix before evaluating internal forces.
187 // This is intentional, since its a simple way to drastically increase convergence for nonlinear problems.
188 // (This old tangent is just used)
189 // This improves convergence for many nonlinear problems, but not all. It may actually
190 // cause divergence for some nonlinear problems. Therefore a flag is used to determine if
191 // the stiffness should be evaluated before the residual (default yes). /ES
192
194
195 // Compute external forces
196 int numDofIdGroups = (int)this->UnknownNumberingSchemeList.size();
197 FloatArray RRT(numDofIdGroups);
198 for ( int dG = 0; dG < numDofIdGroups; dG++ ) {
199 dg.fExtList[dG].beSubArrayOf( RT, dg.locArrayList[dG] );
200 RRT(dG) = dg.fExtList[dG].computeSquaredNorm();
201 }
202
203 for (int nStaggeredIter = 0;; ++nStaggeredIter) {
204
205 // Staggered iterations
206 for ( int dG = 0; dG < (int)this->UnknownNumberingSchemeList.size(); dG++ ) {
207 OOFEM_LOG_INFO("\nSolving for dof group %d \n", dG+1);
208
209 engngModel->updateComponent(tStep, NonLinearLhs, domain);
211
212 if ( this->prescribedDofsFlag ) {
213 if ( !prescribedEqsInitFlag ) {
214 this->initPrescribedEqs();
215 }
217 }
218
219 for (nite = 0;; ++nite) {
220 // Compute the residual
221 engngModel->updateComponent(tStep, InternalRhs, domain);
222 RHS.beDifferenceOf(RT, F);
223
224 dg.fIntList[dG].beSubArrayOf( F, dg.locArrayList[dG] );
225 rhs.beDifferenceOf(dg.fExtList[dG], dg.fIntList[dG]);
226
227 RHS.zero();
228 RHS.assemble(rhs, dg.locArrayList[dG]);
229
230
231 if ( this->prescribedDofsFlag ) {
232 this->applyConstraintsToLoadIncrement(nite, k, rhs, rlm, tStep);
233 }
234
235 // convergence check
236 IntArray &idArray = UnknownNumberingSchemeList[dG].dofIdArray;
237 converged = this->checkConvergenceDofIdArray(RT, F, RHS, ddXtotal, Xtotal, RRTtotal, internalForcesEBENorm, nite, errorOutOfRangeFlag, tStep, idArray);
238
239
240 if ( errorOutOfRangeFlag ) {
241 status = CR_DIVERGED_TOL;
242 OOFEM_WARNING("Divergence reached after %d iterations", nite);
243 break;
244 } else if ( converged && ( nite >= minIterations ) ) {
245 status = CR_CONVERGED;
246 break;
247 } else if ( nite >= nsmax ) {
248 OOFEM_LOG_DEBUG("Maximum number of iterations reached\n");
249 status = CR_DIVERGED_ITS;
250 break;
251 }
252
253 if ( nite > 0 || !mCalcStiffBeforeRes ) {
254 if ( NR_Mode == nrsolverFullNRM || ( NR_Mode == nrsolverAccelNRM && (nite % MANRMSteps) == 0 ) ) {
255 engngModel->updateComponent(tStep, NonLinearLhs, domain);
258 }
259 }
260
261 if ( ( nite == 0 ) && ( deltaL < 1.0 ) ) { // deltaL < 1 means no increment applied, only equilibrate current state
262 rhs.zero();
263 R.zero();
264 dg.ddX[dG] = rhs;
265 } else {
266 status = linSolver->solve(*dg.stiffnessMatrixList[dG], rhs, dg.ddX[dG]);
267 }
268
269 //
270 // update solution
271 //
272 if ( this->lsFlag && ( nite > 0 ) ) { // Why not nite == 0 ?
273 // line search
274 LineSearchNM :: LS_status LSstatus;
275 double eta;
276 this->giveLineSearchSolver()->solve( dg.X[dG], dg.ddX[dG], dg.fIntList[dG], dg.fExtList[dG], R0, prescribedEqs, 1.0, eta, LSstatus, tStep);
277 } else if ( this->constrainedNRFlag && ( nite > this->constrainedNRminiter ) ) {
278 if ( this->forceErrVec.computeSquaredNorm() > this->forceErrVecOld.computeSquaredNorm() ) {
279 OOFEM_LOG_INFO("Constraining increment to be %e times full increment...\n", this->constrainedNRalpha);
280 dg.ddX[dG].times(this->constrainedNRalpha);
281 }
282 }
283 dg.X[dG].add(dg.ddX[dG]);
284 dg.dX[dG].add(dg.ddX[dG]);
285
286
287 // Update total solution (containing all dofs)
288 Xtotal.assemble(dg.ddX[dG], dg.locArrayList[dG]);
289 dXtotal.assemble(dg.ddX[dG], dg.locArrayList[dG]);
290 ddXtotal.zero();
291 ddXtotal.assemble(dg.ddX[dG], dg.locArrayList[dG]);
292
293 tStep->incrementStateCounter(); // update solution state counter
294 tStep->incrementSubStepNumber();
295
296 engngModel->giveExportModuleManager()->doOutput(tStep, true);
297 }
298 }
299
300
301 OOFEM_LOG_INFO("\nStaggered iteration (all dof id's) \n");
302
303 // Check convergence of total system
304 RHS.beDifferenceOf(RT, F);
305 converged = this->checkConvergence(RT, F, RHS, ddXtotal, Xtotal, RRTtotal, internalForcesEBENorm, nStaggeredIter, errorOutOfRangeFlag);
306 if ( converged && ( nStaggeredIter >= minIterations ) ) {
307 break;
308 }
309 }
310
311 // Modify Load vector to include "quasi reaction"
312 if ( R0 ) {
313 for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
314 R.at( prescribedEqs.at(i) ) = F.at( prescribedEqs.at(i) ) - R0->at( prescribedEqs.at(i) ) - R.at( prescribedEqs.at(i) );
315 }
316 } else {
317 for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
318 R.at( prescribedEqs.at(i) ) = F.at( prescribedEqs.at(i) ) - R.at( prescribedEqs.at(i) );
319 }
320 }
321
323
324#ifdef VERBOSE
326 // print quasi reactions if direct displacement control used
327 OOFEM_LOG_INFO("\n");
328 OOFEM_LOG_INFO("StaggeredSolver: Quasi reaction table \n");
329 OOFEM_LOG_INFO("StaggeredSolver: Node Dof Displacement Force\n");
330 double reaction;
331 for ( int i = 1; i <= numberOfPrescribedDofs; i++ ) {
332 reaction = R->at( prescribedEqs.at(i) );
333 if ( R0 ) {
334 reaction += R0->at( prescribedEqs.at(i) );
335 }
336 lastReactions.at(i) = reaction;
337 OOFEM_LOG_INFO("StaggeredSolver: %-15d %-15d %-+15.5e %-+15.5e\n", prescribedDofs.at(2 * i - 1), prescribedDofs.at(2 * i),
338 X.at( prescribedEqs.at(i) ), reaction);
339 }
340 OOFEM_LOG_INFO("\n");
341 }
342#endif
343
344 return status;
345}
346
347
348//copied from nrsolver
349
350bool
351StaggeredSolver :: checkConvergenceDofIdArray(FloatArray &RT, FloatArray &F, FloatArray &rhs, FloatArray &ddX, FloatArray &X,
352 double RRT, const FloatArray &internalForcesEBENorm, int nite, bool &errorOutOfRange, TimeStep *tStep, IntArray &dofIdArray)
353{
354 double forceErr, dispErr;
355 FloatArray dg_forceErr, dg_dispErr, dg_totalLoadLevel, dg_totalDisp;
356 bool answer;
358 ParallelContext *parallel_context = engngModel->giveParallelContext( this->domain->giveNumber() );
359
360 /*
361 * The force errors are (if possible) evaluated as relative errors.
362 * If the norm of applied load vector is zero (one may load by temperature, etc)
363 * then the norm of reaction forces is used in relative norm evaluation.
364 *
365 * Note: This is done only when all dofs are included (nccdg = 0). Not implemented if
366 * multiple convergence criteria are used.
367 *
368 */
369
370 answer = true;
371 errorOutOfRange = false;
372
373 // Store the errors associated with the dof groups
374 if ( this->constrainedNRFlag ) {
375 this->forceErrVecOld = this->forceErrVec; // copy the old values
376 this->forceErrVec.resize( internalForcesEBENorm.giveSize() );
377 forceErrVec.zero();
378 }
379
380 if ( internalForcesEBENorm.giveSize() > 1 ) { // Special treatment when just one norm is given; No grouping
381 int nccdg = this->domain->giveMaxDofID();
382 // Keeps tracks of which dof IDs are actually in use;
383 IntArray idsInUse(nccdg);
384 idsInUse.zero();
385 // zero error norms per group
386 dg_forceErr.resize(nccdg);
387 dg_forceErr.zero();
388 dg_dispErr.resize(nccdg);
389 dg_dispErr.zero();
390 dg_totalLoadLevel.resize(nccdg);
391 dg_totalLoadLevel.zero();
392 dg_totalDisp.resize(nccdg);
393 dg_totalDisp.zero();
394 // loop over dof managers
395 for ( auto &dofman : domain->giveDofManagers() ) {
396 if ( !parallel_context->isLocal(dofman.get()) ) {
397 continue;
398 }
399
400 // loop over individual dofs
401 for ( Dof *dof: *dofman ) {
402 if ( !dof->isPrimaryDof() ) {
403 continue;
404 }
405 int eq = dof->giveEquationNumber(dn);
406 int dofid = dof->giveDofID();
407 if ( !eq ) {
408 continue;
409 }
410
411 dg_forceErr.at(dofid) += rhs.at(eq) * rhs.at(eq);
412 dg_dispErr.at(dofid) += ddX.at(eq) * ddX.at(eq);
413 dg_totalLoadLevel.at(dofid) += RT.at(eq) * RT.at(eq);
414 dg_totalDisp.at(dofid) += X.at(eq) * X.at(eq);
415 idsInUse.at(dofid) = 1;
416 } // end loop over DOFs
417 } // end loop over dof managers
418
419 // loop over elements and their DOFs
420 for ( auto &elem : domain->giveElements() ) {
421 if ( elem->giveParallelMode() != Element_local ) {
422 continue;
423 }
424
425 // loop over element internal Dofs
426 for ( int idofman = 1; idofman <= elem->giveNumberOfInternalDofManagers(); idofman++ ) {
427 DofManager *dofman = elem->giveInternalDofManager(idofman);
428 // loop over individual dofs
429 for ( Dof *dof: *dofman ) {
430 if ( !dof->isPrimaryDof() ) {
431 continue;
432 }
433 int eq = dof->giveEquationNumber(dn);
434 int dofid = dof->giveDofID();
435
436 if ( !eq ) {
437 continue;
438 }
439
440 dg_forceErr.at(dofid) += rhs.at(eq) * rhs.at(eq);
441 dg_dispErr.at(dofid) += ddX.at(eq) * ddX.at(eq);
442 dg_totalLoadLevel.at(dofid) += RT.at(eq) * RT.at(eq);
443 dg_totalDisp.at(dofid) += X.at(eq) * X.at(eq);
444 idsInUse.at(dofid) = 1;
445 } // end loop over DOFs
446 } // end loop over element internal dofmans
447 } // end loop over elements
448
449 // loop over boundary conditions and their internal DOFs
450 for ( auto &bc : domain->giveBcs() ) {
451 // loop over element internal Dofs
452 for ( int idofman = 1; idofman <= bc->giveNumberOfInternalDofManagers(); idofman++ ) {
453 DofManager *dofman = bc->giveInternalDofManager(idofman);
454 // loop over individual dofs
455 for ( Dof *dof: *dofman ) {
456 if ( !dof->isPrimaryDof() ) {
457 continue;
458 }
459 int eq = dof->giveEquationNumber(dn);
460 int dofid = dof->giveDofID();
461
462 if ( !eq ) {
463 continue;
464 }
465
466 dg_forceErr.at(dofid) += rhs.at(eq) * rhs.at(eq);
467 dg_dispErr.at(dofid) += ddX.at(eq) * ddX.at(eq);
468 dg_totalLoadLevel.at(dofid) += RT.at(eq) * RT.at(eq);
469 dg_totalDisp.at(dofid) += X.at(eq) * X.at(eq);
470 idsInUse.at(dofid) = 1;
471 } // end loop over DOFs
472 } // end loop over element internal dofmans
473 } // end loop over elements
474
475 // exchange individual partition contributions (simultaneously for all groups)
476 FloatArray collectiveErr(nccdg);
477 parallel_context->accumulate(dg_forceErr, collectiveErr);
478 dg_forceErr = collectiveErr;
479 parallel_context->accumulate(dg_dispErr, collectiveErr);
480 dg_dispErr = collectiveErr;
481 parallel_context->accumulate(dg_totalLoadLevel, collectiveErr);
482 dg_totalLoadLevel = collectiveErr;
483 parallel_context->accumulate(dg_totalDisp, collectiveErr);
484 dg_totalDisp = collectiveErr;
485
486 OOFEM_LOG_INFO("StaggeredSolver: %-5d", nite);
487 //bool zeroNorm = false;
488 // loop over dof groups and check convergence individually
489 for ( int dg = 1; dg <= nccdg; dg++ ) {
490 bool zeroFNorm = false, zeroDNorm = false;
491 // Skips the ones which aren't used in this problem (the residual will be zero for these anyway, but it is annoying to print them all)
492 if ( !idsInUse.at(dg) ) {
493 continue;
494 }
495
496 if ( dofIdArray.giveSize() && !dofIdArray.contains(dg) ) {
497 continue;
498 }
499
500
501 OOFEM_LOG_INFO( " %s:", __DofIDItemToString( ( DofIDItem ) dg ).c_str() );
502
503 if ( rtolf.at(1) > 0.0 ) {
504 // compute a relative error norm
505 if ( ( dg_totalLoadLevel.at(dg) + internalForcesEBENorm.at(dg) ) > ERROR_NORM_SMALL_NUM ) {
506 forceErr = sqrt( dg_forceErr.at(dg) / ( dg_totalLoadLevel.at(dg) + internalForcesEBENorm.at(dg) ) );
507 } else {
508 // If both external forces and internal ebe norms are zero, then the residual must be zero.
509 //zeroNorm = true; // Warning about this afterwards.
510 zeroFNorm = true;
511 forceErr = sqrt( dg_forceErr.at(dg) );
512 }
513
514 if ( forceErr > rtolf.at(1) * MAX_REL_ERROR_BOUND ) {
515 errorOutOfRange = true;
516 }
517 if ( forceErr > rtolf.at(1) ) {
518 answer = false;
519 }
520 OOFEM_LOG_INFO(zeroFNorm ? " *%.3e" : " %.3e", forceErr);
521
522 // Store the errors from the current iteration
523 if ( this->constrainedNRFlag ) {
524 forceErrVec.at(dg) = forceErr;
525 }
526 }
527
528 if ( rtold.at(1) > 0.0 ) {
529 // compute displacement error
530 if ( dg_totalDisp.at(dg) > ERROR_NORM_SMALL_NUM ) {
531 dispErr = sqrt( dg_dispErr.at(dg) / dg_totalDisp.at(dg) );
532 } else {
534 //zeroNorm = true; // Warning about this afterwards.
535 //zeroDNorm = true;
536 dispErr = sqrt( dg_dispErr.at(dg) );
537 }
538 if ( dispErr > rtold.at(1) * MAX_REL_ERROR_BOUND ) {
539 errorOutOfRange = true;
540 }
541 if ( dispErr > rtold.at(1) ) {
542 answer = false;
543 }
544 OOFEM_LOG_INFO(zeroDNorm ? " *%.3e" : " %.3e", dispErr);
545 }
546 }
547 OOFEM_LOG_INFO("\n");
548 //if ( zeroNorm ) OOFEM_WARNING("Had to resort to absolute error measure (marked by *)");
549 } else { // No dof grouping
550 double dXX, dXdX;
551
552 if ( engngModel->giveProblemScale() == macroScale ) {
553 OOFEM_LOG_INFO("StaggeredSolver: %-15d", nite);
554 } else {
555 OOFEM_LOG_INFO(" StaggeredSolver: %-15d", nite);
556 }
557
558 forceErr = parallel_context->localNorm(rhs);
559 forceErr *= forceErr;
560 dXX = parallel_context->localNorm(X);
561 dXX *= dXX; // Note: Solutions are always total global values (natural distribution makes little sense for the solution)
562 dXdX = parallel_context->localNorm(ddX);
563 dXdX *= dXdX;
564
565 if ( rtolf.at(1) > 0.0 ) {
566 // we compute a relative error norm
567 if ( ( RRT + internalForcesEBENorm.at(1) ) > ERROR_NORM_SMALL_NUM ) {
568 forceErr = sqrt( forceErr / ( RRT + internalForcesEBENorm.at(1) ) );
569 } else {
570 forceErr = sqrt(forceErr); // absolute norm as last resort
571 }
572 if ( fabs(forceErr) > rtolf.at(1) * MAX_REL_ERROR_BOUND ) {
573 errorOutOfRange = true;
574 }
575 if ( fabs(forceErr) > rtolf.at(1) ) {
576 answer = false;
577 }
578 OOFEM_LOG_INFO(" %-15e", forceErr);
579
580 if ( this->constrainedNRFlag ) {
581 // store the errors from the current iteration for use in the next
582 forceErrVec.at(1) = forceErr;
583 }
584 }
585
586 if ( rtold.at(1) > 0.0 ) {
587 // compute displacement error
588 // err is relative displacement change
589 if ( dXX > ERROR_NORM_SMALL_NUM ) {
590 dispErr = sqrt(dXdX / dXX);
591 } else {
592 dispErr = sqrt(dXdX);
593 }
594 if ( fabs(dispErr) > rtold.at(1) * MAX_REL_ERROR_BOUND ) {
595 errorOutOfRange = true;
596 }
597 if ( fabs(dispErr) > rtold.at(1) ) {
598 answer = false;
599 }
600 OOFEM_LOG_INFO(" %-15e", dispErr);
601 }
602
603 OOFEM_LOG_INFO("\n");
604 } // end default case (all dofs contributing)
605
606 return answer;
607}
608
609} // end namespace oofem
610
#define REGISTER_SparseNonLinearSystemNM(class)
std ::vector< FloatArray > dX
void giveTotalLocationArray(IntArray &locationArray, const UnknownNumberingScheme &s, Domain *d)
std ::vector< FloatArray > fExtList
std ::vector< FloatArray > ddX
std ::vector< std ::unique_ptr< SparseMtrx > > stiffnessMatrixList
std ::vector< FloatArray > X
std ::vector< IntArray > locArrayList
std ::vector< FloatArray > fIntList
DofIDItem giveDofID() const
Definition dof.h:276
virtual int __giveEquationNumber() const =0
virtual int __givePrescribedEquationNumber()=0
std ::vector< std ::unique_ptr< DofManager > > & giveDofManagers()
Definition domain.h:427
std ::vector< std ::unique_ptr< Element > > & giveElements()
Definition domain.h:294
void assemble(const FloatArray &fe, const IntArray &loc)
Definition floatarray.C:616
void resize(Index s)
Definition floatarray.C:94
double & at(Index i)
Definition floatarray.h:202
Index giveSize() const
Returns the size of receiver.
Definition floatarray.h:261
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
Definition floatarray.C:403
void zero()
Zeroes all coefficients of receiver.
Definition floatarray.C:683
void add(const FloatArray &src)
Definition floatarray.C:218
void followedBy(const IntArray &b, int allocChunk=0)
Definition intarray.C:94
void resize(int n)
Definition intarray.C:73
bool contains(int value) const
Definition intarray.h:292
void zero()
Sets all component to zero.
Definition intarray.C:52
void findNonzeros(const IntArray &logical)
Definition intarray.C:155
int & at(std::size_t i)
Definition intarray.h:104
int giveSize() const
Definition intarray.h:211
NRSolver(Domain *d, EngngModel *m)
FloatArray lastReactions
Computed reactions. They are stored in order to print them in printState method.
Definition nrsolver.h:135
int constrainedNRminiter
Minimum number of iterations before constraint is activated.
Definition nrsolver.h:147
SparseLinearSystemNM * giveLinearSolver() override
Definition nrsolver.C:406
bool checkConvergence(FloatArray &RT, FloatArray &F, FloatArray &rhs, FloatArray &ddX, FloatArray &X, double RRT, const FloatArray &internalForcesEBENorm, int nite, bool &errorOutOfRange)
Definition nrsolver.C:594
void applyConstraintsToStiffness(SparseMtrx &k)
Definition nrsolver.C:468
std ::unique_ptr< SparseLinearSystemNM > linSolver
linear system solver
Definition nrsolver.h:109
double constrainedNRalpha
Scale factor for dX, dX_new = alpha * dX.
Definition nrsolver.h:145
IntArray prescribedDofs
Array of pairs identifying prescribed dofs (node, dof).
Definition nrsolver.h:125
int numberOfPrescribedDofs
number of prescribed displacement
Definition nrsolver.h:115
bool prescribedDofsFlag
Definition nrsolver.h:122
void applyConstraintsToLoadIncrement(int nite, const SparseMtrx &k, FloatArray &R, referenceLoadInputModeType rlm, TimeStep *tStep)
Definition nrsolver.C:512
LineSearchNM * giveLineSearchSolver()
Constructs and returns a line search solver.
Definition nrsolver.C:424
IntArray prescribedEqs
Array of prescribed equations.
Definition nrsolver.h:131
FloatArray rtold
Relative iterative displacement change tolerance for each group.
Definition nrsolver.h:152
bool prescribedEqsInitFlag
Flag indicating that prescribedEqs were initialized.
Definition nrsolver.h:133
FloatArray rtolf
Relative unbalanced force tolerance for each group.
Definition nrsolver.h:150
FloatArray forceErrVec
Definition nrsolver.h:155
bool lsFlag
Flag indicating whether to use line-search.
Definition nrsolver.h:137
void initPrescribedEqs()
Initiates prescribed equations.
Definition nrsolver.C:434
bool mCalcStiffBeforeRes
Flag indicating if the stiffness should be evaluated before the residual in the first iteration.
Definition nrsolver.h:141
nrsolver_ModeType NR_Mode
Definition nrsolver.h:104
FloatArray forceErrVecOld
Definition nrsolver.h:156
bool constrainedNRFlag
Flag indicating whether to use constrained Newton.
Definition nrsolver.h:143
Domain * domain
Pointer to domain.
Definition nummet.h:84
EngngModel * engngModel
Pointer to engineering model.
Definition nummet.h:86
bool isLocal(DofManager *dman)
double accumulate(double local)
double localNorm(const FloatArray &src)
virtual std::unique_ptr< SparseMtrx > giveSubMatrix(const IntArray &rows, const IntArray &cols)
Definition sparsemtrx.h:261
bool checkConvergenceDofIdArray(FloatArray &RT, FloatArray &F, FloatArray &rhs, FloatArray &ddX, FloatArray &X, double RRT, const FloatArray &internalForcesEBENorm, int nite, bool &errorOutOfRange, TimeStep *tStep, IntArray &dofIdArray)
std ::vector< CustomEquationNumbering > UnknownNumberingSchemeList
void incrementSubStepNumber()
Increments receiver's substep number.
Definition timestep.h:217
void incrementStateCounter()
Updates solution state counter.
Definition timestep.h:213
#define ERROR_NORM_SMALL_NUM
#define MAX_REL_ERROR_BOUND
#define OOFEM_WARNING(...)
Definition error.h:80
#define IR_GIVE_FIELD(__ir, __value, __id)
Definition inputrecord.h:67
#define OOFEM_LOG_INFO(...)
Definition logger.h:143
#define OOFEM_LOG_DEBUG(...)
Definition logger.h:144
std::string __DofIDItemToString(DofIDItem _value)
Definition cltypes.C:329
@ Element_local
Element is local, there are no contributions from other domains to this element.
Definition element.h:88
@ CR_DIVERGED_TOL
@ CR_DIVERGED_ITS
@ NonLinearLhs
@ InternalRhs
@ macroScale
Definition problemmode.h:46
#define _IFT_StaggeredSolver_DofIdList
#define _IFT_StaggeredSolver_DofIdListPositions

This page is part of the OOFEM-3.0 documentation. Copyright Copyright (C) 1994-2025 Borek Patzak Bořek Patzák
Project e-mail: oofem@fsv.cvut.cz
Generated at for OOFEM by doxygen 1.15.0 written by Dimitri van Heesch, © 1997-2011