Reference documentation for deal.II version 8.4.2
geometry_info.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2015 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/geometry_info.h>
17 #include <deal.II/base/tensor.h>
18 
19 DEAL_II_NAMESPACE_OPEN
20 
21 
22 unsigned int
24 {
25  return 0;
26 }
27 
28 
29 
30 template <int dim> const unsigned int GeometryInfo<dim>::max_children_per_cell;
31 template <int dim> const unsigned int GeometryInfo<dim>::faces_per_cell;
32 template <int dim> const unsigned int GeometryInfo<dim>::max_children_per_face;
33 template <int dim> const unsigned int GeometryInfo<dim>::vertices_per_cell;
34 template <int dim> const unsigned int GeometryInfo<dim>::vertices_per_face;
35 template <int dim> const unsigned int GeometryInfo<dim>::lines_per_face;
36 template <int dim> const unsigned int GeometryInfo<dim>::quads_per_face;
37 template <int dim> const unsigned int GeometryInfo<dim>::lines_per_cell;
38 template <int dim> const unsigned int GeometryInfo<dim>::quads_per_cell;
39 template <int dim> const unsigned int GeometryInfo<dim>::hexes_per_cell;
40 
41 
42 using namespace numbers;
43 
44 // make sure that also the icc compiler defines (and not only declares)
45 // these variables
46 namespace internal
47 {
48  void foo (const unsigned int *) {}
49 
50  template <int dim>
51  void define_variables ()
52  {
54  }
55 
56  template void define_variables<2> ();
57  template void define_variables<3> ();
58  template void define_variables<4> ();
59 }
60 
61 
62 
63 template <>
64 const unsigned int
66  = { 0, 0 };
67 
68 template <>
69 const unsigned int
71  = { 0, 0, 1, 1 };
72 
73 template <>
74 const unsigned int
76  = { 0, 0, 1, 1, 2, 2 };
77 
78 template <>
79 const unsigned int
81  = { 0, 0, 1, 1, 2, 2, 3, 3 };
82 
83 
84 
85 template <>
86 const int
88  = { -1, 1 };
89 
90 template <>
91 const int
93  = { -1, 1, -1, 1 };
94 
95 template <>
96 const int
98  = { -1, 1, -1, 1, -1, 1 };
99 
100 template <>
101 const int
103  = { -1, 1, -1, 1, -1, 1, -1, 1 };
104 
105 
106 
107 template <>
108 const unsigned int
110  = { 1, 0 };
111 
112 template <>
113 const unsigned int
115  = { 1, 0, 3, 2 };
116 
117 template <>
118 const unsigned int
120  = { 1, 0, 3, 2, 5, 4 };
121 
122 template <>
123 const unsigned int
125  = { 1, 0, 3, 2, 5, 4, 7, 6 };
126 
127 
128 
129 template <>
131  = { 0, 1};
132 
133 template <>
135  = { 0, 1, 3, 2};
136 
137 template <>
139  = { 0, 1, 5, 4, 2, 3, 7, 6};
140 
141 template <>
143  = { invalid_unsigned_int,
144  invalid_unsigned_int,
145  invalid_unsigned_int,
146  invalid_unsigned_int,
147  invalid_unsigned_int,
148  invalid_unsigned_int,
149  invalid_unsigned_int,
150  invalid_unsigned_int,
151  invalid_unsigned_int,
152  invalid_unsigned_int,
153  invalid_unsigned_int,
154  invalid_unsigned_int,
155  invalid_unsigned_int,
156  invalid_unsigned_int,
157  invalid_unsigned_int,
158  invalid_unsigned_int
159  };
160 
161 
162 template <>
164  = { 0, 1};
165 
166 template <>
168  = { 0, 2, 1, 3};
169 
170 template <>
172  = { 0, 4, 2, 6, 1, 5, 3, 7};
173 
174 template <>
176  = { invalid_unsigned_int,
177  invalid_unsigned_int,
178  invalid_unsigned_int,
179  invalid_unsigned_int,
180  invalid_unsigned_int,
181  invalid_unsigned_int,
182  invalid_unsigned_int,
183  invalid_unsigned_int,
184  invalid_unsigned_int,
185  invalid_unsigned_int,
186  invalid_unsigned_int,
187  invalid_unsigned_int,
188  invalid_unsigned_int,
189  invalid_unsigned_int,
190  invalid_unsigned_int,
191  invalid_unsigned_int
192  };
193 
194 template <>
195 const unsigned int GeometryInfo<1>::vertex_to_face
197 = { { 0 },
198  { 1 }
199 };
200 
201 template <>
202 const unsigned int GeometryInfo<2>::vertex_to_face
204 = { { 0, 2 },
205  { 1, 2 },
206  { 0, 3 },
207  { 1, 3 }
208 };
209 
210 template <>
211 const unsigned int GeometryInfo<3>::vertex_to_face
213 = { { 0, 2, 4 },
214  { 1, 2, 4 },
215  { 0, 3, 4 },
216  { 1, 3, 4 },
217  { 0, 2, 5 },
218  { 1, 2, 5 },
219  { 0, 3, 5 },
220  { 1, 3, 5 }
221 };
222 
223 template <>
224 const unsigned int GeometryInfo<4>::vertex_to_face
226 = { { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
227  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
228  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
229  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
230  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
231  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
232  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
233  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
234  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
235  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
236  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
237  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
238  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
239  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
240  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int },
241  { invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int, invalid_unsigned_int }
242 };
243 
244 
245 template<int dim>
246 unsigned int
248 {
249  static const unsigned int n_children[RefinementCase<3>::cut_xyz+1]=
250  {0, 2, 2, 4, 2, 4, 4, 8};
251 
252  return n_children[ref_case];
253 }
254 
255 
256 template<>
257 unsigned int
259 {
260  Assert(false, ExcImpossibleInDim(1));
261  return 0;
262 }
263 
264 
265 
266 template<>
267 unsigned int
269 {
270  return (subface_case == internal::SubfaceCase<2>::case_x) ? 2 : 0;
271 }
272 
273 
274 
275 template<>
276 unsigned int
278 {
279  static const unsigned int nsubs[internal::SubfaceCase<3>::case_isotropic+1]=
280  {0, 2, 3, 3, 4, 2, 3, 3, 4, 4};
281  return nsubs[subface_case];
282 }
283 
284 
285 template<>
286 double
288  const unsigned int)
289 {
290  return 1;
291 }
292 
293 
294 template<>
295 double
297  const unsigned int)
298 {
299  const unsigned int dim=2;
300 
301  double ratio=1;
302  switch (subface_case)
303  {
305  // Here, an
306  // Assert(false,ExcInternalError())
307  // would be the right
308  // choice, but
309  // unfortunately the
310  // current function is
311  // also called for faces
312  // without children (see
313  // tests/fe/mapping.cc).
314 // Assert(false, ExcMessage("Face has no subfaces."));
315  // Furthermore, assign
316  // following value as
317  // otherwise the
318  // bits/volume_x tests
319  // break
321  break;
323  ratio=0.5;
324  break;
325  default:
326  // there should be no
327  // cases left
328  Assert(false, ExcInternalError());
329  break;
330  }
331 
332  return ratio;
333 }
334 
335 
336 template<>
337 double
339  const unsigned int subface_no)
340 {
341  const unsigned int dim=3;
342 
343  double ratio=1;
344  switch (subface_case)
345  {
347  // Here, an
348  // Assert(false,ExcInternalError())
349  // would be the right
350  // choice, but
351  // unfortunately the
352  // current function is
353  // also called for faces
354  // without children (see
355  // tests/bits/mesh_3d_16.cc). Add
356  // following switch to
357  // avoid diffs in
358  // tests/bits/mesh_3d_16
360  break;
363  ratio=0.5;
364  break;
368  ratio=0.25;
369  break;
372  if (subface_no<2)
373  ratio=0.25;
374  else
375  ratio=0.5;
376  break;
379  if (subface_no==0)
380  ratio=0.5;
381  else
382  ratio=0.25;
383  break;
384  default:
385  // there should be no
386  // cases left
387  Assert(false, ExcInternalError());
388  break;
389  }
390 
391  return ratio;
392 }
393 
394 
395 
396 template<>
399  const unsigned int,
400  const bool,
401  const bool,
402  const bool)
403 {
404  Assert(false, ExcImpossibleInDim(1));
405 
407 }
408 
409 
410 template<>
412 GeometryInfo<2>::face_refinement_case(const RefinementCase<2> &cell_refinement_case,
413  const unsigned int face_no,
414  const bool,
415  const bool,
416  const bool)
417 {
418  const unsigned int dim=2;
419  Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
420  ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
422  ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
423 
424  static const RefinementCase<dim-1>
426  {
427  {
428  RefinementCase<dim-1>::no_refinement, // no_refinement
429  RefinementCase<dim-1>::no_refinement
430  },
431 
432  {
433  RefinementCase<dim-1>::no_refinement,
434  RefinementCase<dim-1>::cut_x
435  },
436 
437  {
438  RefinementCase<dim-1>::cut_x,
439  RefinementCase<dim-1>::no_refinement
440  },
441 
442  {
443  RefinementCase<dim-1>::cut_x, // cut_xy
444  RefinementCase<dim-1>::cut_x
445  }
446  };
447 
448  return ref_cases[cell_refinement_case][face_no/2];
449 }
450 
451 
452 template<>
454 GeometryInfo<3>::face_refinement_case(const RefinementCase<3> &cell_refinement_case,
455  const unsigned int face_no,
456  const bool face_orientation,
457  const bool /*face_flip*/,
458  const bool face_rotation)
459 {
460  const unsigned int dim=3;
461  Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
462  ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
464  ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
465 
466  static const RefinementCase<dim-1>
468  {
469  {
470  RefinementCase<dim-1>::no_refinement, // no_refinement
471  RefinementCase<dim-1>::no_refinement,
472  RefinementCase<dim-1>::no_refinement
473  },
474 
475  {
476  RefinementCase<dim-1>::no_refinement, // cut_x
477  RefinementCase<dim-1>::cut_y,
478  RefinementCase<dim-1>::cut_x
479  },
480 
481  {
482  RefinementCase<dim-1>::cut_x, // cut_y
483  RefinementCase<dim-1>::no_refinement,
484  RefinementCase<dim-1>::cut_y
485  },
486 
487  {
488  RefinementCase<dim-1>::cut_x, // cut_xy
489  RefinementCase<dim-1>::cut_y,
490  RefinementCase<dim-1>::cut_xy
491  },
492 
493  {
494  RefinementCase<dim-1>::cut_y, // cut_z
495  RefinementCase<dim-1>::cut_x,
496  RefinementCase<dim-1>::no_refinement
497  },
498 
499  {
500  RefinementCase<dim-1>::cut_y, // cut_xz
501  RefinementCase<dim-1>::cut_xy,
502  RefinementCase<dim-1>::cut_x
503  },
504 
505  {
506  RefinementCase<dim-1>::cut_xy, // cut_yz
507  RefinementCase<dim-1>::cut_x,
508  RefinementCase<dim-1>::cut_y
509  },
510 
511  {
512  RefinementCase<dim-1>::cut_xy, // cut_xyz
513  RefinementCase<dim-1>::cut_xy,
514  RefinementCase<dim-1>::cut_xy
515  },
516  };
517 
518  const RefinementCase<dim-1> ref_case=ref_cases[cell_refinement_case][face_no/2];
519 
520  static const RefinementCase<dim-1> flip[4]=
521  {
522  RefinementCase<dim-1>::no_refinement,
523  RefinementCase<dim-1>::cut_y,
524  RefinementCase<dim-1>::cut_x,
525  RefinementCase<dim-1>::cut_xy
526  };
527 
528  // correct the ref_case for face_orientation
529  // and face_rotation. for face_orientation,
530  // 'true' is the default value whereas for
531  // face_rotation, 'false' is standard. If
532  // <tt>face_rotation==face_orientation</tt>,
533  // then one of them is non-standard and we
534  // have to swap cut_x and cut_y, otherwise no
535  // change is necessary. face_flip has no
536  // influence. however, in order to keep the
537  // interface consistent with other functions,
538  // we still include it as an argument to this
539  // function
540  return (face_orientation==face_rotation) ? flip[ref_case] : ref_case;
541 }
542 
543 
544 
545 template<>
547 GeometryInfo<1>::line_refinement_case(const RefinementCase<1> &cell_refinement_case,
548  const unsigned int line_no)
549 {
550  (void)line_no;
551  const unsigned int dim = 1;
552  (void)dim;
553  Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
554  ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
556  ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
557 
558  return cell_refinement_case;
559 }
560 
561 
562 template<>
564 GeometryInfo<2>::line_refinement_case(const RefinementCase<2> &cell_refinement_case,
565  const unsigned int line_no)
566 {
567  // Assertions are in face_refinement_case()
568  return face_refinement_case(cell_refinement_case, line_no);
569 }
570 
571 
572 template<>
574 GeometryInfo<3>::line_refinement_case(const RefinementCase<3> &cell_refinement_case,
575  const unsigned int line_no)
576 {
577  const unsigned int dim=3;
578  Assert(cell_refinement_case<RefinementCase<dim>::isotropic_refinement+1,
579  ExcIndexRange(cell_refinement_case, 0, RefinementCase<dim>::isotropic_refinement+1));
581  ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
582 
583  // array indicating, which simple refine
584  // case cuts a line in direction x, y or
585  // z. For example, cut_y and everything
586  // containing cut_y (cut_xy, cut_yz,
587  // cut_xyz) cuts lines, which are in y
588  // direction.
589  static const RefinementCase<dim>
590  cut_one[dim] =
591  {
595  };
596 
597  // order the direction of lines
598  // 0->x, 1->y, 2->z
599  static const unsigned int direction[lines_per_cell]=
600  {1,1,0,0,1,1,0,0,2,2,2,2};
601 
602  return ((cell_refinement_case & cut_one[direction[line_no]]) ?
604 }
605 
606 
607 
608 template<>
611  const unsigned int,
612  const bool,
613  const bool,
614  const bool)
615 {
616  const unsigned int dim = 1;
617  Assert(false, ExcImpossibleInDim(dim));
618 
620 }
621 
622 
623 template<>
626  const unsigned int face_no,
627  const bool,
628  const bool,
629  const bool)
630 {
631  const unsigned int dim = 2;
633  ExcIndexRange(face_refinement_case, 0, RefinementCase<dim-1>::isotropic_refinement+1));
635  ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
636 
637  if (face_refinement_case==RefinementCase<dim>::cut_x)
639  else
641 }
642 
643 
644 template<>
647  const unsigned int face_no,
648  const bool face_orientation,
649  const bool /*face_flip*/,
650  const bool face_rotation)
651 {
652  const unsigned int dim=3;
654  ExcIndexRange(face_refinement_case, 0, RefinementCase<dim-1>::isotropic_refinement+1));
656  ExcIndexRange(face_no, 0, GeometryInfo<dim>::faces_per_cell));
657 
658  static const RefinementCase<2> flip[4]=
659  {
664  };
665 
666  // correct the face_refinement_case for
667  // face_orientation and face_rotation. for
668  // face_orientation, 'true' is the default
669  // value whereas for face_rotation, 'false'
670  // is standard. If
671  // <tt>face_rotation==face_orientation</tt>,
672  // then one of them is non-standard and we
673  // have to swap cut_x and cut_y, otherwise no
674  // change is necessary. face_flip has no
675  // influence. however, in order to keep the
676  // interface consistent with other functions,
677  // we still include it as an argument to this
678  // function
679  const RefinementCase<dim-1> std_face_ref = (face_orientation==face_rotation) ? flip[face_refinement_case] : face_refinement_case;
680 
681  static const RefinementCase<dim> face_to_cell[3][4]=
682  {
683  {
684  RefinementCase<dim>::no_refinement, // faces 0 and 1
685  RefinementCase<dim>::cut_y, // cut_x in face 0 means cut_y for the cell
688  },
689 
690  {
691  RefinementCase<dim>::no_refinement, // faces 2 and 3 (note that x and y are "exchanged on faces 2 and 3")
695  },
696 
697  {
698  RefinementCase<dim>::no_refinement, // faces 4 and 5
702  }
703  };
704 
705  return face_to_cell[face_no/2][std_face_ref];
706 }
707 
708 
709 
710 template<>
713 {
714  (void)line_no;
715  Assert(line_no==0, ExcIndexRange(line_no,0,1));
716 
718 }
719 
720 
721 template<>
724 {
725  const unsigned int dim = 2;
726  (void)dim;
728  ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
729 
730  return (line_no/2) ? RefinementCase<2>::cut_x : RefinementCase<2>::cut_y;
731 }
732 
733 
734 template<>
737 {
738  const unsigned int dim=3;
740  ExcIndexRange(line_no, 0, GeometryInfo<dim>::lines_per_cell));
741 
742  static const RefinementCase<dim> ref_cases[6]=
743  {
744  RefinementCase<dim>::cut_y, // lines 0 and 1
745  RefinementCase<dim>::cut_x, // lines 2 and 3
746  RefinementCase<dim>::cut_y, // lines 4 and 5
747  RefinementCase<dim>::cut_x, // lines 6 and 7
748  RefinementCase<dim>::cut_z, // lines 8 and 9
749  RefinementCase<dim>::cut_z
750  }; // lines 10 and 11
751 
752  return ref_cases[line_no/2];
753 }
754 
755 
756 
757 template <>
758 unsigned int
759 GeometryInfo<3>::standard_to_real_face_vertex(const unsigned int vertex,
760  const bool face_orientation,
761  const bool face_flip,
762  const bool face_rotation)
763 {
765  ExcIndexRange(vertex,0,GeometryInfo<3>::vertices_per_face));
766 
767  // set up a table to make sure that
768  // we handle non-standard faces correctly
769  //
770  // so set up a table that for each vertex (of
771  // a quad in standard position) describes
772  // which vertex to take
773  //
774  // first index: four vertices 0...3
775  //
776  // second index: face_orientation; 0:
777  // opposite normal, 1: standard
778  //
779  // third index: face_flip; 0: standard, 1:
780  // face rotated by 180 degrees
781  //
782  // forth index: face_rotation: 0: standard,
783  // 1: face rotated by 90 degrees
784 
785  static const unsigned int vertex_translation[4][2][2][2] =
786  {
787  { { { 0, 2 }, // vertex 0, face_orientation=false, face_flip=false, face_rotation=false and true
788  { 3, 1 }
789  }, // vertex 0, face_orientation=false, face_flip=true, face_rotation=false and true
790  { { 0, 2 }, // vertex 0, face_orientation=true, face_flip=false, face_rotation=false and true
791  { 3, 1 }
792  }
793  },// vertex 0, face_orientation=true, face_flip=true, face_rotation=false and true
794 
795  { { { 2, 3 }, // vertex 1 ...
796  { 1, 0 }
797  },
798  { { 1, 0 },
799  { 2, 3 }
800  }
801  },
802 
803  { { { 1, 0 }, // vertex 2 ...
804  { 2, 3 }
805  },
806  { { 2, 3 },
807  { 1, 0 }
808  }
809  },
810 
811  { { { 3, 1 }, // vertex 3 ...
812  { 0, 2 }
813  },
814  { { 3, 1 },
815  { 0, 2 }
816  }
817  }
818  };
819 
820  return vertex_translation[vertex][face_orientation][face_flip][face_rotation];
821 }
822 
823 
824 
825 template <int dim>
826 unsigned int
828  const bool,
829  const bool,
830  const bool)
831 {
832  Assert(dim>1, ExcImpossibleInDim(dim));
834  ExcIndexRange(vertex,0,GeometryInfo<dim>::vertices_per_face));
835  return vertex;
836 }
837 
838 
839 
840 template <>
841 unsigned int
842 GeometryInfo<3>::real_to_standard_face_vertex(const unsigned int vertex,
843  const bool face_orientation,
844  const bool face_flip,
845  const bool face_rotation)
846 {
848  ExcIndexRange(vertex,0,GeometryInfo<3>::vertices_per_face));
849 
850  // set up a table to make sure that
851  // we handle non-standard faces correctly
852  //
853  // so set up a table that for each vertex (of
854  // a quad in standard position) describes
855  // which vertex to take
856  //
857  // first index: four vertices 0...3
858  //
859  // second index: face_orientation; 0:
860  // opposite normal, 1: standard
861  //
862  // third index: face_flip; 0: standard, 1:
863  // face rotated by 180 degrees
864  //
865  // forth index: face_rotation: 0: standard,
866  // 1: face rotated by 90 degrees
867 
868  static const unsigned int vertex_translation[4][2][2][2] =
869  {
870  { { { 0, 2 }, // vertex 0, face_orientation=false, face_flip=false, face_rotation=false and true
871  { 3, 1 }
872  }, // vertex 0, face_orientation=false, face_flip=true, face_rotation=false and true
873  { { 0, 1 }, // vertex 0, face_orientation=true, face_flip=false, face_rotation=false and true
874  { 3, 2 }
875  }
876  },// vertex 0, face_orientation=true, face_flip=true, face_rotation=false and true
877 
878  { { { 2, 3 }, // vertex 1 ...
879  { 1, 0 }
880  },
881  { { 1, 3 },
882  { 2, 0 }
883  }
884  },
885 
886  { { { 1, 0 }, // vertex 2 ...
887  { 2, 3 }
888  },
889  { { 2, 0 },
890  { 1, 3 }
891  }
892  },
893 
894  { { { 3, 1 }, // vertex 3 ...
895  { 0, 2 }
896  },
897  { { 3, 2 },
898  { 0, 1 }
899  }
900  }
901  };
902 
903  return vertex_translation[vertex][face_orientation][face_flip][face_rotation];
904 }
905 
906 
907 
908 template <int dim>
909 unsigned int
911  const bool,
912  const bool,
913  const bool)
914 {
915  Assert(dim>1, ExcImpossibleInDim(dim));
917  ExcIndexRange(vertex,0,GeometryInfo<dim>::vertices_per_face));
918  return vertex;
919 }
920 
921 
922 
923 template <>
924 unsigned int
925 GeometryInfo<3>::standard_to_real_face_line(const unsigned int line,
926  const bool face_orientation,
927  const bool face_flip,
928  const bool face_rotation)
929 {
931  ExcIndexRange(line,0,GeometryInfo<3>::lines_per_face));
932 
933 
934  // make sure we handle
935  // non-standard faces correctly
936  //
937  // so set up a table that for each line (of a
938  // quad) describes which line to take
939  //
940  // first index: four lines 0...3
941  //
942  // second index: face_orientation; 0:
943  // opposite normal, 1: standard
944  //
945  // third index: face_flip; 0: standard, 1:
946  // face rotated by 180 degrees
947  //
948  // forth index: face_rotation: 0: standard,
949  // 1: face rotated by 90 degrees
950 
951  static const unsigned int line_translation[4][2][2][2] =
952  {
953  { { { 2, 0 }, // line 0, face_orientation=false, face_flip=false, face_rotation=false and true
954  { 3, 1 }
955  }, // line 0, face_orientation=false, face_flip=true, face_rotation=false and true
956  { { 0, 3 }, // line 0, face_orientation=true, face_flip=false, face_rotation=false and true
957  { 1, 2 }
958  }
959  },// line 0, face_orientation=true, face_flip=true, face_rotation=false and true
960 
961  { { { 3, 1 }, // line 1 ...
962  { 2, 0 }
963  },
964  { { 1, 2 },
965  { 0, 3 }
966  }
967  },
968 
969  { { { 0, 3 }, // line 2 ...
970  { 1, 2 }
971  },
972  { { 2, 0 },
973  { 3, 1 }
974  }
975  },
976 
977  { { { 1, 2 }, // line 3 ...
978  { 0, 3 }
979  },
980  { { 3, 1 },
981  { 2, 0 }
982  }
983  }
984  };
985 
986  return line_translation[line][face_orientation][face_flip][face_rotation];
987 }
988 
989 
990 
991 template <int dim>
992 unsigned int
994  const bool,
995  const bool,
996  const bool)
997 {
998  Assert(false, ExcNotImplemented());
999  return line;
1000 }
1001 
1002 
1003 
1004 template <>
1005 unsigned int
1006 GeometryInfo<3>::real_to_standard_face_line(const unsigned int line,
1007  const bool face_orientation,
1008  const bool face_flip,
1009  const bool face_rotation)
1010 {
1012  ExcIndexRange(line,0,GeometryInfo<3>::lines_per_face));
1013 
1014 
1015  // make sure we handle
1016  // non-standard faces correctly
1017  //
1018  // so set up a table that for each line (of a
1019  // quad) describes which line to take
1020  //
1021  // first index: four lines 0...3
1022  //
1023  // second index: face_orientation; 0:
1024  // opposite normal, 1: standard
1025  //
1026  // third index: face_flip; 0: standard, 1:
1027  // face rotated by 180 degrees
1028  //
1029  // forth index: face_rotation: 0: standard,
1030  // 1: face rotated by 90 degrees
1031 
1032  static const unsigned int line_translation[4][2][2][2] =
1033  {
1034  { { { 2, 0 }, // line 0, face_orientation=false, face_flip=false, face_rotation=false and true
1035  { 3, 1 }
1036  }, // line 0, face_orientation=false, face_flip=true, face_rotation=false and true
1037  { { 0, 2 }, // line 0, face_orientation=true, face_flip=false, face_rotation=false and true
1038  { 1, 3 }
1039  }
1040  },// line 0, face_orientation=true, face_flip=true, face_rotation=false and true
1041 
1042  { { { 3, 1 }, // line 1 ...
1043  { 2, 0 }
1044  },
1045  { { 1, 3 },
1046  { 0, 2 }
1047  }
1048  },
1049 
1050  { { { 0, 3 }, // line 2 ...
1051  { 1, 2 }
1052  },
1053  { { 2, 1 },
1054  { 3, 0 }
1055  }
1056  },
1057 
1058  { { { 1, 2 }, // line 3 ...
1059  { 0, 3 }
1060  },
1061  { { 3, 0 },
1062  { 2, 1 }
1063  }
1064  }
1065  };
1066 
1067  return line_translation[line][face_orientation][face_flip][face_rotation];
1068 }
1069 
1070 
1071 
1072 template <int dim>
1073 unsigned int
1075  const bool,
1076  const bool,
1077  const bool)
1078 {
1079  Assert(false, ExcNotImplemented());
1080  return line;
1081 }
1082 
1083 
1084 
1085 template <>
1086 unsigned int
1088  const unsigned int face,
1089  const unsigned int subface,
1090  const bool, const bool, const bool,
1091  const RefinementCase<0> &)
1092 {
1093  (void)subface;
1094  Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
1095  Assert (subface<max_children_per_face,
1096  ExcIndexRange(subface, 0, max_children_per_face));
1097 
1098  return face;
1099 }
1100 
1101 
1102 
1103 template <>
1104 unsigned int
1106  const unsigned int face,
1107  const unsigned int subface,
1108  const bool /*face_orientation*/,
1109  const bool face_flip,
1110  const bool /*face_rotation*/,
1111  const RefinementCase<1> &)
1112 {
1113  Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
1114  Assert (subface<max_children_per_face,
1115  ExcIndexRange(subface, 0, max_children_per_face));
1116 
1117  // always return the child adjacent to the specified
1118  // subface. if the face of a cell is not refined, don't
1119  // throw an assertion but deliver the child adjacent to
1120  // the face nevertheless, i.e. deliver the child of
1121  // this cell adjacent to the subface of a possibly
1122  // refined neighbor. this simplifies setting neighbor
1123  // information in execute_refinement.
1124  static const unsigned int
1126  {
1127  {
1128  // Normal orientation (face_filp = false)
1129  {{0,0},{1,1},{0,1},{0,1}}, // cut_x
1130  {{0,1},{0,1},{0,0},{1,1}}, // cut_y
1131  {{0,2},{1,3},{0,1},{2,3}} // cut_z
1132  },
1133  {
1134  // Flipped orientation (face_flip = true)
1135  {{0,0},{1,1},{1,0},{1,0}}, // cut_x
1136  {{1,0},{1,0},{0,0},{1,1}}, // cut_y
1137  {{2,0},{3,1},{1,0},{3,2}} // cut_z
1138  }
1139  };
1140 
1141  return subcells[face_flip][ref_case-1][face][subface];
1142 }
1143 
1144 
1145 
1146 template <>
1147 unsigned int
1149  const unsigned int face,
1150  const unsigned int subface,
1151  const bool face_orientation,
1152  const bool face_flip,
1153  const bool face_rotation,
1154  const RefinementCase<2> &face_ref_case)
1155 {
1156  const unsigned int dim = 3;
1157 
1158  Assert (ref_case>RefinementCase<dim-1>::no_refinement, ExcMessage("Cell has no children."));
1159  Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
1160  Assert (subface<GeometryInfo<dim-1>::n_children(face_ref_case) ||
1161  (subface==0 && face_ref_case==RefinementCase<dim-1>::no_refinement),
1162  ExcIndexRange(subface, 0, GeometryInfo<2>::n_children(face_ref_case)));
1163 
1164  // invalid number used for invalid cases,
1165  // e.g. when the children are more refined at
1166  // a given face than the face itself
1167  static const unsigned int e=invalid_unsigned_int;
1168 
1169  // the whole process of finding a child cell
1170  // at a given subface considering the
1171  // possibly anisotropic refinement cases of
1172  // the cell and the face as well as
1173  // orientation, flip and rotation of the face
1174  // is quite complicated. thus, we break it
1175  // down into several steps.
1176 
1177  // first step: convert the given face refine
1178  // case to a face refine case concerning the
1179  // face in standard orientation (, flip and
1180  // rotation). This only affects cut_x and
1181  // cut_y
1182  static const RefinementCase<dim-1> flip[4]=
1183  {
1184  RefinementCase<dim-1>::no_refinement,
1185  RefinementCase<dim-1>::cut_y,
1186  RefinementCase<dim-1>::cut_x,
1187  RefinementCase<dim-1>::cut_xy
1188  };
1189  // for face_orientation, 'true' is the
1190  // default value whereas for face_rotation,
1191  // 'false' is standard. If
1192  // <tt>face_rotation==face_orientation</tt>,
1193  // then one of them is non-standard and we
1194  // have to swap cut_x and cut_y, otherwise no
1195  // change is necessary.
1196  const RefinementCase<dim-1> std_face_ref = (face_orientation==face_rotation) ? flip[face_ref_case] : face_ref_case;
1197 
1198  // second step: convert the given subface
1199  // index to the one for a standard face
1200  // respecting face_orientation, face_flip and
1201  // face_rotation
1202 
1203  // first index: face_ref_case
1204  // second index: face_orientation
1205  // third index: face_flip
1206  // forth index: face_rotation
1207  // fifth index: subface index
1208  static const unsigned int subface_exchange[4][2][2][2][4]=
1209  {
1210  // no_refinement (subface 0 stays 0,
1211  // all others are invalid)
1212  { { { {0,e,e,e},
1213  {0,e,e,e}
1214  },
1215  { {0,e,e,e},
1216  {0,e,e,e}
1217  }
1218  },
1219  { { {0,e,e,e},
1220  {0,e,e,e}
1221  },
1222  { {0,e,e,e},
1223  {0,e,e,e}
1224  }
1225  }
1226  },
1227  // cut_x (here, if the face is only
1228  // rotated OR only falsely oriented,
1229  // then subface 0 of the non-standard
1230  // face does NOT correspond to one of
1231  // the subfaces of a standard
1232  // face. Thus we indicate the subface
1233  // which is located at the lower left
1234  // corner (the origin of the face's
1235  // local coordinate system) with
1236  // '0'. The rest of this issue is
1237  // taken care of using the above
1238  // conversion to a 'standard face
1239  // refine case')
1240  { { { {0,1,e,e},
1241  {0,1,e,e}
1242  },
1243  { {1,0,e,e},
1244  {1,0,e,e}
1245  }
1246  },
1247  { { {0,1,e,e},
1248  {0,1,e,e}
1249  },
1250  { {1,0,e,e},
1251  {1,0,e,e}
1252  }
1253  }
1254  },
1255  // cut_y (the same applies as for
1256  // cut_x)
1257  { { { {0,1,e,e},
1258  {1,0,e,e}
1259  },
1260  { {1,0,e,e},
1261  {0,1,e,e}
1262  }
1263  },
1264  { { {0,1,e,e},
1265  {1,0,e,e}
1266  },
1267  { {1,0,e,e},
1268  {0,1,e,e}
1269  }
1270  }
1271  },
1272  // cut_xyz: this information is
1273  // identical to the information
1274  // returned by
1275  // GeometryInfo<3>::real_to_standard_face_vertex()
1276  { { { {0,2,1,3}, // face_orientation=false, face_flip=false, face_rotation=false, subfaces 0,1,2,3
1277  {2,3,0,1}
1278  }, // face_orientation=false, face_flip=false, face_rotation=true, subfaces 0,1,2,3
1279  { {3,1,2,0}, // face_orientation=false, face_flip=true, face_rotation=false, subfaces 0,1,2,3
1280  {1,0,3,2}
1281  }
1282  }, // face_orientation=false, face_flip=true, face_rotation=true, subfaces 0,1,2,3
1283  { { {0,1,2,3}, // face_orientation=true, face_flip=false, face_rotation=false, subfaces 0,1,2,3
1284  {1,3,0,2}
1285  }, // face_orientation=true, face_flip=false, face_rotation=true, subfaces 0,1,2,3
1286  { {3,2,1,0}, // face_orientation=true, face_flip=true, face_rotation=false, subfaces 0,1,2,3
1287  {2,0,3,1}
1288  }
1289  }
1290  }
1291  };// face_orientation=true, face_flip=true, face_rotation=true, subfaces 0,1,2,3
1292 
1293  const unsigned int std_subface=subface_exchange
1294  [face_ref_case]
1295  [face_orientation]
1296  [face_flip]
1297  [face_rotation]
1298  [subface];
1299  Assert (std_subface!=e, ExcInternalError());
1300 
1301  // third step: these are the children, which
1302  // can be found at the given subfaces of an
1303  // isotropically refined (standard) face
1304  //
1305  // first index: (refinement_case-1)
1306  // second index: face_index
1307  // third index: subface_index (isotropic refinement)
1308  static const unsigned int
1310  {
1311  // cut_x
1312  { {0, 0, 0, 0}, // face 0, subfaces 0,1,2,3
1313  {1, 1, 1, 1}, // face 1, subfaces 0,1,2,3
1314  {0, 0, 1, 1}, // face 2, subfaces 0,1,2,3
1315  {0, 0, 1, 1}, // face 3, subfaces 0,1,2,3
1316  {0, 1, 0, 1}, // face 4, subfaces 0,1,2,3
1317  {0, 1, 0, 1}
1318  }, // face 5, subfaces 0,1,2,3
1319  // cut_y
1320  { {0, 1, 0, 1},
1321  {0, 1, 0, 1},
1322  {0, 0, 0, 0},
1323  {1, 1, 1, 1},
1324  {0, 0, 1, 1},
1325  {0, 0, 1, 1}
1326  },
1327  // cut_xy
1328  { {0, 2, 0, 2},
1329  {1, 3, 1, 3},
1330  {0, 0, 1, 1},
1331  {2, 2, 3, 3},
1332  {0, 1, 2, 3},
1333  {0, 1, 2, 3}
1334  },
1335  // cut_z
1336  { {0, 0, 1, 1},
1337  {0, 0, 1, 1},
1338  {0, 1, 0, 1},
1339  {0, 1, 0, 1},
1340  {0, 0, 0, 0},
1341  {1, 1, 1, 1}
1342  },
1343  // cut_xz
1344  { {0, 0, 1, 1},
1345  {2, 2, 3, 3},
1346  {0, 1, 2, 3},
1347  {0, 1, 2, 3},
1348  {0, 2, 0, 2},
1349  {1, 3, 1, 3}
1350  },
1351  // cut_yz
1352  { {0, 1, 2, 3},
1353  {0, 1, 2, 3},
1354  {0, 2, 0, 2},
1355  {1, 3, 1, 3},
1356  {0, 0, 1, 1},
1357  {2, 2, 3, 3}
1358  },
1359  // cut_xyz
1360  { {0, 2, 4, 6},
1361  {1, 3, 5, 7},
1362  {0, 4, 1, 5},
1363  {2, 6, 3, 7},
1364  {0, 1, 2, 3},
1365  {4, 5, 6, 7}
1366  }
1367  };
1368 
1369  // forth step: check, whether the given face
1370  // refine case is valid for the given cell
1371  // refine case. this is the case, if the
1372  // given face refine case is at least as
1373  // refined as the face is for the given cell
1374  // refine case
1375 
1376  // note, that we are considering standard
1377  // face refinement cases here and thus must
1378  // not pass the given orientation, flip and
1379  // rotation flags
1380  if ((std_face_ref & face_refinement_case(ref_case, face))
1381  == face_refinement_case(ref_case, face))
1382  {
1383  // all is fine. for anisotropic face
1384  // refine cases, select one of the
1385  // isotropic subfaces which neighbors the
1386  // same child
1387 
1388  // first index: (standard) face refine case
1389  // second index: subface index
1390  static const unsigned int equivalent_iso_subface[4][4]=
1391  {
1392  {0,e,e,e}, // no_refinement
1393  {0,3,e,e}, // cut_x
1394  {0,3,e,e}, // cut_y
1395  {0,1,2,3}
1396  }; // cut_xy
1397 
1398  const unsigned int equ_std_subface
1399  =equivalent_iso_subface[std_face_ref][std_subface];
1400  Assert (equ_std_subface!=e, ExcInternalError());
1401 
1402  return iso_children[ref_case-1][face][equ_std_subface];
1403  }
1404  else
1405  {
1406  // the face_ref_case was too coarse,
1407  // throw an error
1408  Assert(false,
1409  ExcMessage("The face RefineCase is too coarse "
1410  "for the given cell RefineCase."));
1411  }
1412  // we only get here in case of an error
1413  return e;
1414 }
1415 
1416 
1417 
1418 template <>
1419 unsigned int
1421  const unsigned int,
1422  const unsigned int,
1423  const bool, const bool, const bool,
1424  const RefinementCase<3> &)
1425 {
1426  Assert(false, ExcNotImplemented());
1427  return invalid_unsigned_int;
1428 }
1429 
1430 
1431 
1432 template <>
1433 unsigned int
1434 GeometryInfo<1>::line_to_cell_vertices (const unsigned int line,
1435  const unsigned int vertex)
1436 {
1437  (void)line;
1438  Assert (line<lines_per_cell, ExcIndexRange(line, 0, lines_per_cell));
1439  Assert (vertex<2, ExcIndexRange(vertex, 0, 2));
1440 
1441  return vertex;
1442 }
1443 
1444 
1445 template <>
1446 unsigned int
1447 GeometryInfo<2>::line_to_cell_vertices (const unsigned int line,
1448  const unsigned int vertex)
1449 {
1451 }
1452 
1453 
1454 
1455 template <>
1456 unsigned int
1457 GeometryInfo<3>::line_to_cell_vertices (const unsigned int line,
1458  const unsigned int vertex)
1459 {
1460  Assert (line<lines_per_cell, ExcIndexRange(line, 0, lines_per_cell));
1461  Assert (vertex<2, ExcIndexRange(vertex, 0, 2));
1462 
1463  static const unsigned
1464  vertices[lines_per_cell][2] = {{0, 2}, // bottom face
1465  {1, 3},
1466  {0, 1},
1467  {2, 3},
1468  {4, 6}, // top face
1469  {5, 7},
1470  {4, 5},
1471  {6, 7},
1472  {0, 4}, // connects of bottom
1473  {1, 5}, // top face
1474  {2, 6},
1475  {3, 7}
1476  };
1477  return vertices[line][vertex];
1478 }
1479 
1480 
1481 template <>
1482 unsigned int
1483 GeometryInfo<4>::line_to_cell_vertices (const unsigned int,
1484  const unsigned int)
1485 {
1486  Assert(false, ExcNotImplemented());
1487  return invalid_unsigned_int;
1488 }
1489 
1490 
1491 template <>
1492 unsigned int
1493 GeometryInfo<1>::face_to_cell_lines (const unsigned int face,
1494  const unsigned int line,
1495  const bool, const bool, const bool)
1496 {
1497  (void)face;
1498  (void)line;
1499  Assert (face+1<faces_per_cell+1, ExcIndexRange(face, 0, faces_per_cell));
1500  Assert (line+1<lines_per_face+1, ExcIndexRange(line, 0, lines_per_face));
1501 
1502  // There is only a single line, so
1503  // it must be this.
1504  return 0;
1505 }
1506 
1507 
1508 
1509 template <>
1510 unsigned int
1511 GeometryInfo<2>::face_to_cell_lines (const unsigned int face,
1512  const unsigned int line,
1513  const bool, const bool, const bool)
1514 {
1515  (void)line;
1516  Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
1517  Assert (line<lines_per_face, ExcIndexRange(line, 0, lines_per_face));
1518 
1519  // The face is a line itself.
1520  return face;
1521 }
1522 
1523 
1524 
1525 template <>
1526 unsigned int
1527 GeometryInfo<3>::face_to_cell_lines (const unsigned int face,
1528  const unsigned int line,
1529  const bool face_orientation,
1530  const bool face_flip,
1531  const bool face_rotation)
1532 {
1533  Assert (face<faces_per_cell, ExcIndexRange(face, 0, faces_per_cell));
1534  Assert (line<lines_per_face, ExcIndexRange(line, 0, lines_per_face));
1535 
1536  static const unsigned
1537  lines[faces_per_cell][lines_per_face] = {{8,10, 0, 4}, // left face
1538  {9,11, 1, 5}, // right face
1539  {2, 6, 8, 9}, // front face
1540  {3, 7,10,11}, // back face
1541  {0, 1, 2, 3}, // bottom face
1542  {4, 5, 6, 7}
1543  };// top face
1544  return lines[face][real_to_standard_face_line(line,
1545  face_orientation,
1546  face_flip,
1547  face_rotation)];
1548 }
1549 
1550 
1551 
1552 template<int dim>
1553 unsigned int
1555  const unsigned int,
1556  const bool, const bool, const bool)
1557 {
1558  Assert(false, ExcNotImplemented());
1559  return invalid_unsigned_int;
1560 }
1561 
1562 
1563 
1564 template <int dim>
1565 unsigned int
1567  const unsigned int vertex,
1568  const bool face_orientation,
1569  const bool face_flip,
1570  const bool face_rotation)
1571 {
1573  face_orientation, face_flip, face_rotation);
1574 }
1575 
1576 
1577 
1578 template <int dim>
1579 Point<dim>
1581 {
1582  Point<dim> p = q;
1583  for (unsigned int i=0; i<dim; i++)
1584  if (p[i] < 0.) p[i] = 0.;
1585  else if (p[i] > 1.) p[i] = 1.;
1586 
1587  return p;
1588 }
1589 
1590 
1591 
1592 template <int dim>
1593 double
1595 {
1596  double result = 0.0;
1597 
1598  for (unsigned int i=0; i<dim; i++)
1599  if ((-p[i]) > result)
1600  result = -p[i];
1601  else if ((p[i]-1.) > result)
1602  result = (p[i] - 1.);
1603 
1604  return result;
1605 }
1606 
1607 
1608 
1609 template <int dim>
1610 double
1613  const unsigned int i)
1614 {
1616  ExcIndexRange (i, 0, GeometryInfo<dim>::vertices_per_cell));
1617 
1618  switch (dim)
1619  {
1620  case 1:
1621  {
1622  const double x = xi[0];
1623  switch (i)
1624  {
1625  case 0:
1626  return 1-x;
1627  case 1:
1628  return x;
1629  }
1630  }
1631 
1632  case 2:
1633  {
1634  const double x = xi[0];
1635  const double y = xi[1];
1636  switch (i)
1637  {
1638  case 0:
1639  return (1-x)*(1-y);
1640  case 1:
1641  return x*(1-y);
1642  case 2:
1643  return (1-x)*y;
1644  case 3:
1645  return x*y;
1646  }
1647  }
1648 
1649  case 3:
1650  {
1651  const double x = xi[0];
1652  const double y = xi[1];
1653  const double z = xi[2];
1654  switch (i)
1655  {
1656  case 0:
1657  return (1-x)*(1-y)*(1-z);
1658  case 1:
1659  return x*(1-y)*(1-z);
1660  case 2:
1661  return (1-x)*y*(1-z);
1662  case 3:
1663  return x*y*(1-z);
1664  case 4:
1665  return (1-x)*(1-y)*z;
1666  case 5:
1667  return x*(1-y)*z;
1668  case 6:
1669  return (1-x)*y*z;
1670  case 7:
1671  return x*y*z;
1672  }
1673  }
1674 
1675  default:
1676  Assert (false, ExcNotImplemented());
1677  }
1678  return -1e9;
1679 }
1680 
1681 
1682 
1683 template <>
1687  const unsigned int i)
1688 {
1690  ExcIndexRange (i, 0, GeometryInfo<1>::vertices_per_cell));
1691 
1692  switch (i)
1693  {
1694  case 0:
1695  return Point<1>(-1.);
1696  case 1:
1697  return Point<1>(1.);
1698  }
1699 
1700  return Point<1>(-1e9);
1701 }
1702 
1703 
1704 
1705 template <>
1709  const unsigned int i)
1710 {
1712  ExcIndexRange (i, 0, GeometryInfo<2>::vertices_per_cell));
1713 
1714  const double x = xi[0];
1715  const double y = xi[1];
1716  switch (i)
1717  {
1718  case 0:
1719  return Point<2>(-(1-y),-(1-x));
1720  case 1:
1721  return Point<2>(1-y,-x);
1722  case 2:
1723  return Point<2>(-y, 1-x);
1724  case 3:
1725  return Point<2>(y,x);
1726  }
1727  return Point<2> (-1e9, -1e9);
1728 }
1729 
1730 
1731 
1732 template <>
1736  const unsigned int i)
1737 {
1739  ExcIndexRange (i, 0, GeometryInfo<3>::vertices_per_cell));
1740 
1741  const double x = xi[0];
1742  const double y = xi[1];
1743  const double z = xi[2];
1744  switch (i)
1745  {
1746  case 0:
1747  return Point<3>(-(1-y)*(1-z),
1748  -(1-x)*(1-z),
1749  -(1-x)*(1-y));
1750  case 1:
1751  return Point<3>((1-y)*(1-z),
1752  -x*(1-z),
1753  -x*(1-y));
1754  case 2:
1755  return Point<3>(-y*(1-z),
1756  (1-x)*(1-z),
1757  -(1-x)*y);
1758  case 3:
1759  return Point<3>(y*(1-z),
1760  x*(1-z),
1761  -x*y);
1762  case 4:
1763  return Point<3>(-(1-y)*z,
1764  -(1-x)*z,
1765  (1-x)*(1-y));
1766  case 5:
1767  return Point<3>((1-y)*z,
1768  -x*z,
1769  x*(1-y));
1770  case 6:
1771  return Point<3>(-y*z,
1772  (1-x)*z,
1773  (1-x)*y);
1774  case 7:
1775  return Point<3>(y*z, x*z, x*y);
1776  }
1777 
1778  return Point<3> (-1e9, -1e9, -1e9);
1779 }
1780 
1781 
1782 
1783 template <int dim>
1787  const unsigned int)
1788 {
1789  Assert (false, ExcNotImplemented());
1790  return Tensor<1,dim>();
1791 }
1792 
1793 
1794 
1795 
1796 
1797 namespace internal
1798 {
1799  namespace GeometryInfo
1800  {
1801  // wedge product of a single
1802  // vector in 2d: we just have to
1803  // rotate it by 90 degrees to the
1804  // right
1805  inline
1806  Tensor<1,2>
1807  wedge_product (const Tensor<1,2> (&derivative)[1])
1808  {
1809  Tensor<1,2> result;
1810  result[0] = derivative[0][1];
1811  result[1] = -derivative[0][0];
1812 
1813  return result;
1814  }
1815 
1816 
1817  // wedge product of 2 vectors in
1818  // 3d is the cross product
1819  inline
1820  Tensor<1,3>
1821  wedge_product (const Tensor<1,3> (&derivative)[2])
1822  {
1823  return cross_product_3d (derivative[0], derivative[1]);
1824  }
1825 
1826 
1827  // wedge product of dim vectors
1828  // in dim-d: that's the
1829  // determinant of the matrix
1830  template <int dim>
1831  inline
1833  wedge_product (const Tensor<1,dim> (&derivative)[dim])
1834  {
1835  Tensor<2,dim> jacobian;
1836  for (unsigned int i=0; i<dim; ++i)
1837  jacobian[i] = derivative[i];
1838 
1839  return determinant (jacobian);
1840  }
1841  }
1842 }
1843 
1844 
1845 template <int dim>
1846 template <int spacedim>
1847 void
1850 #ifndef DEAL_II_CONSTEXPR_BUG
1853 #else
1854 (const Point<spacedim> *vertices,
1856 #endif
1857 {
1858  // for each of the vertices,
1859  // compute the alternating form
1860  // of the mapped unit
1861  // vectors. consider for
1862  // example the case of a quad
1863  // in spacedim==3: to do so, we
1864  // need to see how the
1865  // infinitesimal vectors
1866  // (d\xi_1,0) and (0,d\xi_2)
1867  // are transformed into
1868  // spacedim-dimensional space
1869  // and then form their cross
1870  // product (i.e. the wedge product
1871  // of two vectors). to this end, note
1872  // that
1873  // \vec x = sum_i \vec v_i phi_i(\vec xi)
1874  // so the transformed vectors are
1875  // [x(\xi+(d\xi_1,0))-x(\xi)]/d\xi_1
1876  // and
1877  // [x(\xi+(0,d\xi_2))-x(\xi)]/d\xi_2
1878  // which boils down to the columns
1879  // of the 3x2 matrix \grad_\xi x(\xi)
1880  //
1881  // a similar reasoning would
1882  // hold for all dim,spacedim
1883  // pairs -- we only have to
1884  // compute the wedge product of
1885  // the columns of the
1886  // derivatives
1887  for (unsigned int i=0; i<vertices_per_cell; ++i)
1888  {
1889  Tensor<1,spacedim> derivatives[dim];
1890 
1891  for (unsigned int j=0; j<vertices_per_cell; ++j)
1892  {
1893  const Tensor<1,dim> grad_phi_j
1895  j);
1896  for (unsigned int l=0; l<dim; ++l)
1897  derivatives[l] += vertices[j] * grad_phi_j[l];
1898  }
1899 
1900  forms[i] = internal::GeometryInfo::wedge_product (derivatives);
1901  }
1902 }
1903 
1904 
1905 template struct GeometryInfo<1>;
1906 template struct GeometryInfo<2>;
1907 template struct GeometryInfo<3>;
1908 template struct GeometryInfo<4>;
1909 
1910 template
1911 void
1914 #ifndef DEAL_II_CONSTEXPR_BUG
1915 (const Point<1> (&)[vertices_per_cell],
1917 #else
1918 (const Point<1> *, Tensor<1-1,1> *)
1919 #endif
1920 ;
1921 
1922 template
1923 void
1926 #ifndef DEAL_II_CONSTEXPR_BUG
1927 (const Point<2> (&)[vertices_per_cell],
1929 #else
1930 (const Point<2> *, Tensor<2-1,2> *)
1931 #endif
1932 ;
1933 
1934 template
1935 void
1938 #ifndef DEAL_II_CONSTEXPR_BUG
1939 (const Point<2> (&vertices)[vertices_per_cell],
1940  Tensor<2-2,2> (&forms)[vertices_per_cell])
1941 #else
1942 (const Point<2> *, Tensor<2-2,2> *)
1943 #endif
1944 ;
1945 
1946 template
1947 void
1950 #ifndef DEAL_II_CONSTEXPR_BUG
1951 (const Point<3> (&vertices)[vertices_per_cell],
1952  Tensor<3-2,3> (&forms)[vertices_per_cell])
1953 #else
1954 (const Point<3> *, Tensor<3-2,3> *)
1955 #endif
1956 ;
1957 
1958 
1959 template
1960 void
1963 #ifndef DEAL_II_CONSTEXPR_BUG
1964 (const Point<3> (&vertices)[vertices_per_cell],
1965  Tensor<3-3,3> (&forms)[vertices_per_cell])
1966 #else
1967 (const Point<3> *, Tensor<3-3,3> *)
1968 #endif
1969 ;
1970 
1971 
1972 DEAL_II_NAMESPACE_CLOSE
static unsigned int standard_to_real_face_vertex(const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static RefinementCase< 1 > line_refinement_case(const RefinementCase< dim > &cell_refinement_case, const unsigned int line_no)
static unsigned int real_to_standard_face_line(const unsigned int line, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static unsigned int face_to_cell_vertices(const unsigned int face, const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static unsigned int line_to_cell_vertices(const unsigned int line, const unsigned int vertex)
::ExceptionBase & ExcMessage(std::string arg1)
static const unsigned int max_children_per_face
static RefinementCase< dim-1 > face_refinement_case(const RefinementCase< dim > &cell_refinement_case, const unsigned int face_no, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static Point< dim > unit_cell_vertex(const unsigned int vertex)
static const unsigned int vertices_per_cell
static const unsigned int lines_per_cell
static unsigned int n_children(const RefinementCase< dim > &refinement_case)
static unsigned int face_to_cell_lines(const unsigned int face, const unsigned int line, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static unsigned int child_cell_on_face(const RefinementCase< dim > &ref_case, const unsigned int face, const unsigned int subface, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false, const RefinementCase< dim-1 > &face_refinement_case=RefinementCase< dim-1 >::isotropic_refinement)
#define Assert(cond, exc)
Definition: exceptions.h:294
static double distance_to_unit_cell(const Point< dim > &p)
static const unsigned int lines_per_face
static unsigned int standard_to_real_face_line(const unsigned int line, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static RefinementCase< dim > min_cell_refinement_case_for_line_refinement(const unsigned int line_no)
static void alternating_form_at_vertices(const Point< spacedim >(&vertices)[vertices_per_cell], Tensor< spacedim-dim, spacedim >(&forms)[vertices_per_cell])
Definition: mpi.h:48
static unsigned int n_subfaces(const internal::SubfaceCase< dim > &subface_case)
static unsigned int real_to_standard_face_vertex(const unsigned int vertex, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static Point< dim > project_to_unit_cell(const Point< dim > &p)
static const unsigned int faces_per_cell
static Tensor< 1, dim > d_linear_shape_function_gradient(const Point< dim > &xi, const unsigned int i)
static double subface_ratio(const internal::SubfaceCase< dim > &subface_case, const unsigned int subface_no)
static RefinementCase< dim > min_cell_refinement_case_for_face_refinement(const RefinementCase< dim-1 > &face_refinement_case, const unsigned int face_no, const bool face_orientation=true, const bool face_flip=false, const bool face_rotation=false)
static double d_linear_shape_function(const Point< dim > &xi, const unsigned int i)