49#define ERROR_NORM_SMALL_NUM 1.e-6
50#define MAX_REL_ERROR_BOUND 1.e20
55int CustomEquationNumbering :: giveDofEquationNumber(
Dof* dof)
const
59 if ( this->dofIdArray.contains( (
int)
id ) ) {
82 NRSolver ::initializeFrom(ir);
87 int numDofIdGroups =
idPos.giveSize()/2;
89 for (
int i = 0; i < numDofIdGroups; i++ ) {
90 int sz =
idPos.at(i*2 + 2) -
idPos.at(i*2 + 1) + 1;
92 for (
int j = 0; j < sz; j++) {
93 int pos =
idPos.at(i*2 + 1) + j;
101DofGrouping :: DofGrouping(
const std :: vector< CustomEquationNumbering > &numberings,
Domain *d):
106 X(numberings.size()),
107 dX(numberings.size()),
108 ddX(numberings.size())
110 for (
int dG = 0; dG < (int)numberings.size(); dG++ ) {
119 IntArray nodalArray, ids, locationArray;
120 locationArray.
clear();
123 dman->giveCompleteLocationArray(nodalArray, s);
127 for (
int i = 1; i <= elem->giveNumberOfInternalDofManagers(); i++ ) {
128 elem->giveInternalDofManDofIDMask(i, ids);
129 elem->giveInternalDofManager(i)->giveLocationArray(ids, nodalArray, s);
138 for (
int i = 1; i <= nonZeroMask.
giveSize(); i++ ) {
139 condensedLocationArray.
at(i) = locationArray.
at( nonZeroMask.
at(i) );
156 bool converged, errorOutOfRangeFlag;
161 if (
rtolf.at(1) > 0.0 ) {
164 if (
rtold.at(1) > 0.0 ) {
167 OOFEM_LOG_INFO(
"\n----------------------------------------------------------------------------\n");
180 RRTtotal = parallel_context->
localNorm(RT);
181 RRTtotal *= RRTtotal;
198 for (
int dG = 0; dG < numDofIdGroups; dG++ ) {
200 RRT(dG) = dg.
fExtList[dG].computeSquaredNorm();
203 for (
int nStaggeredIter = 0;; ++nStaggeredIter) {
219 for (nite = 0;; ++nite) {
237 converged = this->
checkConvergenceDofIdArray(RT, F, RHS, ddXtotal, Xtotal, RRTtotal, internalForcesEBENorm, nite, errorOutOfRangeFlag, tStep, idArray);
240 if ( errorOutOfRangeFlag ) {
242 OOFEM_WARNING(
"Divergence reached after %d iterations", nite);
247 }
else if ( nite >=
nsmax ) {
261 if ( ( nite == 0 ) && (
deltaL < 1.0 ) ) {
272 if ( this->
lsFlag && ( nite > 0 ) ) {
274 LineSearchNM :: LS_status LSstatus;
278 if ( this->
forceErrVec.computeSquaredNorm() > this->forceErrVecOld.computeSquaredNorm() ) {
283 dg.
X[dG].add(dg.
ddX[dG]);
284 dg.
dX[dG].add(dg.
ddX[dG]);
296 engngModel->giveExportModuleManager()->doOutput(tStep,
true);
305 converged = this->
checkConvergence(RT, F, RHS, ddXtotal, Xtotal, RRTtotal, internalForcesEBENorm, nStaggeredIter, errorOutOfRangeFlag);
354 double forceErr, dispErr;
355 FloatArray dg_forceErr, dg_dispErr, dg_totalLoadLevel, dg_totalDisp;
371 errorOutOfRange =
false;
380 if ( internalForcesEBENorm.
giveSize() > 1 ) {
381 int nccdg = this->
domain->giveMaxDofID();
386 dg_forceErr.
resize(nccdg);
390 dg_totalLoadLevel.
resize(nccdg);
391 dg_totalLoadLevel.
zero();
392 dg_totalDisp.
resize(nccdg);
395 for (
auto &dofman :
domain->giveDofManagers() ) {
396 if ( !parallel_context->
isLocal(dofman.get()) ) {
401 for (
Dof *dof: *dofman ) {
402 if ( !dof->isPrimaryDof() ) {
405 int eq = dof->giveEquationNumber(dn);
406 int dofid = dof->giveDofID();
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;
420 for (
auto &elem :
domain->giveElements() ) {
426 for (
int idofman = 1; idofman <= elem->giveNumberOfInternalDofManagers(); idofman++ ) {
427 DofManager *dofman = elem->giveInternalDofManager(idofman);
429 for (
Dof *dof: *dofman ) {
430 if ( !dof->isPrimaryDof() ) {
433 int eq = dof->giveEquationNumber(dn);
434 int dofid = dof->giveDofID();
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;
450 for (
auto &bc :
domain->giveBcs() ) {
452 for (
int idofman = 1; idofman <= bc->giveNumberOfInternalDofManagers(); idofman++ ) {
453 DofManager *dofman = bc->giveInternalDofManager(idofman);
455 for (
Dof *dof: *dofman ) {
456 if ( !dof->isPrimaryDof() ) {
459 int eq = dof->giveEquationNumber(dn);
460 int dofid = dof->giveDofID();
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;
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;
489 for (
int dg = 1; dg <= nccdg; dg++ ) {
490 bool zeroFNorm =
false, zeroDNorm =
false;
492 if ( !idsInUse.
at(dg) ) {
503 if (
rtolf.at(1) > 0.0 ) {
506 forceErr = sqrt( dg_forceErr.
at(dg) / ( dg_totalLoadLevel.
at(dg) + internalForcesEBENorm.
at(dg) ) );
511 forceErr = sqrt( dg_forceErr.
at(dg) );
515 errorOutOfRange =
true;
517 if ( forceErr >
rtolf.at(1) ) {
528 if (
rtold.at(1) > 0.0 ) {
531 dispErr = sqrt( dg_dispErr.
at(dg) / dg_totalDisp.
at(dg) );
536 dispErr = sqrt( dg_dispErr.
at(dg) );
539 errorOutOfRange =
true;
541 if ( dispErr >
rtold.at(1) ) {
558 forceErr = parallel_context->
localNorm(rhs);
559 forceErr *= forceErr;
565 if (
rtolf.at(1) > 0.0 ) {
568 forceErr = sqrt( forceErr / ( RRT + internalForcesEBENorm.
at(1) ) );
570 forceErr = sqrt(forceErr);
573 errorOutOfRange =
true;
575 if ( fabs(forceErr) >
rtolf.at(1) ) {
586 if (
rtold.at(1) > 0.0 ) {
590 dispErr = sqrt(dXdX / dXX);
592 dispErr = sqrt(dXdX);
595 errorOutOfRange =
true;
597 if ( fabs(dispErr) >
rtold.at(1) ) {
#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
virtual int __giveEquationNumber() const =0
virtual int __givePrescribedEquationNumber()=0
std ::vector< std ::unique_ptr< DofManager > > & giveDofManagers()
std ::vector< std ::unique_ptr< Element > > & giveElements()
void assemble(const FloatArray &fe, const IntArray &loc)
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 followedBy(const IntArray &b, int allocChunk=0)
bool contains(int value) const
void zero()
Sets all component to zero.
void findNonzeros(const IntArray &logical)
NRSolver(Domain *d, EngngModel *m)
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.
SparseLinearSystemNM * giveLinearSolver() override
bool checkConvergence(FloatArray &RT, FloatArray &F, FloatArray &rhs, FloatArray &ddX, FloatArray &X, double RRT, const FloatArray &internalForcesEBENorm, int nite, bool &errorOutOfRange)
void applyConstraintsToStiffness(SparseMtrx &k)
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.
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)
virtual std::unique_ptr< SparseMtrx > giveSubMatrix(const IntArray &rows, const IntArray &cols)
referenceLoadInputModeType
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.
void incrementStateCounter()
Updates solution state counter.
UnknownNumberingScheme(void)
#define ERROR_NORM_SMALL_NUM
#define MAX_REL_ERROR_BOUND
#define OOFEM_WARNING(...)
#define OOFEM_LOG_INFO(...)
#define OOFEM_LOG_DEBUG(...)
std::string __DofIDItemToString(DofIDItem _value)
@ Element_local
Element is local, there are no contributions from other domains to this element.
#define _IFT_StaggeredSolver_DofIdList
#define _IFT_StaggeredSolver_DofIdListPositions