23 #include "libmesh/default_coupling.h"
24 #include "libmesh/explicit_system.h"
25 #include "libmesh/fe_interface.h"
26 #include "libmesh/frequency_system.h"
27 #include "libmesh/linear_implicit_system.h"
28 #include "libmesh/mesh_refinement.h"
29 #include "libmesh/newmark_system.h"
30 #include "libmesh/nonlinear_implicit_system.h"
31 #include "libmesh/rb_construction.h"
32 #include "libmesh/transient_rb_construction.h"
33 #include "libmesh/eigen_system.h"
34 #include "libmesh/parallel.h"
35 #include "libmesh/transient_system.h"
36 #include "libmesh/dof_map.h"
37 #include "libmesh/mesh_base.h"
38 #include "libmesh/elem.h"
39 #include "libmesh/libmesh_logging.h"
43 #include "libmesh/equation_systems.h"
58 _refine_in_reinit(true),
59 _enable_default_ghosting(true)
63 this->
parameters.
set<
unsigned int>(
"linear solver maximum iterations") = 5000;
86 System * sys = pos->second;
98 const unsigned int n_sys = this->
n_systems();
100 libmesh_assert_not_equal_to (n_sys, 0);
105 node->set_n_systems(n_sys);
108 elem->set_n_systems(n_sys);
110 for (
unsigned int i=0; i != this->
n_systems(); ++i)
113 #ifdef LIBMESH_ENABLE_AMR
135 parallel_object_only();
137 const unsigned int n_sys = this->
n_systems();
138 libmesh_assert_not_equal_to (n_sys, 0);
142 bool _added_new_systems =
false;
143 for (
unsigned int i=0; i != n_sys; ++i)
145 _added_new_systems =
true;
147 if (_added_new_systems)
151 node->set_n_systems(n_sys);
154 elem->set_n_systems(n_sys);
157 for (
unsigned int i=0; i != n_sys; ++i)
173 node->set_n_systems(this->n_systems());
177 elem->set_n_systems(this->n_systems());
181 for (
unsigned int i=0; i != this->
n_systems(); ++i)
184 #ifdef LIBMESH_ENABLE_AMR
186 bool mesh_changed =
false;
192 for (
unsigned int i=0; i != this->
n_systems(); ++i)
227 for (
unsigned int i=0; i != this->
n_systems(); ++i)
246 for (
unsigned int i=0; i != this->
n_systems(); ++i)
259 #endif // #ifdef LIBMESH_ENABLE_AMR
268 for (
unsigned int i=0; i != this->
n_systems(); ++i)
280 const unsigned int n_sys = this->
n_systems();
282 libmesh_assert_not_equal_to (n_sys, 0);
290 node->set_n_systems(n_sys);
293 elem->set_n_systems(n_sys);
296 for (
unsigned int i=0; i != this->
n_systems(); ++i)
318 mesh.add_ghosting_functor(
mesh.default_ghosting());
320 mesh.remove_ghosting_functor(
mesh.default_ghosting());
322 for (
unsigned int i=0; i != this->
n_systems(); ++i)
336 LOG_SCOPE(
"update()",
"EquationSystems");
339 for (
unsigned int i=0; i != this->
n_systems(); ++i)
346 const std::string &
name)
357 else if (sys_type ==
"Basic")
358 this->add_system<System> (
name);
361 else if (sys_type ==
"Newmark")
362 this->add_system<NewmarkSystem> (
name);
365 else if ((sys_type ==
"Explicit"))
366 this->add_system<ExplicitSystem> (
name);
369 else if ((sys_type ==
"Implicit") ||
370 (sys_type ==
"Steady" ))
371 this->add_system<ImplicitSystem> (
name);
374 else if ((sys_type ==
"Transient") ||
375 (sys_type ==
"TransientImplicit") ||
376 (sys_type ==
"TransientLinearImplicit"))
377 this->add_system<TransientLinearImplicitSystem> (
name);
380 else if (sys_type ==
"TransientNonlinearImplicit")
381 this->add_system<TransientNonlinearImplicitSystem> (
name);
384 else if (sys_type ==
"TransientExplicit")
385 this->add_system<TransientExplicitSystem> (
name);
388 else if (sys_type ==
"LinearImplicit")
389 this->add_system<LinearImplicitSystem> (
name);
392 else if (sys_type ==
"NonlinearImplicit")
393 this->add_system<NonlinearImplicitSystem> (
name);
396 else if (sys_type ==
"RBConstruction")
397 this->add_system<RBConstruction> (
name);
400 else if (sys_type ==
"TransientRBConstruction")
401 this->add_system<TransientRBConstruction> (
name);
403 #ifdef LIBMESH_HAVE_SLEPC
405 else if (sys_type ==
"Eigen")
406 this->add_system<EigenSystem> (
name);
407 else if (sys_type ==
"TransientEigenSystem")
408 this->add_system<TransientEigenSystem> (
name);
411 #if defined(LIBMESH_USE_COMPLEX_NUMBERS)
413 else if (sys_type ==
"Frequency")
414 this->add_system<FrequencySystem> (
name);
418 libmesh_error_msg(
"ERROR: Unknown system type: " << sys_type);
430 #ifdef LIBMESH_ENABLE_DEPRECATED
433 libmesh_deprecated();
436 libmesh_error_msg(
"ERROR: no system named " <<
name);
450 for (
unsigned int i=0; i != this->
n_systems(); ++i)
460 for (
unsigned int i=0; i != this->
n_systems(); ++i)
461 this->
get_system(i).sensitivity_solve(parameters_in);
470 for (
unsigned int i=this->
n_systems(); i != 0; --i)
471 this->
get_system(i-1).adjoint_solve(qoi_indices);
478 const std::set<std::string> * system_names)
const
480 unsigned int var_num=0;
489 unsigned int n_scalar_vars = 0;
490 unsigned int n_vector_vars = 0;
492 for (; pos !=
end; ++pos)
495 bool use_current_system = (system_names ==
nullptr);
496 if (!use_current_system)
497 use_current_system = system_names->count(pos->first);
498 if (!use_current_system || pos->second->hide_output())
513 unsigned int nv = n_scalar_vars +
dim*n_vector_vars;
516 libmesh_assert_less_equal ( nv,
dim*this->
n_vars() );
521 var_names.resize( nv );
527 for (; pos !=
end; ++pos)
530 bool use_current_system = (system_names ==
nullptr);
531 if (!use_current_system)
532 use_current_system = system_names->count(pos->first);
533 if (!use_current_system || pos->second->hide_output())
538 const std::string & var_name = pos->second->variable_name(vn);
539 const FEType & fe_type = pos->second->variable_type(vn);
544 if (type ==
nullptr || (type && *type == fe_type))
552 var_names[var_num++] = var_name;
555 var_names[var_num++] = var_name+
"_x";
556 var_names[var_num++] = var_name+
"_y";
559 var_names[var_num++] = var_name+
"_x";
560 var_names[var_num++] = var_name+
"_y";
561 var_names[var_num++] = var_name+
"_z";
564 libmesh_error_msg(
"Invalid dim in build_variable_names");
568 var_names[var_num++] = var_name;
573 var_names.resize(var_num);
580 const std::string &)
const
583 libmesh_not_implemented();
589 std::unique_ptr<NumericVector<Number>>
592 LOG_SCOPE(
"build_parallel_solution_vector()",
"EquationSystems");
595 parallel_object_only();
615 unsigned int n_scalar_vars = 0;
616 unsigned int n_vector_vars = 0;
620 for (; pos !=
end; ++pos)
623 bool use_current_system = (system_names ==
nullptr);
624 if (!use_current_system)
625 use_current_system = system_names->count(pos->first);
626 if (!use_current_system || pos->second->hide_output())
639 nv = n_scalar_vars +
dim*n_vector_vars;
657 n_local_nodes = n_local_nodes +
664 parallel_soln.
init(max_nn*nv, n_local_nodes*nv,
false,
PARALLEL);
670 repeat_count.
init(max_nn*nv, n_local_nodes*nv,
false,
PARALLEL);
672 repeat_count.
close();
674 unsigned int var_num=0;
684 for (; pos !=
end; ++pos)
687 bool use_current_system = (system_names ==
nullptr);
688 if (!use_current_system)
689 use_current_system = system_names->count(pos->first);
690 if (!use_current_system || pos->second->hide_output())
693 const System & system = *(pos->second);
694 const unsigned int nv_sys = system.
n_vars();
695 const unsigned int sys_num = system.
number();
698 unsigned int n_scalar_vars = 0;
699 unsigned int n_vector_vars = 0;
710 unsigned int nv_sys_split = n_scalar_vars +
dim*n_vector_vars;
714 System & non_const_sys = const_cast<System &>(system);
721 if (!non_const_sys.
solution->closed())
728 std::vector<Number> elem_soln;
729 std::vector<Number> nodal_soln;
730 std::vector<dof_id_type> dof_indices;
732 unsigned var_inc = 0;
733 for (
unsigned int var=0; var<nv_sys; var++)
747 elem_soln.resize(dof_indices.size());
750 elem_soln[i] = sys_soln(dof_indices[i]);
758 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
760 if (!elem->infinite())
763 libmesh_assert_equal_to (nodal_soln.size(), n_vec_dim*elem->n_nodes());
765 for (
auto n : elem->node_index_range())
767 for (
unsigned int d=0; d < n_vec_dim; d++)
771 parallel_soln.
add(nv*(elem->node_id(n)) + (var_inc+d + var_num), nodal_soln[n_vec_dim*n+d]);
774 repeat_count.
add(nv*(elem->node_id(n)) + (var_inc+d + var_num), 1);
780 for (
const Node & node : elem->node_ref_range())
782 if (!node.n_dofs(sys_num, var))
783 for (
unsigned int d=0; d < n_vec_dim; d++)
784 repeat_count.
add(nv*node.id() + (var_inc+d + var_num), 1);
787 var_inc += n_vec_dim;
790 var_num += nv_sys_split;
794 parallel_soln.
close();
795 repeat_count.
close();
810 repeat_count.
set(i, 1.);
815 repeat_count.
close();
819 parallel_soln /= repeat_count;
821 return std::unique_ptr<NumericVector<Number>>(parallel_soln_ptr.release());
827 const std::set<std::string> * system_names)
const
829 LOG_SCOPE(
"build_solution_vector()",
"EquationSystems");
832 std::unique_ptr<NumericVector<Number>> parallel_soln =
836 parallel_soln->localize_to_one(soln);
842 std::vector<std::set<subdomain_id_type>> & vars_active_subdomains)
const
844 unsigned int var_num=0;
846 vars_active_subdomains.clear();
847 vars_active_subdomains.resize(names.size());
852 for (; pos !=
end; ++pos)
856 const std::string & var_name = pos->second->variable_name(vn);
858 auto names_it = std::find(names.begin(), names.end(), var_name);
859 if(names_it != names.end())
861 const Variable & variable = pos->second->variable(vn);
862 const std::set<subdomain_id_type> & active_subdomains = variable.
active_subdomains();
863 vars_active_subdomains[var_num++] = active_subdomains;
868 libmesh_assert_equal_to(var_num, names.size());
874 std::vector<std::string> & names)
const
876 libmesh_deprecated();
884 std::vector<std::string> & names)
const
887 std::unique_ptr<NumericVector<Number>> parallel_soln =
897 parallel_soln->localize_to_one(soln);
902 std::vector<std::pair<unsigned int, unsigned int>>
904 (std::vector<std::string> & names,
const FEType * type)
const
907 parallel_object_only();
914 std::vector<std::pair<unsigned int, unsigned int>> var_nums;
915 std::vector<std::string> filter_names = names;
916 bool is_filter_names = !filter_names.empty();
922 unsigned sys_ctr = 0;
924 for (; pos !=
end; ++pos, ++sys_ctr)
926 const System & system = *(pos->second);
927 const unsigned int nv_sys = system.
n_vars();
929 for (
unsigned int var=0; var < nv_sys; ++var)
933 (is_filter_names && std::find(filter_names.begin(), filter_names.end(),
name) == filter_names.end()))
938 (std::make_pair(system.
number(), var));
942 std::sort(var_nums.begin(), var_nums.end());
944 for (
const auto & var_num : var_nums)
946 const std::string &
name =
947 this->get_system(var_num.first).variable_name(var_num.second);
948 if (names.empty() || names.back() !=
name)
949 names.push_back(
name);
956 std::unique_ptr<NumericVector<Number>>
960 std::vector<std::pair<unsigned int, unsigned int>> var_nums =
963 const std::size_t nv = var_nums.size();
969 return std::unique_ptr<NumericVector<Number>>(
nullptr);
983 parallel_soln_local_size = div+1;
988 parallel_soln.
init(parallel_soln_global_size,
989 parallel_soln_local_size,
993 unsigned int sys_ctr = 0;
1001 std::pair<unsigned int, unsigned int> var_num = var_nums[i];
1005 if (sys_ctr != var_num.first)
1007 System & non_const_sys = const_cast<System &>(system);
1014 if (!non_const_sys.
solution->closed())
1017 sys_ctr = var_num.first;
1023 std::vector<dof_id_type> dof_indices;
1025 const unsigned int var = var_num.second;
1035 libmesh_assert_equal_to (1, dof_indices.size());
1037 parallel_soln.
set((ne*i)+elem->id(), sys_soln(dof_indices[0]));
1041 parallel_soln.
close();
1042 return std::unique_ptr<NumericVector<Number>>(parallel_soln_ptr.release());
1049 (std::vector<Number> & soln,
1050 const std::set<std::string> * system_names,
1051 const std::vector<std::string> * var_names,
1052 bool vertices_only)
const
1054 LOG_SCOPE(
"build_discontinuous_solution_vector()",
"EquationSystems");
1058 const unsigned int dim = _mesh.mesh_dimension();
1062 unsigned int nv = 0;
1064 for (
const auto & pr : _systems)
1067 bool use_current_system = (system_names ==
nullptr);
1068 if (!use_current_system)
1069 use_current_system = system_names->count(pr.first);
1070 if (!use_current_system || pr.second->hide_output())
1073 const System * system = pr.second;
1079 bool use_current_var = (var_names ==
nullptr);
1080 if (!use_current_var)
1081 use_current_var = std::count(var_names->begin(),
1087 if (use_current_var)
1094 for (
const auto & elem : _mesh.active_element_ptr_range())
1095 tw += vertices_only ? elem->n_vertices() : elem->n_nodes();
1099 if (_mesh.processor_id() == 0)
1102 std::vector<Number> sys_soln;
1106 unsigned int var_offset = 0;
1113 for (
const auto & pr : _systems)
1116 bool use_current_system = (system_names ==
nullptr);
1117 if (!use_current_system)
1118 use_current_system = system_names->count(pr.first);
1119 if (!use_current_system || pr.second->hide_output())
1122 const System * system = pr.second;
1123 const unsigned int nv_sys = system->
n_vars();
1128 unsigned int n_vars_written_current_system = 0;
1130 if (_mesh.processor_id() == 0)
1132 std::vector<Number> soln_coeffs;
1133 std::vector<Number> nodal_soln;
1134 std::vector<dof_id_type> dof_indices;
1141 for (
unsigned int var=0; var<nv_sys; var++)
1143 bool use_current_var = (var_names ==
nullptr);
1144 if (!use_current_var)
1145 use_current_var = std::count(var_names->begin(),
1151 if (!use_current_var)
1159 for (
auto & elem : _mesh.active_element_ptr_range())
1165 soln_coeffs.resize(dof_indices.size());
1168 soln_coeffs[i] = sys_soln[dof_indices[i]];
1179 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
1181 if (!elem->infinite())
1184 libmesh_assert_equal_to (nodal_soln.size(), elem->n_nodes());
1186 const unsigned int n_vals =
1187 vertices_only ? elem->n_vertices() : elem->n_nodes();
1189 for (
unsigned int n=0; n<n_vals; n++)
1193 nv * (nn++) + (n_vars_written_current_system + var_offset);
1195 soln[index] += nodal_soln[n];
1200 nn += vertices_only ? elem->n_vertices() : elem->n_nodes();
1205 n_vars_written_current_system++;
1211 var_offset += n_vars_written_current_system;
1218 const Real threshold,
1219 const bool verbose)
const
1223 std::vector<bool> os_result;
1229 libMesh::out <<
" Fatal difference. This system handles "
1230 << this->
n_systems() <<
" systems," << std::endl
1231 <<
" while the other system handles "
1233 <<
" systems." << std::endl
1234 <<
" Aborting comparison." << std::endl;
1244 for (; pos !=
end; ++pos)
1246 const std::string & sys_name = pos->first;
1247 const System & system = *(pos->second);
1252 os_result.push_back (system.
compare (other_system, threshold, verbose));
1260 if (os_result.size()==0)
1268 os_identical = os_result[n];
1271 while (os_identical && n<os_result.size());
1272 return os_identical;
1280 std::ostringstream oss;
1282 oss <<
" EquationSystems\n"
1283 <<
" n_systems()=" << this->
n_systems() <<
'\n';
1289 for (; pos !=
end; ++pos)
1290 oss << pos->second->get_info();
1338 for (; pos !=
end; ++pos)
1339 tot += pos->second->n_vars();
1353 for (; pos !=
end; ++pos)
1354 tot += pos->second->n_dofs();
1369 for (; pos !=
end; ++pos)
1370 tot += pos->second->n_active_dofs();
1389 this->
get_system(sys_num).get_dof_map().remove_default_ghosting();