30 const std::string & name_in,
31 const unsigned int number_in) :
32 Parent(es, name_in, number_in),
33 continuation_parameter(nullptr),
35 continuation_parameter_tolerance(1.e-6),
36 solution_tolerance(1.e-6),
37 initial_newton_tolerance(0.01),
38 old_continuation_parameter(0.),
39 min_continuation_parameter(0.),
40 max_continuation_parameter(0.),
44 n_arclength_reductions(5),
47 newton_stepgrowth_aggressiveness(1.),
48 newton_progress_check(true),
51 tangent_initialized(false),
52 newton_solver(nullptr),
56 previous_dlambda_ds(0.),
61 libmesh_experimental();
291 libmesh_assert_not_equal_to (dlambda, 0.0);
362 libmesh_error_msg(
"You must set the continuation_parameter pointer " \
363 <<
"to a member variable of the derived class, preferably in the " \
364 <<
"Derived class's init_data function. This is how the ContinuationSystem " \
365 <<
"updates the continuation parameter.");
391 std::pair<unsigned int, Real> rval;
394 bool arcstep_converged =
false;
407 bool newton_converged =
false;
410 Real nonlinear_residual_firststep = 0.;
413 Real nonlinear_residual_beforestep = 0.;
416 Real nonlinear_residual_afterstep = 0.;
419 Real current_linear_tolerance = 0.;
445 const Real alp=0.5*(1.+std::sqrt(5.));
448 libmesh_assert_not_equal_to (nonlinear_residual_beforestep, 0.0);
449 libmesh_assert_not_equal_to (nonlinear_residual_afterstep, 0.0);
451 current_linear_tolerance =
std::min(gam*
std::pow(nonlinear_residual_afterstep/nonlinear_residual_beforestep, alp),
452 current_linear_tolerance*current_linear_tolerance
456 if (current_linear_tolerance < 1.e-12)
457 current_linear_tolerance = 1.e-12;
461 libMesh::out <<
"Using current_linear_tolerance=" << current_linear_tolerance << std::endl;
475 nonlinear_residual_beforestep =
rhs->
l2_norm();
480 nonlinear_residual_firststep = nonlinear_residual_beforestep;
483 libMesh::out <<
" (before step) ||R||_{L2} = " << nonlinear_residual_beforestep << std::endl;
484 libMesh::out <<
" (before step) ||R||_{L2}/||u|| = " << nonlinear_residual_beforestep / old_norm_u << std::endl;
491 libMesh::out <<
"Initial guess satisfied linear tolerance, exiting with zero Newton iterations!" << std::endl;
496 newton_converged=
true;
503 nonlinear_residual_beforestep = nonlinear_residual_afterstep;
523 current_linear_tolerance,
530 libMesh::out <<
"Repeating initial solve with smaller linear tolerance!" << std::endl;
537 libmesh_error_msg(
"Linear solver did no work!");
540 }
while (rval.first==0);
546 <<
" linear tolerance = " 556 if ((rval.first == 0) && (rval.second > current_linear_tolerance*nonlinear_residual_beforestep))
559 libMesh::out <<
"Linear solver exited in zero iterations!" << std::endl;
588 libmesh_error_msg(
"||G_Lambda|| = 0");
592 const Real ysystemtol=current_linear_tolerance*(nonlinear_residual_beforestep/yrhsnorm);
594 libMesh::out <<
"ysystemtol=" << ysystemtol << std::endl;
620 libMesh::out <<
" G_u*y = G_{lambda} solver converged at step " 622 <<
", linear tolerance = " 631 if ((rval.first == 0) && (rval.second > ysystemtol))
634 libMesh::out <<
"Linear solver exited in zero iterations!" << std::endl;
665 const Number N = N1+N2-N3;
680 libmesh_assert_not_equal_to (delta_lambda_denominator, 0.0);
683 const Number delta_lambda_comp = delta_lambda_numerator /
684 delta_lambda_denominator;
705 nonlinear_residual_afterstep =
rhs->
l2_norm();
714 libMesh::out <<
" norm_du_norm_R=" << norm_du_norm_R << std::endl;
718 Real newton_stepfactor = 1.;
720 const bool attempt_backtracking =
722 && (nonlinear_residual_afterstep > nonlinear_residual_beforestep)
724 && (norm_du_norm_R > 1.)
728 if (attempt_backtracking)
731 libMesh::out <<
"Newton step did not reduce residual." << std::endl;
740 for (
unsigned int backtrack_step=0; backtrack_step<
n_backtrack_steps; ++backtrack_step)
742 newton_stepfactor *= 0.5;
745 libMesh::out <<
"Shrinking step size by " << newton_stepfactor << std::endl;
756 nonlinear_residual_afterstep =
rhs->
l2_norm();
761 <<
", nonlinear_residual_afterstep=" 762 << nonlinear_residual_afterstep
765 if (nonlinear_residual_afterstep < nonlinear_residual_beforestep)
788 if ((attempt_backtracking) && (nonlinear_residual_afterstep > nonlinear_residual_beforestep))
803 libMesh::out <<
"Backtracking could not reduce residual ... continuing anyway!" << std::endl;
821 if ((nonlinear_residual_afterstep > nonlinear_residual_firststep) &&
824 libMesh::out <<
"Progress check failed: the current residual: " 825 << nonlinear_residual_afterstep
827 <<
"larger than the initial residual, and half of the allowed\n" 828 <<
"number of Newton iterations have elapsed.\n" 829 <<
"Exiting Newton iterations with converged==false." << std::endl;
838 libMesh::out <<
"Continuation parameter fell below min-allowable value." << std::endl;
846 libMesh::out <<
"Current continuation parameter value: " 848 <<
" exceeded max-allowable value." 858 libMesh::out <<
" delta_lambda = " << delta_lambda << std::endl;
859 libMesh::out <<
" newton_stepfactor*delta_lambda = " << newton_stepfactor*delta_lambda << std::endl;
861 libMesh::out <<
" ||delta_u|| = " << norm_delta_u << std::endl;
862 libMesh::out <<
" ||delta_u||/||u|| = " << norm_delta_u / norm_u << std::endl;
872 libMesh::out <<
" ||R||_{L2} = " << norm_residual << std::endl;
873 libMesh::out <<
" ||R||_{L2}/||u|| = " << norm_residual / norm_u << std::endl;
885 libMesh::out <<
"Newton iterations converged!" << std::endl;
887 newton_converged =
true;
892 if (!newton_converged)
894 libMesh::out <<
"Newton iterations of augmented system did not converge!" << std::endl;
910 arcstep_converged=
true;
918 if (!arcstep_converged)
919 libmesh_error_msg(
"Arcstep failed to converge after max number of reductions! Exiting...");
964 cast_ptr<NewtonSolver *> (this->
time_solver->diff_solver().get());
977 std::pair<unsigned int, Real> rval =
988 libMesh::out <<
"G_u*y = G_{lambda} solver converged at step " 990 <<
" linear tolerance = " 1035 const Real sgn_dlambda_ds =
1039 if (sgn_dlambda_ds < 0.)
1042 libMesh::out <<
"dlambda_ds is negative." << std::endl;
1213 const Real yold_over_y = yoldnorm/ynorm;
1220 libMesh::out <<
"yoldnorm/ynorm=" << yoldnorm/ynorm << std::endl;
1241 if (yold_over_y > 1.e-6)
1266 const Real double_threshold = 0.5;
1267 const Real halve_threshold = 0.5;
1268 if (yold_over_y > double_threshold)
1270 else if (yold_over_y < halve_threshold)
1286 const Real newtonstep_growthfactor =
1291 libMesh::out <<
"newtonstep_growthfactor=" << newtonstep_growthfactor << std::endl;
1305 libMesh::out <<
"Enforcing minimum-allowed arclength stepsize of " <<
ds_min << std::endl;
1340 libMesh::out <<
"Updating the solution with the tangent guess." << std::endl;
1407 libmesh_error_msg(
"Unknown predictor!");
Manages multiples systems of equations.
NumericVector< Number > * previous_u
virtual void clear() override
std::streamsize precision() const
std::unique_ptr< LinearSolver< Number > > linear_solver
Real initial_newton_tolerance
unsigned int max_nonlinear_iterations
Real old_continuation_parameter
NumericVector< Number > * previous_du_ds
std::unique_ptr< TimeSolver > time_solver
Real * continuation_parameter
NumericVector< Number > * delta_u
NumericVector< Number > * rhs
virtual T dot(const NumericVector< T > &v) const =0
void continuation_solve()
unsigned int n_arclength_reductions
virtual void scale(const T factor)=0
NumericVector< Number > * du_ds
NumericVector< Number > & add_vector(const std::string &vec_name, const bool projections=true, const ParallelType type=PARALLEL)
virtual Real l2_norm() const =0
virtual void init_data() override
Real max_continuation_parameter
NumericVector< Number > * z
unsigned int max_linear_iterations
NumericVector< Number > * y_old
NumericVector< Number > * y
std::unique_ptr< NumericVector< Number > > solution
void unsetf(std::ios_base::fmtflags mask)
Real newton_stepgrowth_aggressiveness
virtual void solve() override
ContinuationSystem(EquationSystems &es, const std::string &name, const unsigned int number)
Real min_continuation_parameter
double pow(double a, int b)
NewtonSolver * newton_solver
void initialize_tangent()
void save_current_solution()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::ios_base::fmtflags setf(std::ios_base::fmtflags fmtfl)
SparseMatrix< Number > * matrix
virtual ~ContinuationSystem()
bool newton_progress_check
unsigned int n_backtrack_steps
virtual void solve() override
virtual void clear() override
bool on_command_line(std::string arg)
const std::string & name() const
Real continuation_parameter_tolerance
virtual void add(const numeric_index_type i, const T value)=0
OStreamProxy out(std::cout)
long double min(long double a, double b)
virtual void init_data() override
virtual void assembly(bool get_residual, bool get_jacobian, bool apply_heterogeneous_constraints=false, bool apply_no_constraints=false) override