void MeshFunctionSolutionTransfer::transfer(const Variable & from_var, const Variable & to_var) { // This only works when transferring to a Lagrange variable libmesh_assert(to_var.type().family == LAGRANGE); unsigned int to_var_num = to_var.number(); System * from_sys = from_var.system(); System * to_sys = to_var.system(); // Only works with a serialized mesh to transfer from! libmesh_assert(from_sys->get_mesh().is_serial()); unsigned int to_sys_num = to_sys->number(); EquationSystems & from_es = from_sys->get_equation_systems(); //Create a serialized version of the solution vector NumericVector<Number> * serialized_solution = NumericVector<Number>::build(from_sys->get_mesh().comm()).release(); serialized_solution->init(from_sys->n_dofs(), false, SERIAL); // Need to pull down a full copy of this vector on every processor // so we can get values in parallel from_sys->solution->localize(*serialized_solution); MeshFunction from_func(from_es, *serialized_solution, from_sys->get_dof_map(), to_var_num); from_func.init(); MeshBase::const_node_iterator nd = to_sys->get_mesh().local_nodes_begin(); MeshBase::const_node_iterator nd_end = to_sys->get_mesh().local_nodes_end(); // Now loop over the nodes of the 'To' mesh setting values for each variable. for(;nd != nd_end; ++nd) // 0 is for the value component to_sys->solution->set((*nd)->dof_number(to_sys_num, to_var_num, 0), from_func(**nd)); to_sys->solution->close(); to_sys->update(); delete serialized_solution; }
void MultiAppProjectionTransfer::assembleL2To(EquationSystems & es, const std::string & system_name) { unsigned int app = es.parameters.get<unsigned int>("app"); FEProblem & from_problem = *_multi_app->problem(); EquationSystems & from_es = from_problem.es(); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); System & from_sys = from_var.sys().system(); unsigned int from_var_num = from_sys.variable_number(from_var.name()); NumericVector<Number> * serialized_from_solution = NumericVector<Number>::build(from_sys.comm()).release(); serialized_from_solution->init(from_sys.n_dofs(), false, SERIAL); // Need to pull down a full copy of this vector on every processor so we can get values in parallel from_sys.solution->localize(*serialized_from_solution); MeshFunction from_func(from_es, *serialized_from_solution, from_sys.get_dof_map(), from_var_num); from_func.init(Trees::ELEMENTS); from_func.enable_out_of_mesh_mode(0.); const MeshBase& mesh = es.get_mesh(); const unsigned int dim = mesh.mesh_dimension(); LinearImplicitSystem & system = es.get_system<LinearImplicitSystem>(system_name); FEType fe_type = system.variable_type(0); AutoPtr<FEBase> fe(FEBase::build(dim, fe_type)); QGauss qrule(dim, fe_type.default_quadrature_order()); fe->attach_quadrature_rule(&qrule); const std::vector<Real> & JxW = fe->get_JxW(); const std::vector<std::vector<Real> > & phi = fe->get_phi(); const std::vector<Point> & xyz = fe->get_xyz(); const DofMap& dof_map = system.get_dof_map(); DenseMatrix<Number> Ke; DenseVector<Number> Fe; std::vector<dof_id_type> dof_indices; MeshBase::const_element_iterator el = mesh.active_local_elements_begin(); const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end(); for ( ; el != end_el; ++el) { const Elem* elem = *el; fe->reinit (elem); dof_map.dof_indices (elem, dof_indices); Ke.resize (dof_indices.size(), dof_indices.size()); Fe.resize (dof_indices.size()); for (unsigned int qp = 0; qp < qrule.n_points(); qp++) { Point qpt = xyz[qp]; Point pt = qpt + _multi_app->position(app); Real f = from_func(pt); // Now compute the element matrix and RHS contributions. for (unsigned int i=0; i<phi.size(); i++) { // RHS Fe(i) += JxW[qp] * (f * phi[i][qp]); if (_compute_matrix) for (unsigned int j = 0; j < phi.size(); j++) { // The matrix contribution Ke(i,j) += JxW[qp] * (phi[i][qp] * phi[j][qp]); } } dof_map.constrain_element_matrix_and_vector(Ke, Fe, dof_indices); if (_compute_matrix) system.matrix->add_matrix(Ke, dof_indices); system.rhs->add_vector(Fe, dof_indices); } } }
void MultiAppMeshFunctionTransfer::execute() { Moose::out << "Beginning MeshFunctionTransfer " << _name << std::endl; switch(_direction) { case TO_MULTIAPP: { FEProblem & from_problem = *_multi_app->problem(); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); // Only works with a serialized mesh to transfer from! mooseAssert(from_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!"); unsigned int from_var_num = from_sys.variable_number(from_var.name()); EquationSystems & from_es = from_sys.get_equation_systems(); //Create a serialized version of the solution vector NumericVector<Number> * serialized_solution = NumericVector<Number>::build().release(); serialized_solution->init(from_sys.n_dofs(), false, SERIAL); // Need to pull down a full copy of this vector on every processor so we can get values in parallel from_sys.solution->localize(*serialized_solution); MeshFunction from_func(from_es, *serialized_solution, from_sys.get_dof_map(), from_var_num); from_func.init(Trees::ELEMENTS); from_func.enable_out_of_mesh_mode(NOTFOUND); for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (_multi_app->hasLocalApp(i)) { MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); // Loop over the master nodes and set the value of the variable System * to_sys = find_sys(_multi_app->appProblem(i)->es(), _to_var_name); if (!to_sys) mooseError("Cannot find variable "<<_to_var_name<<" for "<<_name<<" Transfer"); unsigned int sys_num = to_sys->number(); unsigned int var_num = to_sys->variable_number(_to_var_name); NumericVector<Real> & solution = _multi_app->appTransferVector(i, _to_var_name); MeshBase & mesh = _multi_app->appProblem(i)->mesh().getMesh(); bool is_nodal = to_sys->variable_type(var_num).family == LAGRANGE; if (is_nodal) { MeshBase::const_node_iterator node_it = mesh.local_nodes_begin(); MeshBase::const_node_iterator node_end = mesh.local_nodes_end(); for(; node_it != node_end; ++node_it) { Node * node = *node_it; if (node->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this node { // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(sys_num, var_num, 0); // Swap back Moose::swapLibMeshComm(swapped); Real from_value = from_func(*node+_multi_app->position(i)); // Swap again swapped = Moose::swapLibMeshComm(_multi_app->comm()); if (from_value != NOTFOUND) solution.set(dof, from_value); else if (_error_on_miss) mooseError("Point not found! " << *node+_multi_app->position(i) << std::endl); } } } else // Elemental { MeshBase::const_element_iterator elem_it = mesh.local_elements_begin(); MeshBase::const_element_iterator elem_end = mesh.local_elements_end(); for(; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; Point centroid = elem->centroid(); if (elem->n_dofs(sys_num, var_num) > 0) // If this variable has dofs at this elem { // The zero only works for LAGRANGE! dof_id_type dof = elem->dof_number(sys_num, var_num, 0); // Swap back Moose::swapLibMeshComm(swapped); Real from_value = from_func(centroid+_multi_app->position(i)); // Swap again swapped = Moose::swapLibMeshComm(_multi_app->comm()); if (from_value != NOTFOUND) solution.set(dof, from_value); else if (_error_on_miss) mooseError("Point not found! " << centroid+_multi_app->position(i) << std::endl); } } } solution.close(); to_sys->update(); // Swap back Moose::swapLibMeshComm(swapped); } } delete serialized_solution; break; } case FROM_MULTIAPP: { FEProblem & to_problem = *_multi_app->problem(); MooseVariable & to_var = to_problem.getVariable(0, _to_var_name); SystemBase & to_system_base = to_var.sys(); System & to_sys = to_system_base.system(); unsigned int to_sys_num = to_sys.number(); // Only works with a serialized mesh to transfer to! mooseAssert(to_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!"); unsigned int to_var_num = to_sys.variable_number(to_var.name()); EquationSystems & to_es = to_sys.get_equation_systems(); NumericVector<Number> * to_solution = to_sys.solution.get(); MeshBase & to_mesh = to_es.get_mesh(); bool is_nodal = to_sys.variable_type(to_var_num).family == LAGRANGE; for(unsigned int i=0; i<_multi_app->numGlobalApps(); i++) { if (!_multi_app->hasLocalApp(i)) continue; MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); FEProblem & from_problem = *_multi_app->appProblem(i); MooseVariable & from_var = from_problem.getVariable(0, _from_var_name); SystemBase & from_system_base = from_var.sys(); System & from_sys = from_system_base.system(); // Only works with a serialized mesh to transfer from! mooseAssert(from_sys.get_mesh().is_serial(), "MultiAppMeshFunctionTransfer only works with SerialMesh!"); unsigned int from_var_num = from_sys.variable_number(from_var.name()); EquationSystems & from_es = from_sys.get_equation_systems(); //Create a serialized version of the solution vector NumericVector<Number> * serialized_from_solution = NumericVector<Number>::build().release(); serialized_from_solution->init(from_sys.n_dofs(), false, SERIAL); // Need to pull down a full copy of this vector on every processor so we can get values in parallel from_sys.solution->localize(*serialized_from_solution); MeshBase & from_mesh = from_es.get_mesh(); MeshTools::BoundingBox app_box = MeshTools::processor_bounding_box(from_mesh, libMesh::processor_id()); Point app_position = _multi_app->position(i); MeshFunction from_func(from_es, *serialized_from_solution, from_sys.get_dof_map(), from_var_num); from_func.init(Trees::ELEMENTS); from_func.enable_out_of_mesh_mode(NOTFOUND); Moose::swapLibMeshComm(swapped); if (is_nodal) { MeshBase::const_node_iterator node_it = to_mesh.nodes_begin(); MeshBase::const_node_iterator node_end = to_mesh.nodes_end(); for(; node_it != node_end; ++node_it) { Node * node = *node_it; if (node->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this node { // See if this node falls in this bounding box if (app_box.contains_point(*node-app_position)) { // The zero only works for LAGRANGE! dof_id_type dof = node->dof_number(to_sys_num, to_var_num, 0); MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); Real from_value = from_func(*node-app_position); Moose::swapLibMeshComm(swapped); if (from_value != NOTFOUND) to_solution->set(dof, from_value); else if (_error_on_miss) mooseError("Point not found! " << *node-app_position <<std::endl); } } } } else // Elemental { MeshBase::const_element_iterator elem_it = to_mesh.elements_begin(); MeshBase::const_element_iterator elem_end = to_mesh.elements_end(); for(; elem_it != elem_end; ++elem_it) { Elem * elem = *elem_it; if (elem->n_dofs(to_sys_num, to_var_num) > 0) // If this variable has dofs at this elem { Point centroid = elem->centroid(); // See if this elem falls in this bounding box if (app_box.contains_point(centroid-app_position)) { // The zero only works for LAGRANGE! dof_id_type dof = elem->dof_number(to_sys_num, to_var_num, 0); MPI_Comm swapped = Moose::swapLibMeshComm(_multi_app->comm()); Real from_value = from_func(centroid-app_position); Moose::swapLibMeshComm(swapped); if (from_value != NOTFOUND) to_solution->set(dof, from_value); else if (_error_on_miss) mooseError("Point not found! " << centroid-app_position << std::endl); } } } } delete serialized_from_solution; } to_solution->close(); to_sys.update(); break; } } Moose::out << "Finished MeshFunctionTransfer " << _name << std::endl; }