143{
146
147
148
149 libmesh_assert_equal_to (system_name, "EllipticDG");
150
151
153
155
156
158
160 std::string refinement_type = es.
parameters.
get<std::string> (
"refinement");
161
162
163
164
166
167
168
170
171
172
173
174
178
179
180#ifdef QORDER
182#else
184#endif
185 fe->attach_quadrature_rule (&qrule);
186
187#ifdef QORDER
189#else
191#endif
192
193
194 fe_elem_face->attach_quadrature_rule(&qface);
195 fe_neighbor_face->attach_quadrature_rule(&qface);
196
197
198
199
200 const std::vector<Real> & JxW = fe->get_JxW();
201 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
202
203
204 const std::vector<std::vector<Real>> & phi_face = fe_elem_face->get_phi();
205 const std::vector<std::vector<RealGradient>> & dphi_face = fe_elem_face->get_dphi();
206 const std::vector<Real> & JxW_face = fe_elem_face->get_JxW();
207 const std::vector<Point> & qface_normals = fe_elem_face->get_normals();
208 const std::vector<Point> & qface_points = fe_elem_face->get_xyz();
209
210
211 const std::vector<std::vector<Real>> & phi_neighbor_face = fe_neighbor_face->get_phi();
212 const std::vector<std::vector<RealGradient>> & dphi_neighbor_face = fe_neighbor_face->get_dphi();
213
214
215
216
217
220
221
222
223
224
229
230
231
232
233 std::vector<dof_id_type> dof_indices;
234
235
237
238
239
240
241
243
244
245
246
247 for (
const auto & elem :
mesh.active_local_element_ptr_range())
248 {
249
250
251
252
253 dof_map.dof_indices (elem, dof_indices);
254 const unsigned int n_dofs =
255 cast_int<unsigned int>(dof_indices.size());
256
257
258
259
260
261 fe->reinit (elem);
262
263
264
265
266
267 Ke.
resize (n_dofs, n_dofs);
269
270
271
272
273 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
274 for (unsigned int i=0; i<n_dofs; i++)
275 for (unsigned int j=0; j<n_dofs; j++)
276 Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
277
278
279
280
281
282
283 for (auto side : elem->side_index_range())
284 {
285 if (elem->neighbor_ptr(side) == nullptr)
286 {
287
288 fe_elem_face->reinit(elem, side);
289
290
291 const auto side_volume = side_builder(*elem, side).volume();
292 const unsigned int elem_b_order = static_cast<unsigned int> (fe_elem_face->get_order());
293 const Real h_elem = elem->volume()/side_volume * 1./
pow(elem_b_order, 2.);
294
295 for (unsigned int qp=0; qp<qface.n_points(); qp++)
296 {
298 for (unsigned int i=0; i<n_dofs; i++)
299 {
300
301 for (unsigned int j=0; j<n_dofs; j++)
302 {
303
304 Ke(i,j) += JxW_face[qp] * penalty/h_elem * phi_face[i][qp] * phi_face[j][qp];
305
306
307 Ke(i,j) -=
308 JxW_face[qp] *
309 (phi_face[i][qp] * (dphi_face[j][qp]*qface_normals[qp]) +
310 phi_face[j][qp] * (dphi_face[i][qp]*qface_normals[qp]));
311 }
312
313
314
315
316 Fe(i) += JxW_face[qp] * bc_value * penalty/h_elem * phi_face[i][qp];
317
318
319 Fe(i) -= JxW_face[qp] * dphi_face[i][qp] * (bc_value*qface_normals[qp]);
320 }
321 }
322 }
323
324
325
326
327 else
328 {
329
330
332
333
334 const unsigned int elem_id = elem->
id();
335 const unsigned int neighbor_id = neighbor->
id();
336
337
338
339
340
341
342 if ((neighbor->
active() &&
343 (neighbor->
level() == elem->level()) &&
344 (elem_id < neighbor_id)) ||
345 (neighbor->
level() < elem->level()))
346 {
347 const Elem & elem_side = side_builder(*elem, side);
348
349
350 const unsigned int elem_b_order = static_cast<unsigned int>(fe_elem_face->get_order());
351 const unsigned int neighbor_b_order = static_cast<unsigned int>(fe_neighbor_face->get_order());
352 const double side_order = (elem_b_order + neighbor_b_order)/2.;
353 const Real h_elem = (elem->volume()/elem_side.
volume()) * 1./
pow(side_order,2.);
354
355
356 std::vector<Point> qface_neighbor_point;
357
358
359 std::vector<Point > qface_point;
360
361
362 fe_elem_face->reinit(elem, side);
363
364
365 qface_point = fe_elem_face->get_xyz();
366
367
369 if (refinement_type == "p")
370 fe_neighbor_face->side_map (neighbor,
371 &elem_side,
372 side_neighbor,
373 qface.get_points(),
374 qface_neighbor_point);
375 else
377 qface_point,
378 qface_neighbor_point);
379
380
381 fe_neighbor_face->reinit(neighbor, &qface_neighbor_point);
382
383
384
385
386 std::vector<dof_id_type> neighbor_dof_indices;
387 dof_map.dof_indices (neighbor, neighbor_dof_indices);
388 const unsigned int n_neighbor_dofs =
389 cast_int<unsigned int>(neighbor_dof_indices.size());
390
391
392
393
394
395
396
397 Kne.
resize (n_neighbor_dofs, n_dofs);
398 Ken.
resize (n_dofs, n_neighbor_dofs);
399 Kee.
resize (n_dofs, n_dofs);
400 Knn.
resize (n_neighbor_dofs, n_neighbor_dofs);
401
402
403
404
405
406 for (unsigned int qp=0; qp<qface.n_points(); qp++)
407 {
408
409
410 for (unsigned int i=0; i<n_dofs; i++)
411 {
412 for (unsigned int j=0; j<n_dofs; j++)
413 {
414
415 Kee(i,j) -=
416 0.5 * JxW_face[qp] *
417 (phi_face[j][qp]*(qface_normals[qp]*dphi_face[i][qp]) +
418 phi_face[i][qp]*(qface_normals[qp]*dphi_face[j][qp]));
419
420
421 Kee(i,j) += JxW_face[qp] * penalty/h_elem * phi_face[j][qp]*phi_face[i][qp];
422 }
423 }
424
425
426
427 for (unsigned int i=0; i<n_neighbor_dofs; i++)
428 {
429 for (unsigned int j=0; j<n_neighbor_dofs; j++)
430 {
431
432 Knn(i,j) +=
433 0.5 * JxW_face[qp] *
434 (phi_neighbor_face[j][qp]*(qface_normals[qp]*dphi_neighbor_face[i][qp]) +
435 phi_neighbor_face[i][qp]*(qface_normals[qp]*dphi_neighbor_face[j][qp]));
436
437
438 Knn(i,j) +=
439 JxW_face[qp] * penalty/h_elem * phi_neighbor_face[j][qp]*phi_neighbor_face[i][qp];
440 }
441 }
442
443
444
445 for (unsigned int i=0; i<n_neighbor_dofs; i++)
446 {
447 for (unsigned int j=0; j<n_dofs; j++)
448 {
449
450 Kne(i,j) +=
451 0.5 * JxW_face[qp] *
452 (phi_neighbor_face[i][qp]*(qface_normals[qp]*dphi_face[j][qp]) -
453 phi_face[j][qp]*(qface_normals[qp]*dphi_neighbor_face[i][qp]));
454
455
456 Kne(i,j) -= JxW_face[qp] * penalty/h_elem * phi_face[j][qp]*phi_neighbor_face[i][qp];
457 }
458 }
459
460
461
462 for (unsigned int i=0; i<n_dofs; i++)
463 {
464 for (unsigned int j=0; j<n_neighbor_dofs; j++)
465 {
466
467 Ken(i,j) +=
468 0.5 * JxW_face[qp] *
469 (phi_neighbor_face[j][qp]*(qface_normals[qp]*dphi_face[i][qp]) -
470 phi_face[i][qp]*(qface_normals[qp]*dphi_neighbor_face[j][qp]));
471
472
473 Ken(i,j) -= JxW_face[qp] * penalty/h_elem * phi_face[i][qp]*phi_neighbor_face[j][qp];
474 }
475 }
476 }
477
478
479
480
481 matrix.
add_matrix(Kne, neighbor_dof_indices, dof_indices);
482 matrix.
add_matrix(Ken, dof_indices, neighbor_dof_indices);
485 }
486 }
487 }
488
489
490
491
494 }
495
497}
Number(* exact_solution)(const Point &p, const Parameters &, const std::string &, const std::string &)
BasicOStreamProxy & flush()
Flush the associated stream buffer.
Defines a dense matrix for use in Finite Element-type computations.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
This class handles the numbering of degrees of freedom on a mesh.
Helper for building element sides that minimizes the construction of new elements.
This is the base class from which all geometric element types are derived.
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
unsigned int level() const
virtual Real volume() const
const Elem * neighbor_ptr(unsigned int i) const
const MeshBase & get_mesh() const
Parameters parameters
Data structure holding arbitrary parameters.
const T_sys & get_system(std::string_view name) const
NumericVector< Number > * rhs
The system matrix.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Order default_quadrature_order() const
const SparseMatrix< Number > & get_system_matrix() const
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and linear solvers ...
This is the MeshBase class.
unsigned int mesh_dimension() const
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
const T & get(std::string_view) const
This class implements specific orders of Gauss quadrature.
virtual void add_matrix(const DenseMatrix< T > &dm, const std::vector< numeric_index_type > &rows, const std::vector< numeric_index_type > &cols)=0
Add the full matrix dm to the SparseMatrix.
const FEType & variable_type(const unsigned int i) const
const DofMap & get_dof_map() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real