libMesh
Public Member Functions | Static Public Member Functions | Private Attributes | List of all members
Biharmonic::JR Class Reference

Biharmonic's friend class definition. More...

#include <biharmonic_jr.h>

Inheritance diagram for Biharmonic::JR:
[legend]

Public Member Functions

 JR (EquationSystems &eqSys, const std::string &name, const unsigned int number)
 Constructor. More...
 
void initialize ()
 
void residual_and_jacobian (const NumericVector< Number > &u, NumericVector< Number > *R, SparseMatrix< Number > *J, NonlinearImplicitSystem &)
 The residual and Jacobian assembly function for the Biharmonic system. More...
 
void bounds (NumericVector< Number > &XL, NumericVector< Number > &XU, NonlinearImplicitSystem &)
 Function defining the bounds of the Biharmonic system. More...
 

Static Public Member Functions

static Number InitialDensityBall (const Point &p, const Parameters &parameters, const std::string &, const std::string &)
 Static functions to be used for initialization. More...
 
static Number InitialDensityRod (const Point &p, const Parameters &parameters, const std::string &, const std::string &)
 
static Number InitialDensityStrip (const Point &p, const Parameters &parameters, const std::string &, const std::string &)
 
static Gradient InitialGradientZero (const Point &, const Parameters &, const std::string &, const std::string &)
 

Private Attributes

Biharmonic_biharmonic
 

Detailed Description

Biharmonic's friend class definition.

Definition at line 29 of file biharmonic_jr.h.

Constructor & Destructor Documentation

◆ JR()

Biharmonic::JR::JR ( EquationSystems eqSys,
const std::string &  name,
const unsigned int  number 
)

Constructor.

Definition at line 19 of file biharmonic_jr.C.

21  :
22  TransientNonlinearImplicitSystem(eqSys, name_in, number_in),
23  _biharmonic(dynamic_cast<Biharmonic &>(eqSys))
24 {
25  // Check that we can actually compute second derivatives
26 #ifndef LIBMESH_ENABLE_SECOND_DERIVATIVES
27  libmesh_error_msg("Must have second derivatives enabled");
28 #endif
29 
30 #ifdef LIBMESH_ENABLE_PERIODIC
31  // Add periodicity to the mesh
32  DofMap & dof_map = get_dof_map();
33  PeriodicBoundary xbdry(RealVectorValue(1.0, 0.0, 0.0));
34 #if LIBMESH_DIM > 1
35  PeriodicBoundary ybdry(RealVectorValue(0.0, 1.0, 0.0));
36 #endif
37 #if LIBMESH_DIM > 2
38  PeriodicBoundary zbdry(RealVectorValue(0.0, 0.0, 1.0));
39 #endif
40 
41  switch(_biharmonic._dim)
42  {
43  case 1:
44  xbdry.myboundary = 0;
45  xbdry.pairedboundary = 1;
46  dof_map.add_periodic_boundary(xbdry);
47  break;
48 #if LIBMESH_DIM > 1
49  case 2:
50  xbdry.myboundary = 3;
51  xbdry.pairedboundary = 1;
52  dof_map.add_periodic_boundary(xbdry);
53  ybdry.myboundary = 0;
54  ybdry.pairedboundary = 2;
55  dof_map.add_periodic_boundary(ybdry);
56  break;
57 #endif
58 #if LIBMESH_DIM > 2
59  case 3:
60  xbdry.myboundary = 4;
61  xbdry.pairedboundary = 2;
62  dof_map.add_periodic_boundary(xbdry);
63  ybdry.myboundary = 1;
64  ybdry.pairedboundary = 3;
65  dof_map.add_periodic_boundary(ybdry);
66  zbdry.myboundary = 0;
67  zbdry.pairedboundary = 5;
68  dof_map.add_periodic_boundary(zbdry);
69  break;
70 #endif
71  default:
72  libmesh_error_msg("Invalid dimension = " << _biharmonic._dim);
73  }
74 #endif // LIBMESH_ENABLE_PERIODIC
75 
76  // Adds the variable "u" to the system.
77  // u will be approximated using Hermite elements
78  add_variable("u", THIRD, HERMITE);
79 
80  // Give the system an object to compute the initial state.
81  attach_init_object(*this);
82 
83  // Attache the R & J calculation object
84  nonlinear_solver->residual_and_jacobian_object = this;
85 
86  // Attach the bounds calculation object
87  nonlinear_solver->bounds_object = this;
88 }

