void
MultiAppProjectionTransfer::projectSolution(FEProblem & to_problem, unsigned int app)
{
  EquationSystems & proj_es = to_problem.es();
  LinearImplicitSystem & ls = *_proj_sys[app];
  // activate the current transfer
  proj_es.parameters.set<MultiAppProjectionTransfer *>("transfer") = this;
  proj_es.parameters.set<unsigned int>("app") = app;

  // TODO: specify solver params in an input file
  // solver tolerance
  Real tol = proj_es.parameters.get<Real>("linear solver tolerance");
  proj_es.parameters.set<Real>("linear solver tolerance") = 1e-10;      // set our tolerance
  // solve it
  ls.solve();
  proj_es.parameters.set<Real>("linear solver tolerance") = tol;        // restore the original tolerance

  // copy projected solution into target es
  MeshBase & to_mesh = proj_es.get_mesh();

  MooseVariable & to_var = to_problem.getVariable(0, _to_var_name);
  System & to_sys = to_var.sys().system();
  NumericVector<Number> * to_solution = to_sys.solution.get();

  {
    MeshBase::const_node_iterator it = to_mesh.local_nodes_begin();
    const MeshBase::const_node_iterator end_it = to_mesh.local_nodes_end();
    for ( ; it != end_it; ++it)
    {
      const Node * node = *it;
      if (node->n_comp(to_sys.number(), to_var.number()) > 0)
      {
        const dof_id_type proj_index = node->dof_number(ls.number(), _proj_var_num, 0);
        const dof_id_type to_index = node->dof_number(to_sys.number(), to_var.number(), 0);
        to_solution->set(to_index, (*ls.solution)(proj_index));
      }
    }
  }
  {
    MeshBase::const_element_iterator it = to_mesh.active_local_elements_begin();
    const MeshBase::const_element_iterator end_it = to_mesh.active_local_elements_end();
    for ( ; it != end_it; ++it)
    {
      const Elem * elem = *it;
      if (elem->n_comp(to_sys.number(), to_var.number()) > 0)
      {
        const dof_id_type proj_index = elem->dof_number(ls.number(), _proj_var_num, 0);
        const dof_id_type to_index = elem->dof_number(to_sys.number(), to_var.number(), 0);
        to_solution->set(to_index, (*ls.solution)(proj_index));
      }
    }
  }

  to_solution->close();
  to_sys.update();
}
Example #2
0
void
CoupledExecutioner::projectVariables(FEProblem & fep)
{
  std::string dest = _fep_mapping[&fep];
  if (_var_mapping.find(dest) == _var_mapping.end())
    return;

  std::vector<ProjInfo *> & proj_list = _var_mapping[dest];
  for (std::vector<ProjInfo *>::iterator it = proj_list.begin(); it != proj_list.end(); ++it)
  {
    ProjInfo * pi = *it;

    unsigned int isrc = _name_index[pi->src];
    FEProblem * src_fep = _fe_problems[isrc];
    MooseVariable & src_mv = src_fep->getVariable(0, pi->src_var);
    SystemBase & src_sys = src_mv.sys();

    MooseVariable & dest_mv = fep.getVariable(0, pi->dest_var);
    SystemBase & dest_sys = dest_mv.sys();

    // get dof indices for source variable
    unsigned int src_vn = src_sys.system().variable_number(src_mv.name());
    std::set<dof_id_type> src_var_indices;
    src_sys.system().local_dof_indices(src_vn, src_var_indices);

    // get dof indices for destination variable
    unsigned int dest_vn = dest_sys.system().variable_number(dest_mv.name());
    std::set<dof_id_type> dest_var_indices;
    dest_sys.system().local_dof_indices(dest_vn, dest_var_indices);

    // NOTE: this is not very robust code. It relies on the same node numbering and that inserting values in the set in the same order will result
    // in a std::set with the same ordering, i.e. items in src_var_indices and dest_var_indices correspond to each other.

    // copy the values from src solution vector to dest solution vector
    std::set<dof_id_type>::iterator src_it = src_var_indices.begin();
    std::set<dof_id_type>::iterator src_it_end = src_var_indices.end();
    std::set<dof_id_type>::iterator dest_it = dest_var_indices.begin();
    for (; src_it != src_it_end; ++src_it, ++dest_it)
      dest_sys.solution().set(*dest_it, src_sys.solution()(*src_it));

    dest_sys.solution().close();
    dest_sys.update();
  }
}