Esempio n. 1
0
    bokhoven::bokhoven(const math::lcp& lcp)
      : lcp(lcp),
	d( diagp1(lcp.M) ),
	P( off_diag(lcp.M) )
    {
      assert( ! (d.array() == 0 ).any() );
    }
Esempio n. 2
0
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);
}
Esempio n. 3
0
    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));
}
Esempio n. 5
0
    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);
}
Esempio n. 8
0
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();
}
Esempio n. 9
0
/** 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;
}
Esempio n. 11
0
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");
}