示例#1
0
void
AddPeriodicBCAction::act()
{
  NonlinearSystem & nl = _problem->getNonlinearSystem();
  _mesh = &_problem->mesh();

  if (autoTranslationBoundaries())
    return;

  if (_pars.isParamValid("translation"))
  {
    RealVectorValue translation = getParam<RealVectorValue>("translation");

    PeriodicBoundary p(translation);
    p.myboundary = _mesh->getBoundaryID(getParam<BoundaryName>("primary"));
    p.pairedboundary = _mesh->getBoundaryID(getParam<BoundaryName>("secondary"));
    setPeriodicVars(p, getParam<std::vector<VariableName> >("variable"));

    _problem->addGhostedBoundary(p.myboundary);
    _problem->addGhostedBoundary(p.pairedboundary);

    nl.dofMap().add_periodic_boundary(p);
  }
  else if (getParam<std::vector<std::string> >("transform_func") != std::vector<std::string>())
  {
    std::vector<std::string> inv_fn_names = getParam<std::vector<std::string> >("inv_transform_func");
    std::vector<std::string> fn_names = getParam<std::vector<std::string> >("transform_func");

    // If the user provided a forward transformation, he must also provide an inverse -- we can't
    // form the inverse of an arbitrary function automatically...
    if (inv_fn_names == std::vector<std::string>())
      mooseError("You must provide an inv_transform_func for FunctionPeriodicBoundary!");

    FunctionPeriodicBoundary pb(*_problem, fn_names);
    pb.myboundary = _mesh->getBoundaryID(getParam<BoundaryName>("primary"));
    pb.pairedboundary = _mesh->getBoundaryID(getParam<BoundaryName>("secondary"));
    setPeriodicVars(pb, getParam<std::vector<VariableName> >("variable"));

    FunctionPeriodicBoundary ipb(*_problem, inv_fn_names);
    ipb.myboundary = _mesh->getBoundaryID(getParam<BoundaryName>("secondary"));   // these are swapped
    ipb.pairedboundary = _mesh->getBoundaryID(getParam<BoundaryName>("primary")); // these are swapped
    setPeriodicVars(ipb, getParam<std::vector<VariableName> >("variable"));

    _problem->addGhostedBoundary(ipb.myboundary);
    _problem->addGhostedBoundary(ipb.pairedboundary);

    // Add the pair of periodic boundaries to the dof map
    nl.dofMap().add_periodic_boundary(pb, ipb);
  }
  else
  {
    mooseError("You have to specify either 'auto_direction', 'translation' or 'trans_func' in your period boundary section '" + _name + "'");
  }
}
示例#2
0
bool
AddPeriodicBCAction::autoTranslationBoundaries()
{
  if (isParamValid("auto_direction"))
  {
    // If we are working with a parallel mesh then we're going to ghost all the boundaries everywhere because we don't know what we need...
    if (_mesh->isParallelMesh())
    {
      const std::set<BoundaryID> & ids = _mesh->meshBoundaryIds();
      for (std::set<BoundaryID>::const_iterator id_it = ids.begin();
          id_it != ids.end();
          ++id_it)
        _problem->addGhostedBoundary(*id_it);

      _problem->ghostGhostedBoundaries();
      _mesh->detectOrthogonalDimRanges();
    }

    NonlinearSystem & nl = _problem->getNonlinearSystem();
    std::vector<std::string> auto_dirs = getParam<std::vector<std::string> >("auto_direction");

    int dim_offset = _mesh->dimension() - 2;
    for (unsigned int i=0; i<auto_dirs.size(); ++i)
    {
      int component = -1;
      if (auto_dirs[i] == "X" || auto_dirs[i] == "x")
        component = 0;
      else if (auto_dirs[i] == "Y" || auto_dirs[i] == "y")
      {
        if (dim_offset < 0)
          mooseError("Cannot wrap 'Y' direction when using a 1D mesh");
        component = 1;
      }
      else if (auto_dirs[i] == "Z" || auto_dirs[i] == "z")
      {
        if (dim_offset <= 0)
          mooseError("Cannot wrap 'Z' direction when using a 1D or 2D mesh");
        component = 2;
      }

      if (component >= 0)
      {
        std::pair<BoundaryID, BoundaryID> *boundary_ids = _mesh->getPairedBoundaryMapping(component);
        RealVectorValue v;
        v(component) = _mesh->dimensionWidth(component);
        PeriodicBoundary p(v);

        if (boundary_ids == NULL)
          mooseError("Couldn't auto-detect a paired boundary for use with periodic boundary conditions");

        p.myboundary = boundary_ids->first;
        p.pairedboundary = boundary_ids->second;
        setPeriodicVars(p, getParam<std::vector<VariableName> >("variable"));
        nl.dofMap().add_periodic_boundary(p);
      }
    }
    return true;
  }
  return false;
}
示例#3
0
bool
AddPeriodicBCAction::autoTranslationBoundaries()
{
  auto displaced_problem = _problem->getDisplacedProblem();

  if (isParamValid("auto_direction"))
  {
    // If we are working with a parallel mesh then we're going to ghost all the boundaries
    // everywhere because we don't know what we need...
    if (_mesh->isDistributedMesh())
    {
      const std::set<BoundaryID> & ids = _mesh->meshBoundaryIds();
      for (const auto & bid : ids)
        _problem->addGhostedBoundary(bid);

      _problem->ghostGhostedBoundaries();

      bool is_orthogonal_mesh = _mesh->detectOrthogonalDimRanges();

      // If we can't detect the orthogonal dimension ranges for this
      // Mesh, then auto_direction periodicity isn't going to work.
      if (!is_orthogonal_mesh)
        mooseError("Could not detect orthogonal dimension ranges for DistributedMesh.");
    }

    NonlinearSystemBase & nl = _problem->getNonlinearSystemBase();
    std::vector<std::string> auto_dirs = getParam<std::vector<std::string>>("auto_direction");

    int dim_offset = _mesh->dimension() - 2;
    for (const auto & dir : auto_dirs)
    {
      int component = -1;
      if (dir == "X" || dir == "x")
        component = 0;
      else if (dir == "Y" || dir == "y")
      {
        if (dim_offset < 0)
          mooseError("Cannot wrap 'Y' direction when using a 1D mesh");
        component = 1;
      }
      else if (dir == "Z" || dir == "z")
      {
        if (dim_offset <= 0)
          mooseError("Cannot wrap 'Z' direction when using a 1D or 2D mesh");
        component = 2;
      }

      if (component >= 0)
      {
        const std::pair<BoundaryID, BoundaryID> * boundary_ids =
            _mesh->getPairedBoundaryMapping(component);
        RealVectorValue v;
        v(component) = _mesh->dimensionWidth(component);
        PeriodicBoundary p(v);

        if (boundary_ids == NULL)
          mooseError(
              "Couldn't auto-detect a paired boundary for use with periodic boundary conditions");

        p.myboundary = boundary_ids->first;
        p.pairedboundary = boundary_ids->second;
        setPeriodicVars(p, getParam<std::vector<VariableName>>("variable"));
        nl.dofMap().add_periodic_boundary(p);
        if (displaced_problem)
          displaced_problem->nlSys().dofMap().add_periodic_boundary(p);
      }
    }
    return true;
  }
  return false;
}