1 /****************************************************************************/
2 /* This file is part of FreeFEM.                                            */
3 /*                                                                          */
4 /* FreeFEM is free software: you can redistribute it and/or modify          */
5 /* it under the terms of the GNU Lesser General Public License as           */
6 /* published by the Free Software Foundation, either version 3 of           */
7 /* the License, or (at your option) any later version.                      */
8 /*                                                                          */
9 /* FreeFEM is distributed in the hope that it will be useful,               */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of           */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
12 /* GNU Lesser General Public License for more details.                      */
13 /*                                                                          */
14 /* You should have received a copy of the GNU Lesser General Public License */
15 /* along with FreeFEM. If not, see <http://www.gnu.org/licenses/>.          */
16 /****************************************************************************/
17 // SUMMARY : Add 3D finite elements
18 // LICENSE : LGPLv3
19 // ORG     : LJLL Universite Pierre et Marie Curie, Paris, FRANCE
20 // AUTHORS : Frederic Hecht
21 // E-MAIL  : frederic.hecht@sorbonne-universite.fr
22 
23 // RT1
24 // Pk = P1^3  + P1h (x,y,z)  ( dim Pk = 4*3 + 3) = 15
25 
26 // Related files:
27 // LaplaceRT1.edp
28 // lame-TD-NSS.edp
29 // test-ElementMixte.edp
30 
31 /* clang-format off */
32 //ff-c++-LIBRARY-dep:
33 //ff-c++-cpp-dep:
34 /* clang-format on */
35 
36 #include "ff++.hpp"
37 #include "AddNewFE.h"
38 
39 #ifdef __INTEL_COMPILER
40 #pragma optimize("", off)
41 #endif
42 
43 namespace Fem2D {
44   // Author: Marcella Bonazzoli
45   // Edge elements of degree 2, 3D
46   // (they are called Edge13d because the Nedelec elements of degree 1 are called Edge03d)
47   // TypeOfFE_Edge1_3d derived from GTypeOfFE<> (which is defined in FESpacen.hpp)
48   class TypeOfFE_Edge1_3d : public GTypeOfFE< Mesh3 > {
49    public:
50     typedef Mesh3 Mesh;
51     typedef Mesh3::Element Element;
52     typedef GFElement< Mesh3 > FElement;
53 
54     static int dfon[];
55     static const int d = Mesh::Rd::d;
56     static const GQuadratureFormular< R1 > QFe;    // quadrature formula on an edge
57     static const GQuadratureFormular< R2 > QFf;    // quadrature formula on a face
58     TypeOfFE_Edge1_3d( );                          // constructor
59     void FB(const What_d whatd, const Mesh &Th, const Mesh3::Element &K, const RdHat &PHat,
60             RNMK_ &val) const;
61     void set(const Mesh &Th, const Element &K, InterpolationMatrix< RdHat > &M, int ocoef, int odf,
62              int *nump) const;
63   };
64 
65   int TypeOfFE_Edge1_3d::dfon[] = {0, 2, 2, 0};    // 2 dofs on each edge, 2 dofs on each face
66 
67   // Quadrature formula on an edge, exact for degree 3 (ok: int_e (deg2*t *lambda))
68   const GQuadratureFormular< R1 > TypeOfFE_Edge1_3d::QFe(-1 + 2 * 2, 2, GaussLegendre(2), true);
69   // arguments: exact, num of integration pts, integration pts, clean (~GQuadratureFormular()
70   // {if(clean) delete [] p;}) GaussLegendre defined in QuadratureFormular.cpp
71 
72   // Quadrature formula on a face, exact for degree 2 (ok: int_f (deg2*t)), internal quadrature
73   // points
74   static GQuadraturePoint< R2 > P_QuadratureFormular_T_2_intp[3] = {
75     GQuadraturePoint< R2 >(1. / 3., R2(1. / 6., 4. / 6.)),
76     GQuadraturePoint< R2 >(1. / 3., R2(4. / 6., 1. / 6.)),
77     GQuadraturePoint< R2 >(1. / 3., R2(1. / 6., 1. / 6.))};
78   const GQuadratureFormular< R2 > TypeOfFE_Edge1_3d::QFf(2, 3, P_QuadratureFormular_T_2_intp);
79 
80   // In Mesh3dn.cpp:
81   // static const int  nvedgeTet[6][2] = { {0,1},{0,2},{0,3},{1,2},{1,3},{2,3} };
82   // static const int  nvfaceTet[4][3] = { {3,2,1},{0,2,3},{3,1,0},{0,1,2} };
83   // In GenericMesh.hpp:
84   // Vertex& at(int i) {return *vertices[i];}
85   // In GenericMesh.hpp:
86   // Rd Edge(int i) const {ASSERTION(i>=0 && i <ne);
87   // return Rd(at(nvedge[i][0]),at(nvedge[i][1]));}
88   // In GenericMesh.hpp:
89   // int   EdgeOrientation(int i) const  +/- 1
90   // { return &at(nvedge[i][0]) < &at(nvedge[i][1]);}
91 
92   // Constructor
93   // dfon, d, nsub,
94   // kPi = NbcoefforInterpolation is the number of alphas in (13.1) (chapter 13 ff++doc)
95   // = 3(=numComp)*QFe.n(num quad pts edge)*2*ne(2 fncts per edge) +
96   // 3(=numComp)*QFf.n(num quad pts face)*2*nf(2 fncts per face)
97   // npPi = NbPtforInterpolation = ne*QFe.n+nf*QFf.n
98   // invariantinterpolationMatrix = false (i.e. it depends on the tetrahedron), discon=true
TypeOfFE_Edge1_3d()99   TypeOfFE_Edge1_3d::TypeOfFE_Edge1_3d( )
100     : GTypeOfFE< Mesh3 >(TypeOfFE_Edge1_3d::dfon, d, 1,
101                          Element::ne * 2 * 3 * QFe.n + Element::nf * 2 * 3 * QFf.n,
102                          Element::ne * QFe.n + Element::nf * QFf.n, false, true) {
103     assert(QFe.n);
104     assert(QFf.n);
105     R3 Pt[] = {R3(0., 0., 0.), R3(1., 0., 0.), R3(0., 1., 0.),
106                R3(0., 0., 1.)};    // 4 ref tetrahedron vertices
107 
108     {
109       // We build the interpolation pts on the edges of the reference tetrahedron:
110       int i;
111       i = 0;
112 
113       for (int e = 0; e < Element::ne; ++e) {
114         for (int q = 0; q < QFe.n; ++q, ++i) {
115           double x = QFe[q].x;
116           this->PtInterpolation[i] =
117             Pt[Element::nvedge[e][0]] * (1. - x) + Pt[Element::nvedge[e][1]] * (x);
118         }
119       }
120 
121       // We build the interpolation pts on the faces of the reference tetrahedron:
122       // (the index i mustn't be reinitialised!)
123       for (int f = 0; f < Element::nf; ++f) {
124         for (int q = 0; q < QFf.n; ++q, ++i) {
125           double x = QFf[q].x;
126           double y = QFf[q].y;
127           this->PtInterpolation[i] = Pt[Element::nvface[f][0]] * (1. - x - y) +
128                                      Pt[Element::nvface[f][1]] * x + Pt[Element::nvface[f][2]] * y;
129         }
130       }
131     }
132     {
133       // We build the indices in (13.1) : edge dofs
134       int i = 0, p = 0;    // i is the k in (13.1) (chapter 13 ff++doc)
135       int e;               // we will need e also below, in the part referred to faces
136 
137       for (e = 0; e < (Element::ne)*2; e++) {    // loop on the 12 dofs
138         if (e % 2 == 1) {
139           p = p - QFe.n;
140         }    // if I consider an 'even' dof, the quad pts are the ones of the previous dof (they
141              // correspond to the same edge)
142 
143         for (int q = 0; q < QFe.n; ++q, ++p) {    // loop on the 2 edge quadrature pts
144           for (int c = 0; c < 3; c++, i++) {      // loop on the 3 components
145             this->pInterpolation[i] = p;          // pk in (13.1)
146             this->cInterpolation[i] = c;          // jk in (13.1)
147             this->dofInterpolation[i] = e;        // ik in (13.1)
148             this->coefInterpolation[i] = 0.;      // alfak: we will fill them with 'set' (below)
149                                                   // because they depend on the tetrahedron
150           }
151         }
152       }
153 
154       // We build the indices in (13.1) : face dofs
155       // (the indices i and p mustn't be reinitialised)
156       for (int f = 0; f < (Element::nf)*2; f++) {    // loop on the 8 dofs
157         if (f % 2 == 1) {
158           p = p - QFf.n;
159         }    // if I consider an 'even' dof, the quad pts are the ones of the previous dof (they
160              // correspond to the same face)
161 
162         for (int q = 0; q < QFf.n; ++q, ++p) {    // loop on the 3 face quadrature pts
163           for (int c = 0; c < 3; c++, i++) {      // loop on the 3 components
164             this->pInterpolation[i] = p;          // pk in (13.1)
165             this->cInterpolation[i] = c;          // jk in (13.1)
166             this->dofInterpolation[i] = e + f;    // ik in (13.1)
167             this->coefInterpolation[i] = 0.;      // alphak: we will fill them with 'set' (below)
168                                                   // because they depend on the tetrahedron
169           }
170         }
171       }
172     }
173   }
174 
175   // For the coefficients of interpolation alphak in (13.1)
set(const Mesh & Th,const Element & K,InterpolationMatrix<RdHat> & M,int ocoef,int odf,int * nump) const176   void TypeOfFE_Edge1_3d::set(const Mesh &Th, const Element &K, InterpolationMatrix< RdHat > &M,
177                               int ocoef, int odf, int *nump) const {
178     int i = ocoef, p = 0;
179 
180     // 12 edge dofs
181     int e;
182 
183     for (e = 0; e < (Element::ne)*2; e++) {
184       int ee = e / 2;
185       int eo = K.EdgeOrientation(ee) > 0;    //  change FH; jan 2019
186       R3 E = K.Edge(ee);    // the edge local number is given by the integer division betweeand
187       if (!eo) {
188         E = -E;
189       }
190 
191       if (e % 2 == 1) {
192         p = p - QFe.n;
193       }    // if I consider an 'even' dof, the quad pts are the ones of the previous dof (they
194            // correspond to the same edge)
195 
196       for (int q = 0; q < QFe.n; ++q, ++p) {
197         double ll = QFe[q].x;    // value of lambda_0 or lambda_1
198         if ((e % 2 + eo) == 1) {
199           ll = 1 - ll;    // if exactly one between e%2 and eo is equal to 1 (so the sum is equal to
200                           // 1), take the other lambda
201         }
202 
203         // i.e. if I'm considering the 2nd dof of the edge (or) if the edge is badly oriented, take
204         // the other lambda (but not if both)
205         for (int c = 0; c < 3; c++, i++) {
206           M.coef[i] = E[c] * QFe[q].a * ll;
207           // QFe[q].a is the weight of the integration point q
208           // QFe[q].x is the x over [0,1] of the integration point q
209         }
210       }
211     }
212 
213     // (the indices i and p mustn't be reinitialised)
214     // 8 face dofs
215     for (int f = 0; f < (Element::nf)*2; f++) {    // loop on the 8 face dofs
216       int ff = f / 2;                              // the face number
217       int iff = f % 2;                             // 1st or 2nd dof of the face
218       const Element::Vertex *fV[3] = {&K.at(Element::nvface[ff][0]), &K.at(Element::nvface[ff][1]),
219                                       &K.at(Element::nvface[ff][2])};
220       // We 'order' the 3 vertices of the face according to their global numbers:
221       // i0 will be the local number in the FACE of the vertex with the smallest global number
222       // i1 will be the local number in the face of the vertex with the second smallest global
223       // number i2 will be the local number in the face of the vertex with the largest global number
224       int i0 = 0, i1 = 1, i2 = 2;
225       if (fV[i0] > fV[i1]) {
226         Exchange(i0, i1);
227       }
228 
229       if (fV[i1] > fV[i2]) {
230         Exchange(i1, i2);
231         if (fV[i0] > fV[i1]) {
232           Exchange(i0, i1);
233         }
234       }
235 
236       // now local numbers in the tetrahedron:
237       i0 = Element::nvface[ff][i0], i1 = Element::nvface[ff][i1], i2 = Element::nvface[ff][i2];
238       int ie0 = i0,
239           ie1 = iff == 0 ? i1 : i2;    // edge for the face dof (its endpoints local numbers)
240       R3 E(K[ie0], K[ie1]);
241       if (iff) {
242         p = p - QFf.n;
243       }    // if I consider an 'even' dof, the quad pts are the ones of the previous dof (they
244            // correspond to the same face)
245 
246       for (int q = 0; q < QFf.n; ++q, ++p) {    // loop on the 3 face quadrature pts
247         for (int c = 0; c < 3; c++, i++) {      // loop on the 3 components
248           M.coef[i] = E[c] * QFf[q].a;
249         }
250       }
251     }
252   }
253 
254   // In Mesh3dn.hpp:
255   // void Gradlambda(R3 * GradL) const
256   // {
257   // R3 V1(at(0),at(1));
258   // R3 V2(at(0),at(2));
259   // R3 V3(at(0),at(3));
260   // R det1=1./(6.*mesure());
261   // GradL[1]= (V2^V3)*det1;
262   // GradL[2]= (V3^V1)*det1;
263   // GradL[3]= (V1^V2)*det1;
264   // GradL[0]=-GradL[1]-GradL[2]-GradL[3];
265   // }
266 
267   /*
268    * FB: We are on a tetrahedron K
269    * (the local numbering of its 4 vertices is given by how they are listed where K is described in
270    * the mesh file).
271    *
272    * AT FIRST we BUILD the 'pre-basis' functions OMEGA in the order given the GLOBAL numbering of
273    * the tetrahedron vertices, that is the 1st examined edge is from the vertex with the 1st
274    * smallest GLOBAL number to the one the 2nd smallest GLOBAL number, and so on (see nvedege), and
275    * the 1st examined face is the one opposite the vertex with the smallest GLOBAL number (and 2
276    * edges of the face are chosen and oriented looking at its 3 global numbers), and so on. In this
277    * way:
278    * - a dof which is common to 2 adjacent tetrahedra is the same in the two tetrahedra
279    * (since the orientation of each edge is chosen using the global numbers),
280    * - we can use the coefficients giving a dual basis that were calculated for the reference
281    * tetrahedron since the structure of orientation of the edges is the same (up to a rotation) as
282    * the one used in the reference tetrahedron.
283    *
284    * BUT THEN, when we build the DUAL basis functions PHI, we use the permutation p20 to go back to
285    * the FreeFem numbering of the dofs (which follows the LOCAL numbering). For instance the 1st
286    * examined edge can be the 3rd edge looking at the local numbering. Here with 'dual' I mean basis
287    * functions and dofs in duality.
288    */
289 
290   // val contains the values of the basis functions and of their derivatives at the point of K
291   // corresponding to the point P of the reference tetrahedron, by components
FB(const What_d whatd,const Mesh & Th,const Mesh3::Element & K,const RdHat & PHat,RNMK_ & val) const292   void TypeOfFE_Edge1_3d::FB(const What_d whatd, const Mesh &Th, const Mesh3::Element &K,
293                              const RdHat &PHat, RNMK_ &val) const {
294     assert(val.N( ) >= 20);    // 20 degrees of freedom
295     assert(val.M( ) == 3);     // 3 components
296     // -------------
297     // perm: the permutation for which the 4 tetrahedron vertices are listed with increasing GLOBAL
298     // number (i.e. perm[0] is the local number of the vertex with the smallest global number, ...
299     // perm[3] is the local number of the vertex with the biggest global number.)
300     const Element::Vertex *tV[4] = {&K.at(0), &K.at(1), &K.at(2), &K.at(3)};
301     int k0 = 0, k1 = 1, k2 = 2, k3 = 3;
302     if (tV[k0] > tV[k1]) {
303       Exchange(k0, k1);
304     }
305 
306     if (tV[k1] > tV[k2]) {
307       Exchange(k1, k2);
308     }
309 
310     if (tV[k2] > tV[k3]) {
311       Exchange(k2, k3);
312     }
313 
314     if (tV[k0] > tV[k1]) {
315       Exchange(k0, k1);
316     }
317 
318     if (tV[k1] > tV[k2]) {
319       Exchange(k1, k2);
320     }
321 
322     if (tV[k0] > tV[k1]) {
323       Exchange(k0, k1);
324     }
325 
326     int perm[4] = {k0, k1, k2, k3};
327     // -------------
328     // We build mynvface to be used here instead of the FreeFem nvface,
329     // (in order to exploit the results of perm and write a better code),
330     // in mynvface in all the triplets the numbers are increasing
331     static const int mynvface[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
332     // -------------
333     // If [a,b] is the i-th edge (where a,b are its vertices local numbers), edgesMap[(a+1)*(b+1)] =
334     // i
335     int edgesMap[13] = {-1, -1, 0,  1,  2,  -1, 3,
336                         -1, 4,  -1, -1, -1, 5};    // a map<int,int> would be more slow
337     // -------------
338     // the 4 barycentric coordinates for the reference tetrahedron evaluated at the point P
339     // (they have the same value at the real tetrahedron's point corresponding to the reference
340     // tetrahedron's point P)
341     R l[] = {1. - PHat.sum( ), PHat.x, PHat.y, PHat.z};
342     R3 D[4];
343     K.Gradlambda(D);    // (riempie un array di 4 R3)
344     val = 0;
345     // -----
346     int p20[20];    // the permutation from the dofs numbering of my tetrahedron (numbered using the
347                     // GLOBAL vertex numbers) to the dofs numbering of FreeFem !!!!!
348 
349     for (int i = 0; i < 6; ++i) {    // edges
350       // see below
351       int ii0 = Element::nvedge[i][0], ii1 = Element::nvedge[i][1];
352       int i0 = perm[ii0];
353       int i1 = perm[ii1];
354       int iEdge = edgesMap[(i0 + 1) * (i1 + 1)];    // i of the edge [i0,i1]
355       p20[i * 2] = iEdge * 2;
356       p20[i * 2 + 1] = iEdge * 2 + 1;
357     }
358 
359     for (int j = 0; j < 4; ++j) {    // faces
360       // using perm the 1st examined face is the one opposite the vertex with the smallest GLOBAL
361       // number, and so on (see below)
362       int jFace = perm[j];
363       p20[12 + j * 2] = 12 + jFace * 2;
364       p20[12 + j * 2 + 1] = 12 + jFace * 2 + 1;
365     }
366 
367     // -----
368 
369     if (whatd & Fop_D0) {    // Fop_D0 defined in FESpacen.hpp
370       R3 X = K(PHat);
371       // First, the functions omega (they don't constitute a dual basis! only a basis)
372       R3 omega[20];
373 
374       // 12 edge functions:
375       for (int i = 0; i < 6; ++i) {
376         int ii0 = Element::nvedge[i][0], ii1 = Element::nvedge[i][1];
377         int i0 = perm[ii0];
378         int i1 = perm[ii1];
379         // ! :
380         // using perm, [i0,i1] is already from the smallest global number to the greatest global
381         // number, since nvedge always gives indices which read perm from left to right
382         omega[i * 2] = l[i0] * (l[i0] * D[i1] - l[i1] * D[i0]);
383         omega[i * 2 + 1] = l[i1] * (l[i0] * D[i1] - l[i1] * D[i0]);
384       }
385 
386       // 8 face functions:
387       for (int j = 0; j < 4; ++j) {
388         // In (my)nvface the face opposite the vertex k is (my)nvface[k][],
389         // using perm the 1st examined face is the one opposite the vertex with the smallest GLOBAL
390         // number, and so on, and, since in mynvface the numbers always increase, [i0,i1,i2] are
391         // already ordered with increasing global number
392         int ii0 = mynvface[j][0];
393         int ii1 = mynvface[j][1];
394         int ii2 = mynvface[j][2];
395         int i0 = perm[ii0];
396         int i1 = perm[ii1];
397         int i2 = perm[ii2];
398         omega[12 + j * 2] = l[i2] * (l[i0] * D[i1] - l[i1] * D[i0]);
399         omega[12 + j * 2 + 1] = l[i1] * (l[i0] * D[i2] - l[i2] * D[i0]);
400       }
401 
402       // Now, the functions phi that really constitute a dual basis
403       R3 phi[20];
404       phi[p20[0]] = +4 * omega[0] - 2 * omega[1] - 4 * omega[16] + 2 * omega[17] - 4 * omega[18] +
405                     2 * omega[19];
406       phi[p20[1]] = -2 * omega[0] + 4 * omega[1] - 2 * omega[16] - 2 * omega[17] - 2 * omega[18] -
407                     2 * omega[19];
408       phi[p20[2]] = +4 * omega[2] - 2 * omega[3] - 4 * omega[14] + 2 * omega[15] + 2 * omega[18] -
409                     4 * omega[19];
410       phi[p20[3]] = -2 * omega[2] + 4 * omega[3] - 2 * omega[14] - 2 * omega[15] - 2 * omega[18] -
411                     2 * omega[19];
412       phi[p20[4]] = +4 * omega[4] - 2 * omega[5] + 2 * omega[14] - 4 * omega[15] + 2 * omega[16] -
413                     4 * omega[17];
414       phi[p20[5]] = -2 * omega[4] + 4 * omega[5] - 2 * omega[14] - 2 * omega[15] - 2 * omega[16] -
415                     2 * omega[17];
416       phi[p20[6]] = +4 * omega[6] - 2 * omega[7] - 4 * omega[12] + 2 * omega[13] + 2 * omega[18] -
417                     4 * omega[19];
418       phi[p20[7]] = -2 * omega[6] + 4 * omega[7] - 2 * omega[12] - 2 * omega[13] + 4 * omega[18] -
419                     2 * omega[19];
420       phi[p20[8]] = +4 * omega[8] - 2 * omega[9] + 2 * omega[12] - 4 * omega[13] + 2 * omega[16] -
421                     4 * omega[17];
422       phi[p20[9]] = -2 * omega[8] + 4 * omega[9] - 2 * omega[12] - 2 * omega[13] + 4 * omega[16] -
423                     2 * omega[17];
424       phi[p20[10]] = +4 * omega[10] - 2 * omega[11] + 2 * omega[12] - 4 * omega[13] +
425                      2 * omega[14] - 4 * omega[15];
426       phi[p20[11]] = -2 * omega[10] + 4 * omega[11] + 4 * omega[12] - 2 * omega[13] +
427                      4 * omega[14] - 2 * omega[15];
428       phi[p20[12]] = +8 * omega[12] - 4 * omega[13];
429       phi[p20[13]] = -4 * omega[12] + 8 * omega[13];
430       phi[p20[14]] = +8 * omega[14] - 4 * omega[15];
431       phi[p20[15]] = -4 * omega[14] + 8 * omega[15];
432       phi[p20[16]] = +8 * omega[16] - 4 * omega[17];
433       phi[p20[17]] = -4 * omega[16] + 8 * omega[17];
434       phi[p20[18]] = +8 * omega[18] - 4 * omega[19];
435       phi[p20[19]] = -4 * omega[18] + 8 * omega[19];
436 
437       for (int k = 0; k < 20; ++k) {
438         val(k, 0, op_id) = phi[k].x;
439         val(k, 1, op_id) = phi[k].y;
440         val(k, 2, op_id) = phi[k].z;
441       }
442     }
443 
444     if (whatd & Fop_D1) {    // First Derivatives wrt x,y,z
445       R3 omegadx[20];
446       R3 omegady[20];
447       R3 omegadz[20];
448 
449       // 12 edge functions:
450       for (int i = 0; i < 6; ++i) {
451         int ii0 = Element::nvedge[i][0], ii1 = Element::nvedge[i][1];
452         int i0 = perm[ii0];
453         int i1 = perm[ii1];
454         // using perm, [i0,i1] is already from the smallest global number to the greatest global
455         // number, since nvedge always gives indices which read perm from left to right
456         if (whatd & Fop_dx) {
457           omegadx[i * 2] =
458             D[i0].x * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i0] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
459           omegadx[i * 2 + 1] =
460             D[i1].x * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i1] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
461         }
462 
463         if (whatd & Fop_dy) {
464           omegady[i * 2] =
465             D[i0].y * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i0] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
466           omegady[i * 2 + 1] =
467             D[i1].y * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i1] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
468         }
469 
470         if (whatd & Fop_dz) {
471           omegadz[i * 2] =
472             D[i0].z * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i0] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
473           omegadz[i * 2 + 1] =
474             D[i1].z * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i1] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
475         }
476       }
477 
478       // 8 face functions:
479       for (int j = 0; j < 4; ++j) {
480         // In (my)nvface the face opposite the vertex k is (my)nvface[k][],
481         // using perm the 1st examined face is the one opposite the vertex with the smallest GLOBAL
482         // number, and so on, and, since in mynvface the numbers always increase, [i0,i1,i2] are
483         // already ordered with increasing global number
484         int ii0 = mynvface[j][0];
485         int ii1 = mynvface[j][1];
486         int ii2 = mynvface[j][2];
487         int i0 = perm[ii0];
488         int i1 = perm[ii1];
489         int i2 = perm[ii2];
490         if (whatd & Fop_dx) {
491           omegadx[12 + j * 2] =
492             D[i2].x * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i2] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
493           omegadx[12 + j * 2 + 1] =
494             D[i1].x * (l[i0] * D[i2] - l[i2] * D[i0]) + l[i1] * (D[i0].x * D[i2] - D[i2].x * D[i0]);
495         }
496 
497         if (whatd & Fop_dy) {
498           omegady[12 + j * 2] =
499             D[i2].y * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i2] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
500           omegady[12 + j * 2 + 1] =
501             D[i1].y * (l[i0] * D[i2] - l[i2] * D[i0]) + l[i1] * (D[i0].y * D[i2] - D[i2].y * D[i0]);
502         }
503 
504         if (whatd & Fop_dz) {
505           omegadz[12 + j * 2] =
506             D[i2].z * (l[i0] * D[i1] - l[i1] * D[i0]) + l[i2] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
507           omegadz[12 + j * 2 + 1] =
508             D[i1].z * (l[i0] * D[i2] - l[i2] * D[i0]) + l[i1] * (D[i0].z * D[i2] - D[i2].z * D[i0]);
509         }
510       }
511 
512       R3 phidx[20];
513       if (whatd & Fop_dx) {
514         phidx[p20[0]] = +4 * omegadx[0] - 2 * omegadx[1] - 4 * omegadx[16] + 2 * omegadx[17] -
515                         4 * omegadx[18] + 2 * omegadx[19];
516         phidx[p20[1]] = -2 * omegadx[0] + 4 * omegadx[1] - 2 * omegadx[16] - 2 * omegadx[17] -
517                         2 * omegadx[18] - 2 * omegadx[19];
518         phidx[p20[2]] = +4 * omegadx[2] - 2 * omegadx[3] - 4 * omegadx[14] + 2 * omegadx[15] +
519                         2 * omegadx[18] - 4 * omegadx[19];
520         phidx[p20[3]] = -2 * omegadx[2] + 4 * omegadx[3] - 2 * omegadx[14] - 2 * omegadx[15] -
521                         2 * omegadx[18] - 2 * omegadx[19];
522         phidx[p20[4]] = +4 * omegadx[4] - 2 * omegadx[5] + 2 * omegadx[14] - 4 * omegadx[15] +
523                         2 * omegadx[16] - 4 * omegadx[17];
524         phidx[p20[5]] = -2 * omegadx[4] + 4 * omegadx[5] - 2 * omegadx[14] - 2 * omegadx[15] -
525                         2 * omegadx[16] - 2 * omegadx[17];
526         phidx[p20[6]] = +4 * omegadx[6] - 2 * omegadx[7] - 4 * omegadx[12] + 2 * omegadx[13] +
527                         2 * omegadx[18] - 4 * omegadx[19];
528         phidx[p20[7]] = -2 * omegadx[6] + 4 * omegadx[7] - 2 * omegadx[12] - 2 * omegadx[13] +
529                         4 * omegadx[18] - 2 * omegadx[19];
530         phidx[p20[8]] = +4 * omegadx[8] - 2 * omegadx[9] + 2 * omegadx[12] - 4 * omegadx[13] +
531                         2 * omegadx[16] - 4 * omegadx[17];
532         phidx[p20[9]] = -2 * omegadx[8] + 4 * omegadx[9] - 2 * omegadx[12] - 2 * omegadx[13] +
533                         4 * omegadx[16] - 2 * omegadx[17];
534         phidx[p20[10]] = +4 * omegadx[10] - 2 * omegadx[11] + 2 * omegadx[12] - 4 * omegadx[13] +
535                          2 * omegadx[14] - 4 * omegadx[15];
536         phidx[p20[11]] = -2 * omegadx[10] + 4 * omegadx[11] + 4 * omegadx[12] - 2 * omegadx[13] +
537                          4 * omegadx[14] - 2 * omegadx[15];
538         phidx[p20[12]] = +8 * omegadx[12] - 4 * omegadx[13];
539         phidx[p20[13]] = -4 * omegadx[12] + 8 * omegadx[13];
540         phidx[p20[14]] = +8 * omegadx[14] - 4 * omegadx[15];
541         phidx[p20[15]] = -4 * omegadx[14] + 8 * omegadx[15];
542         phidx[p20[16]] = +8 * omegadx[16] - 4 * omegadx[17];
543         phidx[p20[17]] = -4 * omegadx[16] + 8 * omegadx[17];
544         phidx[p20[18]] = +8 * omegadx[18] - 4 * omegadx[19];
545         phidx[p20[19]] = -4 * omegadx[18] + 8 * omegadx[19];
546 
547         for (int k = 0; k < 20; ++k) {
548           val(k, 0, op_dx) = phidx[k].x;
549           val(k, 1, op_dx) = phidx[k].y;
550           val(k, 2, op_dx) = phidx[k].z;
551         }
552       }
553 
554       R3 phidy[20];
555       if (whatd & Fop_dy) {
556         phidy[p20[0]] = +4 * omegady[0] - 2 * omegady[1] - 4 * omegady[16] + 2 * omegady[17] -
557                         4 * omegady[18] + 2 * omegady[19];
558         phidy[p20[1]] = -2 * omegady[0] + 4 * omegady[1] - 2 * omegady[16] - 2 * omegady[17] -
559                         2 * omegady[18] - 2 * omegady[19];
560         phidy[p20[2]] = +4 * omegady[2] - 2 * omegady[3] - 4 * omegady[14] + 2 * omegady[15] +
561                         2 * omegady[18] - 4 * omegady[19];
562         phidy[p20[3]] = -2 * omegady[2] + 4 * omegady[3] - 2 * omegady[14] - 2 * omegady[15] -
563                         2 * omegady[18] - 2 * omegady[19];
564         phidy[p20[4]] = +4 * omegady[4] - 2 * omegady[5] + 2 * omegady[14] - 4 * omegady[15] +
565                         2 * omegady[16] - 4 * omegady[17];
566         phidy[p20[5]] = -2 * omegady[4] + 4 * omegady[5] - 2 * omegady[14] - 2 * omegady[15] -
567                         2 * omegady[16] - 2 * omegady[17];
568         phidy[p20[6]] = +4 * omegady[6] - 2 * omegady[7] - 4 * omegady[12] + 2 * omegady[13] +
569                         2 * omegady[18] - 4 * omegady[19];
570         phidy[p20[7]] = -2 * omegady[6] + 4 * omegady[7] - 2 * omegady[12] - 2 * omegady[13] +
571                         4 * omegady[18] - 2 * omegady[19];
572         phidy[p20[8]] = +4 * omegady[8] - 2 * omegady[9] + 2 * omegady[12] - 4 * omegady[13] +
573                         2 * omegady[16] - 4 * omegady[17];
574         phidy[p20[9]] = -2 * omegady[8] + 4 * omegady[9] - 2 * omegady[12] - 2 * omegady[13] +
575                         4 * omegady[16] - 2 * omegady[17];
576         phidy[p20[10]] = +4 * omegady[10] - 2 * omegady[11] + 2 * omegady[12] - 4 * omegady[13] +
577                          2 * omegady[14] - 4 * omegady[15];
578         phidy[p20[11]] = -2 * omegady[10] + 4 * omegady[11] + 4 * omegady[12] - 2 * omegady[13] +
579                          4 * omegady[14] - 2 * omegady[15];
580         phidy[p20[12]] = +8 * omegady[12] - 4 * omegady[13];
581         phidy[p20[13]] = -4 * omegady[12] + 8 * omegady[13];
582         phidy[p20[14]] = +8 * omegady[14] - 4 * omegady[15];
583         phidy[p20[15]] = -4 * omegady[14] + 8 * omegady[15];
584         phidy[p20[16]] = +8 * omegady[16] - 4 * omegady[17];
585         phidy[p20[17]] = -4 * omegady[16] + 8 * omegady[17];
586         phidy[p20[18]] = +8 * omegady[18] - 4 * omegady[19];
587         phidy[p20[19]] = -4 * omegady[18] + 8 * omegady[19];
588 
589         for (int k = 0; k < 20; ++k) {
590           val(k, 0, op_dy) = phidy[k].x;
591           val(k, 1, op_dy) = phidy[k].y;
592           val(k, 2, op_dy) = phidy[k].z;
593         }
594       }
595 
596       R3 phidz[20];
597       if (whatd & Fop_dz) {
598         phidz[p20[0]] = +4 * omegadz[0] - 2 * omegadz[1] - 4 * omegadz[16] + 2 * omegadz[17] -
599                         4 * omegadz[18] + 2 * omegadz[19];
600         phidz[p20[1]] = -2 * omegadz[0] + 4 * omegadz[1] - 2 * omegadz[16] - 2 * omegadz[17] -
601                         2 * omegadz[18] - 2 * omegadz[19];
602         phidz[p20[2]] = +4 * omegadz[2] - 2 * omegadz[3] - 4 * omegadz[14] + 2 * omegadz[15] +
603                         2 * omegadz[18] - 4 * omegadz[19];
604         phidz[p20[3]] = -2 * omegadz[2] + 4 * omegadz[3] - 2 * omegadz[14] - 2 * omegadz[15] -
605                         2 * omegadz[18] - 2 * omegadz[19];
606         phidz[p20[4]] = +4 * omegadz[4] - 2 * omegadz[5] + 2 * omegadz[14] - 4 * omegadz[15] +
607                         2 * omegadz[16] - 4 * omegadz[17];
608         phidz[p20[5]] = -2 * omegadz[4] + 4 * omegadz[5] - 2 * omegadz[14] - 2 * omegadz[15] -
609                         2 * omegadz[16] - 2 * omegadz[17];
610         phidz[p20[6]] = +4 * omegadz[6] - 2 * omegadz[7] - 4 * omegadz[12] + 2 * omegadz[13] +
611                         2 * omegadz[18] - 4 * omegadz[19];
612         phidz[p20[7]] = -2 * omegadz[6] + 4 * omegadz[7] - 2 * omegadz[12] - 2 * omegadz[13] +
613                         4 * omegadz[18] - 2 * omegadz[19];
614         phidz[p20[8]] = +4 * omegadz[8] - 2 * omegadz[9] + 2 * omegadz[12] - 4 * omegadz[13] +
615                         2 * omegadz[16] - 4 * omegadz[17];
616         phidz[p20[9]] = -2 * omegadz[8] + 4 * omegadz[9] - 2 * omegadz[12] - 2 * omegadz[13] +
617                         4 * omegadz[16] - 2 * omegadz[17];
618         phidz[p20[10]] = +4 * omegadz[10] - 2 * omegadz[11] + 2 * omegadz[12] - 4 * omegadz[13] +
619                          2 * omegadz[14] - 4 * omegadz[15];
620         phidz[p20[11]] = -2 * omegadz[10] + 4 * omegadz[11] + 4 * omegadz[12] - 2 * omegadz[13] +
621                          4 * omegadz[14] - 2 * omegadz[15];
622         phidz[p20[12]] = +8 * omegadz[12] - 4 * omegadz[13];
623         phidz[p20[13]] = -4 * omegadz[12] + 8 * omegadz[13];
624         phidz[p20[14]] = +8 * omegadz[14] - 4 * omegadz[15];
625         phidz[p20[15]] = -4 * omegadz[14] + 8 * omegadz[15];
626         phidz[p20[16]] = +8 * omegadz[16] - 4 * omegadz[17];
627         phidz[p20[17]] = -4 * omegadz[16] + 8 * omegadz[17];
628         phidz[p20[18]] = +8 * omegadz[18] - 4 * omegadz[19];
629         phidz[p20[19]] = -4 * omegadz[18] + 8 * omegadz[19];
630 
631         for (int k = 0; k < 20; ++k) {
632           val(k, 0, op_dz) = phidz[k].x;
633           val(k, 1, op_dz) = phidz[k].y;
634           val(k, 2, op_dz) = phidz[k].z;
635         }
636       }
637     }
638 
639     if (whatd & Fop_D2) {    // Second Derivatives
640       R3 omegadxx[20];
641       R3 omegadyy[20];
642       R3 omegadzz[20];
643       R3 omegadxy[20];
644       R3 omegadxz[20];
645       R3 omegadyz[20];
646 
647       // 12 edge functions:
648       for (int i = 0; i < 6; ++i) {
649         int ii0 = Element::nvedge[i][0], ii1 = Element::nvedge[i][1];
650         int i0 = perm[ii0];
651         int i1 = perm[ii1];
652         // using perm, [i0,i1] is already from the smallest global number to the greatest global
653         // number, since nvedge always gives indices which read perm from left to right
654         if (whatd & Fop_dxx) {
655           omegadxx[i * 2] = D[i0].x * (D[i0].x * D[i1] - D[i1].x * D[i0]) +
656                             D[i0].x * (D[i0].x * D[i1] - D[i1].x * D[i0]);
657           omegadxx[i * 2 + 1] = D[i1].x * (D[i0].x * D[i1] - D[i1].x * D[i0]) +
658                                 D[i1].x * (D[i0].x * D[i1] - D[i1].x * D[i0]);
659         }
660 
661         if (whatd & Fop_dyy) {
662           omegadyy[i * 2] = D[i0].y * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
663                             D[i0].y * (D[i0].y * D[i1] - D[i1].y * D[i0]);
664           omegadyy[i * 2 + 1] = D[i1].y * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
665                                 D[i1].y * (D[i0].y * D[i1] - D[i1].y * D[i0]);
666         }
667 
668         if (whatd & Fop_dzz) {
669           omegadzz[i * 2] = D[i0].z * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
670                             D[i0].z * (D[i0].z * D[i1] - D[i1].z * D[i0]);
671           omegadzz[i * 2 + 1] = D[i1].z * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
672                                 D[i1].z * (D[i0].z * D[i1] - D[i1].z * D[i0]);
673         }
674 
675         if (whatd & Fop_dxy) {
676           omegadxy[i * 2] = D[i0].x * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
677                             D[i0].y * (D[i0].x * D[i1] - D[i1].x * D[i0]);
678           omegadxy[i * 2 + 1] = D[i1].x * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
679                                 D[i1].y * (D[i0].x * D[i1] - D[i1].x * D[i0]);
680         }
681 
682         if (whatd & Fop_dxz) {
683           omegadxz[i * 2] = D[i0].x * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
684                             D[i0].z * (D[i0].x * D[i1] - D[i1].x * D[i0]);
685           omegadxz[i * 2 + 1] = D[i1].x * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
686                                 D[i1].z * (D[i0].x * D[i1] - D[i1].x * D[i0]);
687         }
688 
689         if (whatd & Fop_dyz) {
690           omegadyz[i * 2] = D[i0].y * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
691                             D[i0].z * (D[i0].y * D[i1] - D[i1].y * D[i0]);
692           omegadyz[i * 2 + 1] = D[i1].y * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
693                                 D[i1].z * (D[i0].y * D[i1] - D[i1].y * D[i0]);
694         }
695       }
696 
697       // 8 face functions:
698       for (int j = 0; j < 4; ++j) {
699         // In (my)nvface the face opposite the vertex k is (my)nvface[k][],
700         // using perm the 1st examined face is the one opposite the vertex with the smallest GLOBAL
701         // number, and so on, and, since in mynvface the numbers always increase, [i0,i1,i2] are
702         // already ordered with increasing global number
703         int ii0 = mynvface[j][0];
704         int ii1 = mynvface[j][1];
705         int ii2 = mynvface[j][2];
706         int i0 = perm[ii0];
707         int i1 = perm[ii1];
708         int i2 = perm[ii2];
709         if (whatd & Fop_dxx) {
710           omegadxx[12 + j * 2] = D[i2].x * (D[i0].x * D[i1] - D[i1].x * D[i0]) +
711                                  D[i2].x * (D[i0].x * D[i1] - D[i1].x * D[i0]);
712           omegadxx[12 + j * 2 + 1] = D[i1].x * (D[i0].x * D[i2] - D[i2].x * D[i0]) +
713                                      D[i1].x * (D[i0].x * D[i2] - D[i2].x * D[i0]);
714         }
715 
716         if (whatd & Fop_dyy) {
717           omegadyy[12 + j * 2] = D[i2].y * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
718                                  D[i2].y * (D[i0].y * D[i1] - D[i1].y * D[i0]);
719           omegadyy[12 + j * 2 + 1] = D[i1].y * (D[i0].y * D[i2] - D[i2].y * D[i0]) +
720                                      D[i1].y * (D[i0].y * D[i2] - D[i2].y * D[i0]);
721         }
722 
723         if (whatd & Fop_dzz) {
724           omegadzz[12 + j * 2] = D[i2].z * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
725                                  D[i2].z * (D[i0].z * D[i1] - D[i1].z * D[i0]);
726           omegadzz[12 + j * 2 + 1] = D[i1].z * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
727                                      D[i1].z * (D[i0].z * D[i2] - D[i2].z * D[i0]);
728         }
729 
730         if (whatd & Fop_dxy) {
731           omegadxy[12 + j * 2] = D[i2].x * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
732                                  D[i2].y * (D[i0].x * D[i1] - D[i1].x * D[i0]);
733           omegadxy[12 + j * 2 + 1] = D[i1].x * (D[i0].y * D[i2] - D[i2].y * D[i0]) +
734                                      D[i1].y * (D[i0].x * D[i2] - D[i2].x * D[i0]);
735         }
736 
737         if (whatd & Fop_dxz) {
738           omegadxz[12 + j * 2] = D[i2].x * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
739                                  D[i2].z * (D[i0].x * D[i1] - D[i1].x * D[i0]);
740           omegadxz[12 + j * 2 + 1] = D[i1].x * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
741                                      D[i1].z * (D[i0].x * D[i2] - D[i2].x * D[i0]);
742         }
743 
744         if (whatd & Fop_dyz) {
745           omegadyz[12 + j * 2] = D[i2].y * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
746                                  D[i2].z * (D[i0].y * D[i1] - D[i1].y * D[i0]);
747           omegadyz[12 + j * 2 + 1] = D[i1].y * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
748                                      D[i1].z * (D[i0].y * D[i2] - D[i2].y * D[i0]);
749         }
750       }
751 
752       R3 phidxx[20];
753       if (whatd & Fop_dxx) {
754         phidxx[p20[0]] = +4 * omegadxx[0] - 2 * omegadxx[1] - 4 * omegadxx[16] + 2 * omegadxx[17] -
755                          4 * omegadxx[18] + 2 * omegadxx[19];
756         phidxx[p20[1]] = -2 * omegadxx[0] + 4 * omegadxx[1] - 2 * omegadxx[16] - 2 * omegadxx[17] -
757                          2 * omegadxx[18] - 2 * omegadxx[19];
758         phidxx[p20[2]] = +4 * omegadxx[2] - 2 * omegadxx[3] - 4 * omegadxx[14] + 2 * omegadxx[15] +
759                          2 * omegadxx[18] - 4 * omegadxx[19];
760         phidxx[p20[3]] = -2 * omegadxx[2] + 4 * omegadxx[3] - 2 * omegadxx[14] - 2 * omegadxx[15] -
761                          2 * omegadxx[18] - 2 * omegadxx[19];
762         phidxx[p20[4]] = +4 * omegadxx[4] - 2 * omegadxx[5] + 2 * omegadxx[14] - 4 * omegadxx[15] +
763                          2 * omegadxx[16] - 4 * omegadxx[17];
764         phidxx[p20[5]] = -2 * omegadxx[4] + 4 * omegadxx[5] - 2 * omegadxx[14] - 2 * omegadxx[15] -
765                          2 * omegadxx[16] - 2 * omegadxx[17];
766         phidxx[p20[6]] = +4 * omegadxx[6] - 2 * omegadxx[7] - 4 * omegadxx[12] + 2 * omegadxx[13] +
767                          2 * omegadxx[18] - 4 * omegadxx[19];
768         phidxx[p20[7]] = -2 * omegadxx[6] + 4 * omegadxx[7] - 2 * omegadxx[12] - 2 * omegadxx[13] +
769                          4 * omegadxx[18] - 2 * omegadxx[19];
770         phidxx[p20[8]] = +4 * omegadxx[8] - 2 * omegadxx[9] + 2 * omegadxx[12] - 4 * omegadxx[13] +
771                          2 * omegadxx[16] - 4 * omegadxx[17];
772         phidxx[p20[9]] = -2 * omegadxx[8] + 4 * omegadxx[9] - 2 * omegadxx[12] - 2 * omegadxx[13] +
773                          4 * omegadxx[16] - 2 * omegadxx[17];
774         phidxx[p20[10]] = +4 * omegadxx[10] - 2 * omegadxx[11] + 2 * omegadxx[12] -
775                           4 * omegadxx[13] + 2 * omegadxx[14] - 4 * omegadxx[15];
776         phidxx[p20[11]] = -2 * omegadxx[10] + 4 * omegadxx[11] + 4 * omegadxx[12] -
777                           2 * omegadxx[13] + 4 * omegadxx[14] - 2 * omegadxx[15];
778         phidxx[p20[12]] = +8 * omegadxx[12] - 4 * omegadxx[13];
779         phidxx[p20[13]] = -4 * omegadxx[12] + 8 * omegadxx[13];
780         phidxx[p20[14]] = +8 * omegadxx[14] - 4 * omegadxx[15];
781         phidxx[p20[15]] = -4 * omegadxx[14] + 8 * omegadxx[15];
782         phidxx[p20[16]] = +8 * omegadxx[16] - 4 * omegadxx[17];
783         phidxx[p20[17]] = -4 * omegadxx[16] + 8 * omegadxx[17];
784         phidxx[p20[18]] = +8 * omegadxx[18] - 4 * omegadxx[19];
785         phidxx[p20[19]] = -4 * omegadxx[18] + 8 * omegadxx[19];
786 
787         for (int k = 0; k < 20; ++k) {
788           val(k, 0, op_dxx) = phidxx[k].x;
789           val(k, 1, op_dxx) = phidxx[k].y;
790           val(k, 2, op_dxx) = phidxx[k].z;
791         }
792       }
793 
794       R3 phidyy[20];
795       if (whatd & Fop_dyy) {
796         phidyy[p20[0]] = +4 * omegadyy[0] - 2 * omegadyy[1] - 4 * omegadyy[16] + 2 * omegadyy[17] -
797                          4 * omegadyy[18] + 2 * omegadyy[19];
798         phidyy[p20[1]] = -2 * omegadyy[0] + 4 * omegadyy[1] - 2 * omegadyy[16] - 2 * omegadyy[17] -
799                          2 * omegadyy[18] - 2 * omegadyy[19];
800         phidyy[p20[2]] = +4 * omegadyy[2] - 2 * omegadyy[3] - 4 * omegadyy[14] + 2 * omegadyy[15] +
801                          2 * omegadyy[18] - 4 * omegadyy[19];
802         phidyy[p20[3]] = -2 * omegadyy[2] + 4 * omegadyy[3] - 2 * omegadyy[14] - 2 * omegadyy[15] -
803                          2 * omegadyy[18] - 2 * omegadyy[19];
804         phidyy[p20[4]] = +4 * omegadyy[4] - 2 * omegadyy[5] + 2 * omegadyy[14] - 4 * omegadyy[15] +
805                          2 * omegadyy[16] - 4 * omegadyy[17];
806         phidyy[p20[5]] = -2 * omegadyy[4] + 4 * omegadyy[5] - 2 * omegadyy[14] - 2 * omegadyy[15] -
807                          2 * omegadyy[16] - 2 * omegadyy[17];
808         phidyy[p20[6]] = +4 * omegadyy[6] - 2 * omegadyy[7] - 4 * omegadyy[12] + 2 * omegadyy[13] +
809                          2 * omegadyy[18] - 4 * omegadyy[19];
810         phidyy[p20[7]] = -2 * omegadyy[6] + 4 * omegadyy[7] - 2 * omegadyy[12] - 2 * omegadyy[13] +
811                          4 * omegadyy[18] - 2 * omegadyy[19];
812         phidyy[p20[8]] = +4 * omegadyy[8] - 2 * omegadyy[9] + 2 * omegadyy[12] - 4 * omegadyy[13] +
813                          2 * omegadyy[16] - 4 * omegadyy[17];
814         phidyy[p20[9]] = -2 * omegadyy[8] + 4 * omegadyy[9] - 2 * omegadyy[12] - 2 * omegadyy[13] +
815                          4 * omegadyy[16] - 2 * omegadyy[17];
816         phidyy[p20[10]] = +4 * omegadyy[10] - 2 * omegadyy[11] + 2 * omegadyy[12] -
817                           4 * omegadyy[13] + 2 * omegadyy[14] - 4 * omegadyy[15];
818         phidyy[p20[11]] = -2 * omegadyy[10] + 4 * omegadyy[11] + 4 * omegadyy[12] -
819                           2 * omegadyy[13] + 4 * omegadyy[14] - 2 * omegadyy[15];
820         phidyy[p20[12]] = +8 * omegadyy[12] - 4 * omegadyy[13];
821         phidyy[p20[13]] = -4 * omegadyy[12] + 8 * omegadyy[13];
822         phidyy[p20[14]] = +8 * omegadyy[14] - 4 * omegadyy[15];
823         phidyy[p20[15]] = -4 * omegadyy[14] + 8 * omegadyy[15];
824         phidyy[p20[16]] = +8 * omegadyy[16] - 4 * omegadyy[17];
825         phidyy[p20[17]] = -4 * omegadyy[16] + 8 * omegadyy[17];
826         phidyy[p20[18]] = +8 * omegadyy[18] - 4 * omegadyy[19];
827         phidyy[p20[19]] = -4 * omegadyy[18] + 8 * omegadyy[19];
828 
829         for (int k = 0; k < 20; ++k) {
830           val(k, 0, op_dyy) = phidyy[k].x;
831           val(k, 1, op_dyy) = phidyy[k].y;
832           val(k, 2, op_dyy) = phidyy[k].z;
833         }
834       }
835 
836       R3 phidzz[20];
837       if (whatd & Fop_dzz) {
838         phidzz[p20[0]] = +4 * omegadzz[0] - 2 * omegadzz[1] - 4 * omegadzz[16] + 2 * omegadzz[17] -
839                          4 * omegadzz[18] + 2 * omegadzz[19];
840         phidzz[p20[1]] = -2 * omegadzz[0] + 4 * omegadzz[1] - 2 * omegadzz[16] - 2 * omegadzz[17] -
841                          2 * omegadzz[18] - 2 * omegadzz[19];
842         phidzz[p20[2]] = +4 * omegadzz[2] - 2 * omegadzz[3] - 4 * omegadzz[14] + 2 * omegadzz[15] +
843                          2 * omegadzz[18] - 4 * omegadzz[19];
844         phidzz[p20[3]] = -2 * omegadzz[2] + 4 * omegadzz[3] - 2 * omegadzz[14] - 2 * omegadzz[15] -
845                          2 * omegadzz[18] - 2 * omegadzz[19];
846         phidzz[p20[4]] = +4 * omegadzz[4] - 2 * omegadzz[5] + 2 * omegadzz[14] - 4 * omegadzz[15] +
847                          2 * omegadzz[16] - 4 * omegadzz[17];
848         phidzz[p20[5]] = -2 * omegadzz[4] + 4 * omegadzz[5] - 2 * omegadzz[14] - 2 * omegadzz[15] -
849                          2 * omegadzz[16] - 2 * omegadzz[17];
850         phidzz[p20[6]] = +4 * omegadzz[6] - 2 * omegadzz[7] - 4 * omegadzz[12] + 2 * omegadzz[13] +
851                          2 * omegadzz[18] - 4 * omegadzz[19];
852         phidzz[p20[7]] = -2 * omegadzz[6] + 4 * omegadzz[7] - 2 * omegadzz[12] - 2 * omegadzz[13] +
853                          4 * omegadzz[18] - 2 * omegadzz[19];
854         phidzz[p20[8]] = +4 * omegadzz[8] - 2 * omegadzz[9] + 2 * omegadzz[12] - 4 * omegadzz[13] +
855                          2 * omegadzz[16] - 4 * omegadzz[17];
856         phidzz[p20[9]] = -2 * omegadzz[8] + 4 * omegadzz[9] - 2 * omegadzz[12] - 2 * omegadzz[13] +
857                          4 * omegadzz[16] - 2 * omegadzz[17];
858         phidzz[p20[10]] = +4 * omegadzz[10] - 2 * omegadzz[11] + 2 * omegadzz[12] -
859                           4 * omegadzz[13] + 2 * omegadzz[14] - 4 * omegadzz[15];
860         phidzz[p20[11]] = -2 * omegadzz[10] + 4 * omegadzz[11] + 4 * omegadzz[12] -
861                           2 * omegadzz[13] + 4 * omegadzz[14] - 2 * omegadzz[15];
862         phidzz[p20[12]] = +8 * omegadzz[12] - 4 * omegadzz[13];
863         phidzz[p20[13]] = -4 * omegadzz[12] + 8 * omegadzz[13];
864         phidzz[p20[14]] = +8 * omegadzz[14] - 4 * omegadzz[15];
865         phidzz[p20[15]] = -4 * omegadzz[14] + 8 * omegadzz[15];
866         phidzz[p20[16]] = +8 * omegadzz[16] - 4 * omegadzz[17];
867         phidzz[p20[17]] = -4 * omegadzz[16] + 8 * omegadzz[17];
868         phidzz[p20[18]] = +8 * omegadzz[18] - 4 * omegadzz[19];
869         phidzz[p20[19]] = -4 * omegadzz[18] + 8 * omegadzz[19];
870 
871         for (int k = 0; k < 20; ++k) {
872           val(k, 0, op_dzz) = phidzz[k].x;
873           val(k, 1, op_dzz) = phidzz[k].y;
874           val(k, 2, op_dzz) = phidzz[k].z;
875         }
876       }
877 
878       R3 phidxy[20];
879       if (whatd & Fop_dxy) {
880         phidxy[p20[0]] = +4 * omegadxy[0] - 2 * omegadxy[1] - 4 * omegadxy[16] + 2 * omegadxy[17] -
881                          4 * omegadxy[18] + 2 * omegadxy[19];
882         phidxy[p20[1]] = -2 * omegadxy[0] + 4 * omegadxy[1] - 2 * omegadxy[16] - 2 * omegadxy[17] -
883                          2 * omegadxy[18] - 2 * omegadxy[19];
884         phidxy[p20[2]] = +4 * omegadxy[2] - 2 * omegadxy[3] - 4 * omegadxy[14] + 2 * omegadxy[15] +
885                          2 * omegadxy[18] - 4 * omegadxy[19];
886         phidxy[p20[3]] = -2 * omegadxy[2] + 4 * omegadxy[3] - 2 * omegadxy[14] - 2 * omegadxy[15] -
887                          2 * omegadxy[18] - 2 * omegadxy[19];
888         phidxy[p20[4]] = +4 * omegadxy[4] - 2 * omegadxy[5] + 2 * omegadxy[14] - 4 * omegadxy[15] +
889                          2 * omegadxy[16] - 4 * omegadxy[17];
890         phidxy[p20[5]] = -2 * omegadxy[4] + 4 * omegadxy[5] - 2 * omegadxy[14] - 2 * omegadxy[15] -
891                          2 * omegadxy[16] - 2 * omegadxy[17];
892         phidxy[p20[6]] = +4 * omegadxy[6] - 2 * omegadxy[7] - 4 * omegadxy[12] + 2 * omegadxy[13] +
893                          2 * omegadxy[18] - 4 * omegadxy[19];
894         phidxy[p20[7]] = -2 * omegadxy[6] + 4 * omegadxy[7] - 2 * omegadxy[12] - 2 * omegadxy[13] +
895                          4 * omegadxy[18] - 2 * omegadxy[19];
896         phidxy[p20[8]] = +4 * omegadxy[8] - 2 * omegadxy[9] + 2 * omegadxy[12] - 4 * omegadxy[13] +
897                          2 * omegadxy[16] - 4 * omegadxy[17];
898         phidxy[p20[9]] = -2 * omegadxy[8] + 4 * omegadxy[9] - 2 * omegadxy[12] - 2 * omegadxy[13] +
899                          4 * omegadxy[16] - 2 * omegadxy[17];
900         phidxy[p20[10]] = +4 * omegadxy[10] - 2 * omegadxy[11] + 2 * omegadxy[12] -
901                           4 * omegadxy[13] + 2 * omegadxy[14] - 4 * omegadxy[15];
902         phidxy[p20[11]] = -2 * omegadxy[10] + 4 * omegadxy[11] + 4 * omegadxy[12] -
903                           2 * omegadxy[13] + 4 * omegadxy[14] - 2 * omegadxy[15];
904         phidxy[p20[12]] = +8 * omegadxy[12] - 4 * omegadxy[13];
905         phidxy[p20[13]] = -4 * omegadxy[12] + 8 * omegadxy[13];
906         phidxy[p20[14]] = +8 * omegadxy[14] - 4 * omegadxy[15];
907         phidxy[p20[15]] = -4 * omegadxy[14] + 8 * omegadxy[15];
908         phidxy[p20[16]] = +8 * omegadxy[16] - 4 * omegadxy[17];
909         phidxy[p20[17]] = -4 * omegadxy[16] + 8 * omegadxy[17];
910         phidxy[p20[18]] = +8 * omegadxy[18] - 4 * omegadxy[19];
911         phidxy[p20[19]] = -4 * omegadxy[18] + 8 * omegadxy[19];
912 
913         for (int k = 0; k < 20; ++k) {
914           val(k, 0, op_dxy) = phidxy[k].x;
915           val(k, 1, op_dxy) = phidxy[k].y;
916           val(k, 2, op_dxy) = phidxy[k].z;
917         }
918       }
919 
920       R3 phidxz[20];
921       if (whatd & Fop_dxz) {
922         phidxz[p20[0]] = +4 * omegadxz[0] - 2 * omegadxz[1] - 4 * omegadxz[16] + 2 * omegadxz[17] -
923                          4 * omegadxz[18] + 2 * omegadxz[19];
924         phidxz[p20[1]] = -2 * omegadxz[0] + 4 * omegadxz[1] - 2 * omegadxz[16] - 2 * omegadxz[17] -
925                          2 * omegadxz[18] - 2 * omegadxz[19];
926         phidxz[p20[2]] = +4 * omegadxz[2] - 2 * omegadxz[3] - 4 * omegadxz[14] + 2 * omegadxz[15] +
927                          2 * omegadxz[18] - 4 * omegadxz[19];
928         phidxz[p20[3]] = -2 * omegadxz[2] + 4 * omegadxz[3] - 2 * omegadxz[14] - 2 * omegadxz[15] -
929                          2 * omegadxz[18] - 2 * omegadxz[19];
930         phidxz[p20[4]] = +4 * omegadxz[4] - 2 * omegadxz[5] + 2 * omegadxz[14] - 4 * omegadxz[15] +
931                          2 * omegadxz[16] - 4 * omegadxz[17];
932         phidxz[p20[5]] = -2 * omegadxz[4] + 4 * omegadxz[5] - 2 * omegadxz[14] - 2 * omegadxz[15] -
933                          2 * omegadxz[16] - 2 * omegadxz[17];
934         phidxz[p20[6]] = +4 * omegadxz[6] - 2 * omegadxz[7] - 4 * omegadxz[12] + 2 * omegadxz[13] +
935                          2 * omegadxz[18] - 4 * omegadxz[19];
936         phidxz[p20[7]] = -2 * omegadxz[6] + 4 * omegadxz[7] - 2 * omegadxz[12] - 2 * omegadxz[13] +
937                          4 * omegadxz[18] - 2 * omegadxz[19];
938         phidxz[p20[8]] = +4 * omegadxz[8] - 2 * omegadxz[9] + 2 * omegadxz[12] - 4 * omegadxz[13] +
939                          2 * omegadxz[16] - 4 * omegadxz[17];
940         phidxz[p20[9]] = -2 * omegadxz[8] + 4 * omegadxz[9] - 2 * omegadxz[12] - 2 * omegadxz[13] +
941                          4 * omegadxz[16] - 2 * omegadxz[17];
942         phidxz[p20[10]] = +4 * omegadxz[10] - 2 * omegadxz[11] + 2 * omegadxz[12] -
943                           4 * omegadxz[13] + 2 * omegadxz[14] - 4 * omegadxz[15];
944         phidxz[p20[11]] = -2 * omegadxz[10] + 4 * omegadxz[11] + 4 * omegadxz[12] -
945                           2 * omegadxz[13] + 4 * omegadxz[14] - 2 * omegadxz[15];
946         phidxz[p20[12]] = +8 * omegadxz[12] - 4 * omegadxz[13];
947         phidxz[p20[13]] = -4 * omegadxz[12] + 8 * omegadxz[13];
948         phidxz[p20[14]] = +8 * omegadxz[14] - 4 * omegadxz[15];
949         phidxz[p20[15]] = -4 * omegadxz[14] + 8 * omegadxz[15];
950         phidxz[p20[16]] = +8 * omegadxz[16] - 4 * omegadxz[17];
951         phidxz[p20[17]] = -4 * omegadxz[16] + 8 * omegadxz[17];
952         phidxz[p20[18]] = +8 * omegadxz[18] - 4 * omegadxz[19];
953         phidxz[p20[19]] = -4 * omegadxz[18] + 8 * omegadxz[19];
954 
955         for (int k = 0; k < 20; ++k) {
956           val(k, 0, op_dxz) = phidxz[k].x;
957           val(k, 1, op_dxz) = phidxz[k].y;
958           val(k, 2, op_dxz) = phidxz[k].z;
959         }
960       }
961 
962       R3 phidyz[20];
963       if (whatd & Fop_dyz) {
964         phidyz[p20[0]] = +4 * omegadyz[0] - 2 * omegadyz[1] - 4 * omegadyz[16] + 2 * omegadyz[17] -
965                          4 * omegadyz[18] + 2 * omegadyz[19];
966         phidyz[p20[1]] = -2 * omegadyz[0] + 4 * omegadyz[1] - 2 * omegadyz[16] - 2 * omegadyz[17] -
967                          2 * omegadyz[18] - 2 * omegadyz[19];
968         phidyz[p20[2]] = +4 * omegadyz[2] - 2 * omegadyz[3] - 4 * omegadyz[14] + 2 * omegadyz[15] +
969                          2 * omegadyz[18] - 4 * omegadyz[19];
970         phidyz[p20[3]] = -2 * omegadyz[2] + 4 * omegadyz[3] - 2 * omegadyz[14] - 2 * omegadyz[15] -
971                          2 * omegadyz[18] - 2 * omegadyz[19];
972         phidyz[p20[4]] = +4 * omegadyz[4] - 2 * omegadyz[5] + 2 * omegadyz[14] - 4 * omegadyz[15] +
973                          2 * omegadyz[16] - 4 * omegadyz[17];
974         phidyz[p20[5]] = -2 * omegadyz[4] + 4 * omegadyz[5] - 2 * omegadyz[14] - 2 * omegadyz[15] -
975                          2 * omegadyz[16] - 2 * omegadyz[17];
976         phidyz[p20[6]] = +4 * omegadyz[6] - 2 * omegadyz[7] - 4 * omegadyz[12] + 2 * omegadyz[13] +
977                          2 * omegadyz[18] - 4 * omegadyz[19];
978         phidyz[p20[7]] = -2 * omegadyz[6] + 4 * omegadyz[7] - 2 * omegadyz[12] - 2 * omegadyz[13] +
979                          4 * omegadyz[18] - 2 * omegadyz[19];
980         phidyz[p20[8]] = +4 * omegadyz[8] - 2 * omegadyz[9] + 2 * omegadyz[12] - 4 * omegadyz[13] +
981                          2 * omegadyz[16] - 4 * omegadyz[17];
982         phidyz[p20[9]] = -2 * omegadyz[8] + 4 * omegadyz[9] - 2 * omegadyz[12] - 2 * omegadyz[13] +
983                          4 * omegadyz[16] - 2 * omegadyz[17];
984         phidyz[p20[10]] = +4 * omegadyz[10] - 2 * omegadyz[11] + 2 * omegadyz[12] -
985                           4 * omegadyz[13] + 2 * omegadyz[14] - 4 * omegadyz[15];
986         phidyz[p20[11]] = -2 * omegadyz[10] + 4 * omegadyz[11] + 4 * omegadyz[12] -
987                           2 * omegadyz[13] + 4 * omegadyz[14] - 2 * omegadyz[15];
988         phidyz[p20[12]] = +8 * omegadyz[12] - 4 * omegadyz[13];
989         phidyz[p20[13]] = -4 * omegadyz[12] + 8 * omegadyz[13];
990         phidyz[p20[14]] = +8 * omegadyz[14] - 4 * omegadyz[15];
991         phidyz[p20[15]] = -4 * omegadyz[14] + 8 * omegadyz[15];
992         phidyz[p20[16]] = +8 * omegadyz[16] - 4 * omegadyz[17];
993         phidyz[p20[17]] = -4 * omegadyz[16] + 8 * omegadyz[17];
994         phidyz[p20[18]] = +8 * omegadyz[18] - 4 * omegadyz[19];
995         phidyz[p20[19]] = -4 * omegadyz[18] + 8 * omegadyz[19];
996 
997         for (int k = 0; k < 20; ++k) {
998           val(k, 0, op_dyz) = phidyz[k].x;
999           val(k, 1, op_dyz) = phidyz[k].y;
1000           val(k, 2, op_dyz) = phidyz[k].z;
1001         }
1002       }
1003     }
1004   }
1005 
1006   // Author: Marcella Bonazzoli
1007   // Edge elements of degree 3, 3D
1008   // (they are called Edge23d because the Nedelec elements of degree 1 are called Edge03d)
1009   // TypeOfFE_Edge2_3d derived from GTypeOfFE<> (which is defined in FESpacen.hpp)
1010   class TypeOfFE_Edge2_3d : public GTypeOfFE< Mesh3 > {
1011    public:
1012     typedef Mesh3 Mesh;
1013     typedef Mesh3::Element Element;
1014     typedef GFElement< Mesh3 > FElement;
1015 
1016     static int dfon[];
1017     static const int d = Mesh::Rd::d;
1018     static const GQuadratureFormular< R1 > QFe;    // quadrature formula on an edge
1019     static const GQuadratureFormular< R2 > QFf;    // quadrature formula on a face
1020     static const GQuadratureFormular< R3 > QFv;    // quadrature formula on a tetrahedron
1021     TypeOfFE_Edge2_3d( );                          // constructor
1022     void FB(const What_d whatd, const Mesh &Th, const Mesh3::Element &K, const RdHat &PHat,
1023             RNMK_ &val) const;
1024     void set(const Mesh &Th, const Element &K, InterpolationMatrix< RdHat > &M, int ocoef, int odf,
1025              int *nump) const;
1026   };
1027 
1028   int TypeOfFE_Edge2_3d::dfon[] = {
1029     0, 3, 6, 3};    // 3 dofs on each edge, 6 dofs on each face, 3 dofs on the tetrahedron
1030 
1031   // Quadrature formula on an edge, exact for degree 5 (ok: int_e (deg3*t *lambda*lambda))
1032   const GQuadratureFormular< R1 > TypeOfFE_Edge2_3d::QFe(2 * 3 - 1, 3, GaussLegendre(3), true);
1033   // arguments: exact, num of integration pts, integration pts, clean (~GQuadratureFormular()
1034   // {if(clean) delete [] p;}) GaussLegendre defined in QuadratureFormular.cpp
1035 
1036   // Quadrature formula on a face, exact for degree 4 (ok: int_f (deg3*t*lambda))
1037   // (From Mark A. Taylor, Beth A. Wingate, Len P. Bos,
1038   // Several new quadrature formulas for polynomial integration in the triangle)
1039   static GQuadraturePoint< R2 > P_QuadratureFormular_T_4_TWB[6] = {
1040     GQuadraturePoint< R2 >(0.2199034873106 / 2, R2(0.0915762135098, 0.0915762135098)),
1041     GQuadraturePoint< R2 >(0.2199034873106 / 2, R2(0.8168475729805, 0.0915762135098)),
1042     GQuadraturePoint< R2 >(0.2199034873106 / 2, R2(0.0915762135098, 0.8168475729805)),
1043     GQuadraturePoint< R2 >(0.4467631793560 / 2, R2(0.1081030181681, 0.4459484909160)),
1044     GQuadraturePoint< R2 >(0.4467631793560 / 2, R2(0.4459484909160, 0.1081030181681)),
1045     GQuadraturePoint< R2 >(0.4467631793560 / 2, R2(0.4459484909160, 0.4459484909160))};
1046   const GQuadratureFormular< R2 > TypeOfFE_Edge2_3d::QFf(4, 6, P_QuadratureFormular_T_4_TWB);
1047 
1048   // Quadrature formula on a tetrahedron, exact for degree 3 (ok: int_v (deg3*t))
1049   // (From Table 4.57 pag 247 Solin HOFEM, coords trasformed like on pag 68,
1050   // weights multiplied by 6/8 so that their sum is equal to 1)
1051   static GQuadraturePoint< R3 > P_QuadratureFormular_Tet_3_solin[5] = {
1052     GQuadraturePoint< R3 >(R3(0.25, 0.25, 0.25), -0.8),
1053     GQuadraturePoint< R3 >(R3(1. / 6., 1. / 6., 1. / 6.), 0.45),
1054     GQuadraturePoint< R3 >(R3(1. / 6., 1. / 6., 0.5), 0.45),
1055     GQuadraturePoint< R3 >(R3(1. / 6., 0.5, 1. / 6.), 0.45),
1056     GQuadraturePoint< R3 >(R3(0.5, 1. / 6., 1. / 6.), 0.45)};
1057   const GQuadratureFormular< R3 > TypeOfFE_Edge2_3d::QFv(3, 5, P_QuadratureFormular_Tet_3_solin);
1058 
1059   // In Mesh3dn.cpp:
1060   // static const int  nvedgeTet[6][2] = { {0,1},{0,2},{0,3},{1,2},{1,3},{2,3} };
1061   // static const int  nvfaceTet[4][3] = { {3,2,1},{0,2,3},{3,1,0},{0,1,2} };
1062   // In GenericMesh.hpp:
1063   // Vertex& at(int i) {return *vertices[i];}
1064   // In GenericMesh.hpp:
1065   // Rd Edge(int i) const {ASSERTION(i>=0 && i <ne);
1066   // return Rd(at(nvedge[i][0]),at(nvedge[i][1]));}
1067   // In GenericMesh.hpp:
1068   // bool   EdgeOrientation(int i) const
1069   // { return &at(nvedge[i][0]) < &at(nvedge[i][1]);}
1070 
1071   // Constructor
1072   // dfon, d, nsub,
1073   // kPi = NbcoefforInterpolation is the number of alphas in (13.1) (chapter 13 ff++doc)
1074   // = 3(=numComp)*QFe.n(num quad pts edge)*3*ne(3 fncts per edge) +
1075   // 3(=numComp)*QFf.n(num quad pts face)*6*nf(6 fncts per face) +
1076   // 3(=numComp)*QFv.n(num quad pts volume)*3(3 volume fncts)
1077   // npPi = NbPtforInterpolation = ne*QFe.n+nf*QFf.n+QFv.n
1078   // invariantinterpolationMatrix = false (i.e. it depends on the tetrahedron), discon=true
TypeOfFE_Edge2_3d()1079   TypeOfFE_Edge2_3d::TypeOfFE_Edge2_3d( )
1080     : GTypeOfFE< Mesh3 >(TypeOfFE_Edge2_3d::dfon, d, 1,
1081                          3 * QFe.n * 3 * Element::ne + 3 * QFf.n * 6 * Element::nf + 3 * QFv.n * 3,
1082                          Element::ne * QFe.n + Element::nf * QFf.n + QFv.n, false, true) {
1083     assert(QFe.n);
1084     assert(QFf.n);
1085     assert(QFv.n);
1086     R3 Pt[] = {R3(0., 0., 0.), R3(1., 0., 0.), R3(0., 1., 0.),
1087                R3(0., 0., 1.)};    // 4 ref tetrahedron vertices
1088 
1089     {
1090       // We build the interpolation pts on the edges of the reference tetrahedron:
1091       int p;
1092       p = 0;
1093 
1094       for (int e = 0; e < Element::ne; ++e) {
1095         for (int q = 0; q < QFe.n; ++q, ++p) {
1096           double x = QFe[q].x;
1097           this->PtInterpolation[p] =
1098             Pt[Element::nvedge[e][0]] * (1. - x) + Pt[Element::nvedge[e][1]] * (x);
1099         }
1100       }
1101 
1102       // We build the interpolation pts on the faces of the reference tetrahedron:
1103       // (the index i mustn't be reinitialised!)
1104       for (int f = 0; f < Element::nf; ++f) {
1105         for (int q = 0; q < QFf.n; ++q, ++p) {
1106           double x = QFf[q].x;
1107           double y = QFf[q].y;
1108           this->PtInterpolation[p] = Pt[Element::nvface[f][0]] * (1. - x - y) +
1109                                      Pt[Element::nvface[f][1]] * x + Pt[Element::nvface[f][2]] * y;
1110         }
1111       }
1112 
1113       // We build the interpolation pts on the tetrahedron:
1114       // (the index i mustn't be reinitialised!)
1115       for (int q = 0; q < QFv.n; ++q, ++p) {
1116         double x = QFv[q].x;
1117         double y = QFv[q].y;
1118         double z = QFv[q].z;
1119         this->PtInterpolation[p] = Pt[0] * (1. - x - y - z) + Pt[1] * x + Pt[2] * y + Pt[3] * z;
1120       }
1121     }
1122     {
1123       // We build the indices in (13.1) : edge dofs
1124       int i = 0, p = 0;    // i is the k in (13.1) (chapter 13 ff++doc)
1125       int e;               // we will need e also below, in the parts referred to faces and volumes
1126 
1127       for (e = 0; e < (Element::ne)*3; e++) {    // loop on the 18 edge dofs
1128         if (e % 3 != 0) {
1129           p = p - QFe.n;
1130         }    // for 3 successive dofs the quad pts are the same (they correspond to the same edge)
1131 
1132         for (int q = 0; q < QFe.n; ++q, ++p) {    // loop on the edge quadrature pts
1133           for (int c = 0; c < 3; c++, i++) {      // loop on the 3 components
1134             this->pInterpolation[i] = p;          // pk in (13.1)
1135             this->cInterpolation[i] = c;          // jk in (13.1)
1136             this->dofInterpolation[i] = e;        // ik in (13.1)
1137             this->coefInterpolation[i] = 0.;      // alfak: we will fill them with 'set' (below)
1138                                                   // because they depend on the tetrahedron
1139           }
1140         }
1141       }
1142 
1143       // We build the indices in (13.1) : face dofs
1144       // (the indices i and p mustn't be reinitialised)
1145       int f;    // we will need f also below, in the part referred to volumes
1146 
1147       for (f = 0; f < (Element::nf)*6; f++) {    // loop on the 24 face dofs
1148         if (f % 6 != 0) {
1149           p = p - QFf.n;
1150         }    // for 6 successive dofs the quad pts are the same (they correspond to the same face)
1151 
1152         for (int q = 0; q < QFf.n; ++q, ++p) {    // loop on the face quadrature pts
1153           for (int c = 0; c < 3; c++, i++) {      // loop on the 3 components
1154             this->pInterpolation[i] = p;          // pk in (13.1)
1155             this->cInterpolation[i] = c;          // jk in (13.1)
1156             this->dofInterpolation[i] = e + f;    // ik in (13.1)
1157             this->coefInterpolation[i] = 0.;      // alphak: we will fill them with 'set' (below)
1158                                                   // because they depend on the tetrahedron
1159           }
1160         }
1161       }
1162 
1163       // We build the indices in (13.1) : volume dofs
1164       // (the indices i and p mustn't be reinitialised)
1165       for (int v = 0; v < 3; v++) {    // loop on the 3 volume dofs
1166         if (v > 0) {
1167           p = p - QFv.n;
1168         }
1169 
1170         for (int q = 0; q < QFv.n; ++q, ++p) {        // loop on the volume quadrature pts
1171           for (int c = 0; c < 3; c++, i++) {          // loop on the 3 components
1172             this->pInterpolation[i] = p;              // pk in (13.1)
1173             this->cInterpolation[i] = c;              // jk in (13.1)
1174             this->dofInterpolation[i] = e + f + v;    // ik in (13.1)
1175             this->coefInterpolation[i] = 0.;    // alphak: we will fill them with 'set' (below)
1176                                                 // because they depend on the tetrahedron
1177           }
1178         }
1179       }
1180     }
1181   }
1182 
1183   // For the coefficients of interpolation alphak in (13.1)
set(const Mesh & Th,const Element & K,InterpolationMatrix<RdHat> & M,int ocoef,int odf,int * nump) const1184   void TypeOfFE_Edge2_3d::set(const Mesh &Th, const Element &K, InterpolationMatrix< RdHat > &M,
1185                               int ocoef, int odf, int *nump) const {
1186     int i = ocoef, p = 0;
1187     // (p is used only to check)
1188 
1189     // perm: the permutation for which the 4 tetrahedron vertices are listed with increasing GLOBAL
1190     // number (i.e. perm[0] is the local number of the vertex with the smallest global number, ...
1191     // perm[3] is the local number of the vertex with the biggest global number.)
1192     const Element::Vertex *tV[4] = {&K.at(0), &K.at(1), &K.at(2), &K.at(3)};
1193     int k0 = 0, k1 = 1, k2 = 2, k3 = 3;
1194 
1195     if (tV[k0] > tV[k1]) {
1196       Exchange(k0, k1);
1197     }
1198 
1199     if (tV[k1] > tV[k2]) {
1200       Exchange(k1, k2);
1201     }
1202 
1203     if (tV[k2] > tV[k3]) {
1204       Exchange(k2, k3);
1205     }
1206 
1207     if (tV[k0] > tV[k1]) {
1208       Exchange(k0, k1);
1209     }
1210 
1211     if (tV[k1] > tV[k2]) {
1212       Exchange(k1, k2);
1213     }
1214 
1215     if (tV[k0] > tV[k1]) {
1216       Exchange(k0, k1);
1217     }
1218 
1219     int perm[4] = {k0, k1, k2, k3};
1220     // here perm is used only for volume dofs (I wrote a version in which perm is exploited also for
1221     // edge and face dofs, but I don't know if it costs less)
1222 
1223     // 18 edge dofs
1224     for (int ee = 0; ee < Element::ne; ee++) {    // loop on the edges
1225       R3 E = K.EdgeOrientation(ee) * K.Edge(ee);
1226       int eo = K.EdgeOrientation(ee);
1227       if (eo < 0) {
1228         E = -E;
1229       }
1230 
1231       for (int edof = 0; edof < 3; ++edof) {    // 3 dofs for each edge
1232         if (edof != 0) {
1233           p = p - QFe.n;
1234         }
1235 
1236         for (int q = 0; q < QFe.n; ++q, ++p) {    // loop on the edge quadrature pts
1237           double ll = 1 - QFe[q].x;               // lambda of the first vertex of the edge
1238           if (eo < 0) {
1239             ll = 1 - ll;
1240           }
1241 
1242           double prodll;    // the product of two lambdas:
1243           if (edof == 0) {
1244             prodll = ll * ll;
1245           } else if (edof == 1) {
1246             prodll = ll * (1 - ll);
1247           } else {
1248             prodll = (1 - ll) * (1 - ll);    // if (edof==2)
1249           }
1250 
1251           for (int c = 0; c < 3; c++, i++) {    // loop on the 3 components
1252             M.coef[i] = E[c] * QFe[q].a * prodll;
1253             // QFe[q].a is the weight of the integration point q
1254             // QFe[q].x is the x over [0,1] of the integration point q
1255           }
1256         }
1257       }
1258     }
1259 
1260     // (the indices i and p mustn't be reinitialised)
1261     for (int ff = 0; ff < Element::nf; ff++) {    // loop on the 24 face dofs
1262       const Element::Vertex *fV[3] = {&K.at(Element::nvface[ff][0]), &K.at(Element::nvface[ff][1]),
1263                                       &K.at(Element::nvface[ff][2])};
1264       // We 'order' the 3 vertices of the face according to their global numbers:
1265       // i0f will be the local number in the FACE of the vertex with the smallest global number
1266       // i1f will be the local number in the face of the vertex with the second smallest global
1267       // number i2f will be the local number in the face of the vertex with the largest global
1268       // number
1269       int i0f = 0, i1f = 1, i2f = 2;
1270       if (fV[i0f] > fV[i1f]) {
1271         Exchange(i0f, i1f);
1272       }
1273 
1274       if (fV[i1f] > fV[i2f]) {
1275         Exchange(i1f, i2f);
1276         if (fV[i0f] > fV[i1f]) {
1277           Exchange(i0f, i1f);
1278         }
1279       }
1280 
1281       // now local numbers in the tetrahedron:
1282       int i0 = Element::nvface[ff][i0f], i1 = Element::nvface[ff][i1f],
1283           i2 = Element::nvface[ff][i2f];
1284 
1285       for (int fdof = 0; fdof < 6; ++fdof) {    // 6 dofs for each face
1286         int ie0 = i0,
1287             ie1 = fdof < 3 ? i1 : i2;    // edge for the face dof (its endpoints local numbers)
1288         // [i0,i1] for the first 3 dofs, [i0,i2] for the last 3 dofs
1289         R3 E(K[ie0], K[ie1]);
1290         if (fdof != 0) {
1291           p = p - QFf.n;
1292         }
1293 
1294         for (int q = 0; q < QFf.n; ++q, ++p) {    // loop on the face quadrature pts
1295           double ll3[3] = {1. - QFf[q].x - QFf[q].y, QFf[q].x,
1296                            QFf[q].y};    // the 3 lambdas of the face
1297           double ll;
1298           if (fdof % 3 == 0) {
1299             ll = ll3[i0f];
1300           } else if (fdof % 3 == 1) {
1301             ll = ll3[i1f];
1302           } else {
1303             ll = ll3[i2f];    // if (fdof%3==2)
1304           }
1305 
1306           for (int c = 0; c < 3; c++, i++) {    // loop on the 3 components
1307             M.coef[i] = E[c] * QFf[q].a * ll;
1308           }
1309         }
1310       }
1311     }
1312 
1313     // (the indices i and p mustn't be reinitialised)
1314     for (int v = 0; v < 3; v++) {          // loop on the 3 volume dofs
1315       R3 E(K[perm[0]], K[perm[v + 1]]);    // edge for the volume dof
1316       if (v > 0) {
1317         p = p - QFv.n;
1318       }
1319 
1320       for (int q = 0; q < QFv.n; ++q, ++p) {    // loop on the volume quadrature pts
1321         for (int c = 0; c < 3; c++, i++) {      // loop on the 3 components
1322           M.coef[i] = E[c] * QFv[q].a;
1323         }
1324       }
1325     }
1326 
1327     ffassert(i == M.ncoef && M.np == p);
1328   }
1329 
1330   // In Mesh3dn.hpp:
1331   // void Gradlambda(R3 * GradL) const
1332   // {
1333   // R3 V1(at(0),at(1));
1334   // R3 V2(at(0),at(2));
1335   // R3 V3(at(0),at(3));
1336   // R det1=1./(6.*mesure());
1337   // GradL[1]= (V2^V3)*det1;
1338   // GradL[2]= (V3^V1)*det1;
1339   // GradL[3]= (V1^V2)*det1;
1340   // GradL[0]=-GradL[1]-GradL[2]-GradL[3];
1341   // }
1342 
1343   /*
1344    * FB: We are on a tetrahedron K
1345    * (the local numbering of its 4 vertices is given by how they are listed where K is described in
1346    * the mesh file).
1347    *
1348    * AT FIRST we BUILD the 'pre-basis' functions OMEGA in the order given by the GLOBAL numbering of
1349    * the tetrahedron vertices, that is the 1st examined edge is from the vertex with the 1st
1350    * smallest GLOBAL number to the one with the 2nd smallest GLOBAL number, and so on (see nvedege),
1351    * and the 1st examined face is the one opposite the vertex with the smallest GLOBAL number
1352    * (and 2 edges of the face are chosen and oriented looking at its 3 GLOBAL numbers), and so on.
1353    * In this way:
1354    * - a dof which is common to 2 adjacent tetrahedra is the same in the two tetrahedra
1355    * (since the orientation of each edge is chosen using the global numbers),
1356    * - we can use the coefficients giving a dual basis that were calculated for the reference
1357    * tetrahedron since the structure of orientation of the edges is the same (up to a rotation) as
1358    * the one used in the reference tetrahedron.
1359    *
1360    * BUT THEN, when we build the DUAL basis functions PHI, we use the permutation p45 to go back to
1361    * the FreeFem numbering of the dofs, in which edges and faces are ordered following the LOCAL
1362    * numbering (for instance the 1st examined edge can be the 3rd edge looking at the local
1363    * numbering); however inside each edge (resp face) the 3 (resp 6) related dofs are still ordered
1364    * according to the GLOBAL numbers. Here with 'dual' I mean basis functions and dofs in duality.
1365    */
1366 
1367   // val contains the values of the basis functions and of their derivatives at the point of K
1368   // corresponding to the point P of the reference tetrahedron, by components
FB(const What_d whatd,const Mesh & Th,const Mesh3::Element & K,const RdHat & PHat,RNMK_ & val) const1369   void TypeOfFE_Edge2_3d::FB(const What_d whatd, const Mesh &Th, const Mesh3::Element &K,
1370                              const RdHat &PHat, RNMK_ &val) const {
1371     assert(val.N( ) >= 45);    // 45 degrees of freedom
1372     assert(val.M( ) == 3);     // 3 components
1373     // -------------
1374     // perm: the permutation for which the 4 tetrahedron vertices are listed with increasing GLOBAL
1375     // number (i.e. perm[0] is the local number of the vertex with the smallest global number, ...
1376     // perm[3] is the local number of the vertex with the biggest global number.)
1377     const Element::Vertex *tV[4] = {&K.at(0), &K.at(1), &K.at(2), &K.at(3)};
1378     int k0 = 0, k1 = 1, k2 = 2, k3 = 3;
1379     if (tV[k0] > tV[k1]) {
1380       Exchange(k0, k1);
1381     }
1382 
1383     if (tV[k1] > tV[k2]) {
1384       Exchange(k1, k2);
1385     }
1386 
1387     if (tV[k2] > tV[k3]) {
1388       Exchange(k2, k3);
1389     }
1390 
1391     if (tV[k0] > tV[k1]) {
1392       Exchange(k0, k1);
1393     }
1394 
1395     if (tV[k1] > tV[k2]) {
1396       Exchange(k1, k2);
1397     }
1398 
1399     if (tV[k0] > tV[k1]) {
1400       Exchange(k0, k1);
1401     }
1402 
1403     int perm[4] = {k0, k1, k2, k3};
1404     // -------------
1405     // We build mynvface to be used here instead of the FreeFem nvface,
1406     // (in order to exploit the results of perm and write a better code),
1407     // in mynvface in all the triplets the numbers are increasing
1408     static const int mynvface[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
1409     // -------------
1410     // If [a,b] is the i-th edge (where a,b are its vertices local numbers), edgesMap[(a+1)*(b+1)] =
1411     // i
1412     int edgesMap[13] = {-1, -1, 0,  1,  2,  -1, 3,
1413                         -1, 4,  -1, -1, -1, 5};    // a map<int,int> would be more slow
1414     // -------------
1415     // the 4 barycentric coordinates for the reference tetrahedron evaluated at the point P
1416     // (they have the same value at the real tetrahedron's point corresponding to the reference
1417     // tetrahedron's point P)
1418     R l[] = {1. - PHat.sum( ), PHat.x, PHat.y, PHat.z};
1419     R3 D[4];
1420     K.Gradlambda(D);
1421     val = 0;
1422     // -------------
1423     int p45[45];    // the permutation from the dofs numbering of my tetrahedron (numbered using the
1424                     // global vertex numbers)
1425 
1426     // to the dofs numbering of FreeFem !!!!! (see the comment above)
1427     for (int i = 0; i < Element::ne; ++i) {    // edges (3 dofs for each edge)
1428       int ii0 = Element::nvedge[i][0], ii1 = Element::nvedge[i][1];
1429       int i0 = perm[ii0];
1430       int i1 = perm[ii1];
1431       int iEdge = edgesMap[(i0 + 1) * (i1 + 1)];    // i of the edge [i0,i1]
1432       p45[i * 3] = iEdge * 3;
1433       p45[i * 3 + 1] = iEdge * 3 + 1;
1434       p45[i * 3 + 2] = iEdge * 3 + 2;
1435     }
1436 
1437     for (int j = 0; j < Element::nf; ++j) {    // faces (6 dofs for each face)
1438       // using perm the 1st examined face is the one opposite the vertex with the smallest GLOBAL
1439       // number, and so on
1440       int jFace = perm[j];
1441       int dof0j = 18 + j * 6;
1442       int dof0jF = 18 + jFace * 6;
1443 
1444       for (int s = 0; s < 6; ++s) {
1445         p45[dof0j + s] = dof0jF + s;
1446       }    // p45[18+j*6+0] = 18+jFace*6+0; ... p45[18+j*6+5] = 18+jFace*6+5;
1447     }
1448 
1449     // 3 dofs for the tetrahedron
1450     p45[42] = 42;
1451     p45[43] = 43;
1452     p45[44] = 44;    // (there is only 1 'volume', the FF dofs numbering is the same as mine)
1453     // -------------
1454 
1455     if (whatd & Fop_D0) {    // Fop_D0 defined in FESpacen.hpp
1456       // First, the functions omega (om) (they don't constitute a dual basis! only a basis)
1457       R3 om[45];
1458 
1459       // 18 edge functions (3 for each edge):
1460       for (int i = 0; i < Element::ne; ++i) {
1461         int ii0 = Element::nvedge[i][0], ii1 = Element::nvedge[i][1];
1462         int i0 = perm[ii0];
1463         int i1 = perm[ii1];
1464         // ! :
1465         // using perm, [i0,i1] is already from the smallest global number to the greatest global
1466         // number, since nvedge always gives indices which read perm from left to right
1467         om[i * 3] = l[i0] * l[i0] * (l[i0] * D[i1] - l[i1] * D[i0]);
1468         om[i * 3 + 1] = l[i0] * l[i1] * (l[i0] * D[i1] - l[i1] * D[i0]);
1469         om[i * 3 + 2] = l[i1] * l[i1] * (l[i0] * D[i1] - l[i1] * D[i0]);
1470       }
1471 
1472       // 24 face functions (6 for each face):
1473       for (int j = 0; j < Element::nf; ++j) {
1474         // In (my)nvface the face opposite the vertex k is (my)nvface[k][],
1475         // using perm the 1st examined face is the one opposite the vertex with the smallest GLOBAL
1476         // number, and so on, and, since in mynvface the numbers always increase, [i0,i1,i2] are
1477         // already ordered with increasing global number
1478         int ii0 = mynvface[j][0];
1479         int ii1 = mynvface[j][1];
1480         int ii2 = mynvface[j][2];
1481         int i0 = perm[ii0];
1482         int i1 = perm[ii1];
1483         int i2 = perm[ii2];
1484         // (edge i0i1, which requires i2, and in front put a lambda of the face ordered vertices)
1485         om[18 + j * 6] = l[i0] * l[i2] * (l[i0] * D[i1] - l[i1] * D[i0]);
1486         om[18 + j * 6 + 1] = l[i1] * l[i2] * (l[i0] * D[i1] - l[i1] * D[i0]);
1487         om[18 + j * 6 + 2] = l[i2] * l[i2] * (l[i0] * D[i1] - l[i1] * D[i0]);
1488         // (edge i0i2, which requires i1, and in front put a lambda of the face ordered vertices)
1489         om[18 + j * 6 + 3] = l[i0] * l[i1] * (l[i0] * D[i2] - l[i2] * D[i0]);
1490         om[18 + j * 6 + 4] = l[i1] * l[i1] * (l[i0] * D[i2] - l[i2] * D[i0]);
1491         om[18 + j * 6 + 5] = l[i2] * l[i1] * (l[i0] * D[i2] - l[i2] * D[i0]);
1492       }
1493 
1494       // 3 volume functions
1495       // (Although the volume dofs are not shared between adjacent tetrahedra,
1496       // I have to use perm to be allowed to use the calculated coefficients giving a dual basis)
1497       om[42] = l[perm[2]] * l[perm[3]] * (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]);
1498       om[43] = l[perm[1]] * l[perm[3]] * (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]);
1499       om[44] = l[perm[1]] * l[perm[2]] * (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]);
1500 
1501       // Now, the functions phi that really constitute a dual basis
1502       R3 phi[45];
1503       phi[p45[0]] = +9 * om[0] - 18 * om[1] + 3 * om[2] - 27 * om[30] + 12 * om[31] + 9 * om[32] +
1504                     9 * om[33] - 6 * om[34] - 6 * om[35] - 27 * om[36] + 12 * om[37] + 9 * om[38] +
1505                     9 * om[39] - 6 * om[40] - 6 * om[41] + 18 * om[42] - 6 * om[43] - 6 * om[44];
1506       phi[p45[1]] = -18 * om[0] + 84 * om[1] - 18 * om[2] - 6 * om[30] - 36 * om[31] + 12 * om[32] -
1507                     30 * om[33] + 30 * om[34] - 6 * om[36] - 36 * om[37] + 12 * om[38] -
1508                     30 * om[39] + 30 * om[40] + 24 * om[42];
1509       phi[p45[2]] = +3 * om[0] - 18 * om[1] + 9 * om[2] + 6 * om[30] - 18 * om[31] + 3 * om[32] +
1510                     6 * om[33] - 9 * om[34] + 6 * om[35] + 6 * om[36] - 18 * om[37] + 3 * om[38] +
1511                     6 * om[39] - 9 * om[40] + 6 * om[41] + 6 * om[42] + 6 * om[43] + 6 * om[44];
1512       phi[p45[3]] = +9 * om[3] - 18 * om[4] + 3 * om[5] - 27 * om[24] + 12 * om[25] + 9 * om[26] +
1513                     9 * om[27] - 6 * om[28] - 6 * om[29] + 9 * om[36] - 6 * om[37] - 6 * om[38] -
1514                     27 * om[39] + 9 * om[40] + 12 * om[41] - 6 * om[42] + 18 * om[43] - 6 * om[44];
1515       phi[p45[4]] = -18 * om[3] + 84 * om[4] - 18 * om[5] - 6 * om[24] - 36 * om[25] + 12 * om[26] -
1516                     30 * om[27] + 30 * om[28] - 30 * om[36] + 30 * om[38] - 6 * om[39] +
1517                     12 * om[40] - 36 * om[41] + 24 * om[43];
1518       phi[p45[5]] = +3 * om[3] - 18 * om[4] + 9 * om[5] + 6 * om[24] - 18 * om[25] + 3 * om[26] +
1519                     6 * om[27] - 9 * om[28] + 6 * om[29] + 6 * om[36] + 6 * om[37] - 9 * om[38] +
1520                     6 * om[39] + 3 * om[40] - 18 * om[41] + 6 * om[42] + 6 * om[43] + 6 * om[44];
1521       phi[p45[6]] = +9 * om[6] - 18 * om[7] + 3 * om[8] + 9 * om[24] - 6 * om[25] - 6 * om[26] -
1522                     27 * om[27] + 9 * om[28] + 12 * om[29] + 9 * om[30] - 6 * om[31] - 6 * om[32] -
1523                     27 * om[33] + 9 * om[34] + 12 * om[35] - 6 * om[42] - 6 * om[43] + 18 * om[44];
1524       phi[p45[7]] = -18 * om[6] + 84 * om[7] - 18 * om[8] - 30 * om[24] + 30 * om[26] - 6 * om[27] +
1525                     12 * om[28] - 36 * om[29] - 30 * om[30] + 30 * om[32] - 6 * om[33] +
1526                     12 * om[34] - 36 * om[35] + 24 * om[44];
1527       phi[p45[8]] = +3 * om[6] - 18 * om[7] + 9 * om[8] + 6 * om[24] + 6 * om[25] - 9 * om[26] +
1528                     6 * om[27] + 3 * om[28] - 18 * om[29] + 6 * om[30] + 6 * om[31] - 9 * om[32] +
1529                     6 * om[33] + 3 * om[34] - 18 * om[35] + 6 * om[42] + 6 * om[43] + 6 * om[44];
1530       phi[p45[9]] = +9 * om[9] - 18 * om[10] + 3 * om[11] - 27 * om[18] + 12 * om[19] + 9 * om[20] +
1531                     9 * om[21] - 6 * om[22] - 6 * om[23] - 3 * om[36] + 18 * om[37] - 6 * om[38] +
1532                     9 * om[39] - 27 * om[40] + 12 * om[41] - 6 * om[42] + 18 * om[43] - 6 * om[44];
1533       phi[p45[10]] = -18 * om[9] + 84 * om[10] - 18 * om[11] - 6 * om[18] - 36 * om[19] +
1534                      12 * om[20] - 30 * om[21] + 30 * om[22] - 12 * om[36] + 36 * om[37] +
1535                      6 * om[38] + 12 * om[39] - 6 * om[40] - 36 * om[41] - 24 * om[42] +
1536                      24 * om[43];
1537       phi[p45[11]] = +3 * om[9] - 18 * om[10] + 9 * om[11] + 6 * om[18] - 18 * om[19] + 3 * om[20] +
1538                      6 * om[21] - 9 * om[22] + 6 * om[23] - 9 * om[36] - 12 * om[37] + 27 * om[38] +
1539                      3 * om[39] + 6 * om[40] - 18 * om[41] - 18 * om[42] + 6 * om[43] + 6 * om[44];
1540       phi[p45[12]] = +9 * om[12] - 18 * om[13] + 3 * om[14] + 9 * om[18] - 6 * om[19] - 6 * om[20] -
1541                      27 * om[21] + 9 * om[22] + 12 * om[23] - 3 * om[30] + 18 * om[31] -
1542                      6 * om[32] + 9 * om[33] - 27 * om[34] + 12 * om[35] - 6 * om[42] - 6 * om[43] +
1543                      18 * om[44];
1544       phi[p45[13]] = -18 * om[12] + 84 * om[13] - 18 * om[14] - 30 * om[18] + 30 * om[20] -
1545                      6 * om[21] + 12 * om[22] - 36 * om[23] - 12 * om[30] + 36 * om[31] +
1546                      6 * om[32] + 12 * om[33] - 6 * om[34] - 36 * om[35] - 24 * om[42] +
1547                      24 * om[44];
1548       phi[p45[14]] = +3 * om[12] - 18 * om[13] + 9 * om[14] + 6 * om[18] + 6 * om[19] - 9 * om[20] +
1549                      6 * om[21] + 3 * om[22] - 18 * om[23] - 9 * om[30] - 12 * om[31] +
1550                      27 * om[32] + 3 * om[33] + 6 * om[34] - 18 * om[35] - 18 * om[42] +
1551                      6 * om[43] + 6 * om[44];
1552       phi[p45[15]] = +9 * om[15] - 18 * om[16] + 3 * om[17] - 3 * om[18] + 18 * om[19] -
1553                      6 * om[20] + 9 * om[21] - 27 * om[22] + 12 * om[23] - 3 * om[24] +
1554                      18 * om[25] - 6 * om[26] + 9 * om[27] - 27 * om[28] + 12 * om[29] -
1555                      6 * om[42] - 6 * om[43] + 18 * om[44];
1556       phi[p45[16]] = -18 * om[15] + 84 * om[16] - 18 * om[17] - 12 * om[18] + 36 * om[19] +
1557                      6 * om[20] + 12 * om[21] - 6 * om[22] - 36 * om[23] - 12 * om[24] +
1558                      36 * om[25] + 6 * om[26] + 12 * om[27] - 6 * om[28] - 36 * om[29] -
1559                      24 * om[43] + 24 * om[44];
1560       phi[p45[17]] = +3 * om[15] - 18 * om[16] + 9 * om[17] - 9 * om[18] - 12 * om[19] +
1561                      27 * om[20] + 3 * om[21] + 6 * om[22] - 18 * om[23] - 9 * om[24] -
1562                      12 * om[25] + 27 * om[26] + 3 * om[27] + 6 * om[28] - 18 * om[29] +
1563                      6 * om[42] - 18 * om[43] + 6 * om[44];
1564       phi[p45[18]] = +90 * om[18] - 30 * om[19] - 45 * om[20] - 30 * om[21] + 15 * om[22] +
1565                      30 * om[23] + 15 * om[42] - 45 * om[43] + 15 * om[44];
1566       phi[p45[19]] = -30 * om[18] + 120 * om[19] - 30 * om[20] + 30 * om[21] - 60 * om[22] +
1567                      30 * om[42] - 30 * om[43] + 30 * om[44];
1568       phi[p45[20]] = -45 * om[18] - 30 * om[19] + 90 * om[20] + 15 * om[21] + 15 * om[22] -
1569                      60 * om[23] + 15 * om[42] - 45 * om[43] + 15 * om[44];
1570       phi[p45[21]] = -30 * om[18] + 30 * om[19] + 15 * om[20] + 90 * om[21] - 45 * om[22] -
1571                      30 * om[23] + 15 * om[42] + 15 * om[43] - 45 * om[44];
1572       phi[p45[22]] = +15 * om[18] - 60 * om[19] + 15 * om[20] - 45 * om[21] + 90 * om[22] -
1573                      30 * om[23] + 15 * om[42] + 15 * om[43] - 45 * om[44];
1574       phi[p45[23]] = +30 * om[18] - 60 * om[20] - 30 * om[21] - 30 * om[22] + 120 * om[23] +
1575                      30 * om[42] + 30 * om[43] - 30 * om[44];
1576       phi[p45[24]] = +90 * om[24] - 30 * om[25] - 45 * om[26] - 30 * om[27] + 15 * om[28] +
1577                      30 * om[29] + 15 * om[42] - 45 * om[43] + 15 * om[44];
1578       phi[p45[25]] = -30 * om[24] + 120 * om[25] - 30 * om[26] + 30 * om[27] - 60 * om[28] -
1579                      30 * om[42] - 30 * om[43] + 30 * om[44];
1580       phi[p45[26]] = -45 * om[24] - 30 * om[25] + 90 * om[26] + 15 * om[27] + 15 * om[28] -
1581                      60 * om[29] + 15 * om[42] - 45 * om[43] + 15 * om[44];
1582       phi[p45[27]] = -30 * om[24] + 30 * om[25] + 15 * om[26] + 90 * om[27] - 45 * om[28] -
1583                      30 * om[29] + 15 * om[42] + 15 * om[43] - 45 * om[44];
1584       phi[p45[28]] = +15 * om[24] - 60 * om[25] + 15 * om[26] - 45 * om[27] + 90 * om[28] -
1585                      30 * om[29] + 15 * om[42] + 15 * om[43] - 45 * om[44];
1586       phi[p45[29]] = +30 * om[24] - 60 * om[26] - 30 * om[27] - 30 * om[28] + 120 * om[29] -
1587                      30 * om[42] + 30 * om[43] - 30 * om[44];
1588       phi[p45[30]] = +90 * om[30] - 30 * om[31] - 45 * om[32] - 30 * om[33] + 15 * om[34] +
1589                      30 * om[35] - 45 * om[42] + 15 * om[43] + 15 * om[44];
1590       phi[p45[31]] = -30 * om[30] + 120 * om[31] - 30 * om[32] + 30 * om[33] - 60 * om[34] -
1591                      30 * om[42] - 30 * om[43] + 30 * om[44];
1592       phi[p45[32]] = -45 * om[30] - 30 * om[31] + 90 * om[32] + 15 * om[33] + 15 * om[34] -
1593                      60 * om[35] - 45 * om[42] + 15 * om[43] + 15 * om[44];
1594       phi[p45[33]] = -30 * om[30] + 30 * om[31] + 15 * om[32] + 90 * om[33] - 45 * om[34] -
1595                      30 * om[35] + 15 * om[42] + 15 * om[43] - 45 * om[44];
1596       phi[p45[34]] = +15 * om[30] - 60 * om[31] + 15 * om[32] - 45 * om[33] + 90 * om[34] -
1597                      30 * om[35] + 15 * om[42] + 15 * om[43] - 45 * om[44];
1598       phi[p45[35]] = +30 * om[30] - 60 * om[32] - 30 * om[33] - 30 * om[34] + 120 * om[35] +
1599                      30 * om[42] - 30 * om[43] - 30 * om[44];
1600       phi[p45[36]] = +90 * om[36] - 30 * om[37] - 45 * om[38] - 30 * om[39] + 15 * om[40] +
1601                      30 * om[41] - 45 * om[42] + 15 * om[43] + 15 * om[44];
1602       phi[p45[37]] = -30 * om[36] + 120 * om[37] - 30 * om[38] + 30 * om[39] - 60 * om[40] -
1603                      30 * om[42] + 30 * om[43] - 30 * om[44];
1604       phi[p45[38]] = -45 * om[36] - 30 * om[37] + 90 * om[38] + 15 * om[39] + 15 * om[40] -
1605                      60 * om[41] - 45 * om[42] + 15 * om[43] + 15 * om[44];
1606       phi[p45[39]] = -30 * om[36] + 30 * om[37] + 15 * om[38] + 90 * om[39] - 45 * om[40] -
1607                      30 * om[41] + 15 * om[42] - 45 * om[43] + 15 * om[44];
1608       phi[p45[40]] = +15 * om[36] - 60 * om[37] + 15 * om[38] - 45 * om[39] + 90 * om[40] -
1609                      30 * om[41] + 15 * om[42] - 45 * om[43] + 15 * om[44];
1610       phi[p45[41]] = +30 * om[36] - 60 * om[38] - 30 * om[39] - 30 * om[40] + 120 * om[41] +
1611                      30 * om[42] - 30 * om[43] - 30 * om[44];
1612       phi[p45[42]] = +90 * om[42] - 30 * om[43] - 30 * om[44];
1613       phi[p45[43]] = -30 * om[42] + 90 * om[43] - 30 * om[44];
1614       phi[p45[44]] = -30 * om[42] - 30 * om[43] + 90 * om[44];
1615 
1616       for (int k = 0; k < 45; ++k) {
1617         val(k, 0, op_id) = phi[k].x;
1618         val(k, 1, op_id) = phi[k].y;
1619         val(k, 2, op_id) = phi[k].z;
1620       }
1621     }
1622 
1623     if (whatd & Fop_D1) {    // FIRST DERIVATIVES wrt x,y,z
1624       R3 omdx[45];
1625       R3 omdy[45];
1626       R3 omdz[45];
1627 
1628       // 18 edge functions (3 for each edge):
1629       for (int i = 0; i < Element::ne; ++i) {
1630         int ii0 = Element::nvedge[i][0], ii1 = Element::nvedge[i][1];
1631         int i0 = perm[ii0];
1632         int i1 = perm[ii1];
1633         if (whatd & Fop_dx) {
1634           omdx[i * 3] = 2 * D[i0].x * l[i0] * (l[i0] * D[i1] - l[i1] * D[i0]) +
1635                         l[i0] * l[i0] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
1636           omdx[i * 3 + 1] = (D[i0].x * l[i1] + l[i0] * D[i1].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1637                             l[i0] * l[i1] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
1638           omdx[i * 3 + 2] = 2 * D[i1].x * l[i1] * (l[i0] * D[i1] - l[i1] * D[i0]) +
1639                             l[i1] * l[i1] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
1640         }
1641 
1642         if (whatd & Fop_dy) {
1643           omdy[i * 3] = 2 * D[i0].y * l[i0] * (l[i0] * D[i1] - l[i1] * D[i0]) +
1644                         l[i0] * l[i0] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
1645           omdy[i * 3 + 1] = (D[i0].y * l[i1] + l[i0] * D[i1].y) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1646                             l[i0] * l[i1] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
1647           omdy[i * 3 + 2] = 2 * D[i1].y * l[i1] * (l[i0] * D[i1] - l[i1] * D[i0]) +
1648                             l[i1] * l[i1] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
1649         }
1650 
1651         if (whatd & Fop_dz) {
1652           omdz[i * 3] = 2 * D[i0].z * l[i0] * (l[i0] * D[i1] - l[i1] * D[i0]) +
1653                         l[i0] * l[i0] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
1654           omdz[i * 3 + 1] = (D[i0].z * l[i1] + l[i0] * D[i1].z) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1655                             l[i0] * l[i1] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
1656           omdz[i * 3 + 2] = 2 * D[i1].z * l[i1] * (l[i0] * D[i1] - l[i1] * D[i0]) +
1657                             l[i1] * l[i1] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
1658         }
1659       }
1660 
1661       // 24 face functions (6 for each face):
1662       for (int j = 0; j < Element::nf; ++j) {
1663         int ii0 = mynvface[j][0];
1664         int ii1 = mynvface[j][1];
1665         int ii2 = mynvface[j][2];
1666         int i0 = perm[ii0];
1667         int i1 = perm[ii1];
1668         int i2 = perm[ii2];
1669         if (whatd & Fop_dx) {
1670           omdx[18 + j * 6] = (D[i0].x * l[i2] + l[i0] * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1671                              l[i0] * l[i2] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
1672           omdx[18 + j * 6 + 1] =
1673             (D[i1].x * l[i2] + l[i1] * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1674             l[i1] * l[i2] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
1675           omdx[18 + j * 6 + 2] =
1676             (D[i2].x * l[i2] + l[i2] * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1677             l[i2] * l[i2] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
1678           omdx[18 + j * 6 + 3] =
1679             (D[i0].x * l[i1] + l[i0] * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1680             l[i0] * l[i1] * (D[i0].x * D[i2] - D[i2].x * D[i0]);
1681           omdx[18 + j * 6 + 4] =
1682             (D[i1].x * l[i1] + l[i1] * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1683             l[i1] * l[i1] * (D[i0].x * D[i2] - D[i2].x * D[i0]);
1684           omdx[18 + j * 6 + 5] =
1685             (D[i2].x * l[i1] + l[i2] * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1686             l[i2] * l[i1] * (D[i0].x * D[i2] - D[i2].x * D[i0]);
1687         }
1688 
1689         if (whatd & Fop_dy) {
1690           omdy[18 + j * 6] = (D[i0].y * l[i2] + l[i0] * D[i2].y) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1691                              l[i0] * l[i2] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
1692           omdy[18 + j * 6 + 1] =
1693             (D[i1].y * l[i2] + l[i1] * D[i2].y) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1694             l[i1] * l[i2] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
1695           omdy[18 + j * 6 + 2] =
1696             (D[i2].y * l[i2] + l[i2] * D[i2].y) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1697             l[i2] * l[i2] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
1698           omdy[18 + j * 6 + 3] =
1699             (D[i0].y * l[i1] + l[i0] * D[i1].y) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1700             l[i0] * l[i1] * (D[i0].y * D[i2] - D[i2].y * D[i0]);
1701           omdy[18 + j * 6 + 4] =
1702             (D[i1].y * l[i1] + l[i1] * D[i1].y) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1703             l[i1] * l[i1] * (D[i0].y * D[i2] - D[i2].y * D[i0]);
1704           omdy[18 + j * 6 + 5] =
1705             (D[i2].y * l[i1] + l[i2] * D[i1].y) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1706             l[i2] * l[i1] * (D[i0].y * D[i2] - D[i2].y * D[i0]);
1707         }
1708 
1709         if (whatd & Fop_dz) {
1710           omdz[18 + j * 6] = (D[i0].z * l[i2] + l[i0] * D[i2].z) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1711                              l[i0] * l[i2] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
1712           omdz[18 + j * 6 + 1] =
1713             (D[i1].z * l[i2] + l[i1] * D[i2].z) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1714             l[i1] * l[i2] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
1715           omdz[18 + j * 6 + 2] =
1716             (D[i2].z * l[i2] + l[i2] * D[i2].z) * (l[i0] * D[i1] - l[i1] * D[i0]) +
1717             l[i2] * l[i2] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
1718           omdz[18 + j * 6 + 3] =
1719             (D[i0].z * l[i1] + l[i0] * D[i1].z) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1720             l[i0] * l[i1] * (D[i0].z * D[i2] - D[i2].z * D[i0]);
1721           omdz[18 + j * 6 + 4] =
1722             (D[i1].z * l[i1] + l[i1] * D[i1].z) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1723             l[i1] * l[i1] * (D[i0].z * D[i2] - D[i2].z * D[i0]);
1724           omdz[18 + j * 6 + 5] =
1725             (D[i2].z * l[i1] + l[i2] * D[i1].z) * (l[i0] * D[i2] - l[i2] * D[i0]) +
1726             l[i2] * l[i1] * (D[i0].z * D[i2] - D[i2].z * D[i0]);
1727         }
1728       }
1729 
1730       // 3 volume functions
1731       if (whatd & Fop_dx) {
1732         omdx[42] =
1733           (D[perm[2]].x * l[perm[3]] + l[perm[2]] * D[perm[3]].x) *
1734             (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
1735           l[perm[2]] * l[perm[3]] * (D[perm[0]].x * D[perm[1]] - D[perm[1]].x * D[perm[0]]);
1736         omdx[43] =
1737           (D[perm[1]].x * l[perm[3]] + l[perm[1]] * D[perm[3]].x) *
1738             (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
1739           l[perm[1]] * l[perm[3]] * (D[perm[0]].x * D[perm[2]] - D[perm[2]].x * D[perm[0]]);
1740         omdx[44] =
1741           (D[perm[1]].x * l[perm[2]] + l[perm[1]] * D[perm[2]].x) *
1742             (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
1743           l[perm[1]] * l[perm[2]] * (D[perm[0]].x * D[perm[3]] - D[perm[3]].x * D[perm[0]]);
1744       }
1745 
1746       if (whatd & Fop_dy) {
1747         omdy[42] =
1748           (D[perm[2]].y * l[perm[3]] + l[perm[2]] * D[perm[3]].y) *
1749             (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
1750           l[perm[2]] * l[perm[3]] * (D[perm[0]].y * D[perm[1]] - D[perm[1]].y * D[perm[0]]);
1751         omdy[43] =
1752           (D[perm[1]].y * l[perm[3]] + l[perm[1]] * D[perm[3]].y) *
1753             (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
1754           l[perm[1]] * l[perm[3]] * (D[perm[0]].y * D[perm[2]] - D[perm[2]].y * D[perm[0]]);
1755         omdy[44] =
1756           (D[perm[1]].y * l[perm[2]] + l[perm[1]] * D[perm[2]].y) *
1757             (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
1758           l[perm[1]] * l[perm[2]] * (D[perm[0]].y * D[perm[3]] - D[perm[3]].y * D[perm[0]]);
1759       }
1760 
1761       if (whatd & Fop_dz) {
1762         omdz[42] =
1763           (D[perm[2]].z * l[perm[3]] + l[perm[2]] * D[perm[3]].z) *
1764             (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
1765           l[perm[2]] * l[perm[3]] * (D[perm[0]].z * D[perm[1]] - D[perm[1]].z * D[perm[0]]);
1766         omdz[43] =
1767           (D[perm[1]].z * l[perm[3]] + l[perm[1]] * D[perm[3]].z) *
1768             (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
1769           l[perm[1]] * l[perm[3]] * (D[perm[0]].z * D[perm[2]] - D[perm[2]].z * D[perm[0]]);
1770         omdz[44] =
1771           (D[perm[1]].z * l[perm[2]] + l[perm[1]] * D[perm[2]].z) *
1772             (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
1773           l[perm[1]] * l[perm[2]] * (D[perm[0]].z * D[perm[3]] - D[perm[3]].z * D[perm[0]]);
1774       }
1775 
1776       R3 phidx[45];
1777       if (whatd & Fop_dx) {
1778         phidx[p45[0]] = +9 * omdx[0] - 18 * omdx[1] + 3 * omdx[2] - 27 * omdx[30] + 12 * omdx[31] +
1779                         9 * omdx[32] + 9 * omdx[33] - 6 * omdx[34] - 6 * omdx[35] - 27 * omdx[36] +
1780                         12 * omdx[37] + 9 * omdx[38] + 9 * omdx[39] - 6 * omdx[40] - 6 * omdx[41] +
1781                         18 * omdx[42] - 6 * omdx[43] - 6 * omdx[44];
1782         phidx[p45[1]] = -18 * omdx[0] + 84 * omdx[1] - 18 * omdx[2] - 6 * omdx[30] - 36 * omdx[31] +
1783                         12 * omdx[32] - 30 * omdx[33] + 30 * omdx[34] - 6 * omdx[36] -
1784                         36 * omdx[37] + 12 * omdx[38] - 30 * omdx[39] + 30 * omdx[40] +
1785                         24 * omdx[42];
1786         phidx[p45[2]] = +3 * omdx[0] - 18 * omdx[1] + 9 * omdx[2] + 6 * omdx[30] - 18 * omdx[31] +
1787                         3 * omdx[32] + 6 * omdx[33] - 9 * omdx[34] + 6 * omdx[35] + 6 * omdx[36] -
1788                         18 * omdx[37] + 3 * omdx[38] + 6 * omdx[39] - 9 * omdx[40] + 6 * omdx[41] +
1789                         6 * omdx[42] + 6 * omdx[43] + 6 * omdx[44];
1790         phidx[p45[3]] = +9 * omdx[3] - 18 * omdx[4] + 3 * omdx[5] - 27 * omdx[24] + 12 * omdx[25] +
1791                         9 * omdx[26] + 9 * omdx[27] - 6 * omdx[28] - 6 * omdx[29] + 9 * omdx[36] -
1792                         6 * omdx[37] - 6 * omdx[38] - 27 * omdx[39] + 9 * omdx[40] + 12 * omdx[41] -
1793                         6 * omdx[42] + 18 * omdx[43] - 6 * omdx[44];
1794         phidx[p45[4]] = -18 * omdx[3] + 84 * omdx[4] - 18 * omdx[5] - 6 * omdx[24] - 36 * omdx[25] +
1795                         12 * omdx[26] - 30 * omdx[27] + 30 * omdx[28] - 30 * omdx[36] +
1796                         30 * omdx[38] - 6 * omdx[39] + 12 * omdx[40] - 36 * omdx[41] +
1797                         24 * omdx[43];
1798         phidx[p45[5]] = +3 * omdx[3] - 18 * omdx[4] + 9 * omdx[5] + 6 * omdx[24] - 18 * omdx[25] +
1799                         3 * omdx[26] + 6 * omdx[27] - 9 * omdx[28] + 6 * omdx[29] + 6 * omdx[36] +
1800                         6 * omdx[37] - 9 * omdx[38] + 6 * omdx[39] + 3 * omdx[40] - 18 * omdx[41] +
1801                         6 * omdx[42] + 6 * omdx[43] + 6 * omdx[44];
1802         phidx[p45[6]] = +9 * omdx[6] - 18 * omdx[7] + 3 * omdx[8] + 9 * omdx[24] - 6 * omdx[25] -
1803                         6 * omdx[26] - 27 * omdx[27] + 9 * omdx[28] + 12 * omdx[29] + 9 * omdx[30] -
1804                         6 * omdx[31] - 6 * omdx[32] - 27 * omdx[33] + 9 * omdx[34] + 12 * omdx[35] -
1805                         6 * omdx[42] - 6 * omdx[43] + 18 * omdx[44];
1806         phidx[p45[7]] = -18 * omdx[6] + 84 * omdx[7] - 18 * omdx[8] - 30 * omdx[24] +
1807                         30 * omdx[26] - 6 * omdx[27] + 12 * omdx[28] - 36 * omdx[29] -
1808                         30 * omdx[30] + 30 * omdx[32] - 6 * omdx[33] + 12 * omdx[34] -
1809                         36 * omdx[35] + 24 * omdx[44];
1810         phidx[p45[8]] = +3 * omdx[6] - 18 * omdx[7] + 9 * omdx[8] + 6 * omdx[24] + 6 * omdx[25] -
1811                         9 * omdx[26] + 6 * omdx[27] + 3 * omdx[28] - 18 * omdx[29] + 6 * omdx[30] +
1812                         6 * omdx[31] - 9 * omdx[32] + 6 * omdx[33] + 3 * omdx[34] - 18 * omdx[35] +
1813                         6 * omdx[42] + 6 * omdx[43] + 6 * omdx[44];
1814         phidx[p45[9]] = +9 * omdx[9] - 18 * omdx[10] + 3 * omdx[11] - 27 * omdx[18] +
1815                         12 * omdx[19] + 9 * omdx[20] + 9 * omdx[21] - 6 * omdx[22] - 6 * omdx[23] -
1816                         3 * omdx[36] + 18 * omdx[37] - 6 * omdx[38] + 9 * omdx[39] - 27 * omdx[40] +
1817                         12 * omdx[41] - 6 * omdx[42] + 18 * omdx[43] - 6 * omdx[44];
1818         phidx[p45[10]] = -18 * omdx[9] + 84 * omdx[10] - 18 * omdx[11] - 6 * omdx[18] -
1819                          36 * omdx[19] + 12 * omdx[20] - 30 * omdx[21] + 30 * omdx[22] -
1820                          12 * omdx[36] + 36 * omdx[37] + 6 * omdx[38] + 12 * omdx[39] -
1821                          6 * omdx[40] - 36 * omdx[41] - 24 * omdx[42] + 24 * omdx[43];
1822         phidx[p45[11]] = +3 * omdx[9] - 18 * omdx[10] + 9 * omdx[11] + 6 * omdx[18] -
1823                          18 * omdx[19] + 3 * omdx[20] + 6 * omdx[21] - 9 * omdx[22] + 6 * omdx[23] -
1824                          9 * omdx[36] - 12 * omdx[37] + 27 * omdx[38] + 3 * omdx[39] +
1825                          6 * omdx[40] - 18 * omdx[41] - 18 * omdx[42] + 6 * omdx[43] + 6 * omdx[44];
1826         phidx[p45[12]] = +9 * omdx[12] - 18 * omdx[13] + 3 * omdx[14] + 9 * omdx[18] -
1827                          6 * omdx[19] - 6 * omdx[20] - 27 * omdx[21] + 9 * omdx[22] +
1828                          12 * omdx[23] - 3 * omdx[30] + 18 * omdx[31] - 6 * omdx[32] +
1829                          9 * omdx[33] - 27 * omdx[34] + 12 * omdx[35] - 6 * omdx[42] -
1830                          6 * omdx[43] + 18 * omdx[44];
1831         phidx[p45[13]] = -18 * omdx[12] + 84 * omdx[13] - 18 * omdx[14] - 30 * omdx[18] +
1832                          30 * omdx[20] - 6 * omdx[21] + 12 * omdx[22] - 36 * omdx[23] -
1833                          12 * omdx[30] + 36 * omdx[31] + 6 * omdx[32] + 12 * omdx[33] -
1834                          6 * omdx[34] - 36 * omdx[35] - 24 * omdx[42] + 24 * omdx[44];
1835         phidx[p45[14]] = +3 * omdx[12] - 18 * omdx[13] + 9 * omdx[14] + 6 * omdx[18] +
1836                          6 * omdx[19] - 9 * omdx[20] + 6 * omdx[21] + 3 * omdx[22] - 18 * omdx[23] -
1837                          9 * omdx[30] - 12 * omdx[31] + 27 * omdx[32] + 3 * omdx[33] +
1838                          6 * omdx[34] - 18 * omdx[35] - 18 * omdx[42] + 6 * omdx[43] + 6 * omdx[44];
1839         phidx[p45[15]] = +9 * omdx[15] - 18 * omdx[16] + 3 * omdx[17] - 3 * omdx[18] +
1840                          18 * omdx[19] - 6 * omdx[20] + 9 * omdx[21] - 27 * omdx[22] +
1841                          12 * omdx[23] - 3 * omdx[24] + 18 * omdx[25] - 6 * omdx[26] +
1842                          9 * omdx[27] - 27 * omdx[28] + 12 * omdx[29] - 6 * omdx[42] -
1843                          6 * omdx[43] + 18 * omdx[44];
1844         phidx[p45[16]] = -18 * omdx[15] + 84 * omdx[16] - 18 * omdx[17] - 12 * omdx[18] +
1845                          36 * omdx[19] + 6 * omdx[20] + 12 * omdx[21] - 6 * omdx[22] -
1846                          36 * omdx[23] - 12 * omdx[24] + 36 * omdx[25] + 6 * omdx[26] +
1847                          12 * omdx[27] - 6 * omdx[28] - 36 * omdx[29] - 24 * omdx[43] +
1848                          24 * omdx[44];
1849         phidx[p45[17]] = +3 * omdx[15] - 18 * omdx[16] + 9 * omdx[17] - 9 * omdx[18] -
1850                          12 * omdx[19] + 27 * omdx[20] + 3 * omdx[21] + 6 * omdx[22] -
1851                          18 * omdx[23] - 9 * omdx[24] - 12 * omdx[25] + 27 * omdx[26] +
1852                          3 * omdx[27] + 6 * omdx[28] - 18 * omdx[29] + 6 * omdx[42] -
1853                          18 * omdx[43] + 6 * omdx[44];
1854         phidx[p45[18]] = +90 * omdx[18] - 30 * omdx[19] - 45 * omdx[20] - 30 * omdx[21] +
1855                          15 * omdx[22] + 30 * omdx[23] + 15 * omdx[42] - 45 * omdx[43] +
1856                          15 * omdx[44];
1857         phidx[p45[19]] = -30 * omdx[18] + 120 * omdx[19] - 30 * omdx[20] + 30 * omdx[21] -
1858                          60 * omdx[22] + 30 * omdx[42] - 30 * omdx[43] + 30 * omdx[44];
1859         phidx[p45[20]] = -45 * omdx[18] - 30 * omdx[19] + 90 * omdx[20] + 15 * omdx[21] +
1860                          15 * omdx[22] - 60 * omdx[23] + 15 * omdx[42] - 45 * omdx[43] +
1861                          15 * omdx[44];
1862         phidx[p45[21]] = -30 * omdx[18] + 30 * omdx[19] + 15 * omdx[20] + 90 * omdx[21] -
1863                          45 * omdx[22] - 30 * omdx[23] + 15 * omdx[42] + 15 * omdx[43] -
1864                          45 * omdx[44];
1865         phidx[p45[22]] = +15 * omdx[18] - 60 * omdx[19] + 15 * omdx[20] - 45 * omdx[21] +
1866                          90 * omdx[22] - 30 * omdx[23] + 15 * omdx[42] + 15 * omdx[43] -
1867                          45 * omdx[44];
1868         phidx[p45[23]] = +30 * omdx[18] - 60 * omdx[20] - 30 * omdx[21] - 30 * omdx[22] +
1869                          120 * omdx[23] + 30 * omdx[42] + 30 * omdx[43] - 30 * omdx[44];
1870         phidx[p45[24]] = +90 * omdx[24] - 30 * omdx[25] - 45 * omdx[26] - 30 * omdx[27] +
1871                          15 * omdx[28] + 30 * omdx[29] + 15 * omdx[42] - 45 * omdx[43] +
1872                          15 * omdx[44];
1873         phidx[p45[25]] = -30 * omdx[24] + 120 * omdx[25] - 30 * omdx[26] + 30 * omdx[27] -
1874                          60 * omdx[28] - 30 * omdx[42] - 30 * omdx[43] + 30 * omdx[44];
1875         phidx[p45[26]] = -45 * omdx[24] - 30 * omdx[25] + 90 * omdx[26] + 15 * omdx[27] +
1876                          15 * omdx[28] - 60 * omdx[29] + 15 * omdx[42] - 45 * omdx[43] +
1877                          15 * omdx[44];
1878         phidx[p45[27]] = -30 * omdx[24] + 30 * omdx[25] + 15 * omdx[26] + 90 * omdx[27] -
1879                          45 * omdx[28] - 30 * omdx[29] + 15 * omdx[42] + 15 * omdx[43] -
1880                          45 * omdx[44];
1881         phidx[p45[28]] = +15 * omdx[24] - 60 * omdx[25] + 15 * omdx[26] - 45 * omdx[27] +
1882                          90 * omdx[28] - 30 * omdx[29] + 15 * omdx[42] + 15 * omdx[43] -
1883                          45 * omdx[44];
1884         phidx[p45[29]] = +30 * omdx[24] - 60 * omdx[26] - 30 * omdx[27] - 30 * omdx[28] +
1885                          120 * omdx[29] - 30 * omdx[42] + 30 * omdx[43] - 30 * omdx[44];
1886         phidx[p45[30]] = +90 * omdx[30] - 30 * omdx[31] - 45 * omdx[32] - 30 * omdx[33] +
1887                          15 * omdx[34] + 30 * omdx[35] - 45 * omdx[42] + 15 * omdx[43] +
1888                          15 * omdx[44];
1889         phidx[p45[31]] = -30 * omdx[30] + 120 * omdx[31] - 30 * omdx[32] + 30 * omdx[33] -
1890                          60 * omdx[34] - 30 * omdx[42] - 30 * omdx[43] + 30 * omdx[44];
1891         phidx[p45[32]] = -45 * omdx[30] - 30 * omdx[31] + 90 * omdx[32] + 15 * omdx[33] +
1892                          15 * omdx[34] - 60 * omdx[35] - 45 * omdx[42] + 15 * omdx[43] +
1893                          15 * omdx[44];
1894         phidx[p45[33]] = -30 * omdx[30] + 30 * omdx[31] + 15 * omdx[32] + 90 * omdx[33] -
1895                          45 * omdx[34] - 30 * omdx[35] + 15 * omdx[42] + 15 * omdx[43] -
1896                          45 * omdx[44];
1897         phidx[p45[34]] = +15 * omdx[30] - 60 * omdx[31] + 15 * omdx[32] - 45 * omdx[33] +
1898                          90 * omdx[34] - 30 * omdx[35] + 15 * omdx[42] + 15 * omdx[43] -
1899                          45 * omdx[44];
1900         phidx[p45[35]] = +30 * omdx[30] - 60 * omdx[32] - 30 * omdx[33] - 30 * omdx[34] +
1901                          120 * omdx[35] + 30 * omdx[42] - 30 * omdx[43] - 30 * omdx[44];
1902         phidx[p45[36]] = +90 * omdx[36] - 30 * omdx[37] - 45 * omdx[38] - 30 * omdx[39] +
1903                          15 * omdx[40] + 30 * omdx[41] - 45 * omdx[42] + 15 * omdx[43] +
1904                          15 * omdx[44];
1905         phidx[p45[37]] = -30 * omdx[36] + 120 * omdx[37] - 30 * omdx[38] + 30 * omdx[39] -
1906                          60 * omdx[40] - 30 * omdx[42] + 30 * omdx[43] - 30 * omdx[44];
1907         phidx[p45[38]] = -45 * omdx[36] - 30 * omdx[37] + 90 * omdx[38] + 15 * omdx[39] +
1908                          15 * omdx[40] - 60 * omdx[41] - 45 * omdx[42] + 15 * omdx[43] +
1909                          15 * omdx[44];
1910         phidx[p45[39]] = -30 * omdx[36] + 30 * omdx[37] + 15 * omdx[38] + 90 * omdx[39] -
1911                          45 * omdx[40] - 30 * omdx[41] + 15 * omdx[42] - 45 * omdx[43] +
1912                          15 * omdx[44];
1913         phidx[p45[40]] = +15 * omdx[36] - 60 * omdx[37] + 15 * omdx[38] - 45 * omdx[39] +
1914                          90 * omdx[40] - 30 * omdx[41] + 15 * omdx[42] - 45 * omdx[43] +
1915                          15 * omdx[44];
1916         phidx[p45[41]] = +30 * omdx[36] - 60 * omdx[38] - 30 * omdx[39] - 30 * omdx[40] +
1917                          120 * omdx[41] + 30 * omdx[42] - 30 * omdx[43] - 30 * omdx[44];
1918         phidx[p45[42]] = +90 * omdx[42] - 30 * omdx[43] - 30 * omdx[44];
1919         phidx[p45[43]] = -30 * omdx[42] + 90 * omdx[43] - 30 * omdx[44];
1920         phidx[p45[44]] = -30 * omdx[42] - 30 * omdx[43] + 90 * omdx[44];
1921 
1922         for (int k = 0; k < 45; ++k) {
1923           val(k, 0, op_dx) = phidx[k].x;
1924           val(k, 1, op_dx) = phidx[k].y;
1925           val(k, 2, op_dx) = phidx[k].z;
1926         }
1927       }
1928 
1929       R3 phidy[45];
1930       if (whatd & Fop_dy) {
1931         phidy[p45[0]] = +9 * omdy[0] - 18 * omdy[1] + 3 * omdy[2] - 27 * omdy[30] + 12 * omdy[31] +
1932                         9 * omdy[32] + 9 * omdy[33] - 6 * omdy[34] - 6 * omdy[35] - 27 * omdy[36] +
1933                         12 * omdy[37] + 9 * omdy[38] + 9 * omdy[39] - 6 * omdy[40] - 6 * omdy[41] +
1934                         18 * omdy[42] - 6 * omdy[43] - 6 * omdy[44];
1935         phidy[p45[1]] = -18 * omdy[0] + 84 * omdy[1] - 18 * omdy[2] - 6 * omdy[30] - 36 * omdy[31] +
1936                         12 * omdy[32] - 30 * omdy[33] + 30 * omdy[34] - 6 * omdy[36] -
1937                         36 * omdy[37] + 12 * omdy[38] - 30 * omdy[39] + 30 * omdy[40] +
1938                         24 * omdy[42];
1939         phidy[p45[2]] = +3 * omdy[0] - 18 * omdy[1] + 9 * omdy[2] + 6 * omdy[30] - 18 * omdy[31] +
1940                         3 * omdy[32] + 6 * omdy[33] - 9 * omdy[34] + 6 * omdy[35] + 6 * omdy[36] -
1941                         18 * omdy[37] + 3 * omdy[38] + 6 * omdy[39] - 9 * omdy[40] + 6 * omdy[41] +
1942                         6 * omdy[42] + 6 * omdy[43] + 6 * omdy[44];
1943         phidy[p45[3]] = +9 * omdy[3] - 18 * omdy[4] + 3 * omdy[5] - 27 * omdy[24] + 12 * omdy[25] +
1944                         9 * omdy[26] + 9 * omdy[27] - 6 * omdy[28] - 6 * omdy[29] + 9 * omdy[36] -
1945                         6 * omdy[37] - 6 * omdy[38] - 27 * omdy[39] + 9 * omdy[40] + 12 * omdy[41] -
1946                         6 * omdy[42] + 18 * omdy[43] - 6 * omdy[44];
1947         phidy[p45[4]] = -18 * omdy[3] + 84 * omdy[4] - 18 * omdy[5] - 6 * omdy[24] - 36 * omdy[25] +
1948                         12 * omdy[26] - 30 * omdy[27] + 30 * omdy[28] - 30 * omdy[36] +
1949                         30 * omdy[38] - 6 * omdy[39] + 12 * omdy[40] - 36 * omdy[41] +
1950                         24 * omdy[43];
1951         phidy[p45[5]] = +3 * omdy[3] - 18 * omdy[4] + 9 * omdy[5] + 6 * omdy[24] - 18 * omdy[25] +
1952                         3 * omdy[26] + 6 * omdy[27] - 9 * omdy[28] + 6 * omdy[29] + 6 * omdy[36] +
1953                         6 * omdy[37] - 9 * omdy[38] + 6 * omdy[39] + 3 * omdy[40] - 18 * omdy[41] +
1954                         6 * omdy[42] + 6 * omdy[43] + 6 * omdy[44];
1955         phidy[p45[6]] = +9 * omdy[6] - 18 * omdy[7] + 3 * omdy[8] + 9 * omdy[24] - 6 * omdy[25] -
1956                         6 * omdy[26] - 27 * omdy[27] + 9 * omdy[28] + 12 * omdy[29] + 9 * omdy[30] -
1957                         6 * omdy[31] - 6 * omdy[32] - 27 * omdy[33] + 9 * omdy[34] + 12 * omdy[35] -
1958                         6 * omdy[42] - 6 * omdy[43] + 18 * omdy[44];
1959         phidy[p45[7]] = -18 * omdy[6] + 84 * omdy[7] - 18 * omdy[8] - 30 * omdy[24] +
1960                         30 * omdy[26] - 6 * omdy[27] + 12 * omdy[28] - 36 * omdy[29] -
1961                         30 * omdy[30] + 30 * omdy[32] - 6 * omdy[33] + 12 * omdy[34] -
1962                         36 * omdy[35] + 24 * omdy[44];
1963         phidy[p45[8]] = +3 * omdy[6] - 18 * omdy[7] + 9 * omdy[8] + 6 * omdy[24] + 6 * omdy[25] -
1964                         9 * omdy[26] + 6 * omdy[27] + 3 * omdy[28] - 18 * omdy[29] + 6 * omdy[30] +
1965                         6 * omdy[31] - 9 * omdy[32] + 6 * omdy[33] + 3 * omdy[34] - 18 * omdy[35] +
1966                         6 * omdy[42] + 6 * omdy[43] + 6 * omdy[44];
1967         phidy[p45[9]] = +9 * omdy[9] - 18 * omdy[10] + 3 * omdy[11] - 27 * omdy[18] +
1968                         12 * omdy[19] + 9 * omdy[20] + 9 * omdy[21] - 6 * omdy[22] - 6 * omdy[23] -
1969                         3 * omdy[36] + 18 * omdy[37] - 6 * omdy[38] + 9 * omdy[39] - 27 * omdy[40] +
1970                         12 * omdy[41] - 6 * omdy[42] + 18 * omdy[43] - 6 * omdy[44];
1971         phidy[p45[10]] = -18 * omdy[9] + 84 * omdy[10] - 18 * omdy[11] - 6 * omdy[18] -
1972                          36 * omdy[19] + 12 * omdy[20] - 30 * omdy[21] + 30 * omdy[22] -
1973                          12 * omdy[36] + 36 * omdy[37] + 6 * omdy[38] + 12 * omdy[39] -
1974                          6 * omdy[40] - 36 * omdy[41] - 24 * omdy[42] + 24 * omdy[43];
1975         phidy[p45[11]] = +3 * omdy[9] - 18 * omdy[10] + 9 * omdy[11] + 6 * omdy[18] -
1976                          18 * omdy[19] + 3 * omdy[20] + 6 * omdy[21] - 9 * omdy[22] + 6 * omdy[23] -
1977                          9 * omdy[36] - 12 * omdy[37] + 27 * omdy[38] + 3 * omdy[39] +
1978                          6 * omdy[40] - 18 * omdy[41] - 18 * omdy[42] + 6 * omdy[43] + 6 * omdy[44];
1979         phidy[p45[12]] = +9 * omdy[12] - 18 * omdy[13] + 3 * omdy[14] + 9 * omdy[18] -
1980                          6 * omdy[19] - 6 * omdy[20] - 27 * omdy[21] + 9 * omdy[22] +
1981                          12 * omdy[23] - 3 * omdy[30] + 18 * omdy[31] - 6 * omdy[32] +
1982                          9 * omdy[33] - 27 * omdy[34] + 12 * omdy[35] - 6 * omdy[42] -
1983                          6 * omdy[43] + 18 * omdy[44];
1984         phidy[p45[13]] = -18 * omdy[12] + 84 * omdy[13] - 18 * omdy[14] - 30 * omdy[18] +
1985                          30 * omdy[20] - 6 * omdy[21] + 12 * omdy[22] - 36 * omdy[23] -
1986                          12 * omdy[30] + 36 * omdy[31] + 6 * omdy[32] + 12 * omdy[33] -
1987                          6 * omdy[34] - 36 * omdy[35] - 24 * omdy[42] + 24 * omdy[44];
1988         phidy[p45[14]] = +3 * omdy[12] - 18 * omdy[13] + 9 * omdy[14] + 6 * omdy[18] +
1989                          6 * omdy[19] - 9 * omdy[20] + 6 * omdy[21] + 3 * omdy[22] - 18 * omdy[23] -
1990                          9 * omdy[30] - 12 * omdy[31] + 27 * omdy[32] + 3 * omdy[33] +
1991                          6 * omdy[34] - 18 * omdy[35] - 18 * omdy[42] + 6 * omdy[43] + 6 * omdy[44];
1992         phidy[p45[15]] = +9 * omdy[15] - 18 * omdy[16] + 3 * omdy[17] - 3 * omdy[18] +
1993                          18 * omdy[19] - 6 * omdy[20] + 9 * omdy[21] - 27 * omdy[22] +
1994                          12 * omdy[23] - 3 * omdy[24] + 18 * omdy[25] - 6 * omdy[26] +
1995                          9 * omdy[27] - 27 * omdy[28] + 12 * omdy[29] - 6 * omdy[42] -
1996                          6 * omdy[43] + 18 * omdy[44];
1997         phidy[p45[16]] = -18 * omdy[15] + 84 * omdy[16] - 18 * omdy[17] - 12 * omdy[18] +
1998                          36 * omdy[19] + 6 * omdy[20] + 12 * omdy[21] - 6 * omdy[22] -
1999                          36 * omdy[23] - 12 * omdy[24] + 36 * omdy[25] + 6 * omdy[26] +
2000                          12 * omdy[27] - 6 * omdy[28] - 36 * omdy[29] - 24 * omdy[43] +
2001                          24 * omdy[44];
2002         phidy[p45[17]] = +3 * omdy[15] - 18 * omdy[16] + 9 * omdy[17] - 9 * omdy[18] -
2003                          12 * omdy[19] + 27 * omdy[20] + 3 * omdy[21] + 6 * omdy[22] -
2004                          18 * omdy[23] - 9 * omdy[24] - 12 * omdy[25] + 27 * omdy[26] +
2005                          3 * omdy[27] + 6 * omdy[28] - 18 * omdy[29] + 6 * omdy[42] -
2006                          18 * omdy[43] + 6 * omdy[44];
2007         phidy[p45[18]] = +90 * omdy[18] - 30 * omdy[19] - 45 * omdy[20] - 30 * omdy[21] +
2008                          15 * omdy[22] + 30 * omdy[23] + 15 * omdy[42] - 45 * omdy[43] +
2009                          15 * omdy[44];
2010         phidy[p45[19]] = -30 * omdy[18] + 120 * omdy[19] - 30 * omdy[20] + 30 * omdy[21] -
2011                          60 * omdy[22] + 30 * omdy[42] - 30 * omdy[43] + 30 * omdy[44];
2012         phidy[p45[20]] = -45 * omdy[18] - 30 * omdy[19] + 90 * omdy[20] + 15 * omdy[21] +
2013                          15 * omdy[22] - 60 * omdy[23] + 15 * omdy[42] - 45 * omdy[43] +
2014                          15 * omdy[44];
2015         phidy[p45[21]] = -30 * omdy[18] + 30 * omdy[19] + 15 * omdy[20] + 90 * omdy[21] -
2016                          45 * omdy[22] - 30 * omdy[23] + 15 * omdy[42] + 15 * omdy[43] -
2017                          45 * omdy[44];
2018         phidy[p45[22]] = +15 * omdy[18] - 60 * omdy[19] + 15 * omdy[20] - 45 * omdy[21] +
2019                          90 * omdy[22] - 30 * omdy[23] + 15 * omdy[42] + 15 * omdy[43] -
2020                          45 * omdy[44];
2021         phidy[p45[23]] = +30 * omdy[18] - 60 * omdy[20] - 30 * omdy[21] - 30 * omdy[22] +
2022                          120 * omdy[23] + 30 * omdy[42] + 30 * omdy[43] - 30 * omdy[44];
2023         phidy[p45[24]] = +90 * omdy[24] - 30 * omdy[25] - 45 * omdy[26] - 30 * omdy[27] +
2024                          15 * omdy[28] + 30 * omdy[29] + 15 * omdy[42] - 45 * omdy[43] +
2025                          15 * omdy[44];
2026         phidy[p45[25]] = -30 * omdy[24] + 120 * omdy[25] - 30 * omdy[26] + 30 * omdy[27] -
2027                          60 * omdy[28] - 30 * omdy[42] - 30 * omdy[43] + 30 * omdy[44];
2028         phidy[p45[26]] = -45 * omdy[24] - 30 * omdy[25] + 90 * omdy[26] + 15 * omdy[27] +
2029                          15 * omdy[28] - 60 * omdy[29] + 15 * omdy[42] - 45 * omdy[43] +
2030                          15 * omdy[44];
2031         phidy[p45[27]] = -30 * omdy[24] + 30 * omdy[25] + 15 * omdy[26] + 90 * omdy[27] -
2032                          45 * omdy[28] - 30 * omdy[29] + 15 * omdy[42] + 15 * omdy[43] -
2033                          45 * omdy[44];
2034         phidy[p45[28]] = +15 * omdy[24] - 60 * omdy[25] + 15 * omdy[26] - 45 * omdy[27] +
2035                          90 * omdy[28] - 30 * omdy[29] + 15 * omdy[42] + 15 * omdy[43] -
2036                          45 * omdy[44];
2037         phidy[p45[29]] = +30 * omdy[24] - 60 * omdy[26] - 30 * omdy[27] - 30 * omdy[28] +
2038                          120 * omdy[29] - 30 * omdy[42] + 30 * omdy[43] - 30 * omdy[44];
2039         phidy[p45[30]] = +90 * omdy[30] - 30 * omdy[31] - 45 * omdy[32] - 30 * omdy[33] +
2040                          15 * omdy[34] + 30 * omdy[35] - 45 * omdy[42] + 15 * omdy[43] +
2041                          15 * omdy[44];
2042         phidy[p45[31]] = -30 * omdy[30] + 120 * omdy[31] - 30 * omdy[32] + 30 * omdy[33] -
2043                          60 * omdy[34] - 30 * omdy[42] - 30 * omdy[43] + 30 * omdy[44];
2044         phidy[p45[32]] = -45 * omdy[30] - 30 * omdy[31] + 90 * omdy[32] + 15 * omdy[33] +
2045                          15 * omdy[34] - 60 * omdy[35] - 45 * omdy[42] + 15 * omdy[43] +
2046                          15 * omdy[44];
2047         phidy[p45[33]] = -30 * omdy[30] + 30 * omdy[31] + 15 * omdy[32] + 90 * omdy[33] -
2048                          45 * omdy[34] - 30 * omdy[35] + 15 * omdy[42] + 15 * omdy[43] -
2049                          45 * omdy[44];
2050         phidy[p45[34]] = +15 * omdy[30] - 60 * omdy[31] + 15 * omdy[32] - 45 * omdy[33] +
2051                          90 * omdy[34] - 30 * omdy[35] + 15 * omdy[42] + 15 * omdy[43] -
2052                          45 * omdy[44];
2053         phidy[p45[35]] = +30 * omdy[30] - 60 * omdy[32] - 30 * omdy[33] - 30 * omdy[34] +
2054                          120 * omdy[35] + 30 * omdy[42] - 30 * omdy[43] - 30 * omdy[44];
2055         phidy[p45[36]] = +90 * omdy[36] - 30 * omdy[37] - 45 * omdy[38] - 30 * omdy[39] +
2056                          15 * omdy[40] + 30 * omdy[41] - 45 * omdy[42] + 15 * omdy[43] +
2057                          15 * omdy[44];
2058         phidy[p45[37]] = -30 * omdy[36] + 120 * omdy[37] - 30 * omdy[38] + 30 * omdy[39] -
2059                          60 * omdy[40] - 30 * omdy[42] + 30 * omdy[43] - 30 * omdy[44];
2060         phidy[p45[38]] = -45 * omdy[36] - 30 * omdy[37] + 90 * omdy[38] + 15 * omdy[39] +
2061                          15 * omdy[40] - 60 * omdy[41] - 45 * omdy[42] + 15 * omdy[43] +
2062                          15 * omdy[44];
2063         phidy[p45[39]] = -30 * omdy[36] + 30 * omdy[37] + 15 * omdy[38] + 90 * omdy[39] -
2064                          45 * omdy[40] - 30 * omdy[41] + 15 * omdy[42] - 45 * omdy[43] +
2065                          15 * omdy[44];
2066         phidy[p45[40]] = +15 * omdy[36] - 60 * omdy[37] + 15 * omdy[38] - 45 * omdy[39] +
2067                          90 * omdy[40] - 30 * omdy[41] + 15 * omdy[42] - 45 * omdy[43] +
2068                          15 * omdy[44];
2069         phidy[p45[41]] = +30 * omdy[36] - 60 * omdy[38] - 30 * omdy[39] - 30 * omdy[40] +
2070                          120 * omdy[41] + 30 * omdy[42] - 30 * omdy[43] - 30 * omdy[44];
2071         phidy[p45[42]] = +90 * omdy[42] - 30 * omdy[43] - 30 * omdy[44];
2072         phidy[p45[43]] = -30 * omdy[42] + 90 * omdy[43] - 30 * omdy[44];
2073         phidy[p45[44]] = -30 * omdy[42] - 30 * omdy[43] + 90 * omdy[44];
2074 
2075         for (int k = 0; k < 45; ++k) {
2076           val(k, 0, op_dy) = phidy[k].x;
2077           val(k, 1, op_dy) = phidy[k].y;
2078           val(k, 2, op_dy) = phidy[k].z;
2079         }
2080       }
2081 
2082       R3 phidz[45];
2083       if (whatd & Fop_dz) {
2084         phidz[p45[0]] = +9 * omdz[0] - 18 * omdz[1] + 3 * omdz[2] - 27 * omdz[30] + 12 * omdz[31] +
2085                         9 * omdz[32] + 9 * omdz[33] - 6 * omdz[34] - 6 * omdz[35] - 27 * omdz[36] +
2086                         12 * omdz[37] + 9 * omdz[38] + 9 * omdz[39] - 6 * omdz[40] - 6 * omdz[41] +
2087                         18 * omdz[42] - 6 * omdz[43] - 6 * omdz[44];
2088         phidz[p45[1]] = -18 * omdz[0] + 84 * omdz[1] - 18 * omdz[2] - 6 * omdz[30] - 36 * omdz[31] +
2089                         12 * omdz[32] - 30 * omdz[33] + 30 * omdz[34] - 6 * omdz[36] -
2090                         36 * omdz[37] + 12 * omdz[38] - 30 * omdz[39] + 30 * omdz[40] +
2091                         24 * omdz[42];
2092         phidz[p45[2]] = +3 * omdz[0] - 18 * omdz[1] + 9 * omdz[2] + 6 * omdz[30] - 18 * omdz[31] +
2093                         3 * omdz[32] + 6 * omdz[33] - 9 * omdz[34] + 6 * omdz[35] + 6 * omdz[36] -
2094                         18 * omdz[37] + 3 * omdz[38] + 6 * omdz[39] - 9 * omdz[40] + 6 * omdz[41] +
2095                         6 * omdz[42] + 6 * omdz[43] + 6 * omdz[44];
2096         phidz[p45[3]] = +9 * omdz[3] - 18 * omdz[4] + 3 * omdz[5] - 27 * omdz[24] + 12 * omdz[25] +
2097                         9 * omdz[26] + 9 * omdz[27] - 6 * omdz[28] - 6 * omdz[29] + 9 * omdz[36] -
2098                         6 * omdz[37] - 6 * omdz[38] - 27 * omdz[39] + 9 * omdz[40] + 12 * omdz[41] -
2099                         6 * omdz[42] + 18 * omdz[43] - 6 * omdz[44];
2100         phidz[p45[4]] = -18 * omdz[3] + 84 * omdz[4] - 18 * omdz[5] - 6 * omdz[24] - 36 * omdz[25] +
2101                         12 * omdz[26] - 30 * omdz[27] + 30 * omdz[28] - 30 * omdz[36] +
2102                         30 * omdz[38] - 6 * omdz[39] + 12 * omdz[40] - 36 * omdz[41] +
2103                         24 * omdz[43];
2104         phidz[p45[5]] = +3 * omdz[3] - 18 * omdz[4] + 9 * omdz[5] + 6 * omdz[24] - 18 * omdz[25] +
2105                         3 * omdz[26] + 6 * omdz[27] - 9 * omdz[28] + 6 * omdz[29] + 6 * omdz[36] +
2106                         6 * omdz[37] - 9 * omdz[38] + 6 * omdz[39] + 3 * omdz[40] - 18 * omdz[41] +
2107                         6 * omdz[42] + 6 * omdz[43] + 6 * omdz[44];
2108         phidz[p45[6]] = +9 * omdz[6] - 18 * omdz[7] + 3 * omdz[8] + 9 * omdz[24] - 6 * omdz[25] -
2109                         6 * omdz[26] - 27 * omdz[27] + 9 * omdz[28] + 12 * omdz[29] + 9 * omdz[30] -
2110                         6 * omdz[31] - 6 * omdz[32] - 27 * omdz[33] + 9 * omdz[34] + 12 * omdz[35] -
2111                         6 * omdz[42] - 6 * omdz[43] + 18 * omdz[44];
2112         phidz[p45[7]] = -18 * omdz[6] + 84 * omdz[7] - 18 * omdz[8] - 30 * omdz[24] +
2113                         30 * omdz[26] - 6 * omdz[27] + 12 * omdz[28] - 36 * omdz[29] -
2114                         30 * omdz[30] + 30 * omdz[32] - 6 * omdz[33] + 12 * omdz[34] -
2115                         36 * omdz[35] + 24 * omdz[44];
2116         phidz[p45[8]] = +3 * omdz[6] - 18 * omdz[7] + 9 * omdz[8] + 6 * omdz[24] + 6 * omdz[25] -
2117                         9 * omdz[26] + 6 * omdz[27] + 3 * omdz[28] - 18 * omdz[29] + 6 * omdz[30] +
2118                         6 * omdz[31] - 9 * omdz[32] + 6 * omdz[33] + 3 * omdz[34] - 18 * omdz[35] +
2119                         6 * omdz[42] + 6 * omdz[43] + 6 * omdz[44];
2120         phidz[p45[9]] = +9 * omdz[9] - 18 * omdz[10] + 3 * omdz[11] - 27 * omdz[18] +
2121                         12 * omdz[19] + 9 * omdz[20] + 9 * omdz[21] - 6 * omdz[22] - 6 * omdz[23] -
2122                         3 * omdz[36] + 18 * omdz[37] - 6 * omdz[38] + 9 * omdz[39] - 27 * omdz[40] +
2123                         12 * omdz[41] - 6 * omdz[42] + 18 * omdz[43] - 6 * omdz[44];
2124         phidz[p45[10]] = -18 * omdz[9] + 84 * omdz[10] - 18 * omdz[11] - 6 * omdz[18] -
2125                          36 * omdz[19] + 12 * omdz[20] - 30 * omdz[21] + 30 * omdz[22] -
2126                          12 * omdz[36] + 36 * omdz[37] + 6 * omdz[38] + 12 * omdz[39] -
2127                          6 * omdz[40] - 36 * omdz[41] - 24 * omdz[42] + 24 * omdz[43];
2128         phidz[p45[11]] = +3 * omdz[9] - 18 * omdz[10] + 9 * omdz[11] + 6 * omdz[18] -
2129                          18 * omdz[19] + 3 * omdz[20] + 6 * omdz[21] - 9 * omdz[22] + 6 * omdz[23] -
2130                          9 * omdz[36] - 12 * omdz[37] + 27 * omdz[38] + 3 * omdz[39] +
2131                          6 * omdz[40] - 18 * omdz[41] - 18 * omdz[42] + 6 * omdz[43] + 6 * omdz[44];
2132         phidz[p45[12]] = +9 * omdz[12] - 18 * omdz[13] + 3 * omdz[14] + 9 * omdz[18] -
2133                          6 * omdz[19] - 6 * omdz[20] - 27 * omdz[21] + 9 * omdz[22] +
2134                          12 * omdz[23] - 3 * omdz[30] + 18 * omdz[31] - 6 * omdz[32] +
2135                          9 * omdz[33] - 27 * omdz[34] + 12 * omdz[35] - 6 * omdz[42] -
2136                          6 * omdz[43] + 18 * omdz[44];
2137         phidz[p45[13]] = -18 * omdz[12] + 84 * omdz[13] - 18 * omdz[14] - 30 * omdz[18] +
2138                          30 * omdz[20] - 6 * omdz[21] + 12 * omdz[22] - 36 * omdz[23] -
2139                          12 * omdz[30] + 36 * omdz[31] + 6 * omdz[32] + 12 * omdz[33] -
2140                          6 * omdz[34] - 36 * omdz[35] - 24 * omdz[42] + 24 * omdz[44];
2141         phidz[p45[14]] = +3 * omdz[12] - 18 * omdz[13] + 9 * omdz[14] + 6 * omdz[18] +
2142                          6 * omdz[19] - 9 * omdz[20] + 6 * omdz[21] + 3 * omdz[22] - 18 * omdz[23] -
2143                          9 * omdz[30] - 12 * omdz[31] + 27 * omdz[32] + 3 * omdz[33] +
2144                          6 * omdz[34] - 18 * omdz[35] - 18 * omdz[42] + 6 * omdz[43] + 6 * omdz[44];
2145         phidz[p45[15]] = +9 * omdz[15] - 18 * omdz[16] + 3 * omdz[17] - 3 * omdz[18] +
2146                          18 * omdz[19] - 6 * omdz[20] + 9 * omdz[21] - 27 * omdz[22] +
2147                          12 * omdz[23] - 3 * omdz[24] + 18 * omdz[25] - 6 * omdz[26] +
2148                          9 * omdz[27] - 27 * omdz[28] + 12 * omdz[29] - 6 * omdz[42] -
2149                          6 * omdz[43] + 18 * omdz[44];
2150         phidz[p45[16]] = -18 * omdz[15] + 84 * omdz[16] - 18 * omdz[17] - 12 * omdz[18] +
2151                          36 * omdz[19] + 6 * omdz[20] + 12 * omdz[21] - 6 * omdz[22] -
2152                          36 * omdz[23] - 12 * omdz[24] + 36 * omdz[25] + 6 * omdz[26] +
2153                          12 * omdz[27] - 6 * omdz[28] - 36 * omdz[29] - 24 * omdz[43] +
2154                          24 * omdz[44];
2155         phidz[p45[17]] = +3 * omdz[15] - 18 * omdz[16] + 9 * omdz[17] - 9 * omdz[18] -
2156                          12 * omdz[19] + 27 * omdz[20] + 3 * omdz[21] + 6 * omdz[22] -
2157                          18 * omdz[23] - 9 * omdz[24] - 12 * omdz[25] + 27 * omdz[26] +
2158                          3 * omdz[27] + 6 * omdz[28] - 18 * omdz[29] + 6 * omdz[42] -
2159                          18 * omdz[43] + 6 * omdz[44];
2160         phidz[p45[18]] = +90 * omdz[18] - 30 * omdz[19] - 45 * omdz[20] - 30 * omdz[21] +
2161                          15 * omdz[22] + 30 * omdz[23] + 15 * omdz[42] - 45 * omdz[43] +
2162                          15 * omdz[44];
2163         phidz[p45[19]] = -30 * omdz[18] + 120 * omdz[19] - 30 * omdz[20] + 30 * omdz[21] -
2164                          60 * omdz[22] + 30 * omdz[42] - 30 * omdz[43] + 30 * omdz[44];
2165         phidz[p45[20]] = -45 * omdz[18] - 30 * omdz[19] + 90 * omdz[20] + 15 * omdz[21] +
2166                          15 * omdz[22] - 60 * omdz[23] + 15 * omdz[42] - 45 * omdz[43] +
2167                          15 * omdz[44];
2168         phidz[p45[21]] = -30 * omdz[18] + 30 * omdz[19] + 15 * omdz[20] + 90 * omdz[21] -
2169                          45 * omdz[22] - 30 * omdz[23] + 15 * omdz[42] + 15 * omdz[43] -
2170                          45 * omdz[44];
2171         phidz[p45[22]] = +15 * omdz[18] - 60 * omdz[19] + 15 * omdz[20] - 45 * omdz[21] +
2172                          90 * omdz[22] - 30 * omdz[23] + 15 * omdz[42] + 15 * omdz[43] -
2173                          45 * omdz[44];
2174         phidz[p45[23]] = +30 * omdz[18] - 60 * omdz[20] - 30 * omdz[21] - 30 * omdz[22] +
2175                          120 * omdz[23] + 30 * omdz[42] + 30 * omdz[43] - 30 * omdz[44];
2176         phidz[p45[24]] = +90 * omdz[24] - 30 * omdz[25] - 45 * omdz[26] - 30 * omdz[27] +
2177                          15 * omdz[28] + 30 * omdz[29] + 15 * omdz[42] - 45 * omdz[43] +
2178                          15 * omdz[44];
2179         phidz[p45[25]] = -30 * omdz[24] + 120 * omdz[25] - 30 * omdz[26] + 30 * omdz[27] -
2180                          60 * omdz[28] - 30 * omdz[42] - 30 * omdz[43] + 30 * omdz[44];
2181         phidz[p45[26]] = -45 * omdz[24] - 30 * omdz[25] + 90 * omdz[26] + 15 * omdz[27] +
2182                          15 * omdz[28] - 60 * omdz[29] + 15 * omdz[42] - 45 * omdz[43] +
2183                          15 * omdz[44];
2184         phidz[p45[27]] = -30 * omdz[24] + 30 * omdz[25] + 15 * omdz[26] + 90 * omdz[27] -
2185                          45 * omdz[28] - 30 * omdz[29] + 15 * omdz[42] + 15 * omdz[43] -
2186                          45 * omdz[44];
2187         phidz[p45[28]] = +15 * omdz[24] - 60 * omdz[25] + 15 * omdz[26] - 45 * omdz[27] +
2188                          90 * omdz[28] - 30 * omdz[29] + 15 * omdz[42] + 15 * omdz[43] -
2189                          45 * omdz[44];
2190         phidz[p45[29]] = +30 * omdz[24] - 60 * omdz[26] - 30 * omdz[27] - 30 * omdz[28] +
2191                          120 * omdz[29] - 30 * omdz[42] + 30 * omdz[43] - 30 * omdz[44];
2192         phidz[p45[30]] = +90 * omdz[30] - 30 * omdz[31] - 45 * omdz[32] - 30 * omdz[33] +
2193                          15 * omdz[34] + 30 * omdz[35] - 45 * omdz[42] + 15 * omdz[43] +
2194                          15 * omdz[44];
2195         phidz[p45[31]] = -30 * omdz[30] + 120 * omdz[31] - 30 * omdz[32] + 30 * omdz[33] -
2196                          60 * omdz[34] - 30 * omdz[42] - 30 * omdz[43] + 30 * omdz[44];
2197         phidz[p45[32]] = -45 * omdz[30] - 30 * omdz[31] + 90 * omdz[32] + 15 * omdz[33] +
2198                          15 * omdz[34] - 60 * omdz[35] - 45 * omdz[42] + 15 * omdz[43] +
2199                          15 * omdz[44];
2200         phidz[p45[33]] = -30 * omdz[30] + 30 * omdz[31] + 15 * omdz[32] + 90 * omdz[33] -
2201                          45 * omdz[34] - 30 * omdz[35] + 15 * omdz[42] + 15 * omdz[43] -
2202                          45 * omdz[44];
2203         phidz[p45[34]] = +15 * omdz[30] - 60 * omdz[31] + 15 * omdz[32] - 45 * omdz[33] +
2204                          90 * omdz[34] - 30 * omdz[35] + 15 * omdz[42] + 15 * omdz[43] -
2205                          45 * omdz[44];
2206         phidz[p45[35]] = +30 * omdz[30] - 60 * omdz[32] - 30 * omdz[33] - 30 * omdz[34] +
2207                          120 * omdz[35] + 30 * omdz[42] - 30 * omdz[43] - 30 * omdz[44];
2208         phidz[p45[36]] = +90 * omdz[36] - 30 * omdz[37] - 45 * omdz[38] - 30 * omdz[39] +
2209                          15 * omdz[40] + 30 * omdz[41] - 45 * omdz[42] + 15 * omdz[43] +
2210                          15 * omdz[44];
2211         phidz[p45[37]] = -30 * omdz[36] + 120 * omdz[37] - 30 * omdz[38] + 30 * omdz[39] -
2212                          60 * omdz[40] - 30 * omdz[42] + 30 * omdz[43] - 30 * omdz[44];
2213         phidz[p45[38]] = -45 * omdz[36] - 30 * omdz[37] + 90 * omdz[38] + 15 * omdz[39] +
2214                          15 * omdz[40] - 60 * omdz[41] - 45 * omdz[42] + 15 * omdz[43] +
2215                          15 * omdz[44];
2216         phidz[p45[39]] = -30 * omdz[36] + 30 * omdz[37] + 15 * omdz[38] + 90 * omdz[39] -
2217                          45 * omdz[40] - 30 * omdz[41] + 15 * omdz[42] - 45 * omdz[43] +
2218                          15 * omdz[44];
2219         phidz[p45[40]] = +15 * omdz[36] - 60 * omdz[37] + 15 * omdz[38] - 45 * omdz[39] +
2220                          90 * omdz[40] - 30 * omdz[41] + 15 * omdz[42] - 45 * omdz[43] +
2221                          15 * omdz[44];
2222         phidz[p45[41]] = +30 * omdz[36] - 60 * omdz[38] - 30 * omdz[39] - 30 * omdz[40] +
2223                          120 * omdz[41] + 30 * omdz[42] - 30 * omdz[43] - 30 * omdz[44];
2224         phidz[p45[42]] = +90 * omdz[42] - 30 * omdz[43] - 30 * omdz[44];
2225         phidz[p45[43]] = -30 * omdz[42] + 90 * omdz[43] - 30 * omdz[44];
2226         phidz[p45[44]] = -30 * omdz[42] - 30 * omdz[43] + 90 * omdz[44];
2227 
2228         for (int k = 0; k < 45; ++k) {
2229           val(k, 0, op_dz) = phidz[k].x;
2230           val(k, 1, op_dz) = phidz[k].y;
2231           val(k, 2, op_dz) = phidz[k].z;
2232         }
2233       }
2234     }
2235 
2236     if (whatd & Fop_D2) {    // SECOND DERIVATIVES
2237       R3 omdxx[45];
2238       R3 omdyy[45];
2239       R3 omdzz[45];
2240       R3 omdxy[45];
2241       R3 omdxz[45];
2242       R3 omdyz[45];
2243 
2244       // 18 edge functions (3 for each edge):
2245       for (int i = 0; i < Element::ne; ++i) {
2246         int ii0 = Element::nvedge[i][0], ii1 = Element::nvedge[i][1];
2247         int i0 = perm[ii0];
2248         int i1 = perm[ii1];
2249         if (whatd & Fop_dxx) {
2250           omdxx[i * 3] = 2 * D[i0].x * D[i0].x * (l[i0] * D[i1] - l[i1] * D[i0]) +
2251                          4 * D[i0].x * l[i0] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2252           omdxx[i * 3 + 1] =
2253             2 * D[i0].x * D[i1].x * (l[i0] * D[i1] - l[i1] * D[i0]) +
2254             2 * (D[i0].x * l[i1] + l[i0] * D[i1].x) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2255           omdxx[i * 3 + 2] = 2 * D[i1].x * D[i1].x * (l[i0] * D[i1] - l[i1] * D[i0]) +
2256                              4 * D[i1].x * l[i1] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2257         }
2258 
2259         if (whatd & Fop_dyy) {
2260           omdyy[i * 3] = 2 * D[i0].y * D[i0].y * (l[i0] * D[i1] - l[i1] * D[i0]) +
2261                          4 * D[i0].y * l[i0] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2262           omdyy[i * 3 + 1] =
2263             2 * D[i0].y * D[i1].y * (l[i0] * D[i1] - l[i1] * D[i0]) +
2264             2 * (D[i0].y * l[i1] + l[i0] * D[i1].y) * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2265           omdyy[i * 3 + 2] = 2 * D[i1].y * D[i1].y * (l[i0] * D[i1] - l[i1] * D[i0]) +
2266                              4 * D[i1].y * l[i1] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2267         }
2268 
2269         if (whatd & Fop_dzz) {
2270           omdzz[i * 3] = 2 * D[i0].z * D[i0].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2271                          4 * D[i0].z * l[i0] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
2272           omdzz[i * 3 + 1] =
2273             2 * D[i0].z * D[i1].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2274             2 * (D[i0].z * l[i1] + l[i0] * D[i1].z) * (D[i0].z * D[i1] - D[i1].z * D[i0]);
2275           omdzz[i * 3 + 2] = 2 * D[i1].z * D[i1].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2276                              4 * D[i1].z * l[i1] * (D[i0].z * D[i1] - D[i1].z * D[i0]);
2277         }
2278 
2279         if (whatd & Fop_dxy) {
2280           omdxy[i * 3] = 2 * D[i0].x * D[i0].y * (l[i0] * D[i1] - l[i1] * D[i0]) +
2281                          2 * D[i0].x * l[i0] * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
2282                          2 * D[i0].y * l[i0] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2283           omdxy[i * 3 + 1] =
2284             (D[i0].x * D[i1].y + D[i0].y * D[i1].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2285             (D[i0].x * l[i1] + l[i0] * D[i1].x) * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
2286             (D[i0].y * l[i1] + l[i0] * D[i1].y) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2287           omdxy[i * 3 + 2] = 2 * D[i1].x * D[i1].y * (l[i0] * D[i1] - l[i1] * D[i0]) +
2288                              2 * D[i1].x * l[i1] * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
2289                              2 * D[i1].y * l[i1] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2290         }
2291 
2292         if (whatd & Fop_dxz) {
2293           omdxz[i * 3] = 2 * D[i0].x * D[i0].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2294                          2 * D[i0].x * l[i0] * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2295                          2 * D[i0].z * l[i0] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2296           omdxz[i * 3 + 1] =
2297             (D[i0].x * D[i1].z + D[i0].z * D[i1].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2298             (D[i0].x * l[i1] + l[i0] * D[i1].x) * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2299             (D[i0].z * l[i1] + l[i0] * D[i1].z) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2300           omdxz[i * 3 + 2] = 2 * D[i1].x * D[i1].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2301                              2 * D[i1].x * l[i1] * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2302                              2 * D[i1].z * l[i1] * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2303         }
2304 
2305         if (whatd & Fop_dyz) {
2306           omdyz[i * 3] = 2 * D[i0].y * D[i0].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2307                          2 * D[i0].y * l[i0] * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2308                          2 * D[i0].z * l[i0] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2309           omdyz[i * 3 + 1] =
2310             (D[i0].y * D[i1].z + D[i0].z * D[i1].y) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2311             (D[i0].y * l[i1] + l[i0] * D[i1].y) * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2312             (D[i0].z * l[i1] + l[i0] * D[i1].z) * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2313           omdyz[i * 3 + 2] = 2 * D[i1].y * D[i1].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2314                              2 * D[i1].y * l[i1] * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2315                              2 * D[i1].z * l[i1] * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2316         }
2317       }
2318 
2319       // 24 face functions (6 for each face):
2320       for (int j = 0; j < Element::nf; ++j) {
2321         int ii0 = mynvface[j][0];
2322         int ii1 = mynvface[j][1];
2323         int ii2 = mynvface[j][2];
2324         int i0 = perm[ii0];
2325         int i1 = perm[ii1];
2326         int i2 = perm[ii2];
2327         if (whatd & Fop_dxx) {
2328           omdxx[18 + j * 6] =
2329             2 * D[i0].x * D[i2].x * (l[i0] * D[i1] - l[i1] * D[i0]) +
2330             2 * (D[i0].x * l[i2] + l[i0] * D[i2].x) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2331           omdxx[18 + j * 6 + 1] =
2332             2 * D[i1].x * D[i2].x * (l[i0] * D[i1] - l[i1] * D[i0]) +
2333             2 * (D[i1].x * l[i2] + l[i1] * D[i2].x) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2334           omdxx[18 + j * 6 + 2] =
2335             2 * D[i2].x * D[i2].x * (l[i0] * D[i1] - l[i1] * D[i0]) +
2336             2 * (D[i2].x * l[i2] + l[i2] * D[i2].x) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2337           omdxx[18 + j * 6 + 3] =
2338             2 * D[i0].x * D[i1].x * (l[i0] * D[i2] - l[i2] * D[i0]) +
2339             2 * (D[i0].x * l[i1] + l[i0] * D[i1].x) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2340           omdxx[18 + j * 6 + 4] =
2341             2 * D[i1].x * D[i1].x * (l[i0] * D[i2] - l[i2] * D[i0]) +
2342             2 * (D[i1].x * l[i1] + l[i1] * D[i1].x) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2343           omdxx[18 + j * 6 + 5] =
2344             2 * D[i2].x * D[i1].x * (l[i0] * D[i2] - l[i2] * D[i0]) +
2345             2 * (D[i2].x * l[i1] + l[i2] * D[i1].x) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2346         }
2347 
2348         if (whatd & Fop_dyy) {
2349           omdyy[18 + j * 6] =
2350             2 * D[i0].y * D[i2].y * (l[i0] * D[i1] - l[i1] * D[i0]) +
2351             2 * (D[i0].y * l[i2] + l[i0] * D[i2].y) * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2352           omdyy[18 + j * 6 + 1] =
2353             2 * D[i1].y * D[i2].y * (l[i0] * D[i1] - l[i1] * D[i0]) +
2354             2 * (D[i1].y * l[i2] + l[i1] * D[i2].y) * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2355           omdyy[18 + j * 6 + 2] =
2356             2 * D[i2].y * D[i2].y * (l[i0] * D[i1] - l[i1] * D[i0]) +
2357             2 * (D[i2].y * l[i2] + l[i2] * D[i2].y) * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2358           omdyy[18 + j * 6 + 3] =
2359             2 * D[i0].y * D[i1].y * (l[i0] * D[i2] - l[i2] * D[i0]) +
2360             2 * (D[i0].y * l[i1] + l[i0] * D[i1].y) * (D[i0].y * D[i2] - D[i2].y * D[i0]);
2361           omdyy[18 + j * 6 + 4] =
2362             2 * D[i1].y * D[i1].y * (l[i0] * D[i2] - l[i2] * D[i0]) +
2363             2 * (D[i1].y * l[i1] + l[i1] * D[i1].y) * (D[i0].y * D[i2] - D[i2].y * D[i0]);
2364           omdyy[18 + j * 6 + 5] =
2365             2 * D[i2].y * D[i1].y * (l[i0] * D[i2] - l[i2] * D[i0]) +
2366             2 * (D[i2].y * l[i1] + l[i2] * D[i1].y) * (D[i0].y * D[i2] - D[i2].y * D[i0]);
2367         }
2368 
2369         if (whatd & Fop_dzz) {
2370           omdzz[18 + j * 6] =
2371             2 * D[i0].z * D[i2].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2372             2 * (D[i0].z * l[i2] + l[i0] * D[i2].z) * (D[i0].z * D[i1] - D[i1].z * D[i0]);
2373           omdzz[18 + j * 6 + 1] =
2374             2 * D[i1].z * D[i2].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2375             2 * (D[i1].z * l[i2] + l[i1] * D[i2].z) * (D[i0].z * D[i1] - D[i1].z * D[i0]);
2376           omdzz[18 + j * 6 + 2] =
2377             2 * D[i2].z * D[i2].z * (l[i0] * D[i1] - l[i1] * D[i0]) +
2378             2 * (D[i2].z * l[i2] + l[i2] * D[i2].z) * (D[i0].z * D[i1] - D[i1].z * D[i0]);
2379           omdzz[18 + j * 6 + 3] =
2380             2 * D[i0].z * D[i1].z * (l[i0] * D[i2] - l[i2] * D[i0]) +
2381             2 * (D[i0].z * l[i1] + l[i0] * D[i1].z) * (D[i0].z * D[i2] - D[i2].z * D[i0]);
2382           omdzz[18 + j * 6 + 4] =
2383             2 * D[i1].z * D[i1].z * (l[i0] * D[i2] - l[i2] * D[i0]) +
2384             2 * (D[i1].z * l[i1] + l[i1] * D[i1].z) * (D[i0].z * D[i2] - D[i2].z * D[i0]);
2385           omdzz[18 + j * 6 + 5] =
2386             2 * D[i2].z * D[i1].z * (l[i0] * D[i2] - l[i2] * D[i0]) +
2387             2 * (D[i2].z * l[i1] + l[i2] * D[i1].z) * (D[i0].z * D[i2] - D[i2].z * D[i0]);
2388         }
2389 
2390         if (whatd & Fop_dxy) {
2391           omdxy[18 + j * 6] =
2392             (D[i0].x * D[i2].y + D[i0].y * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2393             (D[i0].x * l[i2] + l[i0] * D[i2].x) * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
2394             (D[i0].y * l[i2] + l[i0] * D[i2].y) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2395           omdxy[18 + j * 6 + 1] =
2396             (D[i1].x * D[i2].y + D[i1].y * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2397             (D[i1].x * l[i2] + l[i1] * D[i2].x) * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
2398             (D[i1].y * l[i2] + l[i1] * D[i2].y) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2399           omdxy[18 + j * 6 + 2] =
2400             (D[i2].x * D[i2].y + D[i2].y * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2401             (D[i2].x * l[i2] + l[i2] * D[i2].x) * (D[i0].y * D[i1] - D[i1].y * D[i0]) +
2402             (D[i2].y * l[i2] + l[i2] * D[i2].y) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2403           omdxy[18 + j * 6 + 3] =
2404             (D[i0].x * D[i1].y + D[i0].y * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2405             (D[i0].x * l[i1] + l[i0] * D[i1].x) * (D[i0].y * D[i2] - D[i2].y * D[i0]) +
2406             (D[i0].y * l[i1] + l[i0] * D[i1].y) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2407           omdxy[18 + j * 6 + 4] =
2408             (D[i1].x * D[i1].y + D[i1].y * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2409             (D[i1].x * l[i1] + l[i1] * D[i1].x) * (D[i0].y * D[i2] - D[i2].y * D[i0]) +
2410             (D[i1].y * l[i1] + l[i1] * D[i1].y) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2411           omdxy[18 + j * 6 + 5] =
2412             (D[i2].x * D[i1].y + D[i2].y * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2413             (D[i2].x * l[i1] + l[i2] * D[i1].x) * (D[i0].y * D[i2] - D[i2].y * D[i0]) +
2414             (D[i2].y * l[i1] + l[i2] * D[i1].y) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2415         }
2416 
2417         if (whatd & Fop_dxz) {
2418           omdxz[18 + j * 6] =
2419             (D[i0].x * D[i2].z + D[i0].z * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2420             (D[i0].x * l[i2] + l[i0] * D[i2].x) * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2421             (D[i0].z * l[i2] + l[i0] * D[i2].z) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2422           omdxz[18 + j * 6 + 1] =
2423             (D[i1].x * D[i2].z + D[i1].z * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2424             (D[i1].x * l[i2] + l[i1] * D[i2].x) * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2425             (D[i1].z * l[i2] + l[i1] * D[i2].z) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2426           omdxz[18 + j * 6 + 2] =
2427             (D[i2].x * D[i2].z + D[i2].z * D[i2].x) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2428             (D[i2].x * l[i2] + l[i2] * D[i2].x) * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2429             (D[i2].z * l[i2] + l[i2] * D[i2].z) * (D[i0].x * D[i1] - D[i1].x * D[i0]);
2430           omdxz[18 + j * 6 + 3] =
2431             (D[i0].x * D[i1].z + D[i0].z * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2432             (D[i0].x * l[i1] + l[i0] * D[i1].x) * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
2433             (D[i0].z * l[i1] + l[i0] * D[i1].z) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2434           omdxz[18 + j * 6 + 4] =
2435             (D[i1].x * D[i1].z + D[i1].z * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2436             (D[i1].x * l[i1] + l[i1] * D[i1].x) * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
2437             (D[i1].z * l[i1] + l[i1] * D[i1].z) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2438           omdxz[18 + j * 6 + 5] =
2439             (D[i2].x * D[i1].z + D[i2].z * D[i1].x) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2440             (D[i2].x * l[i1] + l[i2] * D[i1].x) * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
2441             (D[i2].z * l[i1] + l[i2] * D[i1].z) * (D[i0].x * D[i2] - D[i2].x * D[i0]);
2442         }
2443 
2444         if (whatd & Fop_dyz) {
2445           omdyz[18 + j * 6] =
2446             (D[i0].y * D[i2].z + D[i0].z * D[i2].y) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2447             (D[i0].y * l[i2] + l[i0] * D[i2].y) * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2448             (D[i0].z * l[i2] + l[i0] * D[i2].z) * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2449           omdyz[18 + j * 6 + 1] =
2450             (D[i1].y * D[i2].z + D[i1].z * D[i2].y) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2451             (D[i1].y * l[i2] + l[i1] * D[i2].y) * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2452             (D[i1].z * l[i2] + l[i1] * D[i2].z) * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2453           omdyz[18 + j * 6 + 2] =
2454             (D[i2].y * D[i2].z + D[i2].z * D[i2].y) * (l[i0] * D[i1] - l[i1] * D[i0]) +
2455             (D[i2].y * l[i2] + l[i2] * D[i2].y) * (D[i0].z * D[i1] - D[i1].z * D[i0]) +
2456             (D[i2].z * l[i2] + l[i2] * D[i2].z) * (D[i0].y * D[i1] - D[i1].y * D[i0]);
2457           omdyz[18 + j * 6 + 3] =
2458             (D[i0].y * D[i1].z + D[i0].z * D[i1].y) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2459             (D[i0].y * l[i1] + l[i0] * D[i1].y) * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
2460             (D[i0].z * l[i1] + l[i0] * D[i1].z) * (D[i0].y * D[i2] - D[i2].y * D[i0]);
2461           omdyz[18 + j * 6 + 4] =
2462             (D[i1].y * D[i1].z + D[i1].z * D[i1].y) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2463             (D[i1].y * l[i1] + l[i1] * D[i1].y) * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
2464             (D[i1].z * l[i1] + l[i1] * D[i1].z) * (D[i0].y * D[i2] - D[i2].y * D[i0]);
2465           omdyz[18 + j * 6 + 5] =
2466             (D[i2].y * D[i1].z + D[i2].z * D[i1].y) * (l[i0] * D[i2] - l[i2] * D[i0]) +
2467             (D[i2].y * l[i1] + l[i2] * D[i1].y) * (D[i0].z * D[i2] - D[i2].z * D[i0]) +
2468             (D[i2].z * l[i1] + l[i2] * D[i1].z) * (D[i0].y * D[i2] - D[i2].y * D[i0]);
2469         }
2470       }
2471 
2472       // 3 volume functions
2473       if (whatd & Fop_dxx) {
2474         omdxx[42] =
2475           2 * D[perm[2]].x * D[perm[3]].x * (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
2476           2 * (D[perm[2]].x * l[perm[3]] + l[perm[2]] * D[perm[3]].x) *
2477             (D[perm[0]].x * D[perm[1]] - D[perm[1]].x * D[perm[0]]);
2478         omdxx[43] =
2479           2 * D[perm[1]].x * D[perm[3]].x * (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
2480           2 * (D[perm[1]].x * l[perm[3]] + l[perm[1]] * D[perm[3]].x) *
2481             (D[perm[0]].x * D[perm[2]] - D[perm[2]].x * D[perm[0]]);
2482         omdxx[44] =
2483           2 * D[perm[1]].x * D[perm[2]].x * (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
2484           2 * (D[perm[1]].x * l[perm[2]] + l[perm[1]] * D[perm[2]].x) *
2485             (D[perm[0]].x * D[perm[3]] - D[perm[3]].x * D[perm[0]]);
2486       }
2487 
2488       if (whatd & Fop_dyy) {
2489         omdyy[42] =
2490           2 * D[perm[2]].y * D[perm[3]].y * (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
2491           2 * (D[perm[2]].y * l[perm[3]] + l[perm[2]] * D[perm[3]].y) *
2492             (D[perm[0]].y * D[perm[1]] - D[perm[1]].y * D[perm[0]]);
2493         omdyy[43] =
2494           2 * D[perm[1]].y * D[perm[3]].y * (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
2495           2 * (D[perm[1]].y * l[perm[3]] + l[perm[1]] * D[perm[3]].y) *
2496             (D[perm[0]].y * D[perm[2]] - D[perm[2]].y * D[perm[0]]);
2497         omdyy[44] =
2498           2 * D[perm[1]].y * D[perm[2]].y * (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
2499           2 * (D[perm[1]].y * l[perm[2]] + l[perm[1]] * D[perm[2]].y) *
2500             (D[perm[0]].y * D[perm[3]] - D[perm[3]].y * D[perm[0]]);
2501       }
2502 
2503       if (whatd & Fop_dzz) {
2504         omdzz[42] =
2505           2 * D[perm[2]].z * D[perm[3]].z * (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
2506           2 * (D[perm[2]].z * l[perm[3]] + l[perm[2]] * D[perm[3]].z) *
2507             (D[perm[0]].z * D[perm[1]] - D[perm[1]].z * D[perm[0]]);
2508         omdzz[43] =
2509           2 * D[perm[1]].z * D[perm[3]].z * (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
2510           2 * (D[perm[1]].z * l[perm[3]] + l[perm[1]] * D[perm[3]].z) *
2511             (D[perm[0]].z * D[perm[2]] - D[perm[2]].z * D[perm[0]]);
2512         omdzz[44] =
2513           2 * D[perm[1]].z * D[perm[2]].z * (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
2514           2 * (D[perm[1]].z * l[perm[2]] + l[perm[1]] * D[perm[2]].z) *
2515             (D[perm[0]].z * D[perm[3]] - D[perm[3]].z * D[perm[0]]);
2516       }
2517 
2518       if (whatd & Fop_dxy) {
2519         omdxy[42] = (D[perm[2]].x * D[perm[3]].y + D[perm[2]].y * D[perm[3]].x) *
2520                       (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
2521                     (D[perm[2]].x * l[perm[3]] + l[perm[2]] * D[perm[3]].x) *
2522                       (D[perm[0]].y * D[perm[1]] - D[perm[1]].y * D[perm[0]]) +
2523                     (D[perm[2]].y * l[perm[3]] + l[perm[2]] * D[perm[3]].y) *
2524                       (D[perm[0]].x * D[perm[1]] - D[perm[1]].x * D[perm[0]]);
2525 
2526         omdxy[43] = (D[perm[1]].x * D[perm[3]].y + D[perm[1]].y * D[perm[3]].x) *
2527                       (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
2528                     (D[perm[1]].x * l[perm[3]] + l[perm[1]] * D[perm[3]].x) *
2529                       (D[perm[0]].y * D[perm[2]] - D[perm[2]].y * D[perm[0]]) +
2530                     (D[perm[1]].y * l[perm[3]] + l[perm[1]] * D[perm[3]].y) *
2531                       (D[perm[0]].x * D[perm[2]] - D[perm[2]].x * D[perm[0]]);
2532 
2533         omdxy[44] = (D[perm[1]].x * D[perm[2]].y + D[perm[1]].y * D[perm[2]].x) *
2534                       (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
2535                     (D[perm[1]].x * l[perm[2]] + l[perm[1]] * D[perm[2]].x) *
2536                       (D[perm[0]].y * D[perm[3]] - D[perm[3]].y * D[perm[0]]) +
2537                     (D[perm[1]].y * l[perm[2]] + l[perm[1]] * D[perm[2]].y) *
2538                       (D[perm[0]].x * D[perm[3]] - D[perm[3]].x * D[perm[0]]);
2539       }
2540 
2541       if (whatd & Fop_dxz) {
2542         omdxz[42] = (D[perm[2]].x * D[perm[3]].z + D[perm[2]].z * D[perm[3]].x) *
2543                       (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
2544                     (D[perm[2]].x * l[perm[3]] + l[perm[2]] * D[perm[3]].x) *
2545                       (D[perm[0]].z * D[perm[1]] - D[perm[1]].z * D[perm[0]]) +
2546                     (D[perm[2]].z * l[perm[3]] + l[perm[2]] * D[perm[3]].z) *
2547                       (D[perm[0]].x * D[perm[1]] - D[perm[1]].x * D[perm[0]]);
2548 
2549         omdxz[43] = (D[perm[1]].x * D[perm[3]].z + D[perm[1]].z * D[perm[3]].x) *
2550                       (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
2551                     (D[perm[1]].x * l[perm[3]] + l[perm[1]] * D[perm[3]].x) *
2552                       (D[perm[0]].z * D[perm[2]] - D[perm[2]].z * D[perm[0]]) +
2553                     (D[perm[1]].z * l[perm[3]] + l[perm[1]] * D[perm[3]].z) *
2554                       (D[perm[0]].x * D[perm[2]] - D[perm[2]].x * D[perm[0]]);
2555 
2556         omdxz[44] = (D[perm[1]].x * D[perm[2]].z + D[perm[1]].z * D[perm[2]].x) *
2557                       (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
2558                     (D[perm[1]].x * l[perm[2]] + l[perm[1]] * D[perm[2]].x) *
2559                       (D[perm[0]].z * D[perm[3]] - D[perm[3]].z * D[perm[0]]) +
2560                     (D[perm[1]].z * l[perm[2]] + l[perm[1]] * D[perm[2]].z) *
2561                       (D[perm[0]].x * D[perm[3]] - D[perm[3]].x * D[perm[0]]);
2562       }
2563 
2564       if (whatd & Fop_dyz) {
2565         omdyz[42] = (D[perm[2]].y * D[perm[3]].z + D[perm[2]].z * D[perm[3]].y) *
2566                       (l[perm[0]] * D[perm[1]] - l[perm[1]] * D[perm[0]]) +
2567                     (D[perm[2]].y * l[perm[3]] + l[perm[2]] * D[perm[3]].y) *
2568                       (D[perm[0]].z * D[perm[1]] - D[perm[1]].z * D[perm[0]]) +
2569                     (D[perm[2]].z * l[perm[3]] + l[perm[2]] * D[perm[3]].z) *
2570                       (D[perm[0]].y * D[perm[1]] - D[perm[1]].y * D[perm[0]]);
2571 
2572         omdyz[43] = (D[perm[1]].y * D[perm[3]].z + D[perm[1]].z * D[perm[3]].y) *
2573                       (l[perm[0]] * D[perm[2]] - l[perm[2]] * D[perm[0]]) +
2574                     (D[perm[1]].y * l[perm[3]] + l[perm[1]] * D[perm[3]].y) *
2575                       (D[perm[0]].z * D[perm[2]] - D[perm[2]].z * D[perm[0]]) +
2576                     (D[perm[1]].z * l[perm[3]] + l[perm[1]] * D[perm[3]].z) *
2577                       (D[perm[0]].y * D[perm[2]] - D[perm[2]].y * D[perm[0]]);
2578 
2579         omdyz[44] = (D[perm[1]].y * D[perm[2]].z + D[perm[1]].z * D[perm[2]].y) *
2580                       (l[perm[0]] * D[perm[3]] - l[perm[3]] * D[perm[0]]) +
2581                     (D[perm[1]].y * l[perm[2]] + l[perm[1]] * D[perm[2]].y) *
2582                       (D[perm[0]].z * D[perm[3]] - D[perm[3]].z * D[perm[0]]) +
2583                     (D[perm[1]].z * l[perm[2]] + l[perm[1]] * D[perm[2]].z) *
2584                       (D[perm[0]].y * D[perm[3]] - D[perm[3]].y * D[perm[0]]);
2585       }
2586 
2587       R3 phidxx[45];
2588       if (whatd & Fop_dxx) {
2589         phidxx[p45[0]] = +9 * omdxx[0] - 18 * omdxx[1] + 3 * omdxx[2] - 27 * omdxx[30] +
2590                          12 * omdxx[31] + 9 * omdxx[32] + 9 * omdxx[33] - 6 * omdxx[34] -
2591                          6 * omdxx[35] - 27 * omdxx[36] + 12 * omdxx[37] + 9 * omdxx[38] +
2592                          9 * omdxx[39] - 6 * omdxx[40] - 6 * omdxx[41] + 18 * omdxx[42] -
2593                          6 * omdxx[43] - 6 * omdxx[44];
2594         phidxx[p45[1]] = -18 * omdxx[0] + 84 * omdxx[1] - 18 * omdxx[2] - 6 * omdxx[30] -
2595                          36 * omdxx[31] + 12 * omdxx[32] - 30 * omdxx[33] + 30 * omdxx[34] -
2596                          6 * omdxx[36] - 36 * omdxx[37] + 12 * omdxx[38] - 30 * omdxx[39] +
2597                          30 * omdxx[40] + 24 * omdxx[42];
2598         phidxx[p45[2]] = +3 * omdxx[0] - 18 * omdxx[1] + 9 * omdxx[2] + 6 * omdxx[30] -
2599                          18 * omdxx[31] + 3 * omdxx[32] + 6 * omdxx[33] - 9 * omdxx[34] +
2600                          6 * omdxx[35] + 6 * omdxx[36] - 18 * omdxx[37] + 3 * omdxx[38] +
2601                          6 * omdxx[39] - 9 * omdxx[40] + 6 * omdxx[41] + 6 * omdxx[42] +
2602                          6 * omdxx[43] + 6 * omdxx[44];
2603         phidxx[p45[3]] = +9 * omdxx[3] - 18 * omdxx[4] + 3 * omdxx[5] - 27 * omdxx[24] +
2604                          12 * omdxx[25] + 9 * omdxx[26] + 9 * omdxx[27] - 6 * omdxx[28] -
2605                          6 * omdxx[29] + 9 * omdxx[36] - 6 * omdxx[37] - 6 * omdxx[38] -
2606                          27 * omdxx[39] + 9 * omdxx[40] + 12 * omdxx[41] - 6 * omdxx[42] +
2607                          18 * omdxx[43] - 6 * omdxx[44];
2608         phidxx[p45[4]] = -18 * omdxx[3] + 84 * omdxx[4] - 18 * omdxx[5] - 6 * omdxx[24] -
2609                          36 * omdxx[25] + 12 * omdxx[26] - 30 * omdxx[27] + 30 * omdxx[28] -
2610                          30 * omdxx[36] + 30 * omdxx[38] - 6 * omdxx[39] + 12 * omdxx[40] -
2611                          36 * omdxx[41] + 24 * omdxx[43];
2612         phidxx[p45[5]] = +3 * omdxx[3] - 18 * omdxx[4] + 9 * omdxx[5] + 6 * omdxx[24] -
2613                          18 * omdxx[25] + 3 * omdxx[26] + 6 * omdxx[27] - 9 * omdxx[28] +
2614                          6 * omdxx[29] + 6 * omdxx[36] + 6 * omdxx[37] - 9 * omdxx[38] +
2615                          6 * omdxx[39] + 3 * omdxx[40] - 18 * omdxx[41] + 6 * omdxx[42] +
2616                          6 * omdxx[43] + 6 * omdxx[44];
2617         phidxx[p45[6]] = +9 * omdxx[6] - 18 * omdxx[7] + 3 * omdxx[8] + 9 * omdxx[24] -
2618                          6 * omdxx[25] - 6 * omdxx[26] - 27 * omdxx[27] + 9 * omdxx[28] +
2619                          12 * omdxx[29] + 9 * omdxx[30] - 6 * omdxx[31] - 6 * omdxx[32] -
2620                          27 * omdxx[33] + 9 * omdxx[34] + 12 * omdxx[35] - 6 * omdxx[42] -
2621                          6 * omdxx[43] + 18 * omdxx[44];
2622         phidxx[p45[7]] = -18 * omdxx[6] + 84 * omdxx[7] - 18 * omdxx[8] - 30 * omdxx[24] +
2623                          30 * omdxx[26] - 6 * omdxx[27] + 12 * omdxx[28] - 36 * omdxx[29] -
2624                          30 * omdxx[30] + 30 * omdxx[32] - 6 * omdxx[33] + 12 * omdxx[34] -
2625                          36 * omdxx[35] + 24 * omdxx[44];
2626         phidxx[p45[8]] = +3 * omdxx[6] - 18 * omdxx[7] + 9 * omdxx[8] + 6 * omdxx[24] +
2627                          6 * omdxx[25] - 9 * omdxx[26] + 6 * omdxx[27] + 3 * omdxx[28] -
2628                          18 * omdxx[29] + 6 * omdxx[30] + 6 * omdxx[31] - 9 * omdxx[32] +
2629                          6 * omdxx[33] + 3 * omdxx[34] - 18 * omdxx[35] + 6 * omdxx[42] +
2630                          6 * omdxx[43] + 6 * omdxx[44];
2631         phidxx[p45[9]] = +9 * omdxx[9] - 18 * omdxx[10] + 3 * omdxx[11] - 27 * omdxx[18] +
2632                          12 * omdxx[19] + 9 * omdxx[20] + 9 * omdxx[21] - 6 * omdxx[22] -
2633                          6 * omdxx[23] - 3 * omdxx[36] + 18 * omdxx[37] - 6 * omdxx[38] +
2634                          9 * omdxx[39] - 27 * omdxx[40] + 12 * omdxx[41] - 6 * omdxx[42] +
2635                          18 * omdxx[43] - 6 * omdxx[44];
2636         phidxx[p45[10]] = -18 * omdxx[9] + 84 * omdxx[10] - 18 * omdxx[11] - 6 * omdxx[18] -
2637                           36 * omdxx[19] + 12 * omdxx[20] - 30 * omdxx[21] + 30 * omdxx[22] -
2638                           12 * omdxx[36] + 36 * omdxx[37] + 6 * omdxx[38] + 12 * omdxx[39] -
2639                           6 * omdxx[40] - 36 * omdxx[41] - 24 * omdxx[42] + 24 * omdxx[43];
2640         phidxx[p45[11]] = +3 * omdxx[9] - 18 * omdxx[10] + 9 * omdxx[11] + 6 * omdxx[18] -
2641                           18 * omdxx[19] + 3 * omdxx[20] + 6 * omdxx[21] - 9 * omdxx[22] +
2642                           6 * omdxx[23] - 9 * omdxx[36] - 12 * omdxx[37] + 27 * omdxx[38] +
2643                           3 * omdxx[39] + 6 * omdxx[40] - 18 * omdxx[41] - 18 * omdxx[42] +
2644                           6 * omdxx[43] + 6 * omdxx[44];
2645         phidxx[p45[12]] = +9 * omdxx[12] - 18 * omdxx[13] + 3 * omdxx[14] + 9 * omdxx[18] -
2646                           6 * omdxx[19] - 6 * omdxx[20] - 27 * omdxx[21] + 9 * omdxx[22] +
2647                           12 * omdxx[23] - 3 * omdxx[30] + 18 * omdxx[31] - 6 * omdxx[32] +
2648                           9 * omdxx[33] - 27 * omdxx[34] + 12 * omdxx[35] - 6 * omdxx[42] -
2649                           6 * omdxx[43] + 18 * omdxx[44];
2650         phidxx[p45[13]] = -18 * omdxx[12] + 84 * omdxx[13] - 18 * omdxx[14] - 30 * omdxx[18] +
2651                           30 * omdxx[20] - 6 * omdxx[21] + 12 * omdxx[22] - 36 * omdxx[23] -
2652                           12 * omdxx[30] + 36 * omdxx[31] + 6 * omdxx[32] + 12 * omdxx[33] -
2653                           6 * omdxx[34] - 36 * omdxx[35] - 24 * omdxx[42] + 24 * omdxx[44];
2654         phidxx[p45[14]] = +3 * omdxx[12] - 18 * omdxx[13] + 9 * omdxx[14] + 6 * omdxx[18] +
2655                           6 * omdxx[19] - 9 * omdxx[20] + 6 * omdxx[21] + 3 * omdxx[22] -
2656                           18 * omdxx[23] - 9 * omdxx[30] - 12 * omdxx[31] + 27 * omdxx[32] +
2657                           3 * omdxx[33] + 6 * omdxx[34] - 18 * omdxx[35] - 18 * omdxx[42] +
2658                           6 * omdxx[43] + 6 * omdxx[44];
2659         phidxx[p45[15]] = +9 * omdxx[15] - 18 * omdxx[16] + 3 * omdxx[17] - 3 * omdxx[18] +
2660                           18 * omdxx[19] - 6 * omdxx[20] + 9 * omdxx[21] - 27 * omdxx[22] +
2661                           12 * omdxx[23] - 3 * omdxx[24] + 18 * omdxx[25] - 6 * omdxx[26] +
2662                           9 * omdxx[27] - 27 * omdxx[28] + 12 * omdxx[29] - 6 * omdxx[42] -
2663                           6 * omdxx[43] + 18 * omdxx[44];
2664         phidxx[p45[16]] = -18 * omdxx[15] + 84 * omdxx[16] - 18 * omdxx[17] - 12 * omdxx[18] +
2665                           36 * omdxx[19] + 6 * omdxx[20] + 12 * omdxx[21] - 6 * omdxx[22] -
2666                           36 * omdxx[23] - 12 * omdxx[24] + 36 * omdxx[25] + 6 * omdxx[26] +
2667                           12 * omdxx[27] - 6 * omdxx[28] - 36 * omdxx[29] - 24 * omdxx[43] +
2668                           24 * omdxx[44];
2669         phidxx[p45[17]] = +3 * omdxx[15] - 18 * omdxx[16] + 9 * omdxx[17] - 9 * omdxx[18] -
2670                           12 * omdxx[19] + 27 * omdxx[20] + 3 * omdxx[21] + 6 * omdxx[22] -
2671                           18 * omdxx[23] - 9 * omdxx[24] - 12 * omdxx[25] + 27 * omdxx[26] +
2672                           3 * omdxx[27] + 6 * omdxx[28] - 18 * omdxx[29] + 6 * omdxx[42] -
2673                           18 * omdxx[43] + 6 * omdxx[44];
2674         phidxx[p45[18]] = +90 * omdxx[18] - 30 * omdxx[19] - 45 * omdxx[20] - 30 * omdxx[21] +
2675                           15 * omdxx[22] + 30 * omdxx[23] + 15 * omdxx[42] - 45 * omdxx[43] +
2676                           15 * omdxx[44];
2677         phidxx[p45[19]] = -30 * omdxx[18] + 120 * omdxx[19] - 30 * omdxx[20] + 30 * omdxx[21] -
2678                           60 * omdxx[22] + 30 * omdxx[42] - 30 * omdxx[43] + 30 * omdxx[44];
2679         phidxx[p45[20]] = -45 * omdxx[18] - 30 * omdxx[19] + 90 * omdxx[20] + 15 * omdxx[21] +
2680                           15 * omdxx[22] - 60 * omdxx[23] + 15 * omdxx[42] - 45 * omdxx[43] +
2681                           15 * omdxx[44];
2682         phidxx[p45[21]] = -30 * omdxx[18] + 30 * omdxx[19] + 15 * omdxx[20] + 90 * omdxx[21] -
2683                           45 * omdxx[22] - 30 * omdxx[23] + 15 * omdxx[42] + 15 * omdxx[43] -
2684                           45 * omdxx[44];
2685         phidxx[p45[22]] = +15 * omdxx[18] - 60 * omdxx[19] + 15 * omdxx[20] - 45 * omdxx[21] +
2686                           90 * omdxx[22] - 30 * omdxx[23] + 15 * omdxx[42] + 15 * omdxx[43] -
2687                           45 * omdxx[44];
2688         phidxx[p45[23]] = +30 * omdxx[18] - 60 * omdxx[20] - 30 * omdxx[21] - 30 * omdxx[22] +
2689                           120 * omdxx[23] + 30 * omdxx[42] + 30 * omdxx[43] - 30 * omdxx[44];
2690         phidxx[p45[24]] = +90 * omdxx[24] - 30 * omdxx[25] - 45 * omdxx[26] - 30 * omdxx[27] +
2691                           15 * omdxx[28] + 30 * omdxx[29] + 15 * omdxx[42] - 45 * omdxx[43] +
2692                           15 * omdxx[44];
2693         phidxx[p45[25]] = -30 * omdxx[24] + 120 * omdxx[25] - 30 * omdxx[26] + 30 * omdxx[27] -
2694                           60 * omdxx[28] - 30 * omdxx[42] - 30 * omdxx[43] + 30 * omdxx[44];
2695         phidxx[p45[26]] = -45 * omdxx[24] - 30 * omdxx[25] + 90 * omdxx[26] + 15 * omdxx[27] +
2696                           15 * omdxx[28] - 60 * omdxx[29] + 15 * omdxx[42] - 45 * omdxx[43] +
2697                           15 * omdxx[44];
2698         phidxx[p45[27]] = -30 * omdxx[24] + 30 * omdxx[25] + 15 * omdxx[26] + 90 * omdxx[27] -
2699                           45 * omdxx[28] - 30 * omdxx[29] + 15 * omdxx[42] + 15 * omdxx[43] -
2700                           45 * omdxx[44];
2701         phidxx[p45[28]] = +15 * omdxx[24] - 60 * omdxx[25] + 15 * omdxx[26] - 45 * omdxx[27] +
2702                           90 * omdxx[28] - 30 * omdxx[29] + 15 * omdxx[42] + 15 * omdxx[43] -
2703                           45 * omdxx[44];
2704         phidxx[p45[29]] = +30 * omdxx[24] - 60 * omdxx[26] - 30 * omdxx[27] - 30 * omdxx[28] +
2705                           120 * omdxx[29] - 30 * omdxx[42] + 30 * omdxx[43] - 30 * omdxx[44];
2706         phidxx[p45[30]] = +90 * omdxx[30] - 30 * omdxx[31] - 45 * omdxx[32] - 30 * omdxx[33] +
2707                           15 * omdxx[34] + 30 * omdxx[35] - 45 * omdxx[42] + 15 * omdxx[43] +
2708                           15 * omdxx[44];
2709         phidxx[p45[31]] = -30 * omdxx[30] + 120 * omdxx[31] - 30 * omdxx[32] + 30 * omdxx[33] -
2710                           60 * omdxx[34] - 30 * omdxx[42] - 30 * omdxx[43] + 30 * omdxx[44];
2711         phidxx[p45[32]] = -45 * omdxx[30] - 30 * omdxx[31] + 90 * omdxx[32] + 15 * omdxx[33] +
2712                           15 * omdxx[34] - 60 * omdxx[35] - 45 * omdxx[42] + 15 * omdxx[43] +
2713                           15 * omdxx[44];
2714         phidxx[p45[33]] = -30 * omdxx[30] + 30 * omdxx[31] + 15 * omdxx[32] + 90 * omdxx[33] -
2715                           45 * omdxx[34] - 30 * omdxx[35] + 15 * omdxx[42] + 15 * omdxx[43] -
2716                           45 * omdxx[44];
2717         phidxx[p45[34]] = +15 * omdxx[30] - 60 * omdxx[31] + 15 * omdxx[32] - 45 * omdxx[33] +
2718                           90 * omdxx[34] - 30 * omdxx[35] + 15 * omdxx[42] + 15 * omdxx[43] -
2719                           45 * omdxx[44];
2720         phidxx[p45[35]] = +30 * omdxx[30] - 60 * omdxx[32] - 30 * omdxx[33] - 30 * omdxx[34] +
2721                           120 * omdxx[35] + 30 * omdxx[42] - 30 * omdxx[43] - 30 * omdxx[44];
2722         phidxx[p45[36]] = +90 * omdxx[36] - 30 * omdxx[37] - 45 * omdxx[38] - 30 * omdxx[39] +
2723                           15 * omdxx[40] + 30 * omdxx[41] - 45 * omdxx[42] + 15 * omdxx[43] +
2724                           15 * omdxx[44];
2725         phidxx[p45[37]] = -30 * omdxx[36] + 120 * omdxx[37] - 30 * omdxx[38] + 30 * omdxx[39] -
2726                           60 * omdxx[40] - 30 * omdxx[42] + 30 * omdxx[43] - 30 * omdxx[44];
2727         phidxx[p45[38]] = -45 * omdxx[36] - 30 * omdxx[37] + 90 * omdxx[38] + 15 * omdxx[39] +
2728                           15 * omdxx[40] - 60 * omdxx[41] - 45 * omdxx[42] + 15 * omdxx[43] +
2729                           15 * omdxx[44];
2730         phidxx[p45[39]] = -30 * omdxx[36] + 30 * omdxx[37] + 15 * omdxx[38] + 90 * omdxx[39] -
2731                           45 * omdxx[40] - 30 * omdxx[41] + 15 * omdxx[42] - 45 * omdxx[43] +
2732                           15 * omdxx[44];
2733         phidxx[p45[40]] = +15 * omdxx[36] - 60 * omdxx[37] + 15 * omdxx[38] - 45 * omdxx[39] +
2734                           90 * omdxx[40] - 30 * omdxx[41] + 15 * omdxx[42] - 45 * omdxx[43] +
2735                           15 * omdxx[44];
2736         phidxx[p45[41]] = +30 * omdxx[36] - 60 * omdxx[38] - 30 * omdxx[39] - 30 * omdxx[40] +
2737                           120 * omdxx[41] + 30 * omdxx[42] - 30 * omdxx[43] - 30 * omdxx[44];
2738         phidxx[p45[42]] = +90 * omdxx[42] - 30 * omdxx[43] - 30 * omdxx[44];
2739         phidxx[p45[43]] = -30 * omdxx[42] + 90 * omdxx[43] - 30 * omdxx[44];
2740         phidxx[p45[44]] = -30 * omdxx[42] - 30 * omdxx[43] + 90 * omdxx[44];
2741 
2742         for (int k = 0; k < 45; ++k) {
2743           val(k, 0, op_dxx) = phidxx[k].x;
2744           val(k, 1, op_dxx) = phidxx[k].y;
2745           val(k, 2, op_dxx) = phidxx[k].z;
2746         }
2747       }
2748 
2749       R3 phidyy[45];
2750       if (whatd & Fop_dyy) {
2751         phidyy[p45[0]] = +9 * omdyy[0] - 18 * omdyy[1] + 3 * omdyy[2] - 27 * omdyy[30] +
2752                          12 * omdyy[31] + 9 * omdyy[32] + 9 * omdyy[33] - 6 * omdyy[34] -
2753                          6 * omdyy[35] - 27 * omdyy[36] + 12 * omdyy[37] + 9 * omdyy[38] +
2754                          9 * omdyy[39] - 6 * omdyy[40] - 6 * omdyy[41] + 18 * omdyy[42] -
2755                          6 * omdyy[43] - 6 * omdyy[44];
2756         phidyy[p45[1]] = -18 * omdyy[0] + 84 * omdyy[1] - 18 * omdyy[2] - 6 * omdyy[30] -
2757                          36 * omdyy[31] + 12 * omdyy[32] - 30 * omdyy[33] + 30 * omdyy[34] -
2758                          6 * omdyy[36] - 36 * omdyy[37] + 12 * omdyy[38] - 30 * omdyy[39] +
2759                          30 * omdyy[40] + 24 * omdyy[42];
2760         phidyy[p45[2]] = +3 * omdyy[0] - 18 * omdyy[1] + 9 * omdyy[2] + 6 * omdyy[30] -
2761                          18 * omdyy[31] + 3 * omdyy[32] + 6 * omdyy[33] - 9 * omdyy[34] +
2762                          6 * omdyy[35] + 6 * omdyy[36] - 18 * omdyy[37] + 3 * omdyy[38] +
2763                          6 * omdyy[39] - 9 * omdyy[40] + 6 * omdyy[41] + 6 * omdyy[42] +
2764                          6 * omdyy[43] + 6 * omdyy[44];
2765         phidyy[p45[3]] = +9 * omdyy[3] - 18 * omdyy[4] + 3 * omdyy[5] - 27 * omdyy[24] +
2766                          12 * omdyy[25] + 9 * omdyy[26] + 9 * omdyy[27] - 6 * omdyy[28] -
2767                          6 * omdyy[29] + 9 * omdyy[36] - 6 * omdyy[37] - 6 * omdyy[38] -
2768                          27 * omdyy[39] + 9 * omdyy[40] + 12 * omdyy[41] - 6 * omdyy[42] +
2769                          18 * omdyy[43] - 6 * omdyy[44];
2770         phidyy[p45[4]] = -18 * omdyy[3] + 84 * omdyy[4] - 18 * omdyy[5] - 6 * omdyy[24] -
2771                          36 * omdyy[25] + 12 * omdyy[26] - 30 * omdyy[27] + 30 * omdyy[28] -
2772                          30 * omdyy[36] + 30 * omdyy[38] - 6 * omdyy[39] + 12 * omdyy[40] -
2773                          36 * omdyy[41] + 24 * omdyy[43];
2774         phidyy[p45[5]] = +3 * omdyy[3] - 18 * omdyy[4] + 9 * omdyy[5] + 6 * omdyy[24] -
2775                          18 * omdyy[25] + 3 * omdyy[26] + 6 * omdyy[27] - 9 * omdyy[28] +
2776                          6 * omdyy[29] + 6 * omdyy[36] + 6 * omdyy[37] - 9 * omdyy[38] +
2777                          6 * omdyy[39] + 3 * omdyy[40] - 18 * omdyy[41] + 6 * omdyy[42] +
2778                          6 * omdyy[43] + 6 * omdyy[44];
2779         phidyy[p45[6]] = +9 * omdyy[6] - 18 * omdyy[7] + 3 * omdyy[8] + 9 * omdyy[24] -
2780                          6 * omdyy[25] - 6 * omdyy[26] - 27 * omdyy[27] + 9 * omdyy[28] +
2781                          12 * omdyy[29] + 9 * omdyy[30] - 6 * omdyy[31] - 6 * omdyy[32] -
2782                          27 * omdyy[33] + 9 * omdyy[34] + 12 * omdyy[35] - 6 * omdyy[42] -
2783                          6 * omdyy[43] + 18 * omdyy[44];
2784         phidyy[p45[7]] = -18 * omdyy[6] + 84 * omdyy[7] - 18 * omdyy[8] - 30 * omdyy[24] +
2785                          30 * omdyy[26] - 6 * omdyy[27] + 12 * omdyy[28] - 36 * omdyy[29] -
2786                          30 * omdyy[30] + 30 * omdyy[32] - 6 * omdyy[33] + 12 * omdyy[34] -
2787                          36 * omdyy[35] + 24 * omdyy[44];
2788         phidyy[p45[8]] = +3 * omdyy[6] - 18 * omdyy[7] + 9 * omdyy[8] + 6 * omdyy[24] +
2789                          6 * omdyy[25] - 9 * omdyy[26] + 6 * omdyy[27] + 3 * omdyy[28] -
2790                          18 * omdyy[29] + 6 * omdyy[30] + 6 * omdyy[31] - 9 * omdyy[32] +
2791                          6 * omdyy[33] + 3 * omdyy[34] - 18 * omdyy[35] + 6 * omdyy[42] +
2792                          6 * omdyy[43] + 6 * omdyy[44];
2793         phidyy[p45[9]] = +9 * omdyy[9] - 18 * omdyy[10] + 3 * omdyy[11] - 27 * omdyy[18] +
2794                          12 * omdyy[19] + 9 * omdyy[20] + 9 * omdyy[21] - 6 * omdyy[22] -
2795                          6 * omdyy[23] - 3 * omdyy[36] + 18 * omdyy[37] - 6 * omdyy[38] +
2796                          9 * omdyy[39] - 27 * omdyy[40] + 12 * omdyy[41] - 6 * omdyy[42] +
2797                          18 * omdyy[43] - 6 * omdyy[44];
2798         phidyy[p45[10]] = -18 * omdyy[9] + 84 * omdyy[10] - 18 * omdyy[11] - 6 * omdyy[18] -
2799                           36 * omdyy[19] + 12 * omdyy[20] - 30 * omdyy[21] + 30 * omdyy[22] -
2800                           12 * omdyy[36] + 36 * omdyy[37] + 6 * omdyy[38] + 12 * omdyy[39] -
2801                           6 * omdyy[40] - 36 * omdyy[41] - 24 * omdyy[42] + 24 * omdyy[43];
2802         phidyy[p45[11]] = +3 * omdyy[9] - 18 * omdyy[10] + 9 * omdyy[11] + 6 * omdyy[18] -
2803                           18 * omdyy[19] + 3 * omdyy[20] + 6 * omdyy[21] - 9 * omdyy[22] +
2804                           6 * omdyy[23] - 9 * omdyy[36] - 12 * omdyy[37] + 27 * omdyy[38] +
2805                           3 * omdyy[39] + 6 * omdyy[40] - 18 * omdyy[41] - 18 * omdyy[42] +
2806                           6 * omdyy[43] + 6 * omdyy[44];
2807         phidyy[p45[12]] = +9 * omdyy[12] - 18 * omdyy[13] + 3 * omdyy[14] + 9 * omdyy[18] -
2808                           6 * omdyy[19] - 6 * omdyy[20] - 27 * omdyy[21] + 9 * omdyy[22] +
2809                           12 * omdyy[23] - 3 * omdyy[30] + 18 * omdyy[31] - 6 * omdyy[32] +
2810                           9 * omdyy[33] - 27 * omdyy[34] + 12 * omdyy[35] - 6 * omdyy[42] -
2811                           6 * omdyy[43] + 18 * omdyy[44];
2812         phidyy[p45[13]] = -18 * omdyy[12] + 84 * omdyy[13] - 18 * omdyy[14] - 30 * omdyy[18] +
2813                           30 * omdyy[20] - 6 * omdyy[21] + 12 * omdyy[22] - 36 * omdyy[23] -
2814                           12 * omdyy[30] + 36 * omdyy[31] + 6 * omdyy[32] + 12 * omdyy[33] -
2815                           6 * omdyy[34] - 36 * omdyy[35] - 24 * omdyy[42] + 24 * omdyy[44];
2816         phidyy[p45[14]] = +3 * omdyy[12] - 18 * omdyy[13] + 9 * omdyy[14] + 6 * omdyy[18] +
2817                           6 * omdyy[19] - 9 * omdyy[20] + 6 * omdyy[21] + 3 * omdyy[22] -
2818                           18 * omdyy[23] - 9 * omdyy[30] - 12 * omdyy[31] + 27 * omdyy[32] +
2819                           3 * omdyy[33] + 6 * omdyy[34] - 18 * omdyy[35] - 18 * omdyy[42] +
2820                           6 * omdyy[43] + 6 * omdyy[44];
2821         phidyy[p45[15]] = +9 * omdyy[15] - 18 * omdyy[16] + 3 * omdyy[17] - 3 * omdyy[18] +
2822                           18 * omdyy[19] - 6 * omdyy[20] + 9 * omdyy[21] - 27 * omdyy[22] +
2823                           12 * omdyy[23] - 3 * omdyy[24] + 18 * omdyy[25] - 6 * omdyy[26] +
2824                           9 * omdyy[27] - 27 * omdyy[28] + 12 * omdyy[29] - 6 * omdyy[42] -
2825                           6 * omdyy[43] + 18 * omdyy[44];
2826         phidyy[p45[16]] = -18 * omdyy[15] + 84 * omdyy[16] - 18 * omdyy[17] - 12 * omdyy[18] +
2827                           36 * omdyy[19] + 6 * omdyy[20] + 12 * omdyy[21] - 6 * omdyy[22] -
2828                           36 * omdyy[23] - 12 * omdyy[24] + 36 * omdyy[25] + 6 * omdyy[26] +
2829                           12 * omdyy[27] - 6 * omdyy[28] - 36 * omdyy[29] - 24 * omdyy[43] +
2830                           24 * omdyy[44];
2831         phidyy[p45[17]] = +3 * omdyy[15] - 18 * omdyy[16] + 9 * omdyy[17] - 9 * omdyy[18] -
2832                           12 * omdyy[19] + 27 * omdyy[20] + 3 * omdyy[21] + 6 * omdyy[22] -
2833                           18 * omdyy[23] - 9 * omdyy[24] - 12 * omdyy[25] + 27 * omdyy[26] +
2834                           3 * omdyy[27] + 6 * omdyy[28] - 18 * omdyy[29] + 6 * omdyy[42] -
2835                           18 * omdyy[43] + 6 * omdyy[44];
2836         phidyy[p45[18]] = +90 * omdyy[18] - 30 * omdyy[19] - 45 * omdyy[20] - 30 * omdyy[21] +
2837                           15 * omdyy[22] + 30 * omdyy[23] + 15 * omdyy[42] - 45 * omdyy[43] +
2838                           15 * omdyy[44];
2839         phidyy[p45[19]] = -30 * omdyy[18] + 120 * omdyy[19] - 30 * omdyy[20] + 30 * omdyy[21] -
2840                           60 * omdyy[22] + 30 * omdyy[42] - 30 * omdyy[43] + 30 * omdyy[44];
2841         phidyy[p45[20]] = -45 * omdyy[18] - 30 * omdyy[19] + 90 * omdyy[20] + 15 * omdyy[21] +
2842                           15 * omdyy[22] - 60 * omdyy[23] + 15 * omdyy[42] - 45 * omdyy[43] +
2843                           15 * omdyy[44];
2844         phidyy[p45[21]] = -30 * omdyy[18] + 30 * omdyy[19] + 15 * omdyy[20] + 90 * omdyy[21] -
2845                           45 * omdyy[22] - 30 * omdyy[23] + 15 * omdyy[42] + 15 * omdyy[43] -
2846                           45 * omdyy[44];
2847         phidyy[p45[22]] = +15 * omdyy[18] - 60 * omdyy[19] + 15 * omdyy[20] - 45 * omdyy[21] +
2848                           90 * omdyy[22] - 30 * omdyy[23] + 15 * omdyy[42] + 15 * omdyy[43] -
2849                           45 * omdyy[44];
2850         phidyy[p45[23]] = +30 * omdyy[18] - 60 * omdyy[20] - 30 * omdyy[21] - 30 * omdyy[22] +
2851                           120 * omdyy[23] + 30 * omdyy[42] + 30 * omdyy[43] - 30 * omdyy[44];
2852         phidyy[p45[24]] = +90 * omdyy[24] - 30 * omdyy[25] - 45 * omdyy[26] - 30 * omdyy[27] +
2853                           15 * omdyy[28] + 30 * omdyy[29] + 15 * omdyy[42] - 45 * omdyy[43] +
2854                           15 * omdyy[44];
2855         phidyy[p45[25]] = -30 * omdyy[24] + 120 * omdyy[25] - 30 * omdyy[26] + 30 * omdyy[27] -
2856                           60 * omdyy[28] - 30 * omdyy[42] - 30 * omdyy[43] + 30 * omdyy[44];
2857         phidyy[p45[26]] = -45 * omdyy[24] - 30 * omdyy[25] + 90 * omdyy[26] + 15 * omdyy[27] +
2858                           15 * omdyy[28] - 60 * omdyy[29] + 15 * omdyy[42] - 45 * omdyy[43] +
2859                           15 * omdyy[44];
2860         phidyy[p45[27]] = -30 * omdyy[24] + 30 * omdyy[25] + 15 * omdyy[26] + 90 * omdyy[27] -
2861                           45 * omdyy[28] - 30 * omdyy[29] + 15 * omdyy[42] + 15 * omdyy[43] -
2862                           45 * omdyy[44];
2863         phidyy[p45[28]] = +15 * omdyy[24] - 60 * omdyy[25] + 15 * omdyy[26] - 45 * omdyy[27] +
2864                           90 * omdyy[28] - 30 * omdyy[29] + 15 * omdyy[42] + 15 * omdyy[43] -
2865                           45 * omdyy[44];
2866         phidyy[p45[29]] = +30 * omdyy[24] - 60 * omdyy[26] - 30 * omdyy[27] - 30 * omdyy[28] +
2867                           120 * omdyy[29] - 30 * omdyy[42] + 30 * omdyy[43] - 30 * omdyy[44];
2868         phidyy[p45[30]] = +90 * omdyy[30] - 30 * omdyy[31] - 45 * omdyy[32] - 30 * omdyy[33] +
2869                           15 * omdyy[34] + 30 * omdyy[35] - 45 * omdyy[42] + 15 * omdyy[43] +
2870                           15 * omdyy[44];
2871         phidyy[p45[31]] = -30 * omdyy[30] + 120 * omdyy[31] - 30 * omdyy[32] + 30 * omdyy[33] -
2872                           60 * omdyy[34] - 30 * omdyy[42] - 30 * omdyy[43] + 30 * omdyy[44];
2873         phidyy[p45[32]] = -45 * omdyy[30] - 30 * omdyy[31] + 90 * omdyy[32] + 15 * omdyy[33] +
2874                           15 * omdyy[34] - 60 * omdyy[35] - 45 * omdyy[42] + 15 * omdyy[43] +
2875                           15 * omdyy[44];
2876         phidyy[p45[33]] = -30 * omdyy[30] + 30 * omdyy[31] + 15 * omdyy[32] + 90 * omdyy[33] -
2877                           45 * omdyy[34] - 30 * omdyy[35] + 15 * omdyy[42] + 15 * omdyy[43] -
2878                           45 * omdyy[44];
2879         phidyy[p45[34]] = +15 * omdyy[30] - 60 * omdyy[31] + 15 * omdyy[32] - 45 * omdyy[33] +
2880                           90 * omdyy[34] - 30 * omdyy[35] + 15 * omdyy[42] + 15 * omdyy[43] -
2881                           45 * omdyy[44];
2882         phidyy[p45[35]] = +30 * omdyy[30] - 60 * omdyy[32] - 30 * omdyy[33] - 30 * omdyy[34] +
2883                           120 * omdyy[35] + 30 * omdyy[42] - 30 * omdyy[43] - 30 * omdyy[44];
2884         phidyy[p45[36]] = +90 * omdyy[36] - 30 * omdyy[37] - 45 * omdyy[38] - 30 * omdyy[39] +
2885                           15 * omdyy[40] + 30 * omdyy[41] - 45 * omdyy[42] + 15 * omdyy[43] +
2886                           15 * omdyy[44];
2887         phidyy[p45[37]] = -30 * omdyy[36] + 120 * omdyy[37] - 30 * omdyy[38] + 30 * omdyy[39] -
2888                           60 * omdyy[40] - 30 * omdyy[42] + 30 * omdyy[43] - 30 * omdyy[44];
2889         phidyy[p45[38]] = -45 * omdyy[36] - 30 * omdyy[37] + 90 * omdyy[38] + 15 * omdyy[39] +
2890                           15 * omdyy[40] - 60 * omdyy[41] - 45 * omdyy[42] + 15 * omdyy[43] +
2891                           15 * omdyy[44];
2892         phidyy[p45[39]] = -30 * omdyy[36] + 30 * omdyy[37] + 15 * omdyy[38] + 90 * omdyy[39] -
2893                           45 * omdyy[40] - 30 * omdyy[41] + 15 * omdyy[42] - 45 * omdyy[43] +
2894                           15 * omdyy[44];
2895         phidyy[p45[40]] = +15 * omdyy[36] - 60 * omdyy[37] + 15 * omdyy[38] - 45 * omdyy[39] +
2896                           90 * omdyy[40] - 30 * omdyy[41] + 15 * omdyy[42] - 45 * omdyy[43] +
2897                           15 * omdyy[44];
2898         phidyy[p45[41]] = +30 * omdyy[36] - 60 * omdyy[38] - 30 * omdyy[39] - 30 * omdyy[40] +
2899                           120 * omdyy[41] + 30 * omdyy[42] - 30 * omdyy[43] - 30 * omdyy[44];
2900         phidyy[p45[42]] = +90 * omdyy[42] - 30 * omdyy[43] - 30 * omdyy[44];
2901         phidyy[p45[43]] = -30 * omdyy[42] + 90 * omdyy[43] - 30 * omdyy[44];
2902         phidyy[p45[44]] = -30 * omdyy[42] - 30 * omdyy[43] + 90 * omdyy[44];
2903 
2904         for (int k = 0; k < 45; ++k) {
2905           val(k, 0, op_dyy) = phidyy[k].x;
2906           val(k, 1, op_dyy) = phidyy[k].y;
2907           val(k, 2, op_dyy) = phidyy[k].z;
2908         }
2909       }
2910 
2911       R3 phidzz[45];
2912       if (whatd & Fop_dzz) {
2913         phidzz[p45[0]] = +9 * omdzz[0] - 18 * omdzz[1] + 3 * omdzz[2] - 27 * omdzz[30] +
2914                          12 * omdzz[31] + 9 * omdzz[32] + 9 * omdzz[33] - 6 * omdzz[34] -
2915                          6 * omdzz[35] - 27 * omdzz[36] + 12 * omdzz[37] + 9 * omdzz[38] +
2916                          9 * omdzz[39] - 6 * omdzz[40] - 6 * omdzz[41] + 18 * omdzz[42] -
2917                          6 * omdzz[43] - 6 * omdzz[44];
2918         phidzz[p45[1]] = -18 * omdzz[0] + 84 * omdzz[1] - 18 * omdzz[2] - 6 * omdzz[30] -
2919                          36 * omdzz[31] + 12 * omdzz[32] - 30 * omdzz[33] + 30 * omdzz[34] -
2920                          6 * omdzz[36] - 36 * omdzz[37] + 12 * omdzz[38] - 30 * omdzz[39] +
2921                          30 * omdzz[40] + 24 * omdzz[42];
2922         phidzz[p45[2]] = +3 * omdzz[0] - 18 * omdzz[1] + 9 * omdzz[2] + 6 * omdzz[30] -
2923                          18 * omdzz[31] + 3 * omdzz[32] + 6 * omdzz[33] - 9 * omdzz[34] +
2924                          6 * omdzz[35] + 6 * omdzz[36] - 18 * omdzz[37] + 3 * omdzz[38] +
2925                          6 * omdzz[39] - 9 * omdzz[40] + 6 * omdzz[41] + 6 * omdzz[42] +
2926                          6 * omdzz[43] + 6 * omdzz[44];
2927         phidzz[p45[3]] = +9 * omdzz[3] - 18 * omdzz[4] + 3 * omdzz[5] - 27 * omdzz[24] +
2928                          12 * omdzz[25] + 9 * omdzz[26] + 9 * omdzz[27] - 6 * omdzz[28] -
2929                          6 * omdzz[29] + 9 * omdzz[36] - 6 * omdzz[37] - 6 * omdzz[38] -
2930                          27 * omdzz[39] + 9 * omdzz[40] + 12 * omdzz[41] - 6 * omdzz[42] +
2931                          18 * omdzz[43] - 6 * omdzz[44];
2932         phidzz[p45[4]] = -18 * omdzz[3] + 84 * omdzz[4] - 18 * omdzz[5] - 6 * omdzz[24] -
2933                          36 * omdzz[25] + 12 * omdzz[26] - 30 * omdzz[27] + 30 * omdzz[28] -
2934                          30 * omdzz[36] + 30 * omdzz[38] - 6 * omdzz[39] + 12 * omdzz[40] -
2935                          36 * omdzz[41] + 24 * omdzz[43];
2936         phidzz[p45[5]] = +3 * omdzz[3] - 18 * omdzz[4] + 9 * omdzz[5] + 6 * omdzz[24] -
2937                          18 * omdzz[25] + 3 * omdzz[26] + 6 * omdzz[27] - 9 * omdzz[28] +
2938                          6 * omdzz[29] + 6 * omdzz[36] + 6 * omdzz[37] - 9 * omdzz[38] +
2939                          6 * omdzz[39] + 3 * omdzz[40] - 18 * omdzz[41] + 6 * omdzz[42] +
2940                          6 * omdzz[43] + 6 * omdzz[44];
2941         phidzz[p45[6]] = +9 * omdzz[6] - 18 * omdzz[7] + 3 * omdzz[8] + 9 * omdzz[24] -
2942                          6 * omdzz[25] - 6 * omdzz[26] - 27 * omdzz[27] + 9 * omdzz[28] +
2943                          12 * omdzz[29] + 9 * omdzz[30] - 6 * omdzz[31] - 6 * omdzz[32] -
2944                          27 * omdzz[33] + 9 * omdzz[34] + 12 * omdzz[35] - 6 * omdzz[42] -
2945                          6 * omdzz[43] + 18 * omdzz[44];
2946         phidzz[p45[7]] = -18 * omdzz[6] + 84 * omdzz[7] - 18 * omdzz[8] - 30 * omdzz[24] +
2947                          30 * omdzz[26] - 6 * omdzz[27] + 12 * omdzz[28] - 36 * omdzz[29] -
2948                          30 * omdzz[30] + 30 * omdzz[32] - 6 * omdzz[33] + 12 * omdzz[34] -
2949                          36 * omdzz[35] + 24 * omdzz[44];
2950         phidzz[p45[8]] = +3 * omdzz[6] - 18 * omdzz[7] + 9 * omdzz[8] + 6 * omdzz[24] +
2951                          6 * omdzz[25] - 9 * omdzz[26] + 6 * omdzz[27] + 3 * omdzz[28] -
2952                          18 * omdzz[29] + 6 * omdzz[30] + 6 * omdzz[31] - 9 * omdzz[32] +
2953                          6 * omdzz[33] + 3 * omdzz[34] - 18 * omdzz[35] + 6 * omdzz[42] +
2954                          6 * omdzz[43] + 6 * omdzz[44];
2955         phidzz[p45[9]] = +9 * omdzz[9] - 18 * omdzz[10] + 3 * omdzz[11] - 27 * omdzz[18] +
2956                          12 * omdzz[19] + 9 * omdzz[20] + 9 * omdzz[21] - 6 * omdzz[22] -
2957                          6 * omdzz[23] - 3 * omdzz[36] + 18 * omdzz[37] - 6 * omdzz[38] +
2958                          9 * omdzz[39] - 27 * omdzz[40] + 12 * omdzz[41] - 6 * omdzz[42] +
2959                          18 * omdzz[43] - 6 * omdzz[44];
2960         phidzz[p45[10]] = -18 * omdzz[9] + 84 * omdzz[10] - 18 * omdzz[11] - 6 * omdzz[18] -
2961                           36 * omdzz[19] + 12 * omdzz[20] - 30 * omdzz[21] + 30 * omdzz[22] -
2962                           12 * omdzz[36] + 36 * omdzz[37] + 6 * omdzz[38] + 12 * omdzz[39] -
2963                           6 * omdzz[40] - 36 * omdzz[41] - 24 * omdzz[42] + 24 * omdzz[43];
2964         phidzz[p45[11]] = +3 * omdzz[9] - 18 * omdzz[10] + 9 * omdzz[11] + 6 * omdzz[18] -
2965                           18 * omdzz[19] + 3 * omdzz[20] + 6 * omdzz[21] - 9 * omdzz[22] +
2966                           6 * omdzz[23] - 9 * omdzz[36] - 12 * omdzz[37] + 27 * omdzz[38] +
2967                           3 * omdzz[39] + 6 * omdzz[40] - 18 * omdzz[41] - 18 * omdzz[42] +
2968                           6 * omdzz[43] + 6 * omdzz[44];
2969         phidzz[p45[12]] = +9 * omdzz[12] - 18 * omdzz[13] + 3 * omdzz[14] + 9 * omdzz[18] -
2970                           6 * omdzz[19] - 6 * omdzz[20] - 27 * omdzz[21] + 9 * omdzz[22] +
2971                           12 * omdzz[23] - 3 * omdzz[30] + 18 * omdzz[31] - 6 * omdzz[32] +
2972                           9 * omdzz[33] - 27 * omdzz[34] + 12 * omdzz[35] - 6 * omdzz[42] -
2973                           6 * omdzz[43] + 18 * omdzz[44];
2974         phidzz[p45[13]] = -18 * omdzz[12] + 84 * omdzz[13] - 18 * omdzz[14] - 30 * omdzz[18] +
2975                           30 * omdzz[20] - 6 * omdzz[21] + 12 * omdzz[22] - 36 * omdzz[23] -
2976                           12 * omdzz[30] + 36 * omdzz[31] + 6 * omdzz[32] + 12 * omdzz[33] -
2977                           6 * omdzz[34] - 36 * omdzz[35] - 24 * omdzz[42] + 24 * omdzz[44];
2978         phidzz[p45[14]] = +3 * omdzz[12] - 18 * omdzz[13] + 9 * omdzz[14] + 6 * omdzz[18] +
2979                           6 * omdzz[19] - 9 * omdzz[20] + 6 * omdzz[21] + 3 * omdzz[22] -
2980                           18 * omdzz[23] - 9 * omdzz[30] - 12 * omdzz[31] + 27 * omdzz[32] +
2981                           3 * omdzz[33] + 6 * omdzz[34] - 18 * omdzz[35] - 18 * omdzz[42] +
2982                           6 * omdzz[43] + 6 * omdzz[44];
2983         phidzz[p45[15]] = +9 * omdzz[15] - 18 * omdzz[16] + 3 * omdzz[17] - 3 * omdzz[18] +
2984                           18 * omdzz[19] - 6 * omdzz[20] + 9 * omdzz[21] - 27 * omdzz[22] +
2985                           12 * omdzz[23] - 3 * omdzz[24] + 18 * omdzz[25] - 6 * omdzz[26] +
2986                           9 * omdzz[27] - 27 * omdzz[28] + 12 * omdzz[29] - 6 * omdzz[42] -
2987                           6 * omdzz[43] + 18 * omdzz[44];
2988         phidzz[p45[16]] = -18 * omdzz[15] + 84 * omdzz[16] - 18 * omdzz[17] - 12 * omdzz[18] +
2989                           36 * omdzz[19] + 6 * omdzz[20] + 12 * omdzz[21] - 6 * omdzz[22] -
2990                           36 * omdzz[23] - 12 * omdzz[24] + 36 * omdzz[25] + 6 * omdzz[26] +
2991                           12 * omdzz[27] - 6 * omdzz[28] - 36 * omdzz[29] - 24 * omdzz[43] +
2992                           24 * omdzz[44];
2993         phidzz[p45[17]] = +3 * omdzz[15] - 18 * omdzz[16] + 9 * omdzz[17] - 9 * omdzz[18] -
2994                           12 * omdzz[19] + 27 * omdzz[20] + 3 * omdzz[21] + 6 * omdzz[22] -
2995                           18 * omdzz[23] - 9 * omdzz[24] - 12 * omdzz[25] + 27 * omdzz[26] +
2996                           3 * omdzz[27] + 6 * omdzz[28] - 18 * omdzz[29] + 6 * omdzz[42] -
2997                           18 * omdzz[43] + 6 * omdzz[44];
2998         phidzz[p45[18]] = +90 * omdzz[18] - 30 * omdzz[19] - 45 * omdzz[20] - 30 * omdzz[21] +
2999                           15 * omdzz[22] + 30 * omdzz[23] + 15 * omdzz[42] - 45 * omdzz[43] +
3000                           15 * omdzz[44];
3001         phidzz[p45[19]] = -30 * omdzz[18] + 120 * omdzz[19] - 30 * omdzz[20] + 30 * omdzz[21] -
3002                           60 * omdzz[22] + 30 * omdzz[42] - 30 * omdzz[43] + 30 * omdzz[44];
3003         phidzz[p45[20]] = -45 * omdzz[18] - 30 * omdzz[19] + 90 * omdzz[20] + 15 * omdzz[21] +
3004                           15 * omdzz[22] - 60 * omdzz[23] + 15 * omdzz[42] - 45 * omdzz[43] +
3005                           15 * omdzz[44];
3006         phidzz[p45[21]] = -30 * omdzz[18] + 30 * omdzz[19] + 15 * omdzz[20] + 90 * omdzz[21] -
3007                           45 * omdzz[22] - 30 * omdzz[23] + 15 * omdzz[42] + 15 * omdzz[43] -
3008                           45 * omdzz[44];
3009         phidzz[p45[22]] = +15 * omdzz[18] - 60 * omdzz[19] + 15 * omdzz[20] - 45 * omdzz[21] +
3010                           90 * omdzz[22] - 30 * omdzz[23] + 15 * omdzz[42] + 15 * omdzz[43] -
3011                           45 * omdzz[44];
3012         phidzz[p45[23]] = +30 * omdzz[18] - 60 * omdzz[20] - 30 * omdzz[21] - 30 * omdzz[22] +
3013                           120 * omdzz[23] + 30 * omdzz[42] + 30 * omdzz[43] - 30 * omdzz[44];
3014         phidzz[p45[24]] = +90 * omdzz[24] - 30 * omdzz[25] - 45 * omdzz[26] - 30 * omdzz[27] +
3015                           15 * omdzz[28] + 30 * omdzz[29] + 15 * omdzz[42] - 45 * omdzz[43] +
3016                           15 * omdzz[44];
3017         phidzz[p45[25]] = -30 * omdzz[24] + 120 * omdzz[25] - 30 * omdzz[26] + 30 * omdzz[27] -
3018                           60 * omdzz[28] - 30 * omdzz[42] - 30 * omdzz[43] + 30 * omdzz[44];
3019         phidzz[p45[26]] = -45 * omdzz[24] - 30 * omdzz[25] + 90 * omdzz[26] + 15 * omdzz[27] +
3020                           15 * omdzz[28] - 60 * omdzz[29] + 15 * omdzz[42] - 45 * omdzz[43] +
3021                           15 * omdzz[44];
3022         phidzz[p45[27]] = -30 * omdzz[24] + 30 * omdzz[25] + 15 * omdzz[26] + 90 * omdzz[27] -
3023                           45 * omdzz[28] - 30 * omdzz[29] + 15 * omdzz[42] + 15 * omdzz[43] -
3024                           45 * omdzz[44];
3025         phidzz[p45[28]] = +15 * omdzz[24] - 60 * omdzz[25] + 15 * omdzz[26] - 45 * omdzz[27] +
3026                           90 * omdzz[28] - 30 * omdzz[29] + 15 * omdzz[42] + 15 * omdzz[43] -
3027                           45 * omdzz[44];
3028         phidzz[p45[29]] = +30 * omdzz[24] - 60 * omdzz[26] - 30 * omdzz[27] - 30 * omdzz[28] +
3029                           120 * omdzz[29] - 30 * omdzz[42] + 30 * omdzz[43] - 30 * omdzz[44];
3030         phidzz[p45[30]] = +90 * omdzz[30] - 30 * omdzz[31] - 45 * omdzz[32] - 30 * omdzz[33] +
3031                           15 * omdzz[34] + 30 * omdzz[35] - 45 * omdzz[42] + 15 * omdzz[43] +
3032                           15 * omdzz[44];
3033         phidzz[p45[31]] = -30 * omdzz[30] + 120 * omdzz[31] - 30 * omdzz[32] + 30 * omdzz[33] -
3034                           60 * omdzz[34] - 30 * omdzz[42] - 30 * omdzz[43] + 30 * omdzz[44];
3035         phidzz[p45[32]] = -45 * omdzz[30] - 30 * omdzz[31] + 90 * omdzz[32] + 15 * omdzz[33] +
3036                           15 * omdzz[34] - 60 * omdzz[35] - 45 * omdzz[42] + 15 * omdzz[43] +
3037                           15 * omdzz[44];
3038         phidzz[p45[33]] = -30 * omdzz[30] + 30 * omdzz[31] + 15 * omdzz[32] + 90 * omdzz[33] -
3039                           45 * omdzz[34] - 30 * omdzz[35] + 15 * omdzz[42] + 15 * omdzz[43] -
3040                           45 * omdzz[44];
3041         phidzz[p45[34]] = +15 * omdzz[30] - 60 * omdzz[31] + 15 * omdzz[32] - 45 * omdzz[33] +
3042                           90 * omdzz[34] - 30 * omdzz[35] + 15 * omdzz[42] + 15 * omdzz[43] -
3043                           45 * omdzz[44];
3044         phidzz[p45[35]] = +30 * omdzz[30] - 60 * omdzz[32] - 30 * omdzz[33] - 30 * omdzz[34] +
3045                           120 * omdzz[35] + 30 * omdzz[42] - 30 * omdzz[43] - 30 * omdzz[44];
3046         phidzz[p45[36]] = +90 * omdzz[36] - 30 * omdzz[37] - 45 * omdzz[38] - 30 * omdzz[39] +
3047                           15 * omdzz[40] + 30 * omdzz[41] - 45 * omdzz[42] + 15 * omdzz[43] +
3048                           15 * omdzz[44];
3049         phidzz[p45[37]] = -30 * omdzz[36] + 120 * omdzz[37] - 30 * omdzz[38] + 30 * omdzz[39] -
3050                           60 * omdzz[40] - 30 * omdzz[42] + 30 * omdzz[43] - 30 * omdzz[44];
3051         phidzz[p45[38]] = -45 * omdzz[36] - 30 * omdzz[37] + 90 * omdzz[38] + 15 * omdzz[39] +
3052                           15 * omdzz[40] - 60 * omdzz[41] - 45 * omdzz[42] + 15 * omdzz[43] +
3053                           15 * omdzz[44];
3054         phidzz[p45[39]] = -30 * omdzz[36] + 30 * omdzz[37] + 15 * omdzz[38] + 90 * omdzz[39] -
3055                           45 * omdzz[40] - 30 * omdzz[41] + 15 * omdzz[42] - 45 * omdzz[43] +
3056                           15 * omdzz[44];
3057         phidzz[p45[40]] = +15 * omdzz[36] - 60 * omdzz[37] + 15 * omdzz[38] - 45 * omdzz[39] +
3058                           90 * omdzz[40] - 30 * omdzz[41] + 15 * omdzz[42] - 45 * omdzz[43] +
3059                           15 * omdzz[44];
3060         phidzz[p45[41]] = +30 * omdzz[36] - 60 * omdzz[38] - 30 * omdzz[39] - 30 * omdzz[40] +
3061                           120 * omdzz[41] + 30 * omdzz[42] - 30 * omdzz[43] - 30 * omdzz[44];
3062         phidzz[p45[42]] = +90 * omdzz[42] - 30 * omdzz[43] - 30 * omdzz[44];
3063         phidzz[p45[43]] = -30 * omdzz[42] + 90 * omdzz[43] - 30 * omdzz[44];
3064         phidzz[p45[44]] = -30 * omdzz[42] - 30 * omdzz[43] + 90 * omdzz[44];
3065 
3066         for (int k = 0; k < 45; ++k) {
3067           val(k, 0, op_dzz) = phidzz[k].x;
3068           val(k, 1, op_dzz) = phidzz[k].y;
3069           val(k, 2, op_dzz) = phidzz[k].z;
3070         }
3071       }
3072 
3073       R3 phidxy[45];
3074       if (whatd & Fop_dxy) {
3075         phidxy[p45[0]] = +9 * omdxy[0] - 18 * omdxy[1] + 3 * omdxy[2] - 27 * omdxy[30] +
3076                          12 * omdxy[31] + 9 * omdxy[32] + 9 * omdxy[33] - 6 * omdxy[34] -
3077                          6 * omdxy[35] - 27 * omdxy[36] + 12 * omdxy[37] + 9 * omdxy[38] +
3078                          9 * omdxy[39] - 6 * omdxy[40] - 6 * omdxy[41] + 18 * omdxy[42] -
3079                          6 * omdxy[43] - 6 * omdxy[44];
3080         phidxy[p45[1]] = -18 * omdxy[0] + 84 * omdxy[1] - 18 * omdxy[2] - 6 * omdxy[30] -
3081                          36 * omdxy[31] + 12 * omdxy[32] - 30 * omdxy[33] + 30 * omdxy[34] -
3082                          6 * omdxy[36] - 36 * omdxy[37] + 12 * omdxy[38] - 30 * omdxy[39] +
3083                          30 * omdxy[40] + 24 * omdxy[42];
3084         phidxy[p45[2]] = +3 * omdxy[0] - 18 * omdxy[1] + 9 * omdxy[2] + 6 * omdxy[30] -
3085                          18 * omdxy[31] + 3 * omdxy[32] + 6 * omdxy[33] - 9 * omdxy[34] +
3086                          6 * omdxy[35] + 6 * omdxy[36] - 18 * omdxy[37] + 3 * omdxy[38] +
3087                          6 * omdxy[39] - 9 * omdxy[40] + 6 * omdxy[41] + 6 * omdxy[42] +
3088                          6 * omdxy[43] + 6 * omdxy[44];
3089         phidxy[p45[3]] = +9 * omdxy[3] - 18 * omdxy[4] + 3 * omdxy[5] - 27 * omdxy[24] +
3090                          12 * omdxy[25] + 9 * omdxy[26] + 9 * omdxy[27] - 6 * omdxy[28] -
3091                          6 * omdxy[29] + 9 * omdxy[36] - 6 * omdxy[37] - 6 * omdxy[38] -
3092                          27 * omdxy[39] + 9 * omdxy[40] + 12 * omdxy[41] - 6 * omdxy[42] +
3093                          18 * omdxy[43] - 6 * omdxy[44];
3094         phidxy[p45[4]] = -18 * omdxy[3] + 84 * omdxy[4] - 18 * omdxy[5] - 6 * omdxy[24] -
3095                          36 * omdxy[25] + 12 * omdxy[26] - 30 * omdxy[27] + 30 * omdxy[28] -
3096                          30 * omdxy[36] + 30 * omdxy[38] - 6 * omdxy[39] + 12 * omdxy[40] -
3097                          36 * omdxy[41] + 24 * omdxy[43];
3098         phidxy[p45[5]] = +3 * omdxy[3] - 18 * omdxy[4] + 9 * omdxy[5] + 6 * omdxy[24] -
3099                          18 * omdxy[25] + 3 * omdxy[26] + 6 * omdxy[27] - 9 * omdxy[28] +
3100                          6 * omdxy[29] + 6 * omdxy[36] + 6 * omdxy[37] - 9 * omdxy[38] +
3101                          6 * omdxy[39] + 3 * omdxy[40] - 18 * omdxy[41] + 6 * omdxy[42] +
3102                          6 * omdxy[43] + 6 * omdxy[44];
3103         phidxy[p45[6]] = +9 * omdxy[6] - 18 * omdxy[7] + 3 * omdxy[8] + 9 * omdxy[24] -
3104                          6 * omdxy[25] - 6 * omdxy[26] - 27 * omdxy[27] + 9 * omdxy[28] +
3105                          12 * omdxy[29] + 9 * omdxy[30] - 6 * omdxy[31] - 6 * omdxy[32] -
3106                          27 * omdxy[33] + 9 * omdxy[34] + 12 * omdxy[35] - 6 * omdxy[42] -
3107                          6 * omdxy[43] + 18 * omdxy[44];
3108         phidxy[p45[7]] = -18 * omdxy[6] + 84 * omdxy[7] - 18 * omdxy[8] - 30 * omdxy[24] +
3109                          30 * omdxy[26] - 6 * omdxy[27] + 12 * omdxy[28] - 36 * omdxy[29] -
3110                          30 * omdxy[30] + 30 * omdxy[32] - 6 * omdxy[33] + 12 * omdxy[34] -
3111                          36 * omdxy[35] + 24 * omdxy[44];
3112         phidxy[p45[8]] = +3 * omdxy[6] - 18 * omdxy[7] + 9 * omdxy[8] + 6 * omdxy[24] +
3113                          6 * omdxy[25] - 9 * omdxy[26] + 6 * omdxy[27] + 3 * omdxy[28] -
3114                          18 * omdxy[29] + 6 * omdxy[30] + 6 * omdxy[31] - 9 * omdxy[32] +
3115                          6 * omdxy[33] + 3 * omdxy[34] - 18 * omdxy[35] + 6 * omdxy[42] +
3116                          6 * omdxy[43] + 6 * omdxy[44];
3117         phidxy[p45[9]] = +9 * omdxy[9] - 18 * omdxy[10] + 3 * omdxy[11] - 27 * omdxy[18] +
3118                          12 * omdxy[19] + 9 * omdxy[20] + 9 * omdxy[21] - 6 * omdxy[22] -
3119                          6 * omdxy[23] - 3 * omdxy[36] + 18 * omdxy[37] - 6 * omdxy[38] +
3120                          9 * omdxy[39] - 27 * omdxy[40] + 12 * omdxy[41] - 6 * omdxy[42] +
3121                          18 * omdxy[43] - 6 * omdxy[44];
3122         phidxy[p45[10]] = -18 * omdxy[9] + 84 * omdxy[10] - 18 * omdxy[11] - 6 * omdxy[18] -
3123                           36 * omdxy[19] + 12 * omdxy[20] - 30 * omdxy[21] + 30 * omdxy[22] -
3124                           12 * omdxy[36] + 36 * omdxy[37] + 6 * omdxy[38] + 12 * omdxy[39] -
3125                           6 * omdxy[40] - 36 * omdxy[41] - 24 * omdxy[42] + 24 * omdxy[43];
3126         phidxy[p45[11]] = +3 * omdxy[9] - 18 * omdxy[10] + 9 * omdxy[11] + 6 * omdxy[18] -
3127                           18 * omdxy[19] + 3 * omdxy[20] + 6 * omdxy[21] - 9 * omdxy[22] +
3128                           6 * omdxy[23] - 9 * omdxy[36] - 12 * omdxy[37] + 27 * omdxy[38] +
3129                           3 * omdxy[39] + 6 * omdxy[40] - 18 * omdxy[41] - 18 * omdxy[42] +
3130                           6 * omdxy[43] + 6 * omdxy[44];
3131         phidxy[p45[12]] = +9 * omdxy[12] - 18 * omdxy[13] + 3 * omdxy[14] + 9 * omdxy[18] -
3132                           6 * omdxy[19] - 6 * omdxy[20] - 27 * omdxy[21] + 9 * omdxy[22] +
3133                           12 * omdxy[23] - 3 * omdxy[30] + 18 * omdxy[31] - 6 * omdxy[32] +
3134                           9 * omdxy[33] - 27 * omdxy[34] + 12 * omdxy[35] - 6 * omdxy[42] -
3135                           6 * omdxy[43] + 18 * omdxy[44];
3136         phidxy[p45[13]] = -18 * omdxy[12] + 84 * omdxy[13] - 18 * omdxy[14] - 30 * omdxy[18] +
3137                           30 * omdxy[20] - 6 * omdxy[21] + 12 * omdxy[22] - 36 * omdxy[23] -
3138                           12 * omdxy[30] + 36 * omdxy[31] + 6 * omdxy[32] + 12 * omdxy[33] -
3139                           6 * omdxy[34] - 36 * omdxy[35] - 24 * omdxy[42] + 24 * omdxy[44];
3140         phidxy[p45[14]] = +3 * omdxy[12] - 18 * omdxy[13] + 9 * omdxy[14] + 6 * omdxy[18] +
3141                           6 * omdxy[19] - 9 * omdxy[20] + 6 * omdxy[21] + 3 * omdxy[22] -
3142                           18 * omdxy[23] - 9 * omdxy[30] - 12 * omdxy[31] + 27 * omdxy[32] +
3143                           3 * omdxy[33] + 6 * omdxy[34] - 18 * omdxy[35] - 18 * omdxy[42] +
3144                           6 * omdxy[43] + 6 * omdxy[44];
3145         phidxy[p45[15]] = +9 * omdxy[15] - 18 * omdxy[16] + 3 * omdxy[17] - 3 * omdxy[18] +
3146                           18 * omdxy[19] - 6 * omdxy[20] + 9 * omdxy[21] - 27 * omdxy[22] +
3147                           12 * omdxy[23] - 3 * omdxy[24] + 18 * omdxy[25] - 6 * omdxy[26] +
3148                           9 * omdxy[27] - 27 * omdxy[28] + 12 * omdxy[29] - 6 * omdxy[42] -
3149                           6 * omdxy[43] + 18 * omdxy[44];
3150         phidxy[p45[16]] = -18 * omdxy[15] + 84 * omdxy[16] - 18 * omdxy[17] - 12 * omdxy[18] +
3151                           36 * omdxy[19] + 6 * omdxy[20] + 12 * omdxy[21] - 6 * omdxy[22] -
3152                           36 * omdxy[23] - 12 * omdxy[24] + 36 * omdxy[25] + 6 * omdxy[26] +
3153                           12 * omdxy[27] - 6 * omdxy[28] - 36 * omdxy[29] - 24 * omdxy[43] +
3154                           24 * omdxy[44];
3155         phidxy[p45[17]] = +3 * omdxy[15] - 18 * omdxy[16] + 9 * omdxy[17] - 9 * omdxy[18] -
3156                           12 * omdxy[19] + 27 * omdxy[20] + 3 * omdxy[21] + 6 * omdxy[22] -
3157                           18 * omdxy[23] - 9 * omdxy[24] - 12 * omdxy[25] + 27 * omdxy[26] +
3158                           3 * omdxy[27] + 6 * omdxy[28] - 18 * omdxy[29] + 6 * omdxy[42] -
3159                           18 * omdxy[43] + 6 * omdxy[44];
3160         phidxy[p45[18]] = +90 * omdxy[18] - 30 * omdxy[19] - 45 * omdxy[20] - 30 * omdxy[21] +
3161                           15 * omdxy[22] + 30 * omdxy[23] + 15 * omdxy[42] - 45 * omdxy[43] +
3162                           15 * omdxy[44];
3163         phidxy[p45[19]] = -30 * omdxy[18] + 120 * omdxy[19] - 30 * omdxy[20] + 30 * omdxy[21] -
3164                           60 * omdxy[22] + 30 * omdxy[42] - 30 * omdxy[43] + 30 * omdxy[44];
3165         phidxy[p45[20]] = -45 * omdxy[18] - 30 * omdxy[19] + 90 * omdxy[20] + 15 * omdxy[21] +
3166                           15 * omdxy[22] - 60 * omdxy[23] + 15 * omdxy[42] - 45 * omdxy[43] +
3167                           15 * omdxy[44];
3168         phidxy[p45[21]] = -30 * omdxy[18] + 30 * omdxy[19] + 15 * omdxy[20] + 90 * omdxy[21] -
3169                           45 * omdxy[22] - 30 * omdxy[23] + 15 * omdxy[42] + 15 * omdxy[43] -
3170                           45 * omdxy[44];
3171         phidxy[p45[22]] = +15 * omdxy[18] - 60 * omdxy[19] + 15 * omdxy[20] - 45 * omdxy[21] +
3172                           90 * omdxy[22] - 30 * omdxy[23] + 15 * omdxy[42] + 15 * omdxy[43] -
3173                           45 * omdxy[44];
3174         phidxy[p45[23]] = +30 * omdxy[18] - 60 * omdxy[20] - 30 * omdxy[21] - 30 * omdxy[22] +
3175                           120 * omdxy[23] + 30 * omdxy[42] + 30 * omdxy[43] - 30 * omdxy[44];
3176         phidxy[p45[24]] = +90 * omdxy[24] - 30 * omdxy[25] - 45 * omdxy[26] - 30 * omdxy[27] +
3177                           15 * omdxy[28] + 30 * omdxy[29] + 15 * omdxy[42] - 45 * omdxy[43] +
3178                           15 * omdxy[44];
3179         phidxy[p45[25]] = -30 * omdxy[24] + 120 * omdxy[25] - 30 * omdxy[26] + 30 * omdxy[27] -
3180                           60 * omdxy[28] - 30 * omdxy[42] - 30 * omdxy[43] + 30 * omdxy[44];
3181         phidxy[p45[26]] = -45 * omdxy[24] - 30 * omdxy[25] + 90 * omdxy[26] + 15 * omdxy[27] +
3182                           15 * omdxy[28] - 60 * omdxy[29] + 15 * omdxy[42] - 45 * omdxy[43] +
3183                           15 * omdxy[44];
3184         phidxy[p45[27]] = -30 * omdxy[24] + 30 * omdxy[25] + 15 * omdxy[26] + 90 * omdxy[27] -
3185                           45 * omdxy[28] - 30 * omdxy[29] + 15 * omdxy[42] + 15 * omdxy[43] -
3186                           45 * omdxy[44];
3187         phidxy[p45[28]] = +15 * omdxy[24] - 60 * omdxy[25] + 15 * omdxy[26] - 45 * omdxy[27] +
3188                           90 * omdxy[28] - 30 * omdxy[29] + 15 * omdxy[42] + 15 * omdxy[43] -
3189                           45 * omdxy[44];
3190         phidxy[p45[29]] = +30 * omdxy[24] - 60 * omdxy[26] - 30 * omdxy[27] - 30 * omdxy[28] +
3191                           120 * omdxy[29] - 30 * omdxy[42] + 30 * omdxy[43] - 30 * omdxy[44];
3192         phidxy[p45[30]] = +90 * omdxy[30] - 30 * omdxy[31] - 45 * omdxy[32] - 30 * omdxy[33] +
3193                           15 * omdxy[34] + 30 * omdxy[35] - 45 * omdxy[42] + 15 * omdxy[43] +
3194                           15 * omdxy[44];
3195         phidxy[p45[31]] = -30 * omdxy[30] + 120 * omdxy[31] - 30 * omdxy[32] + 30 * omdxy[33] -
3196                           60 * omdxy[34] - 30 * omdxy[42] - 30 * omdxy[43] + 30 * omdxy[44];
3197         phidxy[p45[32]] = -45 * omdxy[30] - 30 * omdxy[31] + 90 * omdxy[32] + 15 * omdxy[33] +
3198                           15 * omdxy[34] - 60 * omdxy[35] - 45 * omdxy[42] + 15 * omdxy[43] +
3199                           15 * omdxy[44];
3200         phidxy[p45[33]] = -30 * omdxy[30] + 30 * omdxy[31] + 15 * omdxy[32] + 90 * omdxy[33] -
3201                           45 * omdxy[34] - 30 * omdxy[35] + 15 * omdxy[42] + 15 * omdxy[43] -
3202                           45 * omdxy[44];
3203         phidxy[p45[34]] = +15 * omdxy[30] - 60 * omdxy[31] + 15 * omdxy[32] - 45 * omdxy[33] +
3204                           90 * omdxy[34] - 30 * omdxy[35] + 15 * omdxy[42] + 15 * omdxy[43] -
3205                           45 * omdxy[44];
3206         phidxy[p45[35]] = +30 * omdxy[30] - 60 * omdxy[32] - 30 * omdxy[33] - 30 * omdxy[34] +
3207                           120 * omdxy[35] + 30 * omdxy[42] - 30 * omdxy[43] - 30 * omdxy[44];
3208         phidxy[p45[36]] = +90 * omdxy[36] - 30 * omdxy[37] - 45 * omdxy[38] - 30 * omdxy[39] +
3209                           15 * omdxy[40] + 30 * omdxy[41] - 45 * omdxy[42] + 15 * omdxy[43] +
3210                           15 * omdxy[44];
3211         phidxy[p45[37]] = -30 * omdxy[36] + 120 * omdxy[37] - 30 * omdxy[38] + 30 * omdxy[39] -
3212                           60 * omdxy[40] - 30 * omdxy[42] + 30 * omdxy[43] - 30 * omdxy[44];
3213         phidxy[p45[38]] = -45 * omdxy[36] - 30 * omdxy[37] + 90 * omdxy[38] + 15 * omdxy[39] +
3214                           15 * omdxy[40] - 60 * omdxy[41] - 45 * omdxy[42] + 15 * omdxy[43] +
3215                           15 * omdxy[44];
3216         phidxy[p45[39]] = -30 * omdxy[36] + 30 * omdxy[37] + 15 * omdxy[38] + 90 * omdxy[39] -
3217                           45 * omdxy[40] - 30 * omdxy[41] + 15 * omdxy[42] - 45 * omdxy[43] +
3218                           15 * omdxy[44];
3219         phidxy[p45[40]] = +15 * omdxy[36] - 60 * omdxy[37] + 15 * omdxy[38] - 45 * omdxy[39] +
3220                           90 * omdxy[40] - 30 * omdxy[41] + 15 * omdxy[42] - 45 * omdxy[43] +
3221                           15 * omdxy[44];
3222         phidxy[p45[41]] = +30 * omdxy[36] - 60 * omdxy[38] - 30 * omdxy[39] - 30 * omdxy[40] +
3223                           120 * omdxy[41] + 30 * omdxy[42] - 30 * omdxy[43] - 30 * omdxy[44];
3224         phidxy[p45[42]] = +90 * omdxy[42] - 30 * omdxy[43] - 30 * omdxy[44];
3225         phidxy[p45[43]] = -30 * omdxy[42] + 90 * omdxy[43] - 30 * omdxy[44];
3226         phidxy[p45[44]] = -30 * omdxy[42] - 30 * omdxy[43] + 90 * omdxy[44];
3227 
3228         for (int k = 0; k < 45; ++k) {
3229           val(k, 0, op_dxy) = phidxy[k].x;
3230           val(k, 1, op_dxy) = phidxy[k].y;
3231           val(k, 2, op_dxy) = phidxy[k].z;
3232         }
3233       }
3234 
3235       R3 phidxz[45];
3236       if (whatd & Fop_dxz) {
3237         phidxz[p45[0]] = +9 * omdxz[0] - 18 * omdxz[1] + 3 * omdxz[2] - 27 * omdxz[30] +
3238                          12 * omdxz[31] + 9 * omdxz[32] + 9 * omdxz[33] - 6 * omdxz[34] -
3239                          6 * omdxz[35] - 27 * omdxz[36] + 12 * omdxz[37] + 9 * omdxz[38] +
3240                          9 * omdxz[39] - 6 * omdxz[40] - 6 * omdxz[41] + 18 * omdxz[42] -
3241                          6 * omdxz[43] - 6 * omdxz[44];
3242         phidxz[p45[1]] = -18 * omdxz[0] + 84 * omdxz[1] - 18 * omdxz[2] - 6 * omdxz[30] -
3243                          36 * omdxz[31] + 12 * omdxz[32] - 30 * omdxz[33] + 30 * omdxz[34] -
3244                          6 * omdxz[36] - 36 * omdxz[37] + 12 * omdxz[38] - 30 * omdxz[39] +
3245                          30 * omdxz[40] + 24 * omdxz[42];
3246         phidxz[p45[2]] = +3 * omdxz[0] - 18 * omdxz[1] + 9 * omdxz[2] + 6 * omdxz[30] -
3247                          18 * omdxz[31] + 3 * omdxz[32] + 6 * omdxz[33] - 9 * omdxz[34] +
3248                          6 * omdxz[35] + 6 * omdxz[36] - 18 * omdxz[37] + 3 * omdxz[38] +
3249                          6 * omdxz[39] - 9 * omdxz[40] + 6 * omdxz[41] + 6 * omdxz[42] +
3250                          6 * omdxz[43] + 6 * omdxz[44];
3251         phidxz[p45[3]] = +9 * omdxz[3] - 18 * omdxz[4] + 3 * omdxz[5] - 27 * omdxz[24] +
3252                          12 * omdxz[25] + 9 * omdxz[26] + 9 * omdxz[27] - 6 * omdxz[28] -
3253                          6 * omdxz[29] + 9 * omdxz[36] - 6 * omdxz[37] - 6 * omdxz[38] -
3254                          27 * omdxz[39] + 9 * omdxz[40] + 12 * omdxz[41] - 6 * omdxz[42] +
3255                          18 * omdxz[43] - 6 * omdxz[44];
3256         phidxz[p45[4]] = -18 * omdxz[3] + 84 * omdxz[4] - 18 * omdxz[5] - 6 * omdxz[24] -
3257                          36 * omdxz[25] + 12 * omdxz[26] - 30 * omdxz[27] + 30 * omdxz[28] -
3258                          30 * omdxz[36] + 30 * omdxz[38] - 6 * omdxz[39] + 12 * omdxz[40] -
3259                          36 * omdxz[41] + 24 * omdxz[43];
3260         phidxz[p45[5]] = +3 * omdxz[3] - 18 * omdxz[4] + 9 * omdxz[5] + 6 * omdxz[24] -
3261                          18 * omdxz[25] + 3 * omdxz[26] + 6 * omdxz[27] - 9 * omdxz[28] +
3262                          6 * omdxz[29] + 6 * omdxz[36] + 6 * omdxz[37] - 9 * omdxz[38] +
3263                          6 * omdxz[39] + 3 * omdxz[40] - 18 * omdxz[41] + 6 * omdxz[42] +
3264                          6 * omdxz[43] + 6 * omdxz[44];
3265         phidxz[p45[6]] = +9 * omdxz[6] - 18 * omdxz[7] + 3 * omdxz[8] + 9 * omdxz[24] -
3266                          6 * omdxz[25] - 6 * omdxz[26] - 27 * omdxz[27] + 9 * omdxz[28] +
3267                          12 * omdxz[29] + 9 * omdxz[30] - 6 * omdxz[31] - 6 * omdxz[32] -
3268                          27 * omdxz[33] + 9 * omdxz[34] + 12 * omdxz[35] - 6 * omdxz[42] -
3269                          6 * omdxz[43] + 18 * omdxz[44];
3270         phidxz[p45[7]] = -18 * omdxz[6] + 84 * omdxz[7] - 18 * omdxz[8] - 30 * omdxz[24] +
3271                          30 * omdxz[26] - 6 * omdxz[27] + 12 * omdxz[28] - 36 * omdxz[29] -
3272                          30 * omdxz[30] + 30 * omdxz[32] - 6 * omdxz[33] + 12 * omdxz[34] -
3273                          36 * omdxz[35] + 24 * omdxz[44];
3274         phidxz[p45[8]] = +3 * omdxz[6] - 18 * omdxz[7] + 9 * omdxz[8] + 6 * omdxz[24] +
3275                          6 * omdxz[25] - 9 * omdxz[26] + 6 * omdxz[27] + 3 * omdxz[28] -
3276                          18 * omdxz[29] + 6 * omdxz[30] + 6 * omdxz[31] - 9 * omdxz[32] +
3277                          6 * omdxz[33] + 3 * omdxz[34] - 18 * omdxz[35] + 6 * omdxz[42] +
3278                          6 * omdxz[43] + 6 * omdxz[44];
3279         phidxz[p45[9]] = +9 * omdxz[9] - 18 * omdxz[10] + 3 * omdxz[11] - 27 * omdxz[18] +
3280                          12 * omdxz[19] + 9 * omdxz[20] + 9 * omdxz[21] - 6 * omdxz[22] -
3281                          6 * omdxz[23] - 3 * omdxz[36] + 18 * omdxz[37] - 6 * omdxz[38] +
3282                          9 * omdxz[39] - 27 * omdxz[40] + 12 * omdxz[41] - 6 * omdxz[42] +
3283                          18 * omdxz[43] - 6 * omdxz[44];
3284         phidxz[p45[10]] = -18 * omdxz[9] + 84 * omdxz[10] - 18 * omdxz[11] - 6 * omdxz[18] -
3285                           36 * omdxz[19] + 12 * omdxz[20] - 30 * omdxz[21] + 30 * omdxz[22] -
3286                           12 * omdxz[36] + 36 * omdxz[37] + 6 * omdxz[38] + 12 * omdxz[39] -
3287                           6 * omdxz[40] - 36 * omdxz[41] - 24 * omdxz[42] + 24 * omdxz[43];
3288         phidxz[p45[11]] = +3 * omdxz[9] - 18 * omdxz[10] + 9 * omdxz[11] + 6 * omdxz[18] -
3289                           18 * omdxz[19] + 3 * omdxz[20] + 6 * omdxz[21] - 9 * omdxz[22] +
3290                           6 * omdxz[23] - 9 * omdxz[36] - 12 * omdxz[37] + 27 * omdxz[38] +
3291                           3 * omdxz[39] + 6 * omdxz[40] - 18 * omdxz[41] - 18 * omdxz[42] +
3292                           6 * omdxz[43] + 6 * omdxz[44];
3293         phidxz[p45[12]] = +9 * omdxz[12] - 18 * omdxz[13] + 3 * omdxz[14] + 9 * omdxz[18] -
3294                           6 * omdxz[19] - 6 * omdxz[20] - 27 * omdxz[21] + 9 * omdxz[22] +
3295                           12 * omdxz[23] - 3 * omdxz[30] + 18 * omdxz[31] - 6 * omdxz[32] +
3296                           9 * omdxz[33] - 27 * omdxz[34] + 12 * omdxz[35] - 6 * omdxz[42] -
3297                           6 * omdxz[43] + 18 * omdxz[44];
3298         phidxz[p45[13]] = -18 * omdxz[12] + 84 * omdxz[13] - 18 * omdxz[14] - 30 * omdxz[18] +
3299                           30 * omdxz[20] - 6 * omdxz[21] + 12 * omdxz[22] - 36 * omdxz[23] -
3300                           12 * omdxz[30] + 36 * omdxz[31] + 6 * omdxz[32] + 12 * omdxz[33] -
3301                           6 * omdxz[34] - 36 * omdxz[35] - 24 * omdxz[42] + 24 * omdxz[44];
3302         phidxz[p45[14]] = +3 * omdxz[12] - 18 * omdxz[13] + 9 * omdxz[14] + 6 * omdxz[18] +
3303                           6 * omdxz[19] - 9 * omdxz[20] + 6 * omdxz[21] + 3 * omdxz[22] -
3304                           18 * omdxz[23] - 9 * omdxz[30] - 12 * omdxz[31] + 27 * omdxz[32] +
3305                           3 * omdxz[33] + 6 * omdxz[34] - 18 * omdxz[35] - 18 * omdxz[42] +
3306                           6 * omdxz[43] + 6 * omdxz[44];
3307         phidxz[p45[15]] = +9 * omdxz[15] - 18 * omdxz[16] + 3 * omdxz[17] - 3 * omdxz[18] +
3308                           18 * omdxz[19] - 6 * omdxz[20] + 9 * omdxz[21] - 27 * omdxz[22] +
3309                           12 * omdxz[23] - 3 * omdxz[24] + 18 * omdxz[25] - 6 * omdxz[26] +
3310                           9 * omdxz[27] - 27 * omdxz[28] + 12 * omdxz[29] - 6 * omdxz[42] -
3311                           6 * omdxz[43] + 18 * omdxz[44];
3312         phidxz[p45[16]] = -18 * omdxz[15] + 84 * omdxz[16] - 18 * omdxz[17] - 12 * omdxz[18] +
3313                           36 * omdxz[19] + 6 * omdxz[20] + 12 * omdxz[21] - 6 * omdxz[22] -
3314                           36 * omdxz[23] - 12 * omdxz[24] + 36 * omdxz[25] + 6 * omdxz[26] +
3315                           12 * omdxz[27] - 6 * omdxz[28] - 36 * omdxz[29] - 24 * omdxz[43] +
3316                           24 * omdxz[44];
3317         phidxz[p45[17]] = +3 * omdxz[15] - 18 * omdxz[16] + 9 * omdxz[17] - 9 * omdxz[18] -
3318                           12 * omdxz[19] + 27 * omdxz[20] + 3 * omdxz[21] + 6 * omdxz[22] -
3319                           18 * omdxz[23] - 9 * omdxz[24] - 12 * omdxz[25] + 27 * omdxz[26] +
3320                           3 * omdxz[27] + 6 * omdxz[28] - 18 * omdxz[29] + 6 * omdxz[42] -
3321                           18 * omdxz[43] + 6 * omdxz[44];
3322         phidxz[p45[18]] = +90 * omdxz[18] - 30 * omdxz[19] - 45 * omdxz[20] - 30 * omdxz[21] +
3323                           15 * omdxz[22] + 30 * omdxz[23] + 15 * omdxz[42] - 45 * omdxz[43] +
3324                           15 * omdxz[44];
3325         phidxz[p45[19]] = -30 * omdxz[18] + 120 * omdxz[19] - 30 * omdxz[20] + 30 * omdxz[21] -
3326                           60 * omdxz[22] + 30 * omdxz[42] - 30 * omdxz[43] + 30 * omdxz[44];
3327         phidxz[p45[20]] = -45 * omdxz[18] - 30 * omdxz[19] + 90 * omdxz[20] + 15 * omdxz[21] +
3328                           15 * omdxz[22] - 60 * omdxz[23] + 15 * omdxz[42] - 45 * omdxz[43] +
3329                           15 * omdxz[44];
3330         phidxz[p45[21]] = -30 * omdxz[18] + 30 * omdxz[19] + 15 * omdxz[20] + 90 * omdxz[21] -
3331                           45 * omdxz[22] - 30 * omdxz[23] + 15 * omdxz[42] + 15 * omdxz[43] -
3332                           45 * omdxz[44];
3333         phidxz[p45[22]] = +15 * omdxz[18] - 60 * omdxz[19] + 15 * omdxz[20] - 45 * omdxz[21] +
3334                           90 * omdxz[22] - 30 * omdxz[23] + 15 * omdxz[42] + 15 * omdxz[43] -
3335                           45 * omdxz[44];
3336         phidxz[p45[23]] = +30 * omdxz[18] - 60 * omdxz[20] - 30 * omdxz[21] - 30 * omdxz[22] +
3337                           120 * omdxz[23] + 30 * omdxz[42] + 30 * omdxz[43] - 30 * omdxz[44];
3338         phidxz[p45[24]] = +90 * omdxz[24] - 30 * omdxz[25] - 45 * omdxz[26] - 30 * omdxz[27] +
3339                           15 * omdxz[28] + 30 * omdxz[29] + 15 * omdxz[42] - 45 * omdxz[43] +
3340                           15 * omdxz[44];
3341         phidxz[p45[25]] = -30 * omdxz[24] + 120 * omdxz[25] - 30 * omdxz[26] + 30 * omdxz[27] -
3342                           60 * omdxz[28] - 30 * omdxz[42] - 30 * omdxz[43] + 30 * omdxz[44];
3343         phidxz[p45[26]] = -45 * omdxz[24] - 30 * omdxz[25] + 90 * omdxz[26] + 15 * omdxz[27] +
3344                           15 * omdxz[28] - 60 * omdxz[29] + 15 * omdxz[42] - 45 * omdxz[43] +
3345                           15 * omdxz[44];
3346         phidxz[p45[27]] = -30 * omdxz[24] + 30 * omdxz[25] + 15 * omdxz[26] + 90 * omdxz[27] -
3347                           45 * omdxz[28] - 30 * omdxz[29] + 15 * omdxz[42] + 15 * omdxz[43] -
3348                           45 * omdxz[44];
3349         phidxz[p45[28]] = +15 * omdxz[24] - 60 * omdxz[25] + 15 * omdxz[26] - 45 * omdxz[27] +
3350                           90 * omdxz[28] - 30 * omdxz[29] + 15 * omdxz[42] + 15 * omdxz[43] -
3351                           45 * omdxz[44];
3352         phidxz[p45[29]] = +30 * omdxz[24] - 60 * omdxz[26] - 30 * omdxz[27] - 30 * omdxz[28] +
3353                           120 * omdxz[29] - 30 * omdxz[42] + 30 * omdxz[43] - 30 * omdxz[44];
3354         phidxz[p45[30]] = +90 * omdxz[30] - 30 * omdxz[31] - 45 * omdxz[32] - 30 * omdxz[33] +
3355                           15 * omdxz[34] + 30 * omdxz[35] - 45 * omdxz[42] + 15 * omdxz[43] +
3356                           15 * omdxz[44];
3357         phidxz[p45[31]] = -30 * omdxz[30] + 120 * omdxz[31] - 30 * omdxz[32] + 30 * omdxz[33] -
3358                           60 * omdxz[34] - 30 * omdxz[42] - 30 * omdxz[43] + 30 * omdxz[44];
3359         phidxz[p45[32]] = -45 * omdxz[30] - 30 * omdxz[31] + 90 * omdxz[32] + 15 * omdxz[33] +
3360                           15 * omdxz[34] - 60 * omdxz[35] - 45 * omdxz[42] + 15 * omdxz[43] +
3361                           15 * omdxz[44];
3362         phidxz[p45[33]] = -30 * omdxz[30] + 30 * omdxz[31] + 15 * omdxz[32] + 90 * omdxz[33] -
3363                           45 * omdxz[34] - 30 * omdxz[35] + 15 * omdxz[42] + 15 * omdxz[43] -
3364                           45 * omdxz[44];
3365         phidxz[p45[34]] = +15 * omdxz[30] - 60 * omdxz[31] + 15 * omdxz[32] - 45 * omdxz[33] +
3366                           90 * omdxz[34] - 30 * omdxz[35] + 15 * omdxz[42] + 15 * omdxz[43] -
3367                           45 * omdxz[44];
3368         phidxz[p45[35]] = +30 * omdxz[30] - 60 * omdxz[32] - 30 * omdxz[33] - 30 * omdxz[34] +
3369                           120 * omdxz[35] + 30 * omdxz[42] - 30 * omdxz[43] - 30 * omdxz[44];
3370         phidxz[p45[36]] = +90 * omdxz[36] - 30 * omdxz[37] - 45 * omdxz[38] - 30 * omdxz[39] +
3371                           15 * omdxz[40] + 30 * omdxz[41] - 45 * omdxz[42] + 15 * omdxz[43] +
3372                           15 * omdxz[44];
3373         phidxz[p45[37]] = -30 * omdxz[36] + 120 * omdxz[37] - 30 * omdxz[38] + 30 * omdxz[39] -
3374                           60 * omdxz[40] - 30 * omdxz[42] + 30 * omdxz[43] - 30 * omdxz[44];
3375         phidxz[p45[38]] = -45 * omdxz[36] - 30 * omdxz[37] + 90 * omdxz[38] + 15 * omdxz[39] +
3376                           15 * omdxz[40] - 60 * omdxz[41] - 45 * omdxz[42] + 15 * omdxz[43] +
3377                           15 * omdxz[44];
3378         phidxz[p45[39]] = -30 * omdxz[36] + 30 * omdxz[37] + 15 * omdxz[38] + 90 * omdxz[39] -
3379                           45 * omdxz[40] - 30 * omdxz[41] + 15 * omdxz[42] - 45 * omdxz[43] +
3380                           15 * omdxz[44];
3381         phidxz[p45[40]] = +15 * omdxz[36] - 60 * omdxz[37] + 15 * omdxz[38] - 45 * omdxz[39] +
3382                           90 * omdxz[40] - 30 * omdxz[41] + 15 * omdxz[42] - 45 * omdxz[43] +
3383                           15 * omdxz[44];
3384         phidxz[p45[41]] = +30 * omdxz[36] - 60 * omdxz[38] - 30 * omdxz[39] - 30 * omdxz[40] +
3385                           120 * omdxz[41] + 30 * omdxz[42] - 30 * omdxz[43] - 30 * omdxz[44];
3386         phidxz[p45[42]] = +90 * omdxz[42] - 30 * omdxz[43] - 30 * omdxz[44];
3387         phidxz[p45[43]] = -30 * omdxz[42] + 90 * omdxz[43] - 30 * omdxz[44];
3388         phidxz[p45[44]] = -30 * omdxz[42] - 30 * omdxz[43] + 90 * omdxz[44];
3389 
3390         for (int k = 0; k < 45; ++k) {
3391           val(k, 0, op_dxz) = phidxz[k].x;
3392           val(k, 1, op_dxz) = phidxz[k].y;
3393           val(k, 2, op_dxz) = phidxz[k].z;
3394         }
3395       }
3396 
3397       R3 phidyz[45];
3398       if (whatd & Fop_dyz) {
3399         phidyz[p45[0]] = +9 * omdyz[0] - 18 * omdyz[1] + 3 * omdyz[2] - 27 * omdyz[30] +
3400                          12 * omdyz[31] + 9 * omdyz[32] + 9 * omdyz[33] - 6 * omdyz[34] -
3401                          6 * omdyz[35] - 27 * omdyz[36] + 12 * omdyz[37] + 9 * omdyz[38] +
3402                          9 * omdyz[39] - 6 * omdyz[40] - 6 * omdyz[41] + 18 * omdyz[42] -
3403                          6 * omdyz[43] - 6 * omdyz[44];
3404         phidyz[p45[1]] = -18 * omdyz[0] + 84 * omdyz[1] - 18 * omdyz[2] - 6 * omdyz[30] -
3405                          36 * omdyz[31] + 12 * omdyz[32] - 30 * omdyz[33] + 30 * omdyz[34] -
3406                          6 * omdyz[36] - 36 * omdyz[37] + 12 * omdyz[38] - 30 * omdyz[39] +
3407                          30 * omdyz[40] + 24 * omdyz[42];
3408         phidyz[p45[2]] = +3 * omdyz[0] - 18 * omdyz[1] + 9 * omdyz[2] + 6 * omdyz[30] -
3409                          18 * omdyz[31] + 3 * omdyz[32] + 6 * omdyz[33] - 9 * omdyz[34] +
3410                          6 * omdyz[35] + 6 * omdyz[36] - 18 * omdyz[37] + 3 * omdyz[38] +
3411                          6 * omdyz[39] - 9 * omdyz[40] + 6 * omdyz[41] + 6 * omdyz[42] +
3412                          6 * omdyz[43] + 6 * omdyz[44];
3413         phidyz[p45[3]] = +9 * omdyz[3] - 18 * omdyz[4] + 3 * omdyz[5] - 27 * omdyz[24] +
3414                          12 * omdyz[25] + 9 * omdyz[26] + 9 * omdyz[27] - 6 * omdyz[28] -
3415                          6 * omdyz[29] + 9 * omdyz[36] - 6 * omdyz[37] - 6 * omdyz[38] -
3416                          27 * omdyz[39] + 9 * omdyz[40] + 12 * omdyz[41] - 6 * omdyz[42] +
3417                          18 * omdyz[43] - 6 * omdyz[44];
3418         phidyz[p45[4]] = -18 * omdyz[3] + 84 * omdyz[4] - 18 * omdyz[5] - 6 * omdyz[24] -
3419                          36 * omdyz[25] + 12 * omdyz[26] - 30 * omdyz[27] + 30 * omdyz[28] -
3420                          30 * omdyz[36] + 30 * omdyz[38] - 6 * omdyz[39] + 12 * omdyz[40] -
3421                          36 * omdyz[41] + 24 * omdyz[43];
3422         phidyz[p45[5]] = +3 * omdyz[3] - 18 * omdyz[4] + 9 * omdyz[5] + 6 * omdyz[24] -
3423                          18 * omdyz[25] + 3 * omdyz[26] + 6 * omdyz[27] - 9 * omdyz[28] +
3424                          6 * omdyz[29] + 6 * omdyz[36] + 6 * omdyz[37] - 9 * omdyz[38] +
3425                          6 * omdyz[39] + 3 * omdyz[40] - 18 * omdyz[41] + 6 * omdyz[42] +
3426                          6 * omdyz[43] + 6 * omdyz[44];
3427         phidyz[p45[6]] = +9 * omdyz[6] - 18 * omdyz[7] + 3 * omdyz[8] + 9 * omdyz[24] -
3428                          6 * omdyz[25] - 6 * omdyz[26] - 27 * omdyz[27] + 9 * omdyz[28] +
3429                          12 * omdyz[29] + 9 * omdyz[30] - 6 * omdyz[31] - 6 * omdyz[32] -
3430                          27 * omdyz[33] + 9 * omdyz[34] + 12 * omdyz[35] - 6 * omdyz[42] -
3431                          6 * omdyz[43] + 18 * omdyz[44];
3432         phidyz[p45[7]] = -18 * omdyz[6] + 84 * omdyz[7] - 18 * omdyz[8] - 30 * omdyz[24] +
3433                          30 * omdyz[26] - 6 * omdyz[27] + 12 * omdyz[28] - 36 * omdyz[29] -
3434                          30 * omdyz[30] + 30 * omdyz[32] - 6 * omdyz[33] + 12 * omdyz[34] -
3435                          36 * omdyz[35] + 24 * omdyz[44];
3436         phidyz[p45[8]] = +3 * omdyz[6] - 18 * omdyz[7] + 9 * omdyz[8] + 6 * omdyz[24] +
3437                          6 * omdyz[25] - 9 * omdyz[26] + 6 * omdyz[27] + 3 * omdyz[28] -
3438                          18 * omdyz[29] + 6 * omdyz[30] + 6 * omdyz[31] - 9 * omdyz[32] +
3439                          6 * omdyz[33] + 3 * omdyz[34] - 18 * omdyz[35] + 6 * omdyz[42] +
3440                          6 * omdyz[43] + 6 * omdyz[44];
3441         phidyz[p45[9]] = +9 * omdyz[9] - 18 * omdyz[10] + 3 * omdyz[11] - 27 * omdyz[18] +
3442                          12 * omdyz[19] + 9 * omdyz[20] + 9 * omdyz[21] - 6 * omdyz[22] -
3443                          6 * omdyz[23] - 3 * omdyz[36] + 18 * omdyz[37] - 6 * omdyz[38] +
3444                          9 * omdyz[39] - 27 * omdyz[40] + 12 * omdyz[41] - 6 * omdyz[42] +
3445                          18 * omdyz[43] - 6 * omdyz[44];
3446         phidyz[p45[10]] = -18 * omdyz[9] + 84 * omdyz[10] - 18 * omdyz[11] - 6 * omdyz[18] -
3447                           36 * omdyz[19] + 12 * omdyz[20] - 30 * omdyz[21] + 30 * omdyz[22] -
3448                           12 * omdyz[36] + 36 * omdyz[37] + 6 * omdyz[38] + 12 * omdyz[39] -
3449                           6 * omdyz[40] - 36 * omdyz[41] - 24 * omdyz[42] + 24 * omdyz[43];
3450         phidyz[p45[11]] = +3 * omdyz[9] - 18 * omdyz[10] + 9 * omdyz[11] + 6 * omdyz[18] -
3451                           18 * omdyz[19] + 3 * omdyz[20] + 6 * omdyz[21] - 9 * omdyz[22] +
3452                           6 * omdyz[23] - 9 * omdyz[36] - 12 * omdyz[37] + 27 * omdyz[38] +
3453                           3 * omdyz[39] + 6 * omdyz[40] - 18 * omdyz[41] - 18 * omdyz[42] +
3454                           6 * omdyz[43] + 6 * omdyz[44];
3455         phidyz[p45[12]] = +9 * omdyz[12] - 18 * omdyz[13] + 3 * omdyz[14] + 9 * omdyz[18] -
3456                           6 * omdyz[19] - 6 * omdyz[20] - 27 * omdyz[21] + 9 * omdyz[22] +
3457                           12 * omdyz[23] - 3 * omdyz[30] + 18 * omdyz[31] - 6 * omdyz[32] +
3458                           9 * omdyz[33] - 27 * omdyz[34] + 12 * omdyz[35] - 6 * omdyz[42] -
3459                           6 * omdyz[43] + 18 * omdyz[44];
3460         phidyz[p45[13]] = -18 * omdyz[12] + 84 * omdyz[13] - 18 * omdyz[14] - 30 * omdyz[18] +
3461                           30 * omdyz[20] - 6 * omdyz[21] + 12 * omdyz[22] - 36 * omdyz[23] -
3462                           12 * omdyz[30] + 36 * omdyz[31] + 6 * omdyz[32] + 12 * omdyz[33] -
3463                           6 * omdyz[34] - 36 * omdyz[35] - 24 * omdyz[42] + 24 * omdyz[44];
3464         phidyz[p45[14]] = +3 * omdyz[12] - 18 * omdyz[13] + 9 * omdyz[14] + 6 * omdyz[18] +
3465                           6 * omdyz[19] - 9 * omdyz[20] + 6 * omdyz[21] + 3 * omdyz[22] -
3466                           18 * omdyz[23] - 9 * omdyz[30] - 12 * omdyz[31] + 27 * omdyz[32] +
3467                           3 * omdyz[33] + 6 * omdyz[34] - 18 * omdyz[35] - 18 * omdyz[42] +
3468                           6 * omdyz[43] + 6 * omdyz[44];
3469         phidyz[p45[15]] = +9 * omdyz[15] - 18 * omdyz[16] + 3 * omdyz[17] - 3 * omdyz[18] +
3470                           18 * omdyz[19] - 6 * omdyz[20] + 9 * omdyz[21] - 27 * omdyz[22] +
3471                           12 * omdyz[23] - 3 * omdyz[24] + 18 * omdyz[25] - 6 * omdyz[26] +
3472                           9 * omdyz[27] - 27 * omdyz[28] + 12 * omdyz[29] - 6 * omdyz[42] -
3473                           6 * omdyz[43] + 18 * omdyz[44];
3474         phidyz[p45[16]] = -18 * omdyz[15] + 84 * omdyz[16] - 18 * omdyz[17] - 12 * omdyz[18] +
3475                           36 * omdyz[19] + 6 * omdyz[20] + 12 * omdyz[21] - 6 * omdyz[22] -
3476                           36 * omdyz[23] - 12 * omdyz[24] + 36 * omdyz[25] + 6 * omdyz[26] +
3477                           12 * omdyz[27] - 6 * omdyz[28] - 36 * omdyz[29] - 24 * omdyz[43] +
3478                           24 * omdyz[44];
3479         phidyz[p45[17]] = +3 * omdyz[15] - 18 * omdyz[16] + 9 * omdyz[17] - 9 * omdyz[18] -
3480                           12 * omdyz[19] + 27 * omdyz[20] + 3 * omdyz[21] + 6 * omdyz[22] -
3481                           18 * omdyz[23] - 9 * omdyz[24] - 12 * omdyz[25] + 27 * omdyz[26] +
3482                           3 * omdyz[27] + 6 * omdyz[28] - 18 * omdyz[29] + 6 * omdyz[42] -
3483                           18 * omdyz[43] + 6 * omdyz[44];
3484         phidyz[p45[18]] = +90 * omdyz[18] - 30 * omdyz[19] - 45 * omdyz[20] - 30 * omdyz[21] +
3485                           15 * omdyz[22] + 30 * omdyz[23] + 15 * omdyz[42] - 45 * omdyz[43] +
3486                           15 * omdyz[44];
3487         phidyz[p45[19]] = -30 * omdyz[18] + 120 * omdyz[19] - 30 * omdyz[20] + 30 * omdyz[21] -
3488                           60 * omdyz[22] + 30 * omdyz[42] - 30 * omdyz[43] + 30 * omdyz[44];
3489         phidyz[p45[20]] = -45 * omdyz[18] - 30 * omdyz[19] + 90 * omdyz[20] + 15 * omdyz[21] +
3490                           15 * omdyz[22] - 60 * omdyz[23] + 15 * omdyz[42] - 45 * omdyz[43] +
3491                           15 * omdyz[44];
3492         phidyz[p45[21]] = -30 * omdyz[18] + 30 * omdyz[19] + 15 * omdyz[20] + 90 * omdyz[21] -
3493                           45 * omdyz[22] - 30 * omdyz[23] + 15 * omdyz[42] + 15 * omdyz[43] -
3494                           45 * omdyz[44];
3495         phidyz[p45[22]] = +15 * omdyz[18] - 60 * omdyz[19] + 15 * omdyz[20] - 45 * omdyz[21] +
3496                           90 * omdyz[22] - 30 * omdyz[23] + 15 * omdyz[42] + 15 * omdyz[43] -
3497                           45 * omdyz[44];
3498         phidyz[p45[23]] = +30 * omdyz[18] - 60 * omdyz[20] - 30 * omdyz[21] - 30 * omdyz[22] +
3499                           120 * omdyz[23] + 30 * omdyz[42] + 30 * omdyz[43] - 30 * omdyz[44];
3500         phidyz[p45[24]] = +90 * omdyz[24] - 30 * omdyz[25] - 45 * omdyz[26] - 30 * omdyz[27] +
3501                           15 * omdyz[28] + 30 * omdyz[29] + 15 * omdyz[42] - 45 * omdyz[43] +
3502                           15 * omdyz[44];
3503         phidyz[p45[25]] = -30 * omdyz[24] + 120 * omdyz[25] - 30 * omdyz[26] + 30 * omdyz[27] -
3504                           60 * omdyz[28] - 30 * omdyz[42] - 30 * omdyz[43] + 30 * omdyz[44];
3505         phidyz[p45[26]] = -45 * omdyz[24] - 30 * omdyz[25] + 90 * omdyz[26] + 15 * omdyz[27] +
3506                           15 * omdyz[28] - 60 * omdyz[29] + 15 * omdyz[42] - 45 * omdyz[43] +
3507                           15 * omdyz[44];
3508         phidyz[p45[27]] = -30 * omdyz[24] + 30 * omdyz[25] + 15 * omdyz[26] + 90 * omdyz[27] -
3509                           45 * omdyz[28] - 30 * omdyz[29] + 15 * omdyz[42] + 15 * omdyz[43] -
3510                           45 * omdyz[44];
3511         phidyz[p45[28]] = +15 * omdyz[24] - 60 * omdyz[25] + 15 * omdyz[26] - 45 * omdyz[27] +
3512                           90 * omdyz[28] - 30 * omdyz[29] + 15 * omdyz[42] + 15 * omdyz[43] -
3513                           45 * omdyz[44];
3514         phidyz[p45[29]] = +30 * omdyz[24] - 60 * omdyz[26] - 30 * omdyz[27] - 30 * omdyz[28] +
3515                           120 * omdyz[29] - 30 * omdyz[42] + 30 * omdyz[43] - 30 * omdyz[44];
3516         phidyz[p45[30]] = +90 * omdyz[30] - 30 * omdyz[31] - 45 * omdyz[32] - 30 * omdyz[33] +
3517                           15 * omdyz[34] + 30 * omdyz[35] - 45 * omdyz[42] + 15 * omdyz[43] +
3518                           15 * omdyz[44];
3519         phidyz[p45[31]] = -30 * omdyz[30] + 120 * omdyz[31] - 30 * omdyz[32] + 30 * omdyz[33] -
3520                           60 * omdyz[34] - 30 * omdyz[42] - 30 * omdyz[43] + 30 * omdyz[44];
3521         phidyz[p45[32]] = -45 * omdyz[30] - 30 * omdyz[31] + 90 * omdyz[32] + 15 * omdyz[33] +
3522                           15 * omdyz[34] - 60 * omdyz[35] - 45 * omdyz[42] + 15 * omdyz[43] +
3523                           15 * omdyz[44];
3524         phidyz[p45[33]] = -30 * omdyz[30] + 30 * omdyz[31] + 15 * omdyz[32] + 90 * omdyz[33] -
3525                           45 * omdyz[34] - 30 * omdyz[35] + 15 * omdyz[42] + 15 * omdyz[43] -
3526                           45 * omdyz[44];
3527         phidyz[p45[34]] = +15 * omdyz[30] - 60 * omdyz[31] + 15 * omdyz[32] - 45 * omdyz[33] +
3528                           90 * omdyz[34] - 30 * omdyz[35] + 15 * omdyz[42] + 15 * omdyz[43] -
3529                           45 * omdyz[44];
3530         phidyz[p45[35]] = +30 * omdyz[30] - 60 * omdyz[32] - 30 * omdyz[33] - 30 * omdyz[34] +
3531                           120 * omdyz[35] + 30 * omdyz[42] - 30 * omdyz[43] - 30 * omdyz[44];
3532         phidyz[p45[36]] = +90 * omdyz[36] - 30 * omdyz[37] - 45 * omdyz[38] - 30 * omdyz[39] +
3533                           15 * omdyz[40] + 30 * omdyz[41] - 45 * omdyz[42] + 15 * omdyz[43] +
3534                           15 * omdyz[44];
3535         phidyz[p45[37]] = -30 * omdyz[36] + 120 * omdyz[37] - 30 * omdyz[38] + 30 * omdyz[39] -
3536                           60 * omdyz[40] - 30 * omdyz[42] + 30 * omdyz[43] - 30 * omdyz[44];
3537         phidyz[p45[38]] = -45 * omdyz[36] - 30 * omdyz[37] + 90 * omdyz[38] + 15 * omdyz[39] +
3538                           15 * omdyz[40] - 60 * omdyz[41] - 45 * omdyz[42] + 15 * omdyz[43] +
3539                           15 * omdyz[44];
3540         phidyz[p45[39]] = -30 * omdyz[36] + 30 * omdyz[37] + 15 * omdyz[38] + 90 * omdyz[39] -
3541                           45 * omdyz[40] - 30 * omdyz[41] + 15 * omdyz[42] - 45 * omdyz[43] +
3542                           15 * omdyz[44];
3543         phidyz[p45[40]] = +15 * omdyz[36] - 60 * omdyz[37] + 15 * omdyz[38] - 45 * omdyz[39] +
3544                           90 * omdyz[40] - 30 * omdyz[41] + 15 * omdyz[42] - 45 * omdyz[43] +
3545                           15 * omdyz[44];
3546         phidyz[p45[41]] = +30 * omdyz[36] - 60 * omdyz[38] - 30 * omdyz[39] - 30 * omdyz[40] +
3547                           120 * omdyz[41] + 30 * omdyz[42] - 30 * omdyz[43] - 30 * omdyz[44];
3548         phidyz[p45[42]] = +90 * omdyz[42] - 30 * omdyz[43] - 30 * omdyz[44];
3549         phidyz[p45[43]] = -30 * omdyz[42] + 90 * omdyz[43] - 30 * omdyz[44];
3550         phidyz[p45[44]] = -30 * omdyz[42] - 30 * omdyz[43] + 90 * omdyz[44];
3551 
3552         for (int k = 0; k < 45; ++k) {
3553           val(k, 0, op_dyz) = phidyz[k].x;
3554           val(k, 1, op_dyz) = phidyz[k].y;
3555           val(k, 2, op_dyz) = phidyz[k].z;
3556         }
3557       }
3558     }
3559   }
3560 
3561   // Auxiliary Finite Elements for the partition of unity of DDM methods
3562 
3563   // FE space Edge03ds0 useful to build a partition of unity for the FE space Edge03d of
3564   // edge elements of degree 1 in 3d
3565   // It has only the interpolation operator, it doesn't have basis functions
3566   class TypeOfFE_P0Edge3ds0 : public GTypeOfFE< Mesh3 > {
3567    public:
3568     typedef Mesh3 Mesh;
3569     typedef Mesh::Element Element;
3570     typedef Element::Rd Rd;
3571     typedef Element::RdHat RdHat;
3572     static const int d = Rd::d;
3573     struct A4 {
3574       int dfon[4];
3575 
A4Fem2D::TypeOfFE_P0Edge3ds0::A43576       A4( ) {
3577         dfon[0] = dfon[1] = dfon[2] = dfon[3] = 0;
3578         dfon[1] = 1;
3579       }
3580 
operator const int*Fem2D::TypeOfFE_P0Edge3ds0::A43581       operator const int *( ) const { return dfon; }
3582     };
3583 
3584     TypeOfFE_P0Edge3ds0( );
3585 
3586     void FB(const What_d whatd, const Mesh &Th, const Element &K, const RdHat &PHat,
3587             RNMK_ &val) const;
3588 
~TypeOfFE_P0Edge3ds0()3589     ~TypeOfFE_P0Edge3ds0( ) {}
3590 
3591    private:
3592     TypeOfFE_P0Edge3ds0(const TypeOfFE_P0Edge3ds0 &);
3593     void operator=(const TypeOfFE_P0Edge3ds0 &);
3594   };
3595 
TypeOfFE_P0Edge3ds0()3596   TypeOfFE_P0Edge3ds0::TypeOfFE_P0Edge3ds0( )
3597     : GTypeOfFE< Mesh3 >(A4( ), 1, 1, Element::ne, Element::ne, false, true) {
3598     R3 Pt[] = {R3(0., 0., 0.), R3(1., 0., 0.), R3(0., 1., 0.), R3(0., 0., 1.)};
3599 
3600     for (int e = 0; e < Element::ne; ++e) {
3601       this->PtInterpolation[e] = 0.5 * (Pt[Element::nvedge[e][0]] + Pt[Element::nvedge[e][1]]);
3602     }
3603 
3604     {
3605       for (int e = 0; e < Element::ne; e++) {
3606         this->pInterpolation[e] = e;
3607         this->cInterpolation[e] = 0;
3608         this->dofInterpolation[e] = e;
3609         this->coefInterpolation[e] = 1.;
3610       }
3611     }
3612   }
3613 
FB(const What_d whatd,const Mesh &,const Element & K,const RdHat & PHat,RNMK_ & val) const3614   void TypeOfFE_P0Edge3ds0::FB(const What_d whatd, const Mesh &, const Element &K,
3615                                const RdHat &PHat, RNMK_ &val) const {
3616     assert(0);
3617   }
3618 
3619   // FE space Edge13ds0 useful to build a partition of unity for the FE space Edge13d of
3620   // edge elements of degree 2 in 3d
3621   // It has only the interpolation operator, it doesn't have basis functions
3622   class TypeOfFE_P1Edge3ds0 : public GTypeOfFE< Mesh3 > {
3623    public:
3624     typedef Mesh3 Mesh;
3625     typedef Mesh::Element Element;
3626     typedef Element::Rd Rd;
3627     typedef Element::RdHat RdHat;
3628     static const int d = Rd::d;
3629     struct A4 {
3630       int dfon[4];
3631 
A4Fem2D::TypeOfFE_P1Edge3ds0::A43632       A4( ) {
3633         dfon[0] = dfon[1] = dfon[2] = dfon[3] = 0;
3634         dfon[1] = 2;
3635         dfon[2] = 2;
3636       }
3637 
operator const int*Fem2D::TypeOfFE_P1Edge3ds0::A43638       operator const int *( ) const { return dfon; }
3639     };
3640 
3641     TypeOfFE_P1Edge3ds0( );
3642 
3643     void FB(const What_d whatd, const Mesh &Th, const Element &K, const RdHat &PHat,
3644             RNMK_ &val) const;
3645 
~TypeOfFE_P1Edge3ds0()3646     ~TypeOfFE_P1Edge3ds0( ) {}
3647 
3648    private:
3649     TypeOfFE_P1Edge3ds0(const TypeOfFE_P1Edge3ds0 &);
3650     void operator=(const TypeOfFE_P1Edge3ds0 &);
3651   };
3652 
TypeOfFE_P1Edge3ds0()3653   TypeOfFE_P1Edge3ds0::TypeOfFE_P1Edge3ds0( )
3654     : GTypeOfFE< Mesh3 >(A4( ), 1, 1, Element::ne * 2 + Element::nf * 2, Element::ne + Element::nf,
3655                          false, true) {
3656     R3 Pt[] = {R3(0., 0., 0.), R3(1., 0., 0.), R3(0., 1., 0.), R3(0., 0., 1.)};
3657 
3658     {
3659       int i = 0;
3660 
3661       for (int e = 0; e < Element::ne; ++e, ++i) {
3662         this->PtInterpolation[i] = 0.5 * (Pt[Element::nvedge[e][0]] + Pt[Element::nvedge[e][1]]);
3663       }
3664 
3665       for (int f = 0; f < Element::nf; ++f, ++i) {
3666         this->PtInterpolation[i] =
3667           1. / 3. *
3668           (Pt[Element::nvface[f][0]] + Pt[Element::nvface[f][1]] + Pt[Element::nvface[f][2]]);
3669       }
3670     }
3671     int i = 0, p = 0;
3672     int e;
3673 
3674     for (e = 0; e < (Element::ne)*2; e++) {
3675       if (e % 2 == 1) {
3676         p = p - 1;
3677       }
3678 
3679       this->pInterpolation[i] = p;
3680       this->cInterpolation[i] = 0.;
3681       this->dofInterpolation[i] = e;
3682       this->coefInterpolation[i] = 1.;
3683       i++;
3684       p++;
3685     }
3686 
3687     for (int f = 0; f < (Element::nf)*2; f++) {
3688       if (f % 2 == 1) {
3689         p = p - 1;
3690       }
3691 
3692       this->pInterpolation[i] = p;
3693       this->cInterpolation[i] = 0.;
3694       this->dofInterpolation[i] = e + f;
3695       this->coefInterpolation[i] = 1.;
3696       i++;
3697       p++;
3698     }
3699   }
3700 
FB(const What_d whatd,const Mesh &,const Element & K,const RdHat & PHat,RNMK_ & val) const3701   void TypeOfFE_P1Edge3ds0::FB(const What_d whatd, const Mesh &, const Element &K,
3702                                const RdHat &PHat, RNMK_ &val) const {
3703     assert(0);
3704   }
3705 
3706   // FE space Edge23ds0 useful to build a partition of unity for the FE space Edge23d of
3707   // edge elements of degree 3 in 3d
3708   // It has only the interpolation operator, it doesn't have basis functions
3709   class TypeOfFE_P2Edge3ds0 : public GTypeOfFE< Mesh3 > {
3710    public:
3711     typedef Mesh3 Mesh;
3712     typedef Mesh3::Element Element;
3713     typedef GFElement< Mesh3 > FElement;
3714 
3715     static int dfon[];
3716     static const int d = Mesh::Rd::d;
3717     struct A4 {
3718       int dfon[4];
3719 
A4Fem2D::TypeOfFE_P2Edge3ds0::A43720       A4( ) {
3721         dfon[0] = dfon[1] = dfon[2] = dfon[3] = 0;
3722         dfon[1] = 3;
3723         dfon[2] = 6;
3724         dfon[3] = 3;
3725       }
3726 
operator const int*Fem2D::TypeOfFE_P2Edge3ds0::A43727       operator const int *( ) const { return dfon; }
3728     };
3729 
3730     TypeOfFE_P2Edge3ds0( );    // constructor
3731 
3732     void FB(const What_d whatd, const Mesh &Th, const Mesh3::Element &K, const RdHat &PHat,
3733             RNMK_ &val) const;
3734 
~TypeOfFE_P2Edge3ds0()3735     ~TypeOfFE_P2Edge3ds0( ) {}
3736 
3737    private:
3738     TypeOfFE_P2Edge3ds0(const TypeOfFE_P2Edge3ds0 &);
3739     void operator=(const TypeOfFE_P2Edge3ds0 &);
3740   };
3741 
TypeOfFE_P2Edge3ds0()3742   TypeOfFE_P2Edge3ds0::TypeOfFE_P2Edge3ds0( )
3743     : GTypeOfFE< Mesh3 >(A4( ), 1, 1, 3 * Element::ne + 6 * Element::nf + 3,
3744                          Element::ne + Element::nf + 1, false, true) {
3745     R3 Pt[] = {R3(0., 0., 0.), R3(1., 0., 0.), R3(0., 1., 0.),
3746                R3(0., 0., 1.)};    // 4 ref tetrahedron vertices
3747 
3748     {
3749       // We build the interpolation pts on the edges of the reference tetrahedron:
3750       int i = 0;
3751 
3752       for (int e = 0; e < Element::ne; ++e, ++i) {
3753         this->PtInterpolation[i] = 0.5 * (Pt[Element::nvedge[e][0]] + Pt[Element::nvedge[e][1]]);
3754       }
3755 
3756       // We build the interpolation pts on the faces of the reference tetrahedron:
3757       // (the index i mustn't be reinitialised!)
3758       for (int f = 0; f < Element::nf; ++f, ++i) {
3759         this->PtInterpolation[i] =
3760           1. / 3. *
3761           (Pt[Element::nvface[f][0]] + Pt[Element::nvface[f][1]] + Pt[Element::nvface[f][2]]);
3762       }
3763 
3764       // We build the interpolation pts on the tetrahedron:
3765       // (the index i mustn't be reinitialised!)
3766       this->PtInterpolation[i] = 1. / 4. * (Pt[0] + Pt[1] + Pt[2] + Pt[3]);
3767     }
3768     // We build the indices in (13.1) : edge dofs
3769     int i = 0, p = 0;    // i is the k in (13.1) (chapter 13 ff++doc)
3770     int e;               // we will need e also below, in the parts referred to faces and volumes
3771 
3772     for (e = 0; e < (Element::ne)*3; e++) {    // loop on the 18 edge dofs
3773       if (e % 3 != 0) {
3774         p = p - 1;
3775       }    // for 3 successive basis fcts the quad pts are the same (they correspond to the same
3776            // edge)
3777 
3778       {
3779         this->pInterpolation[i] = p;      // pk in (13.1)
3780         this->cInterpolation[i] = 0;      // jk in (13.1)
3781         this->dofInterpolation[i] = e;    // ik in (13.1)
3782         this->coefInterpolation[i] = 1.;
3783         i++;
3784         p++;
3785       }
3786     }
3787 
3788     // We build the indices in (13.1) : face dofs
3789     // (the indices i and p mustn't be reinitialised)
3790     int f;    // we will need f also below, in the part referred to volumes
3791 
3792     for (f = 0; f < (Element::nf)*6; f++) {    // loop on the 24 face dofs
3793       if (f % 6 != 0) {
3794         p = p - 1;
3795       }    // for 6 successive basis fcts the quad pts are the same (they correspond to the same
3796            // face)
3797 
3798       {
3799         this->pInterpolation[i] = p;          // pk in (13.1)
3800         this->cInterpolation[i] = 0;          // jk in (13.1)
3801         this->dofInterpolation[i] = e + f;    // ik in (13.1)
3802         this->coefInterpolation[i] = 1.;
3803         i++;
3804         p++;
3805       }
3806     }
3807 
3808     // We build the indices in (13.1) : volume basis fncts
3809     // (the indices i and p mustn't be reinitialised)
3810     for (int v = 0; v < 3; v++) {    // loop on the 3 volume dofs
3811       if (v > 0) {
3812         p = p - 1;
3813       }
3814 
3815       {
3816         this->pInterpolation[i] = p;              // pk in (13.1)
3817         this->cInterpolation[i] = 0;              // jk in (13.1)
3818         this->dofInterpolation[i] = e + f + v;    // ik in (13.1)
3819         this->coefInterpolation[i] = 1.;
3820         i++;
3821         p++;
3822       }
3823     }
3824   }
3825 
FB(const What_d whatd,const Mesh & Th,const Mesh3::Element & K,const RdHat & PHat,RNMK_ & val) const3826   void TypeOfFE_P2Edge3ds0::FB(const What_d whatd, const Mesh &Th, const Mesh3::Element &K,
3827                                const RdHat &PHat, RNMK_ &val) const {
3828     assert(0);
3829   }
3830 
3831   class TypeOfFE_RT1_3d : public GTypeOfFE< Mesh3 > {
3832    public:
3833     typedef Mesh3 Mesh;
3834     typedef Mesh3::Element Element;
3835     typedef GFElement< Mesh3 > FElement;
3836     static int dfon[];
3837     static const int d = Mesh::Rd::d;
3838     // quadrature Formula on a face
3839     static const GQuadratureFormular< R2 > QFface;
3840     // quadrature Formula on an element
3841     static const GQuadratureFormular< R3 > QFtetra;
3842     TypeOfFE_RT1_3d( );
3843     int edgeface[4][3];
3844     void FB(const What_d whatd, const Mesh &Th, const Mesh3::Element &K, const RdHat &PHat,
3845             RNMK_ &val) const;
3846     void set(const Mesh &Th, const Element &K, InterpolationMatrix< RdHat > &M, int ocoef, int odf,
3847              int *nump) const;
3848   };
3849 
3850   int TypeOfFE_RT1_3d::dfon[] = {0, 0, 3, 3};    // dofs per vertice, edge, face, volume
3851 
3852   // Quadrature formula on a face,
3853   const GQuadratureFormular< R2 > TypeOfFE_RT1_3d::QFface(QuadratureFormular_T_5);
3854 
3855   // Quadrature formula on the tetraedron
3856   const GQuadratureFormular< R3 > TypeOfFE_RT1_3d::QFtetra(QuadratureFormular_Tet_2);
3857 
TypeOfFE_RT1_3d()3858   TypeOfFE_RT1_3d::TypeOfFE_RT1_3d( )
3859     : GTypeOfFE< Mesh3 >(dfon, d, 1, 3 * QFface.n * 3 * Element::nf + 3 * QFtetra.n * 3,
3860                          Element::nf * QFface.n + QFtetra.n, false, true) {
3861     assert(QFface.n);
3862     assert(QFtetra.n);
3863     // 4 ref tetra vertices
3864     R3 Pt[] = {R3(0., 0., 0.), R3(1., 0., 0.), R3(0., 1., 0.), R3(0., 0., 1.)};
3865 
3866     // We build the interpolation pts on the faces
3867     int p = 0;
3868 
3869     for (int f = 0; f < Element::nf; ++f) {
3870       for (int q = 0; q < QFface.n; ++q, ++p) {
3871         double x = QFface[q].x;
3872         double y = QFface[q].y;
3873         this->PtInterpolation[p] = Pt[Element::nvface[f][0]] * (1. - x - y) +
3874                                    Pt[Element::nvface[f][1]] * x + Pt[Element::nvface[f][2]] * y;
3875       }
3876     }
3877 
3878     // We build the interpolation bubble pts
3879     for (int q = 0; q < QFtetra.n; ++q, ++p) {
3880       double x = QFtetra[q].x;
3881       double y = QFtetra[q].y;
3882       double z = QFtetra[q].z;
3883       this->PtInterpolation[p] = Pt[0] * (1. - x - y - z) + Pt[1] * x + Pt[2] * y + Pt[3] * z;
3884     }
3885 
3886     int i = 0;
3887     p = 0;
3888 
3889     for (int f = 0; f < Element::nf; f++) {        // loop on the 4 face dofs
3890       for (int q = 0; q < QFface.n; ++q, p++) {    // loop on the face quadrature pts
3891         for (int df = 0; df < 3; df++) {           // 3 dof par face
3892           int dof = 3 * f + df;                    // numero  du dof  3 dof / face
3893 
3894           for (int c = 0; c < 3; c++, i++) {    // loop on the 3 components
3895             this->pInterpolation[i] = p;        // pk
3896             this->cInterpolation[i] = c;        // jk
3897             this->dofInterpolation[i] = dof;    // ik
3898             this->coefInterpolation[i] = 0.;
3899           }
3900         }
3901       }
3902     }
3903 
3904     {
3905       p = Element::nf * QFface.n;
3906 
3907       for (int q = 0; q < QFtetra.n; ++q, ++p) {    // loop on the volume quadrature pts
3908         for (int v = 12; v < 15; v++) {             // loop on the 3 volume dofs
3909           for (int c = 0; c < 3; c++, i++) {        // loop on the 3 components
3910             this->pInterpolation[i] = p;            // pk
3911             this->cInterpolation[i] = c;            // jk
3912             this->dofInterpolation[i] = v;          // ik
3913             this->coefInterpolation[i] = 0.;
3914           }
3915         }
3916       }
3917     }
3918     // verif bonne taille
3919     ffassert(p == this->PtInterpolation.N( ));
3920   }    // end TypeOfFE_RT1_3d()
3921 
3922   // For the coefficients of interpolation alphak in (13.1)
3923 
set(const Mesh & Th,const Element & K,InterpolationMatrix<RdHat> & M,int ocoef,int odf,int * nump) const3924   void TypeOfFE_RT1_3d::set(const Mesh &Th, const Element &K, InterpolationMatrix< RdHat > &M,
3925                             int ocoef, int odf, int *nump) const {
3926     int i = ocoef;
3927 
3928     // *******************************************
3929     // DOFs on the 4 faces --- 3 DOFs per face //
3930     // *******************************************
3931 
3932     // inv of int(F) lamda_i lambda_j = Area(K) * (d! (1+delta ij) / (d+max n)! = 0.5 * 2(1+delta
3933     // ij) /(2+2)!
3934     double c1[][3] = {{9, -3, -3} /* 0 */, {-3, 9, -3} /* 1 */, {-3, -3, 9} /* 2 */};
3935     R3 NK[4];
3936 
3937     K.Gradlambda(NK);    // InteriorNormal of F /h = - N  3*|K|/|F|
3938     double coefK = -3. * K.mesure( );
3939 
3940     for (int ff = 0; ff < Element::nf; ff++) {    // loop on the 4 face dofs
3941       const Element::Vertex *fV[3] = {&K.at(Element::nvface[ff][0]), &K.at(Element::nvface[ff][1]),
3942                                       &K.at(Element::nvface[ff][2])};
3943       int p[] = {0, 1, 2};
3944       int fp = K.facePermutation(ff);
3945       if (fp & 1) {
3946         Exchange(p[0], p[1]);
3947       }
3948 
3949       if (fp & 2) {
3950         Exchange(p[1], p[2]);
3951       }
3952 
3953       if (fp & 4) {
3954         Exchange(p[0], p[1]);
3955       }
3956 
3957       R3 N = NK[ff];
3958       N *= coefK * K.faceOrient(ff);
3959 
3960       for (int q = 0; q < QFface.n; ++q) {    // loop on the face quadrature pts
3961         // the 3 lambdas of P1 on the face
3962 
3963         double lambda[3] = {1. - QFface[q].x - QFface[q].y, QFface[q].x, QFface[q].y};
3964         R sa = QFface[q].a;
3965         R cp[3] = {(c1[0][0] * lambda[0] + c1[0][1] * lambda[1] + c1[0][2] * lambda[2]) * sa,
3966                    (c1[1][0] * lambda[0] + c1[1][1] * lambda[1] + c1[1][2] * lambda[2]) * sa,
3967                    (c1[2][0] * lambda[0] + c1[2][1] * lambda[1] + c1[2][2] * lambda[2]) * sa};
3968 
3969         for (int idof = 0; idof < 3; idof++) {    // loop sur 3 dof de la face
3970           for (int c = 0; c < 3; c++, i++) {      // loop on the 3 components
3971             M.coef[i] = N[c] * cp[p[idof]];
3972           }
3973         }
3974       }
3975     }
3976 
3977     // cout << endl;
3978     // **************************************************
3979     // DOFs on the tetraedra --- 3 DOFs in the volume //
3980     // **************************************************
3981     // Base Piola compatible  B_i =N_i* |F_i|/6  for 3 face 1,2,3
3982     double CK = -K.mesure( );    // dof U= [u1,u2,u3] > |K| int_K ( B_i.U )
3983 
3984     for (int p = 0; p < QFtetra.n; ++p) {
3985       double w = QFtetra[p].a * CK;
3986 
3987       for (int l = 0; l < 3; l++) {
3988         M.coef[i++] = w * NK[l + 1].x;
3989         M.coef[i++] = w * NK[l + 1].y;
3990         M.coef[i++] = w * NK[l + 1].z;
3991       }
3992     }
3993 
3994   }    // end set function
3995 
3996   // here the basis functions and theirs derivates
FB(const What_d whatd,const Mesh & Th,const Mesh3::Element & K,const RdHat & PHat,RNMK_ & val) const3997   void TypeOfFE_RT1_3d::FB(const What_d whatd, const Mesh &Th, const Mesh3::Element &K,
3998                            const RdHat &PHat, RNMK_ &val) const {
3999     assert(val.N( ) >= 15);
4000     assert(val.M( ) == 3);
4001 
4002     val = 0;
4003 
4004     // basis functions to RT03d / multiply by sign to have a exterior normal and divide by the
4005     // mesure of K phi = signe * (x - qi)/ (volume*d)
4006     R cc = d * K.mesure( );
4007     R lambda[] = {1. - PHat.sum( ), PHat.x, PHat.y, PHat.z};
4008     R3 X = K(PHat);
4009     R3 phi[4] = {X - K[0], X - K[1], X - K[2], X - K[3]};    // phi * area *6
4010 
4011     // fo contain just the sign about permutation ----- 1perm=-1 / 2perm=1 / 3perm=-1
4012     double fo[4] = {(double)K.faceOrient(0), (double)K.faceOrient(1), (double)K.faceOrient(2),
4013                     (double)K.faceOrient(3)};
4014     int p[15] = {2, 1, 0,  3,  4,  5,  8, 7,
4015                  6, 9, 10, 11, 12, 13, 14};    // Permutation for orientation to dof
4016     R3 Pm[16];                                 // all the momome function ..
4017 
4018     for (int ff = 0, k = 0; ff < Element::nf; ff++, k += 3) {
4019       // orientation de la face a envert
4020       int fp = K.facePermutation(ff);
4021       if (fp & 1) {
4022         Exchange(p[k], p[k + 1]);
4023       }
4024 
4025       if (fp & 2) {
4026         Exchange(p[k + 1], p[k + 2]);
4027       }
4028 
4029       if (fp & 4) {
4030         Exchange(p[k], p[k + 1]);
4031       }
4032     }
4033 
4034     double cf[][3] = {
4035       {-1.25, 0.25, 0} /* 0 */,  {-1.25, 0, 0.25} /* 1 */,   {-1.5, -0.25, -0.25} /* 2 */,
4036       {0.25, -1.25, 0} /* 3 */,  {0, -1.25, 0.25} /* 4 */,   {-0.25, -1.5, -0.25} /* 5 */,
4037       {0.25, 0, -1.25} /* 6 */,  {0, 0.25, -1.25} /* 7 */,   {-0.25, -0.25, -1.5} /* 8 */,
4038       {1.5, 1.25, 1.25} /* 9 */, {1.25, 1.5, 1.25} /* 10 */, {1.25, 1.25, 1.5} /* 11 */,
4039       {-15, 15, 0} /* 12 */,     {-15, 0, 15} /* 13 */,      {-30, -15, -15} /* 14 */};
4040     int Bii[][2] = {{0, 0} /* 0 */,  {0, 1} /* 1 */,  {0, 2} /* 2 */,  {0, 3} /* 3 */,
4041                     {1, 0} /* 4 */,  {1, 1} /* 5 */,  {1, 2} /* 6 */,  {1, 3} /* 7 */,
4042                     {2, 0} /* 8 */,  {2, 1} /* 9 */,  {2, 2} /* 10 */, {2, 3} /* 11 */,
4043                     {3, 0} /* 12 */, {3, 1} /* 13 */, {3, 2} /* 14 */, {3, 3} /* 15 */};
4044     int fe[] = {1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14};
4045     int k6[] = {0, 5, 10};
4046 
4047     // here we build all the monomials phi_i lambda_j
4048     for (int l = 0; l < 16; ++l) {
4049       int i = Bii[l][0];
4050       int j = Bii[l][1];
4051       Pm[l] = phi[i] * lambda[j] / cc;
4052     }
4053 
4054     // caution to the numbering of the nodes of the face to the numbering of the basis function
4055     // cci
4056 
4057     double sg[15] = {fo[0], fo[0], fo[0], fo[1], fo[1], fo[1], fo[2], fo[2],
4058                      fo[2], fo[3], fo[3], fo[3], 1.,    1.,    1.};
4059 
4060     if (whatd & Fop_D0) {
4061       for (int pdf = 0; pdf < 15; ++pdf) {
4062         int df = p[pdf];
4063         R3 fd(0., 0., 0.);
4064         if (df < 12) {
4065           fd = Pm[fe[df]];    // edge function ..
4066         }
4067 
4068         for (int k = 0; k < 3; ++k) {
4069           fd += cf[df][k] * Pm[k6[k]];
4070         }
4071 
4072         fd *= sg[pdf];
4073         val(pdf, 0, op_id) = fd.x;
4074         val(pdf, 1, op_id) = fd.y;
4075         val(pdf, 2, op_id) = fd.z;
4076       }
4077     }
4078 
4079     if (whatd & Fop_D1) {
4080       R3 DL[4];
4081       K.Gradlambda(DL);
4082       R3 Dphix(1, 0, 0);
4083       R3 Dphiy(0, 1, 0);
4084       R3 Dphiz(0, 0, 1);
4085       R3 DxPm[16];
4086       R3 DyPm[16];
4087       R3 DzPm[16];
4088 
4089       for (int l = 0; l < 16; ++l) {
4090         // diff phi[i]*lambda[j]/cc;
4091         int i = Bii[l][0];
4092         int j = Bii[l][1];
4093         R Lj = lambda[j];
4094         R3 DLj = DL[j];
4095         R3 DF1 = (Dphix * Lj + phi[i].x * DLj) / cc;
4096         R3 DF2 = (Dphiy * Lj + phi[i].y * DLj) / cc;
4097         R3 DF3 = (Dphiz * Lj + phi[i].z * DLj) / cc;
4098 
4099         DxPm[l] = R3(DF1.x, DF2.x, DF3.x);
4100         DyPm[l] = R3(DF1.y, DF2.y, DF3.y);
4101         DzPm[l] = R3(DF1.z, DF2.z, DF3.z);
4102       }
4103 
4104       if (whatd & Fop_dx) {
4105         for (int pdf = 0; pdf < 15; ++pdf) {
4106           int df = p[pdf];
4107           R3 fd(0., 0., 0.);
4108           if (df < 12) {
4109             fd = DxPm[fe[df]];    // edge function ..
4110           }
4111 
4112           for (int k = 0; k < 3; ++k) {
4113             fd += cf[df][k] * DxPm[k6[k]];
4114           }
4115 
4116           fd *= sg[df];
4117           val(pdf, 0, op_dx) = fd.x;
4118           val(pdf, 1, op_dx) = fd.y;
4119           val(pdf, 2, op_dx) = fd.z;
4120         }
4121       }
4122 
4123       if (whatd & Fop_dy) {
4124         for (int pdf = 0; pdf < 15; ++pdf) {
4125           int df = p[pdf];
4126           R3 fd(0., 0., 0.);
4127           if (df < 12) {
4128             fd = DyPm[fe[df]];    // edge function ..
4129           }
4130 
4131           for (int k = 0; k < 3; ++k) {
4132             fd += cf[df][k] * DyPm[k6[k]];
4133           }
4134 
4135           fd *= sg[df];
4136           val(pdf, 0, op_dy) = fd.x;
4137           val(pdf, 1, op_dy) = fd.y;
4138           val(pdf, 2, op_dy) = fd.z;
4139         }
4140       }
4141 
4142       if (whatd & Fop_dz) {
4143         for (int pdf = 0; pdf < 15; ++pdf) {
4144           int df = p[pdf];
4145           R3 fd(0., 0., 0.);
4146           if (df < 12) {
4147             fd = DzPm[fe[df]];    // edge function ..
4148           }
4149 
4150           for (int k = 0; k < 3; ++k) {
4151             fd += cf[df][k] * DzPm[k6[k]];
4152           }
4153 
4154           fd *= sg[df];
4155           val(pdf, 0, op_dz) = fd.x;
4156           val(pdf, 1, op_dz) = fd.y;
4157           val(pdf, 2, op_dz) = fd.z;
4158         }
4159       }
4160 
4161       if (whatd & Fop_D2) {
4162         cout << " to do FH RT2 dxx, dyy, dzz, dxy, dxz, dyz " << endl;
4163       }
4164     }
4165   }    // end basis functions declaration
4166 
4167   // add new FEs for DDM to build the partition of unity
4168   static TypeOfFE_P2Edge3ds0 Elm_P2Edge3ds0;
4169   // a static variable to add the finite element to freefem++
4170   static AddNewFE3 P2Edge3ds0("Edge23ds0", &Elm_P2Edge3ds0);
4171   // link with FreeFem++
4172   static TypeOfFE_P1Edge3ds0 Elm_P1Edge3ds0;
4173   // a static variable to add the finite element to freefem++
4174   static AddNewFE3 P1Edge3ds0("Edge13ds0", &Elm_P1Edge3ds0);
4175   // link with FreeFem++
4176   static TypeOfFE_P0Edge3ds0 Elm_P0Edge3ds0;
4177   // a static variable to add the finite element to freefem++
4178   static AddNewFE3 P0Edge3d("Edge03ds0", &Elm_P0Edge3ds0);
4179   static TypeOfFE_Edge1_3d Edge1_3d;    // TypeOfFE_Edge1_3d is the name of the class we defined
4180   GTypeOfFE< Mesh3 > &GEdge13d(Edge1_3d);    // GTypeOfFE<Mesh3> is the mother class
4181   static AddNewFE3 TypeOfFE_Edge1_3d("Edge13d",
4182                                      &GEdge13d);    // Edge13d will be the name used by the user
4183   static TypeOfFE_Edge2_3d Edge2_3d;
4184   GTypeOfFE< Mesh3 > &GEdge23d(Edge2_3d);
4185   static AddNewFE3 TypeOfFE_Edge2_3d("Edge23d", &GEdge23d);
4186   static TypeOfFE_RT1_3d RT1_3d;
4187   GTypeOfFE< Mesh3 > &RT13d(RT1_3d);
4188   static AddNewFE3 TypeOfFE_RT1_3d("RT13d", &RT13d);
4189 }    // namespace Fem2D
4190 
4191 // --- fin --
4192