61#define nrsolver_ERROR_NORM_SMALL_NUM 1.e-6
62#define NRSOLVER_MAX_REL_ERROR_BOUND 1.e20
63#define NRSOLVER_MAX_RESTARTS 4
64#define NRSOLVER_RESET_STEP_REDUCE 0.25
65#define NRSOLVER_DEFAULT_NRM_TICKS 10
77 NR_Mode = NR_OldMode = nrsolverModifiedNRM;
80 numberOfPrescribedDofs = 0;
81 prescribedDofsFlag =
false;
82 prescribedEqsInitFlag =
false;
83 prescribedDisplacementTF = 0;
86 constrainedNRFlag =
false;
87 this->forceErrVecOld.resize(0);
88 this->forceErrVec.resize(0);
89 constrainedNRalpha = 0.5;
91 smConstraintVersion = 0;
92 mCalcStiffBeforeRes =
true;
94 maxIncAllowed = 1.0e20;
98NRSolver :: ~NRSolver()
105 SparseNonLinearSystemNM :: initializeFrom(ir);
158 OOFEM_ERROR(
"direct displacement mask size mismatch");
174 int calcStiffBeforeResFlag = 1;
176 if ( calcStiffBeforeResFlag == 0 ) {
196 for (
int i = 0; i < dofs.
giveSize(); ++i ) {
219 bool converged, errorOutOfRangeFlag;
224 if (
rtolf.at(1) > 0.0 ) {
227 if (
rtold.at(1) > 0.0 ) {
230 OOFEM_LOG_INFO(
"\n----------------------------------------------------------------------------\n");
266 for ( nite = 0; ; ++nite ) {
277 converged = this->
checkConvergence(RT, F, rhs, ddX, X, RRT, internalForcesEBENorm, nite, errorOutOfRangeFlag);
279 if ( errorOutOfRangeFlag ) {
286 }
else if ( nite >=
nsmax ) {
300 if ( ( nite == 0 ) && (
deltaL < 1.0 ) ) {
315 if ( this->
lsFlag && ( nite > 0 ) ) {
317 LineSearchNM :: LS_status LSstatus;
322 if ( this->
forceErrVec.computeSquaredNorm() > this->forceErrVecOld.computeSquaredNorm() ) {
333 for (
double inc : ddX ) {
334 if ( fabs(inc) > maxInc ) {
341 printf(
"Restricting increment. maxInc: %e\n", maxInc);
365 engngModel->giveExportModuleManager()->doOutput(tStep,
true);
406NRSolver :: giveLinearSolver()
424NRSolver :: giveLineSearchSolver()
434NRSolver :: initPrescribedEqs()
438 int count = 0, ndofman =
domain->giveNumberOfDofManagers();
441 for (
int j = 1; j <= ndofman; j++ ) {
445 int jglobnum =
domain->giveNode(j)->giveGlobalNumber();
449 if ( inode == jglobnum ) {
450 localPrescribedEqs.
at(++count) =
domain->giveNode(j)->giveDofWithID(idofid)->giveEquationNumber(dn);
457 for (
int i = 1; i <= count; i++ ) {
483 VecGetArray(
diag, & ptr);
486 MatSetValue(* ( lhs->
giveMtrx() ), eq, eq, ptr [ eq ] * 1.e6, INSERT_VALUES);
489 MatAssemblyBegin(* lhs->
giveMtrx(), MAT_FINAL_ASSEMBLY);
490 MatAssemblyEnd(* lhs->
giveMtrx(), MAT_FINAL_ASSEMBLY);
491 VecRestoreArray(
diag, & ptr);
525 #ifdef __PETSC_MODULE
539 #ifdef __PETSC_MODULE
546 VecGetArray(
diag, & ptr);
553 VecRestoreArray(
diag, & ptr);
572NRSolver :: printState(FILE *outputStream)
576 fprintf(outputStream,
"\nQuasi reaction table:\n\n");
577 fprintf(outputStream,
" node dof force\n");
578 fprintf(outputStream,
"============================\n");
588 fprintf(outputStream,
"============================\n\n");
595 double RRT,
const FloatArray &internalForcesEBENorm,
596 int nite,
bool &errorOutOfRange)
598 double forceErr, dispErr;
599 FloatArray dg_forceErr, dg_dispErr, dg_totalLoadLevel, dg_totalDisp;
615 errorOutOfRange =
false;
624 if ( internalForcesEBENorm.
giveSize() > 1 ) {
625 int nccdg = this->
domain->giveMaxDofID();
630 dg_forceErr.
resize(nccdg);
634 dg_totalLoadLevel.
resize(nccdg);
635 dg_totalLoadLevel.
zero();
636 dg_totalDisp.
resize(nccdg);
639 for (
auto &dofman :
domain->giveDofManagers() ) {
640 if ( !parallel_context->
isLocal( dofman.get() ) ) {
645 for (
Dof *dof : *dofman ) {
646 if ( !dof->isPrimaryDof() ) {
649 int eq = dof->giveEquationNumber(dn);
650 int dofid = dof->giveDofID();
655 dg_forceErr.
at(dofid) += rhs.
at(eq) * rhs.
at(eq);
656 dg_dispErr.
at(dofid) += ddX.
at(eq) * ddX.
at(eq);
657 dg_totalLoadLevel.
at(dofid) += RT.
at(eq) * RT.
at(eq);
658 dg_totalDisp.
at(dofid) += X.
at(eq) * X.
at(eq);
659 idsInUse.
at(dofid)++;
664 for (
auto &elem :
domain->giveElements() ) {
670 for (
int idofman = 1; idofman <= elem->giveNumberOfInternalDofManagers(); idofman++ ) {
671 DofManager *dofman = elem->giveInternalDofManager(idofman);
673 for (
Dof *dof : *dofman ) {
674 if ( !dof->isPrimaryDof() ) {
677 int eq = dof->giveEquationNumber(dn);
678 int dofid = dof->giveDofID();
684 dg_forceErr.
at(dofid) += rhs.
at(eq) * rhs.
at(eq);
685 dg_dispErr.
at(dofid) += ddX.
at(eq) * ddX.
at(eq);
686 dg_totalLoadLevel.
at(dofid) += RT.
at(eq) * RT.
at(eq);
687 dg_totalDisp.
at(dofid) += X.
at(eq) * X.
at(eq);
688 idsInUse.
at(dofid)++;
694 for (
auto &bc :
domain->giveBcs() ) {
696 for (
int idofman = 1; idofman <= bc->giveNumberOfInternalDofManagers(); idofman++ ) {
697 DofManager *dofman = bc->giveInternalDofManager(idofman);
699 for (
Dof *dof : *dofman ) {
700 if ( !dof->isPrimaryDof() ) {
703 int eq = dof->giveEquationNumber(dn);
704 int dofid = dof->giveDofID();
710 dg_forceErr.
at(dofid) += rhs.
at(eq) * rhs.
at(eq);
711 dg_dispErr.
at(dofid) += ddX.
at(eq) * ddX.
at(eq);
712 dg_totalLoadLevel.
at(dofid) += RT.
at(eq) * RT.
at(eq);
713 dg_totalDisp.
at(dofid) += X.
at(eq) * X.
at(eq);
714 idsInUse.
at(dofid)++;
721 parallel_context->
accumulate(dg_forceErr, collectiveErr);
722 dg_forceErr = collectiveErr;
723 parallel_context->
accumulate(dg_dispErr, collectiveErr);
724 dg_dispErr = collectiveErr;
725 parallel_context->
accumulate(dg_totalLoadLevel, collectiveErr);
726 dg_totalLoadLevel = collectiveErr;
727 parallel_context->
accumulate(dg_totalDisp, collectiveErr);
728 dg_totalDisp = collectiveErr;
734 int maxNumPrintouts = 6;
735 int numPrintouts = 0;
739 for (
int dg = 1; dg <= nccdg; dg++ ) {
740 bool zeroFNorm =
false, zeroDNorm =
false;
742 if ( !idsInUse.
at(dg) ) {
752 if (
rtolf.at(1) > 0.0 ) {
755 forceErr = sqrt( dg_forceErr.
at(dg) / ( dg_totalLoadLevel.
at(dg) + internalForcesEBENorm.
at(dg) +
758 forceErr = sqrt( dg_forceErr.
at(dg) / ( dg_totalLoadLevel.
at(dg) + internalForcesEBENorm.
at(dg) ) );
763 forceErr = sqrt( dg_forceErr.
at(dg) );
767 errorOutOfRange =
true;
769 if ( forceErr >
rtolf.at(1) ) {
772 if ( (forceErr > 0.0) && (nite == 0)) {
788 if (
rtold.at(1) > 0.0 ) {
791 dispErr = sqrt( dg_dispErr.
at(dg) / dg_totalDisp.
at(dg) );
796 dispErr = sqrt( dg_dispErr.
at(dg) );
799 errorOutOfRange =
true;
801 if ( dispErr >
rtold.at(1) ) {
827 forceErr = parallel_context->
localNorm(rhs);
828 forceErr *= forceErr;
834 if (
rtolf.at(1) > 0.0 ) {
837 forceErr = sqrt( forceErr / ( RRT + internalForcesEBENorm.
at(1) ) );
839 forceErr = sqrt(forceErr);
842 errorOutOfRange =
true;
844 if ( fabs(forceErr) >
rtolf.at(1) ) {
858 if (
rtold.at(1) > 0.0 ) {
862 dispErr = sqrt(dXdX / dXX);
864 dispErr = sqrt(dXdX);
867 errorOutOfRange =
true;
869 if ( fabs(dispErr) >
rtold.at(1) ) {
#define REGISTER_SparseNonLinearSystemNM(class)
Index giveSize() const
Returns the size of receiver.
void beDifferenceOf(const FloatArray &a, const FloatArray &b)
void zero()
Zeroes all coefficients of receiver.
void add(const FloatArray &src)
void zero()
Sets all component to zero.
FloatArray lastReactions
Computed reactions. They are stored in order to print them in printState method.
int constrainedNRminiter
Minimum number of iterations before constraint is activated.
FloatArray prescribedDofsValues
Array of prescribed values.
SparseMtrx::SparseMtrxVersionType smConstraintVersion
sparse matrix version, used to control constrains application to stiffness
SparseLinearSystemNM * giveLinearSolver() override
bool checkConvergence(FloatArray &RT, FloatArray &F, FloatArray &rhs, FloatArray &ddX, FloatArray &X, double RRT, const FloatArray &internalForcesEBENorm, int nite, bool &errorOutOfRange)
std ::unique_ptr< LineSearchNM > linesearchSolver
Line search solver.
LinSystSolverType solverType
linear system solver ID
void applyConstraintsToStiffness(SparseMtrx &k)
int prescribedDisplacementTF
Load Time Function of prescribed values.
std ::unique_ptr< SparseLinearSystemNM > linSolver
linear system solver
double constrainedNRalpha
Scale factor for dX, dX_new = alpha * dX.
IntArray prescribedDofs
Array of pairs identifying prescribed dofs (node, dof).
int numberOfPrescribedDofs
number of prescribed displacement
void applyConstraintsToLoadIncrement(int nite, const SparseMtrx &k, FloatArray &R, referenceLoadInputModeType rlm, TimeStep *tStep)
LineSearchNM * giveLineSearchSolver()
Constructs and returns a line search solver.
IntArray prescribedEqs
Array of prescribed equations.
FloatArray rtold
Relative iterative displacement change tolerance for each group.
nrsolver_ModeType NR_OldMode
bool solutionDependentExternalForcesFlag
Solution dependent external forces - updating then each NR iteration.
std ::map< int, double > dg_forceScale
Optional user supplied scale of forces used in convergence check.
bool prescribedEqsInitFlag
Flag indicating that prescribedEqs were initialized.
FloatArray rtolf
Relative unbalanced force tolerance for each group.
bool lsFlag
Flag indicating whether to use line-search.
void initPrescribedEqs()
Initiates prescribed equations.
bool mCalcStiffBeforeRes
Flag indicating if the stiffness should be evaluated before the residual in the first iteration.
nrsolver_ModeType NR_Mode
FloatArray forceErrVecOld
bool constrainedNRFlag
Flag indicating whether to use constrained Newton.
Domain * domain
Pointer to domain.
EngngModel * engngModel
Pointer to engineering model.
bool isLocal(DofManager *dman)
double accumulate(double local)
double localNorm(const FloatArray &src)
void createVecGlobal(Vec *answer) const
Creates a global vector that fits the instance of this matrix.
SparseMtrxVersionType giveVersion()
Return receiver version.
virtual double & at(int i, int j)=0
Returns coefficient at position (i,j).
referenceLoadInputModeType
@ rlm_total
The reference incremental load vector is defined as totalLoadVector assembled at given time.
void incrementSubStepNumber()
Increments receiver's substep number.
void incrementStateCounter()
Updates solution state counter.
double giveTimeIncrement()
Returns solution step associated time increment.
double giveTargetTime()
Returns target time.
#define OOFEM_LOG_INFO(...)
std::string __DofIDItemToString(DofIDItem _value)
@ Element_local
Element is local, there are no contributions from other domains to this element.
FloatMatrixF< N, N > diag(const FloatArrayF< N > &v)
ClassFactory & classFactory
static FloatArray Vec1(const double &a)
#define nrsolver_ERROR_NORM_SMALL_NUM
#define NRSOLVER_MAX_REL_ERROR_BOUND
#define _IFT_NRSolver_maxiter
#define _IFT_NRSolver_ddfunc
#define _IFT_NRSolver_ddm
#define _IFT_NRSolver_rtolf
#define _IFT_NRSolver_linesearch
#define _IFT_NRSolver_lstype
#define _IFT_NRSolver_ddv
#define _IFT_NRSolver_calcstiffbeforeres
#define _IFT_NRSolver_miniterations
#define _IFT_NRSolver_manrmsteps
#define _IFT_NRSolver_rtold
#define _IFT_NRSolver_solutionDependentExternalForces
#define _IFT_NRSolver_rtolv
#define _IFT_NRSolver_maxinc
#define _IFT_NRSolver_forceScaleDofs
#define _IFT_NRSolver_minsteplength
#define _IFT_NRSolver_forceScale
#define _IFT_NRSolver_constrainedNRminiter