126 LinearImplicitSystem & system = es.get_system<LinearImplicitSystem>(system_name);
127 MeshBase & to_mesh = es.get_mesh();
130 std::vector<Real> & final_evals = *es.parameters.get<std::vector<Real> *>(
"final_evals");
131 std::map<dof_id_type, unsigned int> & element_map =
132 *es.parameters.get<std::map<dof_id_type, unsigned int> *>(
"element_map");
135 FEType fe_type = system.variable_type(0);
136 std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type));
137 QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order());
138 fe->attach_quadrature_rule(&qrule);
139 const DofMap & dof_map = system.get_dof_map();
140 DenseMatrix<Number> Ke;
141 DenseVector<Number> Fe;
142 std::vector<dof_id_type> dof_indices;
143 const std::vector<Real> & JxW = fe->get_JxW();
144 const std::vector<std::vector<Real>> & phi = fe->get_phi();
145 auto & system_matrix = system.get_system_matrix();
147 for (
const auto & elem : to_mesh.active_local_element_ptr_range())
151 dof_map.dof_indices(elem, dof_indices);
152 Ke.resize(dof_indices.size(), dof_indices.size());
153 Fe.resize(dof_indices.size());
155 for (
unsigned int qp = 0; qp < qrule.n_points(); qp++)
157 Real meshfun_eval = 0.;
158 if (element_map.find(elem->id()) != element_map.end())
161 meshfun_eval = final_evals[element_map[elem->id()] + qp];
165 for (
unsigned int i = 0; i < phi.size(); i++)
168 Fe(i) += JxW[qp] * (meshfun_eval * phi[i][qp]);
171 for (
unsigned int j = 0; j < phi.size(); j++)
174 Ke(i, j) += JxW[qp] * (phi[i][qp] * phi[j][qp]);
177 dof_map.constrain_element_matrix_and_vector(Ke, Fe, dof_indices);
180 system_matrix.add_matrix(Ke, dof_indices);
181 system.rhs->add_vector(Fe, dof_indices);
190 "MultiAppProjectionTransfer::execute()", 5,
"Transferring variables through projection");
231 std::map<processor_id_type, std::vector<Point>> outgoing_qps;
232 std::map<processor_id_type, std::map<std::pair<unsigned int, unsigned int>,
unsigned int>>
239 for (
unsigned int i_to = 0; i_to <
_to_problems.size(); i_to++)
242 const auto to_global_num =
244 MeshBase & to_mesh =
_to_meshes[i_to]->getMesh();
246 LinearImplicitSystem & system = *
_proj_sys[i_to];
248 FEType fe_type = system.variable_type(0);
249 std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type));
250 QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order());
251 fe->attach_quadrature_rule(&qrule);
252 const std::vector<Point> & xyz = fe->get_xyz();
254 unsigned int from0 = 0;
255 for (processor_id_type i_proc = 0; i_proc <
n_processors();
256 from0 += froms_per_proc[i_proc], i_proc++)
258 for (
const auto & elem :
259 as_range(to_mesh.local_elements_begin(), to_mesh.local_elements_end()))
264 for (
unsigned int i_from = 0; i_from < froms_per_proc[i_proc] && !qp_hit; i_from++)
266 for (
unsigned int qp = 0; qp < qrule.n_points() && !qp_hit; qp++)
269 if (bboxes[from0 + i_from].contains_point((*
_to_transforms[to_global_num])(qpt)))
279 std::pair<unsigned int, unsigned int> key(i_to, elem->id());
280 element_index_map[i_proc][key] = outgoing_qps[i_proc].size();
281 for (
unsigned int qp = 0; qp < qrule.n_points(); qp++)
284 outgoing_qps[i_proc].push_back((*
_to_transforms[to_global_num])(qpt));
305 std::vector<BoundingBox> local_bboxes(froms_per_proc[
processor_id()]);
308 unsigned int local_start = 0;
311 local_start += froms_per_proc[i_proc];
314 for (
unsigned int i_from = 0; i_from < froms_per_proc[
processor_id()]; i_from++)
315 local_bboxes[i_from] = bboxes[local_start + i_from];
319 std::vector<libMesh::MeshFunction> local_meshfuns;
320 for (
unsigned int i_from = 0; i_from <
_from_problems.size(); i_from++)
325 System & from_sys = from_var.
sys().
system();
328 local_meshfuns.emplace_back(
329 from_problem.
es(), *from_sys.current_local_solution, from_sys.get_dof_map(), from_var_num);
330 local_meshfuns.back().init();
336 std::map<processor_id_type, std::vector<std::pair<Real, unsigned int>>> outgoing_evals_ids;
340 std::map<processor_id_type, std::vector<Point>> incoming_qps;
343 auto qps_action_functor = [&incoming_qps](processor_id_type pid,
const std::vector<Point> & qps)
346 auto & incoming_qps_from_pid = incoming_qps[pid];
348 incoming_qps_from_pid.reserve(incoming_qps_from_pid.size() + qps.size());
349 std::copy(qps.begin(), qps.end(), std::back_inserter(incoming_qps_from_pid));
352 Parallel::push_parallel_vector_data(
comm(), outgoing_qps, qps_action_functor);
361 const processor_id_type pid = qps.first;
363 outgoing_evals_ids[pid].resize(qps.second.size(),
366 for (
unsigned int qp = 0; qp < qps.second.size(); qp++)
368 Point qpt = qps.second[qp];
372 for (
unsigned int i_from = 0; i_from <
_from_problems.size(); i_from++)
374 if (local_bboxes[i_from].contains_point(qpt))
376 outgoing_evals_ids[pid][qp].first = (local_meshfuns[i_from])(
390 std::map<processor_id_type, std::vector<std::pair<Real, unsigned int>>> incoming_evals_ids;
392 auto evals_action_functor =
393 [&incoming_evals_ids](processor_id_type pid,
394 const std::vector<std::pair<Real, unsigned int>> & evals)
397 auto & incoming_evals_ids_for_pid = incoming_evals_ids[pid];
399 incoming_evals_ids_for_pid.reserve(incoming_evals_ids_for_pid.size() + evals.size());
400 std::copy(evals.begin(), evals.end(), std::back_inserter(incoming_evals_ids_for_pid));
403 Parallel::push_parallel_vector_data(
comm(), outgoing_evals_ids, evals_action_functor);
405 std::vector<std::vector<Real>> final_evals(
_to_problems.size());
406 std::vector<std::map<dof_id_type, unsigned int>> trimmed_element_maps(
_to_problems.size());
408 for (
unsigned int i_to = 0; i_to <
_to_problems.size(); i_to++)
410 MeshBase & to_mesh =
_to_meshes[i_to]->getMesh();
411 LinearImplicitSystem & system = *
_proj_sys[i_to];
413 FEType fe_type = system.variable_type(0);
414 std::unique_ptr<FEBase> fe(FEBase::build(to_mesh.mesh_dimension(), fe_type));
415 QGauss qrule(to_mesh.mesh_dimension(), fe_type.default_quadrature_order());
417 for (
const auto & elem : to_mesh.active_local_element_ptr_range())
421 bool element_is_evaled =
false;
422 std::vector<Real> evals(qrule.n_points(), 0.);
424 for (
unsigned int qp = 0; qp < qrule.n_points(); qp++)
427 for (
auto & values_ids : incoming_evals_ids)
430 const processor_id_type pid = values_ids.first;
434 std::map<std::pair<unsigned int, unsigned int>,
unsigned int> & map =
435 element_index_map[pid];
436 std::pair<unsigned int, unsigned int> key(i_to, elem->id());
437 if (map.find(key) == map.end())
439 unsigned int qp0 = map[key];
444 if (values_ids.second[qp0 + qp].second >= lowest_app_rank)
453 element_is_evaled =
true;
454 evals[qp] = values_ids.second[qp0 + qp].first;
460 if (element_is_evaled)
462 trimmed_element_maps[i_to][elem->id()] = final_evals[i_to].size();
463 for (
unsigned int qp = 0; qp < qrule.n_points(); qp++)
464 final_evals[i_to].push_back(evals[qp]);
475 for (
unsigned int i_to = 0; i_to <
_to_problems.size(); i_to++)
477 _to_es[i_to]->parameters.set<std::vector<Real> *>(
"final_evals") = &final_evals[i_to];
478 _to_es[i_to]->parameters.set<std::map<dof_id_type, unsigned int> *>(
"element_map") =
479 &trimmed_element_maps[i_to];
481 _to_es[i_to]->parameters.set<std::vector<Real> *>(
"final_evals") = NULL;
482 _to_es[i_to]->parameters.set<std::map<dof_id_type, unsigned int> *>(
"element_map") = NULL;
495 EquationSystems & proj_es = to_problem.
es();
496 LinearImplicitSystem & ls = *
_proj_sys[i_to];
502 Real tol = proj_es.parameters.get<Real>(
"linear solver tolerance");
503 proj_es.parameters.set<Real>(
"linear solver tolerance") = 1e-10;
506 proj_es.parameters.set<Real>(
"linear solver tolerance") = tol;
509 MeshBase & to_mesh = proj_es.get_mesh();
514 NumericVector<Number> * to_solution = to_sys.
solution.get();
516 for (
const auto & node : to_mesh.local_node_ptr_range())
518 for (
unsigned int comp = 0; comp < node->n_comp(to_sys.number(), to_var.
number()); comp++)
520 const dof_id_type proj_index = node->dof_number(ls.number(),
_proj_var_num, comp);
521 const dof_id_type to_index = node->dof_number(to_sys.number(), to_var.
number(), comp);
522 to_solution->set(to_index, (*ls.solution)(proj_index));
525 for (
const auto & elem : to_mesh.active_local_element_ptr_range())
526 for (
unsigned int comp = 0; comp < elem->n_comp(to_sys.number(), to_var.
number()); comp++)
528 const dof_id_type proj_index = elem->dof_number(ls.number(),
_proj_var_num, comp);
529 const dof_id_type to_index = elem->dof_number(to_sys.number(), to_var.
number(), comp);
530 to_solution->set(to_index, (*ls.solution)(proj_index));
533 to_solution->close();