28 #include "libmesh/linear_solver.h" 29 #include "libmesh/dof_map.h" 30 #include "libmesh/petsc_matrix.h" 31 #include "libmesh/petsc_vector.h" 44 step_size_change_exponent (0.5),
45 step_desired_iters (5),
46 schur_factorization (true),
100 libMesh::NumericVector<Real>
104 _X0.reset(X.clone().release());
120 << std::setw(10) <<
"iter: " 121 << std::setw(5) << iter
122 << std::setw(10) <<
"res-l2: " 123 << std::setw(15) << norm
124 << std::setw(20) <<
"relative res-l2: " 125 << std::setw(15) << norm/norm0 << std::endl;
131 if (norm <
abs_tol) cont =
false;
132 if (norm/norm0 <
rel_tol) cont =
false;
138 <<
" Retrying with smaller step-size" << std::endl;
156 << std::setw(10) <<
"iter: " 157 << std::setw(5) << iter
158 << std::setw(10) <<
"res-l2: " 159 << std::setw(15) << norm
160 << std::setw(20) <<
"relative res-l2: " 161 << std::setw(15) << norm/norm0
162 << std::setw(20) <<
"Terminated" << std::endl;
170 << std::setw(30) <<
"increased step-size: " 171 << std::setw(15) << arc_length << std::endl;
173 else if (factor < 1.) {
176 << std::setw(30) <<
"reduced step-size: " 177 << std::setw(15) << arc_length << std::endl;
187 libMesh::NumericVector<Real> &f,
189 libMesh::NumericVector<Real> &dfdp,
191 const libMesh::NumericVector<Real> &dgdX,
194 libMesh::NumericVector<Real> &dX,
222 libMesh::DofMap& dof_map = system.get_dof_map();
223 const libMesh::Parallel::Communicator
224 &comm = system.comm();
228 my_m = dof_map.n_dofs(),
232 n_l = dof_map.n_dofs_on_processor(system.processor_id()),
237 std::vector<libMesh::dof_id_type>
238 n_nz = dof_map.get_n_nz(),
239 n_oz = dof_map.get_n_oz();
242 if (rank == comm.size()-1) {
250 for (
unsigned int i=0; i<n_nz.size(); i++)
254 n_nz.push_back(total_n_l);
256 n_oz.push_back(total_n - total_n_l);
261 for (
unsigned int i=0; i<n_oz.size(); i++)
269 ierr = MatCreate(comm.get(), &mat); CHKERRABORT(comm.get(), ierr);
270 ierr = MatSetSizes(mat,
271 total_m_l, total_n_l,
272 total_m, total_n); CHKERRABORT(comm.get(), ierr);
274 if (libMesh::on_command_line(
"--solver_system_names")) {
277 MatSetOptionsPrefix(mat, nm.c_str());
279 ierr = MatSetFromOptions(mat); CHKERRABORT(comm.get(), ierr);
281 ierr = MatSeqAIJSetPreallocation(mat,
283 (PetscInt*)&n_nz[0]); CHKERRABORT(comm.get(), ierr);
284 ierr = MatMPIAIJSetPreallocation(mat,
288 (PetscInt*)&n_oz[0]); CHKERRABORT(comm.get(), ierr);
289 ierr = MatSeqBAIJSetPreallocation (mat, 1,
290 0, (PetscInt*)&n_nz[0]); CHKERRABORT(comm.get(), ierr);
291 ierr = MatMPIBAIJSetPreallocation (mat, 1,
292 0, (PetscInt*)&n_nz[0],
293 0, (PetscInt*)&n_oz[0]); CHKERRABORT(comm.get(), ierr);
296 ierr = MatSetOption(mat,
297 MAT_NEW_NONZERO_ALLOCATION_ERR,
298 PETSC_TRUE); CHKERRABORT(comm.get(), ierr);
301 Vec res_vec, sol_vec;
303 ierr = MatCreateVecs(mat, &res_vec, PETSC_NULL); CHKERRABORT(comm.get(), ierr);
304 ierr = MatCreateVecs(mat, &sol_vec, PETSC_NULL); CHKERRABORT(comm.get(), ierr);
307 std::unique_ptr<libMesh::SparseMatrix<Real> >
308 jac_mat(
new libMesh::PetscMatrix<Real>(mat, comm));
310 std::unique_ptr<libMesh::NumericVector<Real> >
311 res(
new libMesh::PetscVector<Real>(res_vec, comm)),
312 sol(
new libMesh::PetscVector<Real>(sol_vec, comm));
327 update_f?res.get():
nullptr,
337 for (
unsigned int i=dof_map.first_dof(rank); i<dof_map.end_dof(rank); i++)
338 res->set(i, f.el(i));
342 if (rank == comm.size()-1)
343 res->set(total_m-1, g);
353 for (
unsigned int i=dof_map.first_dof(rank);
354 i<dof_map.end_dof(rank); i++) {
356 jac_mat->set( i, total_m-1, dfdp.el(i));
357 jac_mat->set(total_m-1, i, dgdX.el(i));
361 if (rank == comm.size()-1)
362 jac_mat->set(total_m-1, total_m-1, dgdp);
374 ierr = KSPCreate(comm.get(), &ksp); CHKERRABORT(comm.get(), ierr);
376 if (libMesh::on_command_line(
"--solver_system_names")) {
379 KSPSetOptionsPrefix(ksp, nm.c_str());
382 ierr = KSPSetOperators(ksp, mat, mat); CHKERRABORT(comm.get(), ierr);
383 ierr = KSPSetFromOptions(ksp); CHKERRABORT(comm.get(), ierr);
386 ierr = KSPGetPC(ksp, &pc); CHKERRABORT(comm.get(), ierr);
387 ierr = PCSetFromOptions(pc); CHKERRABORT(comm.get(), ierr);
390 ierr = KSPSolve(ksp, res_vec, sol_vec);
394 for (
unsigned int i=dof_map.first_dof(rank);
395 i<dof_map.end_dof(rank); i++)
396 dX.set(i, sol->el(i));
399 #ifdef LIBMESH_ENABLE_CONSTRAINTS 400 system.get_dof_map().enforce_constraints_exactly (system,
405 std::vector<Real> val(1, 0.);
406 std::vector<libMesh::numeric_index_type> dofs(1, total_m-1);
407 sol->localize(val, dofs);
411 ierr = KSPDestroy(&ksp);
412 ierr = MatDestroy(&mat);
413 ierr = VecDestroy(&res_vec);
414 ierr = VecDestroy(&sol_vec);
424 libMesh::SparseMatrix<Real> &jac,
426 libMesh::NumericVector<Real> &f,
428 libMesh::NumericVector<Real> &dfdp,
430 libMesh::NumericVector<Real> &dXdp,
432 const libMesh::NumericVector<Real> &dgdX,
435 libMesh::NumericVector<Real> &dX,
468 std::pair<unsigned int, Real>
473 std::unique_ptr<libMesh::NumericVector<Real>>
474 r1(X.zero_clone().release());
476 libMesh::SparseMatrix<Real>
477 *pc = system.request_matrix(
"Preconditioner");
488 if (update_f || update_jac)
490 update_f? &f:
nullptr,
491 update_jac? &jac:
nullptr,
496 solver_params.second,
497 solver_params.first);
499 #ifdef LIBMESH_ENABLE_CONSTRAINTS 500 system.get_dof_map().enforce_constraints_exactly (system,
513 if (update_dfdp || update_dXdp) {
518 solver_params.second,
519 solver_params.first);
525 #ifdef LIBMESH_ENABLE_CONSTRAINTS 526 system.get_dof_map().enforce_constraints_exactly (system,
535 a = dgdp + dgdX.dot(dXdp);
540 dp = 1./a * (- g + dgdX.dot(*r1));
553 solver_params.second,
554 solver_params.first);
558 #ifdef LIBMESH_ENABLE_CONSTRAINTS 559 system.get_dof_map().enforce_constraints_exactly (system,
584 std::unique_ptr<libMesh::NumericVector<Real>>
585 f(X.zero_clone().release());
595 val = std::pow(std::pow(
_g(X, p), 2) + std::pow(f->l2_norm(), 2), 0.5);
Real rel_tol
Relative tolerance for the solver.
Real max_step
maximum step size allowed with adaptivity
const MAST::NonlinearSystem & system() const
This class implements a system for solution of nonlinear systems.
virtual void clear_elem_operation_object()
clears the association of this object with the assembly element operation object. ...
virtual void solve()
solves for the next load step
This is a scalar function whose value can be changed and one that can be used as a design variable in...
bool close_matrix
flag to control the closing fo the Jacobian after assembly
virtual void set_elem_operation_object(MAST::AssemblyElemOperations &elem_ops)
attaches a element operation to this object, and associated this with the element operation object...
void _solve_schur_factorization(const libMesh::NumericVector< Real > &X, const MAST::Parameter &p, libMesh::SparseMatrix< Real > &jac, bool update_jac, libMesh::NumericVector< Real > &f, bool update_f, libMesh::NumericVector< Real > &dfdp, bool update_dfdp, libMesh::NumericVector< Real > &dXdp, bool update_dXdp, const libMesh::NumericVector< Real > &dgdX, const Real dgdp, const Real g, libMesh::NumericVector< Real > &dX, Real &dp)
solves for the linear system of equation using Schur factorization.
virtual void _solve_NR_iterate(libMesh::NumericVector< Real > &X, MAST::Parameter &p)=0
virtual ~ContinuationSolverBase()
Real min_step
minimum step size allowed with adaptivity
virtual void _save_iteration_data()=0
method saves any data for possible resuse if the solution step is restarted
Real _res_norm(const libMesh::NumericVector< Real > &X, const MAST::Parameter &p)
void _solve(const libMesh::NumericVector< Real > &X, const MAST::Parameter &p, libMesh::NumericVector< Real > &f, bool update_f, libMesh::NumericVector< Real > &dfdp, bool update_dfdp, const libMesh::NumericVector< Real > &dgdX, const Real dgdp, const Real g, libMesh::NumericVector< Real > &dX, Real &dp)
solves for the linear system of equation as a monolithic system dX and dp are returned from the solu...
virtual std::pair< unsigned int, Real > get_linear_solve_parameters()
calls NonlinearImplicitSystem::set_solver_parameters() before accessing the values.
virtual Real _g(const libMesh::NumericVector< Real > &X, const MAST::Parameter &p)=0
Real arc_length
arc length that the solver is required to satisfy for the update.
Real abs_tol
Absolute tolerance for the solver.
MAST::AssemblyBase * _assembly
std::unique_ptr< libMesh::NumericVector< Real > > _X0
void set_operation(MAST::NonlinearSystem::Operation op)
sets the current operation of the system
void set_assembly_and_load_parameter(MAST::AssemblyElemOperations &elem_ops, MAST::AssemblyBase &assembly, MAST::Parameter &p)
sets the assembly object for this solver
std::unique_ptr< libMesh::LinearSolver< Real > > linear_solver
The LinearSolver for solution of the linear equations.
virtual void residual_and_jacobian(const libMesh::NumericVector< Real > &X, libMesh::NumericVector< Real > *R, libMesh::SparseMatrix< Real > *J, libMesh::NonlinearImplicitSystem &S)
function that assembles the matrices and vectors quantities for nonlinear solution ...
MAST::NonlinearSystem::Operation operation()
virtual void _reset_iterations()=0
method resets any data if a soltion step is restarted
unsigned int max_it
Maximum number of Newton-Raphson iterations for the solver.
Real step_size_change_exponent
exponent used in step size update.
MAST::AssemblyElemOperations * _elem_ops
void clear_assembly_and_load_parameters()
clears the assembly object from this solver
unsigned int step_desired_iters
desired N-R iterations per load-step.
virtual bool sensitivity_assemble(const libMesh::NumericVector< Real > &X, bool if_localize_sol, const MAST::FunctionBase &f, libMesh::NumericVector< Real > &sensitivity_rhs, bool close_vector=true)
Assembly function.