libMesh
Loading...
Searching...
No Matches
Public Member Functions | Private Attributes | List of all members
LaplaceYoung Class Reference

A class which provides the residual and jacobian assembly functions for the Laplace-Young system of equations. More...

Inheritance diagram for LaplaceYoung:
[legend]

Public Member Functions

 LaplaceYoung ()
 
virtual void residual (const NumericVector< Number > &X, NumericVector< Number > &R, NonlinearImplicitSystem &S)
 Function which computes the residual.
 
virtual void jacobian (const NumericVector< Number > &X, SparseMatrix< Number > &J, NonlinearImplicitSystem &S)
 Function which computes the jacobian.
 
virtual void postcheck (const NumericVector< Number > &old_soln, NumericVector< Number > &search_direction, NumericVector< Number > &new_soln, bool &changed_search_direction, bool &changed_new_soln, NonlinearImplicitSystem &S)
 Function which performs a postcheck on the solution.
 

Private Attributes

Real _kappa
 
Real _sigma
 
Real _gamma
 

Detailed Description

A class which provides the residual and jacobian assembly functions for the Laplace-Young system of equations.

Definition at line 78 of file miscellaneous_ex3.C.

Constructor & Destructor Documentation

◆ LaplaceYoung()

LaplaceYoung::LaplaceYoung ( )
inline

Definition at line 84 of file miscellaneous_ex3.C.

84 :
85 _kappa(1.),
86 _sigma(0.2),
87 _gamma(1.0)
88 {}

Member Function Documentation

◆ jacobian()

void LaplaceYoung::jacobian ( const NumericVector< Number > &  X,
SparseMatrix< Number > &  J,
NonlinearImplicitSystem S 
)
virtual

Function which computes the jacobian.

Definition at line 456 of file miscellaneous_ex3.C.