References _biharmonic, Biharmonic::_dim, libMesh::DofMap::add_periodic_boundary(), libMesh::HERMITE, libMesh::PeriodicBoundaryBase::myboundary, libMesh::PeriodicBoundaryBase::pairedboundary, and libMesh::THIRD.

Member Function Documentation

◆ bounds()

void Biharmonic::JR::bounds ( NumericVector< Number > &  XL,
NumericVector< Number > &  XU,
NonlinearImplicitSystem  
)

Function defining the bounds of the Biharmonic system.

Definition at line 488 of file biharmonic_jr.C.

491 {
492  // sys is actually ignored, since it should be the same as *this.
493 
494  // Declare a performance log. Give it a descriptive
495  // string to identify what part of the code we are
496  // logging, since there may be many PerfLogs in an
497  // application.
498  PerfLog perf_log ("Biharmonic bounds", false);
499 
500  // A reference to the DofMap object for this system. The DofMap
501  // object handles the index translation from node and element numbers
502  // to degree of freedom numbers. We will talk more about the DofMap
503  // in future examples.
504  const DofMap & dof_map = get_dof_map();
505 
506  // Get a constant reference to the Finite Element type
507  // for the first (and only) variable in the system.
508  FEType fe_type = dof_map.variable_type(0);
509 
510  // Build a Finite Element object of the specified type. Since the
511  // FEBase::build() member dynamically creates memory we will
512  // store the object as a std::unique_ptr<FEBase>. This can be thought
513  // of as a pointer that will clean up after itself.
514  std::unique_ptr<FEBase> fe (FEBase::build(_biharmonic._dim, fe_type));
515 
516  // Define data structures to contain the bound vectors contributions.
517  DenseVector<Number> XLe, XUe;
518 
519  // These vector will hold the degree of freedom indices for
520  // the element. These define where in the global system
521  // the element degrees of freedom get mapped.
522  std::vector<dof_id_type> dof_indices;
523 
524  for (const auto & elem : _biharmonic._mesh.active_local_element_ptr_range())
525  {
526  // Extract the shape function to be evaluated at the nodes
527  const std::vector<std::vector<Real>> & phi = fe->get_phi();
528 
529  // Get the degree of freedom indices for the current element.
530  // They are in 1-1 correspondence with shape functions phi
531  // and define where in the global vector this element will.
532  dof_map.dof_indices (elem, dof_indices);
533 
534  const unsigned int n_dofs =
535  cast_int<unsigned int>(dof_indices.size());
536 
537  // Resize the local bounds vectors (zeroing them out in the process).
538  XLe.resize(n_dofs);
539  XUe.resize(n_dofs);
540 
541  // Extract the element node coordinates in the reference frame
542  std::vector<Point> nodes;
543  fe->get_refspace_nodes(elem->type(), nodes);
544 
545  // Evaluate the shape functions at the nodes
546  fe->reinit(elem, &nodes);
547 
548  // Construct the bounds based on the value of the i-th phi at the nodes.
549  // Observe that this doesn't really work in general: we rely on the fact
550  // that for Hermite elements each shape function is nonzero at most at a
551  // single node.
552  // More generally the bounds must be constructed by inspecting a "mass-like"
553  // matrix (m_{ij}) of the shape functions (i) evaluated at their corresponding nodes (j).
554  // The constraints imposed on the dofs (d_i) are then are -1 \leq \sum_i d_i m_{ij} \leq 1,
555  // since \sum_i d_i m_{ij} is the value of the solution at the j-th node.
556  // Auxiliary variables will need to be introduced to reduce this to a "box" constraint.
557  // Additional complications will arise since m might be singular (as is the case for Hermite,
558  // which, however, is easily handled by inspection).
559  for (unsigned int i=0; i<n_dofs; ++i)
560  {
561  // FIXME: should be able to define INF and pass it to the solve
562  Real infinity = 1.0e20;
563  Real bound = infinity;
564  for (unsigned int j = 0; j < nodes.size(); ++j)
565  {
566  if (phi[i][j])
567  {
568  bound = 1.0/std::abs(phi[i][j]);
569  break;
570  }
571  }
572 
573  // The value of the solution at this node must be between 1.0 and -1.0.
574  // Based on the value of phi(i)(i) the nodal coordinate must be between 1.0/phi(i)(i) and its negative.
575  XLe(i) = -bound;
576  XUe(i) = bound;
577  }
578  // The element bound vectors are now built for this element.
579  // Insert them into the global vectors, potentially overwriting
580  // the same dof contributions from other elements: no matter --
581  // the bounds are always -1.0 and 1.0.
582  XL.insert(XLe, dof_indices);
583  XU.insert(XUe, dof_indices);
584  }
585 }

References std::abs(), libMesh::DofMap::dof_indices(), libMesh::NumericVector< T >::insert(), libMesh::EquationSystems::n_dofs(), libMesh::Real, libMesh::DenseVector< T >::resize(), and libMesh::DofMap::variable_type().

◆ InitialDensityBall()

Number Biharmonic::JR::InitialDensityBall ( const Point p,
const Parameters parameters,
const std::string &  ,
const std::string &   
)
static

Static functions to be used for initialization.

Definition at line 124 of file biharmonic_jr.C.

128 {
129  // Initialize with a ball in the middle, which is a segment in 1D, a disk in 2D and a ball in 3D.
130  Point center = parameters.get<Point>("center");
131  Real width = parameters.get<Real>("width");
132  Point pc = p-center;
133  Real r = pc.norm();
134  return (r < width) ? 1.0 : -0.5;
135 }

References libMesh::Parameters::get(), libMesh::EquationSystems::parameters, and libMesh::Real.

Referenced by initialize().

◆ InitialDensityRod()

Number Biharmonic::JR::InitialDensityRod ( const Point p,
const Parameters parameters,
const std::string &  ,
const std::string &   
)
static

Definition at line 140 of file biharmonic_jr.C.

144 {
145  // Initialize with a rod in the middle so that we have a z-homogeneous system to model the 2D disk.
146  Point center = parameters.get<Point>("center");
147  Real width = parameters.get<Real>("width");
148  Point pc = p-center;
149 #if LIBMESH_DIM > 2
150  pc(2) = 0;
151 #endif
152  Real r = pc.norm();
153  return (r < width) ? 1.0 : -0.5;
154 }

References libMesh::Parameters::get(), libMesh::EquationSystems::parameters, and libMesh::Real.

Referenced by initialize().

◆ InitialDensityStrip()

Number Biharmonic::JR::InitialDensityStrip ( const Point p,
const Parameters parameters,
const std::string &  ,
const std::string &   
)
static

Definition at line 160 of file biharmonic_jr.C.

164 {
165  // Initialize with a wide strip in the middle so that we have a yz-homogeneous system to model the 1D.
166  Point center = parameters.get<Point>("center");
167  Real width = parameters.get<Real>("width");
168  Real r = sqrt((p(0)-center(0))*(p(0)-center(0)));
169  return (r < width) ? 1.0 : -0.5;
170 }

References libMesh::Parameters::get(), libMesh::EquationSystems::parameters, libMesh::Real, and std::sqrt().

Referenced by initialize().

◆ InitialGradientZero()

Gradient Biharmonic::JR::InitialGradientZero ( const Point ,
const Parameters ,
const std::string &  ,
const std::string &   
)
static

Definition at line 175 of file biharmonic_jr.C.

179 {
180  return Gradient(0.0, 0.0, 0.0);
181 }

Referenced by initialize().

◆ initialize()

void Biharmonic::JR::initialize ( )

Definition at line 94 of file biharmonic_jr.C.

95 {
97  libMesh::out << ">>> Initializing Biharmonic::JR\n";
98 
102 
105 
108 
111 
112  // both states are equal
113  *(old_local_solution) = *(current_local_solution);
114 
115  if (_biharmonic._verbose)
116  libMesh::out << "<<< Initializing Biharmonic::JR\n";
117 }

References Biharmonic::BALL, InitialDensityBall(), InitialDensityRod(), InitialDensityStrip(), InitialGradientZero(), libMesh::out, libMesh::EquationSystems::parameters, libMesh::Real, Biharmonic::ROD, libMesh::Parameters::set(), and Biharmonic::STRIP.

◆ residual_and_jacobian()

void Biharmonic::JR::residual_and_jacobian ( const NumericVector< Number > &  u,
NumericVector< Number > *  R,
SparseMatrix< Number > *  J,
NonlinearImplicitSystem  
)

