25 #include "libmesh/libmesh_config.h" 27 #ifdef LIBMESH_HAVE_METAPHYSICL 31 #include "libmesh/libmesh_common.h" 32 #include "libmesh/compare_types.h" 36 #include "metaphysicl/dynamicsparsenumberarray_decl.h" 38 using MetaPhysicL::DynamicSparseNumberArray;
44 template <
typename T,
typename IndexType>
52 template <
typename T,
typename IndexType,
typename T2>
56 MetaPhysicL::DynamicSparseNumberArray
62 template <
typename T,
typename IndexType>
64 typedef std::vector<std::pair<IndexType,T>>
type;
67 template <
typename T,
typename IndexType>
68 const std::vector<std::pair<IndexType,T>>
71 const std::size_t in_size = in.size();
72 std::vector<std::pair<IndexType,T>> returnval(in_size);
74 for (std::size_t i=0; i != in_size; ++i)
76 returnval[i].first = in.raw_index(i);
77 returnval[i].second = in.raw_at(i);
82 template <
typename SendT,
typename T,
typename IndexType>
84 MetaPhysicL::DynamicSparseNumberArray<T,IndexType> & converted)
86 const std::size_t received_size = received.size();
87 converted.resize(received_size);
88 for (std::size_t i=0; i != received_size; ++i)
90 converted.raw_index(i) = received[i].first;
91 converted.raw_at(i) = received[i].second;
100 #include "libmesh/boundary_info.h" 101 #include "libmesh/dense_matrix.h" 102 #include "libmesh/dense_vector.h" 103 #include "libmesh/dof_map.h" 104 #include "libmesh/elem.h" 105 #include "libmesh/fe_base.h" 106 #include "libmesh/fe_interface.h" 107 #include "libmesh/generic_projector.h" 108 #include "libmesh/int_range.h" 109 #include "libmesh/libmesh_logging.h" 110 #include "libmesh/linear_solver.h" 111 #include "libmesh/mesh_base.h" 112 #include "libmesh/numeric_vector.h" 113 #include "libmesh/quadrature.h" 114 #include "libmesh/sparse_matrix.h" 115 #include "libmesh/system.h" 116 #include "libmesh/threads.h" 117 #include "libmesh/wrapped_function.h" 118 #include "libmesh/wrapped_functor.h" 119 #include "libmesh/fe_interface.h" 123 #ifdef LIBMESH_HAVE_METAPHYSICL 125 #include "metaphysicl/dynamicsparsenumberarray.h" 128 #include "libmesh/dense_matrix_impl.h" 131 typedef DynamicSparseNumberArray<Real, dof_id_type>
DSNAN;
133 template LIBMESH_EXPORT
void 136 template LIBMESH_EXPORT
void 150 #ifdef LIBMESH_ENABLE_AMR 174 system(other.system),
184 #endif // LIBMESH_ENABLE_AMR 195 const std::set<boundary_id_type> &
b;
198 std::unique_ptr<FunctionBase<Number>>
f;
199 std::unique_ptr<FunctionBase<Gradient>>
g;
205 const std::vector<unsigned int> & variables_in,
212 variables(variables_in),
216 parameters(parameters_in),
227 variables(in.variables),
231 parameters(in.parameters),
232 new_vector(in.new_vector)
248 int is_adjoint)
const 252 std::unique_ptr<NumericVector<Number>>
253 old_vector (vector.
clone());
256 this->project_vector (*old_vector, vector, is_adjoint);
267 int is_adjoint)
const 269 LOG_SCOPE (
"project_vector(old,new)",
"System");
279 #ifdef LIBMESH_ENABLE_AMR 283 std::unique_ptr<NumericVector<Number>> new_vector_built;
285 std::unique_ptr<NumericVector<Number>> local_old_vector_built;
289 (this->get_mesh().active_local_elements_begin(),
290 this->get_mesh().active_local_elements_end());
297 new_vector_ptr = &new_v;
298 old_vector_ptr = &old_v;
313 new_v.
init (this->n_dofs(), this->n_local_dofs(),
false,
PARALLEL);
316 new_vector_ptr = new_vector_built.
get();
317 local_old_vector = local_old_vector_built.
get();
318 new_vector_ptr->
init(this->n_dofs(), this->n_local_dofs(),
319 this->get_dof_map().get_send_list(),
false,
324 local_old_vector->
close();
325 old_vector_ptr = local_old_vector;
337 new_v.
init (this->n_dofs(), this->n_local_dofs(),
338 this->get_dof_map().get_send_list(),
false,
GHOSTED);
341 new_vector_ptr = &new_v;
342 local_old_vector = local_old_vector_built.
get();
346 local_old_vector->
close();
347 old_vector_ptr = local_old_vector;
350 libmesh_error_msg(
"ERROR: Unknown old_v.type() == " << old_v.
type());
361 const unsigned int n_variables = this->
n_vars();
365 std::vector<unsigned int> vars(n_variables);
367 std::vector<unsigned int> regular_vars, vector_vars;
368 for (
auto var : vars)
370 if (FEInterface::field_type(this->variable_type(var)) ==
TYPE_SCALAR)
371 regular_vars.push_back(var);
373 vector_vars.push_back(var);
378 if (!regular_vars.empty())
387 f(*
this, old_vector, ®ular_vars);
389 g(*
this, old_vector, ®ular_vars);
391 FEMProjector projector(*
this, f, &g, setter, regular_vars);
392 projector.project(active_local_elem_range);
395 if (!vector_vars.empty())
405 FEMVectorProjector vector_projector(*
this, f_vector, &g_vector, setter, vector_vars);
406 vector_projector.project(active_local_elem_range);
412 if (this->processor_id() == (this->n_processors()-1))
414 const DofMap & dof_map = this->get_dof_map();
416 if (this->variable(var).type().family ==
SCALAR)
419 std::vector<dof_id_type> new_SCALAR_indices, old_SCALAR_indices;
423 new_vector.
set(new_SCALAR_indices[i], old_vector(old_SCALAR_indices[i]));
438 dist_v->init(this->n_dofs(), this->n_local_dofs(),
false,
PARALLEL);
442 if (new_vector(i) != 0.0)
443 dist_v->set(i, new_vector(i));
447 dist_v->localize (new_v, this->get_dof_map().get_send_list());
463 if(this->project_with_constraints)
465 if (is_adjoint == -1)
467 this->get_dof_map().enforce_constraints_exactly(*
this, &new_v);
469 else if (is_adjoint >= 0)
471 this->get_dof_map().enforce_adjoint_constraints_exactly(new_v,
482 #endif // #ifdef LIBMESH_ENABLE_AMR 486 #ifdef LIBMESH_ENABLE_AMR 487 #ifdef LIBMESH_HAVE_METAPHYSICL 489 template <
typename Output>
493 typedef DynamicSparseNumberArray<Output, dof_id_type>
type;
496 template <
typename InnerOutput>
512 template <
typename Output,
525 const std::vector<unsigned int> * vars) :
528 this->old_context.set_algebraic_type(FEMContext::OLD_DOFS_ONLY);
532 OldSolutionBase<Output, point_output>(in.sys, in.old_context.active_vars())
534 this->old_context.set_algebraic_type(FEMContext::OLD_DOFS_ONLY);
539 unsigned int elem_dim,
541 bool extra_hanging_dofs,
548 bool skip_context_check);
554 std::vector<DSNA> & derivs)
556 LOG_SCOPE (
"eval_mixed_derivatives",
"OldSolutionCoefs");
559 libmesh_assert_less(c.get_elem().get_node_index(&n),
560 c.get_elem().n_vertices());
563 libmesh_assert_less(i, this->component_to_var.size());
564 unsigned int var = this->component_to_var[i];
567 const unsigned int n_mixed = (
dim-1) * (
dim-1);
568 derivs.resize(n_mixed);
573 if (old_dof_object &&
574 old_dof_object->
n_vars(this->sys.number()) &&
575 old_dof_object->
n_comp(this->sys.number(), var))
579 std::vector<dof_id_type> old_ids(n_mixed);
580 std::iota(old_ids.begin(), old_ids.end(), first_old_id);
584 derivs[d_i].resize(1);
585 derivs[d_i].raw_at(0) = 1;
586 derivs[d_i].raw_index(0) = old_ids[d_i];
591 std::fill(derivs.begin(), derivs.end(), 0);
597 unsigned int node_num,
598 unsigned int var_num,
599 std::vector<dof_id_type> & indices,
600 std::vector<DSNA> & values)
602 LOG_SCOPE (
"eval_old_dofs(node)",
"OldSolutionCoefs");
608 this->sys.get_dof_map().dof_indices(elem, node_num, indices, var_num);
610 std::vector<dof_id_type> old_indices;
612 this->sys.get_dof_map().old_dof_indices(elem, node_num, old_indices, var_num);
614 libmesh_assert_equal_to (old_indices.size(), indices.size());
616 values.resize(old_indices.size());
621 values[i].raw_at(0) = 1;
622 values[i].raw_index(0) = old_indices[i];
629 unsigned int sys_num,
630 unsigned int var_num,
631 std::vector<dof_id_type> & indices,
632 std::vector<DSNA> & values)
634 LOG_SCOPE (
"eval_old_dofs(elem)",
"OldSolutionCoefs");
638 const Elem & old_elem =
643 const unsigned int nc =
644 FEInterface::n_dofs_per_elem(fe_type, &elem);
646 std::vector<dof_id_type> old_dof_indices(nc);
656 const auto [vg, vig] =
659 const unsigned int n_comp = elem.
n_comp_group(sys_num,vg);
660 libmesh_assert_greater(elem.
n_systems(), sys_num);
661 libmesh_assert_greater_equal(n_comp, nc);
663 for (
unsigned int i=0; i<nc; i++)
666 old_dof_object.
dof_number(sys_num, vg, vig, i, n_comp);
669 libmesh_assert_not_equal_to (d_old, DofObject::invalid_id);
670 libmesh_assert_not_equal_to (d_new, DofObject::invalid_id);
672 old_dof_indices[i] = d_old;
677 values.resize(old_dof_indices.size());
682 values[i].raw_at(0) = 1;
683 values[i].raw_index(0) = old_dof_indices[i];
692 DynamicSparseNumberArray<Real, dof_id_type>
693 OldSolutionCoefs<Real, &FEMContext::point_value>::
698 bool skip_context_check)
700 LOG_SCOPE (
"eval_at_point()",
"OldSolutionCoefs");
702 if (!skip_context_check)
703 if (!this->check_old_context(c, p))
708 this->old_context.get_element_fe<
Real>
709 (i, fe, this->old_context.get_elem_dim());
713 this->old_context.build_new_fe(fe, p);
716 const std::vector<std::vector<Real> > & phi = fe_new->
get_phi();
717 const std::vector<dof_id_type> & dof_indices =
718 this->old_context.get_dof_indices(i);
720 const std::size_t n_dofs = phi.size();
721 libmesh_assert_equal_to(n_dofs, dof_indices.size());
723 DynamicSparseNumberArray<Real, dof_id_type> returnval;
724 returnval.resize(n_dofs);
728 returnval.raw_at(j) = phi[j][0];
729 returnval.raw_index(j) = dof_indices[j];
745 bool skip_context_check)
747 LOG_SCOPE (
"eval_at_point()",
"OldSolutionCoefs");
749 if (!skip_context_check)
750 if (!this->check_old_context(c, p))
755 this->old_context.get_element_fe<
Real>
756 (i, fe, this->old_context.get_elem_dim());
760 this->old_context.build_new_fe(fe, p);
763 const std::vector<std::vector<RealGradient> > & dphi = fe_new->
get_dphi();
764 const std::vector<dof_id_type> & dof_indices =
765 this->old_context.get_dof_indices(i);
767 const std::size_t n_dofs = dphi.size();
768 libmesh_assert_equal_to(n_dofs, dof_indices.size());
772 for (
unsigned int d = 0; d != LIBMESH_DIM; ++d)
773 returnval(d).resize(n_dofs);
776 for (
int d = 0; d != LIBMESH_DIM; ++d)
778 returnval(d).raw_at(j) = dphi[j][0](d);
779 returnval(d).raw_index(j) = dof_indices[j];
788 DynamicSparseNumberArray<Real, dof_id_type>
794 bool extra_hanging_dofs,
797 LOG_SCOPE (
"Real eval_at_node()",
"OldSolutionCoefs");
812 if (old_dof_object &&
813 (!extra_hanging_dofs ||
814 flag == Elem::JUST_COARSENED ||
815 flag == Elem::DO_NOTHING) &&
816 old_dof_object->
n_vars(sys.number()) &&
817 old_dof_object->
n_comp(sys.number(), i))
819 DynamicSparseNumberArray<Real, dof_id_type> returnval;
821 old_dof_object->
dof_number(sys.number(), i, 0);
823 returnval.raw_at(0) = 1;
824 returnval.raw_index(0) = old_id;
828 return this->eval_at_point(c, i, n, 0,
false);
839 unsigned int elem_dim,
841 bool extra_hanging_dofs,
844 LOG_SCOPE (
"RealGradient eval_at_node()",
"OldSolutionCoefs");
859 if (old_dof_object &&
860 (!extra_hanging_dofs ||
861 flag == Elem::JUST_COARSENED ||
862 flag == Elem::DO_NOTHING) &&
863 old_dof_object->
n_vars(sys.number()) &&
864 old_dof_object->
n_comp(sys.number(), i))
867 for (
unsigned int d = 0; d != elem_dim; ++d)
870 old_dof_object->
dof_number(sys.number(), i, d+1);
873 g(d).raw_index(0) = old_id;
878 return this->eval_at_point(c, i, n, 0,
false);
891 template <
typename ValIn,
typename ValOut>
901 target_matrix(target_mat) {}
904 const DynamicSparseNumberArray<ValIn, dof_id_type> & val)
910 const std::size_t dnsa_size = val.size();
911 for (
unsigned int j = 0; j != dnsa_size; ++j)
914 const ValIn dof_val = val.raw_at(j);
915 target_matrix.
set(
id, dof_j, dof_val);
921 void insert(
const std::vector<dof_id_type> & dof_indices,
922 const std::vector<DynamicSparseNumberArray<ValIn, dof_id_type> > & Ue)
928 unsigned int size = Ue.size();
930 libmesh_assert_equal_to(size, dof_indices.size());
936 for (
unsigned int i = 0; i != size; ++i)
939 if ((dof_i >= begin_dof) && (dof_i < end_dof))
941 const DynamicSparseNumberArray<ValIn,dof_id_type> & dnsa = Ue[i];
942 const std::size_t dnsa_size = dnsa.size();
943 for (
unsigned int j = 0; j != dnsa_size; ++j)
946 const ValIn dof_val = dnsa.raw_at(j);
947 target_matrix.
set(dof_i, dof_j, dof_val);
963 LOG_SCOPE (
"projection_matrix()",
"System");
965 const unsigned int n_variables = this->
n_vars();
970 (this->get_mesh().active_local_elements_begin(),
971 this->get_mesh().active_local_elements_end());
973 std::vector<unsigned int> vars(n_variables);
982 OldSolutionGradientCoefs,
983 DynamicSparseNumberArray<Real,dof_id_type>,
986 OldSolutionValueCoefs f(*
this, &vars);
987 OldSolutionGradientCoefs g(*
this, &vars);
990 ProjMatFiller mat_filler(*
this, f, &g, setter, vars);
991 mat_filler.project(active_local_elem_range);
996 if (this->processor_id() == (this->n_processors()-1))
998 const DofMap & dof_map = this->get_dof_map();
1000 if (this->variable(var).type().family ==
SCALAR)
1003 std::vector<dof_id_type> new_SCALAR_indices, old_SCALAR_indices;
1006 const unsigned int new_n_dofs =
1007 cast_int<unsigned int>(new_SCALAR_indices.size());
1009 for (
unsigned int i=0; i<new_n_dofs; i++)
1011 proj_mat.
set( new_SCALAR_indices[i],
1012 old_SCALAR_indices[i], 1);
1018 #endif // LIBMESH_HAVE_METAPHYSICL 1019 #endif // LIBMESH_ENABLE_AMR 1027 void System::project_solution (ValueFunctionPointer
fptr,
1028 GradientFunctionPointer
gptr,
1033 this->project_solution(&f, &g);
1044 this->project_vector(*solution, f, g);
1046 solution->localize(*current_local_solution, _dof_map->get_send_list());
1057 this->project_vector(*solution, f, g);
1059 solution->localize(*current_local_solution, _dof_map->get_send_list());
1067 void System::project_vector (ValueFunctionPointer
fptr,
1068 GradientFunctionPointer
gptr,
1071 int is_adjoint)
const 1075 this->project_vector(new_vector, &f, &g, is_adjoint);
1085 int is_adjoint)
const 1087 LOG_SCOPE (
"project_vector(FunctionBase)",
"System");
1097 this->project_vector(new_vector, &f_fem, &g_fem, is_adjoint);
1100 this->project_vector(new_vector, &f_fem,
nullptr, is_adjoint);
1111 int is_adjoint)
const 1113 LOG_SCOPE (
"project_fem_vector()",
"System");
1118 (this->get_mesh().active_local_elements_begin(),
1119 this->get_mesh().active_local_elements_end() );
1123 const unsigned int n_variables = this->
n_vars();
1125 std::vector<unsigned int> vars(n_variables);
1139 FEMProjector projector(*
this, fw, &gw, setter, vars);
1140 projector.project(active_local_range);
1144 FEMProjector projector(*
this, fw,
nullptr, setter, vars);
1145 projector.project(active_local_range);
1151 if (this->processor_id() == (this->n_processors()-1))
1156 const DofMap & dof_map = this->get_dof_map();
1158 if (this->variable(var).type().family ==
SCALAR)
1163 context.
pre_fe_reinit(*
this, *(this->get_mesh().active_local_elements_begin()));
1165 std::vector<dof_id_type> SCALAR_indices;
1167 const unsigned int n_SCALAR_dofs =
1168 cast_int<unsigned int>(SCALAR_indices.size());
1170 for (
unsigned int i=0; i<n_SCALAR_dofs; i++)
1172 const dof_id_type global_index = SCALAR_indices[i];
1173 const unsigned int component_index =
1174 this->variable_scalar_number(var,i);
1176 new_vector.
set(global_index, f->
component(context, component_index,
Point(), this->time));
1185 std::vector<const Variable *> rational_vars;
1186 for (
auto varnum : vars)
1188 const Variable & var = this->get_dof_map().variable(varnum);
1190 rational_vars.push_back(&var);
1195 bool using_spline_bases =
false;
1196 if (!rational_vars.empty())
1200 for (
auto & elem : active_local_range)
1202 for (
auto rational_var : rational_vars)
1203 if (rational_var->active_on_subdomain(elem->subdomain_id()))
1205 using_spline_bases =
true;
1206 goto checked_on_splines;
1214 this->comm().max(using_spline_bases);
1216 if (using_spline_bases)
1217 this->solve_for_unconstrained_dofs(new_vector, is_adjoint);
1219 #ifdef LIBMESH_ENABLE_CONSTRAINTS 1220 if (is_adjoint == -1)
1221 this->get_dof_map().enforce_constraints_exactly(*
this, &new_vector);
1222 else if (is_adjoint >= 0)
1223 this->get_dof_map().enforce_adjoint_constraints_exactly(new_vector,
1236 void System::boundary_project_solution (
const std::set<boundary_id_type> & b,
1237 const std::vector<unsigned int> & variables,
1238 ValueFunctionPointer
fptr,
1239 GradientFunctionPointer
gptr,
1244 this->boundary_project_solution(b, variables, &f, &g);
1253 void System::boundary_project_solution (
const std::set<boundary_id_type> & b,
1254 const std::vector<unsigned int> & variables,
1258 this->boundary_project_vector(b, variables, *solution, f, g);
1260 solution->localize(*current_local_solution);
1271 void System::boundary_project_vector (
const std::set<boundary_id_type> & b,
1272 const std::vector<unsigned int> & variables,
1273 ValueFunctionPointer
fptr,
1274 GradientFunctionPointer
gptr,
1277 int is_adjoint)
const 1281 this->boundary_project_vector(b, variables, new_vector, &f, &g,
1289 void System::boundary_project_vector (
const std::set<boundary_id_type> & b,
1290 const std::vector<unsigned int> & variables,
1294 int is_adjoint)
const 1296 LOG_SCOPE (
"boundary_project_vector()",
"System");
1300 this->get_mesh().active_local_elements_end() ),
1302 this->get_equation_systems().parameters,
1311 #ifdef LIBMESH_ENABLE_CONSTRAINTS 1312 if (is_adjoint == -1)
1313 this->get_dof_map().enforce_constraints_exactly(*
this, &new_vector);
1314 else if (is_adjoint >= 0)
1315 this->get_dof_map().enforce_adjoint_constraints_exactly(new_vector,
1324 #ifdef LIBMESH_ENABLE_AMR 1325 void BuildProjectionList::unique()
1329 std::sort(this->send_list.begin(),
1330 this->send_list.end());
1333 std::vector<dof_id_type>::iterator new_end =
1334 std::unique (this->send_list.begin(),
1335 this->send_list.end());
1339 std::vector<dof_id_type>
1340 (this->send_list.begin(), new_end).swap (this->send_list);
1348 const DofMap & dof_map = system.get_dof_map();
1355 std::vector<dof_id_type> di;
1358 for (
const auto & elem : range)
1374 if (!old_dof_object &&
1375 elem->refinement_flag() != Elem::JUST_REFINED &&
1376 elem->refinement_flag() != Elem::JUST_COARSENED)
1381 if (elem->refinement_flag() == Elem::JUST_REFINED)
1391 for (
auto & node : elem->node_ref_range())
1397 const unsigned int sysnum = system.number();
1398 const unsigned int nvg = old_dofs->
n_var_groups(sysnum);
1400 for (
unsigned int vg=0; vg != nvg; ++vg)
1402 const unsigned int nvig =
1403 old_dofs->
n_vars(sysnum, vg);
1404 for (
unsigned int vig=0; vig != nvig; ++vig)
1406 const unsigned int n_comp =
1408 for (
unsigned int c=0; c != n_comp; ++c)
1418 old_id == DofObject::invalid_id);
1419 di.push_back(old_id);
1426 std::sort(di.begin(), di.end());
1427 std::vector<dof_id_type>::iterator new_end =
1428 std::unique(di.begin(), di.end());
1429 std::vector<dof_id_type>(di.begin(), new_end).swap(di);
1431 else if (elem->refinement_flag() == Elem::JUST_COARSENED)
1433 std::vector<dof_id_type> di_child;
1435 for (
auto & child : elem->child_ref_range())
1438 di.insert(di.end(), di_child.begin(), di_child.end());
1444 for (
auto di_i : di)
1450 if (di_i == DofObject::invalid_id)
1453 libmesh_assert_less(di_i, dof_map.
n_old_dofs());
1454 if (di_i < first_old_dof || di_i >= end_old_dof)
1455 this->send_list.push_back(di_i);
1465 this->send_list.insert(this->send_list.end(),
1469 #endif // LIBMESH_ENABLE_AMR 1486 const unsigned int dim = system.get_mesh().mesh_dimension();
1489 const DofMap & dof_map = system.get_dof_map();
1493 system.get_mesh().get_boundary_info();
1508 const unsigned int var = variables[v];
1517 const unsigned int var_component =
1518 system.variable_scalar_number(var, 0);
1521 std::unique_ptr<FEBase> fe (FEBase::build(
dim, fe_type));
1529 const std::vector<std::vector<Real>> & phi = fe->get_phi();
1533 const std::vector<std::vector<RealGradient>> * dphi =
nullptr;
1542 const std::vector<std::vector<RealGradient>> &
1543 ref_dphi = fe->get_dphi();
1548 const std::vector<Real> & JxW =
1552 const std::vector<Point> & xyz_values =
1556 std::vector<dof_id_type> dof_indices;
1558 std::vector<unsigned int> side_dofs;
1561 std::vector<boundary_id_type> bc_ids;
1564 for (
const auto & elem : range)
1571 const unsigned short n_nodes = elem->n_nodes();
1572 const unsigned short n_edges = elem->n_edges();
1573 const unsigned short n_sides = elem->n_sides();
1577 std::vector<bool> is_boundary_node(
n_nodes,
false),
1578 is_boundary_edge(n_edges,
false),
1579 is_boundary_side(n_sides,
false);
1582 std::vector<bool> is_boundary_nodeset(
n_nodes,
false);
1584 for (
unsigned char s=0; s != n_sides; ++s)
1588 bool do_this_side =
false;
1589 for (
const auto & bc_id : bc_ids)
1592 do_this_side =
true;
1598 is_boundary_side[s] =
true;
1601 for (
unsigned int n=0; n !=
n_nodes; ++n)
1602 if (elem->is_node_on_side(n,s))
1603 is_boundary_node[n] =
true;
1604 for (
unsigned int e=0; e != n_edges; ++e)
1605 if (elem->is_edge_on_side(e,s))
1606 is_boundary_edge[e] =
true;
1611 for (
unsigned int n=0; n !=
n_nodes; ++n)
1613 boundary_info.
boundary_ids (elem->node_ptr(n), bc_ids);
1615 for (
const auto & bc_id : bc_ids)
1618 is_boundary_node[n] =
true;
1619 is_boundary_nodeset[n] =
true;
1625 for (
unsigned short e=0; e != n_edges; ++e)
1629 for (
const auto & bc_id : bc_ids)
1631 is_boundary_edge[e] =
true;
1639 const unsigned int n_dofs =
1640 cast_int<unsigned int>(dof_indices.size());
1643 std::vector<char> dof_is_fixed(n_dofs,
false);
1644 std::vector<int> free_dof(n_dofs, 0);
1656 unsigned int current_dof = 0;
1657 for (
unsigned short n = 0; n !=
n_nodes; ++n)
1663 const unsigned int nc =
1664 FEInterface::n_dofs_at_node (fe_type, elem, n);
1666 if ((!elem->is_vertex(n) || !is_boundary_node[n]) &&
1667 !is_boundary_nodeset[n])
1674 libmesh_assert_equal_to (nc, 0);
1680 libmesh_assert_equal_to (nc, 1);
1681 Ue(current_dof) = f->component(var_component,
1684 dof_is_fixed[current_dof] =
true;
1690 Ue(current_dof) = f->component(var_component,
1693 dof_is_fixed[current_dof] =
true;
1695 Gradient grad = g->component(var_component,
1699 Ue(current_dof) = grad(0);
1700 dof_is_fixed[current_dof] =
true;
1706 Point nxminus = elem->point(n),
1707 nxplus = elem->point(n);
1710 Gradient gxminus = g->component(var_component,
1713 Gradient gxplus = g->component(var_component,
1717 Ue(current_dof) = grad(1);
1718 dof_is_fixed[current_dof] =
true;
1721 Ue(current_dof) = (gxplus(1) - gxminus(1))
1723 dof_is_fixed[current_dof] =
true;
1730 Ue(current_dof) = grad(2);
1731 dof_is_fixed[current_dof] =
true;
1734 Ue(current_dof) = (gxplus(2) - gxminus(2))
1736 dof_is_fixed[current_dof] =
true;
1739 Point nyminus = elem->point(n),
1740 nyplus = elem->point(n);
1743 Gradient gyminus = g->component(var_component,
1746 Gradient gyplus = g->component(var_component,
1750 Ue(current_dof) = (gyplus(2) - gyminus(2))
1752 dof_is_fixed[current_dof] =
true;
1755 Point nxmym = elem->point(n),
1756 nxmyp = elem->point(n),
1757 nxpym = elem->point(n),
1758 nxpyp = elem->point(n);
1767 Gradient gxmym = g->component(var_component,
1770 Gradient gxmyp = g->component(var_component,
1773 Gradient gxpym = g->component(var_component,
1776 Gradient gxpyp = g->component(var_component,
1779 Number gxzplus = (gxpyp(2) - gxmyp(2))
1781 Number gxzminus = (gxpym(2) - gxmym(2))
1784 Ue(current_dof) = (gxzplus - gxzminus)
1786 dof_is_fixed[current_dof] =
true;
1789 #endif // LIBMESH_DIM > 2 1791 #endif // LIBMESH_DIM > 1 1796 else if (cont ==
C_ONE)
1798 libmesh_assert_equal_to (nc, 1 +
dim);
1799 Ue(current_dof) = f->component(var_component,
1802 dof_is_fixed[current_dof] =
true;
1804 Gradient grad = g->component(var_component,
1807 for (
unsigned int i=0; i!=
dim; ++i)
1809 Ue(current_dof) = grad(i);
1810 dof_is_fixed[current_dof] =
true;
1815 libmesh_error_msg(
"Unknown continuity " << cont);
1820 for (
unsigned short e = 0; e != n_edges; ++e)
1822 if (!is_boundary_edge[e])
1825 FEInterface::dofs_on_edge(elem,
dim, fe_type, e,
1828 const unsigned int n_side_dofs =
1829 cast_int<unsigned int>(side_dofs.size());
1833 unsigned int free_dofs = 0;
1835 if (!dof_is_fixed[side_dofs[i]])
1836 free_dof[free_dofs++] = i;
1848 fe->attach_quadrature_rule (qedgerule.get());
1849 fe->edge_reinit (elem, e);
1850 const unsigned int n_qp = qedgerule->n_points();
1853 for (
unsigned int qp=0; qp<n_qp; qp++)
1856 Number fineval = f->component(var_component,
1862 finegrad = g->component(var_component,
1867 for (
unsigned int sidei=0, freei=0;
1868 sidei != n_side_dofs; ++sidei)
1870 unsigned int i = side_dofs[sidei];
1872 if (dof_is_fixed[i])
1874 for (
unsigned int sidej=0, freej=0;
1875 sidej != n_side_dofs; ++sidej)
1877 unsigned int j = side_dofs[sidej];
1878 if (dof_is_fixed[j])
1879 Fe(freei) -= phi[i][qp] * phi[j][qp] *
1882 Ke(freei,freej) += phi[i][qp] *
1883 phi[j][qp] * JxW[qp];
1886 if (dof_is_fixed[j])
1887 Fe(freei) -= ((*dphi)[i][qp] *
1891 Ke(freei,freej) += ((*dphi)[i][qp] *
1895 if (!dof_is_fixed[j])
1898 Fe(freei) += phi[i][qp] * fineval * JxW[qp];
1900 Fe(freei) += (finegrad * (*dphi)[i][qp]) *
1909 for (
unsigned int i=0; i != free_dofs; ++i)
1911 Number & ui = Ue(side_dofs[free_dof[i]]);
1915 dof_is_fixed[side_dofs[free_dof[i]]] =
true;
1921 for (
unsigned short s = 0; s != n_sides; ++s)
1923 if (!is_boundary_side[s])
1926 FEInterface::dofs_on_side(elem,
dim, fe_type, s,
1931 unsigned int free_dofs = 0;
1933 if (!dof_is_fixed[side_dofs[i]])
1934 free_dof[free_dofs++] = i;
1946 fe->attach_quadrature_rule (qsiderule.get());
1947 fe->reinit (elem, s);
1948 const unsigned int n_qp = qsiderule->n_points();
1950 const unsigned int n_side_dofs =
1951 cast_int<unsigned int>(side_dofs.size());
1954 for (
unsigned int qp=0; qp<n_qp; qp++)
1957 Number fineval = f->component(var_component,
1963 finegrad = g->component(var_component,
1968 for (
unsigned int sidei=0, freei=0;
1969 sidei != n_side_dofs; ++sidei)
1971 unsigned int i = side_dofs[sidei];
1973 if (dof_is_fixed[i])
1975 for (
unsigned int sidej=0, freej=0;
1976 sidej != n_side_dofs; ++sidej)
1978 unsigned int j = side_dofs[sidej];
1979 if (dof_is_fixed[j])
1980 Fe(freei) -= phi[i][qp] * phi[j][qp] *
1983 Ke(freei,freej) += phi[i][qp] *
1984 phi[j][qp] * JxW[qp];
1987 if (dof_is_fixed[j])
1988 Fe(freei) -= ((*dphi)[i][qp] *
1992 Ke(freei,freej) += ((*dphi)[i][qp] *
1996 if (!dof_is_fixed[j])
1999 Fe(freei) += (fineval * phi[i][qp]) * JxW[qp];
2001 Fe(freei) += (finegrad * (*dphi)[i][qp]) *
2010 for (
unsigned int i=0; i != free_dofs; ++i)
2012 Number & ui = Ue(side_dofs[free_dof[i]]);
2016 dof_is_fixed[side_dofs[free_dof[i]]] =
true;
2021 first = new_vector.first_local_index(),
2022 last = new_vector.last_local_index();
2028 for (
unsigned int i = 0; i < n_dofs; i++)
2029 if (dof_is_fixed[i] &&
2030 (dof_indices[i] >= first) &&
2031 (dof_indices[i] < last))
2033 new_vector.set(dof_indices[i], Ue(i));
2042 int is_adjoint)
const 2044 const DofMap & dof_map = this->get_dof_map();
2046 std::unique_ptr<SparseMatrix<Number>> mat =
2049 std::unique_ptr<SparsityPattern::Build> sp;
2055 mat->attach_dof_map(dof_map);
2057 mat->attach_sparsity_pattern(*sp);
2062 libmesh_assert_equal_to(vec.
size(), dof_map.
n_dofs());
2065 std::unique_ptr<NumericVector<Number>> rhs =
2094 std::vector<dof_id_type> dof_indices(1, d);
2096 F(0) = (*this->solution)(d);
2098 (K, F, dof_indices,
false, is_adjoint);
2099 mat->add_matrix(K, dof_indices);
2100 rhs->add_vector(F, dof_indices);
2104 std::unique_ptr<LinearSolver<Number>> linear_solver =
2107 linear_solver->solve(*mat, vec, *rhs,
2108 double(this->get_equation_systems().parameters.get<
Real>(
"linear solver tolerance")),
2109 this->get_equation_systems().parameters.
get<
unsigned int>(
"linear solver maximum iterations"));
The GenericProjector class implements the core of other projection operations, using two input functo...
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
FEFamily family
The type of finite element.
void _cholesky_back_substitute(const DenseVector< T2 > &b, DenseVector< T2 > &x) const
Solves the equation Ax=b for the unknown value x and rhs b based on the Cholesky factorization of A...
RefinementState refinement_flag() const
void eval_old_dofs(const Elem &elem, const FEType &fe_type, unsigned int sys_num, unsigned int var_num, std::vector< dof_id_type > &indices, std::vector< DSNA > &values)
Wrap a libMesh-style function pointer into a FunctionBase object.
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
const Elem * parent() const
dof_id_type n_local_dofs() const
OldSolutionCoefs(const libMesh::System &sys_in, const std::vector< unsigned int > *vars)
A Node is like a Point, but with more information.
virtual void zero() override final
Set every element in the vector to 0.
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
unsigned int n_comp(const unsigned int s, const unsigned int var) const
BuildProjectionList(const System &system_in)
SparseMatrix< ValOut > & target_matrix
This class provides the ability to map between arbitrary, user-defined strings and several data types...
unsigned int n_var_groups(const unsigned int s) const
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
virtual void get(const std::vector< numeric_index_type > &index, T *values) const
Access multiple components at once.
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
virtual void zero() override final
Sets all elements of the matrix to 0 and resets any decomposition flag which may have been previously...
void parallel_for(const Range &range, const Body &body)
Execute the provided function object in parallel on the specified range.
static constexpr Real TOLERANCE
const Elem & get_elem() const
Accessor for current Elem object.
std::unique_ptr< FunctionBase< Number > > f
The OldSolutionBase input functor abstract base class is the root of the OldSolutionValue and OldSolu...
BoundaryProjectSolution(const std::set< boundary_id_type > &b_in, const std::vector< unsigned int > &variables_in, const System &system_in, FunctionBase< Number > *f_in, FunctionBase< Gradient > *g_in, const Parameters ¶meters_in, NumericVector< Number > &new_v_in)
virtual numeric_index_type size() const =0
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.
void resize(const unsigned int n)
Resize the vector.
DynamicSparseNumberArray< Output, dof_id_type > type
This is the base class from which all geometric element types are derived.
This class implements projecting an arbitrary boundary function to the current mesh.
RefinementState
Enumeration of possible element refinement states.
std::unique_ptr< SparsityPattern::Build > build_sparsity(const MeshBase &mesh, bool calculate_constrained=false) const
Builds a sparsity pattern for matrices using the current degree-of-freedom numbering and coupling...
virtual std::unique_ptr< NumericVector< T > > clone() const =0
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The StoredRange class defines a contiguous, divisible set of objects.
void eval_mixed_derivatives(const FEMContext &libmesh_dbg_var(c), unsigned int i, unsigned int dim, const Node &n, std::vector< DSNA > &derivs)
The libMesh namespace provides an interface to certain functionality in the library.
The OldSolutionValue input functor class can be used with GenericProjector to read values from a solu...
dof_id_type n_old_dofs() const
const std::vector< unsigned int > & variables
virtual void init(const numeric_index_type n, const numeric_index_type n_local, const bool fast=false, const ParallelType ptype=AUTOMATIC)=0
Change the dimension of the vector to n.
void iota(ForwardIter first, ForwardIter last, T value)
Utility::iota was created back when std::iota was just an SGI STL extension.
void SCALAR_dof_indices(std::vector< dof_id_type > &di, const unsigned int vn, const bool old_dofs=false) const
Fills the vector di with the global degree of freedom indices corresponding to the SCALAR variable vn...
virtual numeric_index_type row_stop() const =0
virtual void set(const numeric_index_type i, const numeric_index_type j, const T value)=0
Set the element (i,j) to value.
Number fptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
This class provides a wrapper with which to evaluate a (libMesh-style) function pointer in a Function...
BuildProjectionList(BuildProjectionList &other, Threads::split)
const Parameters & parameters
This class handles the numbering of degrees of freedom on a mesh.
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
This base class can be inherited from to provide interfaces to linear solvers from different packages...
const std::vector< std::vector< OutputGradient > > & get_dphi() const
This class builds the send_list of old dof indices whose coefficients are needed to perform a project...
void libmesh_ignore(const Args &...)
const dof_id_type n_nodes
dof_id_type n_dofs() const
This class defines the notion of a variable in the system.
const Variable & variable(const unsigned int c) const
dof_id_type numeric_index_type
The MatrixFillAction output functor class can be used with GenericProjector to write solution transfe...
NumericVector< Number > & new_vector
unsigned int n_vars(const unsigned int s, const unsigned int vg) const
VectorValue< DynamicSparseNumberArray< InnerOutput, dof_id_type > > type
Manages consistently variables, degrees of freedom, and coefficient vectors.
unsigned int n_systems() const
NumberVectorValue Gradient
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
bool is_constrained_dof(const dof_id_type dof) const
This class provides all data required for a physics package (e.g.
void insert(dof_id_type id, const DynamicSparseNumberArray< ValIn, dof_id_type > &val)
dof_id_type end_old_dof(const processor_id_type proc) const
DofObject * get_old_dof_object()
Pointer accessor for previously public old_dof_object.
bool active_on_subdomain(subdomain_id_type sid) const
bool computed_sparsity_already() const
Returns true iff a sparsity pattern has already been computed.
void update_sparsity_pattern(SparseMatrix< Number > &matrix) const
Additional matrices may be be temporarily initialized by this DofMap.
BoundaryProjectSolution(const BoundaryProjectSolution &in)
virtual void close()=0
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
DofObject & get_old_dof_object_ref()
As above, but do not use in situations where the old_dof_object may be nullptr, since this function a...
OldSolutionCoefs(const OldSolutionCoefs &in)
ParallelType type() const
void heterogenously_constrain_element_matrix_and_vector(DenseMatrix< Number > &matrix, DenseVector< Number > &rhs, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true, int qoi_index=-1) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void convert_from_receive(SendT &received, T &converted)
DynamicSparseNumberArray< Real, dof_id_type > DSNAN
std::vector< dof_id_type > send_list
FEContinuity
defines an enum for finite element types to libmesh_assert a certain level (or type? Hcurl?) of continuity.
void eval_old_dofs(const Elem &elem, unsigned int node_num, unsigned int var_num, std::vector< dof_id_type > &indices, std::vector< DSNA > &values)
virtual numeric_index_type row_start() const =0
For ease of communication, we allow users to translate their own value types to a more easily computa...
virtual numeric_index_type local_size() const =0
The OldSolutionCoefs input functor class can be used with GenericProjector to read solution transfer ...
virtual Output component(const FEMContext &, unsigned int i, const Point &p, Real time=0.)
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Gradient gptr(const Point &p, const Parameters &, const std::string &libmesh_dbg_var(sys_name), const std::string &unknown_name)
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
The DofObject defines an abstract base class for objects that have degrees of freedom associated with...
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
DynamicSparseNumberArray< ValIn, dof_id_type > InsertInput
MatrixFillAction(SparseMatrix< ValOut > &target_mat)
std::pair< unsigned int, unsigned int > var_to_vg_and_offset(const unsigned int s, const unsigned int var) const
virtual void clear()
Restores the NumericVector<T> to a pristine state.
virtual void set(const numeric_index_type i, const T value)=0
Sets v(i) = value.
void edge_boundary_ids(const Elem *const elem, const unsigned short int edge, std::vector< boundary_id_type > &vec_to_fill) const
Defines a dense vector for use in Finite Element-type computations.
void cholesky_solve(const DenseVector< T2 > &b, DenseVector< T2 > &x)
For symmetric positive definite (SPD) matrices.
dof_id_type first_dof(const processor_id_type proc) const
The VectorSetAction output functor class can be used with a GenericProjector to set projection values...
dof_id_type end_dof(const processor_id_type proc) const
const std::set< boundary_id_type > & b
std::unique_ptr< FunctionBase< Gradient > > g
const TypeToSend< T >::type convert_to_send(const T &in)
unsigned int n_comp_group(const unsigned int s, const unsigned int vg) const
The FEMFunctionWrapper input functor class can be used with a GenericProjector to read values from an...
A Point defines a location in LIBMESH_DIM dimensional Real space.
DSNAOutput< Output >::type DSNA
void ErrorVector unsigned int
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
void insert(const std::vector< dof_id_type > &dof_indices, const std::vector< DynamicSparseNumberArray< ValIn, dof_id_type > > &Ue)
const Elem & get(const ElemType type_in)
This class forms the foundation from which generic finite elements may be derived.
dof_id_type first_old_dof(const processor_id_type proc) const
void old_dof_indices(const Elem &elem, unsigned int n, std::vector< dof_id_type > &di, const unsigned int vn) const
Appends to the vector di the old global degree of freedom indices for elem.node_ref(n), for one variable vn.
const std::vector< std::vector< OutputShape > > & get_phi() const
const FEType & type() const
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
virtual void localize(std::vector< T > &v_local) const =0
Creates a copy of the global vector in the local vector v_local.