278{
279
280
281 libmesh_assert_equal_to (system_name, "Poisson");
282
283
284
285
286
287 PerfLog perf_log (
"Matrix Assembly");
288
289
291
292
294
295
297
298
299
300
301
303
304
305
306 FEType fe_type = dof_map.variable_type(0);
307
308
309
310
311
313
314
316
317
318 fe->attach_quadrature_rule (&qrule);
319
320
321
323
324
325
326
328
329
330
331 fe_face->attach_quadrature_rule (&qface);
332
333
334
335
336
337 const std::vector<Real> & JxW = fe->get_JxW();
338
339
340
341
342 const std::vector<Point> & q_point = fe->get_xyz();
343
344
345 const std::vector<std::vector<Real>> & phi = fe->get_phi();
346
347
348
349 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
350
351
352
353
354
357
358
359
360
361 std::vector<dof_id_type> dof_indices, dof_indices2;
362
363
365
366
367
368
369
370
371
372
373
374 for (
const auto & elem :
as_range(
mesh.local_elements_begin(),
375 mesh.local_elements_end()))
376 {
377
378
379
380 perf_log.push("elem init");
381
382
383
384
385
386 dof_map.dof_indices (elem, dof_indices, 0);
387 dof_map.dof_indices (elem, dof_indices2, 1);
388
389
390
391
392
393
394
395
396
397
398
399 fe->reinit (elem);
400
401
402
403
404
405
406
407 Ke.
resize (std::max(dof_indices.size(), dof_indices2.size()),
408 std::max(dof_indices.size(), dof_indices2.size()));
409
410 Fe.
resize (std::max(dof_indices.size(), dof_indices2.size()));
411
412
413
414
415 perf_log.pop("elem init");
416
417
418
419
420
421
422
423
424
425
426 perf_log.push ("Ke");
427
428 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
429 for (std::size_t i=0; i<phi.size(); i++)
430 for (std::size_t j=0; j<phi.size(); j++)
431 Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
432
433
434
435 perf_log.pop ("Ke");
436
437
438
439
440
441
442 perf_log.push ("Fe");
443
444 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
445 {
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460 const Real x = q_point[qp](0);
461#if LIBMESH_DIM > 1
462 const Real y = q_point[qp](1);
463#else
465#endif
466#if LIBMESH_DIM > 2
467 const Real z = q_point[qp](2);
468#else
470#endif
471 const Real eps = 1.e-3;
472
476
480
484
487 {
488
489
491 fxy = (0.25*
pi*
pi)*sin(.5*
pi*x);
492 }
493 else
494 {
495 fxy = - (uxx + uyy + ((
dim==2) ? 0. : uzz));
496 }
497
498
499 for (std::size_t i=0; i<phi.size(); i++)
500 Fe(i) += JxW[qp]*fxy*phi[i][qp];
501 }
502
503
504 perf_log.pop ("Fe");
505
506
507
508
509
510
511
512 {
513
514
515 LOG_SCOPE_WITH("BCs", "", perf_log);
516
517
518
519
520 for (auto side : elem->side_index_range())
521 if ((elem->neighbor_ptr(side) == nullptr) ||
522 (elem->neighbor_ptr(side)->subdomain_id() != elem->subdomain_id()))
523 {
524
525
526
527 const Real penalty = 1.e10;
528
529
530
531 const std::vector<std::vector<Real>> & phi_face = fe_face->get_phi();
532
533
534
535 const std::vector<Real> & JxW_face = fe_face->get_JxW();
536
537
538
539
540 const std::vector<Point> & qface_point = fe_face->get_xyz();
541
542
543
544 fe_face->reinit(elem, side);
545
546
547 for (unsigned int qp=0; qp<qface.n_points(); qp++)
548 {
549
550
551 const Real xf = qface_point[qp](0);
552#if LIBMESH_DIM > 1
553 const Real yf = qface_point[qp](1);
554#else
556#endif
557#if LIBMESH_DIM > 2
558 const Real zf = qface_point[qp](2);
559#else
561#endif
562
563
564
566
567
568 for (std::size_t i=0; i<phi_face.size(); i++)
569 for (std::size_t j=0; j<phi_face.size(); j++)
570 Ke(i,j) += JxW_face[qp]*penalty*phi_face[i][qp]*phi_face[j][qp];
571
572
573
574 for (std::size_t i=0; i<phi_face.size(); i++)
575 Fe(i) += JxW_face[qp]*penalty*
value*phi_face[i][qp];
576 }
577 }
578 }
579
580
581
582
583
584
585
586
587 LOG_SCOPE_WITH("matrix insertion", "", perf_log);
588
589 if (dof_indices.size())
590 {
593 }
594
595 if (dof_indices2.size())
596 {
599 }
600 }
601
602
603
604
605}
Number(* exact_solution)(const Point &p, const Parameters &, const std::string &, const std::string &)
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
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...
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].
The PerfLog class allows monitoring of specific events.
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 DofMap & get_dof_map() const
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real