Added: enum value NONE_UPTAN implying linear analysis, but with calculation

of tangent matrix at each step. Must use this when we have inhomogeneous
Dirichlet conditions, as a workaround. The ideal solution would be that the
integrands had a special RHS_ONLY mode that includes element matrix
calculation, but where only the force vector is assembled.
This commit is contained in:
Knut Morten Okstad
2021-09-23 06:46:02 +02:00
parent 19b3033e7c
commit 352b5ff97c
2 changed files with 18 additions and 9 deletions

View File

@@ -30,7 +30,7 @@ const char* NonLinSIM::inputContext = "nonlinearsolver";
NonLinSIM::NonLinSIM (SIMbase& sim, CNORM n) : MultiStepSIM(sim), iteNorm(n)
{
// Default solution parameters
fromIni = iteNorm == NONE;
fromIni = iteNorm <= NONE;
maxIncr = 2;
maxit = 20;
nupdat = 20;
@@ -131,7 +131,7 @@ bool NonLinSIM::parse (const TiXmlElement* elem)
else if (!strcasecmp(value,"max"))
refNopt = MAX;
}
else if (iteNorm != NONE && (value = utl::getValue(child,"convnorm")))
else if (iteNorm > NONE && (value = utl::getValue(child,"convnorm")))
{
if (!strncasecmp(value,"energ",5))
iteNorm = ENERGY;
@@ -151,13 +151,16 @@ bool NonLinSIM::parse (const TiXmlElement* elem)
rCond = 0.0; // Compute and report condition number in the iteration log
}
if (iteNorm == NONE && nupdat < 0)
iteNorm = NONE_UPTAN; // Recalculate tangent in each step in linear analysis
return true;
}
void NonLinSIM::initPrm ()
{
if (iteNorm == NONE) // Flag to integrand that a linear solver is used
if (iteNorm <= NONE) // Flag to integrand that a linear solver is used
model.setIntegrationPrm(3,1.0);
}
@@ -227,7 +230,7 @@ ConvStatus NonLinSIM::solveStep (TimeStep& param, SolutionMode mode,
if (!this->assembleSystem(param.time,solution,newTangent))
return model.getProblem()->diverged() ? DIVERGED : FAILURE;
if (iteNorm != NONE)
if (iteNorm > NONE)
if (!model.extractLoadVec(residual))
return FAILURE;
@@ -391,7 +394,7 @@ bool NonLinSIM::lineSearch (TimeStep& param)
ConvStatus NonLinSIM::checkConvergence (TimeStep& param)
{
if (iteNorm == NONE)
if (iteNorm <= NONE)
return CONVERGED; // No iterations, we are solving a linear problem
static double convTol = 0.0;
@@ -504,7 +507,7 @@ void NonLinSIM::printWorst (utl::LogStream& os, double eps)
bool NonLinSIM::updateConfiguration (TimeStep& time)
{
if (solution.front().empty() || iteNorm == NONE)
if (solution.front().empty() || iteNorm <= NONE)
{
solution.front() = linsol;
model.updateRotations(linsol);

View File

@@ -28,7 +28,13 @@ class NonLinSIM : public MultiStepSIM
{
public:
//! \brief Enum describing the norm used for convergence checks.
enum CNORM { NONE, L2, L2SOL, ENERGY };
//! \details The value \a NONE imples no checking at all and is used to
//! conduct a pure linear analysis without equilibrium iterations.
//! The value \a NONE_UPTAN value implies the same as \a NONE, but with
//! recalculation of the tangent matrix at each step. This is needed for
//! problems with inhomogeneous dirichlet conditions where the element
//! tangent matrix is used to calculate the equivalent load vector.
enum CNORM { NONE_UPTAN=-1, NONE=0, L2=1, L2SOL=2, ENERGY=3 };
//! \brief The constructor initializes default solution parameters.
//! \param sim Pointer to the spline FE model
@@ -38,7 +44,7 @@ public:
virtual ~NonLinSIM();
//! \brief Defines which type of iteration norm to use in convergence checks.
void setConvNorm(CNORM n) { if ((iteNorm = n) == NONE) fromIni = true; }
void setConvNorm(CNORM n) { if ((iteNorm = n) <= NONE) fromIni = true; }
//! \brief Initializes the primary solution vectors.
//! \param[in] nSol Number of consequtive solutions stored in core
@@ -77,7 +83,7 @@ public:
int getMaxit() const { return maxit; }
//! \brief Returns whether this solution driver is linear or not.
virtual bool isLinear() const { return iteNorm == NONE; }
virtual bool isLinear() const { return iteNorm <= NONE; }
protected:
//! \brief Prints out the worst DOFs when slow convergence is detected.