libMesh
dg_fem_context.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #include "libmesh/dg_fem_context.h"
19 #include "libmesh/dof_map.h"
20 #include "libmesh/elem.h"
21 #include "libmesh/fe_base.h"
22 #include "libmesh/fe_interface.h"
23 #include "libmesh/quadrature.h"
24 #include "libmesh/system.h"
25 
26 namespace libMesh
27 {
28 
30  : FEMContext(sys),
31  _neighbor(nullptr),
32  _neighbor_dof_indices_var(sys.n_vars()),
33  _dg_terms_active(false)
34 {
35  unsigned int nv = sys.n_vars();
36  libmesh_assert (nv);
37 
38  _neighbor_subresiduals.reserve(nv);
39  _elem_elem_subjacobians.resize(nv);
40  _elem_neighbor_subjacobians.resize(nv);
41  _neighbor_elem_subjacobians.resize(nv);
43 
44  for (unsigned int i=0; i != nv; ++i)
45  {
46  _neighbor_subresiduals.emplace_back(libmesh_make_unique<DenseSubVector<Number>>(_neighbor_residual));
47  _elem_elem_subjacobians[i].reserve(nv);
48  _elem_neighbor_subjacobians[i].reserve(nv);
49  _neighbor_elem_subjacobians[i].reserve(nv);
50  _neighbor_neighbor_subjacobians[i].reserve(nv);
51 
52  for (unsigned int j=0; j != nv; ++j)
53  {
54  _elem_elem_subjacobians[i].emplace_back(libmesh_make_unique<DenseSubMatrix<Number>>(_elem_elem_jacobian));
55  _elem_neighbor_subjacobians[i].emplace_back(libmesh_make_unique<DenseSubMatrix<Number>>(_elem_neighbor_jacobian));
56  _neighbor_elem_subjacobians[i].emplace_back(libmesh_make_unique<DenseSubMatrix<Number>>(_neighbor_elem_jacobian));
58  }
59  }
60 
61  _neighbor_side_fe_var.resize(nv);
62  for (unsigned int i=0; i != nv; ++i)
63  {
64  FEType fe_type = sys.variable_type(i);
65 
66  if (_neighbor_side_fe[fe_type] == nullptr)
67  _neighbor_side_fe[fe_type] = FEAbstract::build(this->_dim, fe_type);
68 
69  _neighbor_side_fe_var[i] = _neighbor_side_fe[fe_type].get();
70  }
71 }
72 
74 {
75 }
76 
78 {
80 
81  // By default we assume that the DG terms are inactive
82  // They are only active if neighbor_side_fe_reinit is called
83  _dg_terms_active = false;
84 }
85 
87 {
88  // Call this *after* side_fe_reinit
89 
90  // Initialize all the neighbor side FE objects based on inverse mapping
91  // the quadrature points on the current side
92  std::vector<Point> qface_side_points;
93  std::vector<Point> qface_neighbor_points;
94  for (auto & pr : _neighbor_side_fe)
95  {
96  FEType neighbor_side_fe_type = pr.first;
97  FEAbstract * side_fe = _side_fe[this->get_dim()][neighbor_side_fe_type].get();
98  qface_side_points = side_fe->get_xyz();
99 
101  qface_side_points, qface_neighbor_points);
102 
103  pr.second->reinit(&get_neighbor(), &qface_neighbor_points);
104  }
105 
106  // Set boolean flag to indicate that the DG terms are active on this element
107  _dg_terms_active = true;
108 
109  // Also, initialize data required for DG assembly on the current side,
110  // analogously to FEMContext::pre_fe_reinit
111 
112  // Initialize the per-element data for elem.
114 
115  const unsigned int n_dofs = cast_int<unsigned int>
116  (this->get_dof_indices().size());
117  const unsigned int n_neighbor_dofs = cast_int<unsigned int>
118  (_neighbor_dof_indices.size());
119 
120  // These resize calls also zero out the residual and jacobian
121  _neighbor_residual.resize(n_neighbor_dofs);
122  _elem_elem_jacobian.resize(n_dofs, n_dofs);
123  _elem_neighbor_jacobian.resize(n_dofs, n_neighbor_dofs);
124  _neighbor_elem_jacobian.resize(n_neighbor_dofs, n_dofs);
125  _neighbor_neighbor_jacobian.resize(n_neighbor_dofs, n_neighbor_dofs);
126 
127  // Initialize the per-variable data for elem.
128  {
129  unsigned int sub_dofs = 0;
130  for (auto i : IntRange<unsigned int>(0, get_system().n_vars()))
131  {
133 
134  const unsigned int n_dofs_var = cast_int<unsigned int>
135  (_neighbor_dof_indices_var[i].size());
136 
137  _neighbor_subresiduals[i]->reposition
138  (sub_dofs, n_dofs_var);
139 
140  for (unsigned int j=0; j != i; ++j)
141  {
142  const unsigned int n_dofs_var_j =
143  cast_int<unsigned int>
144  (this->get_dof_indices(j).size());
145 
146  _elem_elem_subjacobians[i][j]->reposition
147  (sub_dofs, _neighbor_subresiduals[j]->i_off(),
148  n_dofs_var, n_dofs_var_j);
149  _elem_elem_subjacobians[j][i]->reposition
150  (_neighbor_subresiduals[j]->i_off(), sub_dofs,
151  n_dofs_var_j, n_dofs_var);
152 
153  _elem_neighbor_subjacobians[i][j]->reposition
154  (sub_dofs, _neighbor_subresiduals[j]->i_off(),
155  n_dofs_var, n_dofs_var_j);
156  _elem_neighbor_subjacobians[j][i]->reposition
157  (_neighbor_subresiduals[j]->i_off(), sub_dofs,
158  n_dofs_var_j, n_dofs_var);
159 
160  _neighbor_elem_subjacobians[i][j]->reposition
161  (sub_dofs, _neighbor_subresiduals[j]->i_off(),
162  n_dofs_var, n_dofs_var_j);
163  _neighbor_elem_subjacobians[j][i]->reposition
164  (_neighbor_subresiduals[j]->i_off(), sub_dofs,
165  n_dofs_var_j, n_dofs_var);
166 
167  _neighbor_neighbor_subjacobians[i][j]->reposition
168  (sub_dofs, _neighbor_subresiduals[j]->i_off(),
169  n_dofs_var, n_dofs_var_j);
170  _neighbor_neighbor_subjacobians[j][i]->reposition
171  (_neighbor_subresiduals[j]->i_off(), sub_dofs,
172  n_dofs_var_j, n_dofs_var);
173  }
174  _elem_elem_subjacobians[i][i]->reposition
175  (sub_dofs, sub_dofs,
176  n_dofs_var,
177  n_dofs_var);
178  _elem_neighbor_subjacobians[i][i]->reposition
179  (sub_dofs, sub_dofs,
180  n_dofs_var,
181  n_dofs_var);
182  _neighbor_elem_subjacobians[i][i]->reposition
183  (sub_dofs, sub_dofs,
184  n_dofs_var,
185  n_dofs_var);
186  _neighbor_neighbor_subjacobians[i][i]->reposition
187  (sub_dofs, sub_dofs,
188  n_dofs_var,
189  n_dofs_var);
190  sub_dofs += n_dofs_var;
191  }
192  libmesh_assert_equal_to (sub_dofs, n_dofs);
193  }
194 
195 }
196 
197 }
libMesh::System
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:100
libMesh::DGFEMContext::_elem_neighbor_subjacobians
std::vector< std::vector< std::unique_ptr< DenseSubMatrix< Number > > > > _elem_neighbor_subjacobians
Definition: dg_fem_context.h:267
libMesh::System::n_vars
unsigned int n_vars() const
Definition: system.h:2155
libMesh::DGFEMContext::neighbor_side_fe_reinit
void neighbor_side_fe_reinit()
Initialize neighbor side data needed to assemble DG terms.
Definition: dg_fem_context.C:86
libMesh::DGFEMContext::_neighbor_dof_indices
std::vector< dof_id_type > _neighbor_dof_indices
Global Degree of freedom index lists for the neighbor element.
Definition: dg_fem_context.h:274
libMesh::FEAbstract::get_xyz
const std::vector< Point > & get_xyz() const
Definition: fe_abstract.h:237
libMesh::DofMap::dof_indices
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:1967
n_vars
unsigned int n_vars
Definition: adaptivity_ex3.C:116
libMesh::DiffContext::get_dof_indices
const std::vector< dof_id_type > & get_dof_indices() const
Accessor for element dof indices.
Definition: diff_context.h:367
libMesh::DGFEMContext::side_fe_reinit
virtual void side_fe_reinit() override
Override side_fe_reinit to set a boolean flag so that by default DG terms are assumed to be inactive.
Definition: dg_fem_context.C:77
libMesh::FEMContext::side_fe_reinit
virtual void side_fe_reinit()
Reinitializes side FE objects on the current geometric element.
Definition: fem_context.C:1457
libMesh::DGFEMContext::_elem_elem_jacobian
DenseMatrix< Number > _elem_elem_jacobian
The DG Jacobian terms.
Definition: dg_fem_context.h:257
libMesh::DenseSubMatrix
Defines a dense submatrix for use in Finite Element-type computations.
Definition: dense_submatrix.h:45
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::DiffContext::n_vars
unsigned int n_vars() const
Number of variables in solution.
Definition: diff_context.h:99
libMesh::FEAbstract
This class forms the foundation from which generic finite elements may be derived.
Definition: fe_abstract.h:100
libMesh::FEMContext::_side_fe
std::vector< std::map< FEType, std::unique_ptr< FEAbstract > > > _side_fe
Definition: fem_context.h:1137
libMesh::DiffContext::get_system
const System & get_system() const
Accessor for associated system.
Definition: diff_context.h:105
libMesh::DGFEMContext::_elem_elem_subjacobians
std::vector< std::vector< std::unique_ptr< DenseSubMatrix< Number > > > > _elem_elem_subjacobians
Definition: dg_fem_context.h:266
libMesh::DGFEMContext::_neighbor_dof_indices_var
std::vector< std::vector< dof_id_type > > _neighbor_dof_indices_var
Definition: dg_fem_context.h:275
libMesh::DenseMatrix::resize
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
Definition: dense_matrix.h:822
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::IntRange
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libMesh::FEMap::inverse_map
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition: fe_map.C:1622
libMesh::DGFEMContext::_neighbor_side_fe_var
std::vector< FEAbstract * > _neighbor_side_fe_var
Pointers to the same finite element objects on the neighbor element, but indexed by variable number.
Definition: dg_fem_context.h:290
libMesh::FEAbstract::build
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
Definition: fe_abstract.C:72
libMesh::DGFEMContext::_neighbor_neighbor_jacobian
DenseMatrix< Number > _neighbor_neighbor_jacobian
Definition: dg_fem_context.h:260
libMesh::DGFEMContext::_elem_neighbor_jacobian
DenseMatrix< Number > _elem_neighbor_jacobian
Definition: dg_fem_context.h:258
libMesh::DGFEMContext::_neighbor_residual
DenseVector< Number > _neighbor_residual
Residual vector of the neighbor component.
Definition: dg_fem_context.h:251
libMesh::DenseSubVector< Number >
libMesh::DGFEMContext::_neighbor_elem_jacobian
DenseMatrix< Number > _neighbor_elem_jacobian
Definition: dg_fem_context.h:259
libMesh::System::variable_type
const FEType & variable_type(const unsigned int i) const
Definition: system.h:2233
libMesh::DenseVector::resize
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:355
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::DGFEMContext::_neighbor_subresiduals
std::vector< std::unique_ptr< DenseSubVector< Number > > > _neighbor_subresiduals
Element residual subvectors and Jacobian submatrices.
Definition: dg_fem_context.h:265
libMesh::DGFEMContext::_neighbor_neighbor_subjacobians
std::vector< std::vector< std::unique_ptr< DenseSubMatrix< Number > > > > _neighbor_neighbor_subjacobians
Definition: dg_fem_context.h:269
libMesh::DGFEMContext::_neighbor_side_fe
std::map< FEType, std::unique_ptr< FEAbstract > > _neighbor_side_fe
Finite element objects for each variable's sides on the neighbor element.
Definition: dg_fem_context.h:284
libMesh::FEMContext::get_dim
unsigned char get_dim() const
Accessor for cached mesh dimension.
Definition: fem_context.h:924
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::DGFEMContext::_dg_terms_active
bool _dg_terms_active
Boolean flag to indicate whether or not the DG terms have been assembled and should be used in the gl...
Definition: dg_fem_context.h:296
libMesh::DGFEMContext::DGFEMContext
DGFEMContext(const System &sys)
Constructor.
Definition: dg_fem_context.C:29
libMesh::DGFEMContext::~DGFEMContext
virtual ~DGFEMContext()
Destructor.
Definition: dg_fem_context.C:73
libMesh::DGFEMContext::_neighbor_elem_subjacobians
std::vector< std::vector< std::unique_ptr< DenseSubMatrix< Number > > > > _neighbor_elem_subjacobians
Definition: dg_fem_context.h:268
libMesh::DGFEMContext::get_neighbor
const Elem & get_neighbor() const
Accessor for current neighbor Elem object for assembling DG terms.
Definition: dg_fem_context.h:226
libMesh::FEMContext::_dim
unsigned char _dim
Cached dimension of largest dimension element in this mesh.
Definition: fem_context.h:1165
libMesh::FEMContext
This class provides all data required for a physics package (e.g.
Definition: fem_context.h:62