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(); }
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(); } }