Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit edbdf6b

Browse files
committed
Must use full (ghosted) solution for reading trace solution
1 parent 6b2bc94 commit edbdf6b

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

src/numerics/static_condensation.C

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,36 @@ StaticCondensation::backwards_substitution(const NumericVector<Number> & full_rh
380380
NumericVector<Number> & full_sol)
381381
{
382382
std::vector<dof_id_type> elem_dofs; // only used to satisfy API
383-
std::vector<dof_id_type> elem_interior_dofs;
383+
std::vector<dof_id_type> elem_interior_dofs, elem_trace_dofs;
384384
std::vector<Number> elem_interior_rhs_vec, elem_trace_sol_vec;
385385
EigenVector elem_interior_rhs, elem_trace_sol, elem_interior_sol;
386386

387+
auto scalar_dofs_functor =
388+
[&elem_interior_dofs, &elem_trace_dofs](const Elem & elem,
389+
std::vector<dof_id_type> & dof_indices,
390+
const std::vector<dof_id_type> & scalar_dof_indices)
391+
{
392+
computeElemInteriorDofsScalar(elem_interior_dofs)(elem, dof_indices, scalar_dof_indices);
393+
elem_trace_dofs.insert(
394+
elem_trace_dofs.end(), scalar_dof_indices.begin(), scalar_dof_indices.end());
395+
};
396+
397+
auto field_dofs_functor =
398+
[&elem_interior_dofs, &elem_trace_dofs](const Elem & elem,
399+
const unsigned int node_num,
400+
std::vector<dof_id_type> & dof_indices,
401+
const dof_id_type field_dof)
402+
{
403+
computeElemInteriorDofsField(elem_interior_dofs)(elem, node_num, dof_indices, field_dof);
404+
405+
if (node_num != invalid_uint && !elem.is_internal(node_num))
406+
elem_trace_dofs.push_back(field_dof);
407+
};
408+
387409
for (auto elem : _mesh.active_local_element_ptr_range())
388410
{
389411
elem_interior_dofs.clear();
412+
elem_trace_dofs.clear();
390413
auto & local_data = _elem_to_local_data[elem->id()];
391414

392415
const auto sub_id = elem->subdomain_id();
@@ -397,17 +420,12 @@ StaticCondensation::backwards_substitution(const NumericVector<Number> & full_rh
397420
continue;
398421

399422
for (const auto v : make_range(var_group.n_variables()))
400-
_dof_map.dof_indices(elem,
401-
elem_dofs,
402-
v,
403-
computeElemInteriorDofsScalar(elem_interior_dofs),
404-
computeElemInteriorDofsField(elem_interior_dofs),
405-
elem->p_level());
423+
_dof_map.dof_indices(
424+
elem, elem_dofs, v, scalar_dofs_functor, field_dofs_functor, elem->p_level());
406425
}
407426

408427
set_local_vectors(full_rhs, elem_interior_dofs, elem_interior_rhs_vec, elem_interior_rhs);
409-
set_local_vectors(
410-
*_reduced_sol, local_data.reduced_space_indices, elem_trace_sol_vec, elem_trace_sol);
428+
set_local_vectors(full_sol, elem_trace_dofs, elem_trace_sol_vec, elem_trace_sol);
411429

412430
elem_interior_sol =
413431
local_data.AiiFactor.solve(elem_interior_rhs - local_data.Aib * elem_trace_sol);
@@ -424,7 +442,9 @@ StaticCondensation::solve(const NumericVector<Number> & full_rhs, NumericVector<
424442
forward_elimination(full_rhs);
425443
_reduced_sol = full_sol.get_subvector(_local_trace_dofs);
426444
_reduced_solver->solve(*_reduced_sys_mat, *_reduced_sol, *_reduced_rhs, 1e-5, 300);
427-
backwards_substitution(full_rhs, full_sol);
445+
// Must restore to the full solution because during backwards substitution we will need to be able
446+
// to read ghosted dofs and we don't support ghosting of subvectors
428447
full_sol.restore_subvector(std::move(_reduced_sol), _local_trace_dofs);
448+
backwards_substitution(full_rhs, full_sol);
429449
}
430450
}

0 commit comments

Comments
 (0)