From 46404aee0e85e329275755099a6c5583f2d49a08 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 10 Apr 2025 13:37:15 -0600 Subject: [PATCH 01/41] Create DofMapBase --- include/base/dof_map_base.h | 80 +++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 include/base/dof_map_base.h diff --git a/include/base/dof_map_base.h b/include/base/dof_map_base.h new file mode 100644 index 00000000000..f59a07d3e7e --- /dev/null +++ b/include/base/dof_map_base.h @@ -0,0 +1,80 @@ +// The libMesh Finite Element Library. +// Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef LIBMESH_DOF_MAP_BASE_H +#define LIBMESH_DOF_MAP_BASE_H + +#include "libmesh/id_types.h" +#include + +namespace libMesh +{ +class Variable; +class Elem; +class Node; + +class DofMapBase +{ +public: + DofMapBase() = default; + + /** + * \returns The number of variables in the global solution vector. Defaults + * to 1, should be 1 for a scalar equation, 3 for 2D incompressible Navier + * Stokes (u,v,p), etc... + */ + virtual unsigned int n_variables() const = 0; + + /** + * \returns The variable description object for variable \p c. + */ + virtual const Variable & variable(const unsigned int c) const = 0; + + /** + * \returns The first dof index that is local to partition \p proc. + */ + virtual dof_id_type first_dof() const = 0; + + /** + * \returns The first dof index that is after all indices local to + * processor \p proc. + * + * Analogous to the end() member function of STL containers. + */ + virtual dof_id_type end_dof() const = 0; + + /** + * Fills the vector \p di with the global degree of freedom indices + * for the element. For one variable, and potentially for a + * non-default element p refinement level + */ + virtual void dof_indices(const Elem * const elem, + std::vector & di, + const unsigned int vn, + int p_level = -12345) const = 0; + + /** + * Fills the vector \p di with the global degree of freedom indices + * for the \p node, for one variable \p vn. + */ + virtual void dof_indices(const Node * const node, + std::vector & di, + const unsigned int vn) const = 0; +}; + +} +#endif // LIBMESH_DOF_MAP_BASE_H From f501013441e26b89c53cf69b0a3c34d321a75e5b Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 10 Apr 2025 13:37:51 -0600 Subject: [PATCH 02/41] Update Makefile.am files --- include/include_HEADERS | 1 + include/libmesh/Makefile.am | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/include/include_HEADERS b/include/include_HEADERS index 5a31513b7ee..7b1520d43fb 100644 --- a/include/include_HEADERS +++ b/include/include_HEADERS @@ -20,6 +20,7 @@ include_HEADERS = \ base/auto_ptr.h \ base/dirichlet_boundaries.h \ base/dof_map.h \ + base/dof_map_base.h \ base/dof_object.h \ base/factory.h \ base/float128_shims.h \ diff --git a/include/libmesh/Makefile.am b/include/libmesh/Makefile.am index fca975b85e8..a5d9166efb9 100644 --- a/include/libmesh/Makefile.am +++ b/include/libmesh/Makefile.am @@ -9,6 +9,7 @@ BUILT_SOURCES = \ auto_ptr.h \ dirichlet_boundaries.h \ dof_map.h \ + dof_map_base.h \ dof_object.h \ factory.h \ float128_shims.h \ @@ -622,6 +623,9 @@ dirichlet_boundaries.h: $(top_srcdir)/include/base/dirichlet_boundaries.h dof_map.h: $(top_srcdir)/include/base/dof_map.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ +dof_map_base.h: $(top_srcdir)/include/base/dof_map_base.h + $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ + dof_object.h: $(top_srcdir)/include/base/dof_object.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ From f6369a4abf17da66e289466d176b6b4ee93e2626 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 10 Apr 2025 14:26:22 -0600 Subject: [PATCH 03/41] Run bootstrap --- include/Makefile.in | 1 + include/libmesh/Makefile.in | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/Makefile.in b/include/Makefile.in index 9f1f2ce7d51..7d09912b559 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -621,6 +621,7 @@ include_HEADERS = \ base/auto_ptr.h \ base/dirichlet_boundaries.h \ base/dof_map.h \ + base/dof_map_base.h \ base/dof_object.h \ base/factory.h \ base/float128_shims.h \ diff --git a/include/libmesh/Makefile.in b/include/libmesh/Makefile.in index 5e5e169cb03..35a2527c09a 100644 --- a/include/libmesh/Makefile.in +++ b/include/libmesh/Makefile.in @@ -521,12 +521,12 @@ vtkversion = @vtkversion@ # include the magic script! EXTRA_DIST = rebuild_makefile.sh BUILT_SOURCES = auto_ptr.h dirichlet_boundaries.h dof_map.h \ - dof_object.h factory.h float128_shims.h getpot.h id_types.h \ - libmesh.h libmesh_augment_std_namespace.h libmesh_base.h \ - libmesh_common.h libmesh_documentation.h libmesh_exceptions.h \ - libmesh_logging.h libmesh_singleton.h libmesh_version.h \ - multi_predicates.h periodic_boundaries.h periodic_boundary.h \ - periodic_boundary_base.h print_trace.h \ + dof_map_base.h dof_object.h factory.h float128_shims.h \ + getpot.h id_types.h libmesh.h libmesh_augment_std_namespace.h \ + libmesh_base.h libmesh_common.h libmesh_documentation.h \ + libmesh_exceptions.h libmesh_logging.h libmesh_singleton.h \ + libmesh_version.h multi_predicates.h periodic_boundaries.h \ + periodic_boundary.h periodic_boundary_base.h print_trace.h \ reference_counted_object.h reference_counter.h \ single_predicates.h sparsity_pattern.h variable.h \ variant_filter_iterator.h enum_convergence_flags.h \ @@ -952,6 +952,9 @@ dirichlet_boundaries.h: $(top_srcdir)/include/base/dirichlet_boundaries.h dof_map.h: $(top_srcdir)/include/base/dof_map.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ +dof_map_base.h: $(top_srcdir)/include/base/dof_map_base.h + $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ + dof_object.h: $(top_srcdir)/include/base/dof_object.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ From 1a65c5c199ef9dbf6faa433a96f403cf8f090e5b Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Fri, 11 Apr 2025 12:30:24 -0600 Subject: [PATCH 04/41] Add variable.C to libmesh_SOURCES --- src/libmesh_SOURCES | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libmesh_SOURCES b/src/libmesh_SOURCES index 82a031240f2..90a568b81f0 100644 --- a/src/libmesh_SOURCES +++ b/src/libmesh_SOURCES @@ -16,6 +16,7 @@ libmesh_SOURCES = \ src/base/reference_counter.C \ src/base/single_predicates.C \ src/base/sparsity_pattern.C \ + src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ src/error_estimation/adjoint_residual_error_estimator.C \ src/error_estimation/discontinuity_measure.C \ From 8d6a9d66768b2e50ce92d522ed35548ee28acc16 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Fri, 11 Apr 2025 12:31:29 -0600 Subject: [PATCH 05/41] Update Variable and System::n_components --- include/base/variable.h | 20 ++++++--- include/numerics/wrapped_function.h | 11 ++--- include/systems/system.h | 2 +- src/base/variable.C | 43 +++++++++++++++++++ .../boundary_volume_solution_transfer.C | 6 +-- 5 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 src/base/variable.C diff --git a/include/base/variable.h b/include/base/variable.h index 253531d57f8..84735df4156 100644 --- a/include/base/variable.h +++ b/include/base/variable.h @@ -33,6 +33,7 @@ namespace libMesh // Forward Declaration class System; +class MeshBase; /** * This class defines the notion of a variable in the system. @@ -128,8 +129,11 @@ class Variable { return _number; } /** - * \returns The index of the first scalar component of this variable in the - * system. + * \returns The index of the first scalar component of this variable in the system. Say you've + * got a flow problem that's (u,v,w,p,T) - p will be at first_scalar_number 3 regardless of + * whether p is variable number 1 in the case that u,v,w is represented by a single vector-valued + * variable at number 0, or p is variable number 3 in the case that u,v,w are three scalar-valued + * variables with variable numbers 0,1,2 */ unsigned int first_scalar_number() const { return _first_scalar_number; } @@ -141,10 +145,16 @@ class Variable { return _type; } /** - * \returns The number of components of this variable. + * \returns The number of components of this variable if the \p FEFamily is \p SCALAR or if the + * associated \p FEFieldType is \p TYPE_SCALAR. Otherwise this will error because determination of + * the number of components for a \p TYPE_VECTOR requires the mesh + */ + unsigned int n_components() const; + + /** + * \returns The number of components of this variable */ - unsigned int n_components() const - { return type().family == SCALAR ? _type.order.get_order() : 1; } + unsigned int n_components(const MeshBase & mesh) const; /** * \returns \p true if this variable is active on subdomain \p sid, diff --git a/include/numerics/wrapped_function.h b/include/numerics/wrapped_function.h index bc133353c32..c1fa7929883 100644 --- a/include/numerics/wrapped_function.h +++ b/include/numerics/wrapped_function.h @@ -160,8 +160,8 @@ void WrappedFunction::operator() (const Point & p, const unsigned int n_vars = _sys.n_vars(); for (unsigned int v = 0; v != n_vars; ++v) { - const unsigned int n_components = - _sys.variable(v).n_components(); + const auto n_components = + _sys.variable(v).n_components(_sys.get_mesh()); if (n_components == 1) output(_sys.variable_scalar_number(v,0)) = _fptr(p, *_parameters, _sys.name(), _sys.variable_name(v)); @@ -199,12 +199,7 @@ Output WrappedFunction::component (unsigned int i, for (unsigned int v = 0; v != n_vars; ++v) { const auto & var_fe_type = _sys.variable_type(v); - const unsigned int n_components = [&var_fe_type, v, this](){ - if (var_fe_type.family == SCALAR) - return _sys.variable(v).n_components(); - else - return FEInterface::n_vec_dim(_sys.get_mesh(), var_fe_type); - }(); + const auto n_components = _sys.variable(v).n_components(_sys.get_mesh()); if (i >= vc + n_components) { vc += n_components; diff --git a/include/systems/system.h b/include/systems/system.h index 6c83b15a10d..95c13aee42b 100644 --- a/include/systems/system.h +++ b/include/systems/system.h @@ -2445,7 +2445,7 @@ unsigned int System::n_components() const return 0; const Variable & last = _variables.back(); - return last.first_scalar_number() + last.n_components(); + return last.first_scalar_number() + last.n_components(this->get_mesh()); } diff --git a/src/base/variable.C b/src/base/variable.C new file mode 100644 index 00000000000..2345d958533 --- /dev/null +++ b/src/base/variable.C @@ -0,0 +1,43 @@ +// The libMesh Finite Element Library. +// Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "libmesh/variable.h" +#include "libmesh/fe_interface.h" + +namespace libMesh +{ +unsigned int Variable::n_components() const +{ + if (_type.family == SCALAR) + return _type.order.get_order(); + + if (const auto fe_field_type = FEInterface::field_type(_type.family); + fe_field_type == TYPE_VECTOR) + libmesh_error_msg("Cannot determine the number of components. Please call the n_components " + "overload with a mesh argument"); + else + return 1; +} + +unsigned int Variable::n_components(const MeshBase & mesh) const +{ + if (_type.family == SCALAR) + return _type.order.get_order(); + else + return FEInterface::n_vec_dim(mesh, _type); +} +} diff --git a/src/solution_transfer/boundary_volume_solution_transfer.C b/src/solution_transfer/boundary_volume_solution_transfer.C index 2422d0c08cf..0a8c57c6d66 100644 --- a/src/solution_transfer/boundary_volume_solution_transfer.C +++ b/src/solution_transfer/boundary_volume_solution_transfer.C @@ -65,8 +65,8 @@ transfer_volume_boundary(const Variable & from_var, const Variable & to_var) const unsigned int to_var_number = to_var.number(); // Get a constant reference to variables, get their number of components - const unsigned int from_n_comp = from_var.n_components(); - const unsigned int to_n_comp = to_var.n_components(); + const unsigned int from_n_comp = from_var.n_components(from_sys->get_mesh()); + const unsigned int to_n_comp = to_var.n_components(to_mesh); // Sanity check that the variables have the same number of components libmesh_assert_equal_to(from_n_comp, to_n_comp); @@ -157,7 +157,7 @@ transfer_boundary_volume(const Variable & from_var, const Variable & to_var) const unsigned int to_sys_number = to_sys->number(); const unsigned int to_var_number = to_var.number(); const unsigned int from_var_number = from_var.number(); - const unsigned int to_n_comp = to_var.n_components(); + const unsigned int to_n_comp = to_var.n_components(to_sys->get_mesh()); // In order to get solution vectors from BoundaryMesh std::vector from_dof_indices; From e33706a825fe1ebba91a6c4a2d433f46da0d16c9 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Fri, 11 Apr 2025 12:32:17 -0600 Subject: [PATCH 06/41] run bootstrap --- Makefile.in | 81 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9eb32461d94..611e3ca0dca 100644 --- a/Makefile.in +++ b/Makefile.in @@ -274,7 +274,7 @@ am__libmesh_dbg_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ src/base/print_trace.C src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ - src/base/sparsity_pattern.C \ + src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ src/error_estimation/adjoint_residual_error_estimator.C \ src/error_estimation/discontinuity_measure.C \ @@ -600,6 +600,7 @@ am__objects_1 = src/base/libmesh_dbg_la-dirichlet_boundary.lo \ src/base/libmesh_dbg_la-reference_counter.lo \ src/base/libmesh_dbg_la-single_predicates.lo \ src/base/libmesh_dbg_la-sparsity_pattern.lo \ + src/base/libmesh_dbg_la-variable.lo \ src/error_estimation/libmesh_dbg_la-adjoint_refinement_estimator.lo \ src/error_estimation/libmesh_dbg_la-adjoint_residual_error_estimator.lo \ src/error_estimation/libmesh_dbg_la-discontinuity_measure.lo \ @@ -1074,7 +1075,7 @@ am__libmesh_devel_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ src/base/print_trace.C src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ - src/base/sparsity_pattern.C \ + src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ src/error_estimation/adjoint_residual_error_estimator.C \ src/error_estimation/discontinuity_measure.C \ @@ -1399,6 +1400,7 @@ am__objects_2 = src/base/libmesh_devel_la-dirichlet_boundary.lo \ src/base/libmesh_devel_la-reference_counter.lo \ src/base/libmesh_devel_la-single_predicates.lo \ src/base/libmesh_devel_la-sparsity_pattern.lo \ + src/base/libmesh_devel_la-variable.lo \ src/error_estimation/libmesh_devel_la-adjoint_refinement_estimator.lo \ src/error_estimation/libmesh_devel_la-adjoint_residual_error_estimator.lo \ src/error_estimation/libmesh_devel_la-discontinuity_measure.lo \ @@ -1870,7 +1872,7 @@ am__libmesh_oprof_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ src/base/print_trace.C src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ - src/base/sparsity_pattern.C \ + src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ src/error_estimation/adjoint_residual_error_estimator.C \ src/error_estimation/discontinuity_measure.C \ @@ -2195,6 +2197,7 @@ am__objects_3 = src/base/libmesh_oprof_la-dirichlet_boundary.lo \ src/base/libmesh_oprof_la-reference_counter.lo \ src/base/libmesh_oprof_la-single_predicates.lo \ src/base/libmesh_oprof_la-sparsity_pattern.lo \ + src/base/libmesh_oprof_la-variable.lo \ src/error_estimation/libmesh_oprof_la-adjoint_refinement_estimator.lo \ src/error_estimation/libmesh_oprof_la-adjoint_residual_error_estimator.lo \ src/error_estimation/libmesh_oprof_la-discontinuity_measure.lo \ @@ -2666,7 +2669,7 @@ am__libmesh_opt_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ src/base/print_trace.C src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ - src/base/sparsity_pattern.C \ + src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ src/error_estimation/adjoint_residual_error_estimator.C \ src/error_estimation/discontinuity_measure.C \ @@ -2991,6 +2994,7 @@ am__objects_4 = src/base/libmesh_opt_la-dirichlet_boundary.lo \ src/base/libmesh_opt_la-reference_counter.lo \ src/base/libmesh_opt_la-single_predicates.lo \ src/base/libmesh_opt_la-sparsity_pattern.lo \ + src/base/libmesh_opt_la-variable.lo \ src/error_estimation/libmesh_opt_la-adjoint_refinement_estimator.lo \ src/error_estimation/libmesh_opt_la-adjoint_residual_error_estimator.lo \ src/error_estimation/libmesh_opt_la-discontinuity_measure.lo \ @@ -3461,7 +3465,7 @@ am__libmesh_prof_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ src/base/print_trace.C src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ - src/base/sparsity_pattern.C \ + src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ src/error_estimation/adjoint_residual_error_estimator.C \ src/error_estimation/discontinuity_measure.C \ @@ -3786,6 +3790,7 @@ am__objects_5 = src/base/libmesh_prof_la-dirichlet_boundary.lo \ src/base/libmesh_prof_la-reference_counter.lo \ src/base/libmesh_prof_la-single_predicates.lo \ src/base/libmesh_prof_la-sparsity_pattern.lo \ + src/base/libmesh_prof_la-variable.lo \ src/error_estimation/libmesh_prof_la-adjoint_refinement_estimator.lo \ src/error_estimation/libmesh_prof_la-adjoint_residual_error_estimator.lo \ src/error_estimation/libmesh_prof_la-discontinuity_measure.lo \ @@ -4722,6 +4727,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_dbg_la-reference_counter.Plo \ src/base/$(DEPDIR)/libmesh_dbg_la-single_predicates.Plo \ src/base/$(DEPDIR)/libmesh_dbg_la-sparsity_pattern.Plo \ + src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-dof_map.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo \ @@ -4738,6 +4744,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_devel_la-reference_counter.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-single_predicates.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-sparsity_pattern.Plo \ + src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-dof_map.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo \ @@ -4754,6 +4761,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_oprof_la-reference_counter.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-single_predicates.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-sparsity_pattern.Plo \ + src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-dof_map.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo \ @@ -4770,6 +4778,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_opt_la-reference_counter.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-single_predicates.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-sparsity_pattern.Plo \ + src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-dof_map.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo \ @@ -4786,6 +4795,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_prof_la-reference_counter.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-single_predicates.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-sparsity_pattern.Plo \ + src/base/$(DEPDIR)/libmesh_prof_la-variable.Plo \ src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_refinement_estimator.Plo \ src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_residual_error_estimator.Plo \ src/error_estimation/$(DEPDIR)/libmesh_dbg_la-discontinuity_measure.Plo \ @@ -7722,6 +7732,7 @@ libmesh_SOURCES = \ src/base/reference_counter.C \ src/base/single_predicates.C \ src/base/sparsity_pattern.C \ + src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ src/error_estimation/adjoint_residual_error_estimator.C \ src/error_estimation/discontinuity_measure.C \ @@ -8671,6 +8682,8 @@ src/base/libmesh_dbg_la-single_predicates.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_dbg_la-sparsity_pattern.lo: src/base/$(am__dirstamp) \ src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_dbg_la-variable.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/error_estimation/$(am__dirstamp): @$(MKDIR_P) src/error_estimation @: > src/error_estimation/$(am__dirstamp) @@ -9912,6 +9925,8 @@ src/base/libmesh_devel_la-single_predicates.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_devel_la-sparsity_pattern.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_devel_la-variable.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/error_estimation/libmesh_devel_la-adjoint_refinement_estimator.lo: \ src/error_estimation/$(am__dirstamp) \ src/error_estimation/$(DEPDIR)/$(am__dirstamp) @@ -11066,6 +11081,8 @@ src/base/libmesh_oprof_la-single_predicates.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_oprof_la-sparsity_pattern.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_oprof_la-variable.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/error_estimation/libmesh_oprof_la-adjoint_refinement_estimator.lo: \ src/error_estimation/$(am__dirstamp) \ src/error_estimation/$(DEPDIR)/$(am__dirstamp) @@ -12220,6 +12237,8 @@ src/base/libmesh_opt_la-single_predicates.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_opt_la-sparsity_pattern.lo: src/base/$(am__dirstamp) \ src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_opt_la-variable.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/error_estimation/libmesh_opt_la-adjoint_refinement_estimator.lo: \ src/error_estimation/$(am__dirstamp) \ src/error_estimation/$(DEPDIR)/$(am__dirstamp) @@ -13371,6 +13390,8 @@ src/base/libmesh_prof_la-single_predicates.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_prof_la-sparsity_pattern.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_prof_la-variable.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/error_estimation/libmesh_prof_la-adjoint_refinement_estimator.lo: \ src/error_estimation/$(am__dirstamp) \ src/error_estimation/$(DEPDIR)/$(am__dirstamp) @@ -15045,6 +15066,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-reference_counter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-single_predicates.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-sparsity_pattern.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @@ -15061,6 +15083,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-reference_counter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-single_predicates.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-sparsity_pattern.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @@ -15077,6 +15100,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-reference_counter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-single_predicates.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-sparsity_pattern.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @@ -15093,6 +15117,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-reference_counter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-single_predicates.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-sparsity_pattern.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @@ -15109,6 +15134,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-reference_counter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-single_predicates.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-sparsity_pattern.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_refinement_estimator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_residual_error_estimator.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/error_estimation/$(DEPDIR)/libmesh_dbg_la-discontinuity_measure.Plo@am__quote@ # am--include-marker @@ -17512,6 +17538,13 @@ src/base/libmesh_dbg_la-sparsity_pattern.lo: src/base/sparsity_pattern.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_dbg_la-sparsity_pattern.lo `test -f 'src/base/sparsity_pattern.C' || echo '$(srcdir)/'`src/base/sparsity_pattern.C +src/base/libmesh_dbg_la-variable.lo: src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_dbg_la-variable.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_dbg_la-variable.Tpo -c -o src/base/libmesh_dbg_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_dbg_la-variable.Tpo src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/variable.C' object='src/base/libmesh_dbg_la-variable.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_dbg_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C + src/error_estimation/libmesh_dbg_la-adjoint_refinement_estimator.lo: src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -MT src/error_estimation/libmesh_dbg_la-adjoint_refinement_estimator.lo -MD -MP -MF src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_refinement_estimator.Tpo -c -o src/error_estimation/libmesh_dbg_la-adjoint_refinement_estimator.lo `test -f 'src/error_estimation/adjoint_refinement_estimator.C' || echo '$(srcdir)/'`src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_refinement_estimator.Tpo src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_refinement_estimator.Plo @@ -20788,6 +20821,13 @@ src/base/libmesh_devel_la-sparsity_pattern.lo: src/base/sparsity_pattern.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_devel_la-sparsity_pattern.lo `test -f 'src/base/sparsity_pattern.C' || echo '$(srcdir)/'`src/base/sparsity_pattern.C +src/base/libmesh_devel_la-variable.lo: src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_devel_la-variable.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_devel_la-variable.Tpo -c -o src/base/libmesh_devel_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_devel_la-variable.Tpo src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/variable.C' object='src/base/libmesh_devel_la-variable.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_devel_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C + src/error_estimation/libmesh_devel_la-adjoint_refinement_estimator.lo: src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -MT src/error_estimation/libmesh_devel_la-adjoint_refinement_estimator.lo -MD -MP -MF src/error_estimation/$(DEPDIR)/libmesh_devel_la-adjoint_refinement_estimator.Tpo -c -o src/error_estimation/libmesh_devel_la-adjoint_refinement_estimator.lo `test -f 'src/error_estimation/adjoint_refinement_estimator.C' || echo '$(srcdir)/'`src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/error_estimation/$(DEPDIR)/libmesh_devel_la-adjoint_refinement_estimator.Tpo src/error_estimation/$(DEPDIR)/libmesh_devel_la-adjoint_refinement_estimator.Plo @@ -24064,6 +24104,13 @@ src/base/libmesh_oprof_la-sparsity_pattern.lo: src/base/sparsity_pattern.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_oprof_la-sparsity_pattern.lo `test -f 'src/base/sparsity_pattern.C' || echo '$(srcdir)/'`src/base/sparsity_pattern.C +src/base/libmesh_oprof_la-variable.lo: src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_oprof_la-variable.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_oprof_la-variable.Tpo -c -o src/base/libmesh_oprof_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_oprof_la-variable.Tpo src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/variable.C' object='src/base/libmesh_oprof_la-variable.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_oprof_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C + src/error_estimation/libmesh_oprof_la-adjoint_refinement_estimator.lo: src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -MT src/error_estimation/libmesh_oprof_la-adjoint_refinement_estimator.lo -MD -MP -MF src/error_estimation/$(DEPDIR)/libmesh_oprof_la-adjoint_refinement_estimator.Tpo -c -o src/error_estimation/libmesh_oprof_la-adjoint_refinement_estimator.lo `test -f 'src/error_estimation/adjoint_refinement_estimator.C' || echo '$(srcdir)/'`src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/error_estimation/$(DEPDIR)/libmesh_oprof_la-adjoint_refinement_estimator.Tpo src/error_estimation/$(DEPDIR)/libmesh_oprof_la-adjoint_refinement_estimator.Plo @@ -27340,6 +27387,13 @@ src/base/libmesh_opt_la-sparsity_pattern.lo: src/base/sparsity_pattern.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_opt_la-sparsity_pattern.lo `test -f 'src/base/sparsity_pattern.C' || echo '$(srcdir)/'`src/base/sparsity_pattern.C +src/base/libmesh_opt_la-variable.lo: src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_opt_la-variable.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_opt_la-variable.Tpo -c -o src/base/libmesh_opt_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_opt_la-variable.Tpo src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/variable.C' object='src/base/libmesh_opt_la-variable.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_opt_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C + src/error_estimation/libmesh_opt_la-adjoint_refinement_estimator.lo: src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -MT src/error_estimation/libmesh_opt_la-adjoint_refinement_estimator.lo -MD -MP -MF src/error_estimation/$(DEPDIR)/libmesh_opt_la-adjoint_refinement_estimator.Tpo -c -o src/error_estimation/libmesh_opt_la-adjoint_refinement_estimator.lo `test -f 'src/error_estimation/adjoint_refinement_estimator.C' || echo '$(srcdir)/'`src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/error_estimation/$(DEPDIR)/libmesh_opt_la-adjoint_refinement_estimator.Tpo src/error_estimation/$(DEPDIR)/libmesh_opt_la-adjoint_refinement_estimator.Plo @@ -30616,6 +30670,13 @@ src/base/libmesh_prof_la-sparsity_pattern.lo: src/base/sparsity_pattern.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_prof_la-sparsity_pattern.lo `test -f 'src/base/sparsity_pattern.C' || echo '$(srcdir)/'`src/base/sparsity_pattern.C +src/base/libmesh_prof_la-variable.lo: src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_prof_la-variable.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_prof_la-variable.Tpo -c -o src/base/libmesh_prof_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_prof_la-variable.Tpo src/base/$(DEPDIR)/libmesh_prof_la-variable.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/variable.C' object='src/base/libmesh_prof_la-variable.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_prof_la-variable.lo `test -f 'src/base/variable.C' || echo '$(srcdir)/'`src/base/variable.C + src/error_estimation/libmesh_prof_la-adjoint_refinement_estimator.lo: src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -MT src/error_estimation/libmesh_prof_la-adjoint_refinement_estimator.lo -MD -MP -MF src/error_estimation/$(DEPDIR)/libmesh_prof_la-adjoint_refinement_estimator.Tpo -c -o src/error_estimation/libmesh_prof_la-adjoint_refinement_estimator.lo `test -f 'src/error_estimation/adjoint_refinement_estimator.C' || echo '$(srcdir)/'`src/error_estimation/adjoint_refinement_estimator.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/error_estimation/$(DEPDIR)/libmesh_prof_la-adjoint_refinement_estimator.Tpo src/error_estimation/$(DEPDIR)/libmesh_prof_la-adjoint_refinement_estimator.Plo @@ -35128,6 +35189,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo @@ -35144,6 +35206,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_devel_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo @@ -35160,6 +35223,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo @@ -35176,6 +35240,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_opt_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo @@ -35192,6 +35257,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_prof_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_prof_la-variable.Plo -rm -f src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_refinement_estimator.Plo -rm -f src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_residual_error_estimator.Plo -rm -f src/error_estimation/$(DEPDIR)/libmesh_dbg_la-discontinuity_measure.Plo @@ -37576,6 +37642,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo @@ -37592,6 +37659,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_devel_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo @@ -37608,6 +37676,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo @@ -37624,6 +37693,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_opt_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo @@ -37640,6 +37710,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_prof_la-reference_counter.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-single_predicates.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-sparsity_pattern.Plo + -rm -f src/base/$(DEPDIR)/libmesh_prof_la-variable.Plo -rm -f src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_refinement_estimator.Plo -rm -f src/error_estimation/$(DEPDIR)/libmesh_dbg_la-adjoint_residual_error_estimator.Plo -rm -f src/error_estimation/$(DEPDIR)/libmesh_dbg_la-discontinuity_measure.Plo From d9a7a5b575adfc8b4953bd2323e5a2d429cedebb Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Fri, 11 Apr 2025 16:35:06 -0600 Subject: [PATCH 07/41] Update StaticCondensation to be a DofMapBase --- include/base/dof_map.h | 37 +--- include/numerics/static_condensation.h | 32 ++- src/numerics/static_condensation.C | 285 ++++++++++++++----------- 3 files changed, 195 insertions(+), 159 deletions(-) diff --git a/include/base/dof_map.h b/include/base/dof_map.h index d70673da30d..72cc4d8cf8b 100644 --- a/include/base/dof_map.h +++ b/include/base/dof_map.h @@ -38,6 +38,7 @@ #include "libmesh/libmesh_logging.h" #include "libmesh/enum_elem_type.h" #include "libmesh/mesh_subdivision_support.h" +#include "libmesh/dof_map_base.h" // TIMPI includes #include "timpi/parallel_implementation.h" @@ -175,7 +176,8 @@ class NodeConstraints : public std::map, +class DofMap : public DofMapBase, + public ReferenceCountedObject, public ParallelObject { public: @@ -594,10 +596,7 @@ class DofMap : public ReferenceCountedObject, */ const VariableGroup & variable_group (const unsigned int c) const; - /** - * \returns The variable description object for variable \p c. - */ - const Variable & variable (const unsigned int c) const; + const Variable & variable (const unsigned int c) const override; /** * \returns The approximation order for variable \p c. @@ -627,12 +626,7 @@ class DofMap : public ReferenceCountedObject, unsigned int n_variable_groups() const { return cast_int(_variable_groups.size()); } - /** - * \returns The number of variables in the global solution vector. Defaults - * to 1, should be 1 for a scalar equation, 3 for 2D incompressible Navier - * Stokes (u,v,p), etc... - */ - unsigned int n_variables() const + unsigned int n_variables() const override { return cast_int(_variables.size()); } /** @@ -726,13 +720,10 @@ class DofMap : public ReferenceCountedObject, return n_local_dofs; } - /** - * \returns The first dof index that is local to partition \p proc. - */ dof_id_type first_dof(const processor_id_type proc) const { libmesh_assert_less (proc, _first_df.size()); return _first_df[proc]; } - dof_id_type first_dof() const + dof_id_type first_dof() const override { return this->first_dof(this->processor_id()); } #ifdef LIBMESH_ENABLE_AMR @@ -747,16 +738,10 @@ class DofMap : public ReferenceCountedObject, #endif //LIBMESH_ENABLE_AMR - /** - * \returns The first dof index that is after all indices local to - * processor \p proc. - * - * Analogous to the end() member function of STL containers. - */ dof_id_type end_dof(const processor_id_type proc) const { libmesh_assert_less (proc, _end_df.size()); return _end_df[proc]; } - dof_id_type end_dof() const + dof_id_type end_dof() const override { return this->end_dof(this->processor_id()); } /** @@ -784,10 +769,6 @@ class DofMap : public ReferenceCountedObject, #endif //LIBMESH_ENABLE_AMR - /** - * Fills the vector \p di with the global degree of freedom indices - * for the element. - */ void dof_indices (const Elem * const elem, std::vector & di) const; @@ -799,7 +780,7 @@ class DofMap : public ReferenceCountedObject, void dof_indices (const Elem * const elem, std::vector & di, const unsigned int vn, - int p_level = -12345) const; + int p_level = -12345) const override; /** * Retrieves degree of freedom indices for a given \p elem and then performs actions for these @@ -851,7 +832,7 @@ class DofMap : public ReferenceCountedObject, */ void dof_indices (const Node * const node, std::vector & di, - const unsigned int vn) const; + const unsigned int vn) const override; /** * Appends to the vector \p di the global degree of freedom indices diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index 63c724c58e2..a2d223a71fe 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -27,6 +27,8 @@ #include "libmesh/id_types.h" #include "libmesh/libmesh_common.h" #include "libmesh/dense_matrix.h" +#include "libmesh/dof_map_base.h" +#include "libmesh/variable.h" #include #include @@ -54,7 +56,7 @@ class StaticCondensationPreconditioner; typedef Eigen::Matrix EigenMatrix; typedef Eigen::Matrix EigenVector; -class StaticCondensation : public PetscMatrixShellMatrix +class StaticCondensation : public PetscMatrixShellMatrix, public DofMapBase { public: StaticCondensation(const MeshBase & mesh, const System & system, const DofMap & dof_map); @@ -180,6 +182,23 @@ class StaticCondensation : public PetscMatrixShellMatrix */ StaticCondensationPreconditioner & get_preconditioner() { return *_scp; } + virtual unsigned int n_variables() const override; + + virtual const Variable & variable(const unsigned int c) const override; + + virtual dof_id_type first_dof() const override { return this->row_start(); } + + virtual dof_id_type end_dof() const override { return this->row_stop(); } + + virtual void dof_indices(const Elem * const elem, + std::vector & di, + const unsigned int vn, + int p_level = -12345) const override; + + virtual void dof_indices(const Node * const node, + std::vector & di, + const unsigned int vn) const override; + private: /** * Retrieves the degree of freedom values from \p global_vector corresponding to \p @@ -227,7 +246,7 @@ class StaticCondensation : public PetscMatrixShellMatrix /// The uncondensed degrees of freedom with global numbering corresponding to the the \emph reduced /// system. Note that initially this will actually hold the indices corresponding to the fully /// sized problem, but we will swap it out by the time we are done initializing - std::vector reduced_space_indices; + std::vector> reduced_space_indices; /// A map from the global degree of freedom number for the full system (condensed + uncondensed) /// to an element local number. If this map is queried with a condensed dof, nothing will be @@ -286,17 +305,18 @@ class StaticCondensation : public PetscMatrixShellMatrix /// Whether we have cached values via add_XXX() bool _have_cached_values; + + /// The variables in the reduced system + std::vector _reduced_vars; }; -inline const SparseMatrix & -StaticCondensation::get_condensed_mat() const +inline const SparseMatrix & StaticCondensation::get_condensed_mat() const { libmesh_assert(_reduced_sys_mat); return *_reduced_sys_mat; } -inline void -StaticCondensation::dont_condense_vars(const std::unordered_set & vars) +inline void StaticCondensation::dont_condense_vars(const std::unordered_set & vars) { _uncondensed_vars.insert(vars.begin(), vars.end()); } diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 250ed185dda..7f2ee737de7 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -51,26 +51,22 @@ StaticCondensation::StaticCondensation(const MeshBase & mesh, StaticCondensation::~StaticCondensation() = default; -SparseMatrix & -StaticCondensation::operator=(const SparseMatrix &) +SparseMatrix & StaticCondensation::operator=(const SparseMatrix &) { libmesh_not_implemented(); } -std::unique_ptr> -StaticCondensation::zero_clone() const +std::unique_ptr> StaticCondensation::zero_clone() const { libmesh_not_implemented(); } -std::unique_ptr> -StaticCondensation::clone() const +std::unique_ptr> StaticCondensation::clone() const { libmesh_not_implemented(); } -void -StaticCondensation::clear() noexcept +void StaticCondensation::clear() noexcept { PetscMatrixShellMatrix::clear(); @@ -85,14 +81,13 @@ StaticCondensation::clear() noexcept _sc_is_initialized = false; } -void -StaticCondensation::init(const numeric_index_type m, - const numeric_index_type n, - const numeric_index_type m_l, - const numeric_index_type n_l, - const numeric_index_type nnz, - const numeric_index_type noz, - const numeric_index_type blocksize) +void StaticCondensation::init(const numeric_index_type m, + const numeric_index_type n, + const numeric_index_type m_l, + const numeric_index_type n_l, + const numeric_index_type nnz, + const numeric_index_type noz, + const numeric_index_type blocksize) { if (!this->initialized()) { @@ -101,8 +96,7 @@ StaticCondensation::init(const numeric_index_type m, } } -void -StaticCondensation::init(const ParallelType type) +void StaticCondensation::init(const ParallelType type) { if (!this->initialized()) { @@ -111,14 +105,12 @@ StaticCondensation::init(const ParallelType type) } } -bool -StaticCondensation::initialized() const +bool StaticCondensation::initialized() const { return PetscMatrixShellMatrix::initialized() && _sc_is_initialized; } -void -StaticCondensation::init() +void StaticCondensation::init() { if (_sc_is_initialized) return; @@ -130,6 +122,7 @@ StaticCondensation::init() dof_id_type condensed_local_dof_number = 0, uncondensed_local_dof_number = 0; std::unordered_map *condensed_global_to_local_map = nullptr, *uncondensed_global_to_local_map = nullptr; + std::set full_vars_present_in_reduced_sys; // Handle SCALAR dofs for (const auto vg : make_range(_dof_map.n_variable_groups())) @@ -225,6 +218,7 @@ StaticCondensation::init() for (const auto v : make_range(var_group.n_variables())) { const auto var_num = var_group.number(v); + local_data.reduced_space_indices.resize(var_num + 1); elem_uncondensed_dofs.clear(); _dof_map.dof_indices(elem, elem_dofs, @@ -232,9 +226,14 @@ StaticCondensation::init() scalar_dofs_functor, field_dofs_functor, elem->p_level()); - local_data.reduced_space_indices.insert(local_data.reduced_space_indices.end(), - elem_uncondensed_dofs.begin(), - elem_uncondensed_dofs.end()); + if (!elem_uncondensed_dofs.empty()) + { + auto & var_reduced_space_indices = local_data.reduced_space_indices[var_num]; + var_reduced_space_indices.insert(var_reduced_space_indices.end(), + elem_uncondensed_dofs.begin(), + elem_uncondensed_dofs.end()); + full_vars_present_in_reduced_sys.insert(var_num); + } } } @@ -338,16 +337,48 @@ StaticCondensation::init() &DofObject::invalid_id); nonlocal_uncondensed_dofs_mapvec.clear(); + // Determine the variables with any degrees of freedom present in the reduced system + _communicator.set_union(full_vars_present_in_reduced_sys); + _reduced_vars.reserve(full_vars_present_in_reduced_sys.size()); + unsigned int first_local_number = 0; + for (const auto i : index_range(full_vars_present_in_reduced_sys)) + { + const auto full_var_num = *std::next(full_vars_present_in_reduced_sys.begin(), i); + const auto & full_var = _dof_map.variable(full_var_num); + _reduced_vars.push_back(Variable{nullptr, + full_var.name(), + cast_int(i), + first_local_number, + full_var.type()}); + first_local_number += _reduced_vars.back().n_components(_mesh); + } + // Now we can finally set our element reduced dof indices - std::vector full_dof_indices; + std::vector var_full_dof_indices; for (auto & [elem, local_data] : _elem_to_local_data) { libmesh_ignore(elem); - full_dof_indices = local_data.reduced_space_indices; - local_data.reduced_space_indices.clear(); - for (const auto full_dof : full_dof_indices) - local_data.reduced_space_indices.push_back( - libmesh_map_find(full_dof_to_reduced_dof, full_dof)); + auto & reduced_space_indices = local_data.reduced_space_indices; + // Start erasing from the back to reduce the number of copy assignment operations + if (reduced_space_indices.size()) + for (typename std::vector::difference_type i = + reduced_space_indices.size() - 1; + i >= 0; + --i) + if (!full_vars_present_in_reduced_sys.count(i)) + reduced_space_indices.erase(reduced_space_indices.begin() + i); + // It is theoretically possible that we have an element that doesn't have dofs for one of the + // variables present in our reduced system, which is why the assertion below is not an + // equality assertion + libmesh_assert(reduced_space_indices.size() <= full_vars_present_in_reduced_sys.size()); + + for (auto & var_dof_indices : reduced_space_indices) + { + var_full_dof_indices = var_dof_indices; + var_dof_indices.clear(); + for (const auto full_dof : var_full_dof_indices) + var_dof_indices.push_back(libmesh_map_find(full_dof_to_reduced_dof, full_dof)); + } } // Build ghosted full solution vector. Note that this is, in general, *not equal* to the system @@ -356,8 +387,7 @@ StaticCondensation::init() _sc_is_initialized = true; } -void -StaticCondensation::close() +void StaticCondensation::close() { _communicator.max(_have_cached_values); if (!_have_cached_values) @@ -370,9 +400,11 @@ StaticCondensation::close() } DenseMatrix shim; + std::vector reduced_space_indices; for (auto & [elem_id, local_data] : _elem_to_local_data) { libmesh_ignore(elem_id); + reduced_space_indices.clear(); local_data.AccFactor = local_data.Acc.partialPivLu(); const EigenMatrix S = local_data.Auu - local_data.Auc * local_data.AccFactor.solve(local_data.Acu); @@ -380,7 +412,11 @@ StaticCondensation::close() for (const auto i : make_range(S.rows())) for (const auto j : make_range(S.cols())) shim(i, j) = S(i, j); - _reduced_sys_mat->add_matrix(shim, local_data.reduced_space_indices); + for (const auto & var_reduced_space_indices : local_data.reduced_space_indices) + reduced_space_indices.insert(reduced_space_indices.end(), + var_reduced_space_indices.begin(), + var_reduced_space_indices.end()); + _reduced_sys_mat->add_matrix(shim, reduced_space_indices); } _reduced_sys_mat->close(); @@ -388,14 +424,12 @@ StaticCondensation::close() _have_cached_values = false; } -bool -StaticCondensation::closed() const +bool StaticCondensation::closed() const { return _reduced_sys_mat->closed() && !_have_cached_values; } -void -StaticCondensation::zero() +void StaticCondensation::zero() { _reduced_sys_mat->zero(); for (auto & [elem_id, local_data] : _elem_to_local_data) @@ -408,66 +442,70 @@ StaticCondensation::zero() } } -void -StaticCondensation::setup() -{ - libmesh_assert(this->closed()); -} +void StaticCondensation::setup() { libmesh_assert(this->closed()); } -numeric_index_type -StaticCondensation::m() const -{ - return _dof_map.n_dofs(); -} +numeric_index_type StaticCondensation::m() const { return _dof_map.n_dofs(); } -numeric_index_type -StaticCondensation::row_start() const -{ - return _dof_map.first_dof(); -} +numeric_index_type StaticCondensation::row_start() const { return _dof_map.first_dof(); } -numeric_index_type -StaticCondensation::row_stop() const -{ - return _dof_map.end_dof(); -} +numeric_index_type StaticCondensation::row_stop() const { return _dof_map.end_dof(); } -void -StaticCondensation::set(const numeric_index_type, const numeric_index_type, const Number) +void StaticCondensation::set(const numeric_index_type, const numeric_index_type, const Number) { libmesh_not_implemented(); } -void -StaticCondensation::set_current_elem(const Elem & elem) +void StaticCondensation::set_current_elem(const Elem & elem) { libmesh_assert(!Threads::in_threads || libMesh::n_threads() == 1); _current_elem_id = elem.id(); } -void -StaticCondensation::add(const numeric_index_type i, const numeric_index_type j, const Number value) +void StaticCondensation::add(const numeric_index_type i, + const numeric_index_type j, + const Number value) { _size_one_mat(0, 0) = value; this->add_matrix(_size_one_mat, {i}, {j}); } -void -StaticCondensation::add_matrix(const DenseMatrix & dm, - const std::vector & rows, - const std::vector & cols) +void StaticCondensation::add_matrix(const DenseMatrix & dm, + const std::vector & rows, + const std::vector & cols) { libmesh_assert(_current_elem_id != DofObject::invalid_id); auto & local_data = libmesh_map_find(_elem_to_local_data, _current_elem_id); EigenMatrix * mat; - - auto info_from_index = [&local_data](const auto global_index) { +#ifdef DEBUG + std::vector local_to_global_reduced_indices; + for (const auto & var_reduced_space_indices : local_data.reduced_space_indices) + local_to_global_reduced_indices.insert(local_to_global_reduced_indices.end(), + var_reduced_space_indices.begin(), + var_reduced_space_indices.end()); +#endif + + auto info_from_index = [&local_data +#ifdef DEBUG + , + &local_to_global_reduced_indices, + this +#endif + ](const auto global_index) { auto index_it = local_data.condensed_global_to_local_map.find(global_index); const bool index_is_condensed = index_it != local_data.condensed_global_to_local_map.end(); if (!index_is_condensed) { index_it = local_data.uncondensed_global_to_local_map.find(global_index); libmesh_assert(index_it != local_data.uncondensed_global_to_local_map.end()); +#ifdef DEBUG + const auto element_local_dof = index_it->second; + const auto reduced_space_global_index = local_to_global_reduced_indices[element_local_dof]; + const auto process_local_reduced_space_index = + cast_int(reduced_space_global_index - this->row_start()); + const auto unreduced_space_global_index = + _local_uncondensed_dofs[process_local_reduced_space_index]; + libmesh_assert(unreduced_space_global_index == global_index); +#endif } return std::make_pair(index_is_condensed, index_it->second); }; @@ -499,68 +537,43 @@ StaticCondensation::add_matrix(const DenseMatrix & dm, _have_cached_values = true; } -void -StaticCondensation::add_matrix(const DenseMatrix & dm, - const std::vector & dof_indices) +void StaticCondensation::add_matrix(const DenseMatrix & dm, + const std::vector & dof_indices) { this->add_matrix(dm, dof_indices, dof_indices); } -void -StaticCondensation::add(const Number, const SparseMatrix &) +void StaticCondensation::add(const Number, const SparseMatrix &) { libmesh_not_implemented(); } -Number -StaticCondensation::operator()(const numeric_index_type, const numeric_index_type) const +Number StaticCondensation::operator()(const numeric_index_type, const numeric_index_type) const { libmesh_not_implemented(); } -Real -StaticCondensation::l1_norm() const -{ - libmesh_not_implemented(); -} +Real StaticCondensation::l1_norm() const { libmesh_not_implemented(); } -Real -StaticCondensation::linfty_norm() const -{ - libmesh_not_implemented(); -} +Real StaticCondensation::linfty_norm() const { libmesh_not_implemented(); } -void -StaticCondensation::print_personal(std::ostream &) const -{ - libmesh_not_implemented(); -} +void StaticCondensation::print_personal(std::ostream &) const { libmesh_not_implemented(); } -void -StaticCondensation::get_diagonal(NumericVector &) const -{ - libmesh_not_implemented(); -} +void StaticCondensation::get_diagonal(NumericVector &) const { libmesh_not_implemented(); } -void -StaticCondensation::get_transpose(SparseMatrix &) const -{ - libmesh_not_implemented(); -} +void StaticCondensation::get_transpose(SparseMatrix &) const { libmesh_not_implemented(); } -void -StaticCondensation::get_row(numeric_index_type, - std::vector &, - std::vector &) const +void StaticCondensation::get_row(numeric_index_type, + std::vector &, + std::vector &) const { libmesh_not_implemented(); } -void -StaticCondensation::set_local_vectors(const NumericVector & global_vector, - const std::vector & elem_dof_indices, - std::vector & elem_dof_values_vec, - EigenVector & elem_dof_values) +void StaticCondensation::set_local_vectors(const NumericVector & global_vector, + const std::vector & elem_dof_indices, + std::vector & elem_dof_values_vec, + EigenVector & elem_dof_values) { global_vector.get(elem_dof_indices, elem_dof_values_vec); elem_dof_values.resize(elem_dof_indices.size()); @@ -568,8 +581,7 @@ StaticCondensation::set_local_vectors(const NumericVector & global_vecto elem_dof_values(i) = elem_dof_values_vec[i]; } -void -StaticCondensation::forward_elimination(const NumericVector & full_rhs) +void StaticCondensation::forward_elimination(const NumericVector & full_rhs) { std::vector elem_condensed_dofs; std::vector elem_condensed_rhs_vec; @@ -577,9 +589,15 @@ StaticCondensation::forward_elimination(const NumericVector & full_rhs) full_rhs.create_subvector(*_reduced_rhs, _local_uncondensed_dofs, /*all_global_entries=*/false); + std::vector reduced_space_indices; for (auto elem : _mesh.active_local_element_ptr_range()) { - auto & local_data = _elem_to_local_data[elem->id()]; + auto & local_data = libmesh_map_find(_elem_to_local_data, elem->id()); + reduced_space_indices.clear(); + for (const auto & var_reduced_space_indices : local_data.reduced_space_indices) + reduced_space_indices.insert(reduced_space_indices.end(), + var_reduced_space_indices.begin(), + var_reduced_space_indices.end()); elem_condensed_dofs.resize(local_data.condensed_global_to_local_map.size()); for (const auto & [global_dof, local_dof] : local_data.condensed_global_to_local_map) { @@ -591,15 +609,14 @@ StaticCondensation::forward_elimination(const NumericVector & full_rhs) elem_uncondensed_rhs = -local_data.Auc * local_data.AccFactor.solve(elem_condensed_rhs); libmesh_assert(cast_int(elem_uncondensed_rhs.size()) == - local_data.reduced_space_indices.size()); - _reduced_rhs->add_vector(elem_uncondensed_rhs.data(), local_data.reduced_space_indices); + reduced_space_indices.size()); + _reduced_rhs->add_vector(elem_uncondensed_rhs.data(), reduced_space_indices); } _reduced_rhs->close(); } -void -StaticCondensation::backwards_substitution(const NumericVector & full_rhs, - NumericVector & full_sol) +void StaticCondensation::backwards_substitution(const NumericVector & full_rhs, + NumericVector & full_sol) { std::vector elem_condensed_dofs, elem_uncondensed_dofs; std::vector elem_condensed_rhs_vec, elem_uncondensed_sol_vec; @@ -635,9 +652,8 @@ StaticCondensation::backwards_substitution(const NumericVector & full_rh full_sol.close(); } -void -StaticCondensation::apply(const NumericVector & full_rhs, - NumericVector & full_parallel_sol) +void StaticCondensation::apply(const NumericVector & full_rhs, + NumericVector & full_parallel_sol) { forward_elimination(full_rhs); // Apparently PETSc will send us the yvec without zeroing it ahead of time. This can be a poor @@ -653,14 +669,33 @@ StaticCondensation::apply(const NumericVector & full_rhs, backwards_substitution(full_rhs, full_parallel_sol); } -SolverPackage -StaticCondensation::solver_package() +SolverPackage StaticCondensation::solver_package() { return libMesh::default_solver_package(); } + +unsigned int StaticCondensation::n_variables() const { return _reduced_vars.size(); } + +const Variable & StaticCondensation::variable(const unsigned int c) const { - return libMesh::default_solver_package(); + return _reduced_vars[c]; } +void StaticCondensation::dof_indices(const Elem * const elem, + std::vector & di, + const unsigned int vn, + int /*p_level*/) const +{ + di.clear(); + di = libmesh_map_find(_elem_to_local_data, elem->id()).reduced_space_indices[vn]; } +void StaticCondensation::dof_indices(const Node * const, + std::vector &, + const unsigned int) const +{ + libmesh_error_msg( + "StaticCondensation dof indices are only meant to be queried with elements, not nodes"); +} + +} #else #include "libmesh/dof_map.h" From 3bf0f21c6954ca8d080dbf3640e54d11826bd578 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Fri, 11 Apr 2025 17:43:06 -0600 Subject: [PATCH 08/41] Add compile_commands to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 50e5a2f7cae..3a530685080 100644 --- a/.gitignore +++ b/.gitignore @@ -239,3 +239,4 @@ installed # VSCode related things .cache .vscode +compile_commands.json From f60ec04988f46c4ba3e8aa2706759bbc9b0667a5 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Fri, 11 Apr 2025 22:31:29 -0600 Subject: [PATCH 09/41] Remove bad debug check --- src/numerics/static_condensation.C | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 7f2ee737de7..dd664dffdf1 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -476,36 +476,14 @@ void StaticCondensation::add_matrix(const DenseMatrix & dm, libmesh_assert(_current_elem_id != DofObject::invalid_id); auto & local_data = libmesh_map_find(_elem_to_local_data, _current_elem_id); EigenMatrix * mat; -#ifdef DEBUG - std::vector local_to_global_reduced_indices; - for (const auto & var_reduced_space_indices : local_data.reduced_space_indices) - local_to_global_reduced_indices.insert(local_to_global_reduced_indices.end(), - var_reduced_space_indices.begin(), - var_reduced_space_indices.end()); -#endif - - auto info_from_index = [&local_data -#ifdef DEBUG - , - &local_to_global_reduced_indices, - this -#endif - ](const auto global_index) { + + auto info_from_index = [&local_data](const auto global_index) { auto index_it = local_data.condensed_global_to_local_map.find(global_index); const bool index_is_condensed = index_it != local_data.condensed_global_to_local_map.end(); if (!index_is_condensed) { index_it = local_data.uncondensed_global_to_local_map.find(global_index); libmesh_assert(index_it != local_data.uncondensed_global_to_local_map.end()); -#ifdef DEBUG - const auto element_local_dof = index_it->second; - const auto reduced_space_global_index = local_to_global_reduced_indices[element_local_dof]; - const auto process_local_reduced_space_index = - cast_int(reduced_space_global_index - this->row_start()); - const auto unreduced_space_global_index = - _local_uncondensed_dofs[process_local_reduced_space_index]; - libmesh_assert(unreduced_space_global_index == global_index); -#endif } return std::make_pair(index_is_condensed, index_it->second); }; From bbbe5ee8dc53c6b41ff25323d5f91edeed36a421 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 17 Apr 2025 20:15:18 -0700 Subject: [PATCH 10/41] Add reduced_system_solver API to StaticCondensation --- include/numerics/static_condensation.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index a2d223a71fe..6977fec982e 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -199,6 +199,11 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB std::vector & di, const unsigned int vn) const override; + /** + * @returns The reduced system linear solver + */ + LinearSolver & reduced_system_solver(); + private: /** * Retrieves the degree of freedom values from \p global_vector corresponding to \p @@ -321,6 +326,12 @@ inline void StaticCondensation::dont_condense_vars(const std::unordered_set & StaticCondensation::reduced_system_solver() +{ + libmesh_assert_msg(_reduced_solver, "Reduced system solver not built yet"); + return *_reduced_solver; +} + } #else From dea0ab49c5f1041e9bc11207f1684a4b5a7736e0 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Tue, 22 Apr 2025 17:52:27 -0600 Subject: [PATCH 11/41] More DofMapBase APIs Also, set n components to 0 for DofObjects for the reduced "system" --- include/base/dof_map.h | 10 ++-------- include/base/dof_map_base.h | 9 +++++++++ include/numerics/static_condensation.h | 27 ++++++++++++++++++++------ src/numerics/static_condensation.C | 26 +++++++++++++++++++++++-- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/include/base/dof_map.h b/include/base/dof_map.h index 72cc4d8cf8b..05d7bfc0d5f 100644 --- a/include/base/dof_map.h +++ b/include/base/dof_map.h @@ -661,10 +661,7 @@ class DofMap : public DofMapBase, return (this->has_blocked_representation() ? this->n_variables() : 1); } - /** - * \returns The total number of degrees of freedom in the problem. - */ - dof_id_type n_dofs() const { return _n_dfs; } + dof_id_type n_dofs() const override { return _n_dfs; } /** * \returns The total number of degrees of freedom for a particular @@ -682,10 +679,7 @@ class DofMap : public DofMapBase, */ dof_id_type n_SCALAR_dofs() const { return _n_SCALAR_dofs; } - /** - * \returns The number of degrees of freedom on this processor. - */ - dof_id_type n_local_dofs () const + dof_id_type n_local_dofs () const override { return this->n_dofs_on_processor (this->processor_id()); } /** diff --git a/include/base/dof_map_base.h b/include/base/dof_map_base.h index f59a07d3e7e..cf10a5df0bd 100644 --- a/include/base/dof_map_base.h +++ b/include/base/dof_map_base.h @@ -74,6 +74,15 @@ class DofMapBase virtual void dof_indices(const Node * const node, std::vector & di, const unsigned int vn) const = 0; + /** + * \returns The total number of degrees of freedom in the problem. + */ + virtual dof_id_type n_dofs() const = 0; + + /** + * \returns The number of degrees of freedom on this processor. + */ + virtual dof_id_type n_local_dofs() const = 0; }; } diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index 6977fec982e..1c3263c10c8 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -59,7 +59,7 @@ typedef Eigen::Matrix EigenVector; class StaticCondensation : public PetscMatrixShellMatrix, public DofMapBase { public: - StaticCondensation(const MeshBase & mesh, const System & system, const DofMap & dof_map); + StaticCondensation(const MeshBase & mesh, System & system, const DofMap & dof_map); virtual ~StaticCondensation(); // @@ -186,10 +186,6 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB virtual const Variable & variable(const unsigned int c) const override; - virtual dof_id_type first_dof() const override { return this->row_start(); } - - virtual dof_id_type end_dof() const override { return this->row_stop(); } - virtual void dof_indices(const Elem * const elem, std::vector & di, const unsigned int vn, @@ -199,11 +195,21 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB std::vector & di, const unsigned int vn) const override; + virtual dof_id_type first_dof() const override; + virtual dof_id_type end_dof() const override; + virtual dof_id_type n_dofs() const override; + virtual dof_id_type n_local_dofs() const override; + /** * @returns The reduced system linear solver */ LinearSolver & reduced_system_solver(); + /* + * @returns The dummyish reduced system + */ + const System & reduced_system() const; + private: /** * Retrieves the degree of freedom values from \p global_vector corresponding to \p @@ -274,7 +280,7 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB std::vector _local_uncondensed_dofs; const MeshBase & _mesh; - const System & _system; + System & _system; const DofMap & _dof_map; /// global sparse matrix for the uncondensed degrees of freedom @@ -313,6 +319,9 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB /// The variables in the reduced system std::vector _reduced_vars; + + /// A dummyish system to help with DofObjects + System * _reduced_system; }; inline const SparseMatrix & StaticCondensation::get_condensed_mat() const @@ -332,6 +341,12 @@ inline LinearSolver & StaticCondensation::reduced_system_solver() return *_reduced_solver; } +inline const System & StaticCondensation::reduced_system() const +{ + libmesh_assert(_reduced_system); + return *_reduced_system; +} + } #else diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index dd664dffdf1..1c5778d6629 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -24,18 +24,18 @@ #include "libmesh/elem.h" #include "libmesh/int_range.h" #include "libmesh/numeric_vector.h" -#include "libmesh/petsc_matrix_base.h" #include "libmesh/linear_solver.h" #include "libmesh/static_condensation_preconditioner.h" #include "libmesh/system.h" #include "libmesh/petsc_matrix.h" +#include "libmesh/equation_systems.h" #include "timpi/parallel_sync.h" #include namespace libMesh { StaticCondensation::StaticCondensation(const MeshBase & mesh, - const System & system, + System & system, const DofMap & dof_map) : PetscMatrixShellMatrix(dof_map.comm()), _mesh(mesh), @@ -384,6 +384,20 @@ void StaticCondensation::init() // Build ghosted full solution vector. Note that this is, in general, *not equal* to the system // solution, e.g. this may correspond to the solution for the Newton *update* _ghosted_full_sol = _system.current_local_solution->clone(); + + // Prevent querying Nodes for dof indices + std::vector nvpg(_reduced_vars.size()); + for (auto & elem : nvpg) + elem = 1; + + _reduced_system = &_system.get_equation_systems().add_system("Basic", "reduced"); + _reduced_system->init(); + for (auto * const nd : _mesh.active_node_ptr_range()) + { + nd->set_n_vars_per_group(_reduced_system->number(), nvpg); + for (const auto g : index_range(nvpg)) + nd->set_n_comp_group(_reduced_system->number(), g, 0); + } _sc_is_initialized = true; } @@ -673,6 +687,14 @@ void StaticCondensation::dof_indices(const Node * const, "StaticCondensation dof indices are only meant to be queried with elements, not nodes"); } +dof_id_type StaticCondensation::first_dof() const { return _reduced_sys_mat->row_start(); } + +dof_id_type StaticCondensation::end_dof() const { return _reduced_sys_mat->row_stop(); } + +dof_id_type StaticCondensation::n_dofs() const { return _reduced_sys_mat->m(); } + +dof_id_type StaticCondensation::n_local_dofs() const { return _reduced_sys_mat->local_m(); } + } #else From 96825b0cc2bd4525b1e8e57aa2a0ab086f395e2e Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Wed, 23 Apr 2025 16:32:34 -0600 Subject: [PATCH 12/41] explain interaction between static condensation and sparsity pattern --- src/base/sparsity_pattern.C | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/base/sparsity_pattern.C b/src/base/sparsity_pattern.C index 2748d192e37..17229e583e9 100644 --- a/src/base/sparsity_pattern.C +++ b/src/base/sparsity_pattern.C @@ -96,6 +96,10 @@ void Build::sorted_connected_dofs(const Elem * elem, { if (dof_map.has_static_condensation()) { + // We build a sparsity pattern that will match the size of the condensed system. This is so that + // we have the data necessary to init the reduced system matrix because that's the only matrix + // we will have in our system...unless users have auxiliary matrices that are of the full system + // size... const auto & sc = dof_map.get_static_condensation(); dofs_vi.clear(); From dc30abff257f2878263c67cc1ff8fc3d2acc90be Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Wed, 23 Apr 2025 17:49:28 -0600 Subject: [PATCH 13/41] Allow building both full and reduced sparsity pattern --- include/base/dof_map.h | 3 ++- include/base/sparsity_pattern.h | 5 ++++- include/numerics/petsc_matrix_shell_matrix.h | 2 ++ include/numerics/sparse_matrix.h | 5 +++++ include/numerics/static_condensation.h | 6 ++++++ src/base/dof_map.C | 13 +++++++++++-- src/base/sparsity_pattern.C | 16 ++++++++-------- src/numerics/static_condensation.C | 4 ++++ src/systems/system.C | 3 ++- 9 files changed, 44 insertions(+), 13 deletions(-) diff --git a/include/base/dof_map.h b/include/base/dof_map.h index 05d7bfc0d5f..05e9709dca9 100644 --- a/include/base/dof_map.h +++ b/include/base/dof_map.h @@ -1677,7 +1677,8 @@ class DofMap : public DofMapBase, * constraints or sufficiently many user constraints. */ std::unique_ptr build_sparsity(const MeshBase & mesh, - bool calculate_constrained = false) const; + bool calculate_constrained = false, + bool use_condensed_system = false) const; /** * Describe whether the given variable group should be p-refined. If this API is not called with diff --git a/include/base/sparsity_pattern.h b/include/base/sparsity_pattern.h index 35142953778..61a11fc1ff3 100644 --- a/include/base/sparsity_pattern.h +++ b/include/base/sparsity_pattern.h @@ -35,6 +35,7 @@ namespace libMesh // Forward declarations class DofMap; class CouplingMatrix; +class StaticCondensation; /** * This defines the sparsity pattern, or graph, of a sparse matrix. @@ -107,7 +108,8 @@ class Build : public ParallelObject const std::set & coupling_functors_in, const bool implicit_neighbor_dofs_in, const bool need_full_sparsity_pattern_in, - const bool calculate_constrained_in = false); + const bool calculate_constrained_in = false, + const StaticCondensation * sc = nullptr); /** * Special functions. @@ -210,6 +212,7 @@ class Build : public ParallelObject const bool implicit_neighbor_dofs; const bool need_full_sparsity_pattern; const bool calculate_constrained; + const StaticCondensation * const sc; /** * If there are "spider" nodes in the mesh (i.e. a single node which diff --git a/include/numerics/petsc_matrix_shell_matrix.h b/include/numerics/petsc_matrix_shell_matrix.h index 795fa9af0d2..a1f4870cd92 100644 --- a/include/numerics/petsc_matrix_shell_matrix.h +++ b/include/numerics/petsc_matrix_shell_matrix.h @@ -56,6 +56,8 @@ class PetscMatrixShellMatrix : public PetscMatrixBase virtual SparseMatrix & operator=(const SparseMatrix &) override; + virtual bool require_sparsity_pattern() const override { return false; } + private: // Make this private because we mark as initialized after we've done our initialization, and we // don't want derived classes to mistakenly register their data as initialized (or not) diff --git a/include/numerics/sparse_matrix.h b/include/numerics/sparse_matrix.h index 44a92f0bb0b..753b82deea6 100644 --- a/include/numerics/sparse_matrix.h +++ b/include/numerics/sparse_matrix.h @@ -162,6 +162,11 @@ class SparseMatrix : public ReferenceCountedObject>, virtual bool need_full_sparsity_pattern() const { return false; } + /** + * @returns Whether this matrix needs the sparsity pattern computed by the \p DofMap + */ + virtual bool require_sparsity_pattern() const { return !this->use_hash_table(); } + /** * Updates the matrix sparsity pattern. When your \p SparseMatrix * implementation does not need this data, simply do not override diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index 1c3263c10c8..2c781bd0d73 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -29,6 +29,7 @@ #include "libmesh/dense_matrix.h" #include "libmesh/dof_map_base.h" #include "libmesh/variable.h" +#include "libmesh/sparsity_pattern.h" #include #include @@ -210,6 +211,8 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB */ const System & reduced_system() const; + virtual bool require_sparsity_pattern() const override { return false; } + private: /** * Retrieves the degree of freedom values from \p global_vector corresponding to \p @@ -322,6 +325,9 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB /// A dummyish system to help with DofObjects System * _reduced_system; + + /// Owned storage of the reduced system sparsity pattern. Note that the \p SparseMatrix \p _sp data member is set to point to this + std::unique_ptr _reduced_sp; }; inline const SparseMatrix & StaticCondensation::get_condensed_mat() const diff --git a/src/base/dof_map.C b/src/base/dof_map.C index b369976c693..0ddb20e0c4a 100644 --- a/src/base/dof_map.C +++ b/src/base/dof_map.C @@ -59,7 +59,8 @@ namespace libMesh // DofMap member functions std::unique_ptr DofMap::build_sparsity (const MeshBase & mesh, - const bool calculate_constrained) const + const bool calculate_constrained, + const bool use_condensed_system) const { libmesh_assert (mesh.is_prepared()); @@ -78,6 +79,13 @@ DofMap::build_sparsity (const MeshBase & mesh, // between neighbor dofs bool implicit_neighbor_dofs = this->use_coupled_neighbor_dofs(mesh); + const StaticCondensation * sc = nullptr; + if (use_condensed_system) + { + libmesh_assert(this->has_static_condensation()); + sc = &this->get_static_condensation(); + } + // We can compute the sparsity pattern in parallel on multiple // threads. The goal is for each thread to compute the full sparsity // pattern for a subset of elements. These sparsity patterns can @@ -92,7 +100,8 @@ DofMap::build_sparsity (const MeshBase & mesh, this->_coupling_functors, implicit_neighbor_dofs, need_full_sparsity_pattern, - calculate_constrained); + calculate_constrained, + sc); Threads::parallel_reduce (ConstElemRange (mesh.active_local_elements_begin(), mesh.active_local_elements_end()), *sp); diff --git a/src/base/sparsity_pattern.C b/src/base/sparsity_pattern.C index 17229e583e9..437da705000 100644 --- a/src/base/sparsity_pattern.C +++ b/src/base/sparsity_pattern.C @@ -49,7 +49,8 @@ Build::Build (const DofMap & dof_map_in, const std::set & coupling_functors_in, const bool implicit_neighbor_dofs_in, const bool need_full_sparsity_pattern_in, - const bool calculate_constrained_in) : + const bool calculate_constrained_in, + const StaticCondensation * const sc_in) : ParallelObject(dof_map_in), dof_map(dof_map_in), dof_coupling(dof_coupling_in), @@ -57,6 +58,7 @@ Build::Build (const DofMap & dof_map_in, implicit_neighbor_dofs(implicit_neighbor_dofs_in), need_full_sparsity_pattern(need_full_sparsity_pattern_in), calculate_constrained(calculate_constrained_in), + sc(sc_in), sparsity_pattern(), nonlocal_pattern(), n_nz(), @@ -73,6 +75,7 @@ Build::Build (Build & other, Threads::split) : implicit_neighbor_dofs(other.implicit_neighbor_dofs), need_full_sparsity_pattern(other.need_full_sparsity_pattern), calculate_constrained(other.calculate_constrained), + sc(other.sc), hashed_dof_sets(other.hashed_dof_sets), sparsity_pattern(), nonlocal_pattern(), @@ -94,13 +97,10 @@ void Build::sorted_connected_dofs(const Elem * elem, std::vector & dofs_vi, unsigned int vi) { - if (dof_map.has_static_condensation()) + if (this->sc) { // We build a sparsity pattern that will match the size of the condensed system. This is so that - // we have the data necessary to init the reduced system matrix because that's the only matrix - // we will have in our system...unless users have auxiliary matrices that are of the full system - // size... - const auto & sc = dof_map.get_static_condensation(); + // we have the data necessary to init the reduced system matrix dofs_vi.clear(); auto total_and_uncondensed_from_scalar_dofs_functor = @@ -113,14 +113,14 @@ void Build::sorted_connected_dofs(const Elem * elem, }; auto total_and_uncondensed_from_field_dofs_functor = - [&dofs_vi, &sc](const Elem & functor_elem, + [&dofs_vi, this](const Elem & functor_elem, const unsigned int node_num, const unsigned int var_num, std::vector & dof_indices, const dof_id_type field_dof) { dof_indices.push_back(field_dof); - if (sc.uncondensed_vars().count(var_num) || + if (this->sc->uncondensed_vars().count(var_num) || (node_num != invalid_uint && !functor_elem.is_internal(node_num))) dofs_vi.push_back(field_dof); }; diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 1c5778d6629..b80f447a485 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -269,6 +269,10 @@ void StaticCondensation::init() for (const auto i : index_range(_local_uncondensed_dofs)) full_dof_to_reduced_dof[_local_uncondensed_dofs[i]] = i + local_start; + // Build the condensed system sparsity pattern + _reduced_sp = this->_dof_map.build_sparsity( + this->_mesh, /*calculate_constrained=*/false, /*use_condensed_system=*/true); + _sp = _reduced_sp.get(); _reduced_sys_mat = SparseMatrix::build(this->comm()); const auto & nnz = _sp->get_n_nz(); const auto & noz = _sp->get_n_oz(); diff --git a/src/systems/system.C b/src/systems/system.C index bea958ac373..fbb40885876 100644 --- a/src/systems/system.C +++ b/src/systems/system.C @@ -354,7 +354,8 @@ void System::init_matrices () pr.second->use_hash_table() || (this->_prefer_hash_table_matrix_assembly && pr.second->supports_hash_table()); pr.second->use_hash_table(use_hash); - if (!use_hash) + // Make this call after we've determined whether the matrix is using a hash table + if (pr.second->require_sparsity_pattern()) this->_require_sparsity_pattern = true; } From cf6595949103f04a6b4f69489c9e2e2ea8591f51 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Tue, 29 Apr 2025 16:51:44 -0600 Subject: [PATCH 14/41] Add two argument overload of local_variable_indices --- include/base/dof_map.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/base/dof_map.h b/include/base/dof_map.h index 05e9709dca9..acb35584d2a 100644 --- a/include/base/dof_map.h +++ b/include/base/dof_map.h @@ -947,6 +947,18 @@ class DofMap : public DofMapBase, const MeshBase & mesh, unsigned int var_num) const; + /** + * If T == dof_id_type, counts, if T == std::vector, fills an + * array of, those dof indices which belong to the given variable number and + * live on the current processor. + */ + template || + std::is_same_v>, + int> = 0> + void local_variable_indices(T & idx, unsigned int var_num) const + { this->local_variable_indices(idx, this->_mesh, var_num); } + #ifdef LIBMESH_ENABLE_CONSTRAINTS //-------------------------------------------------------------------- From 6519f8c1365753833931aaa7e7ae9d7ea387a9f7 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Wed, 30 Apr 2025 09:54:14 -0600 Subject: [PATCH 15/41] Update Makefile.am files --- include/include_HEADERS | 1 + include/libmesh/Makefile.am | 4 ++++ src/libmesh_SOURCES | 2 ++ 3 files changed, 7 insertions(+) diff --git a/include/include_HEADERS b/include/include_HEADERS index 7b1520d43fb..d7eb038aded 100644 --- a/include/include_HEADERS +++ b/include/include_HEADERS @@ -288,6 +288,7 @@ include_HEADERS = \ numerics/sparse_matrix.h \ numerics/sparse_shell_matrix.h \ numerics/static_condensation.h \ + numerics/static_condensation_dof_map.h \ numerics/static_condensation_preconditioner.h \ numerics/sum_shell_matrix.h \ numerics/tensor_shell_matrix.h \ diff --git a/include/libmesh/Makefile.am b/include/libmesh/Makefile.am index a5d9166efb9..846dc4dad76 100644 --- a/include/libmesh/Makefile.am +++ b/include/libmesh/Makefile.am @@ -281,6 +281,7 @@ BUILT_SOURCES = \ sparse_matrix.h \ sparse_shell_matrix.h \ static_condensation.h \ + static_condensation_dof_map.h \ static_condensation_preconditioner.h \ sum_shell_matrix.h \ tensor_shell_matrix.h \ @@ -1439,6 +1440,9 @@ sparse_shell_matrix.h: $(top_srcdir)/include/numerics/sparse_shell_matrix.h static_condensation.h: $(top_srcdir)/include/numerics/static_condensation.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ +static_condensation_dof_map.h: $(top_srcdir)/include/numerics/static_condensation_dof_map.h + $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ + static_condensation_preconditioner.h: $(top_srcdir)/include/numerics/static_condensation_preconditioner.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ diff --git a/src/libmesh_SOURCES b/src/libmesh_SOURCES index 90a568b81f0..ad9c50bc0cc 100644 --- a/src/libmesh_SOURCES +++ b/src/libmesh_SOURCES @@ -2,6 +2,7 @@ libmesh_SOURCES = \ src/base/dirichlet_boundary.C \ src/base/dof_map.C \ + src/base/dof_map_base.C \ src/base/dof_map_constraints.C \ src/base/dof_object.C \ src/base/libmesh.C \ @@ -282,6 +283,7 @@ libmesh_SOURCES = \ src/numerics/sparse_matrix.C \ src/numerics/sparse_shell_matrix.C \ src/numerics/static_condensation.C \ + src/numerics/static_condensation_dof_map.C \ src/numerics/sum_shell_matrix.C \ src/numerics/tensor_shell_matrix.C \ src/numerics/tensor_tools.C \ From e2929c14e13ed88464edd27c68563e81a76598ad Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Wed, 30 Apr 2025 09:55:03 -0600 Subject: [PATCH 16/41] Run bootstrap --- Makefile.in | 217 +++++++++++++++++++++++++++++++----- include/Makefile.in | 1 + include/libmesh/Makefile.in | 42 +++---- 3 files changed, 211 insertions(+), 49 deletions(-) diff --git a/Makefile.in b/Makefile.in index 611e3ca0dca..cee5af73b7f 100644 --- a/Makefile.in +++ b/Makefile.in @@ -267,12 +267,13 @@ am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) @LIBMESH_DBG_MODE_TRUE@ contrib/libcontrib_dbg.la \ @LIBMESH_DBG_MODE_TRUE@ $(am__DEPENDENCIES_2) am__libmesh_dbg_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ - src/base/dof_map.C src/base/dof_map_constraints.C \ - src/base/dof_object.C src/base/libmesh.C \ - src/base/libmesh_common.C src/base/libmesh_singleton.C \ - src/base/libmesh_version.C src/base/periodic_boundaries.C \ - src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ - src/base/print_trace.C src/base/reference_counted_object.C \ + src/base/dof_map.C src/base/dof_map_base.C \ + src/base/dof_map_constraints.C src/base/dof_object.C \ + src/base/libmesh.C src/base/libmesh_common.C \ + src/base/libmesh_singleton.C src/base/libmesh_version.C \ + src/base/periodic_boundaries.C src/base/periodic_boundary.C \ + src/base/periodic_boundary_base.C src/base/print_trace.C \ + src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ @@ -428,6 +429,7 @@ am__libmesh_dbg_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/numerics/sparse_matrix.C \ src/numerics/sparse_shell_matrix.C \ src/numerics/static_condensation.C \ + src/numerics/static_condensation_dof_map.C \ src/numerics/sum_shell_matrix.C \ src/numerics/tensor_shell_matrix.C src/numerics/tensor_tools.C \ src/numerics/trilinos_epetra_matrix.C \ @@ -586,6 +588,7 @@ am__libmesh_dbg_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ am__dirstamp = $(am__leading_dot)dirstamp am__objects_1 = src/base/libmesh_dbg_la-dirichlet_boundary.lo \ src/base/libmesh_dbg_la-dof_map.lo \ + src/base/libmesh_dbg_la-dof_map_base.lo \ src/base/libmesh_dbg_la-dof_map_constraints.lo \ src/base/libmesh_dbg_la-dof_object.lo \ src/base/libmesh_dbg_la-libmesh.lo \ @@ -865,6 +868,7 @@ am__objects_1 = src/base/libmesh_dbg_la-dirichlet_boundary.lo \ src/numerics/libmesh_dbg_la-sparse_matrix.lo \ src/numerics/libmesh_dbg_la-sparse_shell_matrix.lo \ src/numerics/libmesh_dbg_la-static_condensation.lo \ + src/numerics/libmesh_dbg_la-static_condensation_dof_map.lo \ src/numerics/libmesh_dbg_la-sum_shell_matrix.lo \ src/numerics/libmesh_dbg_la-tensor_shell_matrix.lo \ src/numerics/libmesh_dbg_la-tensor_tools.lo \ @@ -1068,12 +1072,13 @@ libmesh_dbg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ @LIBMESH_DEVEL_MODE_TRUE@ contrib/libcontrib_devel.la \ @LIBMESH_DEVEL_MODE_TRUE@ $(am__DEPENDENCIES_2) am__libmesh_devel_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ - src/base/dof_map.C src/base/dof_map_constraints.C \ - src/base/dof_object.C src/base/libmesh.C \ - src/base/libmesh_common.C src/base/libmesh_singleton.C \ - src/base/libmesh_version.C src/base/periodic_boundaries.C \ - src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ - src/base/print_trace.C src/base/reference_counted_object.C \ + src/base/dof_map.C src/base/dof_map_base.C \ + src/base/dof_map_constraints.C src/base/dof_object.C \ + src/base/libmesh.C src/base/libmesh_common.C \ + src/base/libmesh_singleton.C src/base/libmesh_version.C \ + src/base/periodic_boundaries.C src/base/periodic_boundary.C \ + src/base/periodic_boundary_base.C src/base/print_trace.C \ + src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ @@ -1229,6 +1234,7 @@ am__libmesh_devel_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/numerics/sparse_matrix.C \ src/numerics/sparse_shell_matrix.C \ src/numerics/static_condensation.C \ + src/numerics/static_condensation_dof_map.C \ src/numerics/sum_shell_matrix.C \ src/numerics/tensor_shell_matrix.C src/numerics/tensor_tools.C \ src/numerics/trilinos_epetra_matrix.C \ @@ -1386,6 +1392,7 @@ am__libmesh_devel_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/utils/tree_node.C src/utils/utility.C src/utils/xdr_cxx.C am__objects_2 = src/base/libmesh_devel_la-dirichlet_boundary.lo \ src/base/libmesh_devel_la-dof_map.lo \ + src/base/libmesh_devel_la-dof_map_base.lo \ src/base/libmesh_devel_la-dof_map_constraints.lo \ src/base/libmesh_devel_la-dof_object.lo \ src/base/libmesh_devel_la-libmesh.lo \ @@ -1665,6 +1672,7 @@ am__objects_2 = src/base/libmesh_devel_la-dirichlet_boundary.lo \ src/numerics/libmesh_devel_la-sparse_matrix.lo \ src/numerics/libmesh_devel_la-sparse_shell_matrix.lo \ src/numerics/libmesh_devel_la-static_condensation.lo \ + src/numerics/libmesh_devel_la-static_condensation_dof_map.lo \ src/numerics/libmesh_devel_la-sum_shell_matrix.lo \ src/numerics/libmesh_devel_la-tensor_shell_matrix.lo \ src/numerics/libmesh_devel_la-tensor_tools.lo \ @@ -1865,12 +1873,13 @@ libmesh_devel_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ @LIBMESH_OPROF_MODE_TRUE@ contrib/libcontrib_oprof.la \ @LIBMESH_OPROF_MODE_TRUE@ $(am__DEPENDENCIES_2) am__libmesh_oprof_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ - src/base/dof_map.C src/base/dof_map_constraints.C \ - src/base/dof_object.C src/base/libmesh.C \ - src/base/libmesh_common.C src/base/libmesh_singleton.C \ - src/base/libmesh_version.C src/base/periodic_boundaries.C \ - src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ - src/base/print_trace.C src/base/reference_counted_object.C \ + src/base/dof_map.C src/base/dof_map_base.C \ + src/base/dof_map_constraints.C src/base/dof_object.C \ + src/base/libmesh.C src/base/libmesh_common.C \ + src/base/libmesh_singleton.C src/base/libmesh_version.C \ + src/base/periodic_boundaries.C src/base/periodic_boundary.C \ + src/base/periodic_boundary_base.C src/base/print_trace.C \ + src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ @@ -2026,6 +2035,7 @@ am__libmesh_oprof_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/numerics/sparse_matrix.C \ src/numerics/sparse_shell_matrix.C \ src/numerics/static_condensation.C \ + src/numerics/static_condensation_dof_map.C \ src/numerics/sum_shell_matrix.C \ src/numerics/tensor_shell_matrix.C src/numerics/tensor_tools.C \ src/numerics/trilinos_epetra_matrix.C \ @@ -2183,6 +2193,7 @@ am__libmesh_oprof_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/utils/tree_node.C src/utils/utility.C src/utils/xdr_cxx.C am__objects_3 = src/base/libmesh_oprof_la-dirichlet_boundary.lo \ src/base/libmesh_oprof_la-dof_map.lo \ + src/base/libmesh_oprof_la-dof_map_base.lo \ src/base/libmesh_oprof_la-dof_map_constraints.lo \ src/base/libmesh_oprof_la-dof_object.lo \ src/base/libmesh_oprof_la-libmesh.lo \ @@ -2462,6 +2473,7 @@ am__objects_3 = src/base/libmesh_oprof_la-dirichlet_boundary.lo \ src/numerics/libmesh_oprof_la-sparse_matrix.lo \ src/numerics/libmesh_oprof_la-sparse_shell_matrix.lo \ src/numerics/libmesh_oprof_la-static_condensation.lo \ + src/numerics/libmesh_oprof_la-static_condensation_dof_map.lo \ src/numerics/libmesh_oprof_la-sum_shell_matrix.lo \ src/numerics/libmesh_oprof_la-tensor_shell_matrix.lo \ src/numerics/libmesh_oprof_la-tensor_tools.lo \ @@ -2662,12 +2674,13 @@ libmesh_oprof_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ @LIBMESH_OPT_MODE_TRUE@ contrib/libcontrib_opt.la \ @LIBMESH_OPT_MODE_TRUE@ $(am__DEPENDENCIES_2) am__libmesh_opt_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ - src/base/dof_map.C src/base/dof_map_constraints.C \ - src/base/dof_object.C src/base/libmesh.C \ - src/base/libmesh_common.C src/base/libmesh_singleton.C \ - src/base/libmesh_version.C src/base/periodic_boundaries.C \ - src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ - src/base/print_trace.C src/base/reference_counted_object.C \ + src/base/dof_map.C src/base/dof_map_base.C \ + src/base/dof_map_constraints.C src/base/dof_object.C \ + src/base/libmesh.C src/base/libmesh_common.C \ + src/base/libmesh_singleton.C src/base/libmesh_version.C \ + src/base/periodic_boundaries.C src/base/periodic_boundary.C \ + src/base/periodic_boundary_base.C src/base/print_trace.C \ + src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ @@ -2823,6 +2836,7 @@ am__libmesh_opt_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/numerics/sparse_matrix.C \ src/numerics/sparse_shell_matrix.C \ src/numerics/static_condensation.C \ + src/numerics/static_condensation_dof_map.C \ src/numerics/sum_shell_matrix.C \ src/numerics/tensor_shell_matrix.C src/numerics/tensor_tools.C \ src/numerics/trilinos_epetra_matrix.C \ @@ -2980,6 +2994,7 @@ am__libmesh_opt_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/utils/tree_node.C src/utils/utility.C src/utils/xdr_cxx.C am__objects_4 = src/base/libmesh_opt_la-dirichlet_boundary.lo \ src/base/libmesh_opt_la-dof_map.lo \ + src/base/libmesh_opt_la-dof_map_base.lo \ src/base/libmesh_opt_la-dof_map_constraints.lo \ src/base/libmesh_opt_la-dof_object.lo \ src/base/libmesh_opt_la-libmesh.lo \ @@ -3259,6 +3274,7 @@ am__objects_4 = src/base/libmesh_opt_la-dirichlet_boundary.lo \ src/numerics/libmesh_opt_la-sparse_matrix.lo \ src/numerics/libmesh_opt_la-sparse_shell_matrix.lo \ src/numerics/libmesh_opt_la-static_condensation.lo \ + src/numerics/libmesh_opt_la-static_condensation_dof_map.lo \ src/numerics/libmesh_opt_la-sum_shell_matrix.lo \ src/numerics/libmesh_opt_la-tensor_shell_matrix.lo \ src/numerics/libmesh_opt_la-tensor_tools.lo \ @@ -3458,12 +3474,13 @@ libmesh_opt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ @LIBMESH_PROF_MODE_TRUE@ contrib/libcontrib_prof.la \ @LIBMESH_PROF_MODE_TRUE@ $(am__DEPENDENCIES_2) am__libmesh_prof_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ - src/base/dof_map.C src/base/dof_map_constraints.C \ - src/base/dof_object.C src/base/libmesh.C \ - src/base/libmesh_common.C src/base/libmesh_singleton.C \ - src/base/libmesh_version.C src/base/periodic_boundaries.C \ - src/base/periodic_boundary.C src/base/periodic_boundary_base.C \ - src/base/print_trace.C src/base/reference_counted_object.C \ + src/base/dof_map.C src/base/dof_map_base.C \ + src/base/dof_map_constraints.C src/base/dof_object.C \ + src/base/libmesh.C src/base/libmesh_common.C \ + src/base/libmesh_singleton.C src/base/libmesh_version.C \ + src/base/periodic_boundaries.C src/base/periodic_boundary.C \ + src/base/periodic_boundary_base.C src/base/print_trace.C \ + src/base/reference_counted_object.C \ src/base/reference_counter.C src/base/single_predicates.C \ src/base/sparsity_pattern.C src/base/variable.C \ src/error_estimation/adjoint_refinement_estimator.C \ @@ -3619,6 +3636,7 @@ am__libmesh_prof_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/numerics/sparse_matrix.C \ src/numerics/sparse_shell_matrix.C \ src/numerics/static_condensation.C \ + src/numerics/static_condensation_dof_map.C \ src/numerics/sum_shell_matrix.C \ src/numerics/tensor_shell_matrix.C src/numerics/tensor_tools.C \ src/numerics/trilinos_epetra_matrix.C \ @@ -3776,6 +3794,7 @@ am__libmesh_prof_la_SOURCES_DIST = src/base/dirichlet_boundary.C \ src/utils/tree_node.C src/utils/utility.C src/utils/xdr_cxx.C am__objects_5 = src/base/libmesh_prof_la-dirichlet_boundary.lo \ src/base/libmesh_prof_la-dof_map.lo \ + src/base/libmesh_prof_la-dof_map_base.lo \ src/base/libmesh_prof_la-dof_map_constraints.lo \ src/base/libmesh_prof_la-dof_object.lo \ src/base/libmesh_prof_la-libmesh.lo \ @@ -4055,6 +4074,7 @@ am__objects_5 = src/base/libmesh_prof_la-dirichlet_boundary.lo \ src/numerics/libmesh_prof_la-sparse_matrix.lo \ src/numerics/libmesh_prof_la-sparse_shell_matrix.lo \ src/numerics/libmesh_prof_la-static_condensation.lo \ + src/numerics/libmesh_prof_la-static_condensation_dof_map.lo \ src/numerics/libmesh_prof_la-sum_shell_matrix.lo \ src/numerics/libmesh_prof_la-tensor_shell_matrix.lo \ src/numerics/libmesh_prof_la-tensor_tools.lo \ @@ -4713,6 +4733,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/apps/$(DEPDIR)/splitter_opt-splitter.Po \ src/base/$(DEPDIR)/libmesh_dbg_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_dbg_la-dof_map.Plo \ + src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_base.Plo \ src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_constraints.Plo \ src/base/$(DEPDIR)/libmesh_dbg_la-dof_object.Plo \ src/base/$(DEPDIR)/libmesh_dbg_la-libmesh.Plo \ @@ -4730,6 +4751,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-dof_map.Plo \ + src/base/$(DEPDIR)/libmesh_devel_la-dof_map_base.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-dof_object.Plo \ src/base/$(DEPDIR)/libmesh_devel_la-libmesh.Plo \ @@ -4747,6 +4769,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-dof_map.Plo \ + src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_base.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-dof_object.Plo \ src/base/$(DEPDIR)/libmesh_oprof_la-libmesh.Plo \ @@ -4764,6 +4787,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-dof_map.Plo \ + src/base/$(DEPDIR)/libmesh_opt_la-dof_map_base.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-dof_object.Plo \ src/base/$(DEPDIR)/libmesh_opt_la-libmesh.Plo \ @@ -4781,6 +4805,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-dirichlet_boundary.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-dof_map.Plo \ + src/base/$(DEPDIR)/libmesh_prof_la-dof_map_base.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-dof_object.Plo \ src/base/$(DEPDIR)/libmesh_prof_la-libmesh.Plo \ @@ -6004,6 +6029,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/numerics/$(DEPDIR)/libmesh_dbg_la-sparse_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_dbg_la-sparse_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation.Plo \ + src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation_dof_map.Plo \ src/numerics/$(DEPDIR)/libmesh_dbg_la-sum_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_dbg_la-tensor_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_dbg_la-tensor_tools.Plo \ @@ -6041,6 +6067,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/numerics/$(DEPDIR)/libmesh_devel_la-sparse_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_devel_la-sparse_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation.Plo \ + src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation_dof_map.Plo \ src/numerics/$(DEPDIR)/libmesh_devel_la-sum_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_devel_la-tensor_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_devel_la-tensor_tools.Plo \ @@ -6078,6 +6105,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/numerics/$(DEPDIR)/libmesh_oprof_la-sparse_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_oprof_la-sparse_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation.Plo \ + src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation_dof_map.Plo \ src/numerics/$(DEPDIR)/libmesh_oprof_la-sum_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_oprof_la-tensor_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_oprof_la-tensor_tools.Plo \ @@ -6115,6 +6143,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/numerics/$(DEPDIR)/libmesh_opt_la-sparse_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_opt_la-sparse_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation.Plo \ + src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation_dof_map.Plo \ src/numerics/$(DEPDIR)/libmesh_opt_la-sum_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_opt_la-tensor_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_opt_la-tensor_tools.Plo \ @@ -6152,6 +6181,7 @@ am__depfiles_remade = src/apps/$(DEPDIR)/amr_dbg-amr.Po \ src/numerics/$(DEPDIR)/libmesh_prof_la-sparse_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_prof_la-sparse_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation.Plo \ + src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation_dof_map.Plo \ src/numerics/$(DEPDIR)/libmesh_prof_la-sum_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_prof_la-tensor_shell_matrix.Plo \ src/numerics/$(DEPDIR)/libmesh_prof_la-tensor_tools.Plo \ @@ -7718,6 +7748,7 @@ DISTCLEANFILES = \ libmesh_SOURCES = \ src/base/dirichlet_boundary.C \ src/base/dof_map.C \ + src/base/dof_map_base.C \ src/base/dof_map_constraints.C \ src/base/dof_object.C \ src/base/libmesh.C \ @@ -7998,6 +8029,7 @@ libmesh_SOURCES = \ src/numerics/sparse_matrix.C \ src/numerics/sparse_shell_matrix.C \ src/numerics/static_condensation.C \ + src/numerics/static_condensation_dof_map.C \ src/numerics/sum_shell_matrix.C \ src/numerics/tensor_shell_matrix.C \ src/numerics/tensor_tools.C \ @@ -8654,6 +8686,8 @@ src/base/libmesh_dbg_la-dirichlet_boundary.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_dbg_la-dof_map.lo: src/base/$(am__dirstamp) \ src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_dbg_la-dof_map_base.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_dbg_la-dof_map_constraints.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_dbg_la-dof_object.lo: src/base/$(am__dirstamp) \ @@ -9297,6 +9331,9 @@ src/numerics/libmesh_dbg_la-sparse_shell_matrix.lo: \ src/numerics/libmesh_dbg_la-static_condensation.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) +src/numerics/libmesh_dbg_la-static_condensation_dof_map.lo: \ + src/numerics/$(am__dirstamp) \ + src/numerics/$(DEPDIR)/$(am__dirstamp) src/numerics/libmesh_dbg_la-sum_shell_matrix.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) @@ -9897,6 +9934,8 @@ src/base/libmesh_devel_la-dirichlet_boundary.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_devel_la-dof_map.lo: src/base/$(am__dirstamp) \ src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_devel_la-dof_map_base.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_devel_la-dof_map_constraints.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_devel_la-dof_object.lo: src/base/$(am__dirstamp) \ @@ -10504,6 +10543,9 @@ src/numerics/libmesh_devel_la-sparse_shell_matrix.lo: \ src/numerics/libmesh_devel_la-static_condensation.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) +src/numerics/libmesh_devel_la-static_condensation_dof_map.lo: \ + src/numerics/$(am__dirstamp) \ + src/numerics/$(DEPDIR)/$(am__dirstamp) src/numerics/libmesh_devel_la-sum_shell_matrix.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) @@ -11053,6 +11095,8 @@ src/base/libmesh_oprof_la-dirichlet_boundary.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_oprof_la-dof_map.lo: src/base/$(am__dirstamp) \ src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_oprof_la-dof_map_base.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_oprof_la-dof_map_constraints.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_oprof_la-dof_object.lo: src/base/$(am__dirstamp) \ @@ -11660,6 +11704,9 @@ src/numerics/libmesh_oprof_la-sparse_shell_matrix.lo: \ src/numerics/libmesh_oprof_la-static_condensation.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) +src/numerics/libmesh_oprof_la-static_condensation_dof_map.lo: \ + src/numerics/$(am__dirstamp) \ + src/numerics/$(DEPDIR)/$(am__dirstamp) src/numerics/libmesh_oprof_la-sum_shell_matrix.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) @@ -12209,6 +12256,8 @@ src/base/libmesh_opt_la-dirichlet_boundary.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_opt_la-dof_map.lo: src/base/$(am__dirstamp) \ src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_opt_la-dof_map_base.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_opt_la-dof_map_constraints.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_opt_la-dof_object.lo: src/base/$(am__dirstamp) \ @@ -12816,6 +12865,9 @@ src/numerics/libmesh_opt_la-sparse_shell_matrix.lo: \ src/numerics/libmesh_opt_la-static_condensation.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) +src/numerics/libmesh_opt_la-static_condensation_dof_map.lo: \ + src/numerics/$(am__dirstamp) \ + src/numerics/$(DEPDIR)/$(am__dirstamp) src/numerics/libmesh_opt_la-sum_shell_matrix.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) @@ -13362,6 +13414,8 @@ src/base/libmesh_prof_la-dirichlet_boundary.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_prof_la-dof_map.lo: src/base/$(am__dirstamp) \ src/base/$(DEPDIR)/$(am__dirstamp) +src/base/libmesh_prof_la-dof_map_base.lo: src/base/$(am__dirstamp) \ + src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_prof_la-dof_map_constraints.lo: \ src/base/$(am__dirstamp) src/base/$(DEPDIR)/$(am__dirstamp) src/base/libmesh_prof_la-dof_object.lo: src/base/$(am__dirstamp) \ @@ -13969,6 +14023,9 @@ src/numerics/libmesh_prof_la-sparse_shell_matrix.lo: \ src/numerics/libmesh_prof_la-static_condensation.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) +src/numerics/libmesh_prof_la-static_condensation_dof_map.lo: \ + src/numerics/$(am__dirstamp) \ + src/numerics/$(DEPDIR)/$(am__dirstamp) src/numerics/libmesh_prof_la-sum_shell_matrix.lo: \ src/numerics/$(am__dirstamp) \ src/numerics/$(DEPDIR)/$(am__dirstamp) @@ -15052,6 +15109,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/apps/$(DEPDIR)/splitter_opt-splitter.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-dof_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_base.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-dof_object.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-libmesh.Plo@am__quote@ # am--include-marker @@ -15069,6 +15127,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-dof_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-dof_map_base.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-dof_object.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-libmesh.Plo@am__quote@ # am--include-marker @@ -15086,6 +15145,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-dof_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_base.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-dof_object.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-libmesh.Plo@am__quote@ # am--include-marker @@ -15103,6 +15163,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-dof_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-dof_map_base.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-dof_object.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-libmesh.Plo@am__quote@ # am--include-marker @@ -15120,6 +15181,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-dirichlet_boundary.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-dof_map.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-dof_map_base.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-dof_object.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/base/$(DEPDIR)/libmesh_prof_la-libmesh.Plo@am__quote@ # am--include-marker @@ -16343,6 +16405,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_dbg_la-sparse_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_dbg_la-sparse_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation_dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_dbg_la-sum_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_dbg_la-tensor_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_dbg_la-tensor_tools.Plo@am__quote@ # am--include-marker @@ -16380,6 +16443,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_devel_la-sparse_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_devel_la-sparse_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation_dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_devel_la-sum_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_devel_la-tensor_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_devel_la-tensor_tools.Plo@am__quote@ # am--include-marker @@ -16417,6 +16481,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_oprof_la-sparse_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_oprof_la-sparse_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation_dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_oprof_la-sum_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_oprof_la-tensor_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_oprof_la-tensor_tools.Plo@am__quote@ # am--include-marker @@ -16454,6 +16519,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_opt_la-sparse_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_opt_la-sparse_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation_dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_opt_la-sum_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_opt_la-tensor_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_opt_la-tensor_tools.Plo@am__quote@ # am--include-marker @@ -16491,6 +16557,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_prof_la-sparse_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_prof_la-sparse_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation_dof_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_prof_la-sum_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_prof_la-tensor_shell_matrix.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/numerics/$(DEPDIR)/libmesh_prof_la-tensor_tools.Plo@am__quote@ # am--include-marker @@ -17440,6 +17507,13 @@ src/base/libmesh_dbg_la-dof_map.lo: src/base/dof_map.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_dbg_la-dof_map.lo `test -f 'src/base/dof_map.C' || echo '$(srcdir)/'`src/base/dof_map.C +src/base/libmesh_dbg_la-dof_map_base.lo: src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_dbg_la-dof_map_base.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_base.Tpo -c -o src/base/libmesh_dbg_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_base.Tpo src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_base.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/dof_map_base.C' object='src/base/libmesh_dbg_la-dof_map_base.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_dbg_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C + src/base/libmesh_dbg_la-dof_map_constraints.lo: src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_dbg_la-dof_map_constraints.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_constraints.Tpo -c -o src/base/libmesh_dbg_la-dof_map_constraints.lo `test -f 'src/base/dof_map_constraints.C' || echo '$(srcdir)/'`src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_constraints.Tpo src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_constraints.Plo @@ -19393,6 +19467,13 @@ src/numerics/libmesh_dbg_la-static_condensation.lo: src/numerics/static_condensa @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_dbg_la-static_condensation.lo `test -f 'src/numerics/static_condensation.C' || echo '$(srcdir)/'`src/numerics/static_condensation.C +src/numerics/libmesh_dbg_la-static_condensation_dof_map.lo: src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_dbg_la-static_condensation_dof_map.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation_dof_map.Tpo -c -o src/numerics/libmesh_dbg_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation_dof_map.Tpo src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation_dof_map.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/numerics/static_condensation_dof_map.C' object='src/numerics/libmesh_dbg_la-static_condensation_dof_map.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_dbg_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C + src/numerics/libmesh_dbg_la-sum_shell_matrix.lo: src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_dbg_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_dbg_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_dbg_la-sum_shell_matrix.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_dbg_la-sum_shell_matrix.Tpo -c -o src/numerics/libmesh_dbg_la-sum_shell_matrix.lo `test -f 'src/numerics/sum_shell_matrix.C' || echo '$(srcdir)/'`src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_dbg_la-sum_shell_matrix.Tpo src/numerics/$(DEPDIR)/libmesh_dbg_la-sum_shell_matrix.Plo @@ -20723,6 +20804,13 @@ src/base/libmesh_devel_la-dof_map.lo: src/base/dof_map.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_devel_la-dof_map.lo `test -f 'src/base/dof_map.C' || echo '$(srcdir)/'`src/base/dof_map.C +src/base/libmesh_devel_la-dof_map_base.lo: src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_devel_la-dof_map_base.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_devel_la-dof_map_base.Tpo -c -o src/base/libmesh_devel_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_devel_la-dof_map_base.Tpo src/base/$(DEPDIR)/libmesh_devel_la-dof_map_base.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/dof_map_base.C' object='src/base/libmesh_devel_la-dof_map_base.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_devel_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C + src/base/libmesh_devel_la-dof_map_constraints.lo: src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_devel_la-dof_map_constraints.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Tpo -c -o src/base/libmesh_devel_la-dof_map_constraints.lo `test -f 'src/base/dof_map_constraints.C' || echo '$(srcdir)/'`src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Tpo src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo @@ -22676,6 +22764,13 @@ src/numerics/libmesh_devel_la-static_condensation.lo: src/numerics/static_conden @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_devel_la-static_condensation.lo `test -f 'src/numerics/static_condensation.C' || echo '$(srcdir)/'`src/numerics/static_condensation.C +src/numerics/libmesh_devel_la-static_condensation_dof_map.lo: src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_devel_la-static_condensation_dof_map.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation_dof_map.Tpo -c -o src/numerics/libmesh_devel_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation_dof_map.Tpo src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation_dof_map.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/numerics/static_condensation_dof_map.C' object='src/numerics/libmesh_devel_la-static_condensation_dof_map.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_devel_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C + src/numerics/libmesh_devel_la-sum_shell_matrix.lo: src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_devel_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_devel_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_devel_la-sum_shell_matrix.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_devel_la-sum_shell_matrix.Tpo -c -o src/numerics/libmesh_devel_la-sum_shell_matrix.lo `test -f 'src/numerics/sum_shell_matrix.C' || echo '$(srcdir)/'`src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_devel_la-sum_shell_matrix.Tpo src/numerics/$(DEPDIR)/libmesh_devel_la-sum_shell_matrix.Plo @@ -24006,6 +24101,13 @@ src/base/libmesh_oprof_la-dof_map.lo: src/base/dof_map.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_oprof_la-dof_map.lo `test -f 'src/base/dof_map.C' || echo '$(srcdir)/'`src/base/dof_map.C +src/base/libmesh_oprof_la-dof_map_base.lo: src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_oprof_la-dof_map_base.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_base.Tpo -c -o src/base/libmesh_oprof_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_base.Tpo src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_base.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/dof_map_base.C' object='src/base/libmesh_oprof_la-dof_map_base.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_oprof_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C + src/base/libmesh_oprof_la-dof_map_constraints.lo: src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_oprof_la-dof_map_constraints.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Tpo -c -o src/base/libmesh_oprof_la-dof_map_constraints.lo `test -f 'src/base/dof_map_constraints.C' || echo '$(srcdir)/'`src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Tpo src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo @@ -25959,6 +26061,13 @@ src/numerics/libmesh_oprof_la-static_condensation.lo: src/numerics/static_conden @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_oprof_la-static_condensation.lo `test -f 'src/numerics/static_condensation.C' || echo '$(srcdir)/'`src/numerics/static_condensation.C +src/numerics/libmesh_oprof_la-static_condensation_dof_map.lo: src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_oprof_la-static_condensation_dof_map.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation_dof_map.Tpo -c -o src/numerics/libmesh_oprof_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation_dof_map.Tpo src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation_dof_map.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/numerics/static_condensation_dof_map.C' object='src/numerics/libmesh_oprof_la-static_condensation_dof_map.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_oprof_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C + src/numerics/libmesh_oprof_la-sum_shell_matrix.lo: src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_oprof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_oprof_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_oprof_la-sum_shell_matrix.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_oprof_la-sum_shell_matrix.Tpo -c -o src/numerics/libmesh_oprof_la-sum_shell_matrix.lo `test -f 'src/numerics/sum_shell_matrix.C' || echo '$(srcdir)/'`src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_oprof_la-sum_shell_matrix.Tpo src/numerics/$(DEPDIR)/libmesh_oprof_la-sum_shell_matrix.Plo @@ -27289,6 +27398,13 @@ src/base/libmesh_opt_la-dof_map.lo: src/base/dof_map.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_opt_la-dof_map.lo `test -f 'src/base/dof_map.C' || echo '$(srcdir)/'`src/base/dof_map.C +src/base/libmesh_opt_la-dof_map_base.lo: src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_opt_la-dof_map_base.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_opt_la-dof_map_base.Tpo -c -o src/base/libmesh_opt_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_opt_la-dof_map_base.Tpo src/base/$(DEPDIR)/libmesh_opt_la-dof_map_base.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/dof_map_base.C' object='src/base/libmesh_opt_la-dof_map_base.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_opt_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C + src/base/libmesh_opt_la-dof_map_constraints.lo: src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_opt_la-dof_map_constraints.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Tpo -c -o src/base/libmesh_opt_la-dof_map_constraints.lo `test -f 'src/base/dof_map_constraints.C' || echo '$(srcdir)/'`src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Tpo src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo @@ -29242,6 +29358,13 @@ src/numerics/libmesh_opt_la-static_condensation.lo: src/numerics/static_condensa @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_opt_la-static_condensation.lo `test -f 'src/numerics/static_condensation.C' || echo '$(srcdir)/'`src/numerics/static_condensation.C +src/numerics/libmesh_opt_la-static_condensation_dof_map.lo: src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_opt_la-static_condensation_dof_map.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation_dof_map.Tpo -c -o src/numerics/libmesh_opt_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation_dof_map.Tpo src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation_dof_map.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/numerics/static_condensation_dof_map.C' object='src/numerics/libmesh_opt_la-static_condensation_dof_map.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_opt_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C + src/numerics/libmesh_opt_la-sum_shell_matrix.lo: src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_opt_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_opt_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_opt_la-sum_shell_matrix.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_opt_la-sum_shell_matrix.Tpo -c -o src/numerics/libmesh_opt_la-sum_shell_matrix.lo `test -f 'src/numerics/sum_shell_matrix.C' || echo '$(srcdir)/'`src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_opt_la-sum_shell_matrix.Tpo src/numerics/$(DEPDIR)/libmesh_opt_la-sum_shell_matrix.Plo @@ -30572,6 +30695,13 @@ src/base/libmesh_prof_la-dof_map.lo: src/base/dof_map.C @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_prof_la-dof_map.lo `test -f 'src/base/dof_map.C' || echo '$(srcdir)/'`src/base/dof_map.C +src/base/libmesh_prof_la-dof_map_base.lo: src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_prof_la-dof_map_base.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_prof_la-dof_map_base.Tpo -c -o src/base/libmesh_prof_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_prof_la-dof_map_base.Tpo src/base/$(DEPDIR)/libmesh_prof_la-dof_map_base.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/base/dof_map_base.C' object='src/base/libmesh_prof_la-dof_map_base.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/base/libmesh_prof_la-dof_map_base.lo `test -f 'src/base/dof_map_base.C' || echo '$(srcdir)/'`src/base/dof_map_base.C + src/base/libmesh_prof_la-dof_map_constraints.lo: src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -MT src/base/libmesh_prof_la-dof_map_constraints.lo -MD -MP -MF src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Tpo -c -o src/base/libmesh_prof_la-dof_map_constraints.lo `test -f 'src/base/dof_map_constraints.C' || echo '$(srcdir)/'`src/base/dof_map_constraints.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Tpo src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo @@ -32525,6 +32655,13 @@ src/numerics/libmesh_prof_la-static_condensation.lo: src/numerics/static_condens @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_prof_la-static_condensation.lo `test -f 'src/numerics/static_condensation.C' || echo '$(srcdir)/'`src/numerics/static_condensation.C +src/numerics/libmesh_prof_la-static_condensation_dof_map.lo: src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_prof_la-static_condensation_dof_map.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation_dof_map.Tpo -c -o src/numerics/libmesh_prof_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation_dof_map.Tpo src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation_dof_map.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='src/numerics/static_condensation_dof_map.C' object='src/numerics/libmesh_prof_la-static_condensation_dof_map.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -c -o src/numerics/libmesh_prof_la-static_condensation_dof_map.lo `test -f 'src/numerics/static_condensation_dof_map.C' || echo '$(srcdir)/'`src/numerics/static_condensation_dof_map.C + src/numerics/libmesh_prof_la-sum_shell_matrix.lo: src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmesh_prof_la_CPPFLAGS) $(CPPFLAGS) $(libmesh_prof_la_CXXFLAGS) $(CXXFLAGS) -MT src/numerics/libmesh_prof_la-sum_shell_matrix.lo -MD -MP -MF src/numerics/$(DEPDIR)/libmesh_prof_la-sum_shell_matrix.Tpo -c -o src/numerics/libmesh_prof_la-sum_shell_matrix.lo `test -f 'src/numerics/sum_shell_matrix.C' || echo '$(srcdir)/'`src/numerics/sum_shell_matrix.C @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) src/numerics/$(DEPDIR)/libmesh_prof_la-sum_shell_matrix.Tpo src/numerics/$(DEPDIR)/libmesh_prof_la-sum_shell_matrix.Plo @@ -35175,6 +35312,7 @@ distclean: distclean-recursive -rm -f src/apps/$(DEPDIR)/splitter_opt-splitter.Po -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-libmesh.Plo @@ -35192,6 +35330,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-libmesh.Plo @@ -35209,6 +35348,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-libmesh.Plo @@ -35226,6 +35366,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-libmesh.Plo @@ -35243,6 +35384,7 @@ distclean: distclean-recursive -rm -f src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-libmesh.Plo @@ -36466,6 +36608,7 @@ distclean: distclean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-tensor_tools.Plo @@ -36503,6 +36646,7 @@ distclean: distclean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-tensor_tools.Plo @@ -36540,6 +36684,7 @@ distclean: distclean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-tensor_tools.Plo @@ -36577,6 +36722,7 @@ distclean: distclean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-tensor_tools.Plo @@ -36614,6 +36760,7 @@ distclean: distclean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-tensor_tools.Plo @@ -37628,6 +37775,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/apps/$(DEPDIR)/splitter_opt-splitter.Po -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-libmesh.Plo @@ -37645,6 +37793,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_dbg_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_devel_la-libmesh.Plo @@ -37662,6 +37811,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_devel_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-libmesh.Plo @@ -37679,6 +37829,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_oprof_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_opt_la-libmesh.Plo @@ -37696,6 +37847,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/base/$(DEPDIR)/libmesh_opt_la-variable.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dirichlet_boundary.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map.Plo + -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map_base.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_map_constraints.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-dof_object.Plo -rm -f src/base/$(DEPDIR)/libmesh_prof_la-libmesh.Plo @@ -38919,6 +39071,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_dbg_la-tensor_tools.Plo @@ -38956,6 +39109,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_devel_la-tensor_tools.Plo @@ -38993,6 +39147,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_oprof_la-tensor_tools.Plo @@ -39030,6 +39185,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_opt_la-tensor_tools.Plo @@ -39067,6 +39223,7 @@ maintainer-clean: maintainer-clean-recursive -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-sparse_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-sparse_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation.Plo + -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-static_condensation_dof_map.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-sum_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-tensor_shell_matrix.Plo -rm -f src/numerics/$(DEPDIR)/libmesh_prof_la-tensor_tools.Plo diff --git a/include/Makefile.in b/include/Makefile.in index 7d09912b559..45a3e49c6c4 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -889,6 +889,7 @@ include_HEADERS = \ numerics/sparse_matrix.h \ numerics/sparse_shell_matrix.h \ numerics/static_condensation.h \ + numerics/static_condensation_dof_map.h \ numerics/static_condensation_preconditioner.h \ numerics/sum_shell_matrix.h \ numerics/tensor_shell_matrix.h \ diff --git a/include/libmesh/Makefile.in b/include/libmesh/Makefile.in index 35a2527c09a..4b4bd1a781b 100644 --- a/include/libmesh/Makefile.in +++ b/include/libmesh/Makefile.in @@ -610,25 +610,26 @@ BUILT_SOURCES = auto_ptr.h dirichlet_boundaries.h dof_map.h \ petsc_shell_matrix.h petsc_solver_exception.h petsc_vector.h \ preconditioner.h raw_accessor.h refinement_selector.h \ shell_matrix.h sparse_matrix.h sparse_shell_matrix.h \ - static_condensation.h static_condensation_preconditioner.h \ - sum_shell_matrix.h tensor_shell_matrix.h tensor_tools.h \ - tensor_value.h trilinos_epetra_matrix.h \ - trilinos_epetra_vector.h trilinos_preconditioner.h tuple_of.h \ - type_n_tensor.h type_tensor.h type_vector.h vector_value.h \ - wrapped_function.h wrapped_functor.h wrapped_petsc.h \ - zero_function.h libmesh_call_mpi.h parallel.h \ - parallel_algebra.h parallel_bin_sorter.h \ - parallel_conversion_utils.h parallel_eigen.h parallel_elem.h \ - parallel_fe_type.h parallel_ghost_sync.h parallel_hilbert.h \ - parallel_histogram.h parallel_node.h parallel_object.h \ - parallel_only.h parallel_sort.h threads.h threads_allocators.h \ - threads_none.h threads_pthread.h threads_tbb.h \ - centroid_partitioner.h hilbert_sfc_partitioner.h \ - linear_partitioner.h mapped_subdomain_partitioner.h \ - metis_csr_graph.h metis_partitioner.h morton_sfc_partitioner.h \ - parmetis_helper.h parmetis_partitioner.h partitioner.h \ - sfc_partitioner.h subdomain_partitioner.h diff_physics.h \ - diff_qoi.h fem_physics.h quadrature.h quadrature_clough.h \ + static_condensation.h static_condensation_dof_map.h \ + static_condensation_preconditioner.h sum_shell_matrix.h \ + tensor_shell_matrix.h tensor_tools.h tensor_value.h \ + trilinos_epetra_matrix.h trilinos_epetra_vector.h \ + trilinos_preconditioner.h tuple_of.h type_n_tensor.h \ + type_tensor.h type_vector.h vector_value.h wrapped_function.h \ + wrapped_functor.h wrapped_petsc.h zero_function.h \ + libmesh_call_mpi.h parallel.h parallel_algebra.h \ + parallel_bin_sorter.h parallel_conversion_utils.h \ + parallel_eigen.h parallel_elem.h parallel_fe_type.h \ + parallel_ghost_sync.h parallel_hilbert.h parallel_histogram.h \ + parallel_node.h parallel_object.h parallel_only.h \ + parallel_sort.h threads.h threads_allocators.h threads_none.h \ + threads_pthread.h threads_tbb.h centroid_partitioner.h \ + hilbert_sfc_partitioner.h linear_partitioner.h \ + mapped_subdomain_partitioner.h metis_csr_graph.h \ + metis_partitioner.h morton_sfc_partitioner.h parmetis_helper.h \ + parmetis_partitioner.h partitioner.h sfc_partitioner.h \ + subdomain_partitioner.h diff_physics.h diff_qoi.h \ + fem_physics.h quadrature.h quadrature_clough.h \ quadrature_composite.h quadrature_conical.h quadrature_gauss.h \ quadrature_gauss_lobatto.h quadrature_gm.h quadrature_grid.h \ quadrature_jacobi.h quadrature_monomial.h quadrature_nodal.h \ @@ -1768,6 +1769,9 @@ sparse_shell_matrix.h: $(top_srcdir)/include/numerics/sparse_shell_matrix.h static_condensation.h: $(top_srcdir)/include/numerics/static_condensation.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ +static_condensation_dof_map.h: $(top_srcdir)/include/numerics/static_condensation_dof_map.h + $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ + static_condensation_preconditioner.h: $(top_srcdir)/include/numerics/static_condensation_preconditioner.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ From 3e13345e77f028f72ac1b67b91b7ec3bc0cb9eae Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Wed, 30 Apr 2025 15:18:48 -0600 Subject: [PATCH 17/41] Divide DofMap and SparseMatrix pieces of StaticCondensation --- .../vector_fe/vector_fe_ex9/vector_fe_ex9.C | 11 +- include/base/dof_map.h | 58 +-- include/base/dof_map_base.h | 65 ++- include/base/sparsity_pattern.h | 6 +- include/numerics/static_condensation.h | 100 +---- .../numerics/static_condensation_dof_map.h | 167 ++++++++ include/systems/implicit_system.h | 36 +- include/systems/system.h | 37 +- src/base/dof_map.C | 38 +- src/base/dof_map_base.C | 58 +++ src/base/sparsity_pattern.C | 4 +- src/numerics/static_condensation.C | 401 +++--------------- src/numerics/static_condensation_dof_map.C | 347 +++++++++++++++ src/systems/implicit_system.C | 32 +- src/systems/linear_implicit_system.C | 5 +- src/systems/nonlinear_implicit_system.C | 6 +- src/systems/system.C | 21 + 17 files changed, 843 insertions(+), 549 deletions(-) create mode 100644 include/numerics/static_condensation_dof_map.h create mode 100644 src/base/dof_map_base.C create mode 100644 src/numerics/static_condensation_dof_map.C diff --git a/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C b/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C index 965a1b6ac0b..3a190a23a55 100644 --- a/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C +++ b/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C @@ -52,6 +52,7 @@ #include "libmesh/equation_systems.h" #include "libmesh/nonlinear_implicit_system.h" #include "libmesh/nonlinear_solver.h" +#include "libmesh/static_condensation_dof_map.h" #include "libmesh/static_condensation.h" // The exact solution and error computation. @@ -151,11 +152,13 @@ main(int argc, char ** argv) const FEType scalar_fe_type(FIRST, L2_LAGRANGE); const FEType lm_fe_type(FIRST, SIDE_HIERARCHIC); - StaticCondensation * sc = nullptr; + StaticCondensationDofMap * sc_dof_map = nullptr; + StaticCondensation * sc_system_matrix = nullptr; if (system.has_static_condensation()) { - sc = &system.get_static_condensation(); - sc->dont_condense_vars({p_num}); + sc_dof_map = &system.get_static_condensation_dof_map(); + sc_dof_map->dont_condense_vars({p_num}); + sc_system_matrix = cast_ptr(system.matrix); } HDGProblem hdg(nu, cavity); @@ -170,7 +173,7 @@ main(int argc, char ** argv) hdg.scalar_fe_face = FEBase::build(dimension, scalar_fe_type); hdg.lm_fe_face = FEBase::build(dimension, lm_fe_type); hdg.mms = mms; - hdg.sc = sc; + hdg.sc = sc_system_matrix; system.nonlinear_solver->residual_object = &hdg; system.nonlinear_solver->jacobian_object = &hdg; diff --git a/include/base/dof_map.h b/include/base/dof_map.h index acb35584d2a..34ca5d2e58b 100644 --- a/include/base/dof_map.h +++ b/include/base/dof_map.h @@ -69,7 +69,7 @@ class PeriodicBoundaryBase; class PeriodicBoundaries; class System; class NonlinearImplicitSystem; -class StaticCondensation; +class StaticCondensationDofMap; template class DenseVectorBase; template class DenseVector; template class DenseMatrix; @@ -177,8 +177,7 @@ class NodeConstraints : public std::map, - public ParallelObject + public ReferenceCountedObject { public: @@ -661,8 +660,7 @@ class DofMap : public DofMapBase, return (this->has_blocked_representation() ? this->n_variables() : 1); } - dof_id_type n_dofs() const override { return _n_dfs; } - + using DofMapBase::n_dofs; /** * \returns The total number of degrees of freedom for a particular * variable \p vn. @@ -679,9 +677,7 @@ class DofMap : public DofMapBase, */ dof_id_type n_SCALAR_dofs() const { return _n_SCALAR_dofs; } - dof_id_type n_local_dofs () const override - { return this->n_dofs_on_processor (this->processor_id()); } - + using DofMapBase::n_local_dofs; /** * \returns The number of degrees of freedom on this processor for a * particular variable \p vn. This is an O(N) operation on serialized or @@ -694,15 +690,6 @@ class DofMap : public DofMapBase, return n; } - /** - * \returns The number of degrees of freedom on partition \p proc. - */ - dof_id_type n_dofs_on_processor(const processor_id_type proc) const - { - libmesh_assert_less (proc, _first_df.size()); - return cast_int(_end_df[proc] - _first_df[proc]); - } - /** * \returns The number of degrees of freedom on each partition for a * particular variable \p vn. @@ -714,12 +701,6 @@ class DofMap : public DofMapBase, return n_local_dofs; } - dof_id_type first_dof(const processor_id_type proc) const - { libmesh_assert_less (proc, _first_df.size()); return _first_df[proc]; } - - dof_id_type first_dof() const override - { return this->first_dof(this->processor_id()); } - #ifdef LIBMESH_ENABLE_AMR /** * \returns The first old dof index that is local to partition \p proc. @@ -732,12 +713,6 @@ class DofMap : public DofMapBase, #endif //LIBMESH_ENABLE_AMR - dof_id_type end_dof(const processor_id_type proc) const - { libmesh_assert_less (proc, _end_df.size()); return _end_df[proc]; } - - dof_id_type end_dof() const override - { return this->end_dof(this->processor_id()); } - /** * \returns The processor id that owns the dof index \p dof */ @@ -1642,7 +1617,7 @@ class DofMap : public DofMapBase, * Free all new memory associated with the object, but restore its * original state, with the mesh pointer and any default ghosting. */ - void clear (); + virtual void clear () override; /** * Prints summary info about the sparsity bandwidth and constraints. @@ -1717,7 +1692,7 @@ class DofMap : public DofMapBase, /** * Add a static condensation class */ - void add_static_condensation(const StaticCondensation & sc) { _sc = ≻ } + void add_static_condensation(const StaticCondensationDofMap & sc) { _sc = ≻ } /** * Checks whether we have static condensation @@ -1728,7 +1703,7 @@ class DofMap : public DofMapBase, * @returns the static condensation class. This should have been already added with a call to \p * add_static_condensation() */ - const StaticCondensation & get_static_condensation() const; + const StaticCondensationDofMap & get_static_condensation() const; private: @@ -2028,16 +2003,6 @@ class DofMap : public DofMapBase, */ std::vector * > _matrices; - /** - * First DOF index on processor \p p. - */ - std::vector _first_df; - - /** - * Last DOF index (plus 1) on processor \p p. - */ - std::vector _end_df; - /** * First DOF index for SCALAR variable v, or garbage for non-SCALAR * variable v @@ -2140,11 +2105,6 @@ class DofMap : public DofMapBase, */ std::unique_ptr _sp; - /** - * Total number of degrees of freedom. - */ - dof_id_type _n_dfs; - /** * The total number of SCALAR dofs associated to * all SCALAR variables. @@ -2244,7 +2204,7 @@ class DofMap : public DofMapBase, bool _verify_dirichlet_bc_consistency; /// Static condensation class - const StaticCondensation * _sc; + const StaticCondensationDofMap * _sc; }; @@ -2768,7 +2728,7 @@ void DofMap::dof_indices (const Elem * const elem, } inline -const StaticCondensation & DofMap::get_static_condensation() const +const StaticCondensationDofMap & DofMap::get_static_condensation() const { libmesh_assert(_sc); return *_sc; diff --git a/include/base/dof_map_base.h b/include/base/dof_map_base.h index cf10a5df0bd..ed065cc2af1 100644 --- a/include/base/dof_map_base.h +++ b/include/base/dof_map_base.h @@ -19,6 +19,7 @@ #define LIBMESH_DOF_MAP_BASE_H #include "libmesh/id_types.h" +#include "libmesh/parallel_object.h" #include namespace libMesh @@ -27,10 +28,10 @@ class Variable; class Elem; class Node; -class DofMapBase +class DofMapBase : public ParallelObject { public: - DofMapBase() = default; + DofMapBase(const Parallel::Communicator & comm) : ParallelObject(comm), _n_dfs(0) {} /** * \returns The number of variables in the global solution vector. Defaults @@ -47,7 +48,9 @@ class DofMapBase /** * \returns The first dof index that is local to partition \p proc. */ - virtual dof_id_type first_dof() const = 0; + dof_id_type first_dof(const processor_id_type proc) const; + + dof_id_type first_dof() const { return this->first_dof(this->processor_id()); } /** * \returns The first dof index that is after all indices local to @@ -55,7 +58,9 @@ class DofMapBase * * Analogous to the end() member function of STL containers. */ - virtual dof_id_type end_dof() const = 0; + dof_id_type end_dof(const processor_id_type proc) const; + + dof_id_type end_dof() const { return this->end_dof(this->processor_id()); } /** * Fills the vector \p di with the global degree of freedom indices @@ -77,13 +82,61 @@ class DofMapBase /** * \returns The total number of degrees of freedom in the problem. */ - virtual dof_id_type n_dofs() const = 0; + dof_id_type n_dofs() const { return _n_dfs; } + + /** + * \returns The number of degrees of freedom on partition \p proc. + */ + dof_id_type n_dofs_on_processor(const processor_id_type proc) const; /** * \returns The number of degrees of freedom on this processor. */ - virtual dof_id_type n_local_dofs() const = 0; + dof_id_type n_local_dofs() const { return this->n_dofs_on_processor(this->processor_id()); } + + virtual void clear(); + +protected: + /** + * compute the key degree of freedom information given the local number of degrees of freedom on + * this process + * \returns The total number of DOFs for the System, summed across all procs. + */ + std::size_t compute_dof_info(dof_id_type n_local_dofs); + + /** + * First DOF index on processor \p p. + */ + std::vector _first_df; + + /** + * Last DOF index (plus 1) on processor \p p. + */ + std::vector _end_df; + + /** + * Total number of degrees of freedom. + */ + dof_id_type _n_dfs; }; +inline dof_id_type DofMapBase::first_dof(const processor_id_type proc) const +{ + libmesh_assert_less(proc, _first_df.size()); + return _first_df[proc]; +} + +inline dof_id_type DofMapBase::end_dof(const processor_id_type proc) const +{ + libmesh_assert_less(proc, _end_df.size()); + return _end_df[proc]; +} + +inline dof_id_type DofMapBase::n_dofs_on_processor(const processor_id_type proc) const +{ + libmesh_assert_less(proc, _first_df.size()); + return cast_int(_end_df[proc] - _first_df[proc]); +} + } #endif // LIBMESH_DOF_MAP_BASE_H diff --git a/include/base/sparsity_pattern.h b/include/base/sparsity_pattern.h index 61a11fc1ff3..5c52cb48dd3 100644 --- a/include/base/sparsity_pattern.h +++ b/include/base/sparsity_pattern.h @@ -35,7 +35,7 @@ namespace libMesh // Forward declarations class DofMap; class CouplingMatrix; -class StaticCondensation; +class StaticCondensationDofMap; /** * This defines the sparsity pattern, or graph, of a sparse matrix. @@ -109,7 +109,7 @@ class Build : public ParallelObject const bool implicit_neighbor_dofs_in, const bool need_full_sparsity_pattern_in, const bool calculate_constrained_in = false, - const StaticCondensation * sc = nullptr); + const StaticCondensationDofMap * sc = nullptr); /** * Special functions. @@ -212,7 +212,7 @@ class Build : public ParallelObject const bool implicit_neighbor_dofs; const bool need_full_sparsity_pattern; const bool calculate_constrained; - const StaticCondensation * const sc; + const StaticCondensationDofMap * const sc; /** * If there are "spider" nodes in the mesh (i.e. a single node which diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index 2c781bd0d73..628ad790da2 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -27,7 +27,6 @@ #include "libmesh/id_types.h" #include "libmesh/libmesh_common.h" #include "libmesh/dense_matrix.h" -#include "libmesh/dof_map_base.h" #include "libmesh/variable.h" #include "libmesh/sparsity_pattern.h" @@ -53,14 +52,18 @@ class NumericVector; template class Preconditioner; class StaticCondensationPreconditioner; +class StaticCondensationDofMap; typedef Eigen::Matrix EigenMatrix; typedef Eigen::Matrix EigenVector; -class StaticCondensation : public PetscMatrixShellMatrix, public DofMapBase +class StaticCondensation : public PetscMatrixShellMatrix { public: - StaticCondensation(const MeshBase & mesh, System & system, const DofMap & dof_map); + StaticCondensation(const MeshBase & mesh, + System & system, + const DofMap & full_dof_map, + const StaticCondensationDofMap & reduced_dof_map); virtual ~StaticCondensation(); // @@ -143,7 +146,7 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB // /** - * Build the element global to local index maps and size the element matrices + * Size the element matrices */ void init(); @@ -161,18 +164,6 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB const SparseMatrix & get_condensed_mat() const; - /** - * Add \p vars to the list of variables not to condense. This can be useful when some variable's - * equation is discretized with a DG method or if including the variable in the condensed block - * diagonal would result in it being singular - */ - void dont_condense_vars(const std::unordered_set & vars); - - /** - * @returns our list of variables for whom we do not condense out any dofs - */ - const std::unordered_set & uncondensed_vars() const { return _uncondensed_vars; } - /** * Set the current element. This enables fast lookups of local indices from global indices */ @@ -183,34 +174,11 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB */ StaticCondensationPreconditioner & get_preconditioner() { return *_scp; } - virtual unsigned int n_variables() const override; - - virtual const Variable & variable(const unsigned int c) const override; - - virtual void dof_indices(const Elem * const elem, - std::vector & di, - const unsigned int vn, - int p_level = -12345) const override; - - virtual void dof_indices(const Node * const node, - std::vector & di, - const unsigned int vn) const override; - - virtual dof_id_type first_dof() const override; - virtual dof_id_type end_dof() const override; - virtual dof_id_type n_dofs() const override; - virtual dof_id_type n_local_dofs() const override; - /** * @returns The reduced system linear solver */ LinearSolver & reduced_system_solver(); - /* - * @returns The dummyish reduced system - */ - const System & reduced_system() const; - virtual bool require_sparsity_pattern() const override { return false; } private: @@ -243,7 +211,7 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB * Data stored on a per-element basis used to compute element Schur complements and their * applications to vectors */ - struct LocalData + struct MatrixData { /// condensed-condensed matrix entries EigenMatrix Acc; @@ -256,35 +224,15 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB // Acc LU decompositions typename std::remove_const::type AccFactor; - - /// The uncondensed degrees of freedom with global numbering corresponding to the the \emph reduced - /// system. Note that initially this will actually hold the indices corresponding to the fully - /// sized problem, but we will swap it out by the time we are done initializing - std::vector> reduced_space_indices; - - /// A map from the global degree of freedom number for the full system (condensed + uncondensed) - /// to an element local number. If this map is queried with a condensed dof, nothing will be - /// found. The size of this container will be the number of uncondensed degrees of freedom whose - /// basis functions are nonzero on the element - std::unordered_map uncondensed_global_to_local_map; - /// A map from the global degree of freedom number for the full system (condensed + uncondensed) - /// to an element local number. If this map is queried with an uncondensed dof, nothing will be - /// found. The size of this container will be the number of condensed degrees of freedom whose - /// basis functions are nonzero on the element - std::unordered_map condensed_global_to_local_map; }; /// A map from element ID to Schur complement data - std::unordered_map _elem_to_local_data; - - /// All the uncondensed degrees of freedom (numbered in the "full" uncondensed + condensed - /// space). This data member is used for creating subvectors corresponding to only uncondensed - /// dofs - std::vector _local_uncondensed_dofs; + std::unordered_map _elem_to_matrix_data; const MeshBase & _mesh; System & _system; - const DofMap & _dof_map; + const DofMap & _full_dof_map; + const StaticCondensationDofMap & _reduced_dof_map; /// global sparse matrix for the uncondensed degrees of freedom std::unique_ptr> _reduced_sys_mat; @@ -301,9 +249,6 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB // solution for the Newton *update* std::unique_ptr> _ghosted_full_sol; - /// Variables for which we will keep all dofs - std::unordered_set _uncondensed_vars; - /// The current element ID. This is one half of a key, along with the global index, that maps to a /// local index dof_id_type _current_elem_id; @@ -319,15 +264,6 @@ class StaticCondensation : public PetscMatrixShellMatrix, public DofMapB /// Whether we have cached values via add_XXX() bool _have_cached_values; - - /// The variables in the reduced system - std::vector _reduced_vars; - - /// A dummyish system to help with DofObjects - System * _reduced_system; - - /// Owned storage of the reduced system sparsity pattern. Note that the \p SparseMatrix \p _sp data member is set to point to this - std::unique_ptr _reduced_sp; }; inline const SparseMatrix & StaticCondensation::get_condensed_mat() const @@ -336,23 +272,12 @@ inline const SparseMatrix & StaticCondensation::get_condensed_mat() cons return *_reduced_sys_mat; } -inline void StaticCondensation::dont_condense_vars(const std::unordered_set & vars) -{ - _uncondensed_vars.insert(vars.begin(), vars.end()); -} - inline LinearSolver & StaticCondensation::reduced_system_solver() { libmesh_assert_msg(_reduced_solver, "Reduced system solver not built yet"); return *_reduced_solver; } -inline const System & StaticCondensation::reduced_system() const -{ - libmesh_assert(_reduced_system); - return *_reduced_system; -} - } #else @@ -366,11 +291,12 @@ class MeshBase; class System; class DofMap; class StaticCondensationPreconditioner; +class StaticCondensationDofMap; class StaticCondensation : public SparseMatrix { public: - StaticCondensation(const MeshBase &, const System &, const DofMap & dof_map); + StaticCondensation(const MeshBase &, const System &, const DofMap & full_dof_map); const std::unordered_set & uncondensed_vars() const { libmesh_not_implemented(); } StaticCondensationPreconditioner & get_preconditioner() { libmesh_not_implemented(); } diff --git a/include/numerics/static_condensation_dof_map.h b/include/numerics/static_condensation_dof_map.h new file mode 100644 index 00000000000..f1105763f86 --- /dev/null +++ b/include/numerics/static_condensation_dof_map.h @@ -0,0 +1,167 @@ +// The libMesh Finite Element Library. +// Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#ifndef LIBMESH_STATIC_CONDENSATION_DOF_MAP_H +#define LIBMESH_STATIC_CONDENSATION_DOF_MAP_H + +#include "libmesh/libmesh_config.h" + +#include "libmesh/id_types.h" +#include "libmesh/libmesh_common.h" +#include "libmesh/dof_map_base.h" +#include "libmesh/variable.h" +#include "libmesh/sparsity_pattern.h" + +#include +#include +#include + +namespace libMesh +{ +class MeshBase; +class System; +class DofMap; +class Elem; + +class StaticCondensationDofMap : public DofMapBase +{ +public: + StaticCondensationDofMap(const MeshBase & mesh, System & system, const DofMap & dof_map); + virtual ~StaticCondensationDofMap(); + + // + // Unique methods + // + + /** + * Build the element global to local index maps + */ + void init(); + + /** + * Add \p vars to the list of variables not to condense. This can be useful when some variable's + * equation is discretized with a DG method or if including the variable in the condensed block + * diagonal would result in it being singular + */ + void dont_condense_vars(const std::unordered_set & vars); + + /** + * @returns our list of variables for whom we do not condense out any dofs + */ + const std::unordered_set & uncondensed_vars() const { return _uncondensed_vars; } + + virtual unsigned int n_variables() const override; + + virtual const Variable & variable(const unsigned int c) const override; + + virtual void dof_indices(const Elem * const elem, + std::vector & di, + const unsigned int vn, + int p_level = -12345) const override; + + virtual void dof_indices(const Node * const node, + std::vector & di, + const unsigned int vn) const override; + + /* + * @returns The dummyish reduced system + */ + const System & reduced_system() const; + + /** + * Whether we are initialized + */ + bool initialized() const { return _sc_is_initialized; } + + virtual void clear() override; + +private: + /** + * Data stored on a per-element basis used to compute element Schur complements and their + * applications to vectors + */ + struct DofData + { + /// The uncondensed degrees of freedom with global numbering corresponding to the the \emph reduced + /// system. Note that initially this will actually hold the indices corresponding to the fully + /// sized problem, but we will swap it out by the time we are done initializing + std::vector> reduced_space_indices; + + /// A map from the global degree of freedom number for the full system (condensed + uncondensed) + /// to an element local number. If this map is queried with a condensed dof, nothing will be + /// found. The size of this container will be the number of uncondensed degrees of freedom whose + /// basis functions are nonzero on the element + std::unordered_map uncondensed_global_to_local_map; + /// A map from the global degree of freedom number for the full system (condensed + uncondensed) + /// to an element local number. If this map is queried with an uncondensed dof, nothing will be + /// found. The size of this container will be the number of condensed degrees of freedom whose + /// basis functions are nonzero on the element + std::unordered_map condensed_global_to_local_map; + }; + + /// Friend the static condensation matrix class so they can inspect our degree of freedom data + friend class StaticCondensation; + + /// A map from element ID to Schur complement data + std::unordered_map _elem_to_dof_data; + + /// All the uncondensed degrees of freedom (numbered in the "full" uncondensed + condensed + /// space). This data member is used for creating subvectors corresponding to only uncondensed + /// dofs + std::vector _local_uncondensed_dofs; + + const MeshBase & _mesh; + System & _system; + const DofMap & _dof_map; + + /// Variables for which we will keep all dofs + std::unordered_set _uncondensed_vars; + + /// Whether our object has been initialized + bool _sc_is_initialized; + + /// The variables in the reduced system + std::vector _reduced_vars; + + /// A dummyish system to help with DofObjects + System * _reduced_system; + + /// Owned storage of the reduced system sparsity pattern + std::unique_ptr _reduced_sp; + + /// Number of on-diagonal nonzeros per row in the reduced system + std::vector _reduced_nnz; + + /// Number of off-diagonal nonzeros per row in the reduced system + std::vector _reduced_noz; +}; + +inline void +StaticCondensationDofMap::dont_condense_vars(const std::unordered_set & vars) +{ + _uncondensed_vars.insert(vars.begin(), vars.end()); +} + +inline const System & StaticCondensationDofMap::reduced_system() const +{ + libmesh_assert(_reduced_system); + return *_reduced_system; +} + +} + +#endif // LIBMESH_STATIC_CONDENSATION_DOF_MAP_H diff --git a/include/systems/implicit_system.h b/include/systems/implicit_system.h index 4b2e533316f..7694e6736fb 100644 --- a/include/systems/implicit_system.h +++ b/include/systems/implicit_system.h @@ -338,42 +338,32 @@ class ImplicitSystem : public ExplicitSystem */ mutable std::unique_ptr> linear_solver; + virtual void create_static_condensation() override; + +protected: /** - * Request that static condensation be performed for this system + * Adds the system matrix */ - virtual void create_static_condensation(); + virtual void add_matrices() override; /** - * Retrieve the static condensation class. Errors if \p create_static_condensation() has not been - * called prior, so calls to this should be guarded by checking \p has_static_condensation() + * Sets up the static condensation preconditioner for the supplied \p solver */ - StaticCondensation & get_static_condensation(); + template + void setup_static_condensation_preconditioner(T & solver); +private: /** - * @returns Whether this system will be statically condensed + * Create the static condensation system matrix */ - bool has_static_condensation() const { return _sc; } + void create_static_condensation_system_matrix(); -protected: /** - * Adds the system matrix + * The system matrix for static condensation problems */ - virtual void add_matrices() override; - - /// Static condensation class - StaticCondensation * _sc; + StaticCondensation * _sc_system_matrix; }; -inline -StaticCondensation & -ImplicitSystem::get_static_condensation() -{ - if (!_sc) - libmesh_error_msg("Static condensation was not requested by the user"); - - return *_sc; -} - } // namespace libMesh #endif // LIBMESH_IMPLICIT_SYSTEM_H diff --git a/include/systems/system.h b/include/systems/system.h index 95c13aee42b..6f44055a53d 100644 --- a/include/systems/system.h +++ b/include/systems/system.h @@ -74,6 +74,7 @@ class SystemSubset; class FEType; class SystemNorm; enum FEMNormType : int; +class StaticCondensationDofMap; /** * \brief Manages consistently variables, degrees of freedom, and coefficient @@ -1894,7 +1895,7 @@ class System : public ReferenceCountedObject, * \returns \p true if this \p System has a matrix associated with the * given name, \p false otherwise. */ - inline bool have_matrix (std::string_view mat_name) const { return _matrices.count(mat_name); }; + inline bool have_matrix (std::string_view mat_name) const { return _matrices.count(mat_name); } /** * \returns A const pointer to this system's additional matrix @@ -1943,6 +1944,22 @@ class System : public ReferenceCountedObject, */ std::string prefix() const { return this->name() + "_"; } + /** + * Request that static condensation be performed for this system + */ + virtual void create_static_condensation(); + + /** + * Retrieve the static condensation class. Errors if \p create_static_condensation() has not been + * called prior, so calls to this should be guarded by checking \p has_static_condensation() + */ + StaticCondensationDofMap & get_static_condensation_dof_map(); + + /** + * @returns Whether this system will be statically condensed + */ + bool has_static_condensation() const { return _sc_dof_map.get(); } + protected: /** @@ -2009,6 +2026,11 @@ class System : public ReferenceCountedObject, virtual bool condense_constrained_dofs() const { return false; } private: + /** + * Creates the degree of freedom map for the statically condensed system + */ + void create_static_condensation_dof_map(); + /** * Helper function to keep DofMap forward declarable in system.h */ @@ -2109,6 +2131,9 @@ class System : public ReferenceCountedObject, dof_id_type write_serialized_vector (Xdr & io, const NumericVector & vec) const; + /// Degree of freedom map for the condensed space + std::unique_ptr _sc_dof_map; + /** * Function that initializes the system. */ @@ -2729,6 +2754,16 @@ System::prefer_hash_table_matrix_assembly(const bool preference) _prefer_hash_table_matrix_assembly = preference; } +inline +StaticCondensationDofMap & +System::get_static_condensation_dof_map() +{ + if (!_sc_dof_map) + libmesh_error_msg("Static condensation was not requested by the user"); + + return *_sc_dof_map; +} + } // namespace libMesh #endif // LIBMESH_SYSTEM_H diff --git a/src/base/dof_map.C b/src/base/dof_map.C index 0ddb20e0c4a..51f2b7c14a3 100644 --- a/src/base/dof_map.C +++ b/src/base/dof_map.C @@ -79,7 +79,7 @@ DofMap::build_sparsity (const MeshBase & mesh, // between neighbor dofs bool implicit_neighbor_dofs = this->use_coupled_neighbor_dofs(mesh); - const StaticCondensation * sc = nullptr; + const StaticCondensationDofMap * sc = nullptr; if (use_condensed_system) { libmesh_assert(this->has_static_condensation()); @@ -135,7 +135,7 @@ DofMap::build_sparsity (const MeshBase & mesh, DofMap::DofMap(const unsigned int number, MeshBase & mesh) : - ParallelObject (mesh.comm()), + DofMapBase (mesh.comm()), _dof_coupling(nullptr), _error_on_constraint_loop(false), _constrained_sparsity_construction(false), @@ -145,8 +145,6 @@ DofMap::DofMap(const unsigned int number, _sys_number(number), _mesh(mesh), _matrices(), - _first_df(), - _end_df(), _first_scalar_df(), _send_list(), _augment_sparsity_pattern(nullptr), @@ -158,7 +156,6 @@ DofMap::DofMap(const unsigned int number, _default_coupling(std::make_unique()), _default_evaluating(std::make_unique()), need_full_sparsity_pattern(false), - _n_dfs(0), _n_SCALAR_dofs(0) #ifdef LIBMESH_ENABLE_AMR , _n_old_dfs(0), @@ -906,6 +903,8 @@ void DofMap::invalidate_dofs(MeshBase & mesh) const void DofMap::clear() { + DofMapBase::clear(); + // we don't want to clear // the coupling matrix! // It should not change... @@ -954,8 +953,6 @@ void DofMap::clear() _variable_groups.clear(); _var_to_vg.clear(); _variable_group_numbers.clear(); - _first_df.clear(); - _end_df.clear(); _first_scalar_df.clear(); this->clear_send_list(); this->clear_sparsity(); @@ -975,8 +972,6 @@ void DofMap::clear() #endif _matrices.clear(); - - _n_dfs = 0; } @@ -992,7 +987,9 @@ std::size_t DofMap::distribute_dofs (MeshBase & mesh) libmesh_assert (mesh.is_prepared()); const processor_id_type proc_id = this->processor_id(); +#ifndef NDEBUG const processor_id_type n_proc = this->n_processors(); +#endif // libmesh_assert_greater (this->n_variables(), 0); libmesh_assert_less (proc_id, n_proc); @@ -1029,8 +1026,7 @@ std::size_t DofMap::distribute_dofs (MeshBase & mesh) (next_free_dof, mesh, constraining_subdomains); // Get DOF counts on all processors - std::vector dofs_on_proc(n_proc, 0); - this->comm().allgather(next_free_dof, dofs_on_proc); + const auto n_dofs = this->compute_dof_info(next_free_dof); // Resize and fill the _first_df and _end_df arrays #ifdef LIBMESH_ENABLE_AMR @@ -1038,15 +1034,6 @@ std::size_t DofMap::distribute_dofs (MeshBase & mesh) _end_old_df = _end_df; #endif - _first_df.resize(n_proc); - _end_df.resize (n_proc); - - // Get DOF offsets - _first_df[0] = 0; - for (processor_id_type i=1; i < n_proc; ++i) - _first_df[i] = _end_df[i-1] = _first_df[i-1] + dofs_on_proc[i-1]; - _end_df[n_proc-1] = _first_df[n_proc-1] + dofs_on_proc[n_proc-1]; - // Clear all the current DOF indices // (distribute_dofs expects them cleared!) this->invalidate_dofs(mesh); @@ -1126,10 +1113,9 @@ std::size_t DofMap::distribute_dofs (MeshBase & mesh) _n_old_dfs = _n_dfs; _first_old_scalar_df = _first_scalar_df; #endif - _n_dfs = _end_df[n_proc-1]; _first_scalar_df.clear(); _first_scalar_df.resize(this->n_variables(), DofObject::invalid_id); - dof_id_type current_SCALAR_dof_index = n_dofs() - n_SCALAR_dofs(); + dof_id_type current_SCALAR_dof_index = n_dofs - n_SCALAR_dofs(); // Calculate and cache the initial DoF indices for SCALAR variables. // This is an O(N_vars) calculation so we want to do it once per @@ -1165,13 +1151,7 @@ std::size_t DofMap::distribute_dofs (MeshBase & mesh) // dependencies to the send_list too. // this->sort_send_list (); - // Return total number of DOFs across all procs. We compute and - // return this as a std::size_t so that we can detect situations in - // which the total number of DOFs across all procs would exceed the - // capability of the underlying NumericVector representation to - // index into it correctly (std::size_t is the largest unsigned - // type, so no NumericVector representation can exceed it). - return std::accumulate(dofs_on_proc.begin(), dofs_on_proc.end(), static_cast(0)); + return n_dofs; } diff --git a/src/base/dof_map_base.C b/src/base/dof_map_base.C new file mode 100644 index 00000000000..73640c220aa --- /dev/null +++ b/src/base/dof_map_base.C @@ -0,0 +1,58 @@ +// The libMesh Finite Element Library. +// Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "libmesh/dof_map_base.h" +#include "libmesh/parallel_implementation.h" + +namespace libMesh +{ +std::size_t DofMapBase::compute_dof_info(const dof_id_type n_local_dofs) +{ + // Get DOF counts on all processors + const auto n_proc = this->n_processors(); + + std::vector dofs_on_proc(n_proc, 0); + this->comm().allgather(n_local_dofs, dofs_on_proc); + + // Resize and fill the _first_df and _end_df arrays + _first_df.resize(n_proc); + _end_df.resize(n_proc); + + // Get DOF offsets + _first_df[0] = 0; + for (processor_id_type i = 1; i < n_proc; ++i) + _first_df[i] = _end_df[i - 1] = _first_df[i - 1] + dofs_on_proc[i - 1]; + _end_df[n_proc - 1] = _first_df[n_proc - 1] + dofs_on_proc[n_proc - 1]; + + _n_dfs = _end_df[n_proc - 1]; + + // Return total number of DOFs across all procs. We compute and + // return this as a std::size_t so that we can detect situations in + // which the total number of DOFs across all procs would exceed the + // capability of the underlying NumericVector representation to + // index into it correctly (std::size_t is the largest unsigned + // type, so no NumericVector representation can exceed it). + return std::accumulate(dofs_on_proc.begin(), dofs_on_proc.end(), static_cast(0)); +} + +void DofMapBase::clear() +{ + _first_df.clear(); + _end_df.clear(); + _n_dfs = 0; +} +} diff --git a/src/base/sparsity_pattern.C b/src/base/sparsity_pattern.C index 437da705000..a34ddacf3be 100644 --- a/src/base/sparsity_pattern.C +++ b/src/base/sparsity_pattern.C @@ -30,7 +30,7 @@ #include "libmesh/parallel.h" #include "libmesh/parallel_sync.h" #include "libmesh/utility.h" -#include "libmesh/static_condensation.h" +#include "libmesh/static_condensation_dof_map.h" // TIMPI includes #include "timpi/communicator.h" @@ -50,7 +50,7 @@ Build::Build (const DofMap & dof_map_in, const bool implicit_neighbor_dofs_in, const bool need_full_sparsity_pattern_in, const bool calculate_constrained_in, - const StaticCondensation * const sc_in) : + const StaticCondensationDofMap * const sc_in) : ParallelObject(dof_map_in), dof_map(dof_map_in), dof_coupling(dof_coupling_in), diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index b80f447a485..878403f1bc0 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -29,6 +29,7 @@ #include "libmesh/system.h" #include "libmesh/petsc_matrix.h" #include "libmesh/equation_systems.h" +#include "libmesh/static_condensation_dof_map.h" #include "timpi/parallel_sync.h" #include @@ -36,11 +37,13 @@ namespace libMesh { StaticCondensation::StaticCondensation(const MeshBase & mesh, System & system, - const DofMap & dof_map) - : PetscMatrixShellMatrix(dof_map.comm()), + const DofMap & full_dof_map, + const StaticCondensationDofMap & reduced_dof_map) + : PetscMatrixShellMatrix(full_dof_map.comm()), _mesh(mesh), _system(system), - _dof_map(dof_map), + _full_dof_map(full_dof_map), + _reduced_dof_map(reduced_dof_map), _current_elem_id(DofObject::invalid_id), _sc_is_initialized(false), _have_cached_values(false) @@ -70,8 +73,7 @@ void StaticCondensation::clear() noexcept { PetscMatrixShellMatrix::clear(); - _elem_to_local_data.clear(); - _local_uncondensed_dofs.clear(); + _elem_to_matrix_data.clear(); _reduced_sys_mat.reset(); _reduced_sol.reset(); _reduced_rhs.reset(); @@ -115,293 +117,55 @@ void StaticCondensation::init() if (_sc_is_initialized) return; - std::vector elem_dofs; // only used to satisfy API - std::vector elem_uncondensed_dofs; - std::unordered_set local_uncondensed_dofs; - std::unordered_map> nonlocal_uncondensed_dofs; - dof_id_type condensed_local_dof_number = 0, uncondensed_local_dof_number = 0; - std::unordered_map *condensed_global_to_local_map = nullptr, - *uncondensed_global_to_local_map = nullptr; - std::set full_vars_present_in_reduced_sys; - - // Handle SCALAR dofs - for (const auto vg : make_range(_dof_map.n_variable_groups())) - if (const auto & vg_description = _dof_map.variable_group(vg); - vg_description.type().family == SCALAR) - { - std::vector scalar_dof_indices; - const processor_id_type last_pid = this->comm().size() - 1; - for (const auto vg_vn : make_range(vg_description.n_variables())) - { - const auto vn = vg_description.number(vg_vn); - _dof_map.SCALAR_dof_indices(scalar_dof_indices, vn); - if (this->comm().rank() == last_pid) - local_uncondensed_dofs.insert(scalar_dof_indices.begin(), scalar_dof_indices.end()); - else - nonlocal_uncondensed_dofs[last_pid].insert(scalar_dof_indices.begin(), - scalar_dof_indices.end()); - } - } - - auto scalar_dofs_functor = - [&elem_uncondensed_dofs, &uncondensed_local_dof_number, &uncondensed_global_to_local_map]( - const Elem & /*elem*/, - std::vector & dof_indices, - const std::vector & scalar_dof_indices) { - dof_indices.insert(dof_indices.end(), scalar_dof_indices.begin(), scalar_dof_indices.end()); - elem_uncondensed_dofs.insert( - elem_uncondensed_dofs.end(), scalar_dof_indices.begin(), scalar_dof_indices.end()); - for (const auto global_dof : scalar_dof_indices) - (*uncondensed_global_to_local_map)[global_dof] = uncondensed_local_dof_number++; - }; - - auto field_dofs_functor = [this, - &local_uncondensed_dofs, - &nonlocal_uncondensed_dofs, - &elem_uncondensed_dofs, - &uncondensed_local_dof_number, - &condensed_local_dof_number, - &uncondensed_global_to_local_map, - &condensed_global_to_local_map](const Elem & elem, - const unsigned int node_num, - const unsigned int var_num, - std::vector & dof_indices, - const dof_id_type field_dof) { - dof_indices.push_back(field_dof); - - bool uncondensed_dof = false; - if (_uncondensed_vars.count(var_num)) - { - libmesh_assert_msg( - node_num == invalid_uint, - "Users should not be providing continuous FEM variables to the uncondensed vars API"); - uncondensed_dof = true; - elem_uncondensed_dofs.push_back(field_dof); - if (elem.processor_id() == this->processor_id()) - local_uncondensed_dofs.insert(field_dof); - else - nonlocal_uncondensed_dofs[elem.processor_id()].insert(field_dof); - } - - if (node_num != invalid_uint && !elem.is_internal(node_num)) - { - uncondensed_dof = true; - elem_uncondensed_dofs.push_back(field_dof); - const auto & nd_ref = elem.node_ref(node_num); - if (nd_ref.processor_id() == this->processor_id()) - local_uncondensed_dofs.insert(field_dof); - else - nonlocal_uncondensed_dofs[nd_ref.processor_id()].insert(field_dof); - } - - if (uncondensed_dof) - (*uncondensed_global_to_local_map)[field_dof] = uncondensed_local_dof_number++; - else - (*condensed_global_to_local_map)[field_dof] = condensed_local_dof_number++; - }; + libmesh_assert(_reduced_dof_map.initialized()); - for (auto elem : _mesh.active_local_element_ptr_range()) + for (const auto & [elem_id, dof_data] : _reduced_dof_map._elem_to_dof_data) { - auto & local_data = _elem_to_local_data[elem->id()]; - condensed_local_dof_number = 0; - uncondensed_local_dof_number = 0; - condensed_global_to_local_map = &local_data.condensed_global_to_local_map; - uncondensed_global_to_local_map = &local_data.uncondensed_global_to_local_map; - - const auto sub_id = elem->subdomain_id(); - for (const auto vg : make_range(_dof_map.n_variable_groups())) - { - const auto & var_group = _dof_map.variable_group(vg); - if (!var_group.active_on_subdomain(sub_id)) - continue; - - for (const auto v : make_range(var_group.n_variables())) - { - const auto var_num = var_group.number(v); - local_data.reduced_space_indices.resize(var_num + 1); - elem_uncondensed_dofs.clear(); - _dof_map.dof_indices(elem, - elem_dofs, - var_num, - scalar_dofs_functor, - field_dofs_functor, - elem->p_level()); - if (!elem_uncondensed_dofs.empty()) - { - auto & var_reduced_space_indices = local_data.reduced_space_indices[var_num]; - var_reduced_space_indices.insert(var_reduced_space_indices.end(), - elem_uncondensed_dofs.begin(), - elem_uncondensed_dofs.end()); - full_vars_present_in_reduced_sys.insert(var_num); - } - } - } + auto & matrix_data = _elem_to_matrix_data[elem_id]; - const auto condensed_dof_size = condensed_global_to_local_map->size(); - const auto uncondensed_dof_size = uncondensed_global_to_local_map->size(); + const auto condensed_dof_size = dof_data.condensed_global_to_local_map.size(); + const auto uncondensed_dof_size = dof_data.uncondensed_global_to_local_map.size(); - local_data.Acc.setZero(condensed_dof_size, condensed_dof_size); - local_data.Acu.setZero(condensed_dof_size, uncondensed_dof_size); - local_data.Auc.setZero(uncondensed_dof_size, condensed_dof_size); - local_data.Auu.setZero(uncondensed_dof_size, uncondensed_dof_size); + matrix_data.Acc.setZero(condensed_dof_size, condensed_dof_size); + matrix_data.Acu.setZero(condensed_dof_size, uncondensed_dof_size); + matrix_data.Auc.setZero(uncondensed_dof_size, condensed_dof_size); + matrix_data.Auu.setZero(uncondensed_dof_size, uncondensed_dof_size); } - _local_uncondensed_dofs.assign(local_uncondensed_dofs.begin(), local_uncondensed_dofs.end()); - local_uncondensed_dofs.clear(); - // // Build the reduced system data // - - const dof_id_type n_local = _local_uncondensed_dofs.size(); - dof_id_type n = n_local; - this->comm().sum(n); + const auto n = _reduced_dof_map.n_dofs(); + const auto n_local = _reduced_dof_map.n_local_dofs(); _reduced_solver = LinearSolver::build(this->comm()); _reduced_solver->init((_system.name() + "_condensed_").c_str()); _reduced_rhs = NumericVector::build(this->comm()); // Init the RHS vector so we can conveniently get processor row offsets _reduced_rhs->init(n, n_local); - // Build a map from the full size problem uncondensed dof indices to the reduced problem - // (uncondensed) dof indices - std::unordered_map full_dof_to_reduced_dof; - const auto local_start = _reduced_rhs->first_local_index(); - for (const auto i : index_range(_local_uncondensed_dofs)) - full_dof_to_reduced_dof[_local_uncondensed_dofs[i]] = i + local_start; - - // Build the condensed system sparsity pattern - _reduced_sp = this->_dof_map.build_sparsity( - this->_mesh, /*calculate_constrained=*/false, /*use_condensed_system=*/true); - _sp = _reduced_sp.get(); + // Initialize the reduced system matrix + _sp = _reduced_dof_map._reduced_sp.get(); _reduced_sys_mat = SparseMatrix::build(this->comm()); - const auto & nnz = _sp->get_n_nz(); - const auto & noz = _sp->get_n_oz(); - libmesh_assert(nnz.size() == noz.size()); if (auto * const petsc_mat = dynamic_cast *>(_reduced_sys_mat.get())) { // Optimization for PETSc. This is critical for problems in which there are SCALAR dofs that // introduce dense rows to avoid allocating a dense matrix - std::vector reduced_nnz, reduced_noz; - reduced_nnz.resize(_local_uncondensed_dofs.size()); - reduced_noz.resize(_local_uncondensed_dofs.size()); - for (const dof_id_type local_reduced_i : index_range(_local_uncondensed_dofs)) - { - const dof_id_type full_i = _local_uncondensed_dofs[local_reduced_i]; - const dof_id_type local_full_i = full_i - _dof_map.first_dof(); - libmesh_assert(local_full_i < nnz.size()); - reduced_nnz[local_reduced_i] = nnz[local_full_i]; - reduced_noz[local_reduced_i] = noz[local_full_i]; - } - petsc_mat->init(n, n, n_local, n_local, reduced_nnz, reduced_noz); + petsc_mat->init( + n, n, n_local, n_local, _reduced_dof_map._reduced_nnz, _reduced_dof_map._reduced_noz); } else { + const auto & nnz = _sp->get_n_nz(); + const auto & noz = _sp->get_n_oz(); const auto nz = nnz.empty() ? dof_id_type(0) : *std::max_element(nnz.begin(), nnz.end()); const auto oz = noz.empty() ? dof_id_type(0) : *std::max_element(noz.begin(), noz.end()); _reduced_sys_mat->init(n, n, n_local, n_local, nz, oz); } - // - // Now we need to pull our nonlocal data - // - - // build our queries - std::unordered_map> nonlocal_uncondensed_dofs_mapvec; - for (const auto & [pid, set] : nonlocal_uncondensed_dofs) - { - auto & vec = nonlocal_uncondensed_dofs_mapvec[pid]; - vec.assign(set.begin(), set.end()); - } - // clear no longer needed memory - nonlocal_uncondensed_dofs.clear(); - - auto gather_functor = [&full_dof_to_reduced_dof](processor_id_type, - const std::vector & full_dof_ids, - std::vector & reduced_dof_ids) { - reduced_dof_ids.resize(full_dof_ids.size()); - for (const auto i : index_range(full_dof_ids)) - reduced_dof_ids[i] = libmesh_map_find(full_dof_to_reduced_dof, full_dof_ids[i]); - }; - - auto action_functor = - [&full_dof_to_reduced_dof](processor_id_type, - const std::vector & full_dof_ids, - const std::vector & reduced_dof_ids) { - for (const auto i : index_range(full_dof_ids)) - { - libmesh_assert(!full_dof_to_reduced_dof.count(full_dof_ids[i])); - full_dof_to_reduced_dof[full_dof_ids[i]] = reduced_dof_ids[i]; - } - }; - - TIMPI::pull_parallel_vector_data(this->comm(), - nonlocal_uncondensed_dofs_mapvec, - gather_functor, - action_functor, - &DofObject::invalid_id); - nonlocal_uncondensed_dofs_mapvec.clear(); - - // Determine the variables with any degrees of freedom present in the reduced system - _communicator.set_union(full_vars_present_in_reduced_sys); - _reduced_vars.reserve(full_vars_present_in_reduced_sys.size()); - unsigned int first_local_number = 0; - for (const auto i : index_range(full_vars_present_in_reduced_sys)) - { - const auto full_var_num = *std::next(full_vars_present_in_reduced_sys.begin(), i); - const auto & full_var = _dof_map.variable(full_var_num); - _reduced_vars.push_back(Variable{nullptr, - full_var.name(), - cast_int(i), - first_local_number, - full_var.type()}); - first_local_number += _reduced_vars.back().n_components(_mesh); - } - - // Now we can finally set our element reduced dof indices - std::vector var_full_dof_indices; - for (auto & [elem, local_data] : _elem_to_local_data) - { - libmesh_ignore(elem); - auto & reduced_space_indices = local_data.reduced_space_indices; - // Start erasing from the back to reduce the number of copy assignment operations - if (reduced_space_indices.size()) - for (typename std::vector::difference_type i = - reduced_space_indices.size() - 1; - i >= 0; - --i) - if (!full_vars_present_in_reduced_sys.count(i)) - reduced_space_indices.erase(reduced_space_indices.begin() + i); - // It is theoretically possible that we have an element that doesn't have dofs for one of the - // variables present in our reduced system, which is why the assertion below is not an - // equality assertion - libmesh_assert(reduced_space_indices.size() <= full_vars_present_in_reduced_sys.size()); - - for (auto & var_dof_indices : reduced_space_indices) - { - var_full_dof_indices = var_dof_indices; - var_dof_indices.clear(); - for (const auto full_dof : var_full_dof_indices) - var_dof_indices.push_back(libmesh_map_find(full_dof_to_reduced_dof, full_dof)); - } - } - // Build ghosted full solution vector. Note that this is, in general, *not equal* to the system // solution, e.g. this may correspond to the solution for the Newton *update* _ghosted_full_sol = _system.current_local_solution->clone(); - // Prevent querying Nodes for dof indices - std::vector nvpg(_reduced_vars.size()); - for (auto & elem : nvpg) - elem = 1; - - _reduced_system = &_system.get_equation_systems().add_system("Basic", "reduced"); - _reduced_system->init(); - for (auto * const nd : _mesh.active_node_ptr_range()) - { - nd->set_n_vars_per_group(_reduced_system->number(), nvpg); - for (const auto g : index_range(nvpg)) - nd->set_n_comp_group(_reduced_system->number(), g, 0); - } _sc_is_initialized = true; } @@ -419,18 +183,18 @@ void StaticCondensation::close() DenseMatrix shim; std::vector reduced_space_indices; - for (auto & [elem_id, local_data] : _elem_to_local_data) + for (auto & [elem_id, matrix_data] : _elem_to_matrix_data) { - libmesh_ignore(elem_id); + const auto & dof_data = libmesh_map_find(_reduced_dof_map._elem_to_dof_data, elem_id); reduced_space_indices.clear(); - local_data.AccFactor = local_data.Acc.partialPivLu(); + matrix_data.AccFactor = matrix_data.Acc.partialPivLu(); const EigenMatrix S = - local_data.Auu - local_data.Auc * local_data.AccFactor.solve(local_data.Acu); + matrix_data.Auu - matrix_data.Auc * matrix_data.AccFactor.solve(matrix_data.Acu); shim.resize(S.rows(), S.cols()); for (const auto i : make_range(S.rows())) for (const auto j : make_range(S.cols())) shim(i, j) = S(i, j); - for (const auto & var_reduced_space_indices : local_data.reduced_space_indices) + for (const auto & var_reduced_space_indices : dof_data.reduced_space_indices) reduced_space_indices.insert(reduced_space_indices.end(), var_reduced_space_indices.begin(), var_reduced_space_indices.end()); @@ -450,23 +214,23 @@ bool StaticCondensation::closed() const void StaticCondensation::zero() { _reduced_sys_mat->zero(); - for (auto & [elem_id, local_data] : _elem_to_local_data) + for (auto & [elem_id, matrix_data] : _elem_to_matrix_data) { libmesh_ignore(elem_id); - local_data.Acc.setZero(); - local_data.Acu.setZero(); - local_data.Auc.setZero(); - local_data.Auu.setZero(); + matrix_data.Acc.setZero(); + matrix_data.Acu.setZero(); + matrix_data.Auc.setZero(); + matrix_data.Auu.setZero(); } } void StaticCondensation::setup() { libmesh_assert(this->closed()); } -numeric_index_type StaticCondensation::m() const { return _dof_map.n_dofs(); } +numeric_index_type StaticCondensation::m() const { return _full_dof_map.n_dofs(); } -numeric_index_type StaticCondensation::row_start() const { return _dof_map.first_dof(); } +numeric_index_type StaticCondensation::row_start() const { return _full_dof_map.first_dof(); } -numeric_index_type StaticCondensation::row_stop() const { return _dof_map.end_dof(); } +numeric_index_type StaticCondensation::row_stop() const { return _full_dof_map.end_dof(); } void StaticCondensation::set(const numeric_index_type, const numeric_index_type, const Number) { @@ -492,16 +256,17 @@ void StaticCondensation::add_matrix(const DenseMatrix & dm, const std::vector & cols) { libmesh_assert(_current_elem_id != DofObject::invalid_id); - auto & local_data = libmesh_map_find(_elem_to_local_data, _current_elem_id); + auto & matrix_data = libmesh_map_find(_elem_to_matrix_data, _current_elem_id); + const auto & dof_data = libmesh_map_find(_reduced_dof_map._elem_to_dof_data, _current_elem_id); EigenMatrix * mat; - auto info_from_index = [&local_data](const auto global_index) { - auto index_it = local_data.condensed_global_to_local_map.find(global_index); - const bool index_is_condensed = index_it != local_data.condensed_global_to_local_map.end(); + auto info_from_index = [&dof_data](const auto global_index) { + auto index_it = dof_data.condensed_global_to_local_map.find(global_index); + const bool index_is_condensed = index_it != dof_data.condensed_global_to_local_map.end(); if (!index_is_condensed) { - index_it = local_data.uncondensed_global_to_local_map.find(global_index); - libmesh_assert(index_it != local_data.uncondensed_global_to_local_map.end()); + index_it = dof_data.uncondensed_global_to_local_map.find(global_index); + libmesh_assert(index_it != dof_data.uncondensed_global_to_local_map.end()); } return std::make_pair(index_is_condensed, index_it->second); }; @@ -516,16 +281,16 @@ void StaticCondensation::add_matrix(const DenseMatrix & dm, if (i_is_condensed) { if (j_is_condensed) - mat = &local_data.Acc; + mat = &matrix_data.Acc; else - mat = &local_data.Acu; + mat = &matrix_data.Acu; } else { if (j_is_condensed) - mat = &local_data.Auc; + mat = &matrix_data.Auc; else - mat = &local_data.Auu; + mat = &matrix_data.Auu; } (*mat)(local_i, local_j) += dm(i, j); } @@ -583,26 +348,28 @@ void StaticCondensation::forward_elimination(const NumericVector & full_ std::vector elem_condensed_rhs_vec; EigenVector elem_condensed_rhs, elem_uncondensed_rhs; - full_rhs.create_subvector(*_reduced_rhs, _local_uncondensed_dofs, /*all_global_entries=*/false); + full_rhs.create_subvector( + *_reduced_rhs, _reduced_dof_map._local_uncondensed_dofs, /*all_global_entries=*/false); std::vector reduced_space_indices; for (auto elem : _mesh.active_local_element_ptr_range()) { - auto & local_data = libmesh_map_find(_elem_to_local_data, elem->id()); + auto & matrix_data = libmesh_map_find(_elem_to_matrix_data, elem->id()); reduced_space_indices.clear(); - for (const auto & var_reduced_space_indices : local_data.reduced_space_indices) + const auto & dof_data = libmesh_map_find(_reduced_dof_map._elem_to_dof_data, elem->id()); + for (const auto & var_reduced_space_indices : dof_data.reduced_space_indices) reduced_space_indices.insert(reduced_space_indices.end(), var_reduced_space_indices.begin(), var_reduced_space_indices.end()); - elem_condensed_dofs.resize(local_data.condensed_global_to_local_map.size()); - for (const auto & [global_dof, local_dof] : local_data.condensed_global_to_local_map) + elem_condensed_dofs.resize(dof_data.condensed_global_to_local_map.size()); + for (const auto & [global_dof, local_dof] : dof_data.condensed_global_to_local_map) { libmesh_assert(local_dof < elem_condensed_dofs.size()); elem_condensed_dofs[local_dof] = global_dof; } set_local_vectors(full_rhs, elem_condensed_dofs, elem_condensed_rhs_vec, elem_condensed_rhs); - elem_uncondensed_rhs = -local_data.Auc * local_data.AccFactor.solve(elem_condensed_rhs); + elem_uncondensed_rhs = -matrix_data.Auc * matrix_data.AccFactor.solve(elem_condensed_rhs); libmesh_assert(cast_int(elem_uncondensed_rhs.size()) == reduced_space_indices.size()); @@ -620,15 +387,16 @@ void StaticCondensation::backwards_substitution(const NumericVector & fu for (auto elem : _mesh.active_local_element_ptr_range()) { - auto & local_data = _elem_to_local_data[elem->id()]; - elem_condensed_dofs.resize(local_data.condensed_global_to_local_map.size()); - elem_uncondensed_dofs.resize(local_data.uncondensed_global_to_local_map.size()); - for (const auto & [global_dof, local_dof] : local_data.condensed_global_to_local_map) + auto & matrix_data = libmesh_map_find(_elem_to_matrix_data, elem->id()); + const auto & dof_data = libmesh_map_find(_reduced_dof_map._elem_to_dof_data, elem->id()); + elem_condensed_dofs.resize(dof_data.condensed_global_to_local_map.size()); + elem_uncondensed_dofs.resize(dof_data.uncondensed_global_to_local_map.size()); + for (const auto & [global_dof, local_dof] : dof_data.condensed_global_to_local_map) { libmesh_assert(local_dof < elem_condensed_dofs.size()); elem_condensed_dofs[local_dof] = global_dof; } - for (const auto & [global_dof, local_dof] : local_data.uncondensed_global_to_local_map) + for (const auto & [global_dof, local_dof] : dof_data.uncondensed_global_to_local_map) { libmesh_assert(local_dof < elem_uncondensed_dofs.size()); elem_uncondensed_dofs[local_dof] = global_dof; @@ -641,7 +409,7 @@ void StaticCondensation::backwards_substitution(const NumericVector & fu elem_uncondensed_sol); elem_condensed_sol = - local_data.AccFactor.solve(elem_condensed_rhs - local_data.Acu * elem_uncondensed_sol); + matrix_data.AccFactor.solve(elem_condensed_rhs - matrix_data.Acu * elem_uncondensed_sol); full_sol.insert(elem_condensed_sol.data(), elem_condensed_dofs); } @@ -656,49 +424,18 @@ void StaticCondensation::apply(const NumericVector & full_rhs, // initial guess for the Krylov solve as well as lead to bewildered users who expect their initial // residual norm to equal the norm of the RHS full_parallel_sol.zero(); - _reduced_sol = full_parallel_sol.get_subvector(_local_uncondensed_dofs); + _reduced_sol = full_parallel_sol.get_subvector(_reduced_dof_map._local_uncondensed_dofs); _reduced_solver->solve(*_reduced_sys_mat, *_reduced_sol, *_reduced_rhs, 1e-5, 300); // Must restore to the full solution because during backwards substitution we will need to be able // to read ghosted dofs and we don't support ghosting of subvectors - full_parallel_sol.restore_subvector(std::move(_reduced_sol), _local_uncondensed_dofs); + full_parallel_sol.restore_subvector(std::move(_reduced_sol), + _reduced_dof_map._local_uncondensed_dofs); *_ghosted_full_sol = full_parallel_sol; backwards_substitution(full_rhs, full_parallel_sol); } SolverPackage StaticCondensation::solver_package() { return libMesh::default_solver_package(); } -unsigned int StaticCondensation::n_variables() const { return _reduced_vars.size(); } - -const Variable & StaticCondensation::variable(const unsigned int c) const -{ - return _reduced_vars[c]; -} - -void StaticCondensation::dof_indices(const Elem * const elem, - std::vector & di, - const unsigned int vn, - int /*p_level*/) const -{ - di.clear(); - di = libmesh_map_find(_elem_to_local_data, elem->id()).reduced_space_indices[vn]; -} - -void StaticCondensation::dof_indices(const Node * const, - std::vector &, - const unsigned int) const -{ - libmesh_error_msg( - "StaticCondensation dof indices are only meant to be queried with elements, not nodes"); -} - -dof_id_type StaticCondensation::first_dof() const { return _reduced_sys_mat->row_start(); } - -dof_id_type StaticCondensation::end_dof() const { return _reduced_sys_mat->row_stop(); } - -dof_id_type StaticCondensation::n_dofs() const { return _reduced_sys_mat->m(); } - -dof_id_type StaticCondensation::n_local_dofs() const { return _reduced_sys_mat->local_m(); } - } #else @@ -706,8 +443,10 @@ dof_id_type StaticCondensation::n_local_dofs() const { return _reduced_sys_mat-> namespace libMesh { -StaticCondensation::StaticCondensation(const MeshBase &, const System &, const DofMap & dof_map) - : SparseMatrix(dof_map.comm()) +StaticCondensation::StaticCondensation(const MeshBase &, + const System &, + const DofMap & full_dof_map) + : SparseMatrix(full_dof_map.comm()) { libmesh_error_msg( "Static condensation requires configuring libMesh with PETSc and Eigen support"); diff --git a/src/numerics/static_condensation_dof_map.C b/src/numerics/static_condensation_dof_map.C new file mode 100644 index 00000000000..05c7cdd1ab4 --- /dev/null +++ b/src/numerics/static_condensation_dof_map.C @@ -0,0 +1,347 @@ +// The libMesh Finite Element Library. +// Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +#include "libmesh/static_condensation_dof_map.h" + +#include "libmesh/mesh_base.h" +#include "libmesh/dof_map.h" +#include "libmesh/elem.h" +#include "libmesh/int_range.h" +#include "libmesh/system.h" +#include "libmesh/equation_systems.h" +#include "timpi/parallel_sync.h" +#include + +namespace libMesh +{ +StaticCondensationDofMap::StaticCondensationDofMap(const MeshBase & mesh, + System & system, + const DofMap & dof_map) + : DofMapBase(dof_map.comm()), + _mesh(mesh), + _system(system), + _dof_map(dof_map), + _sc_is_initialized(false) +{ +} + +StaticCondensationDofMap::~StaticCondensationDofMap() = default; + +void StaticCondensationDofMap::init() +{ + if (_sc_is_initialized) + return; + + std::vector elem_dofs; // only used to satisfy API + std::vector elem_uncondensed_dofs; + std::unordered_set local_uncondensed_dofs; + std::unordered_map> nonlocal_uncondensed_dofs; + dof_id_type condensed_local_dof_number = 0, uncondensed_local_dof_number = 0; + std::unordered_map *condensed_global_to_local_map = nullptr, + *uncondensed_global_to_local_map = nullptr; + std::set full_vars_present_in_reduced_sys; + + // Handle SCALAR dofs + for (const auto vg : make_range(_dof_map.n_variable_groups())) + if (const auto & vg_description = _dof_map.variable_group(vg); + vg_description.type().family == SCALAR) + { + std::vector scalar_dof_indices; + const processor_id_type last_pid = this->comm().size() - 1; + for (const auto vg_vn : make_range(vg_description.n_variables())) + { + const auto vn = vg_description.number(vg_vn); + _dof_map.SCALAR_dof_indices(scalar_dof_indices, vn); + if (this->comm().rank() == last_pid) + local_uncondensed_dofs.insert(scalar_dof_indices.begin(), scalar_dof_indices.end()); + else + nonlocal_uncondensed_dofs[last_pid].insert(scalar_dof_indices.begin(), + scalar_dof_indices.end()); + } + } + + auto scalar_dofs_functor = + [&elem_uncondensed_dofs, &uncondensed_local_dof_number, &uncondensed_global_to_local_map]( + const Elem & /*elem*/, + std::vector & dof_indices, + const std::vector & scalar_dof_indices) { + dof_indices.insert(dof_indices.end(), scalar_dof_indices.begin(), scalar_dof_indices.end()); + elem_uncondensed_dofs.insert( + elem_uncondensed_dofs.end(), scalar_dof_indices.begin(), scalar_dof_indices.end()); + for (const auto global_dof : scalar_dof_indices) + (*uncondensed_global_to_local_map)[global_dof] = uncondensed_local_dof_number++; + }; + + auto field_dofs_functor = [this, + &local_uncondensed_dofs, + &nonlocal_uncondensed_dofs, + &elem_uncondensed_dofs, + &uncondensed_local_dof_number, + &condensed_local_dof_number, + &uncondensed_global_to_local_map, + &condensed_global_to_local_map](const Elem & elem, + const unsigned int node_num, + const unsigned int var_num, + std::vector & dof_indices, + const dof_id_type field_dof) { + dof_indices.push_back(field_dof); + + bool uncondensed_dof = false; + if (_uncondensed_vars.count(var_num)) + { + libmesh_assert_msg( + node_num == invalid_uint, + "Users should not be providing continuous FEM variables to the uncondensed vars API"); + uncondensed_dof = true; + elem_uncondensed_dofs.push_back(field_dof); + if (elem.processor_id() == this->processor_id()) + local_uncondensed_dofs.insert(field_dof); + else + nonlocal_uncondensed_dofs[elem.processor_id()].insert(field_dof); + } + + if (node_num != invalid_uint && !elem.is_internal(node_num)) + { + uncondensed_dof = true; + elem_uncondensed_dofs.push_back(field_dof); + const auto & nd_ref = elem.node_ref(node_num); + if (nd_ref.processor_id() == this->processor_id()) + local_uncondensed_dofs.insert(field_dof); + else + nonlocal_uncondensed_dofs[nd_ref.processor_id()].insert(field_dof); + } + + if (uncondensed_dof) + (*uncondensed_global_to_local_map)[field_dof] = uncondensed_local_dof_number++; + else + (*condensed_global_to_local_map)[field_dof] = condensed_local_dof_number++; + }; + + for (auto elem : _mesh.active_local_element_ptr_range()) + { + auto & dof_data = _elem_to_dof_data[elem->id()]; + condensed_local_dof_number = 0; + uncondensed_local_dof_number = 0; + condensed_global_to_local_map = &dof_data.condensed_global_to_local_map; + uncondensed_global_to_local_map = &dof_data.uncondensed_global_to_local_map; + + const auto sub_id = elem->subdomain_id(); + for (const auto vg : make_range(_dof_map.n_variable_groups())) + { + const auto & var_group = _dof_map.variable_group(vg); + if (!var_group.active_on_subdomain(sub_id)) + continue; + + for (const auto v : make_range(var_group.n_variables())) + { + const auto var_num = var_group.number(v); + dof_data.reduced_space_indices.resize(var_num + 1); + elem_uncondensed_dofs.clear(); + _dof_map.dof_indices(elem, + elem_dofs, + var_num, + scalar_dofs_functor, + field_dofs_functor, + elem->p_level()); + if (!elem_uncondensed_dofs.empty()) + { + auto & var_reduced_space_indices = dof_data.reduced_space_indices[var_num]; + var_reduced_space_indices.insert(var_reduced_space_indices.end(), + elem_uncondensed_dofs.begin(), + elem_uncondensed_dofs.end()); + full_vars_present_in_reduced_sys.insert(var_num); + } + } + } + } + + _local_uncondensed_dofs.assign(local_uncondensed_dofs.begin(), local_uncondensed_dofs.end()); + local_uncondensed_dofs.clear(); + + // + // Build the reduced system data + // + + const dof_id_type n_local = _local_uncondensed_dofs.size(); + dof_id_type n = n_local; + this->comm().sum(n); + + // Get DOF counts on all processors + this->compute_dof_info(n_local); + + // Build a map from the full size problem uncondensed dof indices to the reduced problem + // (uncondensed) dof indices + std::unordered_map full_dof_to_reduced_dof; + const auto local_start = _first_df[this->processor_id()]; + for (const auto i : index_range(_local_uncondensed_dofs)) + full_dof_to_reduced_dof[_local_uncondensed_dofs[i]] = i + local_start; + + // Build the condensed system sparsity pattern + _reduced_sp = this->_dof_map.build_sparsity( + this->_mesh, /*calculate_constrained=*/false, /*use_condensed_system=*/true); + const auto & nnz = _reduced_sp->get_n_nz(); + const auto & noz = _reduced_sp->get_n_oz(); + libmesh_assert(nnz.size() == noz.size()); + + // Optimization for PETSc. This is critical for problems in which there are SCALAR dofs that + // introduce dense rows to avoid allocating a dense matrix + _reduced_nnz.resize(_local_uncondensed_dofs.size()); + _reduced_noz.resize(_local_uncondensed_dofs.size()); + for (const dof_id_type local_reduced_i : index_range(_local_uncondensed_dofs)) + { + const dof_id_type full_i = _local_uncondensed_dofs[local_reduced_i]; + const dof_id_type local_full_i = full_i - _dof_map.first_dof(); + libmesh_assert(local_full_i < nnz.size()); + _reduced_nnz[local_reduced_i] = nnz[local_full_i]; + _reduced_noz[local_reduced_i] = noz[local_full_i]; + } + + // + // Now we need to pull our nonlocal data + // + + // build our queries + std::unordered_map> nonlocal_uncondensed_dofs_mapvec; + for (const auto & [pid, set] : nonlocal_uncondensed_dofs) + { + auto & vec = nonlocal_uncondensed_dofs_mapvec[pid]; + vec.assign(set.begin(), set.end()); + } + // clear no longer needed memory + nonlocal_uncondensed_dofs.clear(); + + auto gather_functor = [&full_dof_to_reduced_dof](processor_id_type, + const std::vector & full_dof_ids, + std::vector & reduced_dof_ids) { + reduced_dof_ids.resize(full_dof_ids.size()); + for (const auto i : index_range(full_dof_ids)) + reduced_dof_ids[i] = libmesh_map_find(full_dof_to_reduced_dof, full_dof_ids[i]); + }; + + auto action_functor = + [&full_dof_to_reduced_dof](processor_id_type, + const std::vector & full_dof_ids, + const std::vector & reduced_dof_ids) { + for (const auto i : index_range(full_dof_ids)) + { + libmesh_assert(!full_dof_to_reduced_dof.count(full_dof_ids[i])); + full_dof_to_reduced_dof[full_dof_ids[i]] = reduced_dof_ids[i]; + } + }; + + TIMPI::pull_parallel_vector_data(this->comm(), + nonlocal_uncondensed_dofs_mapvec, + gather_functor, + action_functor, + &DofObject::invalid_id); + nonlocal_uncondensed_dofs_mapvec.clear(); + + // Determine the variables with any degrees of freedom present in the reduced system + _communicator.set_union(full_vars_present_in_reduced_sys); + _reduced_vars.reserve(full_vars_present_in_reduced_sys.size()); + unsigned int first_local_number = 0; + for (const auto i : index_range(full_vars_present_in_reduced_sys)) + { + const auto full_var_num = *std::next(full_vars_present_in_reduced_sys.begin(), i); + const auto & full_var = _dof_map.variable(full_var_num); + _reduced_vars.push_back(Variable{nullptr, + full_var.name(), + cast_int(i), + first_local_number, + full_var.type()}); + first_local_number += _reduced_vars.back().n_components(_mesh); + } + + // Now we can finally set our element reduced dof indices + std::vector var_full_dof_indices; + for (auto & [elem, dof_data] : _elem_to_dof_data) + { + libmesh_ignore(elem); + auto & reduced_space_indices = dof_data.reduced_space_indices; + // Start erasing from the back to reduce the number of copy assignment operations + if (reduced_space_indices.size()) + for (typename std::vector::difference_type i = + reduced_space_indices.size() - 1; + i >= 0; + --i) + if (!full_vars_present_in_reduced_sys.count(i)) + reduced_space_indices.erase(reduced_space_indices.begin() + i); + // It is theoretically possible that we have an element that doesn't have dofs for one of the + // variables present in our reduced system, which is why the assertion below is not an + // equality assertion + libmesh_assert(reduced_space_indices.size() <= full_vars_present_in_reduced_sys.size()); + + for (auto & var_dof_indices : reduced_space_indices) + { + var_full_dof_indices = var_dof_indices; + var_dof_indices.clear(); + for (const auto full_dof : var_full_dof_indices) + var_dof_indices.push_back(libmesh_map_find(full_dof_to_reduced_dof, full_dof)); + } + } + + // Prevent querying Nodes for dof indices + std::vector nvpg(_reduced_vars.size()); + for (auto & elem : nvpg) + elem = 1; + + _reduced_system = &_system.get_equation_systems().add_system("Basic", "reduced"); + _reduced_system->init(); + for (auto * const nd : _mesh.active_node_ptr_range()) + { + nd->set_n_vars_per_group(_reduced_system->number(), nvpg); + for (const auto g : index_range(nvpg)) + nd->set_n_comp_group(_reduced_system->number(), g, 0); + } + _sc_is_initialized = true; +} + +unsigned int StaticCondensationDofMap::n_variables() const { return _reduced_vars.size(); } + +const Variable & StaticCondensationDofMap::variable(const unsigned int c) const +{ + return _reduced_vars[c]; +} + +void StaticCondensationDofMap::dof_indices(const Elem * const elem, + std::vector & di, + const unsigned int vn, + int /*p_level*/) const +{ + di.clear(); + di = libmesh_map_find(_elem_to_dof_data, elem->id()).reduced_space_indices[vn]; +} + +void StaticCondensationDofMap::dof_indices(const Node * const, + std::vector &, + const unsigned int) const +{ + libmesh_error_msg( + "StaticCondensationDofMap dof indices are only meant to be queried with elements, not nodes"); +} + +void StaticCondensationDofMap::clear() +{ + DofMapBase::clear(); + _elem_to_dof_data.clear(); + _uncondensed_vars.clear(); + _reduced_vars.clear(); + _reduced_sp = nullptr; + _reduced_nnz.clear(); + _reduced_noz.clear(); +} +} diff --git a/src/systems/implicit_system.C b/src/systems/implicit_system.C index 294c80869ae..a64684762a7 100644 --- a/src/systems/implicit_system.C +++ b/src/systems/implicit_system.C @@ -34,6 +34,8 @@ #include "libmesh/diagonal_matrix.h" #include "libmesh/utility.h" #include "libmesh/static_condensation.h" +#include "libmesh/static_condensation_preconditioner.h" +#include "libmesh/nonlinear_solver.h" namespace libMesh { @@ -44,25 +46,33 @@ ImplicitSystem::ImplicitSystem (EquationSystems & es, Parent (es, name_in, number_in), matrix (nullptr), - zero_out_matrix_and_rhs(true), - _sc (nullptr) + zero_out_matrix_and_rhs(true) { - if (libMesh::on_command_line("--" + name_in + "-static-condensation")) - this->create_static_condensation(); + if (this->has_static_condensation()) + this->create_static_condensation_system_matrix(); } ImplicitSystem::~ImplicitSystem () = default; - +void ImplicitSystem::create_static_condensation_system_matrix() +{ + auto sc_system_matrix = std::make_unique(this->get_mesh(), *this, this->get_dof_map(), this->get_static_condensation_dof_map()); + _sc_system_matrix = sc_system_matrix.get(); + matrix = &(this->add_matrix ("System Matrix", std::move(sc_system_matrix))); +} void ImplicitSystem::create_static_condensation () { - auto sc = std::make_unique(this->get_mesh(), *this, this->get_dof_map()); - _sc = sc.get(); - matrix = &(this->add_matrix ("System Matrix", std::move(sc))); - this->get_dof_map().add_static_condensation(*_sc); + Parent::create_static_condensation(); + this->create_static_condensation_system_matrix(); } +template +void ImplicitSystem::setup_static_condensation_preconditioner(T & solver) +{ + libmesh_assert(_sc_system_matrix); + solver.attach_preconditioner(&_sc_system_matrix->get_preconditioner()); +} void ImplicitSystem::clear () @@ -72,7 +82,7 @@ void ImplicitSystem::clear () // Restore us to a "basic" state matrix = nullptr; - _sc = nullptr; + _sc_system_matrix = nullptr; } @@ -1258,4 +1268,6 @@ SparseMatrix & ImplicitSystem::get_system_matrix() return *matrix; } +template void ImplicitSystem::setup_static_condensation_preconditioner(LinearSolver & solver); +template void ImplicitSystem::setup_static_condensation_preconditioner(NonlinearSolver & solver); } // namespace libMesh diff --git a/src/systems/linear_implicit_system.C b/src/systems/linear_implicit_system.C index 7b78745a56f..2d70907ac41 100644 --- a/src/systems/linear_implicit_system.C +++ b/src/systems/linear_implicit_system.C @@ -49,6 +49,9 @@ LinearImplicitSystem::LinearImplicitSystem (EquationSystems & es, // going to keep using it basically the way we did before it was // moved. linear_solver = LinearSolver::build(es.comm()); + + if (this->has_static_condensation()) + this->setup_static_condensation_preconditioner(*linear_solver); } @@ -60,7 +63,7 @@ LinearImplicitSystem::~LinearImplicitSystem () = default; void LinearImplicitSystem::create_static_condensation() { Parent::create_static_condensation(); - linear_solver->attach_preconditioner(&_sc->get_preconditioner()); + this->setup_static_condensation_preconditioner(*linear_solver); } diff --git a/src/systems/nonlinear_implicit_system.C b/src/systems/nonlinear_implicit_system.C index d3836fa4d5c..71235039b62 100644 --- a/src/systems/nonlinear_implicit_system.C +++ b/src/systems/nonlinear_implicit_system.C @@ -58,8 +58,8 @@ NonlinearImplicitSystem::NonlinearImplicitSystem (EquationSystems & es, es.parameters.set("reuse preconditioner") = false; es.parameters.set("reuse preconditioner maximum linear iterations") = 1; - if (_sc) - nonlinear_solver->attach_preconditioner(&_sc->get_preconditioner()); + if (this->has_static_condensation()) + this->setup_static_condensation_preconditioner(*nonlinear_solver); } @@ -71,7 +71,7 @@ NonlinearImplicitSystem::~NonlinearImplicitSystem () = default; void NonlinearImplicitSystem::create_static_condensation() { Parent::create_static_condensation(); - nonlinear_solver->attach_preconditioner(&_sc->get_preconditioner()); + this->setup_static_condensation_preconditioner(*nonlinear_solver); } diff --git a/src/systems/system.C b/src/systems/system.C index fbb40885876..7dce897d73e 100644 --- a/src/systems/system.C +++ b/src/systems/system.C @@ -38,6 +38,7 @@ #include "libmesh/parallel_fe_type.h" #include "libmesh/fe_interface.h" #include "libmesh/fe_compute_data.h" +#include "libmesh/static_condensation_dof_map.h" // includes for calculate_norm, point_* #include "libmesh/fe_base.h" @@ -73,6 +74,7 @@ System::System (EquationSystems & es, time (0.), qoi (0), qoi_error_estimates (0), + _sc_dof_map (nullptr), _init_system_function (nullptr), _init_system_object (nullptr), _assemble_system_function (nullptr), @@ -104,6 +106,8 @@ System::System (EquationSystems & es, { if (libMesh::on_command_line("--solver-system-names")) this->prefix_with_name(true); + if (libMesh::on_command_line("--" + name_in + "-static-condensation")) + this->create_static_condensation_dof_map(); } @@ -175,6 +179,8 @@ void System::clear () _variables.clear(); _variable_numbers.clear(); _dof_map->clear (); + if (_sc_dof_map) + _sc_dof_map->clear(); solution->clear (); current_local_solution->clear (); @@ -222,6 +228,10 @@ void System::init_data () // Distribute the degrees of freedom on the mesh auto total_dofs = _dof_map->distribute_dofs (mesh); + // With the global dofs determined, initialize the condensed system if it exists + if (_sc_dof_map) + _sc_dof_map->init(); + // Throw an error if the total number of DOFs is not capable of // being indexed by our solution vector. auto max_allowed_id = solution->max_allowed_id(); @@ -2842,4 +2852,15 @@ Tensor System::point_hessian(unsigned int, const Point &, const NumericVectorcreate_static_condensation_dof_map(); +} + +void System::create_static_condensation_dof_map() +{ + _sc_dof_map = std::make_unique(this->get_mesh(), *this, this->get_dof_map()); + this->get_dof_map().add_static_condensation(*_sc_dof_map); +} + } // namespace libMesh From 5da8491854cae7aa36775535d7056123ff9c4592 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Wed, 30 Apr 2025 16:55:09 -0600 Subject: [PATCH 18/41] Add get_static_condensation_system_matrix API --- include/systems/implicit_system.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/systems/implicit_system.h b/include/systems/implicit_system.h index 7694e6736fb..b672a788618 100644 --- a/include/systems/implicit_system.h +++ b/include/systems/implicit_system.h @@ -340,6 +340,11 @@ class ImplicitSystem : public ExplicitSystem virtual void create_static_condensation() override; + /** + * \returns The static condensation system matrix + */ + StaticCondensation & get_static_condensation_system_matrix(); + protected: /** * Adds the system matrix @@ -364,6 +369,13 @@ class ImplicitSystem : public ExplicitSystem StaticCondensation * _sc_system_matrix; }; +inline +StaticCondensation & ImplicitSystem::get_static_condensation_system_matrix() +{ + libmesh_assert(_sc_system_matrix); + return *_sc_system_matrix; +} + } // namespace libMesh #endif // LIBMESH_IMPLICIT_SYSTEM_H From a6591786fd5c82e709af2aef9d38a8c05b58a305 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Wed, 30 Apr 2025 16:55:28 -0600 Subject: [PATCH 19/41] Early return in add_matrix if empty rows or columns --- src/numerics/static_condensation.C | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 878403f1bc0..22100b081a2 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -255,6 +255,9 @@ void StaticCondensation::add_matrix(const DenseMatrix & dm, const std::vector & rows, const std::vector & cols) { + if (rows.empty() || cols.empty()) + return; + libmesh_assert(_current_elem_id != DofObject::invalid_id); auto & matrix_data = libmesh_map_find(_elem_to_matrix_data, _current_elem_id); const auto & dof_data = libmesh_map_find(_reduced_dof_map._elem_to_dof_data, _current_elem_id); From f0087e483ba73cdf9c83d28c81b58027491700e2 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 1 May 2025 13:08:48 -0600 Subject: [PATCH 20/41] Remove enum_matrix_build_type --- include/enums/enum_matrix_build_type.h | 36 -------------------------- include/include_HEADERS | 1 - include/libmesh/Makefile.am | 4 --- include/numerics/sparse_matrix.h | 4 +-- include/systems/system.h | 5 +--- src/numerics/sparse_matrix.C | 6 +---- src/systems/system.C | 21 ++++++++------- 7 files changed, 14 insertions(+), 63 deletions(-) delete mode 100644 include/enums/enum_matrix_build_type.h diff --git a/include/enums/enum_matrix_build_type.h b/include/enums/enum_matrix_build_type.h deleted file mode 100644 index 440cffef0a6..00000000000 --- a/include/enums/enum_matrix_build_type.h +++ /dev/null @@ -1,36 +0,0 @@ -// The libMesh Finite Element Library. -// Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner - -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. - -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - - -#ifndef LIBMESH_ENUM_BUILD_MATRIX_TYPE_H -#define LIBMESH_ENUM_BUILD_MATRIX_TYPE_H - -namespace libMesh { - -/** - * Defines an \p enum for matrix build types. This is useful for telling \p System - * derived objects what type of matrix to build - */ -enum class MatrixBuildType -{ - AUTOMATIC, - DIAGONAL -}; -} - -#endif diff --git a/include/include_HEADERS b/include/include_HEADERS index d7eb038aded..dae141d0ddf 100644 --- a/include/include_HEADERS +++ b/include/include_HEADERS @@ -53,7 +53,6 @@ include_HEADERS = \ enums/enum_fe_family.h \ enums/enum_inf_map_type.h \ enums/enum_io_package.h \ - enums/enum_matrix_build_type.h \ enums/enum_norm_type.h \ enums/enum_order.h \ enums/enum_parallel_type.h \ diff --git a/include/libmesh/Makefile.am b/include/libmesh/Makefile.am index 846dc4dad76..67581e6b426 100644 --- a/include/libmesh/Makefile.am +++ b/include/libmesh/Makefile.am @@ -43,7 +43,6 @@ BUILT_SOURCES = \ enum_fe_family.h \ enum_inf_map_type.h \ enum_io_package.h \ - enum_matrix_build_type.h \ enum_norm_type.h \ enum_order.h \ enum_parallel_type.h \ @@ -726,9 +725,6 @@ enum_inf_map_type.h: $(top_srcdir)/include/enums/enum_inf_map_type.h enum_io_package.h: $(top_srcdir)/include/enums/enum_io_package.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ -enum_matrix_build_type.h: $(top_srcdir)/include/enums/enum_matrix_build_type.h - $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ - enum_norm_type.h: $(top_srcdir)/include/enums/enum_norm_type.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ diff --git a/include/numerics/sparse_matrix.h b/include/numerics/sparse_matrix.h index 753b82deea6..c710f12f7b1 100644 --- a/include/numerics/sparse_matrix.h +++ b/include/numerics/sparse_matrix.h @@ -28,7 +28,6 @@ #include "libmesh/id_types.h" #include "libmesh/parallel_object.h" #include "libmesh/enum_parallel_type.h" // PARALLEL -#include "libmesh/enum_matrix_build_type.h" // AUTOMATIC #include "libmesh/enum_solver_package.h" // C++ includes @@ -121,8 +120,7 @@ class SparseMatrix : public ReferenceCountedObject>, */ static std::unique_ptr> build(const Parallel::Communicator & comm, - const SolverPackage solver_package = libMesh::default_solver_package(), - const MatrixBuildType matrix_build_type = MatrixBuildType::AUTOMATIC); + const SolverPackage solver_package = libMesh::default_solver_package()); virtual SolverPackage solver_package() = 0; diff --git a/include/systems/system.h b/include/systems/system.h index 6f44055a53d..0b3bfcc0e8b 100644 --- a/include/systems/system.h +++ b/include/systems/system.h @@ -31,7 +31,6 @@ #include "libmesh/reference_counted_object.h" #include "libmesh/tensor_value.h" // For point_hessian #include "libmesh/variable.h" -#include "libmesh/enum_matrix_build_type.h" // AUTOMATIC // C++ includes #include @@ -1844,12 +1843,10 @@ class System : public ReferenceCountedObject, * * @param mat_name A name for the matrix * @param type The serial/parallel/ghosted type of the matrix - * @param mat_build_type The matrix type to build * */ SparseMatrix & add_matrix (std::string_view mat_name, - ParallelType type = PARALLEL, - MatrixBuildType mat_build_type = MatrixBuildType::AUTOMATIC); + ParallelType type = PARALLEL); /** * Adds the additional matrix \p mat_name to this system. Only diff --git a/src/numerics/sparse_matrix.C b/src/numerics/sparse_matrix.C index b84604efaeb..21f284d2e71 100644 --- a/src/numerics/sparse_matrix.C +++ b/src/numerics/sparse_matrix.C @@ -165,15 +165,11 @@ void SparseMatrix::print(std::ostream & os, const bool sparse) const template std::unique_ptr> SparseMatrix::build(const Parallel::Communicator & comm, - const SolverPackage solver_package, - const MatrixBuildType matrix_build_type /* = AUTOMATIC */) + const SolverPackage solver_package) { // Avoid unused parameter warnings when no solver packages are enabled. libmesh_ignore(comm); - if (matrix_build_type == MatrixBuildType::DIAGONAL) - return std::make_unique>(comm); - // Build the appropriate vector switch (solver_package) { diff --git a/src/systems/system.C b/src/systems/system.C index 7dce897d73e..0e9287e3aef 100644 --- a/src/systems/system.C +++ b/src/systems/system.C @@ -39,6 +39,7 @@ #include "libmesh/fe_interface.h" #include "libmesh/fe_compute_data.h" #include "libmesh/static_condensation_dof_map.h" +#include "libmesh/static_condensation.h" // includes for calculate_norm, point_* #include "libmesh/fe_base.h" @@ -1006,14 +1007,12 @@ const std::string & System::vector_name (const NumericVector & vec_refer SparseMatrix & System::add_matrix (std::string_view mat_name, - const ParallelType type, - const MatrixBuildType mat_build_type) + const ParallelType type) { parallel_object_only(); libmesh_assert(this->comm().verify(std::string(mat_name))); libmesh_assert(this->comm().verify(int(type))); - libmesh_assert(this->comm().verify(int(mat_build_type))); // Return the matrix if it is already there. if (auto it = this->_matrices.find(mat_name); @@ -1021,15 +1020,17 @@ SparseMatrix & System::add_matrix (std::string_view mat_name, return *it->second; // Otherwise build the matrix to return. - auto pr = _matrices.emplace - (mat_name, - SparseMatrix::build(this->comm(), - libMesh::default_solver_package(), - mat_build_type)); + std::unique_ptr> matrix; + if (this->has_static_condensation()) + matrix = std::make_unique( + this->get_mesh(), *this, this->get_dof_map(), *_sc_dof_map); + else + matrix = SparseMatrix::build(this->comm(), libMesh::default_solver_package()); + auto & mat = *matrix; - _matrix_types.emplace(mat_name, type); + _matrices.emplace(mat_name, std::move(matrix)); - SparseMatrix & mat = *(pr.first->second); + _matrix_types.emplace(mat_name, type); // Initialize it first if we've already initialized the others. this->late_matrix_init(mat, type); From aded3055ba78560646b4805900084ac421323aa7 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 1 May 2025 13:09:27 -0600 Subject: [PATCH 21/41] Run bootstrap --- include/Makefile.in | 1 - include/libmesh/Makefile.in | 14 +++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/include/Makefile.in b/include/Makefile.in index 45a3e49c6c4..c82c1570d20 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -654,7 +654,6 @@ include_HEADERS = \ enums/enum_fe_family.h \ enums/enum_inf_map_type.h \ enums/enum_io_package.h \ - enums/enum_matrix_build_type.h \ enums/enum_norm_type.h \ enums/enum_order.h \ enums/enum_parallel_type.h \ diff --git a/include/libmesh/Makefile.in b/include/libmesh/Makefile.in index 4b4bd1a781b..a6e4d07cc8e 100644 --- a/include/libmesh/Makefile.in +++ b/include/libmesh/Makefile.in @@ -532,12 +532,11 @@ BUILT_SOURCES = auto_ptr.h dirichlet_boundaries.h dof_map.h \ variant_filter_iterator.h enum_convergence_flags.h \ enum_eigen_solver_type.h enum_elem_quality.h enum_elem_type.h \ enum_error_estimator_type.h enum_fe_family.h \ - enum_inf_map_type.h enum_io_package.h enum_matrix_build_type.h \ - enum_norm_type.h enum_order.h enum_parallel_type.h \ - enum_partitioner_type.h enum_point_locator_type.h \ - enum_preconditioner_type.h enum_quadrature_type.h \ - enum_solver_package.h enum_solver_type.h \ - enum_subset_solve_mode.h enum_xdr_mode.h \ + enum_inf_map_type.h enum_io_package.h enum_norm_type.h \ + enum_order.h enum_parallel_type.h enum_partitioner_type.h \ + enum_point_locator_type.h enum_preconditioner_type.h \ + enum_quadrature_type.h enum_solver_package.h \ + enum_solver_type.h enum_subset_solve_mode.h enum_xdr_mode.h \ adjoint_refinement_estimator.h \ adjoint_residual_error_estimator.h discontinuity_measure.h \ error_estimator.h exact_error_estimator.h exact_solution.h \ @@ -1055,9 +1054,6 @@ enum_inf_map_type.h: $(top_srcdir)/include/enums/enum_inf_map_type.h enum_io_package.h: $(top_srcdir)/include/enums/enum_io_package.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ -enum_matrix_build_type.h: $(top_srcdir)/include/enums/enum_matrix_build_type.h - $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ - enum_norm_type.h: $(top_srcdir)/include/enums/enum_norm_type.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ From 588dde2ed0b568c0e1a441488a904297691d3ef0 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 1 May 2025 13:39:27 -0600 Subject: [PATCH 22/41] Update misc example 16 --- .../miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C b/examples/miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C index 257fa261a79..97081e02e1c 100644 --- a/examples/miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C +++ b/examples/miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C @@ -171,7 +171,7 @@ main(int argc, char ** argv) libmesh_error_msg_if(!libMesh::relative_fuzzy_equals(*sys.solution, *sc_sys.solution, 1e-4), "mismatching solution"); libMesh::out << "Static condensation reduced problem size to " - << sc_sys.get_static_condensation().get_condensed_mat().m() << std::endl; + << sc_sys.get_static_condensation_system_matrix().get_condensed_mat().m() << std::endl; #if defined(LIBMESH_HAVE_VTK) && !defined(LIBMESH_ENABLE_PARMESH) @@ -208,7 +208,7 @@ assemble_poisson(EquationSystems & es, const std::string & system_name) // Get a pointer to the StaticCondensation class if it exists StaticCondensation * sc = nullptr; if (system.has_static_condensation()) - sc = &system.get_static_condensation(); + sc = &system.get_static_condensation_system_matrix(); // A reference to the DofMap object for this system. The DofMap // object handles the index translation from node and element numbers From 54862d0c2e763d25edd29171dea61aea9fe62e32 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 1 May 2025 13:39:56 -0600 Subject: [PATCH 23/41] Take ParallelType into consideration in PetscMatrix/SC --- include/numerics/static_condensation.h | 3 +++ src/numerics/petsc_matrix.C | 5 +++-- src/numerics/petsc_matrix_shell_matrix.C | 5 ++--- src/numerics/static_condensation.C | 18 +++++++++++++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index 628ad790da2..299faa44a77 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -264,6 +264,9 @@ class StaticCondensation : public PetscMatrixShellMatrix /// Whether we have cached values via add_XXX() bool _have_cached_values; + + /// The parallel type to use for the reduced matrix + ParallelType _parallel_type; }; inline const SparseMatrix & StaticCondensation::get_condensed_mat() const diff --git a/src/numerics/petsc_matrix.C b/src/numerics/petsc_matrix.C index e1db6d81341..4516b1300e8 100644 --- a/src/numerics/petsc_matrix.C +++ b/src/numerics/petsc_matrix.C @@ -351,12 +351,13 @@ void PetscMatrix::init (const numeric_index_type m_in, template -void PetscMatrix::init (const ParallelType) +void PetscMatrix::init (const ParallelType libmesh_dbg_var(type)) { libmesh_assert(this->_dof_map); + libmesh_assert(type != SERIAL); const numeric_index_type m_in = this->_dof_map->n_dofs(); - const numeric_index_type m_l = this->_dof_map->n_local_dofs(); + const numeric_index_type m_l = this->_dof_map->n_local_dofs(); const auto blocksize = this->_dof_map->block_size(); diff --git a/src/numerics/petsc_matrix_shell_matrix.C b/src/numerics/petsc_matrix_shell_matrix.C index ec491a2efd8..495e54726bb 100644 --- a/src/numerics/petsc_matrix_shell_matrix.C +++ b/src/numerics/petsc_matrix_shell_matrix.C @@ -36,16 +36,15 @@ PetscMatrixShellMatrix::init(const numeric_index_type m, const numeric_index_type blocksize) { init_shell_mat(*this, m, n, m_l, n_l, blocksize); - this->set_context(); } template void -PetscMatrixShellMatrix::init(ParallelType) +PetscMatrixShellMatrix::init(ParallelType libmesh_dbg_var(type)) { + libmesh_assert(type != SERIAL); init_shell_mat(*this); - this->set_context(); } diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 22100b081a2..c793f9bd1d8 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -15,6 +15,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +#include "libmesh/enum_parallel_type.h" #include "libmesh/static_condensation.h" #if defined(LIBMESH_HAVE_EIGEN) && defined(LIBMESH_HAVE_PETSC) @@ -46,7 +47,8 @@ StaticCondensation::StaticCondensation(const MeshBase & mesh, _reduced_dof_map(reduced_dof_map), _current_elem_id(DofObject::invalid_id), _sc_is_initialized(false), - _have_cached_values(false) + _have_cached_values(false), + _parallel_type(INVALID_PARALLELIZATION) { _size_one_mat.resize(1, 1); _scp = std::make_unique(*this); @@ -94,6 +96,7 @@ void StaticCondensation::init(const numeric_index_type m, if (!this->initialized()) { PetscMatrixShellMatrix::init(m, n, m_l, n_l, nnz, noz, blocksize); + _parallel_type = ((m == m_l) && (this->n_processors() > 1)) ? SERIAL : PARALLEL; this->init(); } } @@ -103,6 +106,7 @@ void StaticCondensation::init(const ParallelType type) if (!this->initialized()) { PetscMatrixShellMatrix::init(type); + _parallel_type = type; this->init(); } } @@ -114,11 +118,18 @@ bool StaticCondensation::initialized() const void StaticCondensation::init() { - if (_sc_is_initialized) + if (this->initialized()) return; libmesh_assert(_reduced_dof_map.initialized()); + // This API is public, so it can be called without going through the other init overloads which + // would give us an indication of what kind of parallel type the user wants. If we've gotten no + // indication so far, we will default to parallel + if (_parallel_type == INVALID_PARALLELIZATION) + _parallel_type = PARALLEL; + libmesh_assert(_parallel_type != SERIAL); + for (const auto & [elem_id, dof_data] : _reduced_dof_map._elem_to_dof_data) { auto & matrix_data = _elem_to_matrix_data[elem_id]; @@ -136,7 +147,8 @@ void StaticCondensation::init() // Build the reduced system data // const auto n = _reduced_dof_map.n_dofs(); - const auto n_local = _reduced_dof_map.n_local_dofs(); + const auto n_local = + (_parallel_type == SERIAL) ? _reduced_dof_map.n_dofs() : _reduced_dof_map.n_local_dofs(); _reduced_solver = LinearSolver::build(this->comm()); _reduced_solver->init((_system.name() + "_condensed_").c_str()); _reduced_rhs = NumericVector::build(this->comm()); From b6ac09361f119c098c73b85acb57e9262a201848 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 1 May 2025 15:10:55 -0600 Subject: [PATCH 24/41] Add option for building reduced mat only from uncondensed dofs --- include/numerics/static_condensation.h | 11 +++++++++++ src/numerics/static_condensation.C | 23 +++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index 299faa44a77..2fcb9be1f17 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -181,6 +181,12 @@ class StaticCondensation : public PetscMatrixShellMatrix virtual bool require_sparsity_pattern() const override { return false; } + /** + * Sets whether this matrix represents uncondensed dofs only. In that case when building the Schur + * complement we won't attempt to invert zero element matrices corresponding to the condensed dofs + */ + void uncondensed_dofs_only() { _uncondensed_dofs_only = true; } + private: /** * Retrieves the degree of freedom values from \p global_vector corresponding to \p @@ -267,6 +273,11 @@ class StaticCondensation : public PetscMatrixShellMatrix /// The parallel type to use for the reduced matrix ParallelType _parallel_type; + + /// whether this matrix represents uncondensed dofs only. In that case when building the Schur + /// complement we won't attempt to invert zero element matrices corresponding to the condensed + /// dofs + bool _uncondensed_dofs_only; }; inline const SparseMatrix & StaticCondensation::get_condensed_mat() const diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index c793f9bd1d8..10146a01522 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -48,7 +48,8 @@ StaticCondensation::StaticCondensation(const MeshBase & mesh, _current_elem_id(DofObject::invalid_id), _sc_is_initialized(false), _have_cached_values(false), - _parallel_type(INVALID_PARALLELIZATION) + _parallel_type(INVALID_PARALLELIZATION), + _uncondensed_dofs_only(false) { _size_one_mat.resize(1, 1); _scp = std::make_unique(*this); @@ -199,13 +200,19 @@ void StaticCondensation::close() { const auto & dof_data = libmesh_map_find(_reduced_dof_map._elem_to_dof_data, elem_id); reduced_space_indices.clear(); - matrix_data.AccFactor = matrix_data.Acc.partialPivLu(); - const EigenMatrix S = - matrix_data.Auu - matrix_data.Auc * matrix_data.AccFactor.solve(matrix_data.Acu); - shim.resize(S.rows(), S.cols()); - for (const auto i : make_range(S.rows())) - for (const auto j : make_range(S.cols())) - shim(i, j) = S(i, j); + + // The result matrix is either a Schur complement or it's simply the result of summing element + // matrices of the uncondensed degrees of freedom + EigenMatrix result = matrix_data.Auu; + if (!_uncondensed_dofs_only) + { + matrix_data.AccFactor = matrix_data.Acc.partialPivLu(); + result -= matrix_data.Auc * matrix_data.AccFactor.solve(matrix_data.Acu); + } + shim.resize(result.rows(), result.cols()); + for (const auto i : make_range(result.rows())) + for (const auto j : make_range(result.cols())) + shim(i, j) = result(i, j); for (const auto & var_reduced_space_indices : dof_data.reduced_space_indices) reduced_space_indices.insert(reduced_space_indices.end(), var_reduced_space_indices.begin(), From a48aef02bb2b5acba72519006272a05a5c703e4d Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 1 May 2025 15:11:01 -0600 Subject: [PATCH 25/41] Add const API for getting PETSc mat Mat is a pointer so attempting to mark it as const accomplishes nothing. But we shouldn't penalize users working with a const PetscMatrix and refuse to provide them access to the raw Mat. We will assume that they have good intentions --- include/numerics/petsc_matrix_base.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/numerics/petsc_matrix_base.h b/include/numerics/petsc_matrix_base.h index 0a665cc751c..612864ca5d3 100644 --- a/include/numerics/petsc_matrix_base.h +++ b/include/numerics/petsc_matrix_base.h @@ -118,6 +118,7 @@ class PetscMatrixBase : public SparseMatrix * it, or very bad things will likely happen! */ Mat mat () { libmesh_assert (_mat); return _mat; } + Mat mat() const { libmesh_assert(_mat); return _mat; } /** * clear() is called from the destructor, so it should not throw. From 2cbd1a66524fcd425efb8bac07e4a9c2fdca0a19 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 1 May 2025 17:36:42 -0600 Subject: [PATCH 26/41] Move old dof information into DofMapBase --- include/base/dof_map.h | 47 ------------------------------- include/base/dof_map_base.h | 56 ++++++++++++++++++++++++++++++++++++- src/base/dof_map.C | 15 ++-------- src/base/dof_map_base.C | 19 +++++++++++++ 4 files changed, 76 insertions(+), 61 deletions(-) diff --git a/include/base/dof_map.h b/include/base/dof_map.h index 34ca5d2e58b..d32fe043f08 100644 --- a/include/base/dof_map.h +++ b/include/base/dof_map.h @@ -701,18 +701,6 @@ class DofMap : public DofMapBase, return n_local_dofs; } -#ifdef LIBMESH_ENABLE_AMR - /** - * \returns The first old dof index that is local to partition \p proc. - */ - dof_id_type first_old_dof(const processor_id_type proc) const - { libmesh_assert_less (proc, _first_old_df.size()); return _first_old_df[proc]; } - - dof_id_type first_old_dof() const - { return this->first_old_dof(this->processor_id()); } - -#endif //LIBMESH_ENABLE_AMR - /** * \returns The processor id that owns the dof index \p dof */ @@ -723,21 +711,6 @@ class DofMap : public DofMapBase, return cast_int(ub - _end_df.begin()); } -#ifdef LIBMESH_ENABLE_AMR - /** - * \returns The first old dof index that is after all indices local - * to processor \p proc. - * - * Analogous to the end() member function of STL containers. - */ - dof_id_type end_old_dof(const processor_id_type proc) const - { libmesh_assert_less (proc, _end_old_df.size()); return _end_old_df[proc]; } - - dof_id_type end_old_dof() const - { return this->end_old_dof(this->processor_id()); } - -#endif //LIBMESH_ENABLE_AMR - void dof_indices (const Elem * const elem, std::vector & di) const; @@ -1586,11 +1559,6 @@ class DofMap : public DofMapBase, std::vector & di, const unsigned int vn = libMesh::invalid_uint) const; - /** - * \returns The total number of degrees of freedom on old_dof_objects - */ - dof_id_type n_old_dofs() const { return _n_old_dfs; } - #endif // LIBMESH_ENABLE_AMR /** @@ -2113,21 +2081,6 @@ class DofMap : public DofMapBase, #ifdef LIBMESH_ENABLE_AMR - /** - * Total number of degrees of freedom on old dof objects - */ - dof_id_type _n_old_dfs; - - /** - * First old DOF index on processor \p p. - */ - std::vector _first_old_df; - - /** - * Last old DOF index (plus 1) on processor \p p. - */ - std::vector _end_old_df; - /** * First old DOF index for SCALAR variable v, or garbage for * non-SCALAR variable v diff --git a/include/base/dof_map_base.h b/include/base/dof_map_base.h index ed065cc2af1..c44fb445a9d 100644 --- a/include/base/dof_map_base.h +++ b/include/base/dof_map_base.h @@ -31,7 +31,7 @@ class Node; class DofMapBase : public ParallelObject { public: - DofMapBase(const Parallel::Communicator & comm) : ParallelObject(comm), _n_dfs(0) {} + DofMapBase(const Parallel::Communicator & comm); /** * \returns The number of variables in the global solution vector. Defaults @@ -96,6 +96,30 @@ class DofMapBase : public ParallelObject virtual void clear(); + /** + * \returns The total number of degrees of freedom on old_dof_objects + */ + dof_id_type n_old_dofs() const { return _n_old_dfs; } + +#ifdef LIBMESH_ENABLE_AMR + /** + * \returns The first old dof index that is local to partition \p proc. + */ + dof_id_type first_old_dof(const processor_id_type proc) const; + + dof_id_type first_old_dof() const { return this->first_old_dof(this->processor_id()); } + + /** + * \returns The first old dof index that is after all indices local + * to processor \p proc. + * + * Analogous to the end() member function of STL containers. + */ + dof_id_type end_old_dof(const processor_id_type proc) const; + + dof_id_type end_old_dof() const { return this->end_old_dof(this->processor_id()); } +#endif // LIBMESH_ENABLE_AMR + protected: /** * compute the key degree of freedom information given the local number of degrees of freedom on @@ -118,6 +142,24 @@ class DofMapBase : public ParallelObject * Total number of degrees of freedom. */ dof_id_type _n_dfs; + +#ifdef LIBMESH_ENABLE_AMR + + /** + * Total number of degrees of freedom on old dof objects + */ + dof_id_type _n_old_dfs; + + /** + * First old DOF index on processor \p p. + */ + std::vector _first_old_df; + + /** + * Last old DOF index (plus 1) on processor \p p. + */ + std::vector _end_old_df; +#endif }; inline dof_id_type DofMapBase::first_dof(const processor_id_type proc) const @@ -138,5 +180,17 @@ inline dof_id_type DofMapBase::n_dofs_on_processor(const processor_id_type proc) return cast_int(_end_df[proc] - _first_df[proc]); } +inline dof_id_type DofMapBase::first_old_dof(const processor_id_type proc) const +{ + libmesh_assert_less(proc, _first_old_df.size()); + return _first_old_df[proc]; +} + +inline dof_id_type DofMapBase::end_old_dof(const processor_id_type proc) const +{ + libmesh_assert_less(proc, _end_old_df.size()); + return _end_old_df[proc]; +} + } #endif // LIBMESH_DOF_MAP_BASE_H diff --git a/src/base/dof_map.C b/src/base/dof_map.C index 51f2b7c14a3..db6a773b1df 100644 --- a/src/base/dof_map.C +++ b/src/base/dof_map.C @@ -158,10 +158,7 @@ DofMap::DofMap(const unsigned int number, need_full_sparsity_pattern(false), _n_SCALAR_dofs(0) #ifdef LIBMESH_ENABLE_AMR - , _n_old_dfs(0), - _first_old_df(), - _end_old_df(), - _first_old_scalar_df() + , _first_old_scalar_df() #endif #ifdef LIBMESH_ENABLE_CONSTRAINTS , _dof_constraints() @@ -1028,12 +1025,6 @@ std::size_t DofMap::distribute_dofs (MeshBase & mesh) // Get DOF counts on all processors const auto n_dofs = this->compute_dof_info(next_free_dof); - // Resize and fill the _first_df and _end_df arrays -#ifdef LIBMESH_ENABLE_AMR - _first_old_df = _first_df; - _end_old_df = _end_df; -#endif - // Clear all the current DOF indices // (distribute_dofs expects them cleared!) this->invalidate_dofs(mesh); @@ -1107,10 +1098,8 @@ std::size_t DofMap::distribute_dofs (MeshBase & mesh) } #endif - // Set the total number of degrees of freedom, then start finding - // SCALAR degrees of freedom + // start finding SCALAR degrees of freedom #ifdef LIBMESH_ENABLE_AMR - _n_old_dfs = _n_dfs; _first_old_scalar_df = _first_scalar_df; #endif _first_scalar_df.clear(); diff --git a/src/base/dof_map_base.C b/src/base/dof_map_base.C index 73640c220aa..a88ae88be7e 100644 --- a/src/base/dof_map_base.C +++ b/src/base/dof_map_base.C @@ -20,6 +20,16 @@ namespace libMesh { +DofMapBase::DofMapBase(const Parallel::Communicator & comm) + : ParallelObject(comm), + _n_dfs(0) +#ifdef LIBMESH_ENABLE_AMR + , + _n_old_dfs(0) +#endif +{ +} + std::size_t DofMapBase::compute_dof_info(const dof_id_type n_local_dofs) { // Get DOF counts on all processors @@ -28,7 +38,12 @@ std::size_t DofMapBase::compute_dof_info(const dof_id_type n_local_dofs) std::vector dofs_on_proc(n_proc, 0); this->comm().allgather(n_local_dofs, dofs_on_proc); +#ifdef LIBMESH_ENABLE_AMR // Resize and fill the _first_df and _end_df arrays + _first_old_df = _first_df; + _end_old_df = _end_df; +#endif + _first_df.resize(n_proc); _end_df.resize(n_proc); @@ -38,6 +53,10 @@ std::size_t DofMapBase::compute_dof_info(const dof_id_type n_local_dofs) _first_df[i] = _end_df[i - 1] = _first_df[i - 1] + dofs_on_proc[i - 1]; _end_df[n_proc - 1] = _first_df[n_proc - 1] + dofs_on_proc[n_proc - 1]; +// Set the total number of degrees of freedom +#ifdef LIBMESH_ENABLE_AMR + _n_old_dfs = _n_dfs; +#endif _n_dfs = _end_df[n_proc - 1]; // Return total number of DOFs across all procs. We compute and From a9f6fe5811cf1a11d19664eb1720ce2e15dc1e02 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 8 May 2025 16:35:03 -0600 Subject: [PATCH 27/41] copy constant nullspace shift from parent to sc mat I wonder whether this is even valid because I don't know if it's guaranteed that the shift in the condensed system would match the shift in the noncondensed system --- src/numerics/static_condensation.C | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 10146a01522..14b1a562b22 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -243,7 +243,24 @@ void StaticCondensation::zero() } } -void StaticCondensation::setup() { libmesh_assert(this->closed()); } +void StaticCondensation::setup() +{ + libmesh_assert(this->closed()); + libmesh_assert(this->initialized()); + MatNullSpace nullsp; + LibmeshPetscCall(MatGetNullSpace(this->mat(), &nullsp)); + if (nullsp) + { + PetscInt num_nullspace_vecs; + PetscBool const_nullspace; + LibmeshPetscCall(MatNullSpaceGetVecs(nullsp, &const_nullspace, &num_nullspace_vecs, nullptr)); + libmesh_assert((const_nullspace == PETSC_TRUE) == !num_nullspace_vecs); + if (const_nullspace == PETSC_FALSE) + libmesh_error_msg("We only support the constant nullspace in StaticCondensation"); + LibmeshPetscCall(MatSetNullSpace( + cast_ptr *>(_reduced_sys_mat.get())->mat(), nullsp)); + } +} numeric_index_type StaticCondensation::m() const { return _full_dof_map.n_dofs(); } From 100ab0512352fd862e46d60add3a4a6dd150f806 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 8 May 2025 16:36:47 -0600 Subject: [PATCH 28/41] Give meaningful exception in all compilation modes for OOB condensation info lookup --- src/numerics/static_condensation.C | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 14b1a562b22..0548c28bf02 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -305,7 +305,12 @@ void StaticCondensation::add_matrix(const DenseMatrix & dm, if (!index_is_condensed) { index_it = dof_data.uncondensed_global_to_local_map.find(global_index); - libmesh_assert(index_it != dof_data.uncondensed_global_to_local_map.end()); + if (index_it == dof_data.uncondensed_global_to_local_map.end()) + libmesh_error_msg("Failed to find the global index " + << global_index + << " in our current element's degree of freedom information. One way " + "this can happen is when using a discontinuous Galerkin method, " + "adding element matrices to both + and - sides of a face"); } return std::make_pair(index_is_condensed, index_it->second); }; From 4c6d897df2704ed5e30cca13a1a297b2a1f355f4 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 8 May 2025 16:36:53 -0600 Subject: [PATCH 29/41] Revert "copy constant nullspace shift from parent to sc mat" This reverts commit ea7983b2decfb699a467b86773584fa526496704. --- src/numerics/static_condensation.C | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 0548c28bf02..a65356f30ac 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -243,24 +243,7 @@ void StaticCondensation::zero() } } -void StaticCondensation::setup() -{ - libmesh_assert(this->closed()); - libmesh_assert(this->initialized()); - MatNullSpace nullsp; - LibmeshPetscCall(MatGetNullSpace(this->mat(), &nullsp)); - if (nullsp) - { - PetscInt num_nullspace_vecs; - PetscBool const_nullspace; - LibmeshPetscCall(MatNullSpaceGetVecs(nullsp, &const_nullspace, &num_nullspace_vecs, nullptr)); - libmesh_assert((const_nullspace == PETSC_TRUE) == !num_nullspace_vecs); - if (const_nullspace == PETSC_FALSE) - libmesh_error_msg("We only support the constant nullspace in StaticCondensation"); - LibmeshPetscCall(MatSetNullSpace( - cast_ptr *>(_reduced_sys_mat.get())->mat(), nullsp)); - } -} +void StaticCondensation::setup() { libmesh_assert(this->closed()); } numeric_index_type StaticCondensation::m() const { return _full_dof_map.n_dofs(); } From 76536be6fa59092b79e2774f295b0b4425771963 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Mon, 12 May 2025 17:17:33 -0600 Subject: [PATCH 30/41] Remove trailing whitespace. What a noob --- include/systems/implicit_system.h | 2 +- include/systems/system.h | 4 ++-- src/base/dof_map.C | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/systems/implicit_system.h b/include/systems/implicit_system.h index b672a788618..00e01798b86 100644 --- a/include/systems/implicit_system.h +++ b/include/systems/implicit_system.h @@ -357,7 +357,7 @@ class ImplicitSystem : public ExplicitSystem template void setup_static_condensation_preconditioner(T & solver); -private: +private: /** * Create the static condensation system matrix */ diff --git a/include/systems/system.h b/include/systems/system.h index 0b3bfcc0e8b..6e85674a2ce 100644 --- a/include/systems/system.h +++ b/include/systems/system.h @@ -1956,7 +1956,7 @@ class System : public ReferenceCountedObject, * @returns Whether this system will be statically condensed */ bool has_static_condensation() const { return _sc_dof_map.get(); } - + protected: /** @@ -2027,7 +2027,7 @@ class System : public ReferenceCountedObject, * Creates the degree of freedom map for the statically condensed system */ void create_static_condensation_dof_map(); - + /** * Helper function to keep DofMap forward declarable in system.h */ diff --git a/src/base/dof_map.C b/src/base/dof_map.C index db6a773b1df..774f8ded7b4 100644 --- a/src/base/dof_map.C +++ b/src/base/dof_map.C @@ -901,7 +901,7 @@ void DofMap::invalidate_dofs(MeshBase & mesh) const void DofMap::clear() { DofMapBase::clear(); - + // we don't want to clear // the coupling matrix! // It should not change... From 76cdfe8d98996635edf26c7840243cf41272c610 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Tue, 13 May 2025 12:19:29 -0600 Subject: [PATCH 31/41] Fixes for non-petsc configurations --- include/numerics/static_condensation.h | 5 ++++- src/numerics/static_condensation.C | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index 2fcb9be1f17..5c2a200d744 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -310,7 +310,10 @@ class StaticCondensationDofMap; class StaticCondensation : public SparseMatrix { public: - StaticCondensation(const MeshBase &, const System &, const DofMap & full_dof_map); + StaticCondensation(const MeshBase &, + const System &, + const DofMap & full_dof_map, + const StaticCondensationDofMap & reduced_dof_map); const std::unordered_set & uncondensed_vars() const { libmesh_not_implemented(); } StaticCondensationPreconditioner & get_preconditioner() { libmesh_not_implemented(); } diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index a65356f30ac..71a827e1f61 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -472,7 +472,8 @@ namespace libMesh { StaticCondensation::StaticCondensation(const MeshBase &, const System &, - const DofMap & full_dof_map) + const DofMap & full_dof_map, + const StaticCondensationDofMap &) : SparseMatrix(full_dof_map.comm()) { libmesh_error_msg( From 8004e5c2e46902a0a58c8f6d6f550754b8a770e2 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 22 May 2025 13:30:06 -0600 Subject: [PATCH 32/41] Keep around matrix_build_type --- include/enums/enum_matrix_build_type.h | 36 ++++++++++++++++++++++++++ include/include_HEADERS | 1 + include/libmesh/Makefile.am | 4 +++ include/numerics/sparse_matrix.h | 4 ++- include/systems/system.h | 5 +++- src/numerics/sparse_matrix.C | 6 ++++- src/systems/system.C | 4 ++- 7 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 include/enums/enum_matrix_build_type.h diff --git a/include/enums/enum_matrix_build_type.h b/include/enums/enum_matrix_build_type.h new file mode 100644 index 00000000000..440cffef0a6 --- /dev/null +++ b/include/enums/enum_matrix_build_type.h @@ -0,0 +1,36 @@ +// The libMesh Finite Element Library. +// Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner + +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + +#ifndef LIBMESH_ENUM_BUILD_MATRIX_TYPE_H +#define LIBMESH_ENUM_BUILD_MATRIX_TYPE_H + +namespace libMesh { + +/** + * Defines an \p enum for matrix build types. This is useful for telling \p System + * derived objects what type of matrix to build + */ +enum class MatrixBuildType +{ + AUTOMATIC, + DIAGONAL +}; +} + +#endif diff --git a/include/include_HEADERS b/include/include_HEADERS index dae141d0ddf..d7eb038aded 100644 --- a/include/include_HEADERS +++ b/include/include_HEADERS @@ -53,6 +53,7 @@ include_HEADERS = \ enums/enum_fe_family.h \ enums/enum_inf_map_type.h \ enums/enum_io_package.h \ + enums/enum_matrix_build_type.h \ enums/enum_norm_type.h \ enums/enum_order.h \ enums/enum_parallel_type.h \ diff --git a/include/libmesh/Makefile.am b/include/libmesh/Makefile.am index 67581e6b426..846dc4dad76 100644 --- a/include/libmesh/Makefile.am +++ b/include/libmesh/Makefile.am @@ -43,6 +43,7 @@ BUILT_SOURCES = \ enum_fe_family.h \ enum_inf_map_type.h \ enum_io_package.h \ + enum_matrix_build_type.h \ enum_norm_type.h \ enum_order.h \ enum_parallel_type.h \ @@ -725,6 +726,9 @@ enum_inf_map_type.h: $(top_srcdir)/include/enums/enum_inf_map_type.h enum_io_package.h: $(top_srcdir)/include/enums/enum_io_package.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ +enum_matrix_build_type.h: $(top_srcdir)/include/enums/enum_matrix_build_type.h + $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ + enum_norm_type.h: $(top_srcdir)/include/enums/enum_norm_type.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ diff --git a/include/numerics/sparse_matrix.h b/include/numerics/sparse_matrix.h index c710f12f7b1..753b82deea6 100644 --- a/include/numerics/sparse_matrix.h +++ b/include/numerics/sparse_matrix.h @@ -28,6 +28,7 @@ #include "libmesh/id_types.h" #include "libmesh/parallel_object.h" #include "libmesh/enum_parallel_type.h" // PARALLEL +#include "libmesh/enum_matrix_build_type.h" // AUTOMATIC #include "libmesh/enum_solver_package.h" // C++ includes @@ -120,7 +121,8 @@ class SparseMatrix : public ReferenceCountedObject>, */ static std::unique_ptr> build(const Parallel::Communicator & comm, - const SolverPackage solver_package = libMesh::default_solver_package()); + const SolverPackage solver_package = libMesh::default_solver_package(), + const MatrixBuildType matrix_build_type = MatrixBuildType::AUTOMATIC); virtual SolverPackage solver_package() = 0; diff --git a/include/systems/system.h b/include/systems/system.h index 6e85674a2ce..2e2f96a9e54 100644 --- a/include/systems/system.h +++ b/include/systems/system.h @@ -31,6 +31,7 @@ #include "libmesh/reference_counted_object.h" #include "libmesh/tensor_value.h" // For point_hessian #include "libmesh/variable.h" +#include "libmesh/enum_matrix_build_type.h" // AUTOMATIC // C++ includes #include @@ -1843,10 +1844,12 @@ class System : public ReferenceCountedObject, * * @param mat_name A name for the matrix * @param type The serial/parallel/ghosted type of the matrix + * @param mat_build_type The matrix type to build * */ SparseMatrix & add_matrix (std::string_view mat_name, - ParallelType type = PARALLEL); + ParallelType type = PARALLEL, + MatrixBuildType mat_build_type = MatrixBuildType::AUTOMATIC); /** * Adds the additional matrix \p mat_name to this system. Only diff --git a/src/numerics/sparse_matrix.C b/src/numerics/sparse_matrix.C index 21f284d2e71..b84604efaeb 100644 --- a/src/numerics/sparse_matrix.C +++ b/src/numerics/sparse_matrix.C @@ -165,11 +165,15 @@ void SparseMatrix::print(std::ostream & os, const bool sparse) const template std::unique_ptr> SparseMatrix::build(const Parallel::Communicator & comm, - const SolverPackage solver_package) + const SolverPackage solver_package, + const MatrixBuildType matrix_build_type /* = AUTOMATIC */) { // Avoid unused parameter warnings when no solver packages are enabled. libmesh_ignore(comm); + if (matrix_build_type == MatrixBuildType::DIAGONAL) + return std::make_unique>(comm); + // Build the appropriate vector switch (solver_package) { diff --git a/src/systems/system.C b/src/systems/system.C index 0e9287e3aef..bf2f6cafb88 100644 --- a/src/systems/system.C +++ b/src/systems/system.C @@ -1007,12 +1007,14 @@ const std::string & System::vector_name (const NumericVector & vec_refer SparseMatrix & System::add_matrix (std::string_view mat_name, - const ParallelType type) + const ParallelType type, + const MatrixBuildType mat_build_type) { parallel_object_only(); libmesh_assert(this->comm().verify(std::string(mat_name))); libmesh_assert(this->comm().verify(int(type))); + libmesh_assert(this->comm().verify(int(mat_build_type))); // Return the matrix if it is already there. if (auto it = this->_matrices.find(mat_name); From 6a79d4c15ee78cbd719946a6f3e4563d8497fba8 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 22 May 2025 13:37:44 -0600 Subject: [PATCH 33/41] Error if diagonal matrix type specified with static condensation --- src/systems/system.C | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/systems/system.C b/src/systems/system.C index bf2f6cafb88..6cba69a05ea 100644 --- a/src/systems/system.C +++ b/src/systems/system.C @@ -1024,8 +1024,13 @@ SparseMatrix & System::add_matrix (std::string_view mat_name, // Otherwise build the matrix to return. std::unique_ptr> matrix; if (this->has_static_condensation()) - matrix = std::make_unique( - this->get_mesh(), *this, this->get_dof_map(), *_sc_dof_map); + { + if (mat_build_type == MatrixBuildType::DIAGONAL) + libmesh_error_msg( + "We do not currently support static condensation of the diagonal matrix type"); + matrix = std::make_unique( + this->get_mesh(), *this, this->get_dof_map(), *_sc_dof_map); + } else matrix = SparseMatrix::build(this->comm(), libMesh::default_solver_package()); auto & mat = *matrix; From 80099259a899b585bc18a12afa3beb736deb90db Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 22 May 2025 13:38:37 -0600 Subject: [PATCH 34/41] Bootstrap for return of enum_matrix_build_type --- include/Makefile.in | 1 + include/libmesh/Makefile.in | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/Makefile.in b/include/Makefile.in index c82c1570d20..45a3e49c6c4 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -654,6 +654,7 @@ include_HEADERS = \ enums/enum_fe_family.h \ enums/enum_inf_map_type.h \ enums/enum_io_package.h \ + enums/enum_matrix_build_type.h \ enums/enum_norm_type.h \ enums/enum_order.h \ enums/enum_parallel_type.h \ diff --git a/include/libmesh/Makefile.in b/include/libmesh/Makefile.in index a6e4d07cc8e..4b4bd1a781b 100644 --- a/include/libmesh/Makefile.in +++ b/include/libmesh/Makefile.in @@ -532,11 +532,12 @@ BUILT_SOURCES = auto_ptr.h dirichlet_boundaries.h dof_map.h \ variant_filter_iterator.h enum_convergence_flags.h \ enum_eigen_solver_type.h enum_elem_quality.h enum_elem_type.h \ enum_error_estimator_type.h enum_fe_family.h \ - enum_inf_map_type.h enum_io_package.h enum_norm_type.h \ - enum_order.h enum_parallel_type.h enum_partitioner_type.h \ - enum_point_locator_type.h enum_preconditioner_type.h \ - enum_quadrature_type.h enum_solver_package.h \ - enum_solver_type.h enum_subset_solve_mode.h enum_xdr_mode.h \ + enum_inf_map_type.h enum_io_package.h enum_matrix_build_type.h \ + enum_norm_type.h enum_order.h enum_parallel_type.h \ + enum_partitioner_type.h enum_point_locator_type.h \ + enum_preconditioner_type.h enum_quadrature_type.h \ + enum_solver_package.h enum_solver_type.h \ + enum_subset_solve_mode.h enum_xdr_mode.h \ adjoint_refinement_estimator.h \ adjoint_residual_error_estimator.h discontinuity_measure.h \ error_estimator.h exact_error_estimator.h exact_solution.h \ @@ -1054,6 +1055,9 @@ enum_inf_map_type.h: $(top_srcdir)/include/enums/enum_inf_map_type.h enum_io_package.h: $(top_srcdir)/include/enums/enum_io_package.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ +enum_matrix_build_type.h: $(top_srcdir)/include/enums/enum_matrix_build_type.h + $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ + enum_norm_type.h: $(top_srcdir)/include/enums/enum_norm_type.h $(AM_V_GEN)rm -f $@ && $(LN_S) -f $< $@ From 4da49736753cdfefdcd97a6c58b3c4a3469a1a01 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 22 May 2025 13:44:07 -0600 Subject: [PATCH 35/41] Only assert matrix is not serial if global dofs and local dofs disagree --- src/numerics/petsc_matrix.C | 3 ++- src/numerics/petsc_matrix_shell_matrix.C | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/numerics/petsc_matrix.C b/src/numerics/petsc_matrix.C index 4516b1300e8..66157b15408 100644 --- a/src/numerics/petsc_matrix.C +++ b/src/numerics/petsc_matrix.C @@ -354,10 +354,11 @@ template void PetscMatrix::init (const ParallelType libmesh_dbg_var(type)) { libmesh_assert(this->_dof_map); - libmesh_assert(type != SERIAL); const numeric_index_type m_in = this->_dof_map->n_dofs(); const numeric_index_type m_l = this->_dof_map->n_local_dofs(); + if (m_in != m_l) + libmesh_assert(type != SERIAL); const auto blocksize = this->_dof_map->block_size(); diff --git a/src/numerics/petsc_matrix_shell_matrix.C b/src/numerics/petsc_matrix_shell_matrix.C index 495e54726bb..3afd09ea6dd 100644 --- a/src/numerics/petsc_matrix_shell_matrix.C +++ b/src/numerics/petsc_matrix_shell_matrix.C @@ -43,7 +43,13 @@ template void PetscMatrixShellMatrix::init(ParallelType libmesh_dbg_var(type)) { - libmesh_assert(type != SERIAL); +#ifndef NDEBUG + libmesh_assert(this->_dof_map); + const auto m = this->_dof_map->n_dofs(); + const auto m_l = this->_dof_map->n_local_dofs(); + if (m != m_l) + libmesh_assert(type != SERIAL); +#endif init_shell_mat(*this); this->set_context(); } From 9f830c98e096623c6ed6db5e8cede6afa84e9fee Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 22 May 2025 14:21:25 -0600 Subject: [PATCH 36/41] Slightly tweak SC dof map init comment --- src/systems/system.C | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systems/system.C b/src/systems/system.C index 6cba69a05ea..73b4b0c3f10 100644 --- a/src/systems/system.C +++ b/src/systems/system.C @@ -229,7 +229,7 @@ void System::init_data () // Distribute the degrees of freedom on the mesh auto total_dofs = _dof_map->distribute_dofs (mesh); - // With the global dofs determined, initialize the condensed system if it exists + // With the global dofs determined, initialize the condensed dof data if it exists if (_sc_dof_map) _sc_dof_map->init(); From b9cbbd11e503688192c8dccc4a821efa9773fbc6 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 22 May 2025 14:21:55 -0600 Subject: [PATCH 37/41] Add comment in vector fe ex9 example source about command line SC --- examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C b/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C index 3a190a23a55..7b4b5818938 100644 --- a/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C +++ b/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C @@ -154,6 +154,7 @@ main(int argc, char ** argv) StaticCondensationDofMap * sc_dof_map = nullptr; StaticCondensation * sc_system_matrix = nullptr; + // Has the user requested static condensation from the command line? if (system.has_static_condensation()) { sc_dof_map = &system.get_static_condensation_dof_map(); From 33b607a46238058ed2ee0ec9e9faf7228b22a393 Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 22 May 2025 15:02:03 -0600 Subject: [PATCH 38/41] Add some degree of freedom map doxygen --- include/base/dof_map_base.h | 20 +++++++++++++++++++ .../numerics/static_condensation_dof_map.h | 18 +++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/base/dof_map_base.h b/include/base/dof_map_base.h index c44fb445a9d..abd674c80fd 100644 --- a/include/base/dof_map_base.h +++ b/include/base/dof_map_base.h @@ -28,6 +28,26 @@ class Variable; class Elem; class Node; +/** + * This base class provides a minimal set of interfaces for satisfying user requests for + * - variables that contribute degrees of freedom to this map + * - distribution of degrees of freedom among ranks in parallel (e.g. MPI) simulations + * - degrees of freedom associated with nodes and elements + * This minimal set of interfaces is sufficient for providing information for use cases such + * as building field splits for advanced preconditioning techniques + * + * Sub-classes of this base class may not be fully-featured stand-alone degree of freedom maps. + * For instance a sub-class may not be constructible without information from an already constructed + * fully-featured degree of freedom map. As an example, a degree of freedom map for a statically + * condensed system of equations will require *a priori* and flow naturally from a degree of freedom + * map for the full non-condensed system. In this example, the partitioning of the statically + * condensed degrees of freedom may logically follow the partitioning in the global system, e.g. a + * face degree of freedom in the global system that is assigned to process i by the full degree of + * freedom map will retain its rank assignment in the statically condensed degree of freedom map. + * Because the statically condensed dof map can lazily use the information from the full dof map, + * it does not require its own partitioning capabilities. Consequently, partitioning interfaces + * are not present in this base interface + */ class DofMapBase : public ParallelObject { public: diff --git a/include/numerics/static_condensation_dof_map.h b/include/numerics/static_condensation_dof_map.h index f1105763f86..f3e6529e088 100644 --- a/include/numerics/static_condensation_dof_map.h +++ b/include/numerics/static_condensation_dof_map.h @@ -37,6 +37,24 @@ class System; class DofMap; class Elem; +/** + * A class holding degree of freedom information pertinent to static condensation. + * Static condensation is a process for reducing the number of unknowns in a + * linear(ized) system. It is often used in conjunction with a hybridized discontinuous Galerkin + * (HDG) method to reduce the number of unknowns in the linear system to something more on the order + * of a continuous Galerkin (CG) method as opposed to a discontinuous Galerkin method. In the HDG + * example, degrees of freedom on the element interiors are condensed out and only the degrees of + * freedom on element faces are retained in the condensed system. Static condensation is not only + * applicable to HDG methods, however. One could also use static condensation with a high order CG + * method, again removing internal degrees of freedom and leaving those on element boundaries. + * + * Users may query this class for condensed space degree of freedom information associated with + * elements. Queries with nodes are not supported. This class also holds information for mapping + * degree of freedom indices in the global, uncondensed space to local element degree of freedom + * numbers. This information is essential in order to build the element Schur complement matrices + * that are used to map global system vector and matrix data to the condensed system vector and + * matrix data + */ class StaticCondensationDofMap : public DofMapBase { public: From 6015c7f0be4cb036fa5aa6a1c93fa374b860b07e Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Tue, 27 May 2025 17:21:41 -0600 Subject: [PATCH 39/41] Restore at least those interfaces used by example code --- .../miscellaneous_ex16/miscellaneous_ex16.C | 4 ++-- examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C | 12 ++++-------- include/numerics/static_condensation.h | 13 ++++++++++--- include/systems/implicit_system.h | 4 ++-- src/numerics/static_condensation.C | 9 +++++++-- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/examples/miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C b/examples/miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C index 97081e02e1c..257fa261a79 100644 --- a/examples/miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C +++ b/examples/miscellaneous/miscellaneous_ex16/miscellaneous_ex16.C @@ -171,7 +171,7 @@ main(int argc, char ** argv) libmesh_error_msg_if(!libMesh::relative_fuzzy_equals(*sys.solution, *sc_sys.solution, 1e-4), "mismatching solution"); libMesh::out << "Static condensation reduced problem size to " - << sc_sys.get_static_condensation_system_matrix().get_condensed_mat().m() << std::endl; + << sc_sys.get_static_condensation().get_condensed_mat().m() << std::endl; #if defined(LIBMESH_HAVE_VTK) && !defined(LIBMESH_ENABLE_PARMESH) @@ -208,7 +208,7 @@ assemble_poisson(EquationSystems & es, const std::string & system_name) // Get a pointer to the StaticCondensation class if it exists StaticCondensation * sc = nullptr; if (system.has_static_condensation()) - sc = &system.get_static_condensation_system_matrix(); + sc = &system.get_static_condensation(); // A reference to the DofMap object for this system. The DofMap // object handles the index translation from node and element numbers diff --git a/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C b/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C index 7b4b5818938..965a1b6ac0b 100644 --- a/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C +++ b/examples/vector_fe/vector_fe_ex9/vector_fe_ex9.C @@ -52,7 +52,6 @@ #include "libmesh/equation_systems.h" #include "libmesh/nonlinear_implicit_system.h" #include "libmesh/nonlinear_solver.h" -#include "libmesh/static_condensation_dof_map.h" #include "libmesh/static_condensation.h" // The exact solution and error computation. @@ -152,14 +151,11 @@ main(int argc, char ** argv) const FEType scalar_fe_type(FIRST, L2_LAGRANGE); const FEType lm_fe_type(FIRST, SIDE_HIERARCHIC); - StaticCondensationDofMap * sc_dof_map = nullptr; - StaticCondensation * sc_system_matrix = nullptr; - // Has the user requested static condensation from the command line? + StaticCondensation * sc = nullptr; if (system.has_static_condensation()) { - sc_dof_map = &system.get_static_condensation_dof_map(); - sc_dof_map->dont_condense_vars({p_num}); - sc_system_matrix = cast_ptr(system.matrix); + sc = &system.get_static_condensation(); + sc->dont_condense_vars({p_num}); } HDGProblem hdg(nu, cavity); @@ -174,7 +170,7 @@ main(int argc, char ** argv) hdg.scalar_fe_face = FEBase::build(dimension, scalar_fe_type); hdg.lm_fe_face = FEBase::build(dimension, lm_fe_type); hdg.mms = mms; - hdg.sc = sc_system_matrix; + hdg.sc = sc; system.nonlinear_solver->residual_object = &hdg; system.nonlinear_solver->jacobian_object = &hdg; diff --git a/include/numerics/static_condensation.h b/include/numerics/static_condensation.h index 5c2a200d744..b71336a6676 100644 --- a/include/numerics/static_condensation.h +++ b/include/numerics/static_condensation.h @@ -63,7 +63,7 @@ class StaticCondensation : public PetscMatrixShellMatrix StaticCondensation(const MeshBase & mesh, System & system, const DofMap & full_dof_map, - const StaticCondensationDofMap & reduced_dof_map); + StaticCondensationDofMap & reduced_dof_map); virtual ~StaticCondensation(); // @@ -187,6 +187,13 @@ class StaticCondensation : public PetscMatrixShellMatrix */ void uncondensed_dofs_only() { _uncondensed_dofs_only = true; } + /** + * Add \p vars to the list of variables not to condense. This can be useful when some variable's + * equation is discretized with a DG method or if including the variable in the condensed block + * diagonal would result in it being singular + */ + void dont_condense_vars(const std::unordered_set & vars); + private: /** * Retrieves the degree of freedom values from \p global_vector corresponding to \p @@ -238,7 +245,7 @@ class StaticCondensation : public PetscMatrixShellMatrix const MeshBase & _mesh; System & _system; const DofMap & _full_dof_map; - const StaticCondensationDofMap & _reduced_dof_map; + StaticCondensationDofMap & _reduced_dof_map; /// global sparse matrix for the uncondensed degrees of freedom std::unique_ptr> _reduced_sys_mat; @@ -313,7 +320,7 @@ class StaticCondensation : public SparseMatrix StaticCondensation(const MeshBase &, const System &, const DofMap & full_dof_map, - const StaticCondensationDofMap & reduced_dof_map); + StaticCondensationDofMap & reduced_dof_map); const std::unordered_set & uncondensed_vars() const { libmesh_not_implemented(); } StaticCondensationPreconditioner & get_preconditioner() { libmesh_not_implemented(); } diff --git a/include/systems/implicit_system.h b/include/systems/implicit_system.h index 00e01798b86..b639fb965d8 100644 --- a/include/systems/implicit_system.h +++ b/include/systems/implicit_system.h @@ -343,7 +343,7 @@ class ImplicitSystem : public ExplicitSystem /** * \returns The static condensation system matrix */ - StaticCondensation & get_static_condensation_system_matrix(); + StaticCondensation & get_static_condensation(); protected: /** @@ -370,7 +370,7 @@ class ImplicitSystem : public ExplicitSystem }; inline -StaticCondensation & ImplicitSystem::get_static_condensation_system_matrix() +StaticCondensation & ImplicitSystem::get_static_condensation() { libmesh_assert(_sc_system_matrix); return *_sc_system_matrix; diff --git a/src/numerics/static_condensation.C b/src/numerics/static_condensation.C index 71a827e1f61..b24d05f5a39 100644 --- a/src/numerics/static_condensation.C +++ b/src/numerics/static_condensation.C @@ -39,7 +39,7 @@ namespace libMesh StaticCondensation::StaticCondensation(const MeshBase & mesh, System & system, const DofMap & full_dof_map, - const StaticCondensationDofMap & reduced_dof_map) + StaticCondensationDofMap & reduced_dof_map) : PetscMatrixShellMatrix(full_dof_map.comm()), _mesh(mesh), _system(system), @@ -463,6 +463,11 @@ void StaticCondensation::apply(const NumericVector & full_rhs, SolverPackage StaticCondensation::solver_package() { return libMesh::default_solver_package(); } +void StaticCondensation::dont_condense_vars(const std::unordered_set & vars) +{ + _reduced_dof_map.dont_condense_vars(vars); +} + } #else @@ -473,7 +478,7 @@ namespace libMesh StaticCondensation::StaticCondensation(const MeshBase &, const System &, const DofMap & full_dof_map, - const StaticCondensationDofMap &) + StaticCondensationDofMap &) : SparseMatrix(full_dof_map.comm()) { libmesh_error_msg( From a6789b2dd66b272820a50c83b7e50688a6f1a11c Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Thu, 29 May 2025 15:45:27 -0600 Subject: [PATCH 40/41] Move ownership of SC dof map to DofMap --- include/base/dof_map.h | 10 +++---- .../numerics/static_condensation_dof_map.h | 2 +- include/systems/system.h | 27 +------------------ src/base/dof_map.C | 15 +++++++++-- src/numerics/static_condensation_dof_map.C | 6 ++--- src/systems/implicit_system.C | 2 +- src/systems/system.C | 23 ++++++---------- 7 files changed, 31 insertions(+), 54 deletions(-) diff --git a/include/base/dof_map.h b/include/base/dof_map.h index d32fe043f08..ec8b64f9ef9 100644 --- a/include/base/dof_map.h +++ b/include/base/dof_map.h @@ -1660,18 +1660,18 @@ class DofMap : public DofMapBase, /** * Add a static condensation class */ - void add_static_condensation(const StaticCondensationDofMap & sc) { _sc = ≻ } + void create_static_condensation(const MeshBase & mesh, System & system); /** * Checks whether we have static condensation */ - bool has_static_condensation() const { return _sc; } + bool has_static_condensation() const { return _sc.get(); } /** * @returns the static condensation class. This should have been already added with a call to \p * add_static_condensation() */ - const StaticCondensationDofMap & get_static_condensation() const; + StaticCondensationDofMap & get_static_condensation(); private: @@ -2157,7 +2157,7 @@ class DofMap : public DofMapBase, bool _verify_dirichlet_bc_consistency; /// Static condensation class - const StaticCondensationDofMap * _sc; + std::unique_ptr _sc; }; @@ -2681,7 +2681,7 @@ void DofMap::dof_indices (const Elem * const elem, } inline -const StaticCondensationDofMap & DofMap::get_static_condensation() const +StaticCondensationDofMap & DofMap::get_static_condensation() { libmesh_assert(_sc); return *_sc; diff --git a/include/numerics/static_condensation_dof_map.h b/include/numerics/static_condensation_dof_map.h index f3e6529e088..88aba320424 100644 --- a/include/numerics/static_condensation_dof_map.h +++ b/include/numerics/static_condensation_dof_map.h @@ -68,7 +68,7 @@ class StaticCondensationDofMap : public DofMapBase /** * Build the element global to local index maps */ - void init(); + void reinit(); /** * Add \p vars to the list of variables not to condense. This can be useful when some variable's diff --git a/include/systems/system.h b/include/systems/system.h index 2e2f96a9e54..92bce8d6c25 100644 --- a/include/systems/system.h +++ b/include/systems/system.h @@ -74,7 +74,6 @@ class SystemSubset; class FEType; class SystemNorm; enum FEMNormType : int; -class StaticCondensationDofMap; /** * \brief Manages consistently variables, degrees of freedom, and coefficient @@ -1949,16 +1948,10 @@ class System : public ReferenceCountedObject, */ virtual void create_static_condensation(); - /** - * Retrieve the static condensation class. Errors if \p create_static_condensation() has not been - * called prior, so calls to this should be guarded by checking \p has_static_condensation() - */ - StaticCondensationDofMap & get_static_condensation_dof_map(); - /** * @returns Whether this system will be statically condensed */ - bool has_static_condensation() const { return _sc_dof_map.get(); } + bool has_static_condensation() const; protected: @@ -2026,11 +2019,6 @@ class System : public ReferenceCountedObject, virtual bool condense_constrained_dofs() const { return false; } private: - /** - * Creates the degree of freedom map for the statically condensed system - */ - void create_static_condensation_dof_map(); - /** * Helper function to keep DofMap forward declarable in system.h */ @@ -2131,9 +2119,6 @@ class System : public ReferenceCountedObject, dof_id_type write_serialized_vector (Xdr & io, const NumericVector & vec) const; - /// Degree of freedom map for the condensed space - std::unique_ptr _sc_dof_map; - /** * Function that initializes the system. */ @@ -2754,16 +2739,6 @@ System::prefer_hash_table_matrix_assembly(const bool preference) _prefer_hash_table_matrix_assembly = preference; } -inline -StaticCondensationDofMap & -System::get_static_condensation_dof_map() -{ - if (!_sc_dof_map) - libmesh_error_msg("Static condensation was not requested by the user"); - - return *_sc_dof_map; -} - } // namespace libMesh #endif // LIBMESH_SYSTEM_H diff --git a/src/base/dof_map.C b/src/base/dof_map.C index 774f8ded7b4..a30f2891f75 100644 --- a/src/base/dof_map.C +++ b/src/base/dof_map.C @@ -39,7 +39,7 @@ #include "libmesh/sparse_matrix.h" #include "libmesh/sparsity_pattern.h" #include "libmesh/threads.h" -#include "libmesh/static_condensation.h" +#include "libmesh/static_condensation_dof_map.h" // TIMPI includes #include "timpi/parallel_implementation.h" @@ -83,7 +83,7 @@ DofMap::build_sparsity (const MeshBase & mesh, if (use_condensed_system) { libmesh_assert(this->has_static_condensation()); - sc = &this->get_static_condensation(); + sc = _sc.get(); } // We can compute the sparsity pattern in parallel on multiple @@ -969,6 +969,8 @@ void DofMap::clear() #endif _matrices.clear(); + if (_sc) + _sc->clear(); } @@ -1135,6 +1137,10 @@ std::size_t DofMap::distribute_dofs (MeshBase & mesh) // each element. this->add_neighbors_to_send_list(mesh); + // With the global dofs determined, initialize the condensed dof data if it exists + if (_sc) + _sc->reinit(); + // Here we used to clean up that data structure; now System and // EquationSystems call that for us, after we've added constraint // dependencies to the send_list too. @@ -3070,6 +3076,11 @@ std::string DofMap::get_info() const return os.str(); } +void DofMap::create_static_condensation(const MeshBase & mesh, System & sys) +{ + _sc = std::make_unique(mesh, sys, *this); +} + template LIBMESH_EXPORT bool DofMap::is_evaluable(const Elem &, unsigned int) const; template LIBMESH_EXPORT bool DofMap::is_evaluable(const Node &, unsigned int) const; diff --git a/src/numerics/static_condensation_dof_map.C b/src/numerics/static_condensation_dof_map.C index 05c7cdd1ab4..4a634b3cbc5 100644 --- a/src/numerics/static_condensation_dof_map.C +++ b/src/numerics/static_condensation_dof_map.C @@ -41,11 +41,8 @@ StaticCondensationDofMap::StaticCondensationDofMap(const MeshBase & mesh, StaticCondensationDofMap::~StaticCondensationDofMap() = default; -void StaticCondensationDofMap::init() +void StaticCondensationDofMap::reinit() { - if (_sc_is_initialized) - return; - std::vector elem_dofs; // only used to satisfy API std::vector elem_uncondensed_dofs; std::unordered_set local_uncondensed_dofs; @@ -343,5 +340,6 @@ void StaticCondensationDofMap::clear() _reduced_sp = nullptr; _reduced_nnz.clear(); _reduced_noz.clear(); + _sc_is_initialized = false; } } diff --git a/src/systems/implicit_system.C b/src/systems/implicit_system.C index a64684762a7..8ec1c65319d 100644 --- a/src/systems/implicit_system.C +++ b/src/systems/implicit_system.C @@ -56,7 +56,7 @@ ImplicitSystem::~ImplicitSystem () = default; void ImplicitSystem::create_static_condensation_system_matrix() { - auto sc_system_matrix = std::make_unique(this->get_mesh(), *this, this->get_dof_map(), this->get_static_condensation_dof_map()); + auto sc_system_matrix = std::make_unique(this->get_mesh(), *this, this->get_dof_map(), this->get_dof_map().get_static_condensation()); _sc_system_matrix = sc_system_matrix.get(); matrix = &(this->add_matrix ("System Matrix", std::move(sc_system_matrix))); } diff --git a/src/systems/system.C b/src/systems/system.C index 73b4b0c3f10..c16b672b839 100644 --- a/src/systems/system.C +++ b/src/systems/system.C @@ -38,7 +38,6 @@ #include "libmesh/parallel_fe_type.h" #include "libmesh/fe_interface.h" #include "libmesh/fe_compute_data.h" -#include "libmesh/static_condensation_dof_map.h" #include "libmesh/static_condensation.h" // includes for calculate_norm, point_* @@ -75,7 +74,6 @@ System::System (EquationSystems & es, time (0.), qoi (0), qoi_error_estimates (0), - _sc_dof_map (nullptr), _init_system_function (nullptr), _init_system_object (nullptr), _assemble_system_function (nullptr), @@ -108,7 +106,7 @@ System::System (EquationSystems & es, if (libMesh::on_command_line("--solver-system-names")) this->prefix_with_name(true); if (libMesh::on_command_line("--" + name_in + "-static-condensation")) - this->create_static_condensation_dof_map(); + this->create_static_condensation(); } @@ -180,8 +178,6 @@ void System::clear () _variables.clear(); _variable_numbers.clear(); _dof_map->clear (); - if (_sc_dof_map) - _sc_dof_map->clear(); solution->clear (); current_local_solution->clear (); @@ -229,10 +225,6 @@ void System::init_data () // Distribute the degrees of freedom on the mesh auto total_dofs = _dof_map->distribute_dofs (mesh); - // With the global dofs determined, initialize the condensed dof data if it exists - if (_sc_dof_map) - _sc_dof_map->init(); - // Throw an error if the total number of DOFs is not capable of // being indexed by our solution vector. auto max_allowed_id = solution->max_allowed_id(); @@ -1028,8 +1020,10 @@ SparseMatrix & System::add_matrix (std::string_view mat_name, if (mat_build_type == MatrixBuildType::DIAGONAL) libmesh_error_msg( "We do not currently support static condensation of the diagonal matrix type"); - matrix = std::make_unique( - this->get_mesh(), *this, this->get_dof_map(), *_sc_dof_map); + matrix = std::make_unique(this->get_mesh(), + *this, + this->get_dof_map(), + this->get_dof_map().get_static_condensation()); } else matrix = SparseMatrix::build(this->comm(), libMesh::default_solver_package()); @@ -2862,13 +2856,12 @@ Tensor System::point_hessian(unsigned int, const Point &, const NumericVectorcreate_static_condensation_dof_map(); + this->get_dof_map().create_static_condensation(this->get_mesh(), *this); } -void System::create_static_condensation_dof_map() +bool System::has_static_condensation() const { - _sc_dof_map = std::make_unique(this->get_mesh(), *this, this->get_dof_map()); - this->get_dof_map().add_static_condensation(*_sc_dof_map); + return this->get_dof_map().has_static_condensation(); } } // namespace libMesh From f82ac5703efabfcce5b6babd31991ecd0d6087be Mon Sep 17 00:00:00 2001 From: Alex Lindsay Date: Mon, 2 Jun 2025 10:36:36 -0600 Subject: [PATCH 41/41] Add libmesh_experimental to StaticCondensationDofMap --- src/numerics/static_condensation_dof_map.C | 1 + 1 file changed, 1 insertion(+) diff --git a/src/numerics/static_condensation_dof_map.C b/src/numerics/static_condensation_dof_map.C index 4a634b3cbc5..09eb4b02303 100644 --- a/src/numerics/static_condensation_dof_map.C +++ b/src/numerics/static_condensation_dof_map.C @@ -37,6 +37,7 @@ StaticCondensationDofMap::StaticCondensationDofMap(const MeshBase & mesh, _dof_map(dof_map), _sc_is_initialized(false) { + libmesh_experimental(); } StaticCondensationDofMap::~StaticCondensationDofMap() = default; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy