Qspectral_elements.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// Copyright (C) 2006-2023 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 #include "Qspectral_elements.h"
28 
29 
30 namespace oomph
31 {
32  std::map<unsigned, Vector<double>> OneDLegendreShapeParam::z;
33 
34 
35  /// ///////////////////////////////////////////////////////////////////////
36  /// 1D QLegendreElements
37  /// ///////////////////////////////////////////////////////////////////////
38 
39 
40  //=======================================================================
41  /// Assign the static integral
42  //=======================================================================
43  template<unsigned NNODE_1D>
44  GaussLobattoLegendre<1, NNODE_1D> QSpectralElement<1, NNODE_1D>::integral;
45 
46  //=======================================================================
47  /// The output function for general 1D QSpectralElements
48  //=======================================================================
49  template<unsigned NNODE_1D>
50  void QSpectralElement<1, NNODE_1D>::output(std::ostream& outfile)
51  {
52  // Tecplot header info
53  outfile << "ZONE I=" << NNODE_1D << std::endl;
54 
55  // Find the dimension of the nodes
56  unsigned n_dim = this->nodal_dimension();
57 
58  // Loop over element nodes
59  for (unsigned l = 0; l < NNODE_1D; l++)
60  {
61  // Loop over the dimensions and output the position
62  for (unsigned i = 0; i < n_dim; i++)
63  {
64  outfile << this->node_pt(l)->x(i) << " ";
65  }
66  // Find out how many data values at the node
67  unsigned initial_nvalue = this->node_pt(l)->nvalue();
68  // Lopp over the data and output whether pinned or not
69  for (unsigned i = 0; i < initial_nvalue; i++)
70  {
71  outfile << this->node_pt(l)->is_pinned(i) << " ";
72  }
73  outfile << std::endl;
74  }
75  outfile << std::endl;
76  }
77 
78  //=======================================================================
79  /// The output function for nplot points in each coordinate direction
80  //=======================================================================
81  template<unsigned NNODE_1D>
82  void QSpectralElement<1, NNODE_1D>::output(std::ostream& outfile,
83  const unsigned& nplot)
84  {
85  // Local variables
86  Vector<double> s(1);
87  // Shape functions
88  Shape psi(NNODE_1D);
89 
90  // Find the dimension of the nodes
91  unsigned n_dim = this->nodal_dimension();
92 
93  // Tecplot header info
94  outfile << "ZONE I=" << nplot << std::endl;
95  // Loop over element nodes
96  for (unsigned l = 0; l < nplot; l++)
97  {
98  s[0] = -1.0 + l * 2.0 / (nplot - 1);
99  shape(s, psi);
100  for (unsigned i = 0; i < n_dim; i++)
101  {
102  // Output the x and y positions
103  outfile << this->interpolated_x(s, i) << " ";
104  }
105  for (unsigned i = 0; i < NNODE_1D; i++)
106  {
107  outfile << psi(i) << " ";
108  }
109  outfile << std::endl;
110  }
111  outfile << std::endl;
112  }
113 
114  //===========================================================
115  /// Function to setup geometrical information for lower-dimensional
116  /// FaceElements (which are of type QSpectralElement<0,1>).
117  //===========================================================
118  template<unsigned NNODE_1D>
120  const int& face_index, FaceElement* face_element_pt)
121  {
122  /*throw OomphLibError("Untested",
123  OOMPH_CURRENT_FUNCTION,
124  OOMPH_EXCEPTION_LOCATION);*/
125 
126  // Overload the nodal dimension by reading out the value from the node
127  face_element_pt->set_nodal_dimension(this->node_pt(0)->ndim());
128 
129  // Set the pointer to the "bulk" element
130  face_element_pt->bulk_element_pt() = this;
131 
132 #ifdef OOMPH_HAS_MPI
133  // If the bulk element is halo then the face element must be too
134  // if (this->is_halo())
135  {
136  face_element_pt->set_halo(Non_halo_proc_ID);
137  }
138 #endif
139 
140  // Resize the storage for the original number of values at the (one and
141  // only) node of the face element.
142  face_element_pt->nbulk_value_resize(1);
143 
144  // Resize the storage for the bulk node number corresponding to the (one
145  // and only) node of the face element
146  face_element_pt->bulk_node_number_resize(1);
147 
148  // Set the face index in the face element
149  face_element_pt->face_index() = face_index;
150 
151  // Now set up the node pointer
152  // The convention is that the "normal", should always point
153  // out of the element
154  switch (face_index)
155  {
156  // Bottom, normal sign is negative (coordinate points into element)
157  case (-1):
158  face_element_pt->node_pt(0) = this->node_pt(0);
159  face_element_pt->bulk_node_number(0) = 0;
160  face_element_pt->normal_sign() = -1;
161 
162  // Set the pointer to the function that determines the bulk coordinates
163  // in the face element
164  face_element_pt->face_to_bulk_coordinate_fct_pt() =
166 
167  // Set the pointer to the function that determines the mapping of
168  // derivatives
169  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
171 
172  // Set the number of values stored when the node is part of the "bulk"
173  // element. The required_nvalue() must be used, rather than nvalue(),
174  // because otherwise nodes on boundaries will be resized multiple
175  // times. If you want any other behaviour, you MUST set nbulk_value()
176  // manually after construction of your specific face element.
177  face_element_pt->nbulk_value(0) = this->required_nvalue(0);
178  break;
179 
180  // Top, normal sign is positive (coordinate points out of element)
181  case (1):
182  face_element_pt->node_pt(0) = this->node_pt(NNODE_1D - 1);
183  face_element_pt->bulk_node_number(0) = NNODE_1D - 1;
184  face_element_pt->normal_sign() = +1;
185 
186 
187  // Set the pointer to the function that determines the bulk coordinates
188  // in the face element
189  face_element_pt->face_to_bulk_coordinate_fct_pt() =
191 
192  // Set the pointer to the function that determines the mapping of
193  // derivatives
194  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
196 
197 
198  // Set the number of values stored when the node is part of the "bulk"
199  // element.
200  face_element_pt->nbulk_value(0) = this->required_nvalue(NNODE_1D - 1);
201  break;
202 
203  // Other cases
204  default:
205  std::ostringstream error_message;
206  error_message << "Face_index should only take "
207  << "the values +/-1, not " << face_index << std::endl;
208 
209  throw OomphLibError(error_message.str(),
210  OOMPH_CURRENT_FUNCTION,
211  OOMPH_EXCEPTION_LOCATION);
212  }
213  }
214 
215 
216  /// ///////////////////////////////////////////////////////////////////////
217  /// 2D QLegendreElements
218  /// ///////////////////////////////////////////////////////////////////////
219 
220  //=======================================================================
221  /// Assign the static integral
222  //=======================================================================
223  template<unsigned NNODE_1D>
225 
226  //=======================================================================
227  /// The output function for general 1D QSpectralElements
228  //=======================================================================
229  template<unsigned NNODE_1D>
230  void QSpectralElement<2, NNODE_1D>::output(std::ostream& outfile)
231  {
232  // Tecplot header info
233  outfile << "ZONE I=" << NNODE_1D << ", J=" << NNODE_1D << std::endl;
234 
235  // Find the dimension of the nodes
236  unsigned n_dim = this->nodal_dimension();
237 
238  // Loop over element nodes
239  for (unsigned l2 = 0; l2 < NNODE_1D; l2++)
240  {
241  for (unsigned l1 = 0; l1 < NNODE_1D; l1++)
242  {
243  unsigned l = l2 * NNODE_1D + l1;
244 
245  // Loop over the dimensions and output the position
246  for (unsigned i = 0; i < n_dim; i++)
247  {
248  outfile << this->node_pt(l)->x(i) << " ";
249  }
250  // Find out how many data values at the node
251  unsigned initial_nvalue = this->node_pt(l)->nvalue();
252  // Loop over the data and output whether pinned or not
253  for (unsigned i = 0; i < initial_nvalue; i++)
254  {
255  outfile << this->node_pt(l)->is_pinned(i) << " ";
256  }
257  outfile << std::endl;
258  }
259  }
260  outfile << std::endl;
261  }
262 
263 
264  //=======================================================================
265  /// The output function for n+plot points in each coordinate direction
266  //=======================================================================
267  template<unsigned NNODE_1D>
268  void QSpectralElement<2, NNODE_1D>::output(std::ostream& outfile,
269  const unsigned& n_plot)
270  {
271  // Local variables
272  Vector<double> s(2);
273 
274  // Tecplot header info
275  outfile << "ZONE I=" << n_plot << ", J=" << n_plot << std::endl;
276 
277  // Find the dimension of the first node
278  unsigned n_dim = this->nodal_dimension();
279 
280  // Loop over plot points
281  for (unsigned l2 = 0; l2 < n_plot; l2++)
282  {
283  s[1] = -1.0 + l2 * 2.0 / (n_plot - 1);
284  for (unsigned l1 = 0; l1 < n_plot; l1++)
285  {
286  s[0] = -1.0 + l1 * 2.0 / (n_plot - 1);
287 
288  // Output the coordinates
289  for (unsigned i = 0; i < n_dim; i++)
290  {
291  outfile << this->interpolated_x(s, i) << " ";
292  }
293  outfile << std::endl;
294  }
295  }
296  outfile << std::endl;
297  }
298 
299 
300  //===========================================================
301  /// Function to setup geometrical information for lower-dimensional
302  /// FaceElements (which are of type QSpectralElement<0,1>).
303  //===========================================================
304  template<unsigned NNODE_1D>
306  const int& face_index, FaceElement* face_element_pt)
307  {
308  // Set the nodal dimension from the "bulk"
309  face_element_pt->set_nodal_dimension(this->node_pt(0)->ndim());
310 
311  // Set the pointer to the "bulk" element
312  face_element_pt->bulk_element_pt() = this;
313 
314 #ifdef OOMPH_HAS_MPI
315  // If the bulk element is halo then the face element must be too
316  // if (this->is_halo())
317  {
318  face_element_pt->set_halo(Non_halo_proc_ID);
319  }
320 #endif
321 
322  // Resize the storage for the original number of values at
323  // NNODE_1D nodes of the FaceElement
324  face_element_pt->nbulk_value_resize(NNODE_1D);
325 
326  // Resize the storage for the bulk node numbers corresponding
327  // to the NNODE_1D nodes of the FaceElement
328  face_element_pt->bulk_node_number_resize(NNODE_1D);
329 
330  // Set the face index in the face element
331  // The faces are
332  // +1 East
333  // -1 West
334  // +2 North
335  // -2 South
336 
337  // Set the face index in the face element
338  face_element_pt->face_index() = face_index;
339 
340  // Now set up the node pointers
341  // =================================
342  // The convention here is that interior_tangent X tangent X tangent
343  // is the OUTWARD normal
344  switch (face_index)
345  {
346  unsigned bulk_number;
347  // West face, normal sign is positive
348  case (-1):
349  // Set the pointer to the bulk coordinate translation scheme
350  face_element_pt->face_to_bulk_coordinate_fct_pt() =
352 
353  // Set the pointer to the derivative mappings
354  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
356 
357  for (unsigned i = 0; i < NNODE_1D; i++)
358  {
359  bulk_number = i * NNODE_1D;
360  face_element_pt->node_pt(i) = this->node_pt(bulk_number);
361  face_element_pt->bulk_node_number(i) = bulk_number;
362  face_element_pt->normal_sign() = 1;
363  // Set the number of values originally stored at this node
364  face_element_pt->nbulk_value(i) = this->required_nvalue(bulk_number);
365  }
366  break;
367  // South face, normal sign is positive
368  case (-2):
369  // Set the pointer to the bulk coordinate translation scheme
370  face_element_pt->face_to_bulk_coordinate_fct_pt() =
372 
373  // Set the pointer to the derivative mappings
374  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
376 
377  for (unsigned i = 0; i < NNODE_1D; i++)
378  {
379  bulk_number = i;
380  face_element_pt->node_pt(i) = this->node_pt(bulk_number);
381  face_element_pt->bulk_node_number(i) = bulk_number;
382  face_element_pt->normal_sign() = 1;
383  // Set the number of values originally stored at this node
384  face_element_pt->nbulk_value(i) = this->required_nvalue(bulk_number);
385  }
386  break;
387  // East face, normal sign is negative
388  case (1):
389  // Set the pointer to the bulk coordinate translation scheme
390  face_element_pt->face_to_bulk_coordinate_fct_pt() =
392 
393  // Set the pointer to the derivative mappings
394  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
396 
397  for (unsigned i = 0; i < NNODE_1D; i++)
398  {
399  bulk_number = NNODE_1D * i + NNODE_1D - 1;
400  face_element_pt->node_pt(i) = this->node_pt(bulk_number);
401  face_element_pt->bulk_node_number(i) = bulk_number;
402  face_element_pt->normal_sign() = -1;
403  // Set the number of values originally stored at this node
404  face_element_pt->nbulk_value(i) = this->required_nvalue(bulk_number);
405  }
406  break;
407  // North face, normal sign is negative
408  case (2):
409  // Set the pointer to the bulk coordinate translation scheme
410  face_element_pt->face_to_bulk_coordinate_fct_pt() =
412 
413  // Set the pointer to the derivative mappings
414  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
416 
417  for (unsigned i = 0; i < NNODE_1D; i++)
418  {
419  bulk_number = NNODE_1D * (NNODE_1D - 1) + i;
420  face_element_pt->node_pt(i) = this->node_pt(bulk_number);
421  face_element_pt->bulk_node_number(i) = bulk_number;
422  face_element_pt->normal_sign() = -1;
423  // Set the number of values originally stored at this node
424  face_element_pt->nbulk_value(i) = this->required_nvalue(bulk_number);
425  }
426  break;
427 
428  // Now cover the other cases
429  default:
430  std::ostringstream error_message;
431  error_message
432  << "Face index should only take the values +/- 1 or +/- 2,"
433  << " not " << face_index << std::endl;
434  throw OomphLibError(error_message.str(),
435  OOMPH_CURRENT_FUNCTION,
436  OOMPH_EXCEPTION_LOCATION);
437  }
438  }
439 
440 
441  /// ///////////////////////////////////////////////////////////////////////
442  /// 3D QLegendreElements
443  /// ///////////////////////////////////////////////////////////////////////
444 
445  //=======================================================================
446  /// Assign the static integral
447  //=======================================================================
448  template<unsigned NNODE_1D>
450 
451  //=======================================================================
452  /// The output function for general 1D QSpectralElements
453  //=======================================================================
454  template<unsigned NNODE_1D>
455  void QSpectralElement<3, NNODE_1D>::output(std::ostream& outfile)
456  {
457  // Tecplot header info
458  outfile << "ZONE I=" << NNODE_1D << ", J=" << NNODE_1D << ", K=" << NNODE_1D
459  << std::endl;
460 
461  // Find the dimension of the nodes
462  unsigned n_dim = this->nodal_dimension();
463 
464  // Loop over element nodes
465  for (unsigned l3 = 0; l3 < NNODE_1D; l3++)
466  {
467  for (unsigned l2 = 0; l2 < NNODE_1D; l2++)
468  {
469  for (unsigned l1 = 0; l1 < NNODE_1D; l1++)
470  {
471  unsigned l = l3 * NNODE_1D * NNODE_1D + l2 * NNODE_1D + l1;
472 
473  // Loop over the dimensions and output the position
474  for (unsigned i = 0; i < n_dim; i++)
475  {
476  outfile << this->node_pt(l)->x(i) << " ";
477  }
478  // Find out how many data values at the node
479  unsigned initial_nvalue = this->node_pt(l)->nvalue();
480  // Loop over the data and output whether pinned or not
481  for (unsigned i = 0; i < initial_nvalue; i++)
482  {
483  outfile << this->node_pt(l)->is_pinned(i) << " ";
484  }
485  outfile << std::endl;
486  }
487  }
488  }
489  outfile << std::endl;
490  }
491 
492  //=======================================================================
493  /// The output function for n_plot points in each coordinate direction
494  //=======================================================================
495  template<unsigned NNODE_1D>
496  void QSpectralElement<3, NNODE_1D>::output(std::ostream& outfile,
497  const unsigned& n_plot)
498  {
499  // Local variables
500  Vector<double> s(3);
501 
502  // Tecplot header info
503  outfile << "ZONE I=" << n_plot << ", J=" << n_plot << ", K=" << n_plot
504  << std::endl;
505 
506  // Find the dimension of the first node
507  unsigned n_dim = this->nodal_dimension();
508 
509  // Loop over element nodes
510  for (unsigned l3 = 0; l3 < n_plot; l3++)
511  {
512  s[2] = -1.0 + l3 * 2.0 / (n_plot - 1);
513  for (unsigned l2 = 0; l2 < n_plot; l2++)
514  {
515  s[1] = -1.0 + l2 * 2.0 / (n_plot - 1);
516  for (unsigned l1 = 0; l1 < n_plot; l1++)
517  {
518  s[0] = -1.0 + l1 * 2.0 / (n_plot - 1);
519 
520  // Output the coordinates
521  for (unsigned i = 0; i < n_dim; i++)
522  {
523  outfile << this->interpolated_x(s, i) << " ";
524  }
525  outfile << std::endl;
526  }
527  }
528  }
529  outfile << std::endl;
530  }
531 
532 
533  //=======================================================================
534  /// Function to setup geometrical information for lower-dimensional
535  /// FaceElements (which are of type QElement<3,NNODE_1D>).
536  //=======================================================================
537  template<unsigned NNODE_1D>
539  const int& face_index, FaceElement* face_element_pt)
540  {
541  oomph_info << " WARNING UNTESTED CODE" << std::endl;
542 
543  // Set the nodal dimension from the "bulk"
544  face_element_pt->set_nodal_dimension(this->node_pt(0)->ndim());
545 
546  // Set the pointer to the orginal "bulk" element
547  face_element_pt->bulk_element_pt() = this;
548 
549 #ifdef OOMPH_HAS_MPI
550  // If the bulk element is halo then the face element must be too
551  // if (this->is_halo())
552  {
553  face_element_pt->set_halo(Non_halo_proc_ID);
554  }
555 #endif
556 
557  // Resize storage for the number of values originally stored
558  // at the face element's NNODE_1D*NNODE_1D nodes.
559  face_element_pt->nbulk_value_resize(NNODE_1D * NNODE_1D);
560 
561  // Set the face index in the element
562  // The faces are
563  // -3 : BACK (OLD: Bottom
564  // -2 : DOWN (OLD: Front
565  // -1 : LEFT (OLD: Left Side
566  // 1 : RIGHT (OLD: Right Side
567  // 2 : UP (OLD: Back
568  // 3 : FRONT (OLD: Top
569 
570  face_element_pt->face_index() = face_index;
571 
572  // Now set up the node pointers and the normal vectors
573  switch (face_index)
574  {
575  // BACK
576  //-----
577  case -3:
578  // Set the pointer to the bulk coordinate translation scheme
579  face_element_pt->face_to_bulk_coordinate_fct_pt() =
581 
582  // Set the pointer to the derivative mappings
583  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
585 
586  // Copy nodes
587  for (unsigned i = 0; i < (NNODE_1D * NNODE_1D); i++)
588  {
589  face_element_pt->node_pt(i) = this->node_pt(i);
590  }
591  // Outer unit normal is negative of cross product of two in plane
592  // tangent vectors
593  face_element_pt->normal_sign() = -1;
594 
595  break;
596 
597  // FRONT
598  //------
599  case 3:
600 
601  // Set the pointer to the bulk coordinate translation scheme
602  face_element_pt->face_to_bulk_coordinate_fct_pt() =
604 
605  // Set the pointer to the derivative mappings
606  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
608 
609  // Copy nodes
610  for (unsigned i = 0; i < (NNODE_1D * NNODE_1D); i++)
611  {
612  face_element_pt->node_pt(i) =
613  this->node_pt(i + (NNODE_1D * NNODE_1D) * (NNODE_1D - 1));
614  }
615  // Outer unit normal is cross product of two in plane
616  // tangent vectors
617  face_element_pt->normal_sign() = 1;
618 
619 
620  break;
621 
622  // DOWN:
623  //------
624  case -2:
625 
626  {
627  // Set the pointer to the bulk coordinate translation scheme
628  face_element_pt->face_to_bulk_coordinate_fct_pt() =
630 
631  // Set the pointer to the derivative mappings
632  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
634 
635  // Copy nodes
636  unsigned count = 0;
637  for (unsigned i = 0; i < NNODE_1D; i++)
638  {
639  for (unsigned j = 0; j < NNODE_1D; j++)
640  {
641  face_element_pt->node_pt(count) =
642  this->node_pt(j + i * (NNODE_1D * NNODE_1D));
643  count++;
644  }
645  }
646 
647  // Outer unit normal is cross product of two in plane
648  // tangent vectors
649  face_element_pt->normal_sign() = 1;
650  }
651  break;
652 
653 
654  // UP:
655  //----
656  case 2:
657 
658  {
659  // Set the pointer to the bulk coordinate translation scheme
660  face_element_pt->face_to_bulk_coordinate_fct_pt() =
662 
663  // Set the pointer to the derivative mappings
664  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
666 
667  // Copy nodes
668  unsigned count = 0;
669  for (unsigned i = 0; i < NNODE_1D; i++)
670  {
671  for (unsigned j = 0; j < NNODE_1D; j++)
672  {
673  face_element_pt->node_pt(count) = this->node_pt(
674  j + i * (NNODE_1D * NNODE_1D) + (NNODE_1D * (NNODE_1D - 1)));
675  count++;
676  }
677  }
678 
679  // Outer unit normal is negative of cross product of two in plane
680  // tangent vectors
681  face_element_pt->normal_sign() = -1;
682  }
683  break;
684 
685  // LEFT:
686  //------
687  case -1:
688 
689  {
690  // Set the pointer to the bulk coordinate translation scheme
691  face_element_pt->face_to_bulk_coordinate_fct_pt() =
693 
694  // Set the pointer to the derivative mappings
695  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
697 
698  // Copy nodes
699  unsigned count = 0;
700  for (unsigned i = 0; i < NNODE_1D; i++)
701  {
702  for (unsigned j = 0; j < NNODE_1D; j++)
703  {
704  unsigned jj = j * NNODE_1D + i * (NNODE_1D * NNODE_1D);
705  face_element_pt->node_pt(count) = this->node_pt(jj);
706  count++;
707  }
708  }
709 
710  // Outer unit normal is negative of cross product of two in plane
711  // tangent vectors
712  face_element_pt->normal_sign() = -1;
713  }
714  break;
715 
716 
717  // RIGHT:
718  //-------
719  case 1:
720 
721  {
722  // Set the pointer to the bulk coordinate translation scheme
723  face_element_pt->face_to_bulk_coordinate_fct_pt() =
725 
726  // Set the pointer to the derivative mappings
727  face_element_pt->bulk_coordinate_derivatives_fct_pt() =
729 
730  // Copy nodes
731  unsigned count = 0;
732  for (unsigned i = 0; i < NNODE_1D; i++)
733  {
734  for (unsigned j = 0; j < NNODE_1D; j++)
735  {
736  unsigned jj =
737  j * NNODE_1D + i * (NNODE_1D * NNODE_1D) + (NNODE_1D - 1);
738  face_element_pt->node_pt(count) = this->node_pt(jj);
739  count++;
740  }
741  }
742 
743  // Outer unit normal is cross product of two in plane
744  // tangent vectors
745  face_element_pt->normal_sign() = 1;
746  }
747  break;
748 
749 
750  // Cover all other cases
751  default:
752  std::ostringstream error_message;
753  error_message
754  << "Face index should only take the values +/- 1, +/- 2 or +/- 3,"
755  << " not " << face_index << std::endl;
756  throw OomphLibError(error_message.str(),
757  OOMPH_CURRENT_FUNCTION,
758  OOMPH_EXCEPTION_LOCATION);
759  } // end switch
760  }
761 
762 
763  template class QSpectralElement<1, 2>;
764  template class QSpectralElement<1, 3>;
765  template class QSpectralElement<1, 4>;
766  template class QSpectralElement<1, 5>;
767  template class QSpectralElement<1, 6>;
768  template class QSpectralElement<1, 7>;
769  template class QSpectralElement<1, 8>;
770  template class QSpectralElement<1, 9>;
771  template class QSpectralElement<1, 10>;
772  template class QSpectralElement<1, 11>;
773  template class QSpectralElement<1, 12>;
774  template class QSpectralElement<1, 13>;
775  template class QSpectralElement<1, 14>;
776 
777  template class QSpectralElement<2, 2>;
778  template class QSpectralElement<2, 3>;
779  template class QSpectralElement<2, 4>;
780  template class QSpectralElement<2, 5>;
781  template class QSpectralElement<2, 6>;
782  template class QSpectralElement<2, 7>;
783  template class QSpectralElement<2, 8>;
784 
785  template class QSpectralElement<3, 2>;
786  template class QSpectralElement<3, 3>;
787  template class QSpectralElement<3, 4>;
788  template class QSpectralElement<3, 5>;
789  template class QSpectralElement<3, 6>;
790  template class QSpectralElement<3, 7>;
791  template class QSpectralElement<3, 8>;
792 
793 } // namespace oomph
static char t char * s
Definition: cfortran.h:568
cstr elem_len * i
Definition: cfortran.h:603
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
Definition: elements.h:4338
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:4755
void bulk_node_number_resize(const unsigned &i)
Resize the storage for the bulk node numbers.
Definition: elements.h:4818
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
Definition: elements.h:4626
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:4845
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition: elements.h:4735
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:4770
int & normal_sign()
Sign of outer unit normal (relative to cross-products of tangent vectors in the corresponding "bulk" ...
Definition: elements.h:4612
unsigned & bulk_node_number(const unsigned &n)
Return the bulk node number that corresponds to the n-th local node number.
Definition: elements.h:4825
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:4860
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:1390
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
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:1151
static std::map< unsigned, Vector< double > > z
An OomphLibError object which should be thrown when an run-time error is encountered....
static GaussLobattoLegendre< 1, NNODE_1D > integral
Default integration rule: Gaussian integration of same 'order' as the element.
General QLegendreElement class.
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
Definition: shape.h:76
void output()
Doc the command line arguments.
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
Definition: shape.h:564
void faces0(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for both faces – the bulk coordinate is fixed on both.
void face1(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = 1.0.
void face0(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the face s0 = -1.0.
void faces1(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for the north and south faces, along which s1 is fixed.
void faces0(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for the east and west faces, along which s0 is fixed.
void face2(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the east face (s0 = 1.0)
void face1(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the south face (s1 = -1.0)
void face0(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the west face (s0 = -1.0)
void face3(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the north face (s1 = 1.0)
void faces2(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for the left and right faces, along which s2 is fixed.
void faces0(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for the back and front faces, along which s0 is fixed.
void faces1(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction)
Function for the up and down faces, along which s1 is fixed.
void face4(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the up face (s1 = 1.0)
void face1(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the down face (s1 = -1.0)
void face2(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the back face (s2 = -1.0)
void face0(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the left face (s0 = -1.0)
void face5(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the front face (s2 = 1.0)
void face3(const Vector< double > &s, Vector< double > &s_bulk)
The translation scheme for the right face (s0 = 1.0)
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
OomphInfo oomph_info
Single (global) instantiation of the OomphInfo object – this is used throughout the library as a "rep...