The residual and Jacobian assembly function for the Biharmonic system.

Definition at line 186 of file biharmonic_jr.C.

190 {
191  libmesh_ignore(u, R, J); // if we don't use --enable-second
192 
193 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
194  if (!R && !J)
195  return;
196 
197  // Declare a performance log. Give it a descriptive
198  // string to identify what part of the code we are
199  // logging, since there may be many PerfLogs in an
200  // application.
201  PerfLog perf_log ("Biharmonic Residual and Jacobian", false);
202 
203  // A reference to the DofMap object for this system. The DofMap
204  // object handles the index translation from node and element numbers
205  // to degree of freedom numbers. We will talk more about the DofMap
206  // in future examples.
207  const DofMap & dof_map = get_dof_map();
208 
209  // Get a constant reference to the Finite Element type
210  // for the first (and only) variable in the system.
211  FEType fe_type = dof_map.variable_type(0);
212 
213  // Build a Finite Element object of the specified type. Since the
214  // FEBase::build() member dynamically creates memory we will
215  // store the object as a std::unique_ptr<FEBase>. This can be thought
216  // of as a pointer that will clean up after itself.
217  std::unique_ptr<FEBase> fe (FEBase::build(_biharmonic._dim, fe_type));
218 
219  // Quadrature rule for numerical integration.
220  // With 2D triangles, the Clough quadrature rule puts a Gaussian
221  // quadrature rule on each of the 3 subelements
222  std::unique_ptr<QBase> qrule(fe_type.default_quadrature_rule(_biharmonic._dim));
223 
224  // Tell the finite element object to use our quadrature rule.
225  fe->attach_quadrature_rule (qrule.get());
226 
227  // Here we define some references to element-specific data that
228  // will be used to assemble the linear system.
229  // We begin with the element Jacobian * quadrature weight at each
230  // integration point.
231  const std::vector<Real> & JxW = fe->get_JxW();
232 
233  // The element shape functions evaluated at the quadrature points.
234  const std::vector<std::vector<Real>> & phi = fe->get_phi();
235 
236  // The element shape functions' derivatives evaluated at the quadrature points.
237  const std::vector<std::vector<RealGradient>> & dphi = fe->get_dphi();
238 
239  // The element shape functions' second derivatives evaluated at the quadrature points.
240  const std::vector<std::vector<RealTensor>> & d2phi = fe->get_d2phi();
241 
242  // For efficiency we will compute shape function laplacians n times,
243  // not n^2
244  std::vector<Real> Laplacian_phi_qp;
245 
246  // Define data structures to contain the element matrix
247  // and right-hand-side vector contribution. Following
248  // basic finite element terminology we will denote these
249  // "Je" and "Re". More detail is in example 3.
252 
253  // This vector will hold the degree of freedom indices for
254  // the element. These define where in the global system
255  // the element degrees of freedom get mapped.
256  std::vector<dof_id_type> dof_indices;
257 
258  // Old solution
259  const NumericVector<Number> & u_old = *old_local_solution;
260 
261  // Now we will loop over all the elements in the mesh. We will
262  // compute the element matrix and right-hand-side contribution. See
263  // example 3 for a discussion of the element iterators.
264  for (const auto & elem : _biharmonic._mesh.active_local_element_ptr_range())
265  {
266  // Get the degree of freedom indices for the
267  // current element. These define where in the global
268  // matrix and right-hand-side this element will
269  // contribute to.
270  dof_map.dof_indices (elem, dof_indices);
271 
272  const unsigned int n_dofs =
273  cast_int<unsigned int>(dof_indices.size());
274 
275  // Compute the element-specific data for the current
276  // element. This involves computing the location of the
277  // quadrature points (q_point) and the shape function
278  // values/derivatives (phi, dphi, d2phi) for the current element.
279  fe->reinit (elem);
280 
281  // Zero the element matrix, the right-hand side and the Laplacian matrix
282  // before summing them.
283  if (J)
284  Je.resize(n_dofs, n_dofs);
285 
286  if (R)
287  Re.resize(n_dofs);
288 
289  Laplacian_phi_qp.resize(n_dofs);
290 
291  for (unsigned int qp=0; qp<qrule->n_points(); qp++)
292  {
293  // AUXILIARY QUANTITIES:
294  // Residual and Jacobian share a few calculations:
295  // at the very least, in the case of interfacial energy only with a constant mobility,
296  // both calculations use Laplacian_phi_qp; more is shared the case of a concentration-dependent
297  // mobility and bulk potentials.
298  Number
299  u_qp = 0.0,
300  u_old_qp = 0.0,
301  Laplacian_u_qp = 0.0,
302  Laplacian_u_old_qp = 0.0;
303 
304  Gradient
305  grad_u_qp(0.0, 0.0, 0.0),
306  grad_u_old_qp(0.0, 0.0, 0.0);
307 
308  Number
309  M_qp = 1.0,
310  M_old_qp = 1.0,
311  M_prime_qp = 0.0,
312  M_prime_old_qp = 0.0;
313 
314  for (unsigned int i=0; i<n_dofs; i++)
315  {
316  Laplacian_phi_qp[i] = d2phi[i][qp](0, 0);
317  grad_u_qp(0) += u(dof_indices[i])*dphi[i][qp](0);
318  grad_u_old_qp(0) += u_old(dof_indices[i])*dphi[i][qp](0);
319 
320  if (_biharmonic._dim > 1)
321  {
322  Laplacian_phi_qp[i] += d2phi[i][qp](1, 1);
323  grad_u_qp(1) += u(dof_indices[i])*dphi[i][qp](1);
324  grad_u_old_qp(1) += u_old(dof_indices[i])*dphi[i][qp](1);
325  }
326  if (_biharmonic._dim > 2)
327  {
328  Laplacian_phi_qp[i] += d2phi[i][qp](2, 2);
329  grad_u_qp(2) += u(dof_indices[i])*dphi[i][qp](2);
330  grad_u_old_qp(2) += u_old(dof_indices[i])*dphi[i][qp](2);
331  }
332  u_qp += phi[i][qp]*u(dof_indices[i]);
333  u_old_qp += phi[i][qp]*u_old(dof_indices[i]);
334  Laplacian_u_qp += Laplacian_phi_qp[i]*u(dof_indices[i]);
335  Laplacian_u_old_qp += Laplacian_phi_qp[i]*u_old(dof_indices[i]);
336  } // for i
337 
339  {
340  M_qp = 1.0 - u_qp*u_qp;
341  M_old_qp = 1.0 - u_old_qp*u_old_qp;
342  M_prime_qp = -2.0*u_qp;
343  M_prime_old_qp = -2.0*u_old_qp;
344  }
345 
346  // ELEMENT RESIDUAL AND JACOBIAN
347  for (unsigned int i=0; i<n_dofs; i++)
348  {
349  // RESIDUAL
350  if (R)
351  {
352  Number ri = 0.0, ri_old = 0.0;
353  ri -= Laplacian_phi_qp[i]*M_qp*_biharmonic._kappa*Laplacian_u_qp;
354  ri_old -= Laplacian_phi_qp[i]*M_old_qp*_biharmonic._kappa*Laplacian_u_old_qp;
355 
357  {
358  ri -= (dphi[i][qp]*grad_u_qp)*M_prime_qp*(_biharmonic._kappa*Laplacian_u_qp);
359  ri_old -= (dphi[i][qp]*grad_u_old_qp)*M_prime_old_qp*(_biharmonic._kappa*Laplacian_u_old_qp);
360  }
361 
363  {
365  {
366  ri += Laplacian_phi_qp[i]*M_qp*_biharmonic._theta_c*(u_qp*u_qp - 1.0)*u_qp;
367  ri_old += Laplacian_phi_qp[i]*M_old_qp*_biharmonic._theta_c*(u_old_qp*u_old_qp - 1.0)*u_old_qp;
369  {
370  ri += (dphi[i][qp]*grad_u_qp)*M_prime_qp*_biharmonic._theta_c*(u_qp*u_qp - 1.0)*u_qp;
371  ri_old += (dphi[i][qp]*grad_u_old_qp)*M_prime_old_qp*_biharmonic._theta_c*(u_old_qp*u_old_qp - 1.0)*u_old_qp;
372  }
373  }// if (_biharmonic._energy == DOUBLE_WELL || _biharmonic._energy == LOG_DOUBLE_WELL)
374 
376  {
377  ri -= Laplacian_phi_qp[i]*M_qp*_biharmonic._theta_c*u_qp;
378  ri_old -= Laplacian_phi_qp[i]*M_old_qp*_biharmonic._theta_c*u_old_qp;
380  {
381  ri -= (dphi[i][qp]*grad_u_qp)*M_prime_qp*_biharmonic._theta_c*u_qp;
382  ri_old -= (dphi[i][qp]*grad_u_old_qp)*M_prime_old_qp*_biharmonic._theta_c*u_old_qp;
383  }
384  } // if (_biharmonic._energy == DOUBLE_OBSTACLE || _biharmonic._energy == LOG_DOUBLE_OBSTACLE)
385 
387  {
389  {
390  case 2:
391  break;
392  case 3:
393  break;
394  default:
395  break;
396  }// switch(_biharmonic._log_truncation)
397  }// if (_biharmonic._energy == LOG_DOUBLE_WELL || _biharmonic._energy == LOG_DOUBLE_OBSTACLE)
398  }// if (_biharmonic._cahn_hillard)
399  Re(i) += JxW[qp]*((u_qp-u_old_qp)*phi[i][qp]-_biharmonic._dt*0.5*((2.0-_biharmonic._cnWeight)*ri + _biharmonic._cnWeight*ri_old));
400  } // if (R)
401 
402  // JACOBIAN
403  if (J)
404  {
405  Number M_prime_prime_qp = 0.0;
406  if (_biharmonic._degenerate) M_prime_prime_qp = -2.0;
407  for (unsigned int j=0; j<n_dofs; j++)
408  {
409  Number ri_j = 0.0;
410  ri_j -= Laplacian_phi_qp[i]*M_qp*_biharmonic._kappa*Laplacian_phi_qp[j];
412  {
413  ri_j -=
414  Laplacian_phi_qp[i]*M_prime_qp*phi[j][qp]*_biharmonic._kappa*Laplacian_u_qp +
415  (dphi[i][qp]*dphi[j][qp])*M_prime_qp*(_biharmonic._kappa*Laplacian_u_qp) +
416  (dphi[i][qp]*grad_u_qp)*(M_prime_prime_qp*phi[j][qp])*(_biharmonic._kappa*Laplacian_u_qp) +
417  (dphi[i][qp]*grad_u_qp)*(M_prime_qp)*(_biharmonic._kappa*Laplacian_phi_qp[j]);
418  }
419 
421  {
423  {
424  ri_j +=
425  Laplacian_phi_qp[i]*M_prime_qp*phi[j][qp]*_biharmonic._theta_c*(u_qp*u_qp - 1.0)*u_qp +
426  Laplacian_phi_qp[i]*M_qp*_biharmonic._theta_c*(3.0*u_qp*u_qp - 1.0)*phi[j][qp] +
427  (dphi[i][qp]*dphi[j][qp])*M_prime_qp*_biharmonic._theta_c*(u_qp*u_qp - 1.0)*u_qp +
428  (dphi[i][qp]*grad_u_qp)*M_prime_prime_qp*_biharmonic._theta_c*(u_qp*u_qp - 1.0)*u_qp +
429  (dphi[i][qp]*grad_u_qp)*M_prime_qp*_biharmonic._theta_c*(3.0*u_qp*u_qp - 1.0)*phi[j][qp];
430  }// if (_biharmonic._energy == DOUBLE_WELL || _biharmonic._energy == LOG_DOUBLE_WELL)
431 
433  {
434  ri_j -=
435  Laplacian_phi_qp[i]*M_prime_qp*phi[j][qp]*_biharmonic._theta_c*u_qp +
436  Laplacian_phi_qp[i]*M_qp*_biharmonic._theta_c*phi[j][qp] +
437  (dphi[i][qp]*dphi[j][qp])*M_prime_qp*_biharmonic._theta_c*u_qp +
438  (dphi[i][qp]*grad_u_qp)*M_prime_prime_qp*_biharmonic._theta_c*u_qp +
439  (dphi[i][qp]*grad_u_qp)*M_prime_qp*_biharmonic._theta_c*phi[j][qp];
440  } // if (_biharmonic._energy == DOUBLE_OBSTACLE || _biharmonic._energy == LOG_DOUBLE_OBSTACLE)
441 
443  {
445  {
446  case 2:
447  break;
448  case 3:
449  break;
450  default:
451  break;
452  }// switch(_biharmonic._log_truncation)
453  }// if (_biharmonic._energy == LOG_DOUBLE_WELL || _biharmonic._energy == LOG_DOUBLE_OBSTACLE)
454  }// if (_biharmonic._cahn_hillard)
455  Je(i,j) += JxW[qp]*(phi[i][qp]*phi[j][qp] - 0.5*_biharmonic._dt*(2.0-_biharmonic._cnWeight)*ri_j);
456  } // for j
457  } // if (J)
458  } // for i
459  } // for qp
460 
461  // The element matrix and right-hand-side are now built
462  // for this element. Add them to the global matrix and
463  // right-hand-side vector. The SparseMatrix::add_matrix()
464  // and NumericVector::add_vector() members do this for us.
465  // Start logging the insertion of the local (element)
466  // matrix and vector into the global matrix and vector
467  if (R)
468  {
469  // If the mesh has hanging nodes (e.g., as a result of refinement), those need to be constrained.
470  dof_map.constrain_element_vector(Re, dof_indices);
471  R->add_vector(Re, dof_indices);
472  }
473 
474  if (J)
475  {
476  // If the mesh has hanging nodes (e.g., as a result of refinement), those need to be constrained.
477  dof_map.constrain_element_matrix(Je, dof_indices);
478  J->add_matrix(Je, dof_indices);
479  }
480  } // for el
481 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
482 }

