Telements.cc
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// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 //Non-inline member functions for Telements
31 
32 
33 // oomph-lib headers
34 #include "Telements.h"
35 
36 
37 namespace oomph
38 {
39 
40 //=======================================================================
41 /// Assign the static integral
42 //=======================================================================
43 template<unsigned NNODE_1D>
45 template<unsigned NNODE_1D>
47 template<unsigned NNODE_1D>
49 
50 //////////////////////////////////////////////////////////////////
51 // 1D Telements
52 //////////////////////////////////////////////////////////////////
53 
54 //=======================================================================
55 /// The output function for general 1D TElements
56 //=======================================================================
57 template <unsigned NNODE_1D>
58 void TElement<1,NNODE_1D>::output(std::ostream &outfile)
59 {
60  output(outfile, NNODE_1D);
61 }
62 
63 //=======================================================================
64 /// The output function for n_plot points in each coordinate direction
65 //=======================================================================
66 template <unsigned NNODE_1D>
67 void TElement<1,NNODE_1D>::output(std::ostream &outfile,
68  const unsigned &n_plot)
69 {
70  //Local variables
71  Vector<double> s(1);
72 
73  //Tecplot header info
74  outfile << "ZONE I=" << n_plot << std::endl;
75 
76  //Find the dimension of the nodes
77  unsigned n_dim = this->nodal_dimension();
78 
79  //Loop over plot points
80  for(unsigned l=0;l<n_plot;l++)
81  {
82  s[0] = l*1.0/(n_plot-1);
83  //Output the coordinates
84  for (unsigned i=0;i<n_dim;i++)
85  {
86  outfile << interpolated_x(s,i) << " " ;
87  }
88  outfile << std::endl;
89  }
90  outfile << std::endl;
91 }
92 
93 
94 
95 //=======================================================================
96 /// C style output function for general 1D TElements
97 //=======================================================================
98 template <unsigned NNODE_1D>
99 void TElement<1,NNODE_1D>::output(FILE* file_pt)
100 {
101  output(file_pt, NNODE_1D);
102 }
103 
104 //=======================================================================
105 /// C style output function for n_plot points in each coordinate direction
106 //=======================================================================
107 template <unsigned NNODE_1D>
108 void TElement<1,NNODE_1D>::output(FILE* file_pt, const unsigned &n_plot)
109 {
110  //Local variables
111  Vector<double> s(1);
112 
113  //Tecplot header info
114  //outfile << "ZONE I=" << n_plot << std::endl;
115  fprintf(file_pt,"ZONE I=%i\n",n_plot);
116 
117  //Find the dimension of the first node
118  unsigned n_dim = this->nodal_dimension();
119 
120  //Loop over plot points
121  for(unsigned l=0;l<n_plot;l++)
122  {
123  s[0] = l*1.0/(n_plot-1);
124 
125  //Output the coordinates
126  for (unsigned i=0;i<n_dim;i++)
127  {
128  //outfile << interpolated_x(s,i) << " " ;
129  fprintf(file_pt,"%g ",interpolated_x(s,i));
130  }
131  //outfile << std::endl;
132  fprintf(file_pt,"\n");
133  }
134  //outfile << std::endl;
135  fprintf(file_pt,"\n");
136 }
137 
138 //=============================================================
139 ///Namespace for helper functions that return the local
140 ///coordinates in the bulk elements
141 //==============================================================
142 namespace TElement1FaceToBulkCoordinates
143 {
144  ///The translation scheme for the face s0 = 0.0
145  void face0(const Vector<double> &s, Vector<double> &s_bulk)
146  {
147  s_bulk[0] = 0.0;
148  }
149 
150  ///The translation scheme for the face s0 = 1.0
151  void face1(const Vector<double> &s, Vector<double> &s_bulk)
152  {
153  s_bulk[0] = 1.0;
154  }
155 }
156 
157 
158 //=============================================================
159 /// Namespace for helper functions that calculate derivatives
160 /// of the local coordinates in the bulk elements wrt the
161 /// local coordinates in the face element.
162 //=============================================================
163 namespace TElement1BulkCoordinateDerivatives
164 {
165  ///Function for both faces -- the bulk coordinate is fixed on both
166  void faces0(const Vector<double> &s,
167  DenseMatrix<double> &dsbulk_dsface,
168  unsigned &interior_direction)
169  {
170  //Bulk coordinate s[0] does not vary along the face
171  dsbulk_dsface(0,0) = 0.0;
172 
173  //The interior direction is given by s[0]
174  interior_direction=0;
175  }
176 }
177 
178 //===========================================================
179 /// Function to setup geometrical information for lower-dimensional
180 /// FaceElements (which are Point Elements).
181 //===========================================================
182 template<unsigned NNODE_1D>
183 void TElement<1,NNODE_1D>::build_face_element(const int &face_index,
184  FaceElement *face_element_pt)
185 {
186  // Overload the nodal dimension
187  face_element_pt->set_nodal_dimension(nodal_dimension());
188 
189  // Set the pointer to the "bulk" element
190  face_element_pt->bulk_element_pt()=this;
191 
192 #ifdef OOMPH_HAS_MPI
193  // Pass on non-halo proc ID
194  face_element_pt->set_halo(Non_halo_proc_ID);
195 #endif
196 
197  // Resize the storage for the original number of values at the (one and only)
198  // node of the face element.
199  face_element_pt->nbulk_value_resize(1);
200 
201  // Resize the storage for the bulk node number corresponding to the (one
202  // and only) node of the face element
203  face_element_pt->bulk_node_number_resize(1);
204 
205  //Set the face index in the face element
206  face_element_pt->face_index() = face_index;
207 
208  //Now set up the node pointer
209  //The convention is that the "normal", should always point
210  //out of the element
211  switch(face_index)
212  {
213  //Bottom, normal sign is negative (coordinate points into element)
214  case(-1):
215  face_element_pt->node_pt(0) = node_pt(0);
216  face_element_pt->bulk_node_number(0) = 0;
217  face_element_pt->normal_sign() = -1;
218 
219  //Set the pointer to the function that determines the bulk coordinates
220  //in the face element
221  face_element_pt->face_to_bulk_coordinate_fct_pt() =
223 
224  //Set the pointer to the function that determines the mapping of
225  //derivatives
226  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
228 
229  //Set the number of values stored when the node is part of the "bulk"
230  //element. The required_nvalue() must be used, rather than nvalue(),
231  //because otherwise nodes on boundaries will be resized multiple
232  //times. If you want any other behaviour, you MUST set nbulk_value()
233  //manually after construction of your specific face element.
234  face_element_pt->nbulk_value(0) = required_nvalue(0);
235  break;
236 
237  //Top, normal sign is positive (coordinate points out of element)
238  case(1):
239  face_element_pt->node_pt(0) = node_pt(NNODE_1D-1);
240  face_element_pt->bulk_node_number(0) = NNODE_1D-1;
241  face_element_pt->normal_sign() = +1;
242 
243  //Set the pointer to the function that determines the bulk coordinates
244  //in the face element
245  face_element_pt->face_to_bulk_coordinate_fct_pt() =
247 
248  //Set the pointer to the function that determines the mapping of
249  //derivatives
250  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
252 
253 
254  //Set the number of values stored when the node is part of the "bulk"
255  //element.
256  face_element_pt->nbulk_value(0) = required_nvalue(NNODE_1D-1);
257  break;
258 
259  //All other cases throw an error
260  default:
261  std::ostringstream error_message;
262  error_message << "Face_index should only take "
263  << "the values +/-1, not " << face_index << std::endl;
264 
265  throw OomphLibError(error_message.str(),
266  OOMPH_CURRENT_FUNCTION,
267  OOMPH_EXCEPTION_LOCATION);
268  }
269 }
270 
271 
272 
273 ////////////////////////////////////////////////////////////////
274 // 2D Telements
275 ////////////////////////////////////////////////////////////////
276 
277 /// Assign the nodal translation schemes
278 template<>
279 const unsigned TElement<2,2>::Node_on_face[3][2] ={{2,1},{2,0},{0,1}};
280 
281 template<>
282 const unsigned TElement<2,3>::Node_on_face[3][3] ={{2,4,1},{2,5,0},{0,3,1}};
283 
284 template<>
285 const unsigned TElement<2,4>::Node_on_face[3][4] =
286 {{2,6,5,1},{2,7,8,0},{0,3,4,1}};
287 
288 
289 //===================================================================
290 /// Namespace for the functions that translate local face coordinates
291 /// to the coordinates in the bulk element
292 //==================================================================
293 namespace TElement2FaceToBulkCoordinates
294 {
295  ///The translation scheme for the face s0 = 0
296  void face0(const Vector<double> &s, Vector<double> &s_bulk)
297  {
298  s_bulk[0] = 0.0;
299  s_bulk[1] = s[0];
300  }
301 
302  ///The translation scheme for the face s1 = 0
303  void face1(const Vector<double> &s, Vector<double> &s_bulk)
304  {
305  s_bulk[0] = s[0];
306  s_bulk[1] = 0.0;
307  }
308 
309  ///The translation scheme for the face s2 = 0
310  void face2(const Vector<double> &s, Vector<double> &s_bulk)
311  {
312  s_bulk[0] = 1.0 - s[0];
313  s_bulk[1] = s[0];
314  }
315 }
316 
317 
318 //=============================================================
319 /// Namespace for helper functions that calculate derivatives
320 /// of the local coordinates in the bulk elements wrt the
321 /// local coordinates in the face element.
322 //=============================================================
323 namespace TElement2BulkCoordinateDerivatives
324 {
325  ///Function for the "left" face along which s0 is fixed
326  void face0(const Vector<double> &s,
327  DenseMatrix<double> &dsbulk_dsface,
328  unsigned &interior_direction)
329  {
330  //Bulk coordinate s[0] does not vary along the face
331  dsbulk_dsface(0,0) = 0.0;
332  //Bulk coordinate s[1] is the face coordinate
333  dsbulk_dsface(1,0) = 1.0;
334 
335  //The interior direction is given by s[0]
336  interior_direction=0;
337  }
338 
339 
340  ///Function for the "bottom" face along which s1 is fixed
341  void face1(const Vector<double> &s,
342  DenseMatrix<double> &dsbulk_dsface,
343  unsigned &interior_direction)
344  {
345  //Bulk coordinate s[0] is the face coordinate
346  dsbulk_dsface(0,0) = 1.0;
347  //Bulk coordinate s[1] does not vary along the face
348  dsbulk_dsface(1,0) = 0.0;
349 
350  //The interior direction is given by s[1]
351  interior_direction=1;
352  }
353 
354  ///Function for the sloping face
355  void face2(const Vector<double> &s,
356  DenseMatrix<double> &dsbulk_dsface,
357  unsigned &interior_direction)
358  {
359  //Bulk coordinate s[0] decreases along the face
360  dsbulk_dsface(0,0) = -1.0;
361  //Bulk coordinate s[1] increases along the face
362  dsbulk_dsface(1,0) = 1.0;
363 
364  //The interior direction is given by s[0] (or s[1])
365  interior_direction=0;
366  }
367 
368 }
369 
370 
371 //=======================================================================
372 /// Function to setup geometrical information for lower-dimensional
373 /// FaceElements (which are of type TElement<2,NNODE_1D>).
374 //=======================================================================
375  template<unsigned NNODE_1D>
376  void TElement<2,NNODE_1D>::build_face_element(const int &face_index,
377  FaceElement* face_element_pt)
378 {
379  //Set the nodal dimension from the first node
380  face_element_pt->set_nodal_dimension(nodal_dimension());
381 
382  //Set the pointer to the orginal "bulk" element
383  face_element_pt->bulk_element_pt()=this;
384 
385 #ifdef OOMPH_HAS_MPI
386  // Pass on non-halo proc ID
387  face_element_pt->set_halo(Non_halo_proc_ID);
388 #endif
389 
390  //Calculate the number of nodes in the face element
391  const unsigned n_face_nodes = NNODE_1D;
392 
393  // Resize storage for the number of values originally stored
394  // at the face element's nodes.
395  face_element_pt->nbulk_value_resize(n_face_nodes);
396 
397  // Resize storage for the bulk node numbers corresponding to
398  // the nodes of the face
399  face_element_pt->bulk_node_number_resize(n_face_nodes);
400 
401  //Set the face index in the face element
402  face_element_pt->face_index() = face_index;
403 
404  //So the faces are
405  // 0 : s_0 fixed
406  // 1 : s_1 fixed
407  // 2 : sloping face
408 
409  // Copy nodes across to the face
410  for (unsigned i=0;i<n_face_nodes;i++)
411  {
412  //The number is just offset by one
413  unsigned bulk_number = Node_on_face[face_index][i];
414  face_element_pt->node_pt(i)=node_pt(bulk_number);
415  face_element_pt->bulk_node_number(i) = bulk_number;
416  //set the number of values originally stored at this node
417  face_element_pt->nbulk_value(i) = required_nvalue(bulk_number);
418  }
419 
420  //Now set up the node pointers and the normal vectors
421  switch(face_index)
422  {
423  //
424  //-----The face s0 is constant
425  case 0:
426 
427  //Set the pointer to the function that determines the bulk
428  //coordinates in the face element
429  face_element_pt->face_to_bulk_coordinate_fct_pt() =
431 
432  //Set the pointer to the function that determines the mapping of
433  //derivatives
434  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
436 
437  // Outer unit normal is the positive cross product of two in plane
438  // tangent vectors
439  face_element_pt->normal_sign()=+1;
440 
441  break;
442 
443  //-----The face s1 is constant
444  case 1:
445 
446  //Set the pointer to the function that determines the bulk
447  //coordinates in the face element
448  face_element_pt->face_to_bulk_coordinate_fct_pt() =
450 
451  //Set the pointer to the function that determines the mapping of
452  //derivatives
453  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
455 
456  // Outer unit normal is the positive cross product of two in plane
457  // tangent vectors
458  face_element_pt->normal_sign()=+1;
459 
460  break;
461 
462  //
463  //-----The face s2 is constant
464  case 2:
465 
466  //Set the pointer to the function that determines the bulk
467  //coordinates in the face element
468  face_element_pt->face_to_bulk_coordinate_fct_pt() =
470 
471  //Set the pointer to the function that determines the mapping of
472  //derivatives
473  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
475 
476  // Outer unit normal is the negative cross product of two in plane
477  // tangent vectors
478  face_element_pt->normal_sign()=-1;
479 
480  break;
481 
482  default:
483 
484  std::ostringstream error_message;
485  error_message << "Face_index should only take "
486  << "the values 0, 1 or 2 not " << face_index << std::endl;
487 
488  throw OomphLibError(error_message.str(),
489  OOMPH_CURRENT_FUNCTION,
490  OOMPH_EXCEPTION_LOCATION);
491  } //end switch
492 
493 }
494 
495 
496 
497 
498 //=======================================================================
499 /// The output function for TElement<2,NNODE_1D>
500 //=======================================================================
501 template<unsigned NNODE_1D>
502 void TElement<2,NNODE_1D>::output(std::ostream &outfile)
503 {
504  // QUEHACERES want to perform same output, but at each node
505  output(outfile, NNODE_1D);
506 }
507 
508 
509 
510 //=======================================================================
511 /// The output function for TElement<2,NNODE_1D>
512 //=======================================================================
513 template<unsigned NNODE_1D>
514 void TElement<2,NNODE_1D>::output(std::ostream &outfile,const unsigned &nplot)
515 {
516 
517  //Vector of local coordinates
518  Vector<double> s(2);
519 
520  //Get the dimension of the node
521  unsigned n_dim = this->nodal_dimension();
522 
523  // Tecplot header info
524  outfile << tecplot_zone_string(nplot);
525 
526  // Loop over plot points
527  unsigned num_plot_points=nplot_points(nplot);
528  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
529  {
530  // Get local coordinates of plot point
531  get_s_plot(iplot,nplot,s);
532 
533  for(unsigned i=0;i<n_dim;i++)
534  {
535  outfile << interpolated_x(s,i) << " ";
536  }
537  outfile << std::endl;
538  }
539 
540  // Write tecplot footer (e.g. FE connectivity lists)
541  write_tecplot_zone_footer(outfile,nplot);
542 
543 }
544 
545 //=======================================================================
546 /// The C-style output function for TElement<2,NNODE_1D>
547 //=======================================================================
548 template<unsigned NNODE_1D>
549 void TElement<2,NNODE_1D>::output(FILE* file_pt)
550 {
551  output(file_pt, NNODE_1D);
552 }
553 
554 
555 
556 //=======================================================================
557 /// The C-style output function for TElement<2,NNODE_1D>
558 //=======================================================================
559 template<unsigned NNODE_1D>
560 void TElement<2,NNODE_1D>::output(FILE* file_pt,const unsigned &nplot)
561 {
562 
563  //Vector of local coordinates
564  Vector<double> s(2);
565 
566  //Find the dimensions of the nodes
567  unsigned n_dim = this->nodal_dimension();
568 
569  // Tecplot header info
570  fprintf(file_pt,"%s \n",tecplot_zone_string(nplot).c_str());
571 
572  // Loop over plot points
573  unsigned num_plot_points=nplot_points(nplot);
574  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
575  {
576  // Get local coordinates of plot point
577  get_s_plot(iplot,nplot,s);
578 
579  for(unsigned i=0;i<n_dim;i++)
580  {
581  fprintf(file_pt,"%g ", interpolated_x(s,i));
582  //outfile << interpolated_x(s,i) << " ";
583  }
584  fprintf(file_pt,"\n");
585  //outfile << std::endl;
586  }
587 
588  // Write tecplot footer (e.g. FE connectivity lists)
589  write_tecplot_zone_footer(file_pt,nplot);
590 
591 }
592 
593 
594 ///////////////////////////////////////////////////////////////////////
595 ///////////////////////////////////////////////////////////////////////
596 ///////////////////////////////////////////////////////////////////////
597 
598 
599 
600 //=======================================================================
601 /// The output function for TElement<3,NNODE_1D>
602 //=======================================================================
603 template<unsigned NNODE_1D>
604 void TElement<3,NNODE_1D>::output(std::ostream &outfile)
605 {
606  output(outfile, NNODE_1D);
607 }
608 
609 
610 
611 //=======================================================================
612 /// The output function for TElement<3,NNODE_1D>
613 //=======================================================================
614 template<unsigned NNODE_1D>
615 void TElement<3,NNODE_1D>::output(std::ostream &outfile,const unsigned &nplot)
616 {
617 
618  //Vector of local coordinates
619  Vector<double> s(3);
620 
621  //Find the dimension of the nodes
622  unsigned n_dim = this->nodal_dimension();
623 
624  // Tecplot header info
625  outfile << tecplot_zone_string(nplot);
626 
627  // Loop over plot points
628  unsigned num_plot_points=nplot_points(nplot);
629  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
630  {
631  // Get local coordinates of plot point
632  get_s_plot(iplot,nplot,s);
633 
634  for(unsigned i=0;i<n_dim;i++)
635  {
636  outfile << interpolated_x(s,i) << " ";
637  }
638  outfile << "\n";
639  }
640 
641  // Write tecplot footer (e.g. FE connectivity lists)
642  write_tecplot_zone_footer(outfile,nplot);
643 
644 }
645 
646 
647 //=======================================================================
648 /// The C-style output function for TElement<3,NNODE_1D>
649 //=======================================================================
650 template<unsigned NNODE_1D>
651 void TElement<3,NNODE_1D>::output(FILE* file_pt)
652 {
653  output(file_pt, NNODE_1D);
654 }
655 
656 
657 //=======================================================================
658 /// The C-style output function for TElement<3,NNODE_1D>
659 //=======================================================================
660 template<unsigned NNODE_1D>
661 void TElement<3,NNODE_1D>::output(FILE* file_pt,const unsigned &nplot)
662 {
663 
664  //Vector of local coordinates
665  Vector<double> s(3);
666 
667  //Find the dimension of the nodes
668  unsigned n_dim = this->nodal_dimension();
669 
670  // Tecplot header info
671  fprintf(file_pt,"%s \n",tecplot_zone_string(nplot).c_str());
672 
673  // Loop over plot points
674  unsigned num_plot_points=nplot_points(nplot);
675  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
676  {
677  // Get local coordinates of plot point
678  get_s_plot(iplot,nplot,s);
679 
680  for(unsigned i=0;i<n_dim;i++)
681  {
682  fprintf(file_pt,"%g ", interpolated_x(s,i));
683  //outfile << interpolated_x(s,i) << " ";
684  }
685  fprintf(file_pt,"\n");
686  //outfile << std::endl;
687  }
688 
689  // Write tecplot footer (e.g. FE connectivity lists)
690  write_tecplot_zone_footer(file_pt,nplot);
691 
692 }
693 
694 //===================================================================
695 /// Namespace for the functions that translate local face coordinates
696 /// to the coordinates in the bulk element
697 //==================================================================
698 namespace TElement3FaceToBulkCoordinates
699 {
700  ///The translation scheme for the face s0 = 0
701  void face0(const Vector<double> &s, Vector<double> &s_bulk)
702  {
703  s_bulk[0] = 0.0;
704  s_bulk[1] = s[0];
705  s_bulk[2] = s[1];
706  }
707 
708  ///The translation scheme for the face s1 = 0
709  void face1(const Vector<double> &s, Vector<double> &s_bulk)
710  {
711  s_bulk[0] = s[0];
712  s_bulk[1] = 0.0;
713  s_bulk[2] = s[1];
714  }
715 
716  ///The translation scheme for the face s2 = 0
717  void face2(const Vector<double> &s, Vector<double> &s_bulk)
718  {
719  s_bulk[0] = s[0];
720  s_bulk[1] = s[1];
721  s_bulk[2] = 0.0;
722  }
723 
724  ///The translation scheme for the sloping face
725  void face3(const Vector<double> &s, Vector<double> &s_bulk)
726  {
727  s_bulk[0] = 1 - s[0] - s[1];
728  s_bulk[1] = s[0];
729  s_bulk[2] = s[1];
730  }
731 
732 }
733 
734 ///Assign the nodal translation scheme for linear elements
735 template<>
736 const unsigned TElement<3,2>::Node_on_face[4][3] =
737 {{1,2,3},{0,2,3},{0,1,3},{1,2,0}};
738 
739 ///Assign the nodal translation scheme for quadratic elements
740 template<>
741 const unsigned TElement<3,3>::Node_on_face[4][6] =
742 {{1,2,3,7,8,9},{0,2,3,5,8,6},{0,1,3,4,9,6},{1,2,0,7,5,4}};
743 
744 
745 //=======================================================================
746 /// Function to setup geometrical information for lower-dimensional
747 /// FaceElements (which are of type TElement<2,NNODE_1D>).
748 //=======================================================================
749  template<unsigned NNODE_1D>
750  void TElement<3,NNODE_1D>::build_face_element(const int &face_index,
751  FaceElement* face_element_pt)
752 {
753  //Set the nodal dimension
754  face_element_pt->set_nodal_dimension(nodal_dimension());
755 
756  //Set the pointer to the orginal "bulk" element
757  face_element_pt->bulk_element_pt()=this;
758 
759 #ifdef OOMPH_HAS_MPI
760  // Pass on non-halo proc ID
761  face_element_pt->set_halo(Non_halo_proc_ID);
762 #endif
763 
764  //Calculate the number of nodes in the face element
765  const unsigned n_face_nodes = (NNODE_1D*(NNODE_1D+1))/2;
766 
767  // Resize storage for the number of values originally stored
768  // at the face element's nodes.
769  face_element_pt->nbulk_value_resize(n_face_nodes);
770 
771  // Resize storage for the bulk node numbers corresponding to
772  // the nodes of the face
773  face_element_pt->bulk_node_number_resize(n_face_nodes);
774 
775  //Set the face index in the face element
776  face_element_pt->face_index() = face_index;
777 
778  //So the faces are
779  // 0 : s_0 fixed
780  // 1 : s_1 fixed
781  // 2 : s_2 fixed
782  // 3 : sloping face
783 
784  // Copy nodes across to the face
785  for (unsigned i=0;i<n_face_nodes;i++)
786  {
787  //The number is just offset by one
788  unsigned bulk_number = Node_on_face[face_index][i];
789  face_element_pt->node_pt(i)=node_pt(bulk_number);
790  face_element_pt->bulk_node_number(i) = bulk_number;
791  //set the number of values originally stored at this node
792  face_element_pt->nbulk_value(i) = required_nvalue(bulk_number);
793  }
794 
795  //Now set up the node pointers and the normal vectors
796  switch(face_index)
797  {
798  //
799  //-----The face s0 is constant
800  case 0:
801 
802  //Set the pointer to the function that determines the bulk
803  //coordinates in the face element
804  face_element_pt->face_to_bulk_coordinate_fct_pt() =
806 
807  // Outer unit normal is the negative cross product of two in plane
808  // tangent vectors
809  face_element_pt->normal_sign()=-1;
810 
811  break;
812 
813  //-----The face s1 is constant
814  case 1:
815 
816  //Set the pointer to the function that determines the bulk
817  //coordinates in the face element
818  face_element_pt->face_to_bulk_coordinate_fct_pt() =
820 
821  // Outer unit normal is the positive cross product of two in plane
822  // tangent vectors
823  face_element_pt->normal_sign()=+1;
824 
825  break;
826 
827  //
828  //-----The face s2 is constant
829  case 2:
830 
831  //Set the pointer to the function that determines the bulk
832  //coordinates in the face element
833  face_element_pt->face_to_bulk_coordinate_fct_pt() =
835 
836  // Outer unit normal is the negative cross product of two in plane
837  // tangent vectors
838  face_element_pt->normal_sign()=-1;
839 
840  break;
841 
842  //-----The sloping face of the tetrahedron
843  case 3:
844 
845  //Set the pointer to the function that determines the bulk
846  //coordinates in the face element
847  face_element_pt->face_to_bulk_coordinate_fct_pt() =
849 
850  // Outer unit normal is the positive cross product of two in plane
851  // tangent vectors
852  face_element_pt->normal_sign()=+1;
853 
854  break;
855 
856 
857 
858  default:
859 
860  std::ostringstream error_message;
861  error_message << "Face_index should only take "
862  << "the values 0, 1, 2 or 3, not "
863  << face_index << std::endl;
864 
865  throw OomphLibError(error_message.str(),
866  OOMPH_CURRENT_FUNCTION,
867  OOMPH_EXCEPTION_LOCATION);
868  } //end switch
869 
870 }
871 
872 
873 //==================================================================
874 //Default integration scheme for the TBubbleEnrichedElement<2,3>
875 //===================================================================
876 template<unsigned DIM>
879 
880 //===================================================================
881 //Central node on the face of the TBubbleEnrichedelement<2,3>
882 //===================================================================
883 template<>
885 
886 
887 //================================================================
888 ///The face element for is the same in the two-dimesional case
889 //================================================================
890 template<>
892  const int &face_index,FaceElement* face_element_pt)
893 {TElement<2,3>::build_face_element(face_index,face_element_pt);}
894 
895 
896 //===================================================================
897 //Central node on the face of the TBubbleEnrichedelement<3,3>
898 //===================================================================
899 template<>
901 {13,12,10,11};
902 
903 
904 
905 //=======================================================================
906 /// Function to setup geometrical information for lower-dimensional
907 /// FaceElements (which are of type TBubbleEnrichedElement<2,3>).
908 //=======================================================================
909  template<>
911  const int &face_index,
912  FaceElement* face_element_pt)
913 {
914  //Call the standard unenriched build function
915  TElement<3,3>::build_face_element(face_index,face_element_pt);
916 
917  //Set the enriched number of total face nodes
918  const unsigned n_face_nodes = 7;
919 
920  // Resize storage for the number of values originally stored
921  // at the face element's nodes.
922  face_element_pt->nbulk_value_resize(n_face_nodes);
923 
924  // Resize storage for the bulk node numbers corresponding to
925  // the nodes of the face
926  face_element_pt->bulk_node_number_resize(n_face_nodes);
927 
928  //So the faces are
929  // 0 : s_0 fixed
930  // 1 : s_1 fixed
931  // 2 : s_2 fixed
932  // 3 : sloping face
933 
934  //Copy central node across
935  unsigned bulk_number = Central_node_on_face[face_index];
936  face_element_pt->node_pt(n_face_nodes-1)=node_pt(bulk_number);
937  face_element_pt->bulk_node_number(n_face_nodes-1) = bulk_number;
938  //set the number of values originally stored at this node
939  face_element_pt->nbulk_value(n_face_nodes-1) = required_nvalue(bulk_number);
940 }
941 
942 /////////////////////////////////////////////////////////////////////////
943 /////////////////////////////////////////////////////////////////////////
944 /////////////////////////////////////////////////////////////////////////
945 
946 //===========================================================
947 /// Final override for
948 /// function to setup geometrical information for lower-dimensional
949 /// FaceElements (which are of type SolidTBubbleEnrichedElement<1,3>).
950 //===========================================================
951 template<>
953 build_face_element(const int &face_index, FaceElement *face_element_pt)
954 {
955  //Build the standard non-solid FaceElement
957  build_face_element(face_index,face_element_pt);
958 
959  //Set the Lagrangian dimension from the first node of the present element
960  dynamic_cast<SolidFiniteElement*>(face_element_pt)->
961  set_lagrangian_dimension(static_cast<SolidNode*>(node_pt(0))->nlagrangian());
962 }
963 
964 
965 //===========================================================
966 /// Final override for
967 /// function to setup geometrical information for lower-dimensional
968 /// FaceElements (which are of type SolidTBubbleEnrichedElement<2,3>).
969 //===========================================================
970 template<>
972 build_face_element(const int &face_index, FaceElement *face_element_pt)
973 {
974  //Build the standard non-solid FaceElement
976  build_face_element(face_index,face_element_pt);
977 
978  //Set the Lagrangian dimension from the first node of the present element
979  dynamic_cast<SolidFiniteElement*>(face_element_pt)->
980  set_lagrangian_dimension(static_cast<SolidNode*>(node_pt(0))->nlagrangian());
981 }
982 
983 
984 
985 
986 //===================================================================
987 // Build required templates
988 //===================================================================
989 template class TElement<1,2>;
990 template class TElement<1,3>;
991 template class TElement<1,4>;
992 template class TElement<2,2>;
993 template class TElement<2,3>;
994 template class TElement<2,4>;
995 template class TElement<3,2>;
996 template class TElement<3,3>;
997 template class TBubbleEnrichedElement<2,3>;
998 template class TBubbleEnrichedElement<3,3>;
999 template class SolidTBubbleEnrichedElement<2,3>;
1000 template class SolidTBubbleEnrichedElement<3,3>;
1001 template class TBubbleEnrichedGauss<2,3>;
1002 template class TBubbleEnrichedGauss<3,3>;
1003 }
cstr elem_len * i
Definition: cfortran.h:607
void face0(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = 0.
Definition: Telements.cc:701
void face3(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the sloping face.
Definition: Telements.cc:725
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
Definition: elements.h:4412
BulkCoordinateDerivativesFctPt & bulk_coordinate_derivatives_fct_pt()
Return the pointer to the function that returns the derivatives of the bulk coordinates wrt the face ...
Definition: elements.h:4540
void faces0(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for both faces – the bulk coordinate is fixed on both.
Definition: Telements.cc:166
unsigned & bulk_node_number(const unsigned &n)
Return the bulk node number that corresponds to the n-th local node number.
Definition: elements.h:4584
int & normal_sign()
Sign of outer unit normal (relative to cross-products of tangent vectors in the corresponding "bulk" ...
Definition: elements.h:4404
void face0(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = 0.0.
Definition: Telements.cc:145
static TGauss< 1, NNODE_1D > Default_integration_scheme
Default integration rule: Gaussian integration of same &#39;order&#39; as the element.
Definition: Telements.h:1264
void set_halo(const unsigned &non_halo_proc_ID)
Label the element as halo and specify processor that holds non-halo counterpart.
Definition: elements.h:1132
void face1(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s1 = 0.
Definition: Telements.cc:709
static char t char * s
Definition: cfortran.h:572
void build_face_element(const int &face_index, FaceElement *face_element_pt)
Definition: Telements.cc:953
static TGauss< 2, NNODE_1D > Default_integration_scheme
Default integration rule: Gaussian integration of same &#39;order&#39; as the element.
Definition: Telements.h:1534
void nbulk_value_resize(const unsigned &i)
Resize the storage for the number of values originally stored at the local nodes to i entries...
Definition: elements.h:4607
const unsigned Node_on_face[3][2]
Assign the nodal translation schemes.
Definition: Telements.cc:279
void face2(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for the sloping face.
Definition: Telements.cc:355
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2109
void output(std::ostream &outfile)
Output with default number of plot points.
static TGauss< 3, NNODE_1D > Default_integration_scheme
Default integration rule: Gaussian integration of same &#39;order&#39; as the element.
Definition: Telements.h:3008
void face0(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for the "left" face along which s0 is fixed.
Definition: Telements.cc:326
void face2(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s2 = 0.
Definition: Telements.cc:310
void face1(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s1 = 0.
Definition: Telements.cc:303
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition: elements.h:4515
void face2(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s2 = 0.
Definition: Telements.cc:717
void set_nodal_dimension(const unsigned &nodal_dim)
Set the dimension of the nodes in the element. This will typically only be required when constructing...
Definition: elements.h:1351
CoordinateMappingFctPt & face_to_bulk_coordinate_fct_pt()
Return the pointer to the function that maps the face coordinate to the bulk coordinate.
Definition: elements.h:4529
void bulk_node_number_resize(const unsigned &i)
Resize the storage for the bulk node numbers.
Definition: elements.h:4580
unsigned & nbulk_value(const unsigned &n)
Return the number of values originally stored at local node n (before the FaceElement added additiona...
Definition: elements.h:4597
void build_face_element(const int &face_index, FaceElement *face_element_pt)
The face element for is the same in the two-dimesional case.
Definition: Telements.cc:891
void face1(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = 1.0.
Definition: Telements.cc:151
SolidFiniteElement class.
Definition: elements.h:3361
void face1(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for the "bottom" face along which s1 is fixed.
Definition: Telements.cc:341
void face0(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = 0.
Definition: Telements.cc:296