Reference documentation for deal.II version 8.4.2
tria_accessor.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 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/grid/tria.h>
17 #include <deal.II/grid/tria_levels.h>
18 #include <deal.II/grid/tria_iterator.h>
19 #include <deal.II/grid/tria_accessor.h>
20 #include <deal.II/grid/tria_accessor.templates.h>
21 #include <deal.II/grid/tria_iterator.templates.h>
22 #include <deal.II/base/geometry_info.h>
23 #include <deal.II/base/quadrature.h>
24 #include <deal.II/grid/grid_tools.h>
25 #include <deal.II/grid/manifold.h>
26 #include <deal.II/fe/mapping_q1.h>
27 #include <deal.II/fe/fe_q.h>
28 
29 #include <cmath>
30 
31 DEAL_II_NAMESPACE_OPEN
32 
33 // anonymous namespace for helper functions
34 namespace
35 {
36  // given the number of face's child
37  // (subface_no), return the number of the
38  // subface concerning the FaceRefineCase of
39  // the face
40  inline
41  unsigned int translate_subface_no(const TriaIterator<TriaAccessor<2, 3, 3> > &face,
42  const unsigned int subface_no)
43  {
44  Assert(face->has_children(), ExcInternalError());
45  Assert(subface_no<face->n_children(), ExcInternalError());
46 
47  if (face->child(subface_no)->has_children())
48  // although the subface is refine, it
49  // still matches the face of the cell
50  // invoking the
51  // neighbor_of_coarser_neighbor
52  // function. this means that we are
53  // looking from one cell (anisotropic
54  // child) to a coarser neighbor which is
55  // refined stronger than we are
56  // (isotropically). So we won't be able
57  // to use the neighbor_child_on_subface
58  // function anyway, as the neighbor is
59  // not active. In this case, simply
60  // return the subface_no.
61  return subface_no;
62 
63  const bool first_child_has_children=face->child(0)->has_children();
64  // if the first child has children
65  // (FaceRefineCase case_x1y or case_y1x),
66  // then the current subface_no needs to be
67  // 1 and the result of this function is 2,
68  // else simply return the given number,
69  // which is 0 or 1 in an anisotropic case
70  // (case_x, case_y, casex2y or casey2x) or
71  // 0...3 in an isotropic case (case_xy)
72  return subface_no + first_child_has_children;
73  }
74 
75 
76 
77  // given the number of face's child
78  // (subface_no) and grandchild
79  // (subsubface_no), return the number of the
80  // subface concerning the FaceRefineCase of
81  // the face
82  inline
83  unsigned int translate_subface_no(const TriaIterator<TriaAccessor<2, 3, 3> > &face,
84  const unsigned int subface_no,
85  const unsigned int subsubface_no)
86  {
87  Assert(face->has_children(), ExcInternalError());
88  // the subface must be refined, otherwise
89  // we would have ended up in the second
90  // function of this name...
91  Assert(face->child(subface_no)->has_children(), ExcInternalError());
92  Assert(subsubface_no<face->child(subface_no)->n_children(), ExcInternalError());
93  // This can only be an anisotropic refinement case
94  Assert(face->refinement_case() < RefinementCase<2>::isotropic_refinement,
95  ExcInternalError());
96 
97  const bool first_child_has_children=face->child(0)->has_children();
98 
99  static const unsigned int e = numbers::invalid_unsigned_int;
100 
101  // array containing the translation of the
102  // numbers,
103  //
104  // first index: subface_no
105  // second index: subsubface_no
106  // third index: does the first subface have children? -> no and yes
107  static const unsigned int translated_subface_no[2][2][2]
108  =
109  {
110  { {e,0}, // first subface, first subsubface, first_child_has_children==no and yes
111  {e,1}
112  }, // first subface, second subsubface, first_child_has_children==no and yes
113  { {1,2}, // second subface, first subsubface, first_child_has_children==no and yes
114  {2,3}
115  }
116  }; // second subface, second subsubface, first_child_has_children==no and yes
117 
118  Assert(translated_subface_no[subface_no][subsubface_no][first_child_has_children]!=e,
119  ExcInternalError());
120 
121  return translated_subface_no[subface_no][subsubface_no][first_child_has_children];
122  }
123 
124 
125  template <int dim, int spacedim>
127  barycenter (const TriaAccessor<1, dim, spacedim> &accessor)
128  {
129  return (accessor.vertex(1)+accessor.vertex(0))/2.;
130  }
131 
132 
133  Point<2>
134  barycenter (const TriaAccessor<2, 2, 2> &accessor)
135  {
136  // the evaluation of the formulae
137  // is a bit tricky when done dimension
138  // independently, so we write this function
139  // for 2D and 3D separately
140  /*
141  Get the computation of the barycenter by this little Maple script. We
142  use the bilinear mapping of the unit quad to the real quad. However,
143  every transformation mapping the unit faces to strait lines should
144  do.
145 
146  Remember that the area of the quad is given by
147  |K| = \int_K 1 dx dy = \int_{\hat K} |det J| d(xi) d(eta)
148  and that the barycenter is given by
149  \vec x_s = 1/|K| \int_K \vec x dx dy
150  = 1/|K| \int_{\hat K} \vec x(xi,eta) |det J| d(xi) d(eta)
151 
152  # x and y are arrays holding the x- and y-values of the four vertices
153  # of this cell in real space.
154  x := array(0..3);
155  y := array(0..3);
156  tphi[0] := (1-xi)*(1-eta):
157  tphi[1] := xi*(1-eta):
158  tphi[2] := (1-xi)*eta:
159  tphi[3] := xi*eta:
160  x_real := sum(x[s]*tphi[s], s=0..3):
161  y_real := sum(y[s]*tphi[s], s=0..3):
162  detJ := diff(x_real,xi)*diff(y_real,eta) - diff(x_real,eta)*diff(y_real,xi):
163 
164  measure := simplify ( int ( int (detJ, xi=0..1), eta=0..1)):
165 
166  xs := simplify (1/measure * int ( int (x_real * detJ, xi=0..1), eta=0..1)):
167  ys := simplify (1/measure * int ( int (y_real * detJ, xi=0..1), eta=0..1)):
168  readlib(C):
169 
170  C(array(1..2, [xs, ys]), optimized);
171  */
172 
173  const double x[4] = { accessor.vertex(0)(0),
174  accessor.vertex(1)(0),
175  accessor.vertex(2)(0),
176  accessor.vertex(3)(0)
177  };
178  const double y[4] = { accessor.vertex(0)(1),
179  accessor.vertex(1)(1),
180  accessor.vertex(2)(1),
181  accessor.vertex(3)(1)
182  };
183  const double t1 = x[0]*x[1];
184  const double t3 = x[0]*x[0];
185  const double t5 = x[1]*x[1];
186  const double t9 = y[0]*x[0];
187  const double t11 = y[1]*x[1];
188  const double t14 = x[2]*x[2];
189  const double t16 = x[3]*x[3];
190  const double t20 = x[2]*x[3];
191  const double t27 = t1*y[1]+t3*y[1]-t5*y[0]-t3*y[2]+t5*y[3]+t9*x[2]-t11*x[3]-t1*y[0]-t14*y[3]+t16*y[2]-t16*y[1]+t14*y[0]-t20*y[3]-x[0]*x[2]*y[2]+x[1]*x[3]*y[3]+t20*y[2];
192  const double t37 = 1/(-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2]);
193  const double t39 = y[2]*y[2];
194  const double t51 = y[0]*y[0];
195  const double t53 = y[1]*y[1];
196  const double t59 = y[3]*y[3];
197  const double t63 = t39*x[3]+y[2]*y[0]*x[2]+y[3]*x[3]*y[2]-y[2]*x[2]*y[3]-y[3]*y[1]*x[3]-t9*y[2]+t11*y[3]+t51*x[2]-t53*x[3]-x[1]*t51+t9*y[1]-t11*y[0]+x[0]*t53-t59*x[2]+t59*x[1]-t39*x[0];
198 
199  return Point<2> (t27*t37/3, t63*t37/3);
200  }
201 
202 
203 
204  Point<3>
205  barycenter (const TriaAccessor<3,3,3> &accessor)
206  {
207  /*
208  Get the computation of the barycenter by this little Maple script. We
209  use the trilinear mapping of the unit hex to the real hex.
210 
211  Remember that the area of the hex is given by
212  |K| = \int_K 1 dx dy dz = \int_{\hat K} |det J| d(xi) d(eta) d(zeta)
213  and that the barycenter is given by
214  \vec x_s = 1/|K| \int_K \vec x dx dy dz
215  = 1/|K| \int_{\hat K} \vec x(xi,eta,zeta) |det J| d(xi) d(eta) d(zeta)
216 
217  Note, that in the ordering of the shape functions tphi[0]-tphi[7]
218  below, eta and zeta have been exchanged (zeta belongs to the y, and
219  eta to the z direction). However, the resulting Jacobian determinant
220  detJ should be the same, as a matrix and the matrix created from it
221  by exchanging two consecutive lines and two neighboring columns have
222  the same determinant.
223 
224  # x, y and z are arrays holding the x-, y- and z-values of the four vertices
225  # of this cell in real space.
226  x := array(0..7):
227  y := array(0..7):
228  z := array(0..7):
229  tphi[0] := (1-xi)*(1-eta)*(1-zeta):
230  tphi[1] := xi*(1-eta)*(1-zeta):
231  tphi[2] := xi*eta*(1-zeta):
232  tphi[3] := (1-xi)*eta*(1-zeta):
233  tphi[4] := (1-xi)*(1-eta)*zeta:
234  tphi[5] := xi*(1-eta)*zeta:
235  tphi[6] := xi*eta*zeta:
236  tphi[7] := (1-xi)*eta*zeta:
237  x_real := sum(x[s]*tphi[s], s=0..7):
238  y_real := sum(y[s]*tphi[s], s=0..7):
239  z_real := sum(z[s]*tphi[s], s=0..7):
240  with (linalg):
241  J := matrix(3,3, [[diff(x_real, xi), diff(x_real, eta), diff(x_real, zeta)],
242  [diff(y_real, xi), diff(y_real, eta), diff(y_real, zeta)],
243  [diff(z_real, xi), diff(z_real, eta), diff(z_real, zeta)]]):
244  detJ := det (J):
245 
246  measure := simplify ( int ( int ( int (detJ, xi=0..1), eta=0..1), zeta=0..1)):
247 
248  xs := simplify (1/measure * int ( int ( int (x_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
249  ys := simplify (1/measure * int ( int ( int (y_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
250  zs := simplify (1/measure * int ( int ( int (z_real * detJ, xi=0..1), eta=0..1), zeta=0..1)):
251 
252  readlib(C):
253 
254  C(array(1..3, [xs, ys, zs]));
255 
256 
257  This script takes more than several hours when using an old version
258  of maple on an old and slow computer. Therefore, when changing to
259  the new deal.II numbering scheme (lexicographic numbering) the code
260  lines below have not been reproduced with maple but only the
261  ordering of points in the definitions of x[], y[] and z[] have been
262  changed.
263 
264  For the case, someone is willing to rerun the maple script, he/she
265  should use following ordering of shape functions:
266 
267  tphi[0] := (1-xi)*(1-eta)*(1-zeta):
268  tphi[1] := xi*(1-eta)*(1-zeta):
269  tphi[2] := (1-xi)* eta*(1-zeta):
270  tphi[3] := xi* eta*(1-zeta):
271  tphi[4] := (1-xi)*(1-eta)*zeta:
272  tphi[5] := xi*(1-eta)*zeta:
273  tphi[6] := (1-xi)* eta*zeta:
274  tphi[7] := xi* eta*zeta:
275 
276  and change the ordering of points in the definitions of x[], y[] and
277  z[] back to the standard ordering.
278  */
279 
280  const double x[8] = { accessor.vertex(0)(0),
281  accessor.vertex(1)(0),
282  accessor.vertex(5)(0),
283  accessor.vertex(4)(0),
284  accessor.vertex(2)(0),
285  accessor.vertex(3)(0),
286  accessor.vertex(7)(0),
287  accessor.vertex(6)(0)
288  };
289  const double y[8] = { accessor.vertex(0)(1),
290  accessor.vertex(1)(1),
291  accessor.vertex(5)(1),
292  accessor.vertex(4)(1),
293  accessor.vertex(2)(1),
294  accessor.vertex(3)(1),
295  accessor.vertex(7)(1),
296  accessor.vertex(6)(1)
297  };
298  const double z[8] = { accessor.vertex(0)(2),
299  accessor.vertex(1)(2),
300  accessor.vertex(5)(2),
301  accessor.vertex(4)(2),
302  accessor.vertex(2)(2),
303  accessor.vertex(3)(2),
304  accessor.vertex(7)(2),
305  accessor.vertex(6)(2)
306  };
307 
308  double s1, s2, s3, s4, s5, s6, s7, s8;
309 
310  s1 = 1.0/6.0;
311  s8 = -x[2]*x[2]*y[0]*z[3]-2.0*z[6]*x[7]*x[7]*y[4]-z[5]*x[7]*x[7]*y[4]-z
312  [6]*x[7]*x[7]*y[5]+2.0*y[6]*x[7]*x[7]*z[4]-z[5]*x[6]*x[6]*y[4]+x[6]*x[6]*y[4]*z
313  [7]-z[1]*x[0]*x[0]*y[2]-x[6]*x[6]*y[7]*z[4]+2.0*x[6]*x[6]*y[5]*z[7]-2.0*x[6]*x
314  [6]*y[7]*z[5]+y[5]*x[6]*x[6]*z[4]+2.0*x[5]*x[5]*y[4]*z[6]+x[0]*x[0]*y[7]*z[4]
315  -2.0*x[5]*x[5]*y[6]*z[4];
316  s7 = s8-y[6]*x[5]*x[5]*z[7]+z[6]*x[5]*x[5]*y[7]-y[1]*x[0]*x[0]*z[5]+x[7]*
317  z[5]*x[4]*y[7]-x[7]*y[6]*x[5]*z[7]-2.0*x[7]*x[6]*y[7]*z[4]+2.0*x[7]*x[6]*y[4]*z
318  [7]-x[7]*x[5]*y[7]*z[4]-2.0*x[7]*y[6]*x[4]*z[7]-x[7]*y[5]*x[4]*z[7]+x[2]*x[2]*y
319  [3]*z[0]-x[7]*x[6]*y[7]*z[5]+x[7]*x[6]*y[5]*z[7]+2.0*x[1]*x[1]*y[0]*z[5]+x[7]*z
320  [6]*x[5]*y[7];
321  s8 = -2.0*x[1]*x[1]*y[5]*z[0]+z[1]*x[0]*x[0]*y[5]+2.0*x[2]*x[2]*y[3]*z[1]
322  -z[5]*x[4]*x[4]*y[1]+y[5]*x[4]*x[4]*z[1]-2.0*x[5]*x[5]*y[4]*z[1]+2.0*x[5]*x[5]*
323  y[1]*z[4]-2.0*x[2]*x[2]*y[1]*z[3]-y[1]*x[2]*x[2]*z[0]+x[7]*y[2]*x[3]*z[7]+x[7]*
324  z[2]*x[6]*y[3]+2.0*x[7]*z[6]*x[4]*y[7]+z[5]*x[1]*x[1]*y[4]+z[1]*x[2]*x[2]*y[0]
325  -2.0*y[0]*x[3]*x[3]*z[7];
326  s6 = s8+2.0*z[0]*x[3]*x[3]*y[7]-x[7]*x[2]*y[3]*z[7]-x[7]*z[2]*x[3]*y[7]+x
327  [7]*x[2]*y[7]*z[3]-x[7]*y[2]*x[6]*z[3]+x[4]*x[5]*y[1]*z[4]-x[4]*x[5]*y[4]*z[1]+
328  x[4]*z[5]*x[1]*y[4]-x[4]*y[5]*x[1]*z[4]-2.0*x[5]*z[5]*x[4]*y[1]-2.0*x[5]*y[5]*x
329  [1]*z[4]+2.0*x[5]*z[5]*x[1]*y[4]+2.0*x[5]*y[5]*x[4]*z[1]-x[6]*z[5]*x[7]*y[4]-z
330  [2]*x[3]*x[3]*y[6]+s7;
331  s8 = -2.0*x[6]*z[6]*x[7]*y[5]-x[6]*y[6]*x[4]*z[7]+y[2]*x[3]*x[3]*z[6]+x
332  [6]*y[6]*x[7]*z[4]+2.0*y[2]*x[3]*x[3]*z[7]+x[0]*x[1]*y[0]*z[5]+x[0]*y[1]*x[5]*z
333  [0]-x[0]*z[1]*x[5]*y[0]-2.0*z[2]*x[3]*x[3]*y[7]+2.0*x[6]*z[6]*x[5]*y[7]-x[0]*x
334  [1]*y[5]*z[0]-x[6]*y[5]*x[4]*z[6]-2.0*x[3]*z[0]*x[7]*y[3]-x[6]*z[6]*x[7]*y[4]
335  -2.0*x[1]*z[1]*x[5]*y[0];
336  s7 = s8+2.0*x[1]*y[1]*x[5]*z[0]+2.0*x[1]*z[1]*x[0]*y[5]+2.0*x[3]*y[0]*x
337  [7]*z[3]+2.0*x[3]*x[0]*y[3]*z[7]-2.0*x[3]*x[0]*y[7]*z[3]-2.0*x[1]*y[1]*x[0]*z
338  [5]-2.0*x[6]*y[6]*x[5]*z[7]+s6-y[5]*x[1]*x[1]*z[4]+x[6]*z[6]*x[4]*y[7]-2.0*x[2]
339  *y[2]*x[3]*z[1]+x[6]*z[5]*x[4]*y[6]+x[6]*x[5]*y[4]*z[6]-y[6]*x[7]*x[7]*z[2]-x
340  [6]*x[5]*y[6]*z[4];
341  s8 = x[3]*x[3]*y[7]*z[4]-2.0*y[6]*x[7]*x[7]*z[3]+z[6]*x[7]*x[7]*y[2]+2.0*
342  z[6]*x[7]*x[7]*y[3]+2.0*y[1]*x[0]*x[0]*z[3]+2.0*x[0]*x[1]*y[3]*z[0]-2.0*x[0]*y
343  [0]*x[3]*z[4]-2.0*x[0]*z[1]*x[4]*y[0]-2.0*x[0]*y[1]*x[3]*z[0]+2.0*x[0]*y[0]*x
344  [4]*z[3]-2.0*x[0]*z[0]*x[4]*y[3]+2.0*x[0]*x[1]*y[0]*z[4]+2.0*x[0]*z[1]*x[3]*y
345  [0]-2.0*x[0]*x[1]*y[0]*z[3]-2.0*x[0]*x[1]*y[4]*z[0]+2.0*x[0]*y[1]*x[4]*z[0];
346  s5 = s8+2.0*x[0]*z[0]*x[3]*y[4]+x[1]*y[1]*x[0]*z[3]-x[1]*z[1]*x[4]*y[0]-x
347  [1]*y[1]*x[0]*z[4]+x[1]*z[1]*x[0]*y[4]-x[1]*y[1]*x[3]*z[0]-x[1]*z[1]*x[0]*y[3]-
348  x[0]*z[5]*x[4]*y[1]+x[0]*y[5]*x[4]*z[1]-2.0*x[4]*x[0]*y[4]*z[7]-2.0*x[4]*y[5]*x
349  [0]*z[4]+2.0*x[4]*z[5]*x[0]*y[4]-2.0*x[4]*x[5]*y[4]*z[0]-2.0*x[4]*y[0]*x[7]*z
350  [4]-x[5]*y[5]*x[0]*z[4]+s7;
351  s8 = x[5]*z[5]*x[0]*y[4]-x[5]*z[5]*x[4]*y[0]+x[1]*z[5]*x[0]*y[4]+x[5]*y
352  [5]*x[4]*z[0]-x[0]*y[0]*x[7]*z[4]-x[0]*z[5]*x[4]*y[0]-x[1]*y[5]*x[0]*z[4]+x[0]*
353  z[0]*x[7]*y[4]+x[0]*y[5]*x[4]*z[0]-x[0]*z[0]*x[4]*y[7]+x[0]*x[5]*y[0]*z[4]+x[0]
354  *y[0]*x[4]*z[7]-x[0]*x[5]*y[4]*z[0]-x[3]*x[3]*y[4]*z[7]+2.0*x[2]*z[2]*x[3]*y[1]
355  ;
356  s7 = s8-x[5]*x[5]*y[4]*z[0]+2.0*y[5]*x[4]*x[4]*z[0]-2.0*z[0]*x[4]*x[4]*y
357  [7]+2.0*y[0]*x[4]*x[4]*z[7]-2.0*z[5]*x[4]*x[4]*y[0]+x[5]*x[5]*y[4]*z[7]-x[5]*x
358  [5]*y[7]*z[4]-2.0*y[5]*x[4]*x[4]*z[7]+2.0*z[5]*x[4]*x[4]*y[7]-x[0]*x[0]*y[7]*z
359  [3]+y[2]*x[0]*x[0]*z[3]+x[0]*x[0]*y[3]*z[7]-x[5]*x[1]*y[4]*z[0]+x[5]*y[1]*x[4]*
360  z[0]-x[4]*y[0]*x[3]*z[4];
361  s8 = -x[4]*y[1]*x[0]*z[4]+x[4]*z[1]*x[0]*y[4]+x[4]*x[0]*y[3]*z[4]-x[4]*x
362  [0]*y[4]*z[3]+x[4]*x[1]*y[0]*z[4]-x[4]*x[1]*y[4]*z[0]+x[4]*z[0]*x[3]*y[4]+x[5]*
363  x[1]*y[0]*z[4]+x[1]*z[1]*x[3]*y[0]+x[1]*y[1]*x[4]*z[0]-x[5]*z[1]*x[4]*y[0]-2.0*
364  y[1]*x[0]*x[0]*z[4]+2.0*z[1]*x[0]*x[0]*y[4]+2.0*x[0]*x[0]*y[3]*z[4]-2.0*z[1]*x
365  [0]*x[0]*y[3];
366  s6 = s8-2.0*x[0]*x[0]*y[4]*z[3]+x[1]*x[1]*y[3]*z[0]+x[1]*x[1]*y[0]*z[4]-x
367  [1]*x[1]*y[0]*z[3]-x[1]*x[1]*y[4]*z[0]-z[1]*x[4]*x[4]*y[0]+y[0]*x[4]*x[4]*z[3]-
368  z[0]*x[4]*x[4]*y[3]+y[1]*x[4]*x[4]*z[0]-x[0]*x[0]*y[4]*z[7]-y[5]*x[0]*x[0]*z[4]
369  +z[5]*x[0]*x[0]*y[4]+x[5]*x[5]*y[0]*z[4]-x[0]*y[0]*x[3]*z[7]+x[0]*z[0]*x[3]*y
370  [7]+s7;
371  s8 = s6+x[0]*x[2]*y[3]*z[0]-x[0]*x[2]*y[0]*z[3]+x[0]*y[0]*x[7]*z[3]-x[0]*
372  y[2]*x[3]*z[0]+x[0]*z[2]*x[3]*y[0]-x[0]*z[0]*x[7]*y[3]+x[1]*x[2]*y[3]*z[0]-z[2]
373  *x[0]*x[0]*y[3]+x[3]*z[2]*x[6]*y[3]-x[3]*x[2]*y[3]*z[6]+x[3]*x[2]*y[6]*z[3]-x
374  [3]*y[2]*x[6]*z[3]-2.0*x[3]*y[2]*x[7]*z[3]+2.0*x[3]*z[2]*x[7]*y[3];
375  s7 = s8+2.0*x[4]*y[5]*x[7]*z[4]+2.0*x[4]*x[5]*y[4]*z[7]-2.0*x[4]*z[5]*x
376  [7]*y[4]-2.0*x[4]*x[5]*y[7]*z[4]+x[5]*y[5]*x[7]*z[4]-x[5]*z[5]*x[7]*y[4]-x[5]*y
377  [5]*x[4]*z[7]+x[5]*z[5]*x[4]*y[7]+2.0*x[3]*x[2]*y[7]*z[3]-2.0*x[2]*z[2]*x[1]*y
378  [3]+2.0*x[4]*z[0]*x[7]*y[4]+2.0*x[4]*x[0]*y[7]*z[4]+2.0*x[4]*x[5]*y[0]*z[4]-x
379  [7]*x[6]*y[2]*z[7]-2.0*x[3]*x[2]*y[3]*z[7]-x[0]*x[4]*y[7]*z[3];
380  s8 = x[0]*x[3]*y[7]*z[4]-x[0]*x[3]*y[4]*z[7]+x[0]*x[4]*y[3]*z[7]-2.0*x[7]
381  *z[6]*x[3]*y[7]+x[3]*x[7]*y[4]*z[3]-x[3]*x[4]*y[7]*z[3]-x[3]*x[7]*y[3]*z[4]+x
382  [3]*x[4]*y[3]*z[7]+2.0*x[2]*y[2]*x[1]*z[3]+y[6]*x[3]*x[3]*z[7]-z[6]*x[3]*x[3]*y
383  [7]-x[1]*z[5]*x[4]*y[1]-x[1]*x[5]*y[4]*z[1]-x[1]*z[2]*x[0]*y[3]-x[1]*x[2]*y[0]*
384  z[3]+x[1]*y[2]*x[0]*z[3];
385  s4 = s8+x[1]*x[5]*y[1]*z[4]+x[1]*y[5]*x[4]*z[1]+x[4]*y[0]*x[7]*z[3]-x[4]*
386  z[0]*x[7]*y[3]-x[4]*x[4]*y[7]*z[3]+x[4]*x[4]*y[3]*z[7]+x[3]*z[6]*x[7]*y[3]-x[3]
387  *x[6]*y[3]*z[7]+x[3]*x[6]*y[7]*z[3]-x[3]*z[6]*x[2]*y[7]-x[3]*y[6]*x[7]*z[3]+x
388  [3]*z[6]*x[7]*y[2]+x[3]*y[6]*x[2]*z[7]+2.0*x[5]*z[5]*x[4]*y[6]+s5+s7;
389  s8 = s4-2.0*x[5]*z[5]*x[6]*y[4]-x[5]*z[6]*x[7]*y[5]+x[5]*x[6]*y[5]*z[7]-x
390  [5]*x[6]*y[7]*z[5]-2.0*x[5]*y[5]*x[4]*z[6]+2.0*x[5]*y[5]*x[6]*z[4]-x[3]*y[6]*x
391  [7]*z[2]+x[4]*x[7]*y[4]*z[3]+x[4]*x[3]*y[7]*z[4]-x[4]*x[7]*y[3]*z[4]-x[4]*x[3]*
392  y[4]*z[7]-z[1]*x[5]*x[5]*y[0]+y[1]*x[5]*x[5]*z[0]+x[4]*y[6]*x[7]*z[4];
393  s7 = s8-x[4]*x[6]*y[7]*z[4]+x[4]*x[6]*y[4]*z[7]-x[4]*z[6]*x[7]*y[4]-x[5]*
394  y[6]*x[4]*z[7]-x[5]*x[6]*y[7]*z[4]+x[5]*x[6]*y[4]*z[7]+x[5]*z[6]*x[4]*y[7]-y[6]
395  *x[4]*x[4]*z[7]+z[6]*x[4]*x[4]*y[7]+x[7]*x[5]*y[4]*z[7]-y[2]*x[7]*x[7]*z[3]+z
396  [2]*x[7]*x[7]*y[3]-y[0]*x[3]*x[3]*z[4]-y[1]*x[3]*x[3]*z[0]+z[1]*x[3]*x[3]*y[0];
397  s8 = z[0]*x[3]*x[3]*y[4]-x[2]*y[1]*x[3]*z[0]+x[2]*z[1]*x[3]*y[0]+x[3]*y
398  [1]*x[0]*z[3]+x[3]*x[1]*y[3]*z[0]+x[3]*x[0]*y[3]*z[4]-x[3]*z[1]*x[0]*y[3]-x[3]*
399  x[0]*y[4]*z[3]+x[3]*y[0]*x[4]*z[3]-x[3]*z[0]*x[4]*y[3]-x[3]*x[1]*y[0]*z[3]+x[3]
400  *z[0]*x[7]*y[4]-x[3]*y[0]*x[7]*z[4]+z[0]*x[7]*x[7]*y[4]-y[0]*x[7]*x[7]*z[4];
401  s6 = s8+y[1]*x[0]*x[0]*z[2]-2.0*y[2]*x[3]*x[3]*z[0]+2.0*z[2]*x[3]*x[3]*y
402  [0]-2.0*x[1]*x[1]*y[0]*z[2]+2.0*x[1]*x[1]*y[2]*z[0]-y[2]*x[3]*x[3]*z[1]+z[2]*x
403  [3]*x[3]*y[1]-y[5]*x[4]*x[4]*z[6]+z[5]*x[4]*x[4]*y[6]+x[7]*x[0]*y[7]*z[4]-x[7]*
404  z[0]*x[4]*y[7]-x[7]*x[0]*y[4]*z[7]+x[7]*y[0]*x[4]*z[7]-x[0]*x[1]*y[0]*z[2]+x[0]
405  *z[1]*x[2]*y[0]+s7;
406  s8 = s6+x[0]*x[1]*y[2]*z[0]-x[0]*y[1]*x[2]*z[0]-x[3]*z[1]*x[0]*y[2]+2.0*x
407  [3]*x[2]*y[3]*z[0]+y[0]*x[7]*x[7]*z[3]-z[0]*x[7]*x[7]*y[3]-2.0*x[3]*z[2]*x[0]*y
408  [3]-2.0*x[3]*x[2]*y[0]*z[3]+2.0*x[3]*y[2]*x[0]*z[3]+x[3]*x[2]*y[3]*z[1]-x[3]*x
409  [2]*y[1]*z[3]-x[5]*y[1]*x[0]*z[5]+x[3]*y[1]*x[0]*z[2]+x[4]*y[6]*x[7]*z[5];
410  s7 = s8-x[5]*x[1]*y[5]*z[0]+2.0*x[1]*z[1]*x[2]*y[0]-2.0*x[1]*z[1]*x[0]*y
411  [2]+x[1]*x[2]*y[3]*z[1]-x[1]*x[2]*y[1]*z[3]+2.0*x[1]*y[1]*x[0]*z[2]-2.0*x[1]*y
412  [1]*x[2]*z[0]-z[2]*x[1]*x[1]*y[3]+y[2]*x[1]*x[1]*z[3]+y[5]*x[7]*x[7]*z[4]+y[6]*
413  x[7]*x[7]*z[5]+x[7]*x[6]*y[7]*z[2]+x[7]*y[6]*x[2]*z[7]-x[7]*z[6]*x[2]*y[7]-2.0*
414  x[7]*x[6]*y[3]*z[7];
415  s8 = s7+2.0*x[7]*x[6]*y[7]*z[3]+2.0*x[7]*y[6]*x[3]*z[7]-x[3]*z[2]*x[1]*y
416  [3]+x[3]*y[2]*x[1]*z[3]+x[5]*x[1]*y[0]*z[5]+x[4]*y[5]*x[6]*z[4]+x[5]*z[1]*x[0]*
417  y[5]-x[4]*z[6]*x[7]*y[5]-x[4]*x[5]*y[6]*z[4]+x[4]*x[5]*y[4]*z[6]-x[4]*z[5]*x[6]
418  *y[4]-x[1]*y[2]*x[3]*z[1]+x[1]*z[2]*x[3]*y[1]-x[2]*x[1]*y[0]*z[2]-x[2]*z[1]*x
419  [0]*y[2];
420  s5 = s8+x[2]*x[1]*y[2]*z[0]-x[2]*z[2]*x[0]*y[3]+x[2]*y[2]*x[0]*z[3]-x[2]*
421  y[2]*x[3]*z[0]+x[2]*z[2]*x[3]*y[0]+x[2]*y[1]*x[0]*z[2]+x[5]*y[6]*x[7]*z[5]+x[6]
422  *y[5]*x[7]*z[4]+2.0*x[6]*y[6]*x[7]*z[5]-x[7]*y[0]*x[3]*z[7]+x[7]*z[0]*x[3]*y[7]
423  -x[7]*x[0]*y[7]*z[3]+x[7]*x[0]*y[3]*z[7]+2.0*x[7]*x[7]*y[4]*z[3]-2.0*x[7]*x[7]*
424  y[3]*z[4]-2.0*x[1]*x[1]*y[2]*z[5];
425  s8 = s5-2.0*x[7]*x[4]*y[7]*z[3]+2.0*x[7]*x[3]*y[7]*z[4]-2.0*x[7]*x[3]*y
426  [4]*z[7]+2.0*x[7]*x[4]*y[3]*z[7]+2.0*x[1]*x[1]*y[5]*z[2]-x[1]*x[1]*y[2]*z[6]+x
427  [1]*x[1]*y[6]*z[2]+z[1]*x[5]*x[5]*y[2]-y[1]*x[5]*x[5]*z[2]-x[1]*x[1]*y[6]*z[5]+
428  x[1]*x[1]*y[5]*z[6]+x[5]*x[5]*y[6]*z[2]-x[5]*x[5]*y[2]*z[6]-2.0*y[1]*x[5]*x[5]*
429  z[6];
430  s7 = s8+2.0*z[1]*x[5]*x[5]*y[6]+2.0*x[1]*z[1]*x[5]*y[2]+2.0*x[1]*y[1]*x
431  [2]*z[5]-2.0*x[1]*z[1]*x[2]*y[5]-2.0*x[1]*y[1]*x[5]*z[2]-x[1]*y[1]*x[6]*z[2]-x
432  [1]*z[1]*x[2]*y[6]+x[1]*z[1]*x[6]*y[2]+x[1]*y[1]*x[2]*z[6]-x[5]*x[1]*y[2]*z[5]+
433  x[5]*y[1]*x[2]*z[5]-x[5]*z[1]*x[2]*y[5]+x[5]*x[1]*y[5]*z[2]-x[5]*y[1]*x[6]*z[2]
434  -x[5]*x[1]*y[2]*z[6];
435  s8 = s7+x[5]*x[1]*y[6]*z[2]+x[5]*z[1]*x[6]*y[2]+x[1]*x[2]*y[5]*z[6]-x[1]*
436  x[2]*y[6]*z[5]-x[1]*z[1]*x[6]*y[5]-x[1]*y[1]*x[5]*z[6]+x[1]*z[1]*x[5]*y[6]+x[1]
437  *y[1]*x[6]*z[5]-x[5]*x[6]*y[5]*z[2]+x[5]*x[2]*y[5]*z[6]-x[5]*x[2]*y[6]*z[5]+x
438  [5]*x[6]*y[2]*z[5]-2.0*x[5]*z[1]*x[6]*y[5]-2.0*x[5]*x[1]*y[6]*z[5]+2.0*x[5]*x
439  [1]*y[5]*z[6];
440  s6 = s8+2.0*x[5]*y[1]*x[6]*z[5]+2.0*x[2]*x[1]*y[6]*z[2]+2.0*x[2]*z[1]*x
441  [6]*y[2]-2.0*x[2]*x[1]*y[2]*z[6]+x[2]*x[5]*y[6]*z[2]+x[2]*x[6]*y[2]*z[5]-x[2]*x
442  [5]*y[2]*z[6]+y[1]*x[2]*x[2]*z[5]-z[1]*x[2]*x[2]*y[5]-2.0*x[2]*y[1]*x[6]*z[2]-x
443  [2]*x[6]*y[5]*z[2]-2.0*z[1]*x[2]*x[2]*y[6]+x[2]*x[2]*y[5]*z[6]-x[2]*x[2]*y[6]*z
444  [5]+2.0*y[1]*x[2]*x[2]*z[6]+x[2]*z[1]*x[5]*y[2];
445  s8 = s6-x[2]*x[1]*y[2]*z[5]+x[2]*x[1]*y[5]*z[2]-x[2]*y[1]*x[5]*z[2]+x[6]*
446  y[1]*x[2]*z[5]-x[6]*z[1]*x[2]*y[5]-z[1]*x[6]*x[6]*y[5]+y[1]*x[6]*x[6]*z[5]-y[1]
447  *x[6]*x[6]*z[2]-2.0*x[6]*x[6]*y[5]*z[2]+2.0*x[6]*x[6]*y[2]*z[5]+z[1]*x[6]*x[6]*
448  y[2]-x[6]*x[1]*y[6]*z[5]-x[6]*y[1]*x[5]*z[6]+x[6]*x[1]*y[5]*z[6];
449  s7 = s8+x[6]*z[1]*x[5]*y[6]-x[6]*z[1]*x[2]*y[6]-x[6]*x[1]*y[2]*z[6]+2.0*x
450  [6]*x[5]*y[6]*z[2]+2.0*x[6]*x[2]*y[5]*z[6]-2.0*x[6]*x[2]*y[6]*z[5]-2.0*x[6]*x
451  [5]*y[2]*z[6]+x[6]*x[1]*y[6]*z[2]+x[6]*y[1]*x[2]*z[6]-x[2]*x[2]*y[3]*z[7]+x[2]*
452  x[2]*y[7]*z[3]-x[2]*z[2]*x[3]*y[7]-x[2]*y[2]*x[7]*z[3]+x[2]*z[2]*x[7]*y[3]+x[2]
453  *y[2]*x[3]*z[7]-x[6]*x[6]*y[3]*z[7];
454  s8 = s7+x[6]*x[6]*y[7]*z[3]-x[6]*x[2]*y[3]*z[7]+x[6]*x[2]*y[7]*z[3]-x[6]*
455  y[6]*x[7]*z[3]+x[6]*y[6]*x[3]*z[7]-x[6]*z[6]*x[3]*y[7]+x[6]*z[6]*x[7]*y[3]+y[6]
456  *x[2]*x[2]*z[7]-z[6]*x[2]*x[2]*y[7]+2.0*x[2]*x[2]*y[6]*z[3]-x[2]*y[6]*x[7]*z[2]
457  -2.0*x[2]*y[2]*x[6]*z[3]-2.0*x[2]*x[2]*y[3]*z[6]+2.0*x[2]*y[2]*x[3]*z[6]-x[2]*x
458  [6]*y[2]*z[7];
459  s3 = s8+x[2]*x[6]*y[7]*z[2]+x[2]*z[6]*x[7]*y[2]+2.0*x[2]*z[2]*x[6]*y[3]
460  -2.0*x[2]*z[2]*x[3]*y[6]-y[2]*x[6]*x[6]*z[3]-2.0*x[6]*x[6]*y[2]*z[7]+2.0*x[6]*x
461  [6]*y[7]*z[2]+z[2]*x[6]*x[6]*y[3]-2.0*x[6]*y[6]*x[7]*z[2]+x[6]*y[2]*x[3]*z[6]-x
462  [6]*x[2]*y[3]*z[6]+2.0*x[6]*z[6]*x[7]*y[2]+2.0*x[6]*y[6]*x[2]*z[7]-2.0*x[6]*z
463  [6]*x[2]*y[7]+x[6]*x[2]*y[6]*z[3]-x[6]*z[2]*x[3]*y[6];
464  s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
465  [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
466  z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
467  +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
468  s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
469  x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
470  *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
471  [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
472  s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
473  [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
474  z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
475  -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
476  s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
477  x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
478  *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
479  [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
480  s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
481  y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
482  *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
483  [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
484  s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
485  x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
486  *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
487  [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
488  s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
489  [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
490  z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
491  +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
492  s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
493  x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
494  *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
495  [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
496  s4 = 1/s5;
497  s2 = s3*s4;
498  const double unknown0 = s1*s2;
499  s1 = 1.0/6.0;
500  s8 = 2.0*x[1]*y[0]*y[0]*z[4]+x[5]*y[0]*y[0]*z[4]-x[1]*y[4]*y[4]*z[0]+z[1]
501  *x[0]*y[4]*y[4]+x[1]*y[0]*y[0]*z[5]-z[1]*x[5]*y[0]*y[0]-2.0*z[1]*x[4]*y[0]*y[0]
502  +2.0*z[1]*x[3]*y[0]*y[0]+z[2]*x[3]*y[0]*y[0]+y[0]*y[0]*x[7]*z[3]+2.0*y[0]*y[0]*
503  x[4]*z[3]-2.0*x[1]*y[0]*y[0]*z[3]-2.0*x[5]*y[4]*y[4]*z[0]+2.0*z[5]*x[0]*y[4]*y
504  [4]+2.0*y[4]*y[5]*x[7]*z[4];
505  s7 = s8-x[3]*y[4]*y[4]*z[7]+x[7]*y[4]*y[4]*z[3]+z[0]*x[3]*y[4]*y[4]-2.0*x
506  [0]*y[4]*y[4]*z[7]-y[1]*x[1]*y[4]*z[0]-x[0]*y[4]*y[4]*z[3]+2.0*z[0]*x[7]*y[4]*y
507  [4]+y[4]*z[6]*x[4]*y[7]-y[0]*y[0]*x[7]*z[4]+y[0]*y[0]*x[4]*z[7]+2.0*y[4]*z[5]*x
508  [4]*y[7]-2.0*y[4]*x[5]*y[7]*z[4]-y[4]*x[6]*y[7]*z[4]-y[4]*y[6]*x[4]*z[7]-2.0*y
509  [4]*y[5]*x[4]*z[7];
510  s8 = y[4]*y[6]*x[7]*z[4]-y[7]*y[2]*x[7]*z[3]+y[7]*z[2]*x[7]*y[3]+y[7]*y
511  [2]*x[3]*z[7]+2.0*x[5]*y[4]*y[4]*z[7]-y[7]*x[2]*y[3]*z[7]-y[0]*z[0]*x[4]*y[7]+z
512  [6]*x[7]*y[3]*y[3]-y[0]*x[0]*y[4]*z[7]+y[0]*x[0]*y[7]*z[4]-2.0*x[2]*y[3]*y[3]*z
513  [7]-z[5]*x[4]*y[0]*y[0]+y[0]*z[0]*x[7]*y[4]-2.0*z[6]*x[3]*y[7]*y[7]+z[1]*x[2]*y
514  [0]*y[0];
515  s6 = s8+y[4]*y[0]*x[4]*z[3]-2.0*y[4]*z[0]*x[4]*y[7]+2.0*y[4]*x[0]*y[7]*z
516  [4]-y[4]*z[0]*x[4]*y[3]-y[4]*x[0]*y[7]*z[3]+y[4]*z[0]*x[3]*y[7]-y[4]*y[0]*x[3]*
517  z[4]+y[0]*x[4]*y[3]*z[7]-y[0]*x[7]*y[3]*z[4]-y[0]*x[3]*y[4]*z[7]+y[0]*x[7]*y[4]
518  *z[3]+x[2]*y[7]*y[7]*z[3]-z[2]*x[3]*y[7]*y[7]-2.0*z[2]*x[0]*y[3]*y[3]+2.0*y[0]*
519  z[1]*x[0]*y[4]+s7;
520  s8 = -2.0*y[0]*y[1]*x[0]*z[4]-y[0]*y[1]*x[0]*z[5]-y[0]*y[0]*x[3]*z[7]-z
521  [1]*x[0]*y[3]*y[3]-y[0]*x[1]*y[5]*z[0]-2.0*z[0]*x[7]*y[3]*y[3]+x[0]*y[3]*y[3]*z
522  [4]+2.0*x[0]*y[3]*y[3]*z[7]-z[0]*x[4]*y[3]*y[3]+2.0*x[2]*y[3]*y[3]*z[0]+x[1]*y
523  [3]*y[3]*z[0]+2.0*y[7]*z[6]*x[7]*y[3]+2.0*y[7]*y[6]*x[3]*z[7]-2.0*y[7]*y[6]*x
524  [7]*z[3]-2.0*y[7]*x[6]*y[3]*z[7];
525  s7 = s8+y[4]*x[4]*y[3]*z[7]-y[4]*x[4]*y[7]*z[3]+y[4]*x[3]*y[7]*z[4]-y[4]*
526  x[7]*y[3]*z[4]+2.0*y[4]*y[0]*x[4]*z[7]-2.0*y[4]*y[0]*x[7]*z[4]+2.0*x[6]*y[7]*y
527  [7]*z[3]+y[4]*x[0]*y[3]*z[4]+y[0]*y[1]*x[5]*z[0]+y[0]*z[1]*x[0]*y[5]-x[2]*y[0]*
528  y[0]*z[3]+x[4]*y[3]*y[3]*z[7]-x[7]*y[3]*y[3]*z[4]-x[5]*y[4]*y[4]*z[1]+y[3]*z[0]
529  *x[3]*y[4];
530  s8 = y[3]*y[0]*x[4]*z[3]+2.0*y[3]*y[0]*x[7]*z[3]+2.0*y[3]*y[2]*x[0]*z[3]
531  -2.0*y[3]*y[2]*x[3]*z[0]+2.0*y[3]*z[2]*x[3]*y[0]+y[3]*z[1]*x[3]*y[0]-2.0*y[3]*x
532  [2]*y[0]*z[3]-y[3]*x[1]*y[0]*z[3]-y[3]*y[1]*x[3]*z[0]-2.0*y[3]*x[0]*y[7]*z[3]-y
533  [3]*x[0]*y[4]*z[3]-2.0*y[3]*y[0]*x[3]*z[7]-y[3]*y[0]*x[3]*z[4]+2.0*y[3]*z[0]*x
534  [3]*y[7]+y[3]*y[1]*x[0]*z[3]+z[5]*x[1]*y[4]*y[4];
535  s5 = s8-2.0*y[0]*y[0]*x[3]*z[4]-2.0*y[0]*x[1]*y[4]*z[0]+y[3]*x[7]*y[4]*z
536  [3]-y[3]*x[4]*y[7]*z[3]+y[3]*x[3]*y[7]*z[4]-y[3]*x[3]*y[4]*z[7]+y[3]*x[0]*y[7]*
537  z[4]-y[3]*z[0]*x[4]*y[7]-2.0*y[4]*y[5]*x[0]*z[4]+s6+y[7]*x[0]*y[3]*z[7]-y[7]*z
538  [0]*x[7]*y[3]+y[7]*y[0]*x[7]*z[3]-y[7]*y[0]*x[3]*z[7]+2.0*y[0]*y[1]*x[4]*z[0]+
539  s7;
540  s8 = -2.0*y[7]*x[7]*y[3]*z[4]-2.0*y[7]*x[3]*y[4]*z[7]+2.0*y[7]*x[4]*y[3]*
541  z[7]+y[7]*y[0]*x[4]*z[7]-y[7]*y[0]*x[7]*z[4]+2.0*y[7]*x[7]*y[4]*z[3]-y[7]*x[0]*
542  y[4]*z[7]+y[7]*z[0]*x[7]*y[4]+z[5]*x[4]*y[7]*y[7]+2.0*z[6]*x[4]*y[7]*y[7]-x[5]*
543  y[7]*y[7]*z[4]-2.0*x[6]*y[7]*y[7]*z[4]+2.0*y[7]*x[6]*y[4]*z[7]-2.0*y[7]*z[6]*x
544  [7]*y[4]+2.0*y[7]*y[6]*x[7]*z[4];
545  s7 = s8-2.0*y[7]*y[6]*x[4]*z[7]-y[7]*z[5]*x[7]*y[4]-y[7]*y[5]*x[4]*z[7]-x
546  [0]*y[7]*y[7]*z[3]+z[0]*x[3]*y[7]*y[7]+y[7]*x[5]*y[4]*z[7]+y[7]*y[5]*x[7]*z[4]-
547  y[4]*x[1]*y[5]*z[0]-x[1]*y[0]*y[0]*z[2]-y[4]*y[5]*x[1]*z[4]-2.0*y[4]*z[5]*x[4]*
548  y[0]-y[4]*y[1]*x[0]*z[4]+y[4]*y[5]*x[4]*z[1]+y[0]*z[0]*x[3]*y[7]-y[0]*z[1]*x[0]
549  *y[2];
550  s8 = 2.0*y[0]*x[1]*y[3]*z[0]+y[4]*y[1]*x[4]*z[0]+2.0*y[0]*y[1]*x[0]*z[3]+
551  y[4]*x[1]*y[0]*z[5]-y[4]*z[1]*x[5]*y[0]+y[4]*z[1]*x[0]*y[5]-y[4]*z[1]*x[4]*y[0]
552  +y[4]*x[1]*y[0]*z[4]-y[4]*z[5]*x[4]*y[1]+x[5]*y[4]*y[4]*z[6]-z[5]*x[6]*y[4]*y
553  [4]+y[4]*x[5]*y[1]*z[4]-y[0]*z[2]*x[0]*y[3]+y[0]*y[5]*x[4]*z[0]+y[0]*x[1]*y[2]*
554  z[0];
555  s6 = s8-2.0*y[0]*z[0]*x[4]*y[3]-2.0*y[0]*x[0]*y[4]*z[3]-2.0*y[0]*z[1]*x
556  [0]*y[3]-y[0]*x[0]*y[7]*z[3]-2.0*y[0]*y[1]*x[3]*z[0]+y[0]*x[2]*y[3]*z[0]-y[0]*y
557  [1]*x[2]*z[0]+y[0]*y[1]*x[0]*z[2]-y[0]*x[2]*y[1]*z[3]+y[0]*x[0]*y[3]*z[7]+y[0]*
558  x[2]*y[3]*z[1]-y[0]*y[2]*x[3]*z[0]+y[0]*y[2]*x[0]*z[3]-y[0]*y[5]*x[0]*z[4]-y[4]
559  *y[5]*x[4]*z[6]+s7;
560  s8 = s6+y[4]*z[6]*x[5]*y[7]-y[4]*x[6]*y[7]*z[5]+y[4]*x[6]*y[5]*z[7]-y[4]*
561  z[6]*x[7]*y[5]-y[4]*x[5]*y[6]*z[4]+y[4]*z[5]*x[4]*y[6]+y[4]*y[5]*x[6]*z[4]-2.0*
562  y[1]*y[1]*x[0]*z[5]+2.0*y[1]*y[1]*x[5]*z[0]-2.0*y[2]*y[2]*x[6]*z[3]+x[5]*y[1]*y
563  [1]*z[4]-z[5]*x[4]*y[1]*y[1]-x[6]*y[2]*y[2]*z[7]+z[6]*x[7]*y[2]*y[2];
564  s7 = s8-x[1]*y[5]*y[5]*z[0]+z[1]*x[0]*y[5]*y[5]+y[1]*y[5]*x[4]*z[1]-y[1]*
565  y[5]*x[1]*z[4]-2.0*y[2]*z[2]*x[3]*y[6]+2.0*y[1]*z[1]*x[0]*y[5]-2.0*y[1]*z[1]*x
566  [5]*y[0]+2.0*y[1]*x[1]*y[0]*z[5]-y[2]*x[2]*y[3]*z[7]-y[2]*z[2]*x[3]*y[7]+y[2]*x
567  [2]*y[7]*z[3]+y[2]*z[2]*x[7]*y[3]-2.0*y[2]*x[2]*y[3]*z[6]+2.0*y[2]*x[2]*y[6]*z
568  [3]+2.0*y[2]*z[2]*x[6]*y[3]-y[3]*y[2]*x[6]*z[3];
569  s8 = y[3]*y[2]*x[3]*z[6]+y[3]*x[2]*y[6]*z[3]-y[3]*z[2]*x[3]*y[6]-y[2]*y
570  [2]*x[7]*z[3]+2.0*y[2]*y[2]*x[3]*z[6]+y[2]*y[2]*x[3]*z[7]-2.0*y[1]*x[1]*y[5]*z
571  [0]-x[2]*y[3]*y[3]*z[6]+z[2]*x[6]*y[3]*y[3]+2.0*y[6]*x[2]*y[5]*z[6]+2.0*y[6]*x
572  [6]*y[2]*z[5]-2.0*y[6]*x[5]*y[2]*z[6]+2.0*y[3]*x[2]*y[7]*z[3]-2.0*y[3]*z[2]*x
573  [3]*y[7]-y[0]*z[0]*x[7]*y[3]-y[0]*z[2]*x[1]*y[3];
574  s4 = s8-y[2]*y[6]*x[7]*z[2]+y[0]*z[2]*x[3]*y[1]+y[1]*z[5]*x[1]*y[4]-y[1]*
575  x[5]*y[4]*z[1]+2.0*y[0]*z[0]*x[3]*y[4]+2.0*y[0]*x[0]*y[3]*z[4]+2.0*z[2]*x[7]*y
576  [3]*y[3]-2.0*z[5]*x[7]*y[4]*y[4]+x[6]*y[4]*y[4]*z[7]-z[6]*x[7]*y[4]*y[4]+y[1]*y
577  [1]*x[0]*z[3]+y[3]*x[6]*y[7]*z[2]-y[3]*z[6]*x[2]*y[7]+2.0*y[3]*y[2]*x[3]*z[7]+
578  s5+s7;
579  s8 = s4+y[2]*x[6]*y[7]*z[2]-y[2]*y[6]*x[7]*z[3]+y[2]*y[6]*x[2]*z[7]-y[2]*
580  z[6]*x[2]*y[7]-y[2]*x[6]*y[3]*z[7]+y[2]*y[6]*x[3]*z[7]+y[2]*z[6]*x[7]*y[3]-2.0*
581  y[3]*y[2]*x[7]*z[3]-x[6]*y[3]*y[3]*z[7]+y[1]*y[1]*x[4]*z[0]-y[1]*y[1]*x[3]*z[0]
582  +x[2]*y[6]*y[6]*z[3]-z[2]*x[3]*y[6]*y[6]-y[1]*y[1]*x[0]*z[4];
583  s7 = s8+y[5]*x[1]*y[0]*z[5]+y[6]*x[2]*y[7]*z[3]-y[6]*y[2]*x[6]*z[3]+y[6]*
584  y[2]*x[3]*z[6]-y[6]*x[2]*y[3]*z[6]+y[6]*z[2]*x[6]*y[3]-y[5]*y[1]*x[0]*z[5]-y[5]
585  *z[1]*x[5]*y[0]+y[5]*y[1]*x[5]*z[0]-y[6]*z[2]*x[3]*y[7]-y[7]*y[6]*x[7]*z[2]+2.0
586  *y[6]*y[6]*x[2]*z[7]+y[6]*y[6]*x[3]*z[7]+x[6]*y[7]*y[7]*z[2]-z[6]*x[2]*y[7]*y
587  [7];
588  s8 = -x[2]*y[1]*y[1]*z[3]+2.0*y[1]*y[1]*x[0]*z[2]-2.0*y[1]*y[1]*x[2]*z[0]
589  +z[2]*x[3]*y[1]*y[1]-z[1]*x[0]*y[2]*y[2]+x[1]*y[2]*y[2]*z[0]+y[2]*y[2]*x[0]*z
590  [3]-y[2]*y[2]*x[3]*z[0]-2.0*y[2]*y[2]*x[3]*z[1]+y[1]*x[1]*y[3]*z[0]-2.0*y[6]*y
591  [6]*x[7]*z[2]+2.0*y[5]*y[5]*x[4]*z[1]-2.0*y[5]*y[5]*x[1]*z[4]-y[6]*y[6]*x[7]*z
592  [3]-2.0*y[1]*x[1]*y[0]*z[2];
593  s6 = s8+2.0*y[1]*z[1]*x[2]*y[0]-2.0*y[1]*z[1]*x[0]*y[2]+2.0*y[1]*x[1]*y
594  [2]*z[0]+y[1]*x[2]*y[3]*z[1]-y[1]*y[2]*x[3]*z[1]-y[1]*z[2]*x[1]*y[3]+y[1]*y[2]*
595  x[1]*z[3]-y[2]*x[1]*y[0]*z[2]+y[2]*z[1]*x[2]*y[0]+y[2]*x[2]*y[3]*z[0]-y[7]*x[6]
596  *y[2]*z[7]+y[7]*z[6]*x[7]*y[2]+y[7]*y[6]*x[2]*z[7]-y[6]*x[6]*y[3]*z[7]+y[6]*x
597  [6]*y[7]*z[3]+s7;
598  s8 = s6-y[6]*z[6]*x[3]*y[7]+y[6]*z[6]*x[7]*y[3]+2.0*y[2]*y[2]*x[1]*z[3]+x
599  [2]*y[3]*y[3]*z[1]-z[2]*x[1]*y[3]*y[3]+y[1]*x[1]*y[0]*z[4]+y[1]*z[1]*x[3]*y[0]-
600  y[1]*x[1]*y[0]*z[3]+2.0*y[5]*x[5]*y[1]*z[4]-2.0*y[5]*x[5]*y[4]*z[1]+2.0*y[5]*z
601  [5]*x[1]*y[4]-2.0*y[5]*z[5]*x[4]*y[1]-2.0*y[6]*x[6]*y[2]*z[7]+2.0*y[6]*x[6]*y
602  [7]*z[2];
603  s7 = s8+2.0*y[6]*z[6]*x[7]*y[2]-2.0*y[6]*z[6]*x[2]*y[7]-y[1]*z[1]*x[4]*y
604  [0]+y[1]*z[1]*x[0]*y[4]-y[1]*z[1]*x[0]*y[3]+2.0*y[6]*y[6]*x[7]*z[5]+2.0*y[5]*y
605  [5]*x[6]*z[4]-2.0*y[5]*y[5]*x[4]*z[6]+x[6]*y[5]*y[5]*z[7]-y[3]*x[2]*y[1]*z[3]-y
606  [3]*y[2]*x[3]*z[1]+y[3]*z[2]*x[3]*y[1]+y[3]*y[2]*x[1]*z[3]-y[2]*x[2]*y[0]*z[3]+
607  y[2]*z[2]*x[3]*y[0];
608  s8 = s7+2.0*y[2]*x[2]*y[3]*z[1]-2.0*y[2]*x[2]*y[1]*z[3]+y[2]*y[1]*x[0]*z
609  [2]-y[2]*y[1]*x[2]*z[0]+2.0*y[2]*z[2]*x[3]*y[1]-2.0*y[2]*z[2]*x[1]*y[3]-y[2]*z
610  [2]*x[0]*y[3]+y[5]*z[6]*x[5]*y[7]-y[5]*x[6]*y[7]*z[5]-y[5]*y[6]*x[4]*z[7]-y[5]*
611  y[6]*x[5]*z[7]-2.0*y[5]*x[5]*y[6]*z[4]+2.0*y[5]*x[5]*y[4]*z[6]-2.0*y[5]*z[5]*x
612  [6]*y[4]+2.0*y[5]*z[5]*x[4]*y[6];
613  s5 = s8-y[1]*y[5]*x[0]*z[4]-z[6]*x[7]*y[5]*y[5]+y[6]*y[6]*x[7]*z[4]-y[6]*
614  y[6]*x[4]*z[7]-2.0*y[6]*y[6]*x[5]*z[7]-x[5]*y[6]*y[6]*z[4]+z[5]*x[4]*y[6]*y[6]+
615  z[6]*x[5]*y[7]*y[7]-x[6]*y[7]*y[7]*z[5]+y[1]*y[5]*x[4]*z[0]+y[7]*y[6]*x[7]*z[5]
616  +y[6]*y[5]*x[7]*z[4]+y[5]*y[6]*x[7]*z[5]+y[6]*y[5]*x[6]*z[4]-y[6]*y[5]*x[4]*z
617  [6]+2.0*y[6]*z[6]*x[5]*y[7];
618  s8 = s5-2.0*y[6]*x[6]*y[7]*z[5]+2.0*y[6]*x[6]*y[5]*z[7]-2.0*y[6]*z[6]*x
619  [7]*y[5]-y[6]*x[5]*y[7]*z[4]-y[6]*x[6]*y[7]*z[4]+y[6]*x[6]*y[4]*z[7]-y[6]*z[6]*
620  x[7]*y[4]+y[6]*z[5]*x[4]*y[7]+y[6]*z[6]*x[4]*y[7]+y[6]*x[5]*y[4]*z[6]-y[6]*z[5]
621  *x[6]*y[4]+y[7]*x[6]*y[5]*z[7]-y[7]*z[6]*x[7]*y[5]-2.0*y[6]*x[6]*y[5]*z[2];
622  s7 = s8-y[7]*y[6]*x[5]*z[7]+2.0*y[4]*y[5]*x[4]*z[0]+2.0*x[3]*y[7]*y[7]*z
623  [4]-2.0*x[4]*y[7]*y[7]*z[3]-z[0]*x[4]*y[7]*y[7]+x[0]*y[7]*y[7]*z[4]-y[0]*z[5]*x
624  [4]*y[1]+y[0]*x[5]*y[1]*z[4]-y[0]*x[5]*y[4]*z[0]+y[0]*z[5]*x[0]*y[4]-y[5]*y[5]*
625  x[0]*z[4]+y[5]*y[5]*x[4]*z[0]+2.0*y[1]*y[1]*x[2]*z[5]-2.0*y[1]*y[1]*x[5]*z[2]+z
626  [1]*x[5]*y[2]*y[2];
627  s8 = s7-x[1]*y[2]*y[2]*z[5]-y[5]*z[5]*x[4]*y[0]+y[5]*z[5]*x[0]*y[4]-y[5]*
628  x[5]*y[4]*z[0]-y[2]*x[1]*y[6]*z[5]-y[2]*y[1]*x[5]*z[6]+y[2]*z[1]*x[5]*y[6]+y[2]
629  *y[1]*x[6]*z[5]-y[1]*z[1]*x[6]*y[5]-y[1]*x[1]*y[6]*z[5]+y[1]*x[1]*y[5]*z[6]+y
630  [1]*z[1]*x[5]*y[6]+y[5]*x[5]*y[0]*z[4]+y[2]*y[1]*x[2]*z[5]-y[2]*z[1]*x[2]*y[5];
631  s6 = s8+y[2]*x[1]*y[5]*z[2]-y[2]*y[1]*x[5]*z[2]-y[1]*y[1]*x[5]*z[6]+y[1]*
632  y[1]*x[6]*z[5]-z[1]*x[2]*y[5]*y[5]+x[1]*y[5]*y[5]*z[2]+2.0*y[1]*z[1]*x[5]*y[2]
633  -2.0*y[1]*x[1]*y[2]*z[5]-2.0*y[1]*z[1]*x[2]*y[5]+2.0*y[1]*x[1]*y[5]*z[2]-y[1]*y
634  [1]*x[6]*z[2]+y[1]*y[1]*x[2]*z[6]-2.0*y[5]*x[1]*y[6]*z[5]-2.0*y[5]*y[1]*x[5]*z
635  [6]+2.0*y[5]*z[1]*x[5]*y[6]+2.0*y[5]*y[1]*x[6]*z[5];
636  s8 = s6-y[6]*z[1]*x[6]*y[5]-y[6]*y[1]*x[5]*z[6]+y[6]*x[1]*y[5]*z[6]+y[6]*
637  y[1]*x[6]*z[5]-2.0*z[1]*x[6]*y[5]*y[5]+2.0*x[1]*y[5]*y[5]*z[6]-x[1]*y[6]*y[6]*z
638  [5]+z[1]*x[5]*y[6]*y[6]+y[5]*z[1]*x[5]*y[2]-y[5]*x[1]*y[2]*z[5]+y[5]*y[1]*x[2]*
639  z[5]-y[5]*y[1]*x[5]*z[2]-y[6]*z[1]*x[2]*y[5]+y[6]*x[1]*y[5]*z[2];
640  s7 = s8-y[1]*z[1]*x[2]*y[6]-y[1]*x[1]*y[2]*z[6]+y[1]*x[1]*y[6]*z[2]+y[1]*
641  z[1]*x[6]*y[2]+y[5]*x[5]*y[6]*z[2]-y[5]*x[2]*y[6]*z[5]+y[5]*x[6]*y[2]*z[5]-y[5]
642  *x[5]*y[2]*z[6]-x[6]*y[5]*y[5]*z[2]+x[2]*y[5]*y[5]*z[6]-y[5]*y[5]*x[4]*z[7]+y
643  [5]*y[5]*x[7]*z[4]-y[1]*x[6]*y[5]*z[2]+y[1]*x[2]*y[5]*z[6]-y[2]*x[6]*y[5]*z[2]
644  -2.0*y[2]*y[1]*x[6]*z[2];
645  s8 = s7-2.0*y[2]*z[1]*x[2]*y[6]+2.0*y[2]*x[1]*y[6]*z[2]+2.0*y[2]*y[1]*x
646  [2]*z[6]-2.0*x[1]*y[2]*y[2]*z[6]+2.0*z[1]*x[6]*y[2]*y[2]+x[6]*y[2]*y[2]*z[5]-x
647  [5]*y[2]*y[2]*z[6]+2.0*x[5]*y[6]*y[6]*z[2]-2.0*x[2]*y[6]*y[6]*z[5]-z[1]*x[2]*y
648  [6]*y[6]-y[6]*y[1]*x[6]*z[2]-y[6]*x[1]*y[2]*z[6]+y[6]*z[1]*x[6]*y[2]+y[6]*y[1]*
649  x[2]*z[6]+x[1]*y[6]*y[6]*z[2];
650  s3 = s8+y[2]*x[5]*y[6]*z[2]+y[2]*x[2]*y[5]*z[6]-y[2]*x[2]*y[6]*z[5]+y[5]*
651  z[5]*x[4]*y[7]+y[5]*x[5]*y[4]*z[7]-y[5]*z[5]*x[7]*y[4]-y[5]*x[5]*y[7]*z[4]+2.0*
652  y[4]*x[5]*y[0]*z[4]-y[3]*z[6]*x[3]*y[7]+y[3]*y[6]*x[3]*z[7]+y[3]*x[6]*y[7]*z[3]
653  -y[3]*y[6]*x[7]*z[3]-y[2]*y[1]*x[3]*z[0]-y[2]*z[1]*x[0]*y[3]+y[2]*y[1]*x[0]*z
654  [3]+y[2]*x[1]*y[3]*z[0];
655  s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
656  [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
657  z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
658  +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
659  s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
660  x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
661  *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
662  [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
663  s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
664  [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
665  z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
666  -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
667  s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
668  x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
669  *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
670  [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
671  s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
672  y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
673  *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
674  [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
675  s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
676  x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
677  *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
678  [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
679  s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
680  [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
681  z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
682  +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
683  s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
684  x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
685  *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
686  [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
687  s4 = 1/s5;
688  s2 = s3*s4;
689  const double unknown1 = s1*s2;
690  s1 = 1.0/6.0;
691  s8 = -z[2]*x[1]*y[2]*z[5]+z[2]*y[1]*x[2]*z[5]-z[2]*z[1]*x[2]*y[5]+z[2]*z
692  [1]*x[5]*y[2]+2.0*y[5]*x[7]*z[4]*z[4]-y[1]*x[2]*z[0]*z[0]+x[0]*y[3]*z[7]*z[7]
693  -2.0*z[5]*z[5]*x[4]*y[1]+2.0*z[5]*z[5]*x[1]*y[4]+z[5]*z[5]*x[0]*y[4]-2.0*z[2]*z
694  [2]*x[1]*y[3]+2.0*z[2]*z[2]*x[3]*y[1]-x[0]*y[4]*z[7]*z[7]-y[0]*x[3]*z[7]*z[7]+x
695  [1]*y[0]*z[5]*z[5];
696  s7 = s8-y[1]*x[0]*z[5]*z[5]+z[1]*y[1]*x[2]*z[6]+y[1]*x[0]*z[2]*z[2]+z[2]*
697  z[2]*x[3]*y[0]-z[2]*z[2]*x[0]*y[3]-x[1]*y[0]*z[2]*z[2]+2.0*z[5]*z[5]*x[4]*y[6]
698  -2.0*z[5]*z[5]*x[6]*y[4]-z[5]*z[5]*x[7]*y[4]-x[6]*y[7]*z[5]*z[5]+2.0*z[2]*y[1]*
699  x[2]*z[6]-2.0*z[2]*x[1]*y[2]*z[6]+2.0*z[2]*z[1]*x[6]*y[2]-y[6]*x[5]*z[7]*z[7]+
700  2.0*x[6]*y[4]*z[7]*z[7];
701  s8 = -2.0*y[6]*x[4]*z[7]*z[7]+x[6]*y[5]*z[7]*z[7]-2.0*z[2]*z[1]*x[2]*y[6]
702  +z[4]*y[6]*x[7]*z[5]+x[5]*y[4]*z[6]*z[6]+z[6]*z[6]*x[4]*y[7]-z[6]*z[6]*x[7]*y
703  [4]-2.0*z[6]*z[6]*x[7]*y[5]+2.0*z[6]*z[6]*x[5]*y[7]-y[5]*x[4]*z[6]*z[6]+2.0*z
704  [0]*z[0]*x[3]*y[4]-x[6]*y[5]*z[2]*z[2]+z[1]*z[1]*x[5]*y[6]-z[1]*z[1]*x[6]*y[5]-
705  z[5]*z[5]*x[4]*y[0];
706  s6 = s8+2.0*x[1]*y[3]*z[0]*z[0]+2.0*x[1]*y[6]*z[2]*z[2]-2.0*y[1]*x[6]*z
707  [2]*z[2]-y[1]*x[5]*z[2]*z[2]-z[1]*z[1]*x[2]*y[6]-2.0*z[1]*z[1]*x[2]*y[5]+2.0*z
708  [1]*z[1]*x[5]*y[2]+z[1]*y[1]*x[6]*z[5]+y[1]*x[2]*z[5]*z[5]+z[2]*z[1]*x[2]*y[0]+
709  z[1]*x[1]*y[5]*z[6]-z[1]*x[1]*y[6]*z[5]-z[1]*y[1]*x[5]*z[6]-z[1]*x[2]*y[6]*z[5]
710  +z[1]*x[6]*y[2]*z[5]+s7;
711  s8 = -x[1]*y[2]*z[5]*z[5]+z[1]*x[5]*y[6]*z[2]-2.0*z[2]*z[2]*x[3]*y[6]+2.0
712  *z[2]*z[2]*x[6]*y[3]+z[2]*z[2]*x[7]*y[3]-z[2]*z[2]*x[3]*y[7]-z[1]*x[6]*y[5]*z
713  [2]+2.0*z[1]*x[1]*y[5]*z[2]-2.0*x[3]*y[4]*z[7]*z[7]+2.0*x[4]*y[3]*z[7]*z[7]+x
714  [5]*y[6]*z[2]*z[2]+y[1]*x[2]*z[6]*z[6]+y[0]*x[4]*z[7]*z[7]+z[2]*x[2]*y[3]*z[0]-
715  x[1]*y[2]*z[6]*z[6];
716  s7 = s8-z[7]*z[2]*x[3]*y[7]+x[2]*y[6]*z[3]*z[3]-y[2]*x[6]*z[3]*z[3]-z[6]*
717  x[2]*y[3]*z[7]-z[2]*z[1]*x[0]*y[2]+z[6]*z[2]*x[6]*y[3]-z[6]*z[2]*x[3]*y[6]+z[6]
718  *x[2]*y[6]*z[3]+z[2]*x[1]*y[2]*z[0]+z[6]*y[2]*x[3]*z[7]-z[4]*z[5]*x[6]*y[4]+z
719  [4]*z[5]*x[4]*y[6]-z[4]*y[6]*x[5]*z[7]+z[4]*z[6]*x[4]*y[7]+z[4]*x[5]*y[4]*z[6];
720  s8 = -z[6]*y[2]*x[6]*z[3]-z[4]*y[5]*x[4]*z[6]-z[2]*y[1]*x[5]*z[6]+z[2]*x
721  [1]*y[5]*z[6]+z[4]*x[6]*y[4]*z[7]+2.0*z[4]*z[5]*x[4]*y[7]-z[4]*z[6]*x[7]*y[4]+x
722  [6]*y[7]*z[3]*z[3]-2.0*z[4]*z[5]*x[7]*y[4]-2.0*z[4]*y[5]*x[4]*z[7]-z[4]*y[6]*x
723  [4]*z[7]+z[4]*x[6]*y[5]*z[7]-z[4]*x[6]*y[7]*z[5]+2.0*z[4]*x[5]*y[4]*z[7]+z[2]*x
724  [2]*y[5]*z[6]-z[2]*x[2]*y[6]*z[5];
725  s5 = s8+z[2]*x[6]*y[2]*z[5]-z[2]*x[5]*y[2]*z[6]-z[2]*x[2]*y[3]*z[7]-x[2]*
726  y[3]*z[7]*z[7]+2.0*z[2]*x[2]*y[3]*z[1]-z[2]*y[2]*x[3]*z[0]+z[2]*y[2]*x[0]*z[3]-
727  z[2]*x[2]*y[0]*z[3]-z[7]*y[2]*x[7]*z[3]+z[7]*z[2]*x[7]*y[3]+z[7]*x[2]*y[7]*z[3]
728  +z[6]*y[1]*x[2]*z[5]-z[6]*x[1]*y[2]*z[5]+z[5]*x[1]*y[5]*z[2]+s6+s7;
729  s8 = z[5]*z[1]*x[5]*y[2]-z[5]*z[1]*x[2]*y[5]-y[6]*x[7]*z[2]*z[2]+2.0*z[2]
730  *x[2]*y[6]*z[3]-2.0*z[2]*x[2]*y[3]*z[6]+2.0*z[2]*y[2]*x[3]*z[6]+y[2]*x[3]*z[6]*
731  z[6]+y[6]*x[7]*z[5]*z[5]+z[2]*y[2]*x[3]*z[7]-z[2]*y[2]*x[7]*z[3]-2.0*z[2]*y[2]*
732  x[6]*z[3]+z[2]*x[2]*y[7]*z[3]+x[6]*y[2]*z[5]*z[5]-2.0*z[2]*x[2]*y[1]*z[3]-x[2]*
733  y[6]*z[5]*z[5];
734  s7 = s8-y[1]*x[5]*z[6]*z[6]+z[6]*x[1]*y[6]*z[2]-z[3]*z[2]*x[3]*y[6]+z[6]*
735  z[1]*x[6]*y[2]-z[6]*z[1]*x[2]*y[6]-z[6]*y[1]*x[6]*z[2]-2.0*x[5]*y[2]*z[6]*z[6]+
736  z[4]*z[1]*x[0]*y[4]-z[3]*x[2]*y[3]*z[6]-z[5]*y[1]*x[5]*z[2]+z[3]*y[2]*x[3]*z[6]
737  +2.0*x[2]*y[5]*z[6]*z[6]-z[5]*x[1]*y[5]*z[0]+y[2]*x[3]*z[7]*z[7]-x[2]*y[3]*z[6]
738  *z[6];
739  s8 = z[5]*y[5]*x[4]*z[0]+z[3]*z[2]*x[6]*y[3]+x[1]*y[5]*z[6]*z[6]+z[5]*y
740  [5]*x[7]*z[4]-z[1]*x[1]*y[2]*z[6]+z[1]*x[1]*y[6]*z[2]+2.0*z[6]*y[6]*x[7]*z[5]-z
741  [7]*y[6]*x[7]*z[2]-z[3]*y[6]*x[7]*z[2]+x[6]*y[7]*z[2]*z[2]-2.0*z[6]*y[6]*x[7]*z
742  [2]-2.0*x[6]*y[3]*z[7]*z[7]-x[6]*y[2]*z[7]*z[7]-z[5]*x[6]*y[5]*z[2]+y[6]*x[2]*z
743  [7]*z[7];
744  s6 = s8+2.0*y[6]*x[3]*z[7]*z[7]+z[6]*z[6]*x[7]*y[3]-y[6]*x[7]*z[3]*z[3]+z
745  [5]*x[5]*y[0]*z[4]+2.0*z[6]*z[6]*x[7]*y[2]-2.0*z[6]*z[6]*x[2]*y[7]-z[6]*z[6]*x
746  [3]*y[7]+z[7]*y[6]*x[7]*z[5]+z[7]*y[5]*x[7]*z[4]-2.0*z[7]*x[7]*y[3]*z[4]+2.0*z
747  [7]*x[3]*y[7]*z[4]-2.0*z[7]*x[4]*y[7]*z[3]+2.0*z[7]*x[7]*y[4]*z[3]-z[7]*y[0]*x
748  [7]*z[4]-2.0*z[7]*z[6]*x[3]*y[7]+s7;
749  s8 = s6+2.0*z[7]*z[6]*x[7]*y[3]+2.0*z[7]*x[6]*y[7]*z[3]+z[7]*x[6]*y[7]*z
750  [2]-2.0*z[7]*y[6]*x[7]*z[3]+z[7]*z[6]*x[7]*y[2]-z[7]*z[6]*x[2]*y[7]+z[5]*y[1]*x
751  [5]*z[0]-z[5]*z[1]*x[5]*y[0]+2.0*y[1]*x[6]*z[5]*z[5]-2.0*x[1]*y[6]*z[5]*z[5]+z
752  [5]*z[1]*x[0]*y[5]+z[6]*y[6]*x[3]*z[7]+2.0*z[6]*x[6]*y[7]*z[2]-z[6]*y[6]*x[7]*z
753  [3];
754  s7 = s8+2.0*z[6]*y[6]*x[2]*z[7]-z[6]*x[6]*y[3]*z[7]+z[6]*x[6]*y[7]*z[3]
755  -2.0*z[6]*x[6]*y[2]*z[7]-2.0*z[1]*y[1]*x[5]*z[2]-z[1]*y[1]*x[6]*z[2]-z[7]*z[0]*
756  x[7]*y[3]-2.0*z[6]*x[6]*y[5]*z[2]-z[2]*z[6]*x[3]*y[7]+z[2]*x[6]*y[7]*z[3]-z[2]*
757  z[6]*x[2]*y[7]+y[5]*x[6]*z[4]*z[4]+z[2]*y[6]*x[2]*z[7]+y[6]*x[7]*z[4]*z[4]+z[2]
758  *z[6]*x[7]*y[2]-2.0*x[5]*y[7]*z[4]*z[4];
759  s8 = -x[6]*y[7]*z[4]*z[4]-z[5]*y[5]*x[0]*z[4]-z[2]*x[6]*y[2]*z[7]-x[5]*y
760  [6]*z[4]*z[4]-2.0*z[5]*y[1]*x[5]*z[6]+2.0*z[5]*z[1]*x[5]*y[6]+2.0*z[5]*x[1]*y
761  [5]*z[6]-2.0*z[5]*z[1]*x[6]*y[5]-z[5]*x[5]*y[2]*z[6]+z[5]*x[5]*y[6]*z[2]+z[5]*x
762  [2]*y[5]*z[6]+z[5]*z[5]*x[4]*y[7]-y[5]*x[4]*z[7]*z[7]+x[5]*y[4]*z[7]*z[7]+z[6]*
763  z[1]*x[5]*y[6]+z[6]*y[1]*x[6]*z[5];
764  s4 = s8-z[6]*z[1]*x[6]*y[5]-z[6]*x[1]*y[6]*z[5]+z[2]*z[6]*x[7]*y[3]+2.0*z
765  [6]*x[6]*y[2]*z[5]+2.0*z[6]*x[5]*y[6]*z[2]-2.0*z[6]*x[2]*y[6]*z[5]+z[7]*z[0]*x
766  [3]*y[7]+z[7]*z[0]*x[7]*y[4]+z[3]*z[6]*x[7]*y[3]-z[3]*z[6]*x[3]*y[7]-z[3]*x[6]*
767  y[3]*z[7]+z[3]*y[6]*x[2]*z[7]-z[3]*x[6]*y[2]*z[7]+z[5]*x[5]*y[4]*z[7]+s5+s7;
768  s8 = s4+z[3]*y[6]*x[3]*z[7]-z[7]*x[0]*y[7]*z[3]+z[6]*x[5]*y[4]*z[7]+z[7]*
769  y[0]*x[7]*z[3]+z[5]*z[6]*x[4]*y[7]-2.0*z[5]*x[5]*y[6]*z[4]+2.0*z[5]*x[5]*y[4]*z
770  [6]-z[5]*x[5]*y[7]*z[4]-z[5]*y[6]*x[5]*z[7]-z[5]*z[6]*x[7]*y[4]-z[7]*z[0]*x[4]*
771  y[7]-z[5]*z[6]*x[7]*y[5]-z[5]*y[5]*x[4]*z[7]+z[7]*x[0]*y[7]*z[4];
772  s7 = s8-2.0*z[5]*y[5]*x[4]*z[6]+z[5]*z[6]*x[5]*y[7]+z[5]*x[6]*y[5]*z[7]+
773  2.0*z[5]*y[5]*x[6]*z[4]+z[6]*z[5]*x[4]*y[6]-z[6]*x[5]*y[6]*z[4]-z[6]*z[5]*x[6]*
774  y[4]-z[6]*x[6]*y[7]*z[4]-2.0*z[6]*y[6]*x[5]*z[7]+z[6]*x[6]*y[4]*z[7]-z[6]*y[5]*
775  x[4]*z[7]-z[6]*y[6]*x[4]*z[7]+z[6]*y[6]*x[7]*z[4]+z[6]*y[5]*x[6]*z[4]+2.0*z[6]*
776  x[6]*y[5]*z[7];
777  s8 = -2.0*z[6]*x[6]*y[7]*z[5]-z[2]*y[1]*x[2]*z[0]+2.0*z[7]*z[6]*x[4]*y[7]
778  -2.0*z[7]*x[6]*y[7]*z[4]-2.0*z[7]*z[6]*x[7]*y[4]+z[7]*z[5]*x[4]*y[7]-z[7]*z[5]*
779  x[7]*y[4]-z[7]*x[5]*y[7]*z[4]+2.0*z[7]*y[6]*x[7]*z[4]-z[7]*z[6]*x[7]*y[5]+z[7]*
780  z[6]*x[5]*y[7]-z[7]*x[6]*y[7]*z[5]+z[1]*z[1]*x[6]*y[2]+s7+x[1]*y[5]*z[2]*z[2];
781  s6 = s8+2.0*z[2]*y[2]*x[1]*z[3]-2.0*z[2]*y[2]*x[3]*z[1]-2.0*x[1]*y[4]*z
782  [0]*z[0]+2.0*y[1]*x[4]*z[0]*z[0]+2.0*x[2]*y[7]*z[3]*z[3]-2.0*y[2]*x[7]*z[3]*z
783  [3]-x[1]*y[5]*z[0]*z[0]+z[0]*z[0]*x[7]*y[4]+z[0]*z[0]*x[3]*y[7]+x[2]*y[3]*z[0]*
784  z[0]-2.0*y[1]*x[3]*z[0]*z[0]+y[5]*x[4]*z[0]*z[0]-2.0*z[0]*z[0]*x[4]*y[3]+x[1]*y
785  [2]*z[0]*z[0]-z[0]*z[0]*x[4]*y[7]+y[1]*x[5]*z[0]*z[0];
786  s8 = s6-y[2]*x[3]*z[0]*z[0]+y[1]*x[0]*z[3]*z[3]-2.0*x[0]*y[7]*z[3]*z[3]-x
787  [0]*y[4]*z[3]*z[3]-2.0*x[2]*y[0]*z[3]*z[3]-x[1]*y[0]*z[3]*z[3]+y[0]*x[4]*z[3]*z
788  [3]-2.0*z[0]*y[1]*x[0]*z[4]+2.0*z[0]*z[1]*x[0]*y[4]+2.0*z[0]*x[1]*y[0]*z[4]-2.0
789  *z[0]*z[1]*x[4]*y[0]-2.0*z[3]*x[2]*y[3]*z[7]-2.0*z[3]*z[2]*x[3]*y[7]+2.0*z[3]*z
790  [2]*x[7]*y[3];
791  s7 = s8+2.0*z[3]*y[2]*x[3]*z[7]+2.0*z[5]*y[5]*x[4]*z[1]+2.0*z[0]*y[1]*x
792  [0]*z[3]-z[0]*y[0]*x[3]*z[7]-2.0*z[0]*y[0]*x[3]*z[4]-z[0]*x[1]*y[0]*z[2]+z[0]*z
793  [1]*x[2]*y[0]-z[0]*y[1]*x[0]*z[5]-z[0]*z[1]*x[0]*y[2]-z[0]*x[0]*y[7]*z[3]-2.0*z
794  [0]*z[1]*x[0]*y[3]-z[5]*x[5]*y[4]*z[0]-2.0*z[0]*x[0]*y[4]*z[3]+z[0]*x[0]*y[7]*z
795  [4]-z[0]*z[2]*x[0]*y[3];
796  s8 = s7+z[0]*x[5]*y[0]*z[4]+z[0]*z[1]*x[0]*y[5]-z[0]*x[2]*y[0]*z[3]-z[0]*
797  z[1]*x[5]*y[0]-2.0*z[0]*x[1]*y[0]*z[3]+2.0*z[0]*y[0]*x[4]*z[3]-z[0]*x[0]*y[4]*z
798  [7]+z[0]*x[1]*y[0]*z[5]+z[0]*y[0]*x[7]*z[3]+z[0]*y[2]*x[0]*z[3]-z[0]*y[5]*x[0]*
799  z[4]+z[0]*z[2]*x[3]*y[0]+z[0]*x[2]*y[3]*z[1]+z[0]*x[0]*y[3]*z[7]-z[0]*x[2]*y[1]
800  *z[3];
801  s5 = s8+z[0]*y[1]*x[0]*z[2]+z[3]*x[1]*y[3]*z[0]-2.0*z[3]*y[0]*x[3]*z[7]-z
802  [3]*y[0]*x[3]*z[4]-z[3]*x[1]*y[0]*z[2]+z[3]*z[0]*x[7]*y[4]+2.0*z[3]*z[0]*x[3]*y
803  [7]+2.0*z[3]*x[2]*y[3]*z[0]-z[3]*y[1]*x[3]*z[0]-z[3]*z[1]*x[0]*y[3]-z[3]*z[0]*x
804  [4]*y[3]+z[3]*x[1]*y[2]*z[0]-z[3]*z[0]*x[4]*y[7]-2.0*z[3]*z[2]*x[0]*y[3]-z[3]*x
805  [0]*y[4]*z[7]-2.0*z[3]*y[2]*x[3]*z[0];
806  s8 = s5+2.0*z[3]*z[2]*x[3]*y[0]+z[3]*x[2]*y[3]*z[1]+2.0*z[3]*x[0]*y[3]*z
807  [7]+z[3]*y[1]*x[0]*z[2]-z[4]*y[0]*x[3]*z[7]-z[4]*x[1]*y[5]*z[0]-z[4]*y[1]*x[0]*
808  z[5]+2.0*z[4]*z[0]*x[7]*y[4]+z[4]*z[0]*x[3]*y[7]+2.0*z[4]*y[5]*x[4]*z[0]+2.0*y
809  [0]*x[7]*z[3]*z[3]+2.0*y[2]*x[0]*z[3]*z[3]-x[2]*y[1]*z[3]*z[3]-y[0]*x[3]*z[4]*z
810  [4];
811  s7 = s8-y[1]*x[0]*z[4]*z[4]+x[1]*y[0]*z[4]*z[4]+2.0*x[0]*y[7]*z[4]*z[4]+
812  2.0*x[5]*y[0]*z[4]*z[4]-2.0*y[5]*x[0]*z[4]*z[4]+2.0*z[1]*z[1]*x[2]*y[0]-2.0*z
813  [1]*z[1]*x[0]*y[2]+z[1]*z[1]*x[0]*y[4]-z[1]*z[1]*x[0]*y[3]-z[1]*z[1]*x[4]*y[0]+
814  2.0*z[1]*z[1]*x[0]*y[5]-2.0*z[1]*z[1]*x[5]*y[0]+x[2]*y[3]*z[1]*z[1]-x[5]*y[4]*z
815  [0]*z[0]-z[0]*z[0]*x[7]*y[3];
816  s8 = s7+x[7]*y[4]*z[3]*z[3]-x[4]*y[7]*z[3]*z[3]+y[2]*x[1]*z[3]*z[3]+x[0]*
817  y[3]*z[4]*z[4]-2.0*y[0]*x[7]*z[4]*z[4]+x[3]*y[7]*z[4]*z[4]-x[7]*y[3]*z[4]*z[4]-
818  y[5]*x[1]*z[4]*z[4]+x[5]*y[1]*z[4]*z[4]+z[1]*z[1]*x[3]*y[0]+y[5]*x[4]*z[1]*z[1]
819  -y[2]*x[3]*z[1]*z[1]-x[5]*y[4]*z[1]*z[1]-z[4]*x[0]*y[4]*z[3]-z[4]*z[0]*x[4]*y
820  [3];
821  s6 = s8-z[4]*z[1]*x[4]*y[0]-2.0*z[4]*z[0]*x[4]*y[7]+z[4]*y[1]*x[5]*z[0]
822  -2.0*z[5]*x[5]*y[4]*z[1]-z[4]*x[1]*y[4]*z[0]+z[4]*y[0]*x[4]*z[3]-2.0*z[4]*x[0]*
823  y[4]*z[7]+z[4]*x[1]*y[0]*z[5]-2.0*z[1]*x[1]*y[2]*z[5]+z[4]*x[0]*y[3]*z[7]+2.0*z
824  [5]*x[5]*y[1]*z[4]+z[4]*y[1]*x[4]*z[0]+z[1]*y[1]*x[0]*z[3]+z[1]*x[1]*y[3]*z[0]
825  -2.0*z[1]*x[1]*y[5]*z[0]-2.0*z[1]*x[1]*y[0]*z[2];
826  s8 = s6-2.0*z[1]*y[1]*x[0]*z[5]-z[1]*y[1]*x[0]*z[4]+2.0*z[1]*y[1]*x[2]*z
827  [5]-z[1]*y[1]*x[3]*z[0]-2.0*z[5]*y[5]*x[1]*z[4]+z[1]*y[5]*x[4]*z[0]+z[1]*x[1]*y
828  [0]*z[4]+2.0*z[1]*x[1]*y[2]*z[0]-z[1]*z[2]*x[0]*y[3]+2.0*z[1]*y[1]*x[5]*z[0]-z
829  [1]*x[1]*y[0]*z[3]-z[1]*x[1]*y[4]*z[0]+2.0*z[1]*x[1]*y[0]*z[5]-z[1]*y[2]*x[3]*z
830  [0];
831  s7 = s8+z[1]*z[2]*x[3]*y[0]-z[1]*x[2]*y[1]*z[3]+z[1]*y[1]*x[4]*z[0]+2.0*z
832  [1]*y[1]*x[0]*z[2]+2.0*z[0]*z[1]*x[3]*y[0]+2.0*z[0]*x[0]*y[3]*z[4]+z[0]*z[5]*x
833  [0]*y[4]+z[0]*y[0]*x[4]*z[7]-z[0]*y[0]*x[7]*z[4]-z[0]*x[7]*y[3]*z[4]-z[0]*z[5]*
834  x[4]*y[0]-z[0]*x[5]*y[4]*z[1]+z[3]*z[1]*x[3]*y[0]+z[3]*x[0]*y[3]*z[4]+z[3]*z[0]
835  *x[3]*y[4]+z[3]*y[0]*x[4]*z[7];
836  s8 = s7+z[3]*x[3]*y[7]*z[4]-z[3]*x[7]*y[3]*z[4]-z[3]*x[3]*y[4]*z[7]+z[3]*
837  x[4]*y[3]*z[7]-z[3]*y[2]*x[3]*z[1]+z[3]*z[2]*x[3]*y[1]-z[3]*z[2]*x[1]*y[3]-2.0*
838  z[3]*z[0]*x[7]*y[3]+z[4]*z[0]*x[3]*y[4]+2.0*z[4]*z[5]*x[0]*y[4]+2.0*z[4]*y[0]*x
839  [4]*z[7]-2.0*z[4]*x[5]*y[4]*z[0]+z[4]*y[5]*x[4]*z[1]+z[4]*x[7]*y[4]*z[3]-z[4]*x
840  [4]*y[7]*z[3];
841  s3 = s8-z[4]*x[3]*y[4]*z[7]+z[4]*x[4]*y[3]*z[7]-2.0*z[4]*z[5]*x[4]*y[0]-z
842  [4]*x[5]*y[4]*z[1]+z[4]*z[5]*x[1]*y[4]-z[4]*z[5]*x[4]*y[1]-2.0*z[1]*y[1]*x[2]*z
843  [0]+z[1]*z[5]*x[0]*y[4]-z[1]*z[5]*x[4]*y[0]-z[1]*y[5]*x[1]*z[4]+z[1]*x[5]*y[1]*
844  z[4]+z[1]*z[5]*x[1]*y[4]-z[1]*z[5]*x[4]*y[1]+z[1]*z[2]*x[3]*y[1]-z[1]*z[2]*x[1]
845  *y[3]+z[1]*y[2]*x[1]*z[3];
846  s8 = y[1]*x[0]*z[3]+x[1]*y[3]*z[0]-y[0]*x[3]*z[7]-x[1]*y[5]*z[0]-y[0]*x
847  [3]*z[4]-x[1]*y[0]*z[2]+z[1]*x[2]*y[0]-y[1]*x[0]*z[5]-z[1]*x[0]*y[2]-y[1]*x[0]*
848  z[4]+z[1]*x[5]*y[2]+z[0]*x[7]*y[4]+z[0]*x[3]*y[7]+z[1]*x[0]*y[4]-x[1]*y[2]*z[5]
849  +x[2]*y[3]*z[0]+y[1]*x[2]*z[5]-x[2]*y[3]*z[7];
850  s7 = s8-z[1]*x[2]*y[5]-y[1]*x[3]*z[0]-x[0]*y[7]*z[3]-z[1]*x[0]*y[3]+y[5]*
851  x[4]*z[0]-x[0]*y[4]*z[3]+y[5]*x[7]*z[4]-z[0]*x[4]*y[3]+x[1]*y[0]*z[4]-z[2]*x[3]
852  *y[7]-y[6]*x[7]*z[2]+x[1]*y[5]*z[2]+y[6]*x[7]*z[5]+x[0]*y[7]*z[4]+x[1]*y[2]*z
853  [0]-z[1]*x[4]*y[0]-z[0]*x[4]*y[7]-z[2]*x[0]*y[3];
854  s8 = x[5]*y[0]*z[4]+z[1]*x[0]*y[5]-x[2]*y[0]*z[3]-z[1]*x[5]*y[0]+y[1]*x
855  [5]*z[0]-x[1]*y[0]*z[3]-x[1]*y[4]*z[0]-y[1]*x[5]*z[2]+x[2]*y[7]*z[3]+y[0]*x[4]*
856  z[3]-x[0]*y[4]*z[7]+x[1]*y[0]*z[5]-y[1]*x[6]*z[2]-y[2]*x[6]*z[3]+y[0]*x[7]*z[3]
857  -y[2]*x[7]*z[3]+z[2]*x[7]*y[3]+y[2]*x[0]*z[3];
858  s6 = s8+y[2]*x[3]*z[7]-y[2]*x[3]*z[0]-x[6]*y[5]*z[2]-y[5]*x[0]*z[4]+z[2]*
859  x[3]*y[0]+x[2]*y[3]*z[1]+x[0]*y[3]*z[7]-x[2]*y[1]*z[3]+y[1]*x[4]*z[0]+y[1]*x[0]
860  *z[2]-z[1]*x[2]*y[6]+y[2]*x[3]*z[6]-y[1]*x[2]*z[0]+z[1]*x[3]*y[0]-x[1]*y[2]*z
861  [6]-x[2]*y[3]*z[6]+x[0]*y[3]*z[4]+z[0]*x[3]*y[4]+s7;
862  s8 = x[5]*y[4]*z[7]+s6+y[5]*x[6]*z[4]-y[5]*x[4]*z[6]+z[6]*x[5]*y[7]-x[6]*
863  y[2]*z[7]-x[6]*y[7]*z[5]+x[5]*y[6]*z[2]+x[6]*y[5]*z[7]+x[6]*y[7]*z[2]+y[6]*x[7]
864  *z[4]-y[6]*x[4]*z[7]-y[6]*x[7]*z[3]+z[6]*x[7]*y[2]+x[2]*y[5]*z[6]-x[2]*y[6]*z
865  [5]+y[6]*x[2]*z[7]+x[6]*y[2]*z[5];
866  s7 = s8-x[5]*y[2]*z[6]-z[6]*x[7]*y[5]-z[5]*x[7]*y[4]+z[5]*x[0]*y[4]-y[5]*
867  x[4]*z[7]+y[0]*x[4]*z[7]-z[6]*x[2]*y[7]-x[5]*y[4]*z[0]-x[5]*y[7]*z[4]-y[0]*x[7]
868  *z[4]+y[5]*x[4]*z[1]-x[6]*y[7]*z[4]+x[7]*y[4]*z[3]-x[4]*y[7]*z[3]+x[3]*y[7]*z
869  [4]-x[7]*y[3]*z[4]-x[6]*y[3]*z[7]+x[6]*y[4]*z[7];
870  s8 = -x[3]*y[4]*z[7]+x[4]*y[3]*z[7]-z[6]*x[7]*y[4]-z[1]*x[6]*y[5]+x[6]*y
871  [7]*z[3]-x[1]*y[6]*z[5]-y[1]*x[5]*z[6]+z[5]*x[4]*y[7]-z[5]*x[4]*y[0]+x[1]*y[5]*
872  z[6]-y[6]*x[5]*z[7]-y[2]*x[3]*z[1]+z[1]*x[5]*y[6]-y[5]*x[1]*z[4]+z[6]*x[4]*y[7]
873  +x[5]*y[1]*z[4]-x[5]*y[6]*z[4]+y[6]*x[3]*z[7]-x[5]*y[4]*z[1];
874  s5 = s8+x[5]*y[4]*z[6]+z[5]*x[1]*y[4]+y[1]*x[6]*z[5]-z[6]*x[3]*y[7]+z[6]*
875  x[7]*y[3]-z[5]*x[6]*y[4]-z[5]*x[4]*y[1]+z[5]*x[4]*y[6]+x[1]*y[6]*z[2]+x[2]*y[6]
876  *z[3]+z[2]*x[6]*y[3]+z[1]*x[6]*y[2]+z[2]*x[3]*y[1]-z[2]*x[1]*y[3]-z[2]*x[3]*y
877  [6]+y[2]*x[1]*z[3]+y[1]*x[2]*z[6]-z[0]*x[7]*y[3]+s7;
878  s4 = 1/s5;
879  s2 = s3*s4;
880  const double unknown2 = s1*s2;
881 
882  return Point<3> (unknown0, unknown1, unknown2);
883  }
884 
885 
886 
887  template <int structdim, int dim, int spacedim>
889  barycenter (const TriaAccessor<structdim, dim, spacedim> &)
890  {
891  // this function catches all the cases not
892  // explicitly handled above
893  Assert (false, ExcNotImplemented());
894  return Point<spacedim>();
895  }
896 
897 
898 
899 
900  template <int dim, int spacedim>
901  double
902  measure (const TriaAccessor<1, dim, spacedim> &accessor)
903  {
904  // remember that we use (dim-)linear
905  // mappings
906  return (accessor.vertex(1)-accessor.vertex(0)).norm();
907  }
908 
909 
910 
911  double
912  measure (const TriaAccessor<2,2,2> &accessor)
913  {
914  // the evaluation of the formulae
915  // is a bit tricky when done dimension
916  // independently, so we write this function
917  // for 2D and 3D separately
918  /*
919  Get the computation of the measure by this little Maple script. We
920  use the blinear mapping of the unit quad to the real quad. However,
921  every transformation mapping the unit faces to straight lines should
922  do.
923 
924  Remember that the area of the quad is given by
925  \int_K 1 dx dy = \int_{\hat K} |det J| d(xi) d(eta)
926 
927  # x and y are arrays holding the x- and y-values of the four vertices
928  # of this cell in real space.
929  x := array(0..3);
930  y := array(0..3);
931  tphi[0] := (1-xi)*(1-eta):
932  tphi[1] := xi*(1-eta):
933  tphi[2] := (1-xi)*eta:
934  tphi[3] := xi*eta:
935  x_real := sum(x[s]*tphi[s], s=0..3):
936  y_real := sum(y[s]*tphi[s], s=0..3):
937  detJ := diff(x_real,xi)*diff(y_real,eta) - diff(x_real,eta)*diff(y_real,xi):
938 
939  measure := simplify ( int ( int (detJ, xi=0..1), eta=0..1)):
940  readlib(C):
941 
942  C(measure, optimized);
943 
944  additional optimizaton: divide by 2 only one time
945  */
946 
947  const double x[4] = { accessor.vertex(0)(0),
948  accessor.vertex(1)(0),
949  accessor.vertex(2)(0),
950  accessor.vertex(3)(0)
951  };
952  const double y[4] = { accessor.vertex(0)(1),
953  accessor.vertex(1)(1),
954  accessor.vertex(2)(1),
955  accessor.vertex(3)(1)
956  };
957 
958  return (-x[1]*y[0]+x[1]*y[3]+y[0]*x[2]+x[0]*y[1]-x[0]*y[2]-y[1]*x[3]-x[2]*y[3]+x[3]*y[2])/2;
959  }
960 
961 
962  double
963  measure (const TriaAccessor<3, 3, 3> &accessor)
964  {
965  unsigned int vertex_indices[GeometryInfo<3>::vertices_per_cell];
966  for (unsigned int i=0; i<GeometryInfo<3>::vertices_per_cell; ++i)
967  vertex_indices[i] = accessor.vertex_index(i);
968 
969  return GridTools::cell_measure<3>(accessor.get_triangulation().get_vertices(),
970  vertex_indices);
971  }
972 
973 
974  // a 2d face in 3d space
975  double measure (const ::TriaAccessor<2,3,3> &accessor)
976  {
977  // If the face is planar, the diagonal from vertex 0 to vertex 3,
978  // v_03, should be in the plane P_012 of vertices 0, 1 and 2. Get
979  // the normal vector of P_012 and test if v_03 is orthogonal to
980  // that. If so, the face is planar and computing its area is simple.
981  const Tensor<1,3> v01 = accessor.vertex(1) - accessor.vertex(0);
982  const Tensor<1,3> v02 = accessor.vertex(2) - accessor.vertex(0);
983 
984  Tensor<1,3> normal = cross_product_3d(v01, v02);
985 
986  const Tensor<1,3> v03 = accessor.vertex(3) - accessor.vertex(0);
987 
988  // check whether v03 does not lie in the plane of v01 and v02
989  // (i.e., whether the face is not planar). we do so by checking
990  // whether the triple product (v01 x v02) * v03 forms a positive
991  // volume relative to |v01|*|v02|*|v03|. the test checks the
992  // squares of these to avoid taking norms/square roots:
993  if (std::abs((v03 * normal) * (v03 * normal) /
994  ((v03 * v03) * (v01 * v01) * (v02 * v02)))
995  >=
996  1e-24)
997  {
998  Assert (false,
999  ExcMessage("Computing the measure of a nonplanar face is not implemented!"));
1000  return std::numeric_limits<double>::quiet_NaN();
1001  }
1002 
1003  // the face is planar. then its area is 1/2 of the norm of the
1004  // cross product of the two diagonals
1005  const Tensor<1,3> v12 = accessor.vertex(2) - accessor.vertex(1);
1006  Tensor<1,3> twice_area = cross_product_3d(v03, v12);
1007  return 0.5 * twice_area.norm();
1008  }
1009 
1010 
1011 
1012  template <int structdim, int dim, int spacedim>
1013  double
1014  measure (const TriaAccessor<structdim, dim, spacedim> &)
1015  {
1016  // catch-all for all cases not explicitly
1017  // listed above
1018  Assert (false, ExcNotImplemented());
1019  return std::numeric_limits<double>::quiet_NaN();
1020  }
1021 
1022 
1023  template <int dim, int spacedim>
1024  Point<spacedim> get_new_point_on_object(const TriaAccessor<1, dim, spacedim> &obj)
1025  {
1027  return obj.get_manifold().get_new_point_on_line(it);
1028  }
1029 
1030  template <int dim, int spacedim>
1031  Point<spacedim> get_new_point_on_object(const TriaAccessor<2, dim, spacedim> &obj)
1032  {
1034  return obj.get_manifold().get_new_point_on_quad(it);
1035  }
1036 
1037  template <int dim, int spacedim>
1038  Point<spacedim> get_new_point_on_object(const TriaAccessor<3, dim, spacedim> &obj)
1039  {
1041  return obj.get_manifold().get_new_point_on_hex(it);
1042  }
1043 
1044  template <int structdim, int dim, int spacedim>
1045  Point<spacedim> get_new_point_on_object(const TriaAccessor<structdim, dim, spacedim> &obj,
1046  const bool use_laplace)
1047  {
1048  if (use_laplace == false)
1049  return get_new_point_on_object(obj);
1050  else
1051  {
1053  Quadrature<spacedim> quadrature = Manifolds::get_default_quadrature(it, use_laplace);
1054  return obj.get_manifold().get_new_point(quadrature);
1055  }
1056  }
1057 }
1058 
1059 
1060 
1061 /*------------------------ Static variables: TriaAccessorBase ---------------------------*/
1062 
1063 template <int structdim, int dim, int spacedim>
1065 
1066 template <int structdim, int dim, int spacedim>
1068 
1069 template <int structdim, int dim, int spacedim>
1071 
1072 
1073 /*------------------------ Functions: TriaAccessor ---------------------------*/
1074 
1075 template <int structdim, int dim, int spacedim>
1076 void
1079 {
1080  this->objects().cells[this->present_index] = object;
1081 }
1082 
1083 
1084 
1085 template <int structdim, int dim, int spacedim>
1088 barycenter () const
1089 {
1090  // call the function in the anonymous
1091  // namespace above
1092  return ::barycenter (*this);
1093 }
1094 
1095 
1096 
1097 template <int structdim, int dim, int spacedim>
1098 double
1100 measure () const
1101 {
1102  // call the function in the anonymous
1103  // namespace above
1104  return ::measure (*this);
1105 }
1106 
1107 
1108 
1109 template <>
1110 double TriaAccessor<1,1,1>::extent_in_direction(const unsigned int axis) const
1111 {
1112  (void)axis;
1113  Assert (axis == 0, ExcIndexRange (axis, 0, 1));
1114 
1115  return this->diameter();
1116 }
1117 
1118 
1119 template <>
1120 double TriaAccessor<1,1,2>::extent_in_direction(const unsigned int axis) const
1121 {
1122  (void)axis;
1123  Assert (axis == 0, ExcIndexRange (axis, 0, 1));
1124 
1125  return this->diameter();
1126 }
1127 
1128 
1129 template <>
1130 double TriaAccessor<2,2,2>::extent_in_direction(const unsigned int axis) const
1131 {
1132  const unsigned int lines[2][2] = {{2,3},
1133  {0,1}
1134  };
1135 
1136  Assert (axis < 2, ExcIndexRange (axis, 0, 2));
1137 
1138  return std::max(this->line(lines[axis][0])->diameter(),
1139  this->line(lines[axis][1])->diameter());
1140 }
1141 
1142 template <>
1143 double TriaAccessor<2,2,3>::extent_in_direction(const unsigned int axis) const
1144 {
1145  const unsigned int lines[2][2] = {{2,3},
1146  {0,1}
1147  };
1148 
1149  Assert (axis < 2, ExcIndexRange (axis, 0, 2));
1150 
1151  return std::max(this->line(lines[axis][0])->diameter(),
1152  this->line(lines[axis][1])->diameter());
1153 }
1154 
1155 
1156 template <>
1157 double TriaAccessor<3,3,3>::extent_in_direction(const unsigned int axis) const
1158 {
1159  const unsigned int lines[3][4] = {{2,3,6,7},
1160  {0,1,4,5},
1161  {8,9,10,11}
1162  };
1163 
1164  Assert (axis < 3, ExcIndexRange (axis, 0, 3));
1165 
1166  double lengths[4] = { this->line(lines[axis][0])->diameter(),
1167  this->line(lines[axis][1])->diameter(),
1168  this->line(lines[axis][2])->diameter(),
1169  this->line(lines[axis][3])->diameter()
1170  };
1171 
1172  return std::max(std::max(lengths[0], lengths[1]),
1173  std::max(lengths[2], lengths[3]));
1174 }
1175 
1176 
1177 // Recursively set manifold ids on hex iterators.
1178 template <>
1179 void
1181 set_all_manifold_ids (const types::manifold_id manifold_ind) const
1182 {
1183  set_manifold_id (manifold_ind);
1184 
1185  if (this->has_children())
1186  for (unsigned int c=0; c<this->n_children(); ++c)
1187  this->child(c)->set_all_manifold_ids (manifold_ind);
1188 
1189  // for hexes also set manifold_id
1190  // of bounding quads and lines
1191 
1192  // Six bonding quads
1193  for (unsigned int i=0; i<6; ++i)
1194  this->quad(i)->set_manifold_id(manifold_ind);
1195  // Twelve bounding lines
1196  for (unsigned int i=0; i<12; ++i)
1197  this->line(i)->set_manifold_id (manifold_ind);
1198 }
1199 
1200 
1201 template <int structdim, int dim, int spacedim>
1204 {
1205  // We use an FE_Q<structdim>(1) to extract the "weights" of each
1206  // vertex, used to get a point from the manifold.
1207  static FE_Q<structdim> fe(1);
1208 
1209  // Surrounding points and weights.
1210  std::vector<Point<spacedim> > p(GeometryInfo<structdim>::vertices_per_cell);
1211  std::vector<double> w(GeometryInfo<structdim>::vertices_per_cell);
1212 
1213  for (unsigned int i=0; i<GeometryInfo<structdim>::vertices_per_cell; ++i)
1214  {
1215  p[i] = this->vertex(i);
1216  w[i] = fe.shape_value(i, coordinates);
1217  }
1218 
1219  Quadrature<spacedim> quadrature(p, w);
1220  return this->get_manifold().get_new_point(quadrature);
1221 }
1222 
1223 
1224 template <int structdim, int dim, int spacedim>
1227  const bool use_laplace) const
1228 {
1229  if (respect_manifold == false)
1230  {
1231  Assert(use_laplace == false, ExcNotImplemented());
1232  Point<spacedim> p;
1233  for (unsigned int v=0; v<GeometryInfo<structdim>::vertices_per_cell; ++v)
1234  p += vertex(v);
1236  }
1237  else
1238  return get_new_point_on_object(*this, use_laplace);
1239 }
1240 
1241 
1242 /*------------------------ Functions: CellAccessor<1> -----------------------*/
1243 
1244 
1245 
1246 template <>
1247 bool CellAccessor<1>::point_inside (const Point<1> &p) const
1248 {
1249  return (this->vertex(0)[0] <= p[0]) && (p[0] <= this->vertex(1)[0]);
1250 }
1251 
1252 
1253 
1254 
1255 
1256 
1257 /*------------------------ Functions: CellAccessor<2> -----------------------*/
1258 
1259 
1260 
1261 template <>
1262 bool CellAccessor<2>::point_inside (const Point<2> &p) const
1263 {
1264  // we check whether the point is
1265  // inside the cell by making sure
1266  // that it on the inner side of
1267  // each line defined by the faces,
1268  // i.e. for each of the four faces
1269  // we take the line that connects
1270  // the two vertices and subdivide
1271  // the whole domain by that in two
1272  // and check whether the point is
1273  // on the `cell-side' (rather than
1274  // the `out-side') of this line. if
1275  // the point is on the `cell-side'
1276  // for all four faces, it must be
1277  // inside the cell.
1278 
1279  // we want the faces in counter
1280  // clockwise orientation
1281  static const int direction[4]= {-1,1,1,-1};
1282  for (unsigned int f=0; f<4; ++f)
1283  {
1284  // vector from the first vertex
1285  // of the line to the point
1286  const Tensor<1,2> to_p = p-this->vertex(
1288  // vector describing the line
1289  const Tensor<1,2> face = direction[f]*(
1290  this->vertex(GeometryInfo<2>::face_to_cell_vertices(f,1)) -
1291  this->vertex(GeometryInfo<2>::face_to_cell_vertices(f,0)));
1292 
1293  // if we rotate the face vector
1294  // by 90 degrees to the left
1295  // (i.e. it points to the
1296  // inside) and take the scalar
1297  // product with the vector from
1298  // the vertex to the point,
1299  // then the point is in the
1300  // `cell-side' if the scalar
1301  // product is positive. if this
1302  // is not the case, we can be
1303  // sure that the point is
1304  // outside
1305  if ((-face[1]*to_p[0]+face[0]*to_p[1])<0)
1306  return false;
1307  };
1308 
1309  // if we arrived here, then the
1310  // point is inside for all four
1311  // faces, and thus inside
1312  return true;
1313 }
1314 
1315 
1316 
1317 
1318 
1319 
1320 
1321 /*------------------------ Functions: CellAccessor<3> -----------------------*/
1322 
1323 
1324 
1325 template <>
1326 bool CellAccessor<3>::point_inside (const Point<3> &p) const
1327 {
1328  // original implementation by Joerg
1329  // Weimar
1330 
1331  // we first eliminate points based
1332  // on the maximum and minimum of
1333  // the corner coordinates, then
1334  // transform to the unit cell, and
1335  // check there.
1336  const unsigned int dim = 3;
1337  const unsigned int spacedim = 3;
1338  Point<spacedim> maxp = this->vertex(0);
1339  Point<spacedim> minp = this->vertex(0);
1340 
1341  for (unsigned int v=1; v<GeometryInfo<dim>::vertices_per_cell; ++v)
1342  for (unsigned int d=0; d<dim; ++d)
1343  {
1344  maxp[d] = std::max (maxp[d],this->vertex(v)[d]);
1345  minp[d] = std::min (minp[d],this->vertex(v)[d]);
1346  }
1347 
1348  // rule out points outside the
1349  // bounding box of this cell
1350  for (unsigned int d=0; d<dim; d++)
1351  if ((p[d] < minp[d]) || (p[d] > maxp[d]))
1352  return false;
1353 
1354  // now we need to check more carefully: transform to the
1355  // unit cube and check there. unfortunately, this isn't
1356  // completely trivial since the transform_real_to_unit_cell
1357  // function may throw an exception that indicates that the
1358  // point given could not be inverted. we take this as a sign
1359  // that the point actually lies outside, as also documented
1360  // for that function
1361  try
1362  {
1363  const TriaRawIterator< CellAccessor<dim,spacedim> > cell_iterator (*this);
1365  (StaticMappingQ1<dim,spacedim>::mapping.transform_real_to_unit_cell(cell_iterator, p)));
1366  }
1368  {
1369  return false;
1370  }
1371 }
1372 
1373 
1374 
1375 
1376 
1377 /*------------------------ Functions: CellAccessor<dim,spacedim> -----------------------*/
1378 
1379 // For codim>0 we proceed as follows:
1380 // 1) project point onto manifold and
1381 // 2) transform to the unit cell with a Q1 mapping
1382 // 3) then check if inside unit cell
1383 template<int dim, int spacedim>
1384 template<int dim_,int spacedim_ >
1387 {
1388  const TriaRawIterator< CellAccessor<dim_,spacedim_> > cell_iterator (*this);
1389  const Point< dim_ > p_unit =
1390  StaticMappingQ1<dim_,spacedim_>::mapping.transform_real_to_unit_cell(cell_iterator, p);
1391 
1393 
1394 }
1395 
1396 
1397 
1398 template <>
1399 bool CellAccessor<1,2>::point_inside (const Point<2> &p) const
1400 {
1401  return point_inside_codim<1,2>(p);
1402 }
1403 
1404 
1405 template <>
1406 bool CellAccessor<1,3>::point_inside (const Point<3> &p) const
1407 {
1408  return point_inside_codim<1,3>(p);
1409 }
1410 
1411 
1412 template <>
1413 bool CellAccessor<2,3>::point_inside (const Point<3> &p) const
1414 {
1415  return point_inside_codim<2,3>(p);
1416 }
1417 
1418 
1419 
1420 template <int dim, int spacedim>
1422 {
1423  switch (dim)
1424  {
1425  case 1:
1426  return at_boundary(0) || at_boundary(1);
1427  case 2:
1428  return (at_boundary(0) || at_boundary(1) ||
1429  at_boundary(2) || at_boundary(3));
1430  case 3:
1431  return (at_boundary(0) || at_boundary(1) ||
1432  at_boundary(2) || at_boundary(3) ||
1433  at_boundary(4) || at_boundary(5));
1434  default:
1435  Assert (false, ExcNotImplemented());
1436  return false;
1437  }
1438 }
1439 
1440 
1441 
1442 template <int dim, int spacedim>
1444 {
1445  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1446  return this->tria->levels[this->present_level]->cells.boundary_or_material_id[this->present_index].material_id;
1447 }
1448 
1449 
1450 
1451 template <int dim, int spacedim>
1453 {
1454  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1455  Assert ( mat_id < numbers::invalid_material_id, ExcIndexRange(mat_id,0,numbers::invalid_material_id));
1456  this->tria->levels[this->present_level]->cells.boundary_or_material_id[this->present_index].material_id = mat_id;
1457 }
1458 
1459 
1460 
1461 template <int dim, int spacedim>
1463 {
1464  set_material_id (mat_id);
1465 
1466  if (this->has_children())
1467  for (unsigned int c=0; c<this->n_children(); ++c)
1468  this->child(c)->recursively_set_material_id (mat_id);
1469 }
1470 
1471 
1472 
1473 template <int dim, int spacedim>
1474 void
1476 {
1477  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1478  Assert (this->active(),
1479  ExcMessage("set_subdomain_id() can only be called on active cells!"));
1480  this->tria->levels[this->present_level]->subdomain_ids[this->present_index]
1481  = new_subdomain_id;
1482 }
1483 
1484 
1485 template <int dim, int spacedim>
1487 {
1488  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1489  return this->tria->levels[this->present_level]->level_subdomain_ids[this->present_index];
1490 }
1491 
1492 
1493 
1494 template <int dim, int spacedim>
1495 void
1497 {
1498  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1499  this->tria->levels[this->present_level]->level_subdomain_ids[this->present_index]
1500  = new_level_subdomain_id;
1501 }
1502 
1503 
1504 template <int dim, int spacedim>
1506 {
1507  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1508  if (dim==spacedim)
1509  return true;
1510  else
1511  return this->tria->levels[this->present_level]->direction_flags[this->present_index];
1512 }
1513 
1514 
1515 
1516 template <int dim, int spacedim>
1517 void
1518 CellAccessor<dim, spacedim>::set_direction_flag (const bool new_direction_flag) const
1519 {
1520  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1521  if (dim<spacedim)
1522  this->tria->levels[this->present_level]->direction_flags[this->present_index]
1523  = new_direction_flag;
1524  else
1525  Assert (new_direction_flag == true,
1526  ExcMessage ("If dim==spacedim, direction flags are always true and "
1527  "can not be set to anything else."));
1528 }
1529 
1530 
1531 
1532 template <int dim, int spacedim>
1533 void
1534 CellAccessor<dim, spacedim>::set_active_cell_index (const unsigned int active_cell_index)
1535 {
1536  // set the active cell index. allow setting it also for non-active (and unused)
1537  // cells to allow resetting the index after refinement
1538  this->tria->levels[this->present_level]->active_cell_indices[this->present_index]
1539  = active_cell_index;
1540 }
1541 
1542 
1543 
1544 template <int dim, int spacedim>
1545 void
1546 CellAccessor<dim, spacedim>::set_parent (const unsigned int parent_index)
1547 {
1548  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1549  Assert (this->present_level > 0, TriaAccessorExceptions::ExcCellHasNoParent ());
1550  this->tria->levels[this->present_level]->parents[this->present_index / 2]
1551  = parent_index;
1552 }
1553 
1554 
1555 
1556 template <int dim, int spacedim>
1557 int
1560 {
1561  Assert (this->present_level > 0, TriaAccessorExceptions::ExcCellHasNoParent ());
1562 
1563  // the parent of two consecutive cells
1564  // is stored only once, since it is
1565  // the same
1566  return this->tria->levels[this->present_level]->parents[this->present_index / 2];
1567 }
1568 
1569 
1570 
1571 template <int dim, int spacedim>
1572 unsigned int
1575 {
1576  Assert (this->has_children()==false, TriaAccessorExceptions::ExcCellNotActive());
1577  return this->tria->levels[this->present_level]->active_cell_indices[this->present_index];
1578 }
1579 
1580 
1581 
1582 template <int dim, int spacedim>
1585 {
1586  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1587  Assert (this->present_level > 0, TriaAccessorExceptions::ExcCellHasNoParent ());
1589  q (this->tria, this->present_level-1, parent_index ());
1590 
1591  return q;
1592 }
1593 
1594 
1595 template <int dim, int spacedim>
1596 void
1599 {
1600  if (this->has_children())
1601  for (unsigned int c=0; c<this->n_children(); ++c)
1602  this->child(c)->recursively_set_subdomain_id (new_subdomain_id);
1603  else
1604  set_subdomain_id (new_subdomain_id);
1605 }
1606 
1607 
1608 
1609 template <int dim, int spacedim>
1611  const TriaIterator<CellAccessor<dim, spacedim> > &pointer) const
1612 {
1614 
1615  if (pointer.state() == IteratorState::valid)
1616  {
1617  this->tria->levels[this->present_level]->
1618  neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].first
1619  = pointer->present_level;
1620  this->tria->levels[this->present_level]->
1621  neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].second
1622  = pointer->present_index;
1623  }
1624  else
1625  {
1626  this->tria->levels[this->present_level]->
1627  neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].first
1628  = -1;
1629  this->tria->levels[this->present_level]->
1630  neighbors[this->present_index*GeometryInfo<dim>::faces_per_cell+i].second
1631  = -1;
1632  };
1633 }
1634 
1635 
1636 
1637 template <int dim, int spacedim>
1638 unsigned int CellAccessor<dim,spacedim>::neighbor_of_neighbor_internal (const unsigned int neighbor) const
1639 {
1641 
1642  // if we have a 1d mesh in 1d, we
1643  // can assume that the left
1644  // neighbor of the right neigbor is
1645  // the current cell. but that is an
1646  // invariant that isn't true if the
1647  // mesh is embedded in a higher
1648  // dimensional space, so we have to
1649  // fall back onto the generic code
1650  // below
1651  if ((dim==1) && (spacedim==dim))
1652  return GeometryInfo<dim>::opposite_face[neighbor];
1653 
1654  const TriaIterator<CellAccessor<dim, spacedim> > neighbor_cell = this->neighbor(neighbor);
1655 
1656  // usually, on regular patches of
1657  // the grid, this cell is just on
1658  // the opposite side of the
1659  // neighbor that the neighbor is of
1660  // this cell. for example in 2d, if
1661  // we want to know the
1662  // neighbor_of_neighbor if
1663  // neighbor==1 (the right
1664  // neighbor), then we will get 3
1665  // (the left neighbor) in most
1666  // cases. look up this relationship
1667  // in the table provided by
1668  // GeometryInfo and try it
1669  const unsigned int this_face_index=face_index(neighbor);
1670 
1671  const unsigned int neighbor_guess
1673 
1674  if (neighbor_cell->face_index (neighbor_guess) == this_face_index)
1675  return neighbor_guess;
1676  else
1677  // if the guess was false, then
1678  // we need to loop over all
1679  // neighbors and find the number
1680  // the hard way
1681  {
1682  for (unsigned int face_no=0; face_no<GeometryInfo<dim>::faces_per_cell; ++face_no)
1683  if (neighbor_cell->face_index (face_no) == this_face_index)
1684  return face_no;
1685 
1686  // running over all neighbors
1687  // faces we did not find the
1688  // present face. Thereby the
1689  // neighbor must be coarser
1690  // than the present
1691  // cell. Return an invalid
1692  // unsigned int in this case.
1694  }
1695 }
1696 
1697 
1698 
1699 template <int dim, int spacedim>
1700 unsigned int CellAccessor<dim,spacedim>::neighbor_of_neighbor (const unsigned int neighbor) const
1701 {
1702  const unsigned int n2=neighbor_of_neighbor_internal(neighbor);
1704  TriaAccessorExceptions::ExcNeighborIsCoarser());
1705 
1706  return n2;
1707 }
1708 
1709 
1710 
1711 template <int dim, int spacedim>
1712 bool
1713 CellAccessor<dim,spacedim>::neighbor_is_coarser (const unsigned int neighbor) const
1714 {
1715  return neighbor_of_neighbor_internal(neighbor)==numbers::invalid_unsigned_int;
1716 }
1717 
1718 
1719 
1720 template <int dim, int spacedim>
1721 std::pair<unsigned int, unsigned int>
1723 {
1725  // make sure that the neighbor is
1726  // on a coarser level
1727  Assert (neighbor_is_coarser(neighbor),
1728  TriaAccessorExceptions::ExcNeighborIsNotCoarser());
1729 
1730  switch (dim)
1731  {
1732  case 2:
1733  {
1734  const int this_face_index=face_index(neighbor);
1735  const TriaIterator<CellAccessor<2,spacedim> > neighbor_cell = this->neighbor(neighbor);
1736 
1737  // usually, on regular patches of
1738  // the grid, this cell is just on
1739  // the opposite side of the
1740  // neighbor that the neighbor is of
1741  // this cell. for example in 2d, if
1742  // we want to know the
1743  // neighbor_of_neighbor if
1744  // neighbor==1 (the right
1745  // neighbor), then we will get 0
1746  // (the left neighbor) in most
1747  // cases. look up this relationship
1748  // in the table provided by
1749  // GeometryInfo and try it
1750  const unsigned int face_no_guess
1751  = GeometryInfo<2>::opposite_face[neighbor];
1752 
1754  =neighbor_cell->face(face_no_guess);
1755 
1756  if (face_guess->has_children())
1757  for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
1758  if (face_guess->child_index(subface_no)==this_face_index)
1759  return std::make_pair (face_no_guess, subface_no);
1760 
1761  // if the guess was false, then
1762  // we need to loop over all faces
1763  // and subfaces and find the
1764  // number the hard way
1765  for (unsigned int face_no=0; face_no<GeometryInfo<2>::faces_per_cell; ++face_no)
1766  {
1767  if (face_no!=face_no_guess)
1768  {
1770  =neighbor_cell->face(face_no);
1771  if (face->has_children())
1772  for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
1773  if (face->child_index(subface_no)==this_face_index)
1774  return std::make_pair (face_no, subface_no);
1775  }
1776  }
1777 
1778  // we should never get here,
1779  // since then we did not find
1780  // our way back...
1781  Assert (false, ExcInternalError());
1782  return std::make_pair (numbers::invalid_unsigned_int,
1784  }
1785 
1786  case 3:
1787  {
1788  const int this_face_index=face_index(neighbor);
1790  neighbor_cell = this->neighbor(neighbor);
1791 
1792  // usually, on regular patches of the grid, this cell is just on the
1793  // opposite side of the neighbor that the neighbor is of this cell.
1794  // for example in 2d, if we want to know the neighbor_of_neighbor if
1795  // neighbor==1 (the right neighbor), then we will get 0 (the left
1796  // neighbor) in most cases. look up this relationship in the table
1797  // provided by GeometryInfo and try it
1798  const unsigned int face_no_guess
1799  = GeometryInfo<3>::opposite_face[neighbor];
1800 
1801  const TriaIterator<TriaAccessor<3-1, 3, spacedim> > face_guess
1802  =neighbor_cell->face(face_no_guess);
1803 
1804  if (face_guess->has_children())
1805  for (unsigned int subface_no=0; subface_no<face_guess->n_children(); ++subface_no)
1806  {
1807  if (face_guess->child_index(subface_no)==this_face_index)
1808  // call a helper function, that translates the current
1809  // subface number to a subface number for the current
1810  // FaceRefineCase
1811  return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no));
1812 
1813  if (face_guess->child(subface_no)->has_children())
1814  for (unsigned int subsub_no=0; subsub_no<face_guess->child(subface_no)->n_children(); ++subsub_no)
1815  if (face_guess->child(subface_no)->child_index(subsub_no)==this_face_index)
1816  // call a helper function, that translates the current
1817  // subface number and subsubface number to a subface
1818  // number for the current FaceRefineCase
1819  return std::make_pair (face_no_guess, translate_subface_no(face_guess, subface_no, subsub_no));
1820  }
1821 
1822  // if the guess was false, then we need to loop over all faces and
1823  // subfaces and find the number the hard way
1824  for (unsigned int face_no=0; face_no<GeometryInfo<3>::faces_per_cell; ++face_no)
1825  {
1826  if (face_no==face_no_guess)
1827  continue;
1828 
1829  const TriaIterator<TriaAccessor<3-1, 3, spacedim> > face
1830  =neighbor_cell->face(face_no);
1831 
1832  if (!face->has_children())
1833  continue;
1834 
1835  for (unsigned int subface_no=0; subface_no<face->n_children(); ++subface_no)
1836  {
1837  if (face->child_index(subface_no)==this_face_index)
1838  // call a helper function, that translates the current
1839  // subface number to a subface number for the current
1840  // FaceRefineCase
1841  return std::make_pair (face_no, translate_subface_no(face, subface_no));
1842 
1843  if (face->child(subface_no)->has_children())
1844  for (unsigned int subsub_no=0; subsub_no<face->child(subface_no)->n_children(); ++subsub_no)
1845  if (face->child(subface_no)->child_index(subsub_no)==this_face_index)
1846  // call a helper function, that translates the current
1847  // subface number and subsubface number to a subface
1848  // number for the current FaceRefineCase
1849  return std::make_pair (face_no, translate_subface_no(face, subface_no, subsub_no));
1850  }
1851  }
1852 
1853  // we should never get here, since then we did not find our way
1854  // back...
1855  Assert (false, ExcInternalError());
1856  return std::make_pair (numbers::invalid_unsigned_int,
1858  }
1859 
1860  default:
1861  {
1862  Assert(false, ExcImpossibleInDim(1));
1863  return std::make_pair (numbers::invalid_unsigned_int,
1865  }
1866  }
1867 }
1868 
1869 
1870 
1871 template <int dim, int spacedim>
1872 bool CellAccessor<dim, spacedim>::at_boundary (const unsigned int i) const
1873 {
1874  Assert (this->used(), TriaAccessorExceptions::ExcCellNotUsed());
1876  ExcIndexRange (i,0,GeometryInfo<dim>::faces_per_cell));
1877 
1878  return (neighbor_index(i) == -1);
1879 }
1880 
1881 
1882 
1883 template <int dim, int spacedim>
1885 {
1886  if (dim == 1)
1887  return at_boundary ();
1888  else
1889  {
1890  for (unsigned int l=0; l<GeometryInfo<dim>::lines_per_cell; ++l)
1891  if (this->line(l)->at_boundary())
1892  return true;
1893 
1894  return false;
1895  }
1896 }
1897 
1898 
1899 
1900 template <int dim, int spacedim>
1903 neighbor_child_on_subface (const unsigned int face,
1904  const unsigned int subface) const
1905 {
1906  Assert (!this->has_children(),
1907  ExcMessage ("The present cell must not have children!"));
1908  Assert (!this->at_boundary(face),
1909  ExcMessage ("The present cell must have a valid neighbor!"));
1910  Assert (this->neighbor(face)->has_children() == true,
1911  ExcMessage ("The neighbor must have children!"));
1912 
1913  switch (dim)
1914  {
1915  case 2:
1916  {
1917  const unsigned int neighbor_neighbor
1918  = this->neighbor_of_neighbor (face);
1919  const unsigned int neighbor_child_index
1921  this->neighbor(face)->refinement_case(),neighbor_neighbor,subface);
1922 
1924  = this->neighbor(face)->child(neighbor_child_index);
1925  // the neighbors child can have children,
1926  // which are not further refined along the
1927  // face under consideration. as we are
1928  // normally interested in one of this
1929  // child's child, search for the right one.
1930  while (sub_neighbor->has_children())
1931  {
1932  Assert ((GeometryInfo<dim>::face_refinement_case(sub_neighbor->refinement_case(),
1933  neighbor_neighbor) ==
1935  ExcInternalError());
1936  sub_neighbor = sub_neighbor->child(GeometryInfo<dim>::child_cell_on_face(
1937  sub_neighbor->refinement_case(),neighbor_neighbor,0));
1938 
1939  }
1940 
1941  return sub_neighbor;
1942  }
1943 
1944 
1945  case 3:
1946  {
1947  // this function returns the neighbor's
1948  // child on a given face and
1949  // subface.
1950 
1951  // we have to consider one other aspect here:
1952  // The face might be refined
1953  // anisotropically. In this case, the subface
1954  // number refers to the following, where we
1955  // look at the face from the current cell,
1956  // thus the subfaces are in standard
1957  // orientation concerning the cell
1958  //
1959  // for isotropic refinement
1960  //
1961  // *---*---*
1962  // | 2 | 3 |
1963  // *---*---*
1964  // | 0 | 1 |
1965  // *---*---*
1966  //
1967  // for 2*anisotropic refinement
1968  // (first cut_y, then cut_x)
1969  //
1970  // *---*---*
1971  // | 2 | 3 |
1972  // *---*---*
1973  // | 0 | 1 |
1974  // *---*---*
1975  //
1976  // for 2*anisotropic refinement
1977  // (first cut_x, then cut_y)
1978  //
1979  // *---*---*
1980  // | 1 | 3 |
1981  // *---*---*
1982  // | 0 | 2 |
1983  // *---*---*
1984  //
1985  // for purely anisotropic refinement:
1986  //
1987  // *---*---* *-------*
1988  // | | | | 1 |
1989  // | 0 | 1 | or *-------*
1990  // | | | | 0 |
1991  // *---*---* *-------*
1992  //
1993  // for "mixed" refinement:
1994  //
1995  // *---*---* *---*---* *---*---* *-------*
1996  // | | 2 | | 1 | | | 1 | 2 | | 2 |
1997  // | 0 *---* or *---* 2 | or *---*---* or *---*---*
1998  // | | 1 | | 0 | | | 0 | | 0 | 1 |
1999  // *---*---* *---*---* *-------* *---*---*
2000 
2002  mother_face = this->face(face);
2003  const unsigned int total_children=mother_face->number_of_children();
2004  Assert (subface<total_children,ExcIndexRange(subface,0,total_children));
2005  Assert (total_children<=GeometryInfo<3>::max_children_per_face, ExcInternalError());
2006 
2007  unsigned int neighbor_neighbor;
2008  TriaIterator<CellAccessor<3,spacedim> > neighbor_child;
2009  const TriaIterator<CellAccessor<3,spacedim> > neighbor
2010  = this->neighbor(face);
2011 
2012 
2013  const RefinementCase<2> mother_face_ref_case
2014  = mother_face->refinement_case();
2015  if (mother_face_ref_case==RefinementCase<2>::cut_xy) // total_children==4
2016  {
2017  // this case is quite easy. we are sure,
2018  // that the neighbor is not coarser.
2019 
2020  // get the neighbor's number for the given
2021  // face and the neighbor
2022  neighbor_neighbor
2023  = this->neighbor_of_neighbor (face);
2024 
2025  // now use the info provided by GeometryInfo
2026  // to extract the neighbors child number
2027  const unsigned int neighbor_child_index
2028  = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
2029  neighbor_neighbor, subface,
2030  neighbor->face_orientation(neighbor_neighbor),
2031  neighbor->face_flip(neighbor_neighbor),
2032  neighbor->face_rotation(neighbor_neighbor));
2033  neighbor_child = neighbor->child(neighbor_child_index);
2034 
2035  // make sure that the neighbor child cell we
2036  // have found shares the desired subface.
2037  Assert((this->face(face)->child(subface) ==
2038  neighbor_child->face(neighbor_neighbor)),
2039  ExcInternalError());
2040  }
2041  else //-> the face is refined anisotropically
2042  {
2043  // first of all, we have to find the
2044  // neighbor at one of the anisotropic
2045  // children of the
2046  // mother_face. determine, which of
2047  // these we need.
2048  unsigned int first_child_to_find;
2049  unsigned int neighbor_child_index;
2050  if (total_children==2)
2051  first_child_to_find=subface;
2052  else
2053  {
2054  first_child_to_find=subface/2;
2055  if (total_children==3 &&
2056  subface==1 &&
2057  !mother_face->child(0)->has_children())
2058  first_child_to_find=1;
2059  }
2060  if (neighbor_is_coarser(face))
2061  {
2062  std::pair<unsigned int, unsigned int> indices=neighbor_of_coarser_neighbor(face);
2063  neighbor_neighbor=indices.first;
2064 
2065 
2066  // we have to translate our
2067  // subface_index according to the
2068  // RefineCase and subface index of
2069  // the coarser face (our face is an
2070  // anisotropic child of the coarser
2071  // face), 'a' denotes our
2072  // subface_index 0 and 'b' denotes
2073  // our subface_index 1, whereas 0...3
2074  // denote isotropic subfaces of the
2075  // coarser face
2076  //
2077  // cut_x and coarser_subface_index=0
2078  //
2079  // *---*---*
2080  // |b=2| |
2081  // | | |
2082  // |a=0| |
2083  // *---*---*
2084  //
2085  // cut_x and coarser_subface_index=1
2086  //
2087  // *---*---*
2088  // | |b=3|
2089  // | | |
2090  // | |a=1|
2091  // *---*---*
2092  //
2093  // cut_y and coarser_subface_index=0
2094  //
2095  // *-------*
2096  // | |
2097  // *-------*
2098  // |a=0 b=1|
2099  // *-------*
2100  //
2101  // cut_y and coarser_subface_index=1
2102  //
2103  // *-------*
2104  // |a=2 b=3|
2105  // *-------*
2106  // | |
2107  // *-------*
2108  unsigned int iso_subface;
2109  if (neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_x)
2110  iso_subface=2*first_child_to_find + indices.second;
2111  else
2112  {
2113  Assert(neighbor->face(neighbor_neighbor)->refinement_case()==RefinementCase<2>::cut_y,
2114  ExcInternalError());
2115  iso_subface=first_child_to_find + 2*indices.second;
2116  }
2117  neighbor_child_index
2118  = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
2119  neighbor_neighbor,
2120  iso_subface,
2121  neighbor->face_orientation(neighbor_neighbor),
2122  neighbor->face_flip(neighbor_neighbor),
2123  neighbor->face_rotation(neighbor_neighbor));
2124  }
2125  else //neighbor is not coarser
2126  {
2127  neighbor_neighbor=neighbor_of_neighbor(face);
2128  neighbor_child_index
2129  = GeometryInfo<3>::child_cell_on_face(neighbor->refinement_case(),
2130  neighbor_neighbor,
2131  first_child_to_find,
2132  neighbor->face_orientation(neighbor_neighbor),
2133  neighbor->face_flip(neighbor_neighbor),
2134  neighbor->face_rotation(neighbor_neighbor),
2135  mother_face_ref_case);
2136  }
2137 
2138  neighbor_child=neighbor->child(neighbor_child_index);
2139  // it might be, that the neighbor_child
2140  // has children, which are not refined
2141  // along the given subface. go down that
2142  // list and deliver the last of those.
2143  while (neighbor_child->has_children() &&
2144  GeometryInfo<3>::face_refinement_case(neighbor_child->refinement_case(),
2145  neighbor_neighbor)
2147  neighbor_child =
2148  neighbor_child->child(GeometryInfo<3>::
2149  child_cell_on_face(neighbor_child->refinement_case(),
2150  neighbor_neighbor,
2151  0));
2152 
2153  // if there are two total subfaces, we
2154  // are finished. if there are four we
2155  // have to get a child of our current
2156  // neighbor_child. If there are three,
2157  // we have to check which of the two
2158  // possibilities applies.
2159  if (total_children==3)
2160  {
2161  if (mother_face->child(0)->has_children())
2162  {
2163  if (subface<2)
2164  neighbor_child =
2165  neighbor_child->child(GeometryInfo<3>::
2166  child_cell_on_face(neighbor_child->refinement_case(),
2167  neighbor_neighbor,subface,
2168  neighbor_child->face_orientation(neighbor_neighbor),
2169  neighbor_child->face_flip(neighbor_neighbor),
2170  neighbor_child->face_rotation(neighbor_neighbor),
2171  mother_face->child(0)->refinement_case()));
2172  }
2173  else
2174  {
2175  Assert(mother_face->child(1)->has_children(), ExcInternalError());
2176  if (subface>0)
2177  neighbor_child =
2178  neighbor_child->child(GeometryInfo<3>::
2179  child_cell_on_face(neighbor_child->refinement_case(),
2180  neighbor_neighbor,subface-1,
2181  neighbor_child->face_orientation(neighbor_neighbor),
2182  neighbor_child->face_flip(neighbor_neighbor),
2183  neighbor_child->face_rotation(neighbor_neighbor),
2184  mother_face->child(1)->refinement_case()));
2185  }
2186  }
2187  else if (total_children==4)
2188  {
2189  neighbor_child =
2190  neighbor_child->child(GeometryInfo<3>::
2191  child_cell_on_face(neighbor_child->refinement_case(),
2192  neighbor_neighbor,subface%2,
2193  neighbor_child->face_orientation(neighbor_neighbor),
2194  neighbor_child->face_flip(neighbor_neighbor),
2195  neighbor_child->face_rotation(neighbor_neighbor),
2196  mother_face->child(subface/2)->refinement_case()));
2197  }
2198  }
2199 
2200  // it might be, that the neighbor_child has
2201  // children, which are not refined along the
2202  // given subface. go down that list and
2203  // deliver the last of those.
2204  while (neighbor_child->has_children())
2205  neighbor_child
2206  = neighbor_child->child(GeometryInfo<3>::
2207  child_cell_on_face(neighbor_child->refinement_case(),
2208  neighbor_neighbor,
2209  0));
2210 
2211 #ifdef DEBUG
2212  // check, whether the face neighbor_child
2213  // matches the requested subface
2214  typename Triangulation<3,spacedim>::face_iterator requested;
2215  switch (this->subface_case(face))
2216  {
2220  requested = mother_face->child(subface);
2221  break;
2224  requested = mother_face->child(subface/2)->child(subface%2);
2225  break;
2226 
2229  switch (subface)
2230  {
2231  case 0:
2232  case 1:
2233  requested = mother_face->child(0)->child(subface);
2234  break;
2235  case 2:
2236  requested = mother_face->child(1);
2237  break;
2238  default:
2239  Assert(false, ExcInternalError());
2240  }
2241  break;
2244  switch (subface)
2245  {
2246  case 0:
2247  requested=mother_face->child(0);
2248  break;
2249  case 1:
2250  case 2:
2251  requested=mother_face->child(1)->child(subface-1);
2252  break;
2253  default:
2254  Assert(false, ExcInternalError());
2255  }
2256  break;
2257  default:
2258  Assert(false, ExcInternalError());
2259  break;
2260  }
2261  Assert (requested==neighbor_child->face(neighbor_neighbor),
2262  ExcInternalError());
2263 #endif
2264 
2265  return neighbor_child;
2266 
2267  }
2268 
2269  default:
2270  // 1d or more than 3d
2271  Assert (false, ExcNotImplemented());
2273  }
2274 }
2275 
2276 
2277 
2278 // explicit instantiations
2279 #include "tria_accessor.inst"
2280 
2281 DEAL_II_NAMESPACE_CLOSE
Quadrature< OBJECT::AccessorType::space_dimension > get_default_quadrature(const OBJECT &obj, bool with_laplace=false)
static const unsigned int invalid_unsigned_int
Definition: types.h:164
bool point_inside_codim(const Point< spacedim_ > &p) const
void set_active_cell_index(const unsigned int active_cell_index)
unsigned int active_cell_index() const
unsigned int neighbor_of_neighbor_internal(const unsigned int neighbor) const
void set_neighbor(const unsigned int i, const TriaIterator< CellAccessor< dim, spacedim > > &pointer) const
static bool is_inside_unit_cell(const Point< dim > &p)
unsigned char material_id
Definition: types.h:130
types::material_id material_id() const
::ExceptionBase & ExcMessage(std::string arg1)
#define AssertIndexRange(index, range)
Definition: exceptions.h:1081
double extent_in_direction(const unsigned int axis) const
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)
void set_all_manifold_ids(const types::manifold_id) const
void set(const ::internal::Triangulation::TriaObject< structdim > &o) const
numbers::NumberTraits< Number >::real_type norm() const
Definition: tensor.h:1047
TriaIterator< CellAccessor< dim, spacedim > > neighbor_child_on_subface(const unsigned int face_no, const unsigned int subface_no) const
bool neighbor_is_coarser(const unsigned int neighbor) const
unsigned int vertex_index(const unsigned int i) const
bool at_boundary() const
TriaIterator< CellAccessor< dim, spacedim > > parent() const
Definition: fe_q.h:522
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
Point< spacedim > & vertex(const unsigned int i) const
void set_material_id(const types::material_id new_material_id) const
Abstract base class for mapping classes.
Definition: dof_tools.h:52
Point< spacedim > center(const bool respect_manifold=false, const bool use_laplace_transformation=false) const
void recursively_set_material_id(const types::material_id new_material_id) const
unsigned int subdomain_id
Definition: types.h:42
Tensor< 1, dim, Number > cross_product_3d(const Tensor< 1, dim, Number > &src1, const Tensor< 1, dim, Number > &src2)
Definition: tensor.h:1748
int parent_index() const
double norm(const FEValuesBase< dim > &fe, const VectorSlice< const std::vector< std::vector< Tensor< 1, dim > > > > &Du)
Definition: divergence.h:604
virtual double shape_value(const unsigned int i, const Point< dim > &p) const
std::pair< unsigned int, unsigned int > neighbor_of_coarser_neighbor(const unsigned int neighbor) const
unsigned int manifold_id
Definition: types.h:122
void recursively_set_subdomain_id(const types::subdomain_id new_subdomain_id) const
bool point_inside(const Point< spacedim > &p) const
Definition: mpi.h:48
Point< spacedim > barycenter() const
void set_direction_flag(const bool new_direction_flag) const
void set_parent(const unsigned int parent_index)
Point< spacedim > intermediate_point(const Point< structdim > &coordinates) const
bool direction_flag() const
const Triangulation< dim, spacedim > & get_triangulation() const
Iterator points to a valid object.
void set_level_subdomain_id(const types::subdomain_id new_level_subdomain_id) const
void set_subdomain_id(const types::subdomain_id new_subdomain_id) const
types::subdomain_id level_subdomain_id() const
double measure() const
const Manifold< dim, spacedim > & get_manifold() const
const types::material_id invalid_material_id
Definition: types.h:185
unsigned int neighbor_of_neighbor(const unsigned int neighbor) const
bool has_boundary_lines() const