459{
460 // Get a reference to the equation system.
461 EquationSystems & es = sys.get_equation_systems();
462
463 // Get a constant reference to the mesh object.
464 const MeshBase & mesh = es.get_mesh();
465
466 // The dimension that we are running
467 const unsigned int dim = mesh.mesh_dimension();
468
469 // Get a reference to the NonlinearImplicitSystem we are solving
470 NonlinearImplicitSystem & system =
471 es.get_system<NonlinearImplicitSystem>("Laplace-Young");
472
473 // A reference to the DofMap object for this system. The DofMap
474 // object handles the index translation from node and element numbers
475 // to degree of freedom numbers. We will talk more about the DofMap
476 // in future examples.
477 const DofMap & dof_map = system.get_dof_map();
478
479 // Get a constant reference to the Finite Element type
480 // for the first (and only) variable in the system.
481 FEType fe_type = dof_map.variable_type(0);
482
483 // Build a Finite Element object of the specified type. Since the
484 // FEBase::build() member dynamically creates memory we will
485 // store the object as a std::unique_ptr<FEBase>. This can be thought
486 // of as a pointer that will clean up after itself.
487 std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
488
489 // A 5th order Gauss quadrature rule for numerical integration.
490 QGauss qrule (dim, FIFTH);
491
492 // Tell the finite element object to use our quadrature rule.
493 fe->attach_quadrature_rule (&qrule);
494
495 // Here we define some references to cell-specific data that
496 // will be used to assemble the linear system.
497 // We begin with the element Jacobian * quadrature weight at each
498 // integration point.
499 const std::vector<Real> & JxW = fe->get_JxW();
500
501 // The element shape functions evaluated at the quadrature points.
502 const std::vector<std::vector<Real>> & phi = fe->get_phi();
503
504 // The element shape function gradients evaluated at the quadrature
505 // points.
506 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
507
508 // Define data structures to contain the Jacobian element matrix.
509 // Following basic finite element terminology we will denote these
510 // "Ke". More detail is in example 3.
512
513 // This vector will hold the degree of freedom indices for
514 // the element. These define where in the global system
515 // the element degrees of freedom get mapped.
516 std::vector<dof_id_type> dof_indices;
517
518 // Now we will loop over all the active elements in the mesh which
519 // are local to this processor.
520 // We will compute the element Jacobian contribution.
521 for (const auto & elem : mesh.active_local_element_ptr_range())
522 {
523 // Get the degree of freedom indices for the
524 // current element. These define where in the global
525 // matrix and right-hand-side this element will
526 // contribute to.
527 dof_map.dof_indices (elem, dof_indices);
528
529 // Compute the element-specific data for the current
530 // element. This involves computing the location of the
531 // quadrature points (q_point) and the shape functions
532 // (phi, dphi) for the current element.
533 fe->reinit (elem);
534
535 // Zero the element Jacobian before
536 // summing them. We use the resize member here because
537 // the number of degrees of freedom might have changed from
538 // the last element. Note that this will be the case if the
539 // element type is different (i.e. the last element was a
540 // triangle, now we are on a quadrilateral).
541 const unsigned int n_dofs =
542 cast_int<unsigned int>(dof_indices.size());
543 Ke.resize (n_dofs, n_dofs);
544
545 // Now we will build the element Jacobian. This involves
546 // a double loop to integrate the test functions (i) against
547 // the trial functions (j). Note that the Jacobian depends
548 // on the current solution x, which we access using the soln
549 // vector.
550 //
551 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
552 {
553 Gradient grad_u;
554
555 for (unsigned int i=0; i<n_dofs; i++)
556 grad_u += dphi[i][qp]*soln(dof_indices[i]);
557
558 const Number
559 sa = 1. + grad_u*grad_u,
560 K = 1. / std::sqrt(sa),
561 dK = -K / sa;
562
563 for (unsigned int i=0; i<n_dofs; i++)
564 for (unsigned int j=0; j<n_dofs; j++)
565 Ke(i,j) += JxW[qp]*(
566 K * (dphi[i][qp]*dphi[j][qp]) +
567 dK * (grad_u*dphi[j][qp]) * (grad_u*dphi[i][qp]) +
568 _kappa * phi[i][qp] * phi[j][qp]
569 );
570 }
571
572 dof_map.constrain_element_matrix (Ke, dof_indices);
573
574 // Add the element matrix to the system Jacobian.
575 jacobian.add_matrix (Ke, dof_indices);
576 }
577
578 // That's it.
579}
unsigned int dim
virtual void jacobian(const NumericVector< Number > &X, SparseMatrix< Number > &J, NonlinearImplicitSystem &S)
Function which computes the jacobian.
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().
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
This is the EquationSystems class.
const MeshBase & get_mesh() const
const T_sys & get_system(std::string_view name) const
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...
Definition fe_type.h:197
This is the MeshBase class.
Definition mesh_base.h:81
unsigned int mesh_dimension() const
Definition mesh_base.C:430
Manages consistently variables, degrees of freedom, coefficient vectors, matrices and non-linear solv...
This class implements specific orders of Gauss quadrature.
const DofMap & get_dof_map() const
Definition system.h:2417
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
MeshBase & mesh

References _kappa, libMesh::FEGenericBase< OutputType >::build(), dim, libMesh::FIFTH, libMesh::System::get_dof_map(), libMesh::System::get_equation_systems(), libMesh::EquationSystems::get_mesh(), libMesh::EquationSystems::get_system(), jacobian(), mesh, libMesh::MeshBase::mesh_dimension(), libMesh::QBase::n_points(), and libMesh::DenseMatrix< T >::resize().

Referenced by jacobian().

◆ postcheck()

void LaplaceYoung::postcheck ( const NumericVector< Number > &  old_soln,
NumericVector< Number > &  search_direction,
NumericVector< Number > &  new_soln,
bool &  changed_search_direction,
bool &  changed_new_soln,
NonlinearImplicitSystem S 
)
virtual

Function which performs a postcheck on the solution.

In this example, we take a "damped" Newton step defined by:

u_new = u_old + gamma*delta_u

where delta_u is the search direction, and 0 < gamma <= 1 is a damping parameter. gamma=1 corresponds to a full Newton step.

This is really for demonstration purposes only, as it just degrades the rate of nonlinear convergence in this particular example.

Definition at line 584 of file miscellaneous_ex3.C.

590{
591 // Back up along the search direction by some amount. Since Newton
592 // already works well for this problem, the only affect of this is
593 // to degrade the rate of convergence.
594 //
595 // The minus sign is due to the sign of the "search_direction"
596 // vector which comes in from the Newton solve. The RHS of the
597 // nonlinear system, i.e. the residual, is generally not multiplied
598 // by -1, so the solution vector, i.e. the search_direction, has a
599 // factor -1.
600 if (_gamma != 1.0)
601 {
602 new_soln = old_soln;
603 new_soln.add(-_gamma, search_direction);
604 changed_new_soln = true;
605 }
606 else
607 changed_new_soln = false;
608}
virtual void add(const numeric_index_type i, const T value)=0
Adds value to the vector entry specified by i.

References _gamma, and libMesh::NumericVector< T >::add().

◆ residual()

void LaplaceYoung::residual ( const NumericVector< Number > &  X,
NumericVector< Number > &  R,
NonlinearImplicitSystem S 
)
virtual

Function which computes the residual.

Definition at line 286 of file miscellaneous_ex3.C.

289{
290 EquationSystems & es = sys.get_equation_systems();
291
292 // Get a constant reference to the mesh object.
293 const MeshBase & mesh = es.get_mesh();
294
295 // The dimension that we are running
296 const unsigned int dim = mesh.mesh_dimension();
297 libmesh_assert_equal_to (dim, 2);
298
299 // Get a reference to the NonlinearImplicitSystem we are solving
300 NonlinearImplicitSystem & system =
301 es.get_system<NonlinearImplicitSystem>("Laplace-Young");
302
303 // A reference to the DofMap object for this system. The DofMap
304 // object handles the index translation from node and element numbers
305 // to degree of freedom numbers. We will talk more about the DofMap
306 // in future examples.
307 const DofMap & dof_map = system.get_dof_map();
308
309 // Get a constant reference to the Finite Element type
310 // for the first (and only) variable in the system.
311 FEType fe_type = dof_map.variable_type(0);
312
313 // Build a Finite Element object of the specified type. Since the
314 // FEBase::build() member dynamically creates memory we will
315 // store the object as a std::unique_ptr<FEBase>. This can be thought
316 // of as a pointer that will clean up after itself.
317 std::unique_ptr<FEBase> fe (FEBase::build(dim, fe_type));
318
319 // A 5th order Gauss quadrature rule for numerical integration.
320 QGauss qrule (dim, FIFTH);
321
322 // Tell the finite element object to use our quadrature rule.
323 fe->attach_quadrature_rule (&qrule);
324
325 // Declare a special finite element object for
326 // boundary integration.
327 std::unique_ptr<FEBase> fe_face (FEBase::build(dim, fe_type));
328
329 // Boundary integration requires one quadrature rule,
330 // with dimensionality one less than the dimensionality
331 // of the element.
332 QGauss qface(dim-1, FIFTH);
333
334 // Tell the finite element object to use our
335 // quadrature rule.
336 fe_face->attach_quadrature_rule (&qface);
337
338 // Here we define some references to cell-specific data that
339 // will be used to assemble the linear system.
340 // We begin with the element Jacobian * quadrature weight at each
341 // integration point.
342 const std::vector<Real> & JxW = fe->get_JxW();
343
344 // The element shape functions evaluated at the quadrature points.
345 const std::vector<std::vector<Real>> & phi = fe->get_phi();
346
347 // The element shape function gradients evaluated at the quadrature
348 // points.
349 const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
350
351 // Define data structures to contain the residual contributions
353
354 // This vector will hold the degree of freedom indices for
355 // the element. These define where in the global system
356 // the element degrees of freedom get mapped.
357 std::vector<dof_id_type> dof_indices;
358
359 // Now we will loop over all the active elements in the mesh which
360 // are local to this processor.
361 // We will compute the element residual.
362 residual.zero();
363
364 for (const auto & elem : mesh.active_local_element_ptr_range())
365 {
366 // Get the degree of freedom indices for the
367 // current element. These define where in the global
368 // matrix and right-hand-side this element will
369 // contribute to.
370 dof_map.dof_indices (elem, dof_indices);
371
372 // Compute the element-specific data for the current
373 // element. This involves computing the location of the
374 // quadrature points (q_point) and the shape functions
375 // (phi, dphi) for the current element.
376 fe->reinit (elem);
377
378 // We use the resize member here because
379 // the number of degrees of freedom might have changed from
380 // the last element. Note that this will be the case if the
381 // element type is different (i.e. the last element was a
382 // triangle, now we are on a quadrilateral).
383 const unsigned int n_dofs =
384 cast_int<unsigned int>(dof_indices.size());
385 Re.resize (n_dofs);
386
387 // Now we will build the residual. This involves
388 // the construction of the matrix K and multiplication of it
389 // with the current solution x. We rearrange this into two loops:
390 // In the first, we calculate only the contribution of
391 // K_ij*x_j which is independent of the row i. In the second loops,
392 // we multiply with the row-dependent part and add it to the element
393 // residual.
394
395 for (unsigned int qp=0; qp<qrule.n_points(); qp++)
396 {
397 Number u = 0;
398 Gradient grad_u;
399
400 for (unsigned int j=0; j<n_dofs; j++)
401 {
402 u += phi[j][qp]*soln(dof_indices[j]);
403 grad_u += dphi[j][qp]*soln(dof_indices[j]);
404 }
405
406 const Number K = 1./std::sqrt(1. + grad_u*grad_u);
407
408 for (unsigned int i=0; i<n_dofs; i++)
409 Re(i) += JxW[qp]*(
410 K*(dphi[i][qp]*grad_u) +
411 _kappa*phi[i][qp]*u
412 );
413 }
414
415 // At this point the interior element integration has
416 // been completed. However, we have not yet addressed
417 // boundary conditions.
418
419 // The following loops over the sides of the element.
420 // If the element has no neighbor on a side then that
421 // side MUST live on a boundary of the domain.
422 for (auto side : elem->side_index_range())
423 if (elem->neighbor_ptr(side) == nullptr)
424 {
425 // The value of the shape functions at the quadrature
426 // points.
427 const std::vector<std::vector<Real>> & phi_face = fe_face->get_phi();
428
429 // The Jacobian * Quadrature Weight at the quadrature
430 // points on the face.
431 const std::vector<Real> & JxW_face = fe_face->get_JxW();
432
433 // Compute the shape function values on the element face.
434 fe_face->reinit(elem, side);
435
436 // Loop over the face quadrature points for integration.
437 for (unsigned int qp=0; qp<qface.n_points(); qp++)
438 {
439 // This is the right-hand-side contribution (f),
440 // which has to be subtracted from the current residual
441 for (unsigned int i=0; i<n_dofs; i++)
442 Re(i) -= JxW_face[qp]*_sigma*phi_face[i][qp];
443 }
444 }
445
446 dof_map.constrain_element_vector (Re, dof_indices);
447 residual.add_vector (Re, dof_indices);
448 }
449
450 // That's it.
451}
virtual void residual(const NumericVector< Number > &X, NumericVector< Number > &R, NonlinearImplicitSystem &S)
Function which computes the residual.
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
virtual void zero() override final
Set every element in the vector to 0.

References _kappa, _sigma, libMesh::FEGenericBase< OutputType >::build(), dim, libMesh::FIFTH, libMesh::System::get_dof_map(), libMesh::System::get_equation_systems(), libMesh::EquationSystems::get_mesh(), libMesh::EquationSystems::get_system(), mesh, libMesh::MeshBase::mesh_dimension(), libMesh::QBase::n_points(), residual(), libMesh::DenseVector< T >::resize(), and libMesh::DenseVector< T >::zero().

Referenced by residual().

Member Data Documentation

◆ _gamma

Real LaplaceYoung::_gamma
private

Definition at line 129 of file miscellaneous_ex3.C.

Referenced by postcheck().

◆ _kappa

Real LaplaceYoung::_kappa
private

Definition at line 125 of file miscellaneous_ex3.C.

Referenced by jacobian(), and residual().

◆ _sigma

Real LaplaceYoung::_sigma
private

Definition at line 126 of file miscellaneous_ex3.C.

Referenced by residual().


The documentation for this class was generated from the following file: