bokhoven::bokhoven(const math::lcp& lcp) : lcp(lcp), d( diagp1(lcp.M) ), P( off_diag(lcp.M) ) { assert( ! (d.array() == 0 ).any() ); }
SplitBasedPreconditioner::SplitBasedPreconditioner (const std::string & name, InputParameters params) : MoosePreconditioner(name, params), _nl(_fe_problem.getNonlinearSystem()) { unsigned int n_vars = _nl.nVariables(); bool full = getParam<bool>("full"); CouplingMatrix *cm = new CouplingMatrix(n_vars); if (!full) { // put 1s on diagonal for (unsigned int i = 0; i < n_vars; i++) (*cm)(i, i) = 1; // off-diagonal entries std::vector<std::vector<unsigned int> > off_diag(n_vars); for (unsigned int i = 0; i < getParam<std::vector<std::string> >("off_diag_row").size(); i++) { unsigned int row = _nl.getVariable(0, getParam<std::vector<std::string> >("off_diag_row")[i]).number(); unsigned int column = _nl.getVariable(0, getParam<std::vector<std::string> >("off_diag_column")[i]).number(); (*cm)(row, column) = 1; } } else { for (unsigned int i = 0; i < n_vars; i++) for (unsigned int j = 0; j < n_vars; j++) (*cm)(i,j) = 1; } _fe_problem.setCouplingMatrix(cm); _nl.useSplitBasedPreconditioner(true); }
modulus_lcp::modulus_lcp(const mat& M) : M(M), d( diagp1(M) ), P( off_diag(M) ) { assert( ! (d.array() == 0 ).any() ); }
SingleMatrixPreconditioner::SingleMatrixPreconditioner(const InputParameters & params) : MoosePreconditioner(params) { NonlinearSystemBase & nl = _fe_problem.getNonlinearSystemBase(); unsigned int n_vars = nl.nVariables(); std::unique_ptr<CouplingMatrix> cm = libmesh_make_unique<CouplingMatrix>(n_vars); bool full = getParam<bool>("full"); if (!full) { // put 1s on diagonal for (unsigned int i = 0; i < n_vars; i++) (*cm)(i, i) = 1; // off-diagonal entries from the off_diag_row and off_diag_column parameters std::vector<std::vector<unsigned int>> off_diag(n_vars); for (unsigned int i = 0; i < getParam<std::vector<NonlinearVariableName>>("off_diag_row").size(); i++) { unsigned int row = nl.getVariable(0, getParam<std::vector<NonlinearVariableName>>("off_diag_row")[i]) .number(); unsigned int column = nl.getVariable(0, getParam<std::vector<NonlinearVariableName>>("off_diag_column")[i]) .number(); (*cm)(row, column) = 1; } // off-diagonal entries from the coupled_groups parameters std::vector<NonlinearVariableName> groups = getParam<std::vector<NonlinearVariableName>>("coupled_groups"); for (unsigned int i = 0; i < groups.size(); ++i) { std::vector<NonlinearVariableName> vars; MooseUtils::tokenize<NonlinearVariableName>(groups[i], vars, 1, ","); for (unsigned int j = 0; j < vars.size(); ++j) for (unsigned int k = j + 1; k < vars.size(); ++k) { unsigned int row = nl.getVariable(0, vars[j]).number(); unsigned int column = nl.getVariable(0, vars[k]).number(); (*cm)(row, column) = 1; (*cm)(column, row) = 1; } } } else { for (unsigned int i = 0; i < n_vars; i++) for (unsigned int j = 0; j < n_vars; j++) (*cm)(i, j) = 1; } _fe_problem.setCouplingMatrix(std::move(cm)); }
static mat qp_off_diag(const mat& Q, const mat& A) { mat res(Q.cols() + A.rows(), Q.cols() + A.rows()); res << off_diag(Q), -A.transpose(), A, mat::Zero(A.rows(), A.rows()); return res; }
FiniteDifferencePreconditioner::FiniteDifferencePreconditioner(const InputParameters & params) : MoosePreconditioner(params), _finite_difference_type(getParam<MooseEnum>("finite_difference_type")) { if (n_processors() > 1) mooseError("Can't use the Finite Difference Preconditioner in parallel yet!"); NonlinearSystemBase & nl = _fe_problem.getNonlinearSystemBase(); unsigned int n_vars = nl.nVariables(); std::unique_ptr<CouplingMatrix> cm = libmesh_make_unique<CouplingMatrix>(n_vars); bool full = getParam<bool>("full"); // standard finite difference method will add off-diagonal entries if (_finite_difference_type == "standard") full = true; if (!full) { // put 1s on diagonal for (unsigned int i = 0; i < n_vars; i++) (*cm)(i, i) = 1; // off-diagonal entries std::vector<std::vector<unsigned int>> off_diag(n_vars); for (unsigned int i = 0; i < getParam<std::vector<std::string>>("off_diag_row").size(); i++) { unsigned int row = nl.getVariable(0, getParam<std::vector<std::string>>("off_diag_row")[i]).number(); unsigned int column = nl.getVariable(0, getParam<std::vector<std::string>>("off_diag_column")[i]).number(); (*cm)(row, column) = 1; } // TODO: handle coupling entries between NL-vars and SCALAR-vars } else { for (unsigned int i = 0; i < n_vars; i++) for (unsigned int j = 0; j < n_vars; j++) (*cm)(i, j) = 1; } _fe_problem.setCouplingMatrix(std::move(cm)); bool implicit_geometric_coupling = getParam<bool>("implicit_geometric_coupling"); nl.addImplicitGeometricCouplingEntriesToJacobian(implicit_geometric_coupling); // Set the jacobian to null so that libMesh won't override our finite differenced jacobian nl.useFiniteDifferencedPreconditioner(true); }
FiniteDifferencePreconditioner::FiniteDifferencePreconditioner(const std::string & name, InputParameters params) : MoosePreconditioner(name, params) { if (libMesh::n_processors() > 1) mooseError("Can't use the Finite Difference Preconditioner in parallel yet!"); NonlinearSystem & nl = _fe_problem.getNonlinearSystem(); unsigned int n_vars = nl.nVariables(); CouplingMatrix * cm = new CouplingMatrix(n_vars); bool full = getParam<bool>("full"); if (!full) { // put 1s on diagonal for (unsigned int i = 0; i < n_vars; i++) (*cm)(i, i) = 1; // off-diagonal entries std::vector<std::vector<unsigned int> > off_diag(n_vars); for (unsigned int i = 0; i < getParam<std::vector<std::string> >("off_diag_row").size(); i++) { unsigned int row = nl.getVariable(0, getParam<std::vector<std::string> >("off_diag_row")[i]).index(); unsigned int column = nl.getVariable(0, getParam<std::vector<std::string> >("off_diag_column")[i]).index(); (*cm)(row, column) = 1; } // TODO: handle coupling entries between NL-vars and SCALAR-vars } else { for (unsigned int i = 0; i < n_vars; i++) for (unsigned int j = 0; j < n_vars; j++) (*cm)(i,j) = 1; } _fe_problem.setCouplingMatrix(cm); bool implicit_geometric_coupling = getParam<bool>("implicit_geometric_coupling"); nl.addImplicitGeometricCouplingEntriesToJacobian(implicit_geometric_coupling); // Set the jacobian to null so that libMesh won't override our finite differenced jacobian nl.useFiniteDifferencedPreconditioner(true); }
FieldSplitPreconditioner::FieldSplitPreconditioner(const InputParameters & parameters) : MoosePreconditioner(parameters), _top_split(getParam<std::vector<std::string> >("topsplit")), _nl(_fe_problem.getNonlinearSystemBase()) { // number of variables unsigned int n_vars = _nl.nVariables(); // if we want to construct a full Jacobian? // it is recommended to have a full Jacobian for using // the fieldSplit preconditioner bool full = getParam<bool>("full"); // how variables couple std::unique_ptr<CouplingMatrix> cm = libmesh_make_unique<CouplingMatrix>(n_vars); if (!full) { // put 1s on diagonal for (unsigned int i = 0; i < n_vars; i++) (*cm)(i, i) = 1; // off-diagonal entries std::vector<std::vector<unsigned int> > off_diag(n_vars); for (unsigned int i = 0; i < getParam<std::vector<std::string> >("off_diag_row").size(); i++) { unsigned int row = _nl.getVariable(0, getParam<std::vector<std::string> >("off_diag_row")[i]).number(); unsigned int column = _nl.getVariable(0, getParam<std::vector<std::string> >("off_diag_column")[i]).number(); (*cm)(row, column) = 1; } } else { for (unsigned int i = 0; i < n_vars; i++) for (unsigned int j = 0; j < n_vars; j++) (*cm)(i,j) = 1; // full coupling } _fe_problem.setCouplingMatrix(std::move(cm)); // turn on a flag _nl.useFieldSplitPreconditioner(true); // set a top splitting _fe_problem.getNonlinearSystemBase().setDecomposition(_top_split); // apply prefix and store PETSc options _fe_problem.getNonlinearSystemBase().setupFieldDecomposition(); }
/** Eigenvalues. \param m Input matrix (unchanged on return). \return Vector of eigenvalues. */ dvector eigenvalues(const dmatrix& m) { if (m.rowsize()!=m.colsize()) { cerr << "error -- non square matrix passed to " "dvector eigen(const dmatrix& m)\n"; ad_exit(1); } dmatrix m1=symmetrize(m); m1.colshift(1); // set minimum column and row indices to 1 m1.rowshift(1); int n=m1.rowsize(); dvector diag(1,n); dvector off_diag(1,n); tri_dag(m1,diag,off_diag); get_eigen(diag,off_diag,m1); // eigenvalues are returned in diag // eigenvalues are returned in columns of z return diag; }
PhysicsBasedPreconditioner::PhysicsBasedPreconditioner (const InputParameters & params) : MoosePreconditioner(params), Preconditioner<Number>(MoosePreconditioner::_communicator), _nl(_fe_problem.getNonlinearSystem()) { unsigned int num_systems = _nl.sys().n_vars(); _systems.resize(num_systems); _preconditioners.resize(num_systems); _off_diag.resize(num_systems); _off_diag_mats.resize(num_systems); _pre_type.resize(num_systems); { // Setup the Coupling Matrix so MOOSE knows what we're doing NonlinearSystem & nl = _fe_problem.getNonlinearSystem(); unsigned int n_vars = nl.nVariables(); // The coupling matrix is held and released by FEProblem, so it is not released in this object CouplingMatrix * cm = new CouplingMatrix(n_vars); bool full = false; //getParam<bool>("full"); // TODO: add a FULL option for PBP if (!full) { // put 1s on diagonal for (unsigned int i = 0; i < n_vars; i++) (*cm)(i, i) = 1; // off-diagonal entries std::vector<std::vector<unsigned int> > off_diag(n_vars); for (unsigned int i = 0; i < getParam<std::vector<std::string> >("off_diag_row").size(); i++) { unsigned int row = nl.getVariable(0, getParam<std::vector<std::string> >("off_diag_row")[i]).number(); unsigned int column = nl.getVariable(0, getParam<std::vector<std::string> >("off_diag_column")[i]).number(); (*cm)(row, column) = 1; } // TODO: handle coupling entries between NL-vars and SCALAR-vars } else { for (unsigned int i = 0; i < n_vars; i++) for (unsigned int j = 0; j < n_vars; j++) (*cm)(i,j) = 1; } _fe_problem.setCouplingMatrix(cm); } // PC types const std::vector<std::string> & pc_types = getParam<std::vector<std::string> >("preconditioner"); for (unsigned int i = 0; i < num_systems; i++) _pre_type[i] = Utility::string_to_enum<PreconditionerType>(pc_types[i]); // solve order const std::vector<std::string> & solve_order = getParam<std::vector<std::string> >("solve_order"); _solve_order.resize(solve_order.size()); for (unsigned int i = 0; i < solve_order.size(); i++) _solve_order[i] = _nl.sys().variable_number(solve_order[i]); // diag and off-diag systems unsigned int n_vars = _nl.sys().n_vars(); // off-diagonal entries const std::vector<std::string> & odr = getParam<std::vector<std::string> >("off_diag_row"); const std::vector<std::string> & odc = getParam<std::vector<std::string> >("off_diag_column"); std::vector<std::vector<unsigned int> > off_diag(n_vars); for (unsigned int i = 0; i < odr.size(); i++) { unsigned int row = _nl.sys().variable_number(odr[i]); unsigned int column = _nl.sys().variable_number(odc[i]); off_diag[row].push_back(column); } // Add all of the preconditioning systems for (unsigned int var = 0; var < n_vars; var++) addSystem(var, off_diag[var], _pre_type[var]); // We don't want to be computing the big Jacobian! _nl.sys().nonlinear_solver->jacobian = NULL; _nl.sys().nonlinear_solver->attach_preconditioner(this); _fe_problem.solverParams()._type = Moose::ST_JFNK; }
PhysicsBasedPreconditioner::PhysicsBasedPreconditioner(const InputParameters & params) : MoosePreconditioner(params), Preconditioner<Number>(MoosePreconditioner::_communicator), _nl(_fe_problem.getNonlinearSystemBase()), _init_timer(registerTimedSection("init", 2)), _apply_timer(registerTimedSection("apply", 1)) { unsigned int num_systems = _nl.system().n_vars(); _systems.resize(num_systems); _preconditioners.resize(num_systems); _off_diag.resize(num_systems); _off_diag_mats.resize(num_systems); _pre_type.resize(num_systems); { // Setup the Coupling Matrix so MOOSE knows what we're doing NonlinearSystemBase & nl = _fe_problem.getNonlinearSystemBase(); unsigned int n_vars = nl.nVariables(); // The coupling matrix is held and released by FEProblemBase, so it is not released in this // object std::unique_ptr<CouplingMatrix> cm = libmesh_make_unique<CouplingMatrix>(n_vars); bool full = false; // getParam<bool>("full"); // TODO: add a FULL option for PBP if (!full) { // put 1s on diagonal for (unsigned int i = 0; i < n_vars; i++) (*cm)(i, i) = 1; // off-diagonal entries std::vector<std::vector<unsigned int>> off_diag(n_vars); for (unsigned int i = 0; i < getParam<std::vector<std::string>>("off_diag_row").size(); i++) { unsigned int row = nl.getVariable(0, getParam<std::vector<std::string>>("off_diag_row")[i]).number(); unsigned int column = nl.getVariable(0, getParam<std::vector<std::string>>("off_diag_column")[i]).number(); (*cm)(row, column) = 1; } // TODO: handle coupling entries between NL-vars and SCALAR-vars } else { for (unsigned int i = 0; i < n_vars; i++) for (unsigned int j = 0; j < n_vars; j++) (*cm)(i, j) = 1; } _fe_problem.setCouplingMatrix(std::move(cm)); } // PC types const std::vector<std::string> & pc_types = getParam<std::vector<std::string>>("preconditioner"); for (unsigned int i = 0; i < num_systems; i++) _pre_type[i] = Utility::string_to_enum<PreconditionerType>(pc_types[i]); // solve order const std::vector<std::string> & solve_order = getParam<std::vector<std::string>>("solve_order"); _solve_order.resize(solve_order.size()); for (unsigned int i = 0; i < solve_order.size(); i++) _solve_order[i] = _nl.system().variable_number(solve_order[i]); // diag and off-diag systems unsigned int n_vars = _nl.system().n_vars(); // off-diagonal entries const std::vector<std::string> & odr = getParam<std::vector<std::string>>("off_diag_row"); const std::vector<std::string> & odc = getParam<std::vector<std::string>>("off_diag_column"); std::vector<std::vector<unsigned int>> off_diag(n_vars); for (unsigned int i = 0; i < odr.size(); i++) { unsigned int row = _nl.system().variable_number(odr[i]); unsigned int column = _nl.system().variable_number(odc[i]); off_diag[row].push_back(column); } // Add all of the preconditioning systems for (unsigned int var = 0; var < n_vars; var++) addSystem(var, off_diag[var], _pre_type[var]); _nl.nonlinearSolver()->attach_preconditioner(this); if (_fe_problem.solverParams()._type != Moose::ST_JFNK) mooseError("PBP must be used with JFNK solve type"); }