constrained_volume_elements.h
Go to the documentation of this file.
1// LIC// ====================================================================
2// LIC// This file forms part of oomph-lib, the object-oriented,
3// LIC// multi-physics finite-element library, available
4// LIC// at http://www.oomph-lib.org.
5// LIC//
6// LIC// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
26// Header file for elements that allow the imposition of a "constant volume"
27// constraint in free surface problems.
28
29// Include guards, to prevent multiple includes
30#ifndef CONSTRAINED_FLUID_VOLUME_ELEMENTS_HEADER
31#define CONSTRAINED_FLUID_VOLUME_ELEMENTS_HEADER
32
33// Config header generated by autoconfig
34#ifdef HAVE_CONFIG_H
35#include <oomph-lib-config.h>
36#endif
37
38// OOMPH-LIB headers
39#include "../generic/Qelements.h"
40#include "../generic/spines.h"
41#include "../axisym_navier_stokes/axisym_navier_stokes_elements.h"
42
43//-------------------------------------------
44// NOTE: This is still work
45// in progress. Need to create versions
46// for axisymmetric and cartesian 3D
47// bulk equations, as well as spine
48// version for all of these (resulting
49// in six elements in total). These
50// will gradually replace the very hacky
51// fix_*.h files that currently live in
52// various demo driver codes.
53//-------------------------------------------
54
55namespace oomph
56{
57 //==========================================================================
58 /// A class that is used to implement the constraint that the fluid volume
59 /// in a region bounded by associated FaceElements (attached, e.g., to the
60 /// mesh boundaries that enclose a bubble) must take a specific value.
61 /// This GeneralisedElement is used only to store the desired volume and
62 /// a pointer to the (usually pressure) freedom that must be traded
63 /// for the volume constraint.
64 //=========================================================================
66 {
67 private:
68 /// Pointer to the desired value of the volume
70
71 /// The Data that contains the traded pressure is stored
72 /// as external or internal Data for the element. What is its index
73 /// in these containers?
75
76 /// The Data that contains the traded pressure is stored
77 /// as external or internal Data for the element. Which one?
79
80 /// Index of the value in traded pressure data that corresponds to the
81 /// traded pressure
83
84 /// The local eqn number for the traded pressure
85 inline int ptraded_local_eqn()
86 {
88 {
89 return this->internal_local_eqn(
90 External_or_internal_data_index_of_traded_pressure,
92 }
93 else
94 {
95 return this->external_local_eqn(
96 External_or_internal_data_index_of_traded_pressure,
98 }
99 }
100
101
102 /// Fill in the residuals for the volume constraint
104 Vector<double>& residuals);
105
106 public:
107 /// Constructor: Pass pointer to target volume. "Pressure" value that
108 /// "traded" for the volume contraint is created internally (as a Data
109 /// item with a single pressure value)
110 VolumeConstraintElement(double* prescribed_volume_pt);
111
112 /// Constructor: Pass pointer to target volume, pointer to Data
113 /// item whose value specified by index_of_traded_pressure represents
114 /// the "Pressure" value that "traded" for the volume contraint.
115 /// The Data is stored as external Data for this element.
116 VolumeConstraintElement(double* prescribed_volume_pt,
118 const unsigned& index_of_traded_pressure);
119
120 /// Empty destructor
122
123 /// Access to Data that contains the traded pressure
125 {
127 {
128 return internal_data_pt(
130 }
131 else
132 {
133 return external_data_pt(
135 }
136 }
137
138 /// Return the traded pressure value
139 inline double p_traded()
140 {
142 }
143
144 /// Return the index of Data object at which the traded pressure is stored
145 inline unsigned index_of_traded_pressure()
146 {
148 }
149
150
151 /// Fill in the residuals for the volume constraint
153 {
155 residuals);
156 }
157
158 /// Fill in the residuals and jacobian for the volume constraint
160 DenseMatrix<double>& jacobian)
161 {
162 // No contribution to jacobian; see comment in that function
164 residuals);
165 }
166
167 /// Fill in the residuals, jacobian and mass matrix for the volume
168 /// constraint.
170 Vector<double>& residuals,
171 DenseMatrix<double>& jacobian,
172 DenseMatrix<double>& mass_matrix)
173 {
174 // No contribution to jacobian or mass matrix; see comment in that
175 // function
177 residuals);
178 }
179 };
180
181 /// //////////////////////////////////////////////////////////////////////
182 /// //////////////////////////////////////////////////////////////////////
183 /// //////////////////////////////////////////////////////////////////////
184
185
186 //=======================================================================
187 /// Base class for interface elements that allow the application of
188 /// a volume constraint on the region bounded by these elements. The
189 /// elements must be used together with the associated
190 /// VolumeConstraintElement which stores the value of the
191 /// target volume. Common functionality is provided in this base
192 /// for storing the external "pressure" value
193 /// that is traded for the volume constraint.
194 //=======================================================================
196 {
197 protected:
198 /// The Data that contains the traded pressure is usually stored
199 /// as external Data for this element, but may also be nodal Data
200 /// Which Data item is it?
202
203 /// Index of the value in traded pressure data that corresponds to the
204 /// traded pressure
206
207 /// Boolean to indicate whether the traded pressure is
208 /// stored externally or at a node (this can happen in Taylor-Hood
209 /// elements)
211
212 /// The local eqn number for the traded pressure
213 inline int ptraded_local_eqn()
214 {
215 // Return the appropriate nodal value if required
217 {
218 return this->nodal_local_eqn(Data_number_of_traded_pressure,
220 }
221 else
222 {
223 return this->external_local_eqn(Data_number_of_traded_pressure,
225 }
226 }
227
228 /// Helper function to fill in contributions to residuals
229 /// (remember that part of the residual is added by the the
230 /// associated VolumeConstraintElement). This is dimension/geometry
231 /// specific and must be implemented in derived classes for
232 /// 1D line, 2D surface and axisymmetric fluid boundaries
234 Vector<double>& residuals) = 0;
235
236 public:
237 /// Constructor initialise the boolean flag
238 /// We expect the traded pressure data to be stored externally
240
241 /// Empty Destructor
243
244 /// Fill in contribution to residuals and Jacobian
246 {
247 // Call the generic routine
249 }
250
251 /// Set the "master" volume constraint element
252 /// The setup here is a bit more complicated than one might expect because
253 /// if an internal pressure on a boundary
254 /// is hijacked in TaylorHood elements then
255 /// that the "traded" value may already be stored as nodal data
256 /// in this element. This causes no problems apart from when running
257 /// with PARANOID in which case the resulting
258 /// repeated local equation numbers are spotted and an error is thrown.
259 /// The check is a finite amount of work and so can be avoided if
260 /// the boolean flag check_nodal_data is set to false.
262 VolumeConstraintElement* const& vol_constraint_el_pt,
263 const bool& check_nodal_data = true)
264 {
265 // In order to buffer the case of nodal data, we (tediously) check that
266 // the traded pressure is not already nodal data of this element
267 if (check_nodal_data)
268 {
269 // Get memory address of the equation indexed by the
270 // traded pressure datum
271 long* global_eqn_number =
272 vol_constraint_el_pt->p_traded_data_pt()->eqn_number_pt(
273 vol_constraint_el_pt->index_of_traded_pressure());
274
275 // Put in a check if the datum already corresponds to any other
276 //(nodal) data in the element by checking the memory addresses of
277 // their global equation numbers
278 const unsigned n_node = this->nnode();
279 for (unsigned n = 0; n < n_node; n++)
280 {
281 // Cache the node pointer
282 Node* const nod_pt = this->node_pt(n);
283 // Find all nodal data values
284 unsigned n_value = nod_pt->nvalue();
285 // If we already have the data, set the
286 // lookup schemes accordingly and return from the function
287 for (unsigned i = 0; i < n_value; i++)
288 {
289 if (nod_pt->eqn_number_pt(i) == global_eqn_number)
290 {
294 // Finished so exit the function
295 return;
296 }
297 }
298 }
299 }
300
301 // Should only get here if the data is not nodal
302
303 // Add "traded" pressure data as external data to this element
305 this->add_external_data(vol_constraint_el_pt->p_traded_data_pt());
306
307 // Which value corresponds to the traded pressure
309 vol_constraint_el_pt->index_of_traded_pressure();
310 }
311 };
312
313 /// //////////////////////////////////////////////////////////////////////
314 /// //////////////////////////////////////////////////////////////////////
315 /// //////////////////////////////////////////////////////////////////////
316
317
318 //=======================================================================
319 /// One-dimensional interface elements that allow the application of
320 /// a volume constraint on the region bounded by these elements.
321 /// The volume is computed by integrating x.n around the boundary of
322 /// the domain and then dividing by two.
323 /// The sign is chosen so that the volume will be positive
324 /// when the elements surround a fluid domain.
325 ///
326 /// These elements must be used together with the associated
327 /// VolumeConstraintElement, which stores the value of the
328 /// target volume.
329 //=======================================================================
332 {
333 protected:
334 /// Helper function to fill in contributions to residuals
335 /// (remember that part of the residual is added by the
336 /// the associated VolumeConstraintElement). This is specific for
337 /// 1D line elements that bound 2D cartesian fluid elements.
339 Vector<double>& residuals);
340
341 public:
342 /// Empty Contructor
344
345 /// Empty Destructor
347
348 /// Return this element's contribution to the total volume enclosed
350 };
351
352
353 /// ///////////////////////////////////////////////////////////////////
354 /// ///////////////////////////////////////////////////////////////////
355 /// ///////////////////////////////////////////////////////////////////
356
357
358 //=======================================================================
359 /// The one-dimensional interface elements that allow imposition of a
360 /// volume constraint specialised for the case when the nodal positions of
361 /// the bulk elements are treated as solid degrees of freedom.
362 /// To enforce that a fluid volume has a
363 /// certain volume, attach these elements to all faces of the
364 /// (2D cartesian) bulk fluid elements (of type ELEMENT) that bound that
365 /// region and then specify the "pressure" value that is traded for the
366 /// constraint.
367 //=======================================================================
368 template<class ELEMENT>
371 public virtual FaceGeometry<ELEMENT>
372 {
373 public:
374 /// Contructor: Specify bulk element and index of face to which
375 /// this face element is to be attached
377 const int& face_index)
379 {
380 // Attach the geometrical information to the element, by
381 // making the face element from the bulk element
382 element_pt->build_face_element(face_index, this);
383 }
384
385 /// Fill in contribution to residuals and Jacobian. This is specific
386 /// to solid-based elements in which derivatives w.r.t. to nodal
387 /// positions are evaluated by finite differencing
389 DenseMatrix<double>& jacobian)
390 {
391 // Call the generic routine
393
394 // Shape derivatives
395 // Call the generic finite difference routine for the solid variables
396 this->fill_in_jacobian_from_solid_position_by_fd(jacobian);
397 }
398
399 /// The "global" intrinsic coordinate of the element when
400 /// viewed as part of a geometric object should be given by
401 /// the FaceElement representation, by default
402 double zeta_nodal(const unsigned& n,
403 const unsigned& k,
404 const unsigned& i) const
405 {
406 return FaceElement::zeta_nodal(n, k, i);
407 }
408 };
409
410 //=======================================================================
411 /// The one-dimensional interface elements that allow imposition of a
412 /// volume constraint specialised for the case when the nodal positions of
413 /// the bulk elements are adjusted using Spines.
414 /// To enforce that a fluid volume has a
415 /// certain volume, attach these elements to all faces of the
416 /// (2D cartesian) bulk fluid elements (of type ELEMENT) that bound that
417 /// region and then specify the "pressure" value that is traded for the
418 /// constraint.
419 //=======================================================================
420 template<class ELEMENT>
423 public virtual SpineElement<FaceGeometry<ELEMENT>>
424 {
425 public:
426 /// Contructor: Specify bulk element and index of face to which
427 /// this face element is to be attached.
429 const int& face_index)
430 : SpineElement<FaceGeometry<ELEMENT>>(),
432 {
433 // Attach the geometrical information to the element, by
434 // making the face element from the bulk element
435 element_pt->build_face_element(face_index, this);
436 }
437
438
439 /// Fill in contribution to residuals and Jacobian. This is specific
440 /// to spine based elements in which the shape derivatives are evaluated
441 /// using geometric data
443 DenseMatrix<double>& jacobian)
444 {
445 // Call the generic routine
447
448 // Call the generic routine to evaluate shape derivatives
450 }
451
452 /// The "global" intrinsic coordinate of the element when
453 /// viewed as part of a geometric object should be given by
454 /// the FaceElement representation, by default
455 double zeta_nodal(const unsigned& n,
456 const unsigned& k,
457 const unsigned& i) const
458 {
459 return FaceElement::zeta_nodal(n, k, i);
460 }
461 };
462
463 /// //////////////////////////////////////////////////////////////////////
464 /// //////////////////////////////////////////////////////////////////////
465 /// //////////////////////////////////////////////////////////////////////
466
467
468 //=======================================================================
469 /// Axisymmetric (one-dimensional) interface elements that
470 /// allow the application of
471 /// a volume constraint on the region bounded by these elements.
472 /// The volume is computed by integrating x.n around the boundary of
473 /// the domain and then dividing by three.
474 /// The sign is chosen so that the volume will be positive
475 /// when the elements surround a fluid domain.
476 ///
477 /// These elements must be used together with the associated
478 /// VolumeConstraintElement, which stores the value of the
479 /// target volume.
480 //=======================================================================
483 {
484 protected:
485 /// Helper function to fill in contributions to residuals
486 /// (remember that part of the residual is added by the
487 /// the associated VolumeConstraintElement). This is specific for
488 /// 1D line elements that bound 2D cartesian fluid elements.
490 Vector<double>& residuals);
491
492 public:
493 /// Empty Contructor
496 {
497 }
498
499 /// Empty Destructor
501
502 /// Return this element's contribution to the total volume enclosed
504
505 /// Return this element's contribution to the volume flux over
506 /// the boundary
508 {
509 // Initialise
510 double vol = 0.0;
511
512 // Find out how many nodes there are
513 const unsigned n_node = this->nnode();
514
515 // Set up memeory for the shape functions
516 Shape psif(n_node);
517 DShape dpsifds(n_node, 1);
518
519 // Set the value of n_intpt
520 const unsigned n_intpt = this->integral_pt()->nweight();
521
522 // Storage for the local cooridinate
523 Vector<double> s(1);
524
525 // Loop over the integration points
526 for (unsigned ipt = 0; ipt < n_intpt; ipt++)
527 {
528 // Get the local coordinate at the integration point
529 s[0] = this->integral_pt()->knot(ipt, 0);
530
531 // Get the integral weight
532 double W = this->integral_pt()->weight(ipt);
533
534 // Call the derivatives of the shape function at the knot point
535 this->dshape_local_at_knot(ipt, psif, dpsifds);
536
537 // Get position, tangent vector and velocity vector (r and z
538 // components only)
539 Vector<double> interpolated_u(2, 0.0);
540 Vector<double> interpolated_t1(2, 0.0);
542 for (unsigned l = 0; l < n_node; l++)
543 {
544 // Loop over directional components
545 for (unsigned i = 0; i < 2; i++)
546 {
547 interpolated_x[i] += this->nodal_position(l, i) * psif(l);
548 interpolated_u[i] +=
549 this->node_pt(l)->value(
552 ->u_index_axi_nst(i)) *
553 psif(l);
554 interpolated_t1[i] += this->nodal_position(l, i) * dpsifds(l, 0);
555 }
556 }
557
558 // Calculate the length of the tangent Vector
559 double tlength = interpolated_t1[0] * interpolated_t1[0] +
560 interpolated_t1[1] * interpolated_t1[1];
561
562 // Set the Jacobian of the line element
563 double J = sqrt(tlength) * interpolated_x[0];
564
565 // Now calculate the normal Vector
566 Vector<double> interpolated_n(2);
567 this->outer_unit_normal(ipt, interpolated_n);
568
569 // Assemble dot product
570 double dot = 0.0;
571 for (unsigned k = 0; k < 2; k++)
572 {
573 dot += interpolated_u[k] * interpolated_n[k];
574 }
575
576 // Add to volume with sign chosen so that the volume is
577 // positive when the elements bound the fluid
578 vol += dot * W * J;
579 }
580
581 return vol;
582 }
583 };
584
585 /// ///////////////////////////////////////////////////////////////////
586 /// ///////////////////////////////////////////////////////////////////
587 /// ///////////////////////////////////////////////////////////////////
588
589
590 //=======================================================================
591 /// The axisymmetric (one-dimensional) interface elements that allow
592 /// imposition of a
593 /// volume constraint specialised for the case when the nodal positions of
594 /// the bulk elements are treated as solid degrees of freedom.
595 /// To enforce that a fluid volume has a
596 /// certain volume, attach these elements to all faces of the
597 /// (2D axisymmetric) bulk fluid elements (of type ELEMENT)
598 /// that bound that region
599 /// and then specify the "pressure" value that is traded for the constraint.
600 //=======================================================================
601 template<class ELEMENT>
604 public virtual FaceGeometry<ELEMENT>
605 {
606 public:
607 /// Contructor: Specify bulk element and index of face to which
608 /// this face element is to be attached
610 FiniteElement* const& element_pt, const int& face_index)
612 {
613 // Attach the geometrical information to the element, by
614 // making the face element from the bulk element
615 element_pt->build_face_element(face_index, this);
616 }
617
618 /// Fill in contribution to residuals and Jacobian. This is specific
619 /// to solid-based elements in which derivatives w.r.t. to nodal
620 /// positions are evaluated by finite differencing
622 DenseMatrix<double>& jacobian)
623 {
624 // Call the generic routine
626
627 // Shape derivatives
628 // Call the generic finite difference routine for the solid variables
629 this->fill_in_jacobian_from_solid_position_by_fd(jacobian);
630 }
631
632 /// The "global" intrinsic coordinate of the element when
633 /// viewed as part of a geometric object should be given by
634 /// the FaceElement representation, by default
635 double zeta_nodal(const unsigned& n,
636 const unsigned& k,
637 const unsigned& i) const
638 {
639 return FaceElement::zeta_nodal(n, k, i);
640 }
641 };
642
643 //=======================================================================
644 /// The axisymmetric (one-dimensional) interface elements that
645 /// allow imposition of a
646 /// volume constraint specialised for the case when the nodal positions of
647 /// the bulk elements are adjusted using Spines.
648 /// To enforce that a fluid volume has a
649 /// certain volume, attach these elements to all faces of the
650 /// (2D axisymmetric) bulk fluid elements (of type ELEMENT) that bound
651 /// that region
652 /// and then specify the "pressure" value that is traded for the constraint.
653 //=======================================================================
654 template<class ELEMENT>
657 public virtual SpineElement<FaceGeometry<ELEMENT>>
658 {
659 public:
660 /// Contructor: Specify bulk element and index of face to which
661 /// this face element is to be attached.
663 FiniteElement* const& element_pt, const int& face_index)
664 : SpineElement<FaceGeometry<ELEMENT>>(),
666 {
667 // Attach the geometrical information to the element, by
668 // making the face element from the bulk element
669 element_pt->build_face_element(face_index, this);
670 }
671
672
673 /// Fill in contribution to residuals and Jacobian. This is specific
674 /// to spine based elements in which the shape derivatives are evaluated
675 /// using geometric data
677 DenseMatrix<double>& jacobian)
678 {
679 // Call the generic routine
681
682 // Call the generic routine to evaluate shape derivatives
684 }
685
686 /// The "global" intrinsic coordinate of the element when
687 /// viewed as part of a geometric object should be given by
688 /// the FaceElement representation, by default
689 double zeta_nodal(const unsigned& n,
690 const unsigned& k,
691 const unsigned& i) const
692 {
693 return FaceElement::zeta_nodal(n, k, i);
694 }
695 };
696
697
698 /// //////////////////////////////////////////////////////////////////////
699 /// //////////////////////////////////////////////////////////////////////
700 /// //////////////////////////////////////////////////////////////////////
701
702
703 //=======================================================================
704 /// Two-dimensional interface elements that allow the application of
705 /// a volume constraint on the region bounded by these elements.
706 /// The volume is computed by integrating x.n around the boundary of
707 /// the domain and then dividing by three.
708 /// The sign is chosen so that the volume will be positive
709 /// when the elements surround a fluid domain.
710 ///
711 /// These elements must be used together with the associated
712 /// VolumeConstraintElement, which stores the value of the
713 /// target volume.
714 //=======================================================================
717 {
718 protected:
719 /// Helper function to fill in contributions to residuals
720 /// (remember that part of the residual is added by the
721 /// the associated VolumeConstraintElement). This is specific for
722 /// 2D surface elements that bound 3D cartesian fluid elements.
724 Vector<double>& residuals);
725
726 public:
727 /// Empty Contructor
729 {
730 }
731
732 /// Empty Desctructor
734 };
735
736
737 /// ///////////////////////////////////////////////////////////////////
738 /// ///////////////////////////////////////////////////////////////////
739 /// ///////////////////////////////////////////////////////////////////
740
741
742 //=======================================================================
743 /// The Two-dimensional interface elements that allow the application of
744 /// a volume constraint specialised for the case when the nodal positions
745 /// of the bulk elements are treated as solid degrees of freedom.
746 /// To enforce that a fluid volume has a
747 /// certain volume, attach these elements to all faces of the
748 /// (3D Cartesian) bulk fluid elements (of type ELEMENT) that bound that
749 /// region and then specify the "pressure" value that is traded for the
750 /// constraint.
751 //=======================================================================
752 template<class ELEMENT>
755 public virtual FaceGeometry<ELEMENT>
756 {
757 public:
758 /// Contructor: Specify bulk element and index of face to which
759 /// this face element is to be attached.
761 FiniteElement* const& element_pt, const int& face_index)
763 {
764 // Attach the geometrical information to the element, by
765 // making the face element from the bulk element
766 element_pt->build_face_element(face_index, this);
767 }
768
769
770 /// Fill in contribution to residuals and Jacobian. This is specific
771 /// to solid-based elements in which derivatives w.r.t. to nodal
772 /// positions are evaluated by finite differencing
774 DenseMatrix<double>& jacobian)
775 {
776 // Call the generic routine
778
779 // Shape derivatives
780 // Call the generic finite difference routine for the solid variables
781 this->fill_in_jacobian_from_solid_position_by_fd(jacobian);
782 }
783
784
785 /// The "global" intrinsic coordinate of the element when
786 /// viewed as part of a geometric object should be given by
787 /// the FaceElement representation, by default
788 double zeta_nodal(const unsigned& n,
789 const unsigned& k,
790 const unsigned& i) const
791 {
792 return FaceElement::zeta_nodal(n, k, i);
793 }
794 };
795
796
797 /// //////////////////////////////////////////////////////////////////////
798 /// //////////////////////////////////////////////////////////////////////
799 /// //////////////////////////////////////////////////////////////////////
800
801
802 //=======================================================================
803 /// The Two-dimensional interface elements that allow the application of
804 /// a volume constraint specialised for the case when the nodal positions
805 /// of the bulk elements are adjusted using spines.
806 /// To enforce that a fluid volume has a
807 /// certain volume, attach these elements to all faces of the
808 /// (3D Cartesian) bulk fluid elements (of type ELEMENT) that bound that
809 /// region and then specify the "pressure" value that is traded for the
810 /// constraint.
811 //=======================================================================
812 template<class ELEMENT>
815 public virtual SpineElement<FaceGeometry<ELEMENT>>
816 {
817 public:
818 /// Contructor: Specify bulk element and index of face to which
819 /// this face element is to be attached.
821 FiniteElement* const& element_pt, const int& face_index)
822 : SpineElement<FaceGeometry<ELEMENT>>(),
824 {
825 // Attach the geometrical information to the element, by
826 // making the face element from the bulk element
827 element_pt->build_face_element(face_index, this);
828 }
829
830
831 /// Fill in contribution to residuals and Jacobian. This is specific
832 /// to spine based elements in which the shape derivatives are evaluated
833 /// using geometric data
835 DenseMatrix<double>& jacobian)
836 {
837 // Call the generic routine
839
840 // Call the generic routine to evaluate shape derivatives
842 }
843
844
845 /// The "global" intrinsic coordinate of the element when
846 /// viewed as part of a geometric object should be given by
847 /// the FaceElement representation, by default
848 double zeta_nodal(const unsigned& n,
849 const unsigned& k,
850 const unsigned& i) const
851 {
852 return FaceElement::zeta_nodal(n, k, i);
853 }
854 };
855
856
857} // namespace oomph
858#endif
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
A class for elements that solve the unsteady axisymmetric Navier–Stokes equations in cylindrical pola...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void fill_in_generic_residual_contribution_volume_constraint(Vector< double > &residuals)
Helper function to fill in contributions to residuals (remember that part of the residual is added by...
double contribution_to_enclosed_volume()
Return this element's contribution to the total volume enclosed.
double contribution_to_volume_flux()
Return this element's contribution to the volume flux over the boundary.
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
Definition: shape.h:278
A class that represents a collection of data; each Data object may contain many different individual ...
Definition: nodes.h:86
long * eqn_number_pt(const unsigned &i)
Return the pointer to the equation number of the i-th stored variable.
Definition: nodes.h:358
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
double value(const unsigned &i) const
Return i-th stored value. This function is not virtual so that it can be inlined. This means that if ...
Definition: nodes.h:293
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
ElasticAxisymmetricVolumeConstraintBoundingElement(FiniteElement *const &element_pt, const int &face_index)
Contructor: Specify bulk element and index of face to which this face element is to be attached.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
The "global" intrinsic coordinate of the element when viewed as part of a geometric object should be ...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution to residuals and Jacobian. This is specific to solid-based elements in which der...
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
ElasticLineVolumeConstraintBoundingElement(FiniteElement *const &element_pt, const int &face_index)
Contructor: Specify bulk element and index of face to which this face element is to be attached.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution to residuals and Jacobian. This is specific to solid-based elements in which der...
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
The "global" intrinsic coordinate of the element when viewed as part of a geometric object should be ...
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution to residuals and Jacobian. This is specific to solid-based elements in which der...
ElasticSurfaceVolumeConstraintBoundingElement(FiniteElement *const &element_pt, const int &face_index)
Contructor: Specify bulk element and index of face to which this face element is to be attached.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
The "global" intrinsic coordinate of the element when viewed as part of a geometric object should be ...
void fill_in_jacobian_from_geometric_data(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contributions to the Jacobian matrix from the geometric data. This version assumes that...
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
Definition: elements.h:4338
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
Definition: elements.h:4626
void outer_unit_normal(const Vector< double > &s, Vector< double > &unit_normal) const
Compute outer unit normal at the specified local coordinate.
Definition: elements.cc:6006
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
In a FaceElement, the "global" intrinsic coordinate of the element along the boundary,...
Definition: elements.h:4497
double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s. Overloaded to get information from bulk...
Definition: elements.h:4528
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition: elements.h:4735
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
Definition: elements.h:4998
A general Finite Element class.
Definition: elements.h:1313
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1963
virtual void dshape_local_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsids) const
Return the geometric shape function and its derivative w.r.t. the local coordinates at the ipt-th int...
Definition: elements.cc:3239
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Return the local equation number corresponding to the i-th value at the n-th local node.
Definition: elements.h:1432
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
double nodal_position(const unsigned &n, const unsigned &i) const
Return the i-th coordinate at local node n. If the node is hanging, the appropriate interpolation is ...
Definition: elements.h:2317
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
virtual void build_face_element(const int &face_index, FaceElement *face_element_pt)
Function for building a lower dimensional FaceElement on the specified face of the FiniteElement....
Definition: elements.cc:5132
A Generalised Element class.
Definition: elements.h:73
Data *& external_data_pt(const unsigned &i)
Return a pointer to i-th external data object.
Definition: elements.h:659
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
int internal_local_eqn(const unsigned &i, const unsigned &j) const
Return the local equation number corresponding to the j-th value stored at the i-th internal data.
Definition: elements.h:267
int external_local_eqn(const unsigned &i, const unsigned &j)
Return the local equation number corresponding to the j-th value stored at the i-th external data.
Definition: elements.h:311
unsigned add_external_data(Data *const &data_pt, const bool &fd=true)
Add a (pointer to an) external data object to the element and return its index (i....
Definition: elements.cc:307
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void fill_in_generic_residual_contribution_volume_constraint(Vector< double > &residuals)
Helper function to fill in contributions to residuals (remember that part of the residual is added by...
double contribution_to_enclosed_volume()
Return this element's contribution to the total volume enclosed.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Definition: nodes.h:906
double value(const unsigned &i) const
Return i-th value (dofs or pinned) at this node either directly or via hanging node representation....
Definition: nodes.cc:2408
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
Definition: shape.h:76
The axisymmetric (one-dimensional) interface elements that allow imposition of a volume constraint sp...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution to residuals and Jacobian. This is specific to spine based elements in which the...
SpineAxisymmetricVolumeConstraintBoundingElement(FiniteElement *const &element_pt, const int &face_index)
Contructor: Specify bulk element and index of face to which this face element is to be attached.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
The "global" intrinsic coordinate of the element when viewed as part of a geometric object should be ...
The SpineElement<ELEMENT> class takes an existing element as a template parameter and adds the necess...
Definition: spines.h:477
The one-dimensional interface elements that allow imposition of a volume constraint specialised for t...
SpineLineVolumeConstraintBoundingElement(FiniteElement *const &element_pt, const int &face_index)
Contructor: Specify bulk element and index of face to which this face element is to be attached.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution to residuals and Jacobian. This is specific to spine based elements in which the...
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
The "global" intrinsic coordinate of the element when viewed as part of a geometric object should be ...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
SpineSurfaceVolumeConstraintBoundingElement(FiniteElement *const &element_pt, const int &face_index)
Contructor: Specify bulk element and index of face to which this face element is to be attached.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution to residuals and Jacobian. This is specific to spine based elements in which the...
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
The "global" intrinsic coordinate of the element when viewed as part of a geometric object should be ...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void fill_in_generic_residual_contribution_volume_constraint(Vector< double > &residuals)
Helper function to fill in contributions to residuals (remember that part of the residual is added by...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in contribution to residuals and Jacobian.
void set_volume_constraint_element(VolumeConstraintElement *const &vol_constraint_el_pt, const bool &check_nodal_data=true)
Set the "master" volume constraint element The setup here is a bit more complicated than one might ex...
unsigned Index_of_traded_pressure_value
Index of the value in traded pressure data that corresponds to the traded pressure.
VolumeConstraintBoundingElement()
Constructor initialise the boolean flag We expect the traded pressure data to be stored externally.
virtual void fill_in_generic_residual_contribution_volume_constraint(Vector< double > &residuals)=0
Helper function to fill in contributions to residuals (remember that part of the residual is added by...
bool Traded_pressure_stored_at_node
Boolean to indicate whether the traded pressure is stored externally or at a node (this can happen in...
int ptraded_local_eqn()
The local eqn number for the traded pressure.
unsigned Data_number_of_traded_pressure
The Data that contains the traded pressure is usually stored as external Data for this element,...
A class that is used to implement the constraint that the fluid volume in a region bounded by associa...
void fill_in_generic_contribution_to_residuals_volume_constraint(Vector< double > &residuals)
Fill in the residuals for the volume constraint.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in the residuals for the volume constraint.
unsigned Index_of_traded_pressure_value
Index of the value in traded pressure data that corresponds to the traded pressure.
unsigned External_or_internal_data_index_of_traded_pressure
The Data that contains the traded pressure is stored as external or internal Data for the element....
VolumeConstraintElement(double *prescribed_volume_pt)
Constructor: Pass pointer to target volume. "Pressure" value that "traded" for the volume contraint i...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in the residuals and jacobian for the volume constraint.
double p_traded()
Return the traded pressure value.
bool Traded_pressure_stored_as_internal_data
The Data that contains the traded pressure is stored as external or internal Data for the element....
int ptraded_local_eqn()
The local eqn number for the traded pressure.
unsigned index_of_traded_pressure()
Return the index of Data object at which the traded pressure is stored.
double * Prescribed_volume_pt
Pointer to the desired value of the volume.
Data * p_traded_data_pt()
Access to Data that contains the traded pressure.
void fill_in_contribution_to_jacobian_and_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix)
Fill in the residuals, jacobian and mass matrix for the volume constraint.
double dot(const Vector< double > &a, const Vector< double > &b)
Probably not always best/fastest because not optimised for dimension but useful...
Definition: Vector.h:291
//////////////////////////////////////////////////////////////////// ////////////////////////////////...