dg_fem_context.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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  neighbor_side_fe_type,
102  &get_neighbor(),
103  qface_side_points,
104  qface_neighbor_points);
105 
106  pr.second->reinit(&get_neighbor(), &qface_neighbor_points);
107  }
108 
109  // Set boolean flag to indicate that the DG terms are active on this element
110  _dg_terms_active = true;
111 
112  // Also, initialize data required for DG assembly on the current side,
113  // analogously to FEMContext::pre_fe_reinit
114 
115  // Initialize the per-element data for elem.
117 
118  const unsigned int n_dofs = cast_int<unsigned int>
119  (this->get_dof_indices().size());
120  const unsigned int n_neighbor_dofs = cast_int<unsigned int>
121  (_neighbor_dof_indices.size());
122 
123  // These resize calls also zero out the residual and jacobian
124  _neighbor_residual.resize(n_neighbor_dofs);
125  _elem_elem_jacobian.resize(n_dofs, n_dofs);
126  _elem_neighbor_jacobian.resize(n_dofs, n_neighbor_dofs);
127  _neighbor_elem_jacobian.resize(n_neighbor_dofs, n_dofs);
128  _neighbor_neighbor_jacobian.resize(n_neighbor_dofs, n_neighbor_dofs);
129 
130  // Initialize the per-variable data for elem.
131  {
132  unsigned int sub_dofs = 0;
133  for (unsigned int i=0; i != get_system().n_vars(); ++i)
134  {
136 
137  const unsigned int n_dofs_var = cast_int<unsigned int>
138  (_neighbor_dof_indices_var[i].size());
139 
140  _neighbor_subresiduals[i]->reposition
141  (sub_dofs, n_dofs_var);
142 
143  for (unsigned int j=0; j != i; ++j)
144  {
145  const unsigned int n_dofs_var_j =
146  cast_int<unsigned int>
147  (this->get_dof_indices(j).size());
148 
149  _elem_elem_subjacobians[i][j]->reposition
150  (sub_dofs, _neighbor_subresiduals[j]->i_off(),
151  n_dofs_var, n_dofs_var_j);
152  _elem_elem_subjacobians[j][i]->reposition
153  (_neighbor_subresiduals[j]->i_off(), sub_dofs,
154  n_dofs_var_j, n_dofs_var);
155 
156  _elem_neighbor_subjacobians[i][j]->reposition
157  (sub_dofs, _neighbor_subresiduals[j]->i_off(),
158  n_dofs_var, n_dofs_var_j);
159  _elem_neighbor_subjacobians[j][i]->reposition
160  (_neighbor_subresiduals[j]->i_off(), sub_dofs,
161  n_dofs_var_j, n_dofs_var);
162 
163  _neighbor_elem_subjacobians[i][j]->reposition
164  (sub_dofs, _neighbor_subresiduals[j]->i_off(),
165  n_dofs_var, n_dofs_var_j);
166  _neighbor_elem_subjacobians[j][i]->reposition
167  (_neighbor_subresiduals[j]->i_off(), sub_dofs,
168  n_dofs_var_j, n_dofs_var);
169 
170  _neighbor_neighbor_subjacobians[i][j]->reposition
171  (sub_dofs, _neighbor_subresiduals[j]->i_off(),
172  n_dofs_var, n_dofs_var_j);
173  _neighbor_neighbor_subjacobians[j][i]->reposition
174  (_neighbor_subresiduals[j]->i_off(), sub_dofs,
175  n_dofs_var_j, n_dofs_var);
176  }
177  _elem_elem_subjacobians[i][i]->reposition
178  (sub_dofs, sub_dofs,
179  n_dofs_var,
180  n_dofs_var);
181  _elem_neighbor_subjacobians[i][i]->reposition
182  (sub_dofs, sub_dofs,
183  n_dofs_var,
184  n_dofs_var);
185  _neighbor_elem_subjacobians[i][i]->reposition
186  (sub_dofs, sub_dofs,
187  n_dofs_var,
188  n_dofs_var);
189  _neighbor_neighbor_subjacobians[i][i]->reposition
190  (sub_dofs, sub_dofs,
191  n_dofs_var,
192  n_dofs_var);
193  sub_dofs += n_dofs_var;
194  }
195  libmesh_assert_equal_to (sub_dofs, n_dofs);
196  }
197 
198 }
199 
200 }
Manages the family, order, etc. parameters for a given FE.
Definition: fe_type.h:179
std::vector< dof_id_type > _neighbor_dof_indices
const std::vector< Point > & get_xyz() const
Definition: fe_abstract.h:238
DenseVector< Number > _neighbor_residual
DenseMatrix< Number > _elem_elem_jacobian
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:1930
std::vector< std::vector< std::unique_ptr< DenseSubMatrix< Number > > > > _elem_elem_subjacobians
virtual void side_fe_reinit() override
void resize(const unsigned int n)
Definition: dense_vector.h:355
std::vector< std::vector< dof_id_type > > _neighbor_dof_indices_var
std::vector< FEAbstract * > _neighbor_side_fe_var
const unsigned int n_vars
Definition: tecplot_io.C:69
unsigned char get_dim() const
Definition: fem_context.h:899
virtual void side_fe_reinit()
Definition: fem_context.C:1383
const System & get_system() const
Definition: diff_context.h:105
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:92
DenseMatrix< Number > _neighbor_elem_jacobian
static Point inverse_map(const unsigned int dim, const FEType &fe_t, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
Definition: fe_interface.C:590
const std::vector< dof_id_type > & get_dof_indices() const
Definition: diff_context.h:367
DenseMatrix< Number > _elem_neighbor_jacobian
std::vector< std::vector< std::unique_ptr< DenseSubMatrix< Number > > > > _elem_neighbor_subjacobians
unsigned char _dim
Definition: fem_context.h:1124
std::vector< std::map< FEType, std::unique_ptr< FEAbstract > > > _side_fe
Definition: fem_context.h:1096
const FEType & variable_type(const unsigned int i) const
Definition: system.h:2183
std::vector< std::vector< std::unique_ptr< DenseSubMatrix< Number > > > > _neighbor_elem_subjacobians
DGFEMContext(const System &sys)
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Definition: fe_abstract.C:71
DenseMatrix< Number > _neighbor_neighbor_jacobian
void resize(const unsigned int new_m, const unsigned int new_n)
Definition: dense_matrix.h:792
std::vector< std::unique_ptr< DenseSubVector< Number > > > _neighbor_subresiduals
unsigned int n_vars() const
Definition: system.h:2105
std::map< FEType, std::unique_ptr< FEAbstract > > _neighbor_side_fe
const DofMap & get_dof_map() const
Definition: system.h:2049
const Elem & get_neighbor() const
std::vector< std::vector< std::unique_ptr< DenseSubMatrix< Number > > > > _neighbor_neighbor_subjacobians