References libMesh::SparseMatrix< T >::add_matrix(), libMesh::NumericVector< T >::add_vector(), libMesh::DofMap::constrain_element_matrix(), libMesh::DofMap::constrain_element_vector(), libMesh::FEType::default_quadrature_rule(), libMesh::DofMap::dof_indices(), Biharmonic::DOUBLE_OBSTACLE, Biharmonic::DOUBLE_WELL, libMesh::libmesh_ignore(), Biharmonic::LOG_DOUBLE_OBSTACLE, Biharmonic::LOG_DOUBLE_WELL, libMesh::EquationSystems::n_dofs(), libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), and libMesh::DofMap::variable_type().

Member Data Documentation

◆ _biharmonic

Biharmonic& Biharmonic::JR::_biharmonic
private

Definition at line 83 of file biharmonic_jr.h.

Referenced by JR().


The documentation for this class was generated from the following files:
libMesh::Number
Real Number
Definition: libmesh_common.h:195
Biharmonic::JR::InitialGradientZero
static Gradient InitialGradientZero(const Point &, const Parameters &, const std::string &, const std::string &)
Definition: biharmonic_jr.C:175
Biharmonic::STRIP
Definition: biharmonic.h:49
libMesh::DofMap::dof_indices
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:1967
Biharmonic::JR::InitialDensityRod
static Number InitialDensityRod(const Point &p, const Parameters &parameters, const std::string &, const std::string &)
Definition: biharmonic_jr.C:140
libMesh::DofMap::constrain_element_vector
void constrain_element_vector(DenseVector< Number > &rhs, std::vector< dof_id_type > &dofs, bool asymmetric_constraint_rows=true) const
Constrains the element vector.
Definition: dof_map.h:2030
Biharmonic::JR::InitialDensityStrip
static Number InitialDensityStrip(const Point &p, const Parameters &parameters, const std::string &, const std::string &)
Definition: biharmonic_jr.C:160
libMesh::HERMITE
Definition: enum_fe_family.h:54
Biharmonic::_dt
Real _dt
Definition: biharmonic.h:102
Biharmonic::DOUBLE_WELL
Definition: biharmonic.h:54
Biharmonic::BALL
Definition: biharmonic.h:51
Biharmonic::JR::InitialDensityBall
static Number InitialDensityBall(const Point &p, const Parameters &parameters, const std::string &, const std::string &)
Static functions to be used for initialization.
Definition: biharmonic_jr.C:124
Biharmonic::_degenerate
bool _degenerate
Definition: biharmonic.h:95
libMesh::TransientNonlinearImplicitSystem
TransientSystem< NonlinearImplicitSystem > TransientNonlinearImplicitSystem
Definition: transient_system.h:153
std::sqrt
MetaPhysicL::DualNumber< T, D > sqrt(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::DenseMatrix< Number >
Biharmonic::_mesh
ReplicatedMesh & _mesh
Definition: biharmonic.h:111
Biharmonic::ROD
Definition: biharmonic.h:50
libMesh::ReplicatedMesh::active_local_element_ptr_range
virtual SimpleRange< element_iterator > active_local_element_ptr_range() override
Definition: replicated_mesh.h:330
libMesh::RealVectorValue
VectorValue< Real > RealVectorValue
Useful typedefs to allow transparent switching between Real and Complex data types.
Definition: hp_coarsentest.h:46
libMesh::NumericVector::insert
virtual void insert(const T *v, const std::vector< numeric_index_type > &dof_indices)
Inserts the entries of v in *this at the locations specified by v.
Definition: numeric_vector.C:83
libMesh::DenseMatrix::resize
void resize(const unsigned int new_m, const unsigned int new_n)
Resize the matrix.
Definition: dense_matrix.h:822
libMesh::VectorValue< Number >
libMesh::NumericVector< Number >
libMesh::NumericVector::add_vector
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].
Definition: numeric_vector.C:363
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
Biharmonic::_initialWidth
Real _initialWidth
Definition: biharmonic.h:101
Biharmonic::_cnWeight
Real _cnWeight
Definition: biharmonic.h:103
libMesh::libmesh_ignore
void libmesh_ignore(const Args &...)
Definition: libmesh_common.h:526
libMesh::PerfLog
The PerfLog class allows monitoring of specific events.
Definition: perf_log.h:125
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
Biharmonic::_verbose
bool _verbose
Definition: biharmonic.h:98
libMesh::DofMap::variable_type
const FEType & variable_type(const unsigned int c) const
Definition: dof_map.h:1924
libMesh::FEType::default_quadrature_rule
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Definition: fe_type.C:31
Biharmonic::JR::_biharmonic
Biharmonic & _biharmonic
Definition: biharmonic_jr.h:83
libMesh::DofMap::add_periodic_boundary
void add_periodic_boundary(const PeriodicBoundaryBase &periodic_boundary)
Adds a copy of the specified periodic boundary to the system.
Definition: dof_map_constraints.C:4510
Biharmonic::_theta_c
Real _theta_c
Definition: biharmonic.h:93
libMesh::EquationSystems::n_dofs
std::size_t n_dofs() const
Definition: equation_systems.C:1346
Biharmonic::_initialCenter
Point _initialCenter
Definition: biharmonic.h:100
Biharmonic::_kappa
Real _kappa
Definition: biharmonic.h:93
libMesh::Parameters::set
T & set(const std::string &)
Definition: parameters.h:460
libMesh::PeriodicBoundary
The definition of a periodic boundary.
Definition: periodic_boundary.h:44
libMesh::DenseVector::resize
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:355
Biharmonic::_initialState
InitialStateEnum _initialState
Definition: biharmonic.h:99
libMesh::DofMap::constrain_element_matrix
void constrain_element_matrix(DenseMatrix< Number > &matrix, std::vector< dof_id_type > &elem_dofs, bool asymmetric_constraint_rows=true) const
Constrains the element matrix.
Definition: dof_map.h:2021
libMesh::Gradient
NumberVectorValue Gradient
Definition: exact_solution.h:58
libMesh::SparseMatrix::add_matrix
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.
libMesh::FEType
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:178
libMesh::DofMap
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:176
Biharmonic::_cahn_hillard
bool _cahn_hillard
Definition: biharmonic.h:95
libMesh::THIRD
Definition: enum_order.h:44
Biharmonic::LOG_DOUBLE_WELL
Definition: biharmonic.h:56
Biharmonic::_energy
FreeEnergyEnum _energy
Definition: biharmonic.h:96
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::Parameters::get
const T & get(const std::string &) const
Definition: parameters.h:421
libMesh::out
OStreamProxy out
libMesh::Parameters
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:59
Biharmonic::DOUBLE_OBSTACLE
Definition: biharmonic.h:55
libMesh::DenseVector< Number >
Biharmonic::_log_truncation
int _log_truncation
Definition: biharmonic.h:97
Biharmonic::LOG_DOUBLE_OBSTACLE
Definition: biharmonic.h:57
Biharmonic::_dim
unsigned int _dim
Definition: biharmonic.h:92
libMesh::EquationSystems::parameters
Parameters parameters
Data structure holding arbitrary parameters.
Definition: equation_systems.h:557