262{
263
264
265
266 libmesh_assert_equal_to (system_name, "DivGrad");
267
268
270
271
273
274
276
277
279
280
281
282
284
285
286
289
290
291
292
293
294
295
298
299
301
302
303 vector_fe->attach_quadrature_rule (&qrule);
304 scalar_fe->attach_quadrature_rule (&qrule);
305
306
308
309
310
312
313
314 vector_fe_face->attach_quadrature_rule (&qface);
315
316
317
318
319
320 const std::vector<Real> & JxW = vector_fe->get_JxW();
321
322
323
324
325 const std::vector<Point> & q_point = vector_fe->get_xyz();
326
327
328 const std::vector<std::vector<RealGradient>> & vector_phi = vector_fe->get_phi();
329 const std::vector<std::vector<Real>> & scalar_phi = scalar_fe->get_phi();
330
331
332
333 const std::vector<std::vector<Real>> & div_vector_phi = vector_fe->get_div_phi();
334
335
336
337
338
339
340
343
344
345
346
347 std::vector<dof_id_type> dof_indices;
348 std::vector<dof_id_type> vector_dof_indices;
349 std::vector<dof_id_type> scalar_dof_indices;
350 std::vector<dof_id_type> lambda_dof_indices;
351
352
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368 for (
const auto & elem :
mesh.active_local_element_ptr_range())
369 {
370
371
372
373
374 dof_map.dof_indices (elem, dof_indices);
375 dof_map.dof_indices (elem, vector_dof_indices, system.
variable_number(
"u"));
376 dof_map.dof_indices (elem, scalar_dof_indices, system.
variable_number(
"p"));
377 if (neumann)
378 dof_map.dof_indices (elem, lambda_dof_indices, system.
variable_number(
"l"));
379
380
381
382
383
384
385 const unsigned int n_dofs =
386 cast_int<unsigned int>(dof_indices.size());
387 const unsigned int vector_n_dofs =
388 cast_int<unsigned int>(vector_dof_indices.size());
389 const unsigned int scalar_n_dofs =
390 cast_int<unsigned int>(scalar_dof_indices.size());
391 const unsigned int lambda_n_dofs =
392 cast_int<unsigned int>(lambda_dof_indices.size());
393
394
395
396
397
398 vector_fe->reinit (elem);
399 scalar_fe->reinit (elem);
400
401
402
403
404 libmesh_assert_equal_to (n_dofs, vector_n_dofs + scalar_n_dofs + lambda_n_dofs);
405 libmesh_assert_equal_to (vector_n_dofs, vector_phi.size());
406 libmesh_assert_equal_to (scalar_n_dofs, scalar_phi.size());
407
408
409
410
411
412
413
414
415
416
417 Ke.
resize (n_dofs, n_dofs);
419
420
421
422 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
423 {
424
425
426
427
428 for (unsigned int i = 0; i != vector_n_dofs; i++)
429 for (unsigned int j = 0; j != vector_n_dofs; j++)
430 {
431 Ke(i, j) += JxW[qp]*(vector_phi[i][qp]*vector_phi[j][qp]);
432 }
433
434
435
436
437 for (unsigned int i = 0; i != vector_n_dofs; i++)
438 for (unsigned int l = 0; l != scalar_n_dofs; l++)
439 {
440 Ke(i, l + vector_n_dofs) -= JxW[qp]*(div_vector_phi[i][qp]*scalar_phi[l][qp]);
441 }
442
443
444
445
446 for (unsigned int k = 0; k != scalar_n_dofs; k++)
447 for (unsigned int j = 0; j != vector_n_dofs; j++)
448 {
449 Ke(k + vector_n_dofs, j) -= JxW[qp]*(div_vector_phi[j][qp]*scalar_phi[k][qp]);
450 }
451
452
453
454
455
456 {
457
458 const Real x = q_point[qp](0);
459 const Real y = q_point[qp](1);
460 const Real z = q_point[qp](2);
461
462
463
464
470
471
472
473 for (unsigned int k = 0; k != scalar_n_dofs; k++)
474 {
475 Fe(k + vector_n_dofs) -= JxW[qp]*f*scalar_phi[k][qp];
476 }
477 }
478
479
480
481
482
483
484 {
485
486 const Real x = q_point[qp](0);
487 const Real y = q_point[qp](1);
488 const Real z = q_point[qp](2);
489
490
491 Real scalar_value = 0;
496
497
498
499 for (unsigned int k = 0; k != scalar_n_dofs; k++)
500 for (unsigned int n = 0; n != lambda_n_dofs; n++)
501 {
502 Ke(k + vector_n_dofs, n + vector_n_dofs + scalar_n_dofs) += JxW[qp]*scalar_phi[k][qp];
503 }
504
505
506
507 for (unsigned int m = 0; m != lambda_n_dofs; m++)
508 for (unsigned int l = 0; l != scalar_n_dofs; l++)
509 {
510 Ke(m + vector_n_dofs + scalar_n_dofs, l + vector_n_dofs) += JxW[qp]*scalar_phi[l][qp];
511 }
512
513
514 for (unsigned int m = 0; m != lambda_n_dofs; m++)
515 {
516 Fe(m + vector_n_dofs + scalar_n_dofs) += JxW[qp]*scalar_value;
517 }
518 }
519 }
520
521
522
523
524
525
526
527
528 {
529
530
531
532
533 for (auto side : elem->side_index_range())
534 if (elem->neighbor_ptr(side) == nullptr)
535 {
536
537 const std::vector<std::vector<RealGradient>> & vector_phi_face = vector_fe_face->get_phi();
538
539
540
541 const std::vector<Real> & JxW_face = vector_fe_face->get_JxW();
542
543
544
545
546 const std::vector<Point> & qface_point = vector_fe_face->get_xyz();
547 const std::vector<Point> & normals = vector_fe_face->get_normals();
548
549
550 vector_fe_face->reinit(elem, side);
551
552
553
554 libmesh_assert_equal_to (vector_n_dofs, vector_phi_face.size());
555
556
557 for (unsigned int qp=0; qp<qface.n_points(); qp++)
558 {
559
560
561 const Real xf = qface_point[qp](0);
562 const Real yf = qface_point[qp](1);
563 const Real zf = qface_point[qp](2);
564
565 if (neumann)
566 {
567
573
574
575
576 const Real penalty = 1.e10;
577
578
579
580
581 for (unsigned int i = 0; i != vector_n_dofs; i++)
582 for (unsigned int j = 0; j != vector_n_dofs; j++)
583 {
584 Ke(i, j) += JxW_face[qp]*penalty*vector_phi_face[i][qp]*
585 normals[qp]*vector_phi_face[j][qp]*normals[qp];
586 }
587
588
589
590
591 for (unsigned int i = 0; i != vector_n_dofs; i++)
592 {
593 Fe(i) += JxW_face[qp]*penalty*vector_phi_face[i][qp]*normals[qp]*
594 vector_value*normals[qp];
595 }
596 }
597 else
598 {
599
600 Real scalar_value = 0;
605
606
607
608 for (unsigned int i = 0; i != vector_n_dofs; i++)
609 {
610 Fe(i) += -JxW_face[qp]*vector_phi_face[i][qp]*normals[qp]*scalar_value;
611 }
612 }
613 }
614 }
615 }
616
617
618
619
620
621
622 dof_map.constrain_element_matrix_and_vector (Ke, Fe, dof_indices);
623
624
625
626
627
630 }
631
632
633}
Real forcing(Real x, Real y)
Real scalar(Real x, Real y)
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.
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.
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.
unsigned int variable_number(std::string_view var) const
const DofMap & get_dof_map() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real