MFEM  v3.2
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
fe.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Finite Element classes
13 
14 #include "fem.hpp"
15 #include <cmath>
16 
17 namespace mfem
18 {
19 
20 using namespace std;
21 
22 FiniteElement::FiniteElement(int D, int G, int Do, int O, int F)
23  : Nodes(Do)
24 {
25  Dim = D ; GeomType = G ; Dof = Do ; Order = O ; FuncSpace = F;
26  RangeType = SCALAR;
27  MapType = VALUE;
28 }
29 
31  const IntegrationPoint &ip, DenseMatrix &shape) const
32 {
33  mfem_error ("FiniteElement::CalcVShape (...)\n"
34  " is not implemented for this class!");
35 }
36 
39 {
40  mfem_error ("FiniteElement::CalcVShape 2 (...)\n"
41  " is not implemented for this class!");
42 }
43 
45  const IntegrationPoint &ip, Vector &divshape) const
46 {
47  mfem_error ("FiniteElement::CalcDivShape (...)\n"
48  " is not implemented for this class!");
49 }
50 
52  DenseMatrix &curl_shape) const
53 {
54  mfem_error ("FiniteElement::CalcCurlShape (...)\n"
55  " is not implemented for this class!");
56 }
57 
58 void FiniteElement::GetFaceDofs(int face, int **dofs, int *ndofs) const
59 {
60  mfem_error ("FiniteElement::GetFaceDofs (...)");
61 }
62 
64  DenseMatrix &h) const
65 {
66  mfem_error ("FiniteElement::CalcHessian (...) is not overloaded !");
67 }
68 
70  DenseMatrix &I) const
71 {
72  mfem_error ("GetLocalInterpolation (...) is not overloaded !");
73 }
74 
76  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
77 {
78  mfem_error ("FiniteElement::Project (...) is not overloaded !");
79 }
80 
83 {
84  mfem_error ("FiniteElement::Project (...) (vector) is not overloaded !");
85 }
86 
87 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
88 {
89  mfem_error("FiniteElement::ProjectDelta(...) is not implemented for "
90  "this element!");
91 }
92 
95 {
96  mfem_error("FiniteElement::Project(...) (fe version) is not implemented "
97  "for this element!");
98 }
99 
102  DenseMatrix &grad) const
103 {
104  mfem_error("FiniteElement::ProjectGrad(...) is not implemented for "
105  "this element!");
106 }
107 
110  DenseMatrix &curl) const
111 {
112  mfem_error("FiniteElement::ProjectCurl(...) is not implemented for "
113  "this element!");
114 }
115 
118  DenseMatrix &div) const
119 {
120  mfem_error("FiniteElement::ProjectDiv(...) is not implemented for "
121  "this element!");
122 }
123 
124 
127  const NodalFiniteElement &fine_fe) const
128 {
129  double v[3];
130  Vector vv (v, Dim);
131  IntegrationPoint f_ip;
132 
133 #ifdef MFEM_THREAD_SAFE
134  Vector c_shape(Dof);
135 #endif
136 
137  MFEM_ASSERT(MapType == fine_fe.GetMapType(), "");
138 
139  for (int i = 0; i < fine_fe.Dof; i++)
140  {
141  Trans.Transform (fine_fe.Nodes.IntPoint (i), vv);
142  f_ip.Set(v, Dim);
143  CalcShape (f_ip, c_shape);
144  for (int j = 0; j < Dof; j++)
145  if (fabs (I (i,j) = c_shape (j)) < 1.0e-12)
146  {
147  I (i,j) = 0.0;
148  }
149  }
150  if (MapType == INTEGRAL)
151  {
152  // assuming Trans is linear; this should be ok for all refinement types
154  I *= Trans.Weight();
155  }
156 }
157 
160  DenseMatrix &curl) const
161 {
162  MFEM_ASSERT(GetMapType() == FiniteElement::INTEGRAL, "");
163 
164  DenseMatrix curl_shape(fe.GetDof(), 1);
165 
166  curl.SetSize(Dof, fe.GetDof());
167  for (int i = 0; i < Dof; i++)
168  {
169  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
170  for (int j = 0; j < fe.GetDof(); j++)
171  {
172  curl(i,j) = curl_shape(j,0);
173  }
174  }
175 }
176 
178  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
179 {
180  for (int i = 0; i < Dof; i++)
181  {
182  const IntegrationPoint &ip = Nodes.IntPoint(i);
183  // some coefficients expect that Trans.IntPoint is the same
184  // as the second argument of Eval
185  Trans.SetIntPoint(&ip);
186  dofs(i) = coeff.Eval (Trans, ip);
187  if (MapType == INTEGRAL)
188  {
189  dofs(i) *= Trans.Weight();
190  }
191  }
192 }
193 
196 {
197  MFEM_ASSERT(vc.GetVDim() <= 3, "");
198 
199  double v[3];
200  Vector x (v, vc.GetVDim());
201 
202  for (int i = 0; i < Dof; i++)
203  {
204  const IntegrationPoint &ip = Nodes.IntPoint(i);
205  Trans.SetIntPoint(&ip);
206  vc.Eval (x, Trans, ip);
207  if (MapType == INTEGRAL)
208  {
209  x *= Trans.Weight();
210  }
211  for (int j = 0; j < x.Size(); j++)
212  {
213  dofs(Dof*j+i) = v[j];
214  }
215  }
216 }
217 
220 {
221  if (fe.GetRangeType() == SCALAR)
222  {
223  MFEM_ASSERT(MapType == fe.GetMapType(), "");
224 
225  Vector shape(fe.GetDof());
226 
227  I.SetSize(Dof, fe.GetDof());
228  for (int k = 0; k < Dof; k++)
229  {
230  fe.CalcShape(Nodes.IntPoint(k), shape);
231  for (int j = 0; j < shape.Size(); j++)
232  {
233  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
234  }
235  }
236  }
237  else
238  {
239  DenseMatrix vshape(fe.GetDof(), Dim);
240 
241  I.SetSize(Dim*Dof, fe.GetDof());
242  for (int k = 0; k < Dof; k++)
243  {
244  Trans.SetIntPoint(&Nodes.IntPoint(k));
245  fe.CalcVShape(Trans, vshape);
246  if (MapType == INTEGRAL)
247  {
248  vshape *= Trans.Weight();
249  }
250  for (int j = 0; j < vshape.Height(); j++)
251  for (int d = 0; d < vshape.Width(); d++)
252  {
253  I(k+d*Dof,j) = vshape(j,d);
254  }
255  }
256  }
257 }
258 
261  DenseMatrix &grad) const
262 {
263  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
264  MFEM_ASSERT(Trans.GetSpaceDim() == Dim, "")
265 
266  DenseMatrix dshape(fe.GetDof(), Dim), grad_k(fe.GetDof(), Dim), Jinv(Dim);
267 
268  grad.SetSize(Dim*Dof, fe.GetDof());
269  for (int k = 0; k < Dof; k++)
270  {
271  const IntegrationPoint &ip = Nodes.IntPoint(k);
272  fe.CalcDShape(ip, dshape);
273  Trans.SetIntPoint(&ip);
274  CalcInverse(Trans.Jacobian(), Jinv);
275  Mult(dshape, Jinv, grad_k);
276  if (MapType == INTEGRAL)
277  {
278  grad_k *= Trans.Weight();
279  }
280  for (int j = 0; j < grad_k.Height(); j++)
281  for (int d = 0; d < Dim; d++)
282  {
283  grad(k+d*Dof,j) = grad_k(j,d);
284  }
285  }
286 }
287 
290  DenseMatrix &div) const
291 {
292  double detJ;
293  Vector div_shape(fe.GetDof());
294 
295  div.SetSize(Dof, fe.GetDof());
296  for (int k = 0; k < Dof; k++)
297  {
298  const IntegrationPoint &ip = Nodes.IntPoint(k);
299  fe.CalcDivShape(ip, div_shape);
300  if (MapType == VALUE)
301  {
302  Trans.SetIntPoint(&ip);
303  detJ = Trans.Weight();
304  for (int j = 0; j < div_shape.Size(); j++)
305  {
306  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
307  }
308  }
309  else
310  {
311  for (int j = 0; j < div_shape.Size(); j++)
312  {
313  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
314  }
315  }
316  }
317 }
318 
319 
321  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
322 {
323  for (int i = 0; i < Dof; i++)
324  {
325  const IntegrationPoint &ip = Nodes.IntPoint(i);
326  Trans.SetIntPoint(&ip);
327  dofs(i) = coeff.Eval(Trans, ip);
328  }
329 }
330 
333 {
334  const NodalFiniteElement *nfe =
335  dynamic_cast<const NodalFiniteElement *>(&fe);
336 
337  if (nfe && Dof == nfe->GetDof())
338  {
339  nfe->Project(*this, Trans, I);
340  I.Invert();
341  }
342  else
343  {
344  // local L2 projection
345  DenseMatrix pos_mass, mixed_mass;
346  MassIntegrator mass_integ;
347 
348  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
349  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
350 
351  DenseMatrixInverse pos_mass_inv(pos_mass);
352  I.SetSize(Dof, fe.GetDof());
353  pos_mass_inv.Mult(mixed_mass, I);
354  }
355 }
356 
357 
358 void VectorFiniteElement::CalcShape (
359  const IntegrationPoint &ip, Vector &shape ) const
360 {
361  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
362  " VectorFiniteElements!");
363 }
364 
365 void VectorFiniteElement::CalcDShape (
366  const IntegrationPoint &ip, DenseMatrix &dshape ) const
367 {
368  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
369  " VectorFiniteElements!");
370 }
371 
373  ElementTransformation &Trans, DenseMatrix &shape) const
374 {
375 #ifdef MFEM_THREAD_SAFE
377 #endif
378  CalcVShape(Trans.GetIntPoint(), vshape);
379 
380  MultABt(vshape, Trans.Jacobian(), shape);
381 
382  shape *= (1.0 / Trans.Weight());
383 }
384 
386  ElementTransformation &Trans, DenseMatrix &shape) const
387 {
388  const DenseMatrix &J = Trans.Jacobian();
389 
390 #ifdef MFEM_THREAD_SAFE
392  DenseMatrix Jinv(J.Width(), J.Height());
393 #else
394  Jinv.SetSize(J.Width(), J.Height());
395 #endif
396 
397  CalcInverse(J, Jinv);
398 
399  CalcVShape(Trans.GetIntPoint(), vshape);
400 
401  Mult(vshape, Jinv, shape);
402 }
403 
405  const double *nk, const Array<int> &d2n,
407 {
408  double vk[3];
409  Vector xk(vk, vc.GetVDim());
410 #ifdef MFEM_THREAD_SAFE
411  DenseMatrix Jinv(Dim, vc.GetVDim());
412 #else
413  Jinv.SetSize(Dim, vc.GetVDim());
414 #endif
415  const bool square_J = (Jinv.Height() == Jinv.Width());
416 
417  for (int k = 0; k < Dof; k++)
418  {
419  Trans.SetIntPoint(&Nodes.IntPoint(k));
420  // set Jinv = |J| J^{-1} = adj(J), when J is square
421  // set Jinv = adj(J^t.J).J^t, otherwise
422  CalcAdjugate(Trans.Jacobian(), Jinv);
423 
424  vc.Eval(xk, Trans, Nodes.IntPoint(k));
425  // dof_k = nk^t adj(J) xk
426  dofs(k) = Jinv.InnerProduct(vk, nk + d2n[k]*Dim);
427  if (!square_J) { dofs(k) /= Trans.Weight(); }
428  }
429 }
430 
432  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
434 {
435  if (fe.GetRangeType() == SCALAR)
436  {
437  double vk[3];
438  Vector shape(fe.GetDof());
439  int sdim = Trans.GetSpaceDim();
440 #ifdef MFEM_THREAD_SAFE
441  DenseMatrix Jinv(Dim, sdim);
442 #endif
443 
444  I.SetSize(Dof, sdim*fe.GetDof());
445  for (int k = 0; k < Dof; k++)
446  {
447  const IntegrationPoint &ip = Nodes.IntPoint(k);
448 
449  fe.CalcShape(ip, shape);
450  Trans.SetIntPoint(&ip);
451  CalcAdjugate(Trans.Jacobian(), Jinv);
452  Jinv.MultTranspose(nk + d2n[k]*Dim, vk);
453  if (fe.GetMapType() == INTEGRAL)
454  {
455  double w = 1.0/Trans.Weight();
456  for (int d = 0; d < Dim; d++)
457  {
458  vk[d] *= w;
459  }
460  }
461 
462  for (int j = 0; j < shape.Size(); j++)
463  {
464  double s = shape(j);
465  if (fabs(s) < 1e-12)
466  {
467  s = 0.0;
468  }
469  for (int d = 0; d < sdim; d++)
470  {
471  I(k,j+d*shape.Size()) = s*vk[d];
472  }
473  }
474  }
475  }
476  else
477  {
478  mfem_error("VectorFiniteElement::Project_RT (fe version)");
479  }
480 }
481 
483  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
485 {
486  if (Dim != 2)
487  {
488  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
489  }
490 
491  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
492  Vector grad_k(fe.GetDof());
493  double tk[2];
494 
495  grad.SetSize(Dof, fe.GetDof());
496  for (int k = 0; k < Dof; k++)
497  {
498  fe.CalcDShape(Nodes.IntPoint(k), dshape);
499  tk[0] = nk[d2n[k]*Dim+1];
500  tk[1] = -nk[d2n[k]*Dim];
501  dshape.Mult(tk, grad_k);
502  for (int j = 0; j < grad_k.Size(); j++)
503  {
504  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
505  }
506  }
507 }
508 
510  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
512 {
513 #ifdef MFEM_THREAD_SAFE
516  DenseMatrix J(Dim, Dim);
517 #else
518  curlshape.SetSize(fe.GetDof(), Dim);
519  curlshape_J.SetSize(fe.GetDof(), Dim);
520  J.SetSize(Dim, Dim);
521 #endif
522 
523  Vector curl_k(fe.GetDof());
524 
525  curl.SetSize(Dof, fe.GetDof());
526  for (int k = 0; k < Dof; k++)
527  {
528  const IntegrationPoint &ip = Nodes.IntPoint(k);
529 
530  // calculate J^t * J / |J|
531  Trans.SetIntPoint(&ip);
532  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
533  J *= 1.0 / Trans.Weight();
534 
535  // transform curl of shapes (rows) by J^t * J / |J|
536  fe.CalcCurlShape(ip, curlshape);
538 
539  curlshape_J.Mult(tk + d2t[k]*Dim, curl_k);
540  for (int j = 0; j < curl_k.Size(); j++)
541  {
542  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
543  }
544  }
545 }
546 
548  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
550 {
551  DenseMatrix curl_shape(fe.GetDof(), Dim);
552  Vector curl_k(fe.GetDof());
553 
554  curl.SetSize(Dof, fe.GetDof());
555  for (int k = 0; k < Dof; k++)
556  {
557  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
558  curl_shape.Mult(nk + d2n[k]*Dim, curl_k);
559  for (int j = 0; j < curl_k.Size(); j++)
560  {
561  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
562  }
563  }
564 }
565 
567  const double *tk, const Array<int> &d2t,
569 {
570  double vk[3];
571  Vector xk(vk, vc.GetVDim());
572 
573  for (int k = 0; k < Dof; k++)
574  {
575  Trans.SetIntPoint(&Nodes.IntPoint(k));
576 
577  vc.Eval(xk, Trans, Nodes.IntPoint(k));
578  // dof_k = xk^t J tk
579  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*Dim, vk);
580  }
581 }
582 
584  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
586 {
587  if (fe.GetRangeType() == SCALAR)
588  {
589  int sdim = Trans.GetSpaceDim();
590  double vk[3];
591  Vector shape(fe.GetDof());
592 
593  I.SetSize(Dof, sdim*fe.GetDof());
594  for (int k = 0; k < Dof; k++)
595  {
596  const IntegrationPoint &ip = Nodes.IntPoint(k);
597 
598  fe.CalcShape(ip, shape);
599  Trans.SetIntPoint(&ip);
600  Trans.Jacobian().Mult(tk + d2t[k]*Dim, vk);
601  if (fe.GetMapType() == INTEGRAL)
602  {
603  double w = 1.0/Trans.Weight();
604  for (int d = 0; d < sdim; d++)
605  {
606  vk[d] *= w;
607  }
608  }
609 
610  for (int j = 0; j < shape.Size(); j++)
611  {
612  double s = shape(j);
613  if (fabs(s) < 1e-12)
614  {
615  s = 0.0;
616  }
617  for (int d = 0; d < sdim; d++)
618  {
619  I(k, j + d*shape.Size()) = s*vk[d];
620  }
621  }
622  }
623  }
624  else
625  {
626  mfem_error("VectorFiniteElement::Project_ND (fe version)");
627  }
628 }
629 
631  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
633 {
634  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
635 
636  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
637  Vector grad_k(fe.GetDof());
638 
639  grad.SetSize(Dof, fe.GetDof());
640  for (int k = 0; k < Dof; k++)
641  {
642  fe.CalcDShape(Nodes.IntPoint(k), dshape);
643  dshape.Mult(tk + d2t[k]*Dim, grad_k);
644  for (int j = 0; j < grad_k.Size(); j++)
645  {
646  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
647  }
648  }
649 }
650 
652  const double *nk, const Array<int> &d2n, ElementTransformation &Trans,
653  DenseMatrix &I) const
654 {
655  double vk[3];
656  Vector xk(vk, Dim);
657  IntegrationPoint ip;
658 #ifdef MFEM_THREAD_SAFE
661 #endif
662 
663  // assuming Trans is linear; this should be ok for all refinement types
665  // set Jinv = |J| J^{-t} = adj(J)^t
667  for (int k = 0; k < Dof; k++)
668  {
669  Trans.Transform(Nodes.IntPoint(k), xk);
670  ip.Set3(vk);
671  CalcVShape(ip, vshape);
672  // xk = |J| J^{-t} n_k
673  Jinv.Mult(nk + d2n[k]*Dim, vk);
674  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,Dof
675  for (int j = 0; j < Dof; j++)
676  {
677  double Ikj = 0.;
678  for (int i = 0; i < Dim; i++)
679  {
680  Ikj += vshape(j, i) * vk[i];
681  }
682  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
683  }
684  }
685 }
686 
688  const double *tk, const Array<int> &d2t, ElementTransformation &Trans,
689  DenseMatrix &I) const
690 {
691  double vk[3];
692  Vector xk(vk, Dim);
693  IntegrationPoint ip;
694 #ifdef MFEM_THREAD_SAFE
696 #endif
697 
698  // assuming Trans is linear; this should be ok for all refinement types
700  const DenseMatrix &J = Trans.Jacobian();
701  for (int k = 0; k < Dof; k++)
702  {
703  Trans.Transform(Nodes.IntPoint(k), xk);
704  ip.Set3(vk);
705  CalcVShape(ip, vshape);
706  // xk = J t_k
707  J.Mult(tk + d2t[k]*Dim, vk);
708  // I_k = vshape_k.J.t_k, k=1,...,Dof
709  for (int j = 0; j < Dof; j++)
710  {
711  double Ikj = 0.;
712  for (int i = 0; i < Dim; i++)
713  {
714  Ikj += vshape(j, i) * vk[i];
715  }
716  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
717  }
718  }
719 }
720 
721 
723  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
724 {
725  Nodes.IntPoint(0).x = 0.0;
726 }
727 
729  Vector &shape) const
730 {
731  shape(0) = 1.;
732 }
733 
735  DenseMatrix &dshape) const
736 {
737  // doesn't make sense
738 }
739 
741  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
742 {
743  Nodes.IntPoint(0).x = 0.0;
744  Nodes.IntPoint(1).x = 1.0;
745 }
746 
748  Vector &shape) const
749 {
750  shape(0) = 1. - ip.x;
751  shape(1) = ip.x;
752 }
753 
755  DenseMatrix &dshape) const
756 {
757  dshape(0,0) = -1.;
758  dshape(1,0) = 1.;
759 }
760 
762  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
763 {
764  Nodes.IntPoint(0).x = 0.0;
765  Nodes.IntPoint(0).y = 0.0;
766  Nodes.IntPoint(1).x = 1.0;
767  Nodes.IntPoint(1).y = 0.0;
768  Nodes.IntPoint(2).x = 0.0;
769  Nodes.IntPoint(2).y = 1.0;
770 }
771 
773  Vector &shape) const
774 {
775  shape(0) = 1. - ip.x - ip.y;
776  shape(1) = ip.x;
777  shape(2) = ip.y;
778 }
779 
781  DenseMatrix &dshape) const
782 {
783  dshape(0,0) = -1.; dshape(0,1) = -1.;
784  dshape(1,0) = 1.; dshape(1,1) = 0.;
785  dshape(2,0) = 0.; dshape(2,1) = 1.;
786 }
787 
789  : NodalFiniteElement(2, Geometry::SQUARE , 4, 1, FunctionSpace::Qk)
790 {
791  Nodes.IntPoint(0).x = 0.0;
792  Nodes.IntPoint(0).y = 0.0;
793  Nodes.IntPoint(1).x = 1.0;
794  Nodes.IntPoint(1).y = 0.0;
795  Nodes.IntPoint(2).x = 1.0;
796  Nodes.IntPoint(2).y = 1.0;
797  Nodes.IntPoint(3).x = 0.0;
798  Nodes.IntPoint(3).y = 1.0;
799 }
800 
802  Vector &shape) const
803 {
804  shape(0) = (1. - ip.x) * (1. - ip.y) ;
805  shape(1) = ip.x * (1. - ip.y) ;
806  shape(2) = ip.x * ip.y ;
807  shape(3) = (1. - ip.x) * ip.y ;
808 }
809 
811  DenseMatrix &dshape) const
812 {
813  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
814  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
815  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
816  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
817 }
818 
820  const IntegrationPoint &ip, DenseMatrix &h) const
821 {
822  h( 0,0) = 0.; h( 0,1) = 1.; h( 0,2) = 0.;
823  h( 1,0) = 0.; h( 1,1) = -1.; h( 1,2) = 0.;
824  h( 2,0) = 0.; h( 2,1) = 1.; h( 2,2) = 0.;
825  h( 3,0) = 0.; h( 3,1) = -1.; h( 3,2) = 0.;
826 }
827 
828 
830  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
831 {
832  Nodes.IntPoint(0).x = 1./6.;
833  Nodes.IntPoint(0).y = 1./6.;
834  Nodes.IntPoint(1).x = 2./3.;
835  Nodes.IntPoint(1).y = 1./6.;
836  Nodes.IntPoint(2).x = 1./6.;
837  Nodes.IntPoint(2).y = 2./3.;
838 }
839 
841  Vector &shape) const
842 {
843  const double x = ip.x, y = ip.y;
844 
845  shape(0) = 5./3. - 2. * (x + y);
846  shape(1) = 2. * (x - 1./6.);
847  shape(2) = 2. * (y - 1./6.);
848 }
849 
851  DenseMatrix &dshape) const
852 {
853  dshape(0,0) = -2.; dshape(0,1) = -2.;
854  dshape(1,0) = 2.; dshape(1,1) = 0.;
855  dshape(2,0) = 0.; dshape(2,1) = 2.;
856 }
857 
859 {
860  dofs(vertex) = 2./3.;
861  dofs((vertex+1)%3) = 1./6.;
862  dofs((vertex+2)%3) = 1./6.;
863 }
864 
865 
866 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
867 const double GaussBiLinear2DFiniteElement::p[] =
868 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
869 
871  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
872 {
873  Nodes.IntPoint(0).x = p[0];
874  Nodes.IntPoint(0).y = p[0];
875  Nodes.IntPoint(1).x = p[1];
876  Nodes.IntPoint(1).y = p[0];
877  Nodes.IntPoint(2).x = p[1];
878  Nodes.IntPoint(2).y = p[1];
879  Nodes.IntPoint(3).x = p[0];
880  Nodes.IntPoint(3).y = p[1];
881 }
882 
884  Vector &shape) const
885 {
886  const double x = ip.x, y = ip.y;
887 
888  shape(0) = 3. * (p[1] - x) * (p[1] - y);
889  shape(1) = 3. * (x - p[0]) * (p[1] - y);
890  shape(2) = 3. * (x - p[0]) * (y - p[0]);
891  shape(3) = 3. * (p[1] - x) * (y - p[0]);
892 }
893 
895  DenseMatrix &dshape) const
896 {
897  const double x = ip.x, y = ip.y;
898 
899  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
900  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
901  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
902  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
903 }
904 
906 {
907 #if 1
908  dofs(vertex) = p[1]*p[1];
909  dofs((vertex+1)%4) = p[0]*p[1];
910  dofs((vertex+2)%4) = p[0]*p[0];
911  dofs((vertex+3)%4) = p[0]*p[1];
912 #else
913  dofs = 1.0;
914 #endif
915 }
916 
917 
919  : NodalFiniteElement(2, Geometry::SQUARE , 3, 1, FunctionSpace::Qk)
920 {
921  Nodes.IntPoint(0).x = 0.0;
922  Nodes.IntPoint(0).y = 0.0;
923  Nodes.IntPoint(1).x = 1.0;
924  Nodes.IntPoint(1).y = 0.0;
925  Nodes.IntPoint(2).x = 0.0;
926  Nodes.IntPoint(2).y = 1.0;
927 }
928 
930  Vector &shape) const
931 {
932  shape(0) = 1. - ip.x - ip.y;
933  shape(1) = ip.x;
934  shape(2) = ip.y;
935 }
936 
938  DenseMatrix &dshape) const
939 {
940  dshape(0,0) = -1.; dshape(0,1) = -1.;
941  dshape(1,0) = 1.; dshape(1,1) = 0.;
942  dshape(2,0) = 0.; dshape(2,1) = 1.;
943 }
944 
945 
947  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
948 {
949  Nodes.IntPoint(0).x = 0.0;
950  Nodes.IntPoint(1).x = 1.0;
951  Nodes.IntPoint(2).x = 0.5;
952 }
953 
955  Vector &shape) const
956 {
957  double x = ip.x;
958  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
959 
960  shape(0) = l1 * (-l3);
961  shape(1) = l2 * l3;
962  shape(2) = 4. * l1 * l2;
963 }
964 
966  DenseMatrix &dshape) const
967 {
968  double x = ip.x;
969 
970  dshape(0,0) = 4. * x - 3.;
971  dshape(1,0) = 4. * x - 1.;
972  dshape(2,0) = 4. - 8. * x;
973 }
974 
975 
977  : FiniteElement(1, Geometry::SEGMENT, 3, 2)
978 {
979  Nodes.IntPoint(0).x = 0.0;
980  Nodes.IntPoint(1).x = 1.0;
981  Nodes.IntPoint(2).x = 0.5;
982 }
983 
985  Vector &shape) const
986 {
987  const double x = ip.x, x1 = 1. - x;
988 
989  shape(0) = x1 * x1;
990  shape(1) = x * x;
991  shape(2) = 2. * x * x1;
992 }
993 
995  DenseMatrix &dshape) const
996 {
997  const double x = ip.x;
998 
999  dshape(0,0) = 2. * x - 2.;
1000  dshape(1,0) = 2. * x;
1001  dshape(2,0) = 2. - 4. * x;
1002 }
1003 
1005  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1006 {
1007  Nodes.IntPoint(0).x = 0.0;
1008  Nodes.IntPoint(0).y = 0.0;
1009  Nodes.IntPoint(1).x = 1.0;
1010  Nodes.IntPoint(1).y = 0.0;
1011  Nodes.IntPoint(2).x = 0.0;
1012  Nodes.IntPoint(2).y = 1.0;
1013  Nodes.IntPoint(3).x = 0.5;
1014  Nodes.IntPoint(3).y = 0.0;
1015  Nodes.IntPoint(4).x = 0.5;
1016  Nodes.IntPoint(4).y = 0.5;
1017  Nodes.IntPoint(5).x = 0.0;
1018  Nodes.IntPoint(5).y = 0.5;
1019 }
1020 
1022  Vector &shape) const
1023 {
1024  double x = ip.x, y = ip.y;
1025  double l1 = 1.-x-y, l2 = x, l3 = y;
1026 
1027  shape(0) = l1 * (2. * l1 - 1.);
1028  shape(1) = l2 * (2. * l2 - 1.);
1029  shape(2) = l3 * (2. * l3 - 1.);
1030  shape(3) = 4. * l1 * l2;
1031  shape(4) = 4. * l2 * l3;
1032  shape(5) = 4. * l3 * l1;
1033 }
1034 
1036  DenseMatrix &dshape) const
1037 {
1038  double x = ip.x, y = ip.y;
1039 
1040  dshape(0,0) =
1041  dshape(0,1) = 4. * (x + y) - 3.;
1042 
1043  dshape(1,0) = 4. * x - 1.;
1044  dshape(1,1) = 0.;
1045 
1046  dshape(2,0) = 0.;
1047  dshape(2,1) = 4. * y - 1.;
1048 
1049  dshape(3,0) = -4. * (2. * x + y - 1.);
1050  dshape(3,1) = -4. * x;
1051 
1052  dshape(4,0) = 4. * y;
1053  dshape(4,1) = 4. * x;
1054 
1055  dshape(5,0) = -4. * y;
1056  dshape(5,1) = -4. * (x + 2. * y - 1.);
1057 }
1058 
1060  DenseMatrix &h) const
1061 {
1062  h(0,0) = 4.;
1063  h(0,1) = 4.;
1064  h(0,2) = 4.;
1065 
1066  h(1,0) = 4.;
1067  h(1,1) = 0.;
1068  h(1,2) = 0.;
1069 
1070  h(2,0) = 0.;
1071  h(2,1) = 0.;
1072  h(2,2) = 4.;
1073 
1074  h(3,0) = -8.;
1075  h(3,1) = -4.;
1076  h(3,2) = 0.;
1077 
1078  h(4,0) = 0.;
1079  h(4,1) = 4.;
1080  h(4,2) = 0.;
1081 
1082  h(5,0) = 0.;
1083  h(5,1) = -4.;
1084  h(5,2) = -8.;
1085 }
1086 
1087 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1088 {
1089 #if 0
1090  dofs = 1.;
1091 #else
1092  dofs = 0.;
1093  dofs(vertex) = 1.;
1094  switch (vertex)
1095  {
1096  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1097  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1098  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1099  }
1100 #endif
1101 }
1102 
1103 
1104 const double GaussQuad2DFiniteElement::p[] =
1105 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1106 
1108  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1109 {
1110  Nodes.IntPoint(0).x = p[0];
1111  Nodes.IntPoint(0).y = p[0];
1112  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1113  Nodes.IntPoint(1).y = p[0];
1114  Nodes.IntPoint(2).x = p[0];
1115  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1116  Nodes.IntPoint(3).x = p[1];
1117  Nodes.IntPoint(3).y = p[1];
1118  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1119  Nodes.IntPoint(4).y = p[1];
1120  Nodes.IntPoint(5).x = p[1];
1121  Nodes.IntPoint(5).y = 1. - 2. * p[1];
1122 
1123  for (int i = 0; i < 6; i++)
1124  {
1125  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
1126  A(0,i) = 1.;
1127  A(1,i) = x;
1128  A(2,i) = y;
1129  A(3,i) = x * x;
1130  A(4,i) = x * y;
1131  A(5,i) = y * y;
1132  }
1133 
1134  A.Invert();
1135 }
1136 
1138  Vector &shape) const
1139 {
1140  const double x = ip.x, y = ip.y;
1141  pol(0) = 1.;
1142  pol(1) = x;
1143  pol(2) = y;
1144  pol(3) = x * x;
1145  pol(4) = x * y;
1146  pol(5) = y * y;
1147 
1148  A.Mult(pol, shape);
1149 }
1150 
1152  DenseMatrix &dshape) const
1153 {
1154  const double x = ip.x, y = ip.y;
1155  D(0,0) = 0.; D(0,1) = 0.;
1156  D(1,0) = 1.; D(1,1) = 0.;
1157  D(2,0) = 0.; D(2,1) = 1.;
1158  D(3,0) = 2. * x; D(3,1) = 0.;
1159  D(4,0) = y; D(4,1) = x;
1160  D(5,0) = 0.; D(5,1) = 2. * y;
1161 
1162  Mult(A, D, dshape);
1163 }
1164 
1165 
1167  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1168 {
1169  Nodes.IntPoint(0).x = 0.0;
1170  Nodes.IntPoint(0).y = 0.0;
1171  Nodes.IntPoint(1).x = 1.0;
1172  Nodes.IntPoint(1).y = 0.0;
1173  Nodes.IntPoint(2).x = 1.0;
1174  Nodes.IntPoint(2).y = 1.0;
1175  Nodes.IntPoint(3).x = 0.0;
1176  Nodes.IntPoint(3).y = 1.0;
1177  Nodes.IntPoint(4).x = 0.5;
1178  Nodes.IntPoint(4).y = 0.0;
1179  Nodes.IntPoint(5).x = 1.0;
1180  Nodes.IntPoint(5).y = 0.5;
1181  Nodes.IntPoint(6).x = 0.5;
1182  Nodes.IntPoint(6).y = 1.0;
1183  Nodes.IntPoint(7).x = 0.0;
1184  Nodes.IntPoint(7).y = 0.5;
1185  Nodes.IntPoint(8).x = 0.5;
1186  Nodes.IntPoint(8).y = 0.5;
1187 }
1188 
1190  Vector &shape) const
1191 {
1192  double x = ip.x, y = ip.y;
1193  double l1x, l2x, l3x, l1y, l2y, l3y;
1194 
1195  l1x = (x - 1.) * (2. * x - 1);
1196  l2x = 4. * x * (1. - x);
1197  l3x = x * (2. * x - 1.);
1198  l1y = (y - 1.) * (2. * y - 1);
1199  l2y = 4. * y * (1. - y);
1200  l3y = y * (2. * y - 1.);
1201 
1202  shape(0) = l1x * l1y;
1203  shape(4) = l2x * l1y;
1204  shape(1) = l3x * l1y;
1205  shape(7) = l1x * l2y;
1206  shape(8) = l2x * l2y;
1207  shape(5) = l3x * l2y;
1208  shape(3) = l1x * l3y;
1209  shape(6) = l2x * l3y;
1210  shape(2) = l3x * l3y;
1211 }
1212 
1214  DenseMatrix &dshape) const
1215 {
1216  double x = ip.x, y = ip.y;
1217  double l1x, l2x, l3x, l1y, l2y, l3y;
1218  double d1x, d2x, d3x, d1y, d2y, d3y;
1219 
1220  l1x = (x - 1.) * (2. * x - 1);
1221  l2x = 4. * x * (1. - x);
1222  l3x = x * (2. * x - 1.);
1223  l1y = (y - 1.) * (2. * y - 1);
1224  l2y = 4. * y * (1. - y);
1225  l3y = y * (2. * y - 1.);
1226 
1227  d1x = 4. * x - 3.;
1228  d2x = 4. - 8. * x;
1229  d3x = 4. * x - 1.;
1230  d1y = 4. * y - 3.;
1231  d2y = 4. - 8. * y;
1232  d3y = 4. * y - 1.;
1233 
1234  dshape(0,0) = d1x * l1y;
1235  dshape(0,1) = l1x * d1y;
1236 
1237  dshape(4,0) = d2x * l1y;
1238  dshape(4,1) = l2x * d1y;
1239 
1240  dshape(1,0) = d3x * l1y;
1241  dshape(1,1) = l3x * d1y;
1242 
1243  dshape(7,0) = d1x * l2y;
1244  dshape(7,1) = l1x * d2y;
1245 
1246  dshape(8,0) = d2x * l2y;
1247  dshape(8,1) = l2x * d2y;
1248 
1249  dshape(5,0) = d3x * l2y;
1250  dshape(5,1) = l3x * d2y;
1251 
1252  dshape(3,0) = d1x * l3y;
1253  dshape(3,1) = l1x * d3y;
1254 
1255  dshape(6,0) = d2x * l3y;
1256  dshape(6,1) = l2x * d3y;
1257 
1258  dshape(2,0) = d3x * l3y;
1259  dshape(2,1) = l3x * d3y;
1260 }
1261 
1262 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1263 {
1264 #if 0
1265  dofs = 1.;
1266 #else
1267  dofs = 0.;
1268  dofs(vertex) = 1.;
1269  switch (vertex)
1270  {
1271  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
1272  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
1273  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
1274  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
1275  }
1276  dofs(8) = 1./16.;
1277 #endif
1278 }
1279 
1281  : FiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1282 {
1283  Nodes.IntPoint(0).x = 0.0;
1284  Nodes.IntPoint(0).y = 0.0;
1285  Nodes.IntPoint(1).x = 1.0;
1286  Nodes.IntPoint(1).y = 0.0;
1287  Nodes.IntPoint(2).x = 1.0;
1288  Nodes.IntPoint(2).y = 1.0;
1289  Nodes.IntPoint(3).x = 0.0;
1290  Nodes.IntPoint(3).y = 1.0;
1291  Nodes.IntPoint(4).x = 0.5;
1292  Nodes.IntPoint(4).y = 0.0;
1293  Nodes.IntPoint(5).x = 1.0;
1294  Nodes.IntPoint(5).y = 0.5;
1295  Nodes.IntPoint(6).x = 0.5;
1296  Nodes.IntPoint(6).y = 1.0;
1297  Nodes.IntPoint(7).x = 0.0;
1298  Nodes.IntPoint(7).y = 0.5;
1299  Nodes.IntPoint(8).x = 0.5;
1300  Nodes.IntPoint(8).y = 0.5;
1301 }
1302 
1304  Vector &shape) const
1305 {
1306  double x = ip.x, y = ip.y;
1307  double l1x, l2x, l3x, l1y, l2y, l3y;
1308 
1309  l1x = (1. - x) * (1. - x);
1310  l2x = 2. * x * (1. - x);
1311  l3x = x * x;
1312  l1y = (1. - y) * (1. - y);
1313  l2y = 2. * y * (1. - y);
1314  l3y = y * y;
1315 
1316  shape(0) = l1x * l1y;
1317  shape(4) = l2x * l1y;
1318  shape(1) = l3x * l1y;
1319  shape(7) = l1x * l2y;
1320  shape(8) = l2x * l2y;
1321  shape(5) = l3x * l2y;
1322  shape(3) = l1x * l3y;
1323  shape(6) = l2x * l3y;
1324  shape(2) = l3x * l3y;
1325 }
1326 
1328  DenseMatrix &dshape) const
1329 {
1330  double x = ip.x, y = ip.y;
1331  double l1x, l2x, l3x, l1y, l2y, l3y;
1332  double d1x, d2x, d3x, d1y, d2y, d3y;
1333 
1334  l1x = (1. - x) * (1. - x);
1335  l2x = 2. * x * (1. - x);
1336  l3x = x * x;
1337  l1y = (1. - y) * (1. - y);
1338  l2y = 2. * y * (1. - y);
1339  l3y = y * y;
1340 
1341  d1x = 2. * x - 2.;
1342  d2x = 2. - 4. * x;
1343  d3x = 2. * x;
1344  d1y = 2. * y - 2.;
1345  d2y = 2. - 4. * y;
1346  d3y = 2. * y;
1347 
1348  dshape(0,0) = d1x * l1y;
1349  dshape(0,1) = l1x * d1y;
1350 
1351  dshape(4,0) = d2x * l1y;
1352  dshape(4,1) = l2x * d1y;
1353 
1354  dshape(1,0) = d3x * l1y;
1355  dshape(1,1) = l3x * d1y;
1356 
1357  dshape(7,0) = d1x * l2y;
1358  dshape(7,1) = l1x * d2y;
1359 
1360  dshape(8,0) = d2x * l2y;
1361  dshape(8,1) = l2x * d2y;
1362 
1363  dshape(5,0) = d3x * l2y;
1364  dshape(5,1) = l3x * d2y;
1365 
1366  dshape(3,0) = d1x * l3y;
1367  dshape(3,1) = l1x * d3y;
1368 
1369  dshape(6,0) = d2x * l3y;
1370  dshape(6,1) = l2x * d3y;
1371 
1372  dshape(2,0) = d3x * l3y;
1373  dshape(2,1) = l3x * d3y;
1374 }
1375 
1378 {
1379  double s[9];
1380  IntegrationPoint tr_ip;
1381  Vector xx(&tr_ip.x, 2), shape(s, 9);
1382 
1383  for (int i = 0; i < 9; i++)
1384  {
1385  Trans.Transform(Nodes.IntPoint(i), xx);
1386  CalcShape(tr_ip, shape);
1387  for (int j = 0; j < 9; j++)
1388  if (fabs(I(i,j) = s[j]) < 1.0e-12)
1389  {
1390  I(i,j) = 0.0;
1391  }
1392  }
1393  for (int i = 0; i < 9; i++)
1394  {
1395  double *d = &I(0,i);
1396  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1397  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1398  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1399  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1400  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1401  0.25 * (d[0] + d[1] + d[2] + d[3]);
1402  }
1403 }
1404 
1406  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
1407 {
1408  double *d = dofs;
1409 
1410  for (int i = 0; i < 9; i++)
1411  {
1412  const IntegrationPoint &ip = Nodes.IntPoint(i);
1413  Trans.SetIntPoint(&ip);
1414  d[i] = coeff.Eval(Trans, ip);
1415  }
1416  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1417  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1418  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1419  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1420  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1421  0.25 * (d[0] + d[1] + d[2] + d[3]);
1422 }
1423 
1426  Vector &dofs) const
1427 {
1428  double v[3];
1429  Vector x (v, vc.GetVDim());
1430 
1431  for (int i = 0; i < 9; i++)
1432  {
1433  const IntegrationPoint &ip = Nodes.IntPoint(i);
1434  Trans.SetIntPoint(&ip);
1435  vc.Eval (x, Trans, ip);
1436  for (int j = 0; j < x.Size(); j++)
1437  {
1438  dofs(9*j+i) = v[j];
1439  }
1440  }
1441  for (int j = 0; j < x.Size(); j++)
1442  {
1443  double *d = &dofs(9*j);
1444 
1445  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1446  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1447  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1448  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1449  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1450  0.25 * (d[0] + d[1] + d[2] + d[3]);
1451  }
1452 }
1453 
1454 
1456  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1457 {
1458  const double p1 = 0.5*(1.-sqrt(3./5.));
1459 
1460  Nodes.IntPoint(0).x = p1;
1461  Nodes.IntPoint(0).y = p1;
1462  Nodes.IntPoint(4).x = 0.5;
1463  Nodes.IntPoint(4).y = p1;
1464  Nodes.IntPoint(1).x = 1.-p1;
1465  Nodes.IntPoint(1).y = p1;
1466  Nodes.IntPoint(7).x = p1;
1467  Nodes.IntPoint(7).y = 0.5;
1468  Nodes.IntPoint(8).x = 0.5;
1469  Nodes.IntPoint(8).y = 0.5;
1470  Nodes.IntPoint(5).x = 1.-p1;
1471  Nodes.IntPoint(5).y = 0.5;
1472  Nodes.IntPoint(3).x = p1;
1473  Nodes.IntPoint(3).y = 1.-p1;
1474  Nodes.IntPoint(6).x = 0.5;
1475  Nodes.IntPoint(6).y = 1.-p1;
1476  Nodes.IntPoint(2).x = 1.-p1;
1477  Nodes.IntPoint(2).y = 1.-p1;
1478 }
1479 
1481  Vector &shape) const
1482 {
1483  const double a = sqrt(5./3.);
1484  const double p1 = 0.5*(1.-sqrt(3./5.));
1485 
1486  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1487  double l1x, l2x, l3x, l1y, l2y, l3y;
1488 
1489  l1x = (x - 1.) * (2. * x - 1);
1490  l2x = 4. * x * (1. - x);
1491  l3x = x * (2. * x - 1.);
1492  l1y = (y - 1.) * (2. * y - 1);
1493  l2y = 4. * y * (1. - y);
1494  l3y = y * (2. * y - 1.);
1495 
1496  shape(0) = l1x * l1y;
1497  shape(4) = l2x * l1y;
1498  shape(1) = l3x * l1y;
1499  shape(7) = l1x * l2y;
1500  shape(8) = l2x * l2y;
1501  shape(5) = l3x * l2y;
1502  shape(3) = l1x * l3y;
1503  shape(6) = l2x * l3y;
1504  shape(2) = l3x * l3y;
1505 }
1506 
1508  DenseMatrix &dshape) const
1509 {
1510  const double a = sqrt(5./3.);
1511  const double p1 = 0.5*(1.-sqrt(3./5.));
1512 
1513  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1514  double l1x, l2x, l3x, l1y, l2y, l3y;
1515  double d1x, d2x, d3x, d1y, d2y, d3y;
1516 
1517  l1x = (x - 1.) * (2. * x - 1);
1518  l2x = 4. * x * (1. - x);
1519  l3x = x * (2. * x - 1.);
1520  l1y = (y - 1.) * (2. * y - 1);
1521  l2y = 4. * y * (1. - y);
1522  l3y = y * (2. * y - 1.);
1523 
1524  d1x = a * (4. * x - 3.);
1525  d2x = a * (4. - 8. * x);
1526  d3x = a * (4. * x - 1.);
1527  d1y = a * (4. * y - 3.);
1528  d2y = a * (4. - 8. * y);
1529  d3y = a * (4. * y - 1.);
1530 
1531  dshape(0,0) = d1x * l1y;
1532  dshape(0,1) = l1x * d1y;
1533 
1534  dshape(4,0) = d2x * l1y;
1535  dshape(4,1) = l2x * d1y;
1536 
1537  dshape(1,0) = d3x * l1y;
1538  dshape(1,1) = l3x * d1y;
1539 
1540  dshape(7,0) = d1x * l2y;
1541  dshape(7,1) = l1x * d2y;
1542 
1543  dshape(8,0) = d2x * l2y;
1544  dshape(8,1) = l2x * d2y;
1545 
1546  dshape(5,0) = d3x * l2y;
1547  dshape(5,1) = l3x * d2y;
1548 
1549  dshape(3,0) = d1x * l3y;
1550  dshape(3,1) = l1x * d3y;
1551 
1552  dshape(6,0) = d2x * l3y;
1553  dshape(6,1) = l2x * d3y;
1554 
1555  dshape(2,0) = d3x * l3y;
1556  dshape(2,1) = l3x * d3y;
1557 }
1558 
1560  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
1561 {
1562  Nodes.IntPoint(0).x = 0.;
1563  Nodes.IntPoint(0).y = 0.;
1564  Nodes.IntPoint(1).x = 1.;
1565  Nodes.IntPoint(1).y = 0.;
1566  Nodes.IntPoint(2).x = 1.;
1567  Nodes.IntPoint(2).y = 1.;
1568  Nodes.IntPoint(3).x = 0.;
1569  Nodes.IntPoint(3).y = 1.;
1570  Nodes.IntPoint(4).x = 1./3.;
1571  Nodes.IntPoint(4).y = 0.;
1572  Nodes.IntPoint(5).x = 2./3.;
1573  Nodes.IntPoint(5).y = 0.;
1574  Nodes.IntPoint(6).x = 1.;
1575  Nodes.IntPoint(6).y = 1./3.;
1576  Nodes.IntPoint(7).x = 1.;
1577  Nodes.IntPoint(7).y = 2./3.;
1578  Nodes.IntPoint(8).x = 2./3.;
1579  Nodes.IntPoint(8).y = 1.;
1580  Nodes.IntPoint(9).x = 1./3.;
1581  Nodes.IntPoint(9).y = 1.;
1582  Nodes.IntPoint(10).x = 0.;
1583  Nodes.IntPoint(10).y = 2./3.;
1584  Nodes.IntPoint(11).x = 0.;
1585  Nodes.IntPoint(11).y = 1./3.;
1586  Nodes.IntPoint(12).x = 1./3.;
1587  Nodes.IntPoint(12).y = 1./3.;
1588  Nodes.IntPoint(13).x = 2./3.;
1589  Nodes.IntPoint(13).y = 1./3.;
1590  Nodes.IntPoint(14).x = 1./3.;
1591  Nodes.IntPoint(14).y = 2./3.;
1592  Nodes.IntPoint(15).x = 2./3.;
1593  Nodes.IntPoint(15).y = 2./3.;
1594 }
1595 
1597  const IntegrationPoint &ip, Vector &shape) const
1598 {
1599  double x = ip.x, y = ip.y;
1600 
1601  double w1x, w2x, w3x, w1y, w2y, w3y;
1602  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1603 
1604  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1605  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1606 
1607  l0x = (- 4.5) * w1x * w2x * w3x;
1608  l1x = ( 13.5) * x * w2x * w3x;
1609  l2x = (-13.5) * x * w1x * w3x;
1610  l3x = ( 4.5) * x * w1x * w2x;
1611 
1612  l0y = (- 4.5) * w1y * w2y * w3y;
1613  l1y = ( 13.5) * y * w2y * w3y;
1614  l2y = (-13.5) * y * w1y * w3y;
1615  l3y = ( 4.5) * y * w1y * w2y;
1616 
1617  shape(0) = l0x * l0y;
1618  shape(1) = l3x * l0y;
1619  shape(2) = l3x * l3y;
1620  shape(3) = l0x * l3y;
1621  shape(4) = l1x * l0y;
1622  shape(5) = l2x * l0y;
1623  shape(6) = l3x * l1y;
1624  shape(7) = l3x * l2y;
1625  shape(8) = l2x * l3y;
1626  shape(9) = l1x * l3y;
1627  shape(10) = l0x * l2y;
1628  shape(11) = l0x * l1y;
1629  shape(12) = l1x * l1y;
1630  shape(13) = l2x * l1y;
1631  shape(14) = l1x * l2y;
1632  shape(15) = l2x * l2y;
1633 }
1634 
1636  const IntegrationPoint &ip, DenseMatrix &dshape) const
1637 {
1638  double x = ip.x, y = ip.y;
1639 
1640  double w1x, w2x, w3x, w1y, w2y, w3y;
1641  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1642  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1643 
1644  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1645  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1646 
1647  l0x = (- 4.5) * w1x * w2x * w3x;
1648  l1x = ( 13.5) * x * w2x * w3x;
1649  l2x = (-13.5) * x * w1x * w3x;
1650  l3x = ( 4.5) * x * w1x * w2x;
1651 
1652  l0y = (- 4.5) * w1y * w2y * w3y;
1653  l1y = ( 13.5) * y * w2y * w3y;
1654  l2y = (-13.5) * y * w1y * w3y;
1655  l3y = ( 4.5) * y * w1y * w2y;
1656 
1657  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1658  d1x = 9. + (-45. + 40.5 * x) * x;
1659  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1660  d3x = 1. + (- 9. + 13.5 * x) * x;
1661 
1662  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1663  d1y = 9. + (-45. + 40.5 * y) * y;
1664  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1665  d3y = 1. + (- 9. + 13.5 * y) * y;
1666 
1667  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
1668  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
1669  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
1670  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
1671  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
1672  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
1673  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
1674  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
1675  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
1676  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
1677  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
1678  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
1679  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
1680  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
1681  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
1682  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
1683 }
1684 
1686  const IntegrationPoint &ip, DenseMatrix &h) const
1687 {
1688  double x = ip.x, y = ip.y;
1689 
1690  double w1x, w2x, w3x, w1y, w2y, w3y;
1691  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1692  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1693  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
1694 
1695  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1696  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1697 
1698  l0x = (- 4.5) * w1x * w2x * w3x;
1699  l1x = ( 13.5) * x * w2x * w3x;
1700  l2x = (-13.5) * x * w1x * w3x;
1701  l3x = ( 4.5) * x * w1x * w2x;
1702 
1703  l0y = (- 4.5) * w1y * w2y * w3y;
1704  l1y = ( 13.5) * y * w2y * w3y;
1705  l2y = (-13.5) * y * w1y * w3y;
1706  l3y = ( 4.5) * y * w1y * w2y;
1707 
1708  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1709  d1x = 9. + (-45. + 40.5 * x) * x;
1710  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1711  d3x = 1. + (- 9. + 13.5 * x) * x;
1712 
1713  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1714  d1y = 9. + (-45. + 40.5 * y) * y;
1715  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1716  d3y = 1. + (- 9. + 13.5 * y) * y;
1717 
1718  h0x = -27. * x + 18.;
1719  h1x = 81. * x - 45.;
1720  h2x = -81. * x + 36.;
1721  h3x = 27. * x - 9.;
1722 
1723  h0y = -27. * y + 18.;
1724  h1y = 81. * y - 45.;
1725  h2y = -81. * y + 36.;
1726  h3y = 27. * y - 9.;
1727 
1728  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
1729  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
1730  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
1731  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
1732  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
1733  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
1734  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
1735  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
1736  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
1737  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
1738  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
1739  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
1740  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
1741  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
1742  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
1743  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
1744 }
1745 
1746 
1748  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
1749 {
1750  Nodes.IntPoint(0).x = 0.0;
1751  Nodes.IntPoint(1).x = 1.0;
1752  Nodes.IntPoint(2).x = 0.33333333333333333333;
1753  Nodes.IntPoint(3).x = 0.66666666666666666667;
1754 }
1755 
1757  Vector &shape) const
1758 {
1759  double x = ip.x;
1760  double l1 = x,
1761  l2 = (1.0-x),
1762  l3 = (0.33333333333333333333-x),
1763  l4 = (0.66666666666666666667-x);
1764 
1765  shape(0) = 4.5 * l2 * l3 * l4;
1766  shape(1) = 4.5 * l1 * l3 * l4;
1767  shape(2) = 13.5 * l1 * l2 * l4;
1768  shape(3) = -13.5 * l1 * l2 * l3;
1769 }
1770 
1772  DenseMatrix &dshape) const
1773 {
1774  double x = ip.x;
1775 
1776  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
1777  dshape(1,0) = 1. - x * (9. - 13.5 * x);
1778  dshape(2,0) = 9. - x * (45. - 40.5 * x);
1779  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
1780 }
1781 
1782 
1784  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
1785 {
1786  Nodes.IntPoint(0).x = 0.0;
1787  Nodes.IntPoint(0).y = 0.0;
1788  Nodes.IntPoint(1).x = 1.0;
1789  Nodes.IntPoint(1).y = 0.0;
1790  Nodes.IntPoint(2).x = 0.0;
1791  Nodes.IntPoint(2).y = 1.0;
1792  Nodes.IntPoint(3).x = 0.33333333333333333333;
1793  Nodes.IntPoint(3).y = 0.0;
1794  Nodes.IntPoint(4).x = 0.66666666666666666667;
1795  Nodes.IntPoint(4).y = 0.0;
1796  Nodes.IntPoint(5).x = 0.66666666666666666667;
1797  Nodes.IntPoint(5).y = 0.33333333333333333333;
1798  Nodes.IntPoint(6).x = 0.33333333333333333333;
1799  Nodes.IntPoint(6).y = 0.66666666666666666667;
1800  Nodes.IntPoint(7).x = 0.0;
1801  Nodes.IntPoint(7).y = 0.66666666666666666667;
1802  Nodes.IntPoint(8).x = 0.0;
1803  Nodes.IntPoint(8).y = 0.33333333333333333333;
1804  Nodes.IntPoint(9).x = 0.33333333333333333333;
1805  Nodes.IntPoint(9).y = 0.33333333333333333333;
1806 }
1807 
1809  Vector &shape) const
1810 {
1811  double x = ip.x, y = ip.y;
1812  double l1 = (-1. + x + y),
1813  lx = (-1. + 3.*x),
1814  ly = (-1. + 3.*y);
1815 
1816  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
1817  shape(1) = 0.5*x*(lx - 1.)*lx;
1818  shape(2) = 0.5*y*(-1. + ly)*ly;
1819  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
1820  shape(4) = -4.5*x*lx*l1;
1821  shape(5) = 4.5*x*lx*y;
1822  shape(6) = 4.5*x*y*ly;
1823  shape(7) = -4.5*y*l1*ly;
1824  shape(8) = 4.5*y*l1*(1. + 3.*l1);
1825  shape(9) = -27.*x*y*l1;
1826 }
1827 
1829  DenseMatrix &dshape) const
1830 {
1831  double x = ip.x, y = ip.y;
1832 
1833  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
1834  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
1835  dshape(2,0) = 0.;
1836  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
1837  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
1838  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
1839  dshape(6,0) = 4.5*y*(-1. + 3.*y);
1840  dshape(7,0) = 4.5*(1. - 3.*y)*y;
1841  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
1842  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
1843 
1844  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
1845  dshape(1,1) = 0.;
1846  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
1847  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
1848  dshape(4,1) = 4.5*(1. - 3.*x)*x;
1849  dshape(5,1) = 4.5*x*(-1. + 3.*x);
1850  dshape(6,1) = 4.5*x*(-1. + 6.*y);
1851  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
1852  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
1853  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
1854 }
1855 
1857  DenseMatrix &h) const
1858 {
1859  double x = ip.x, y = ip.y;
1860 
1861  h(0,0) = 18.-27.*(x+y);
1862  h(0,1) = 18.-27.*(x+y);
1863  h(0,2) = 18.-27.*(x+y);
1864 
1865  h(1,0) = -9.+27.*x;
1866  h(1,1) = 0.;
1867  h(1,2) = 0.;
1868 
1869  h(2,0) = 0.;
1870  h(2,1) = 0.;
1871  h(2,2) = -9.+27.*y;
1872 
1873  h(3,0) = -45.+81.*x+54.*y;
1874  h(3,1) = -22.5+54.*x+27.*y;
1875  h(3,2) = 27.*x;
1876 
1877  h(4,0) = 36.-81.*x-27.*y;
1878  h(4,1) = 4.5-27.*x;
1879  h(4,2) = 0.;
1880 
1881  h(5,0) = 27.*y;
1882  h(5,1) = -4.5+27.*x;
1883  h(5,2) = 0.;
1884 
1885  h(6,0) = 0.;
1886  h(6,1) = -4.5+27.*y;
1887  h(6,2) = 27.*x;
1888 
1889  h(7,0) = 0.;
1890  h(7,1) = 4.5-27.*y;
1891  h(7,2) = 36.-27.*x-81.*y;
1892 
1893  h(8,0) = 27.*y;
1894  h(8,1) = -22.5+27.*x+54.*y;
1895  h(8,2) = -45.+54.*x+81.*y;
1896 
1897  h(9,0) = -54.*y;
1898  h(9,1) = 27.-54.*(x+y);
1899  h(9,2) = -54.*x;
1900 }
1901 
1902 
1904  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
1905 {
1906  Nodes.IntPoint(0).x = 0;
1907  Nodes.IntPoint(0).y = 0;
1908  Nodes.IntPoint(0).z = 0;
1909  Nodes.IntPoint(1).x = 1.;
1910  Nodes.IntPoint(1).y = 0;
1911  Nodes.IntPoint(1).z = 0;
1912  Nodes.IntPoint(2).x = 0;
1913  Nodes.IntPoint(2).y = 1.;
1914  Nodes.IntPoint(2).z = 0;
1915  Nodes.IntPoint(3).x = 0;
1916  Nodes.IntPoint(3).y = 0;
1917  Nodes.IntPoint(3).z = 1.;
1918  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
1919  Nodes.IntPoint(4).y = 0;
1920  Nodes.IntPoint(4).z = 0;
1921  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
1922  Nodes.IntPoint(5).y = 0;
1923  Nodes.IntPoint(5).z = 0;
1924  Nodes.IntPoint(6).x = 0;
1925  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
1926  Nodes.IntPoint(6).z = 0;
1927  Nodes.IntPoint(7).x = 0;
1928  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
1929  Nodes.IntPoint(7).z = 0;
1930  Nodes.IntPoint(8).x = 0;
1931  Nodes.IntPoint(8).y = 0;
1932  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
1933  Nodes.IntPoint(9).x = 0;
1934  Nodes.IntPoint(9).y = 0;
1935  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
1936  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
1937  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
1938  Nodes.IntPoint(10).z = 0;
1939  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
1940  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
1941  Nodes.IntPoint(11).z = 0;
1942  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
1943  Nodes.IntPoint(12).y = 0;
1944  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
1945  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
1946  Nodes.IntPoint(13).y = 0;
1947  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
1948  Nodes.IntPoint(14).x = 0;
1949  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
1950  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
1951  Nodes.IntPoint(15).x = 0;
1952  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
1953  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
1954  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
1955  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
1956  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
1957  Nodes.IntPoint(17).x = 0;
1958  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
1959  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
1960  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
1961  Nodes.IntPoint(18).y = 0;
1962  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
1963  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
1964  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
1965  Nodes.IntPoint(19).z = 0;
1966 }
1967 
1969  Vector &shape) const
1970 {
1971  double x = ip.x, y = ip.y, z = ip.z;
1972 
1973  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
1974  (-1 + 3*x + 3*y + 3*z))/2.;
1975  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
1976  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
1977  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
1978  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
1979  shape(19) = -27*x*y*(-1 + x + y + z);
1980  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
1981  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
1982  shape(11) = (9*x*y*(-1 + 3*y))/2.;
1983  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
1984  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
1985  shape(18) = -27*x*z*(-1 + x + y + z);
1986  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
1987  shape(17) = -27*y*z*(-1 + x + y + z);
1988  shape(16) = 27*x*y*z;
1989  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
1990  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
1991  shape(13) = (9*x*z*(-1 + 3*z))/2.;
1992  shape(15) = (9*y*z*(-1 + 3*z))/2.;
1993  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
1994 }
1995 
1997  DenseMatrix &dshape) const
1998 {
1999  double x = ip.x, y = ip.y, z = ip.z;
2000 
2001  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2002  x*(-4 + 6*y + 6*z)))/2.;
2003  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2004  x*(-4 + 6*y + 6*z)))/2.;
2005  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2006  x*(-4 + 6*y + 6*z)))/2.;
2007  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
2008  2*x*(-5 + 6*y + 6*z)))/2.;
2009  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2010  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2011  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
2012  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
2013  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
2014  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
2015  dshape(1,1) = 0;
2016  dshape(1,2) = 0;
2017  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2018  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
2019  x*(-5 + 12*y + 6*z)))/2.;
2020  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2021  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
2022  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
2023  dshape(19,2) = -27*x*y;
2024  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
2025  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
2026  dshape(10,2) = 0;
2027  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
2028  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
2029  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
2030  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
2031  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
2032  dshape(11,2) = 0;
2033  dshape(2,0) = 0;
2034  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
2035  dshape(2,2) = 0;
2036  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2037  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2038  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
2039  x*(-5 + 6*y + 12*z)))/2.;
2040  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
2041  dshape(18,1) = -27*x*z;
2042  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
2043  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
2044  dshape(12,1) = 0;
2045  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
2046  dshape(17,0) = -27*y*z;
2047  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
2048  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
2049  dshape(16,0) = 27*y*z;
2050  dshape(16,1) = 27*x*z;
2051  dshape(16,2) = 27*x*y;
2052  dshape(14,0) = 0;
2053  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
2054  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
2055  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
2056  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
2057  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
2058  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
2059  dshape(13,1) = 0;
2060  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
2061  dshape(15,0) = 0;
2062  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
2063  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
2064  dshape(3,0) = 0;
2065  dshape(3,1) = 0;
2066  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
2067 }
2068 
2069 
2071  : NodalFiniteElement(2, Geometry::TRIANGLE , 1, 0)
2072 {
2073  Nodes.IntPoint(0).x = 0.333333333333333333;
2074  Nodes.IntPoint(0).y = 0.333333333333333333;
2075 }
2076 
2078  Vector &shape) const
2079 {
2080  shape(0) = 1.0;
2081 }
2082 
2084  DenseMatrix &dshape) const
2085 {
2086  dshape(0,0) = 0.0;
2087  dshape(0,1) = 0.0;
2088 }
2089 
2090 
2092  : NodalFiniteElement(2, Geometry::SQUARE , 1, 0, FunctionSpace::Qk)
2093 {
2094  Nodes.IntPoint(0).x = 0.5;
2095  Nodes.IntPoint(0).y = 0.5;
2096 }
2097 
2099  Vector &shape) const
2100 {
2101  shape(0) = 1.0;
2102 }
2103 
2105  DenseMatrix &dshape) const
2106 {
2107  dshape(0,0) = 0.0;
2108  dshape(0,1) = 0.0;
2109 }
2110 
2111 
2113  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
2114 {
2115  Nodes.IntPoint(0).x = 0.0;
2116  Nodes.IntPoint(0).y = 0.0;
2117  Nodes.IntPoint(0).z = 0.0;
2118  Nodes.IntPoint(1).x = 1.0;
2119  Nodes.IntPoint(1).y = 0.0;
2120  Nodes.IntPoint(1).z = 0.0;
2121  Nodes.IntPoint(2).x = 0.0;
2122  Nodes.IntPoint(2).y = 1.0;
2123  Nodes.IntPoint(2).z = 0.0;
2124  Nodes.IntPoint(3).x = 0.0;
2125  Nodes.IntPoint(3).y = 0.0;
2126  Nodes.IntPoint(3).z = 1.0;
2127 }
2128 
2130  Vector &shape) const
2131 {
2132  shape(0) = 1. - ip.x - ip.y - ip.z;
2133  shape(1) = ip.x;
2134  shape(2) = ip.y;
2135  shape(3) = ip.z;
2136 }
2137 
2139  DenseMatrix &dshape) const
2140 {
2141  if (dshape.Height() == 4)
2142  {
2143  double *A = &dshape(0,0);
2144  A[0] = -1.; A[4] = -1.; A[8] = -1.;
2145  A[1] = 1.; A[5] = 0.; A[9] = 0.;
2146  A[2] = 0.; A[6] = 1.; A[10] = 0.;
2147  A[3] = 0.; A[7] = 0.; A[11] = 1.;
2148  }
2149  else
2150  {
2151  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
2152  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
2153  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
2154  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
2155  }
2156 }
2157 
2158 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
2159 const
2160 {
2161  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
2162 
2163  *ndofs = 3;
2164  *dofs = face_dofs[face];
2165 }
2166 
2167 
2169  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
2170 {
2171  Nodes.IntPoint(0).x = 0.0;
2172  Nodes.IntPoint(0).y = 0.0;
2173  Nodes.IntPoint(0).z = 0.0;
2174  Nodes.IntPoint(1).x = 1.0;
2175  Nodes.IntPoint(1).y = 0.0;
2176  Nodes.IntPoint(1).z = 0.0;
2177  Nodes.IntPoint(2).x = 0.0;
2178  Nodes.IntPoint(2).y = 1.0;
2179  Nodes.IntPoint(2).z = 0.0;
2180  Nodes.IntPoint(3).x = 0.0;
2181  Nodes.IntPoint(3).y = 0.0;
2182  Nodes.IntPoint(3).z = 1.0;
2183  Nodes.IntPoint(4).x = 0.5;
2184  Nodes.IntPoint(4).y = 0.0;
2185  Nodes.IntPoint(4).z = 0.0;
2186  Nodes.IntPoint(5).x = 0.0;
2187  Nodes.IntPoint(5).y = 0.5;
2188  Nodes.IntPoint(5).z = 0.0;
2189  Nodes.IntPoint(6).x = 0.0;
2190  Nodes.IntPoint(6).y = 0.0;
2191  Nodes.IntPoint(6).z = 0.5;
2192  Nodes.IntPoint(7).x = 0.5;
2193  Nodes.IntPoint(7).y = 0.5;
2194  Nodes.IntPoint(7).z = 0.0;
2195  Nodes.IntPoint(8).x = 0.5;
2196  Nodes.IntPoint(8).y = 0.0;
2197  Nodes.IntPoint(8).z = 0.5;
2198  Nodes.IntPoint(9).x = 0.0;
2199  Nodes.IntPoint(9).y = 0.5;
2200  Nodes.IntPoint(9).z = 0.5;
2201 }
2202 
2204  Vector &shape) const
2205 {
2206  double L0, L1, L2, L3;
2207 
2208  L0 = 1. - ip.x - ip.y - ip.z;
2209  L1 = ip.x;
2210  L2 = ip.y;
2211  L3 = ip.z;
2212 
2213  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
2214  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
2215  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
2216  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
2217  shape(4) = 4.0 * L0 * L1;
2218  shape(5) = 4.0 * L0 * L2;
2219  shape(6) = 4.0 * L0 * L3;
2220  shape(7) = 4.0 * L1 * L2;
2221  shape(8) = 4.0 * L1 * L3;
2222  shape(9) = 4.0 * L2 * L3;
2223 }
2224 
2226  DenseMatrix &dshape) const
2227 {
2228  double x, y, z, L0;
2229 
2230  x = ip.x;
2231  y = ip.y;
2232  z = ip.z;
2233  L0 = 1.0 - x - y - z;
2234 
2235  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
2236  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
2237  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
2238  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
2239  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
2240  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
2241  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
2242  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
2243  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
2244  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
2245 }
2246 
2248  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
2249 {
2250  Nodes.IntPoint(0).x = 0.0;
2251  Nodes.IntPoint(0).y = 0.0;
2252  Nodes.IntPoint(0).z = 0.0;
2253 
2254  Nodes.IntPoint(1).x = 1.0;
2255  Nodes.IntPoint(1).y = 0.0;
2256  Nodes.IntPoint(1).z = 0.0;
2257 
2258  Nodes.IntPoint(2).x = 1.0;
2259  Nodes.IntPoint(2).y = 1.0;
2260  Nodes.IntPoint(2).z = 0.0;
2261 
2262  Nodes.IntPoint(3).x = 0.0;
2263  Nodes.IntPoint(3).y = 1.0;
2264  Nodes.IntPoint(3).z = 0.0;
2265 
2266  Nodes.IntPoint(4).x = 0.0;
2267  Nodes.IntPoint(4).y = 0.0;
2268  Nodes.IntPoint(4).z = 1.0;
2269 
2270  Nodes.IntPoint(5).x = 1.0;
2271  Nodes.IntPoint(5).y = 0.0;
2272  Nodes.IntPoint(5).z = 1.0;
2273 
2274  Nodes.IntPoint(6).x = 1.0;
2275  Nodes.IntPoint(6).y = 1.0;
2276  Nodes.IntPoint(6).z = 1.0;
2277 
2278  Nodes.IntPoint(7).x = 0.0;
2279  Nodes.IntPoint(7).y = 1.0;
2280  Nodes.IntPoint(7).z = 1.0;
2281 }
2282 
2284  Vector &shape) const
2285 {
2286  double x = ip.x, y = ip.y, z = ip.z;
2287  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2288 
2289  shape(0) = ox * oy * oz;
2290  shape(1) = x * oy * oz;
2291  shape(2) = x * y * oz;
2292  shape(3) = ox * y * oz;
2293  shape(4) = ox * oy * z;
2294  shape(5) = x * oy * z;
2295  shape(6) = x * y * z;
2296  shape(7) = ox * y * z;
2297 }
2298 
2300  DenseMatrix &dshape) const
2301 {
2302  double x = ip.x, y = ip.y, z = ip.z;
2303  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2304 
2305  dshape(0,0) = - oy * oz;
2306  dshape(0,1) = - ox * oz;
2307  dshape(0,2) = - ox * oy;
2308 
2309  dshape(1,0) = oy * oz;
2310  dshape(1,1) = - x * oz;
2311  dshape(1,2) = - x * oy;
2312 
2313  dshape(2,0) = y * oz;
2314  dshape(2,1) = x * oz;
2315  dshape(2,2) = - x * y;
2316 
2317  dshape(3,0) = - y * oz;
2318  dshape(3,1) = ox * oz;
2319  dshape(3,2) = - ox * y;
2320 
2321  dshape(4,0) = - oy * z;
2322  dshape(4,1) = - ox * z;
2323  dshape(4,2) = ox * oy;
2324 
2325  dshape(5,0) = oy * z;
2326  dshape(5,1) = - x * z;
2327  dshape(5,2) = x * oy;
2328 
2329  dshape(6,0) = y * z;
2330  dshape(6,1) = x * z;
2331  dshape(6,2) = x * y;
2332 
2333  dshape(7,0) = - y * z;
2334  dshape(7,1) = ox * z;
2335  dshape(7,2) = ox * y;
2336 }
2337 
2339  : NodalFiniteElement(1, Geometry::SEGMENT , 1, Ord) // defaul Ord = 0
2340 {
2341  Nodes.IntPoint(0).x = 0.5;
2342 }
2343 
2345  Vector &shape) const
2346 {
2347  shape(0) = 1.0;
2348 }
2349 
2351  DenseMatrix &dshape) const
2352 {
2353  dshape(0,0) = 0.0;
2354 }
2355 
2357  : NodalFiniteElement(2, Geometry::TRIANGLE , 3, 1)
2358 {
2359  Nodes.IntPoint(0).x = 0.5;
2360  Nodes.IntPoint(0).y = 0.0;
2361  Nodes.IntPoint(1).x = 0.5;
2362  Nodes.IntPoint(1).y = 0.5;
2363  Nodes.IntPoint(2).x = 0.0;
2364  Nodes.IntPoint(2).y = 0.5;
2365 }
2366 
2368  Vector &shape) const
2369 {
2370  shape(0) = 1.0 - 2.0 * ip.y;
2371  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
2372  shape(2) = 1.0 - 2.0 * ip.x;
2373 }
2374 
2376  DenseMatrix &dshape) const
2377 {
2378  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
2379  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
2380  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
2381 }
2382 
2384 // the FunctionSpace should be rotated (45 degrees) Q_1
2385 // i.e. the span of { 1, x, y, x^2 - y^2 }
2386  : NodalFiniteElement(2, Geometry::SQUARE , 4, 2, FunctionSpace::Qk)
2387 
2388 {
2389  Nodes.IntPoint(0).x = 0.5;
2390  Nodes.IntPoint(0).y = 0.0;
2391  Nodes.IntPoint(1).x = 1.0;
2392  Nodes.IntPoint(1).y = 0.5;
2393  Nodes.IntPoint(2).x = 0.5;
2394  Nodes.IntPoint(2).y = 1.0;
2395  Nodes.IntPoint(3).x = 0.0;
2396  Nodes.IntPoint(3).y = 0.5;
2397 }
2398 
2400  Vector &shape) const
2401 {
2402  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
2403 
2404  shape(0) = l2 * l3;
2405  shape(1) = l1 * l3;
2406  shape(2) = l1 * l4;
2407  shape(3) = l2 * l4;
2408 }
2409 
2411  DenseMatrix &dshape) const
2412 {
2413  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
2414 
2415  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
2416  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
2417  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
2418  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
2419 }
2420 
2421 
2423  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
2424 {
2425  Nodes.IntPoint(0).x = 0.5;
2426  Nodes.IntPoint(0).y = 0.0;
2427  Nodes.IntPoint(1).x = 0.5;
2428  Nodes.IntPoint(1).y = 0.5;
2429  Nodes.IntPoint(2).x = 0.0;
2430  Nodes.IntPoint(2).y = 0.5;
2431 }
2432 
2434  DenseMatrix &shape) const
2435 {
2436  double x = ip.x, y = ip.y;
2437 
2438  shape(0,0) = x;
2439  shape(0,1) = y - 1.;
2440  shape(1,0) = x;
2441  shape(1,1) = y;
2442  shape(2,0) = x - 1.;
2443  shape(2,1) = y;
2444 }
2445 
2447  Vector &divshape) const
2448 {
2449  divshape(0) = 2.;
2450  divshape(1) = 2.;
2451  divshape(2) = 2.;
2452 }
2453 
2454 const double RT0TriangleFiniteElement::nk[3][2] =
2455 { {0, -1}, {1, 1}, {-1, 0} };
2456 
2459 {
2460  int k, j;
2461 #ifdef MFEM_THREAD_SAFE
2463  DenseMatrix Jinv(Dim);
2464 #endif
2465 
2466 #ifdef MFEM_DEBUG
2467  for (k = 0; k < 3; k++)
2468  {
2470  for (j = 0; j < 3; j++)
2471  {
2472  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2473  if (j == k) { d -= 1.0; }
2474  if (fabs(d) > 1.0e-12)
2475  {
2476  cerr << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
2477  " k = " << k << ", j = " << j << ", d = " << d << endl;
2478  mfem_error();
2479  }
2480  }
2481  }
2482 #endif
2483 
2484  IntegrationPoint ip;
2485  ip.x = ip.y = 0.0;
2486  Trans.SetIntPoint (&ip);
2487  // Trans must be linear
2488  // set Jinv = |J| J^{-t} = adj(J)^t
2489  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2490  double vk[2];
2491  Vector xk (vk, 2);
2492 
2493  for (k = 0; k < 3; k++)
2494  {
2495  Trans.Transform (Nodes.IntPoint (k), xk);
2496  ip.x = vk[0]; ip.y = vk[1];
2497  CalcVShape (ip, vshape);
2498  // vk = |J| J^{-t} nk
2499  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2500  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2501  for (j = 0; j < 3; j++)
2502  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2503  {
2504  I(k,j) = 0.0;
2505  }
2506  }
2507 }
2508 
2511  Vector &dofs) const
2512 {
2513  double vk[2];
2514  Vector xk (vk, 2);
2515 #ifdef MFEM_THREAD_SAFE
2516  DenseMatrix Jinv(Dim);
2517 #endif
2518 
2519  for (int k = 0; k < 3; k++)
2520  {
2521  Trans.SetIntPoint (&Nodes.IntPoint (k));
2522  // set Jinv = |J| J^{-t} = adj(J)^t
2523  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2524 
2525  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2526  // xk^t |J| J^{-t} nk
2527  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2528  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2529  }
2530 }
2531 
2533  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
2534 {
2535  Nodes.IntPoint(0).x = 0.5;
2536  Nodes.IntPoint(0).y = 0.0;
2537  Nodes.IntPoint(1).x = 1.0;
2538  Nodes.IntPoint(1).y = 0.5;
2539  Nodes.IntPoint(2).x = 0.5;
2540  Nodes.IntPoint(2).y = 1.0;
2541  Nodes.IntPoint(3).x = 0.0;
2542  Nodes.IntPoint(3).y = 0.5;
2543 }
2544 
2546  DenseMatrix &shape) const
2547 {
2548  double x = ip.x, y = ip.y;
2549 
2550  shape(0,0) = 0;
2551  shape(0,1) = y - 1.;
2552  shape(1,0) = x;
2553  shape(1,1) = 0;
2554  shape(2,0) = 0;
2555  shape(2,1) = y;
2556  shape(3,0) = x - 1.;
2557  shape(3,1) = 0;
2558 }
2559 
2561  Vector &divshape) const
2562 {
2563  divshape(0) = 1.;
2564  divshape(1) = 1.;
2565  divshape(2) = 1.;
2566  divshape(3) = 1.;
2567 }
2568 
2569 const double RT0QuadFiniteElement::nk[4][2] =
2570 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
2571 
2574 {
2575  int k, j;
2576 #ifdef MFEM_THREAD_SAFE
2578  DenseMatrix Jinv(Dim);
2579 #endif
2580 
2581 #ifdef MFEM_DEBUG
2582  for (k = 0; k < 4; k++)
2583  {
2585  for (j = 0; j < 4; j++)
2586  {
2587  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2588  if (j == k) { d -= 1.0; }
2589  if (fabs(d) > 1.0e-12)
2590  {
2591  cerr << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
2592  " k = " << k << ", j = " << j << ", d = " << d << endl;
2593  mfem_error();
2594  }
2595  }
2596  }
2597 #endif
2598 
2599  IntegrationPoint ip;
2600  ip.x = ip.y = 0.0;
2601  Trans.SetIntPoint (&ip);
2602  // Trans must be linear (more to have embedding?)
2603  // set Jinv = |J| J^{-t} = adj(J)^t
2604  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2605  double vk[2];
2606  Vector xk (vk, 2);
2607 
2608  for (k = 0; k < 4; k++)
2609  {
2610  Trans.Transform (Nodes.IntPoint (k), xk);
2611  ip.x = vk[0]; ip.y = vk[1];
2612  CalcVShape (ip, vshape);
2613  // vk = |J| J^{-t} nk
2614  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2615  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2616  for (j = 0; j < 4; j++)
2617  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2618  {
2619  I(k,j) = 0.0;
2620  }
2621  }
2622 }
2623 
2626  Vector &dofs) const
2627 {
2628  double vk[2];
2629  Vector xk (vk, 2);
2630 #ifdef MFEM_THREAD_SAFE
2631  DenseMatrix Jinv(Dim);
2632 #endif
2633 
2634  for (int k = 0; k < 4; k++)
2635  {
2636  Trans.SetIntPoint (&Nodes.IntPoint (k));
2637  // set Jinv = |J| J^{-t} = adj(J)^t
2638  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2639 
2640  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2641  // xk^t |J| J^{-t} nk
2642  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2643  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2644  }
2645 }
2646 
2648  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
2649 {
2650  Nodes.IntPoint(0).x = 0.33333333333333333333;
2651  Nodes.IntPoint(0).y = 0.0;
2652  Nodes.IntPoint(1).x = 0.66666666666666666667;
2653  Nodes.IntPoint(1).y = 0.0;
2654  Nodes.IntPoint(2).x = 0.66666666666666666667;
2655  Nodes.IntPoint(2).y = 0.33333333333333333333;
2656  Nodes.IntPoint(3).x = 0.33333333333333333333;
2657  Nodes.IntPoint(3).y = 0.66666666666666666667;
2658  Nodes.IntPoint(4).x = 0.0;
2659  Nodes.IntPoint(4).y = 0.66666666666666666667;
2660  Nodes.IntPoint(5).x = 0.0;
2661  Nodes.IntPoint(5).y = 0.33333333333333333333;
2662  Nodes.IntPoint(6).x = 0.33333333333333333333;
2663  Nodes.IntPoint(6).y = 0.33333333333333333333;
2664  Nodes.IntPoint(7).x = 0.33333333333333333333;
2665  Nodes.IntPoint(7).y = 0.33333333333333333333;
2666 }
2667 
2669  DenseMatrix &shape) const
2670 {
2671  double x = ip.x, y = ip.y;
2672 
2673  shape(0,0) = -2 * x * (-1 + x + 2 * y);
2674  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
2675  shape(1,0) = 2 * x * (x - y);
2676  shape(1,1) = 2 * (x - y) * (-1 + y);
2677  shape(2,0) = 2 * x * (-1 + 2 * x + y);
2678  shape(2,1) = 2 * y * (-1 + 2 * x + y);
2679  shape(3,0) = 2 * x * (-1 + x + 2 * y);
2680  shape(3,1) = 2 * y * (-1 + x + 2 * y);
2681  shape(4,0) = -2 * (-1 + x) * (x - y);
2682  shape(4,1) = 2 * y * (-x + y);
2683  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
2684  shape(5,1) = -2 * y * (-1 + 2 * x + y);
2685  shape(6,0) = -3 * x * (-2 + 2 * x + y);
2686  shape(6,1) = -3 * y * (-1 + 2 * x + y);
2687  shape(7,0) = -3 * x * (-1 + x + 2 * y);
2688  shape(7,1) = -3 * y * (-2 + x + 2 * y);
2689 }
2690 
2692  Vector &divshape) const
2693 {
2694  double x = ip.x, y = ip.y;
2695 
2696  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
2697  divshape(1) = 2 + 6 * x - 6 * y;
2698  divshape(2) = -4 + 12 * x + 6 * y;
2699  divshape(3) = -4 + 6 * x + 12 * y;
2700  divshape(4) = 2 - 6 * x + 6 * y;
2701  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
2702  divshape(6) = -9 * (-1 + 2 * x + y);
2703  divshape(7) = -9 * (-1 + x + 2 * y);
2704 }
2705 
2706 const double RT1TriangleFiniteElement::nk[8][2] =
2707 {
2708  { 0,-1}, { 0,-1},
2709  { 1, 1}, { 1, 1},
2710  {-1, 0}, {-1, 0},
2711  { 1, 0}, { 0, 1}
2712 };
2713 
2716 {
2717  int k, j;
2718 #ifdef MFEM_THREAD_SAFE
2720  DenseMatrix Jinv(Dim);
2721 #endif
2722 
2723 #ifdef MFEM_DEBUG
2724  for (k = 0; k < 8; k++)
2725  {
2727  for (j = 0; j < 8; j++)
2728  {
2729  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2730  if (j == k) { d -= 1.0; }
2731  if (fabs(d) > 1.0e-12)
2732  {
2733  cerr << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
2734  " k = " << k << ", j = " << j << ", d = " << d << endl;
2735  mfem_error();
2736  }
2737  }
2738  }
2739 #endif
2740 
2741  IntegrationPoint ip;
2742  ip.x = ip.y = 0.0;
2743  Trans.SetIntPoint (&ip);
2744  // Trans must be linear (more to have embedding?)
2745  // set Jinv = |J| J^{-t} = adj(J)^t
2746  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2747  double vk[2];
2748  Vector xk (vk, 2);
2749 
2750  for (k = 0; k < 8; k++)
2751  {
2752  Trans.Transform (Nodes.IntPoint (k), xk);
2753  ip.x = vk[0]; ip.y = vk[1];
2754  CalcVShape (ip, vshape);
2755  // vk = |J| J^{-t} nk
2756  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2757  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2758  for (j = 0; j < 8; j++)
2759  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2760  {
2761  I(k,j) = 0.0;
2762  }
2763  }
2764 }
2765 
2768 {
2769  double vk[2];
2770  Vector xk (vk, 2);
2771 #ifdef MFEM_THREAD_SAFE
2772  DenseMatrix Jinv(Dim);
2773 #endif
2774 
2775  for (int k = 0; k < 8; k++)
2776  {
2777  Trans.SetIntPoint (&Nodes.IntPoint (k));
2778  // set Jinv = |J| J^{-t} = adj(J)^t
2779  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2780 
2781  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2782  // xk^t |J| J^{-t} nk
2783  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2784  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2785  dofs(k) *= 0.5;
2786  }
2787 }
2788 
2790  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
2791 {
2792  // y = 0
2793  Nodes.IntPoint(0).x = 1./3.;
2794  Nodes.IntPoint(0).y = 0.0;
2795  Nodes.IntPoint(1).x = 2./3.;
2796  Nodes.IntPoint(1).y = 0.0;
2797  // x = 1
2798  Nodes.IntPoint(2).x = 1.0;
2799  Nodes.IntPoint(2).y = 1./3.;
2800  Nodes.IntPoint(3).x = 1.0;
2801  Nodes.IntPoint(3).y = 2./3.;
2802  // y = 1
2803  Nodes.IntPoint(4).x = 2./3.;
2804  Nodes.IntPoint(4).y = 1.0;
2805  Nodes.IntPoint(5).x = 1./3.;
2806  Nodes.IntPoint(5).y = 1.0;
2807  // x = 0
2808  Nodes.IntPoint(6).x = 0.0;
2809  Nodes.IntPoint(6).y = 2./3.;
2810  Nodes.IntPoint(7).x = 0.0;
2811  Nodes.IntPoint(7).y = 1./3.;
2812  // x = 0.5 (interior)
2813  Nodes.IntPoint(8).x = 0.5;
2814  Nodes.IntPoint(8).y = 1./3.;
2815  Nodes.IntPoint(9).x = 0.5;
2816  Nodes.IntPoint(9).y = 2./3.;
2817  // y = 0.5 (interior)
2818  Nodes.IntPoint(10).x = 1./3.;
2819  Nodes.IntPoint(10).y = 0.5;
2820  Nodes.IntPoint(11).x = 2./3.;
2821  Nodes.IntPoint(11).y = 0.5;
2822 }
2823 
2825  DenseMatrix &shape) const
2826 {
2827  double x = ip.x, y = ip.y;
2828 
2829  // y = 0
2830  shape(0,0) = 0;
2831  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
2832  shape(1,0) = 0;
2833  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
2834  // x = 1
2835  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
2836  shape(2,1) = 0;
2837  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
2838  shape(3,1) = 0;
2839  // y = 1
2840  shape(4,0) = 0;
2841  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
2842  shape(5,0) = 0;
2843  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
2844  // x = 0
2845  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
2846  shape(6,1) = 0;
2847  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
2848  shape(7,1) = 0;
2849  // x = 0.5 (interior)
2850  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
2851  shape(8,1) = 0;
2852  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
2853  shape(9,1) = 0;
2854  // y = 0.5 (interior)
2855  shape(10,0) = 0;
2856  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
2857  shape(11,0) = 0;
2858  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
2859 }
2860 
2862  Vector &divshape) const
2863 {
2864  double x = ip.x, y = ip.y;
2865 
2866  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
2867  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
2868  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
2869  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
2870  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
2871  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
2872  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
2873  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
2874  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
2875  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
2876  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
2877  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
2878 }
2879 
2880 const double RT1QuadFiniteElement::nk[12][2] =
2881 {
2882  // y = 0
2883  {0,-1}, {0,-1},
2884  // X = 1
2885  {1, 0}, {1, 0},
2886  // y = 1
2887  {0, 1}, {0, 1},
2888  // x = 0
2889  {-1,0}, {-1,0},
2890  // x = 0.5 (interior)
2891  {1, 0}, {1, 0},
2892  // y = 0.5 (interior)
2893  {0, 1}, {0, 1}
2894 };
2895 
2898 {
2899  int k, j;
2900 #ifdef MFEM_THREAD_SAFE
2902  DenseMatrix Jinv(Dim);
2903 #endif
2904 
2905 #ifdef MFEM_DEBUG
2906  for (k = 0; k < 12; k++)
2907  {
2909  for (j = 0; j < 12; j++)
2910  {
2911  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2912  if (j == k) { d -= 1.0; }
2913  if (fabs(d) > 1.0e-12)
2914  {
2915  cerr << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
2916  " k = " << k << ", j = " << j << ", d = " << d << endl;
2917  mfem_error();
2918  }
2919  }
2920  }
2921 #endif
2922 
2923  IntegrationPoint ip;
2924  ip.x = ip.y = 0.0;
2925  Trans.SetIntPoint (&ip);
2926  // Trans must be linear (more to have embedding?)
2927  // set Jinv = |J| J^{-t} = adj(J)^t
2928  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2929  double vk[2];
2930  Vector xk (vk, 2);
2931 
2932  for (k = 0; k < 12; k++)
2933  {
2934  Trans.Transform (Nodes.IntPoint (k), xk);
2935  ip.x = vk[0]; ip.y = vk[1];
2936  CalcVShape (ip, vshape);
2937  // vk = |J| J^{-t} nk
2938  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2939  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2940  for (j = 0; j < 12; j++)
2941  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2942  {
2943  I(k,j) = 0.0;
2944  }
2945  }
2946 }
2947 
2950 {
2951  double vk[2];
2952  Vector xk (vk, 2);
2953 #ifdef MFEM_THREAD_SAFE
2954  DenseMatrix Jinv(Dim);
2955 #endif
2956 
2957  for (int k = 0; k < 12; k++)
2958  {
2959  Trans.SetIntPoint (&Nodes.IntPoint (k));
2960  // set Jinv = |J| J^{-t} = adj(J)^t
2961  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2962 
2963  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2964  // xk^t |J| J^{-t} nk
2965  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2966  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2967  }
2968 }
2969 
2970 const double RT2TriangleFiniteElement::M[15][15] =
2971 {
2972  {
2973  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
2974  0, 24.442740046346700787, -16.647580015448900262, -12.,
2975  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
2976  12., 30.590320061795601049, 15.295160030897800524
2977  },
2978  {
2979  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
2980  -15., 10.5
2981  },
2982  {
2983  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
2984  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
2985  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
2986  12., -6.5903200617956010489, -3.2951600308978005244
2987  },
2988  {
2989  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
2990  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
2991  0, -3.2951600308978005244
2992  },
2993  {
2994  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
2995  36., 10.5
2996  },
2997  {
2998  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
2999  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
3000  0, 15.295160030897800524
3001  },
3002  {
3003  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
3004  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
3005  -0.76209992275549868892, 4.1189500386222506555, -12.,
3006  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
3007  12.
3008  },
3009  {
3010  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
3011  -15., -15.
3012  },
3013  {
3014  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
3015  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
3016  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
3017  30.590320061795601049, 12.
3018  },
3019  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
3020  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
3021  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
3022  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
3023  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
3024  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
3025 };
3026 
3028  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
3029 {
3030  const double p = 0.11270166537925831148;
3031 
3032  Nodes.IntPoint(0).x = p;
3033  Nodes.IntPoint(0).y = 0.0;
3034  Nodes.IntPoint(1).x = 0.5;
3035  Nodes.IntPoint(1).y = 0.0;
3036  Nodes.IntPoint(2).x = 1.-p;
3037  Nodes.IntPoint(2).y = 0.0;
3038  Nodes.IntPoint(3).x = 1.-p;
3039  Nodes.IntPoint(3).y = p;
3040  Nodes.IntPoint(4).x = 0.5;
3041  Nodes.IntPoint(4).y = 0.5;
3042  Nodes.IntPoint(5).x = p;
3043  Nodes.IntPoint(5).y = 1.-p;
3044  Nodes.IntPoint(6).x = 0.0;
3045  Nodes.IntPoint(6).y = 1.-p;
3046  Nodes.IntPoint(7).x = 0.0;
3047  Nodes.IntPoint(7).y = 0.5;
3048  Nodes.IntPoint(8).x = 0.0;
3049  Nodes.IntPoint(8).y = p;
3050  Nodes.IntPoint(9).x = 0.25;
3051  Nodes.IntPoint(9).y = 0.25;
3052  Nodes.IntPoint(10).x = 0.25;
3053  Nodes.IntPoint(10).y = 0.25;
3054  Nodes.IntPoint(11).x = 0.5;
3055  Nodes.IntPoint(11).y = 0.25;
3056  Nodes.IntPoint(12).x = 0.5;
3057  Nodes.IntPoint(12).y = 0.25;
3058  Nodes.IntPoint(13).x = 0.25;
3059  Nodes.IntPoint(13).y = 0.5;
3060  Nodes.IntPoint(14).x = 0.25;
3061  Nodes.IntPoint(14).y = 0.5;
3062 }
3063 
3065  DenseMatrix &shape) const
3066 {
3067  double x = ip.x, y = ip.y;
3068 
3069  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
3070  x*x*y, x*y*y
3071  };
3072  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
3073  x*x*y, x*y*y, y*y*y
3074  };
3075 
3076  for (int i = 0; i < 15; i++)
3077  {
3078  double cx = 0.0, cy = 0.0;
3079  for (int j = 0; j < 15; j++)
3080  {
3081  cx += M[i][j] * Bx[j];
3082  cy += M[i][j] * By[j];
3083  }
3084  shape(i,0) = cx;
3085  shape(i,1) = cy;
3086  }
3087 }
3088 
3090  Vector &divshape) const
3091 {
3092  double x = ip.x, y = ip.y;
3093 
3094  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
3095  4.*x*x, 4.*x*y, 4.*y*y
3096  };
3097 
3098  for (int i = 0; i < 15; i++)
3099  {
3100  double div = 0.0;
3101  for (int j = 0; j < 15; j++)
3102  {
3103  div += M[i][j] * DivB[j];
3104  }
3105  divshape(i) = div;
3106  }
3107 }
3108 
3109 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
3110 
3111 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
3112 
3114  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
3115 {
3116  // y = 0 (pt[0])
3117  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
3118  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
3119  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
3120  // x = 1 (pt[3])
3121  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
3122  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
3123  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
3124  // y = 1 (pt[3])
3125  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
3126  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
3127  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
3128  // x = 0 (pt[0])
3129  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
3130  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
3131  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
3132  // x = pt[1] (interior)
3133  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
3134  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
3135  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
3136  // x = pt[2] (interior)
3137  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
3138  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
3139  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
3140  // y = pt[1] (interior)
3141  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
3142  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
3143  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
3144  // y = pt[2] (interior)
3145  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
3146  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
3147  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
3148 }
3149 
3151  DenseMatrix &shape) const
3152 {
3153  double x = ip.x, y = ip.y;
3154 
3155  double ax0 = pt[0] - x;
3156  double ax1 = pt[1] - x;
3157  double ax2 = pt[2] - x;
3158  double ax3 = pt[3] - x;
3159 
3160  double by0 = dpt[0] - y;
3161  double by1 = dpt[1] - y;
3162  double by2 = dpt[2] - y;
3163 
3164  double ay0 = pt[0] - y;
3165  double ay1 = pt[1] - y;
3166  double ay2 = pt[2] - y;
3167  double ay3 = pt[3] - y;
3168 
3169  double bx0 = dpt[0] - x;
3170  double bx1 = dpt[1] - x;
3171  double bx2 = dpt[2] - x;
3172 
3173  double A01 = pt[0] - pt[1];
3174  double A02 = pt[0] - pt[2];
3175  double A12 = pt[1] - pt[2];
3176  double A03 = pt[0] - pt[3];
3177  double A13 = pt[1] - pt[3];
3178  double A23 = pt[2] - pt[3];
3179 
3180  double B01 = dpt[0] - dpt[1];
3181  double B02 = dpt[0] - dpt[2];
3182  double B12 = dpt[1] - dpt[2];
3183 
3184  double tx0 = (bx1*bx2)/(B01*B02);
3185  double tx1 = -(bx0*bx2)/(B01*B12);
3186  double tx2 = (bx0*bx1)/(B02*B12);
3187 
3188  double ty0 = (by1*by2)/(B01*B02);
3189  double ty1 = -(by0*by2)/(B01*B12);
3190  double ty2 = (by0*by1)/(B02*B12);
3191 
3192  // y = 0 (p[0])
3193  shape(0, 0) = 0;
3194  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
3195  shape(1, 0) = 0;
3196  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
3197  shape(2, 0) = 0;
3198  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
3199  // x = 1 (p[3])
3200  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
3201  shape(3, 1) = 0;
3202  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
3203  shape(4, 1) = 0;
3204  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
3205  shape(5, 1) = 0;
3206  // y = 1 (p[3])
3207  shape(6, 0) = 0;
3208  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
3209  shape(7, 0) = 0;
3210  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
3211  shape(8, 0) = 0;
3212  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
3213  // x = 0 (p[0])
3214  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
3215  shape(9, 1) = 0;
3216  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
3217  shape(10, 1) = 0;
3218  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
3219  shape(11, 1) = 0;
3220  // x = p[1] (interior)
3221  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
3222  shape(12, 1) = 0;
3223  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
3224  shape(13, 1) = 0;
3225  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
3226  shape(14, 1) = 0;
3227  // x = p[2] (interior)
3228  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
3229  shape(15, 1) = 0;
3230  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
3231  shape(16, 1) = 0;
3232  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
3233  shape(17, 1) = 0;
3234  // y = p[1] (interior)
3235  shape(18, 0) = 0;
3236  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
3237  shape(19, 0) = 0;
3238  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
3239  shape(20, 0) = 0;
3240  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
3241  // y = p[2] (interior)
3242  shape(21, 0) = 0;
3243  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
3244  shape(22, 0) = 0;
3245  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
3246  shape(23, 0) = 0;
3247  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
3248 }
3249 
3251  Vector &divshape) const
3252 {
3253  double x = ip.x, y = ip.y;
3254 
3255  double a01 = pt[0]*pt[1];
3256  double a02 = pt[0]*pt[2];
3257  double a12 = pt[1]*pt[2];
3258  double a03 = pt[0]*pt[3];
3259  double a13 = pt[1]*pt[3];
3260  double a23 = pt[2]*pt[3];
3261 
3262  double bx0 = dpt[0] - x;
3263  double bx1 = dpt[1] - x;
3264  double bx2 = dpt[2] - x;
3265 
3266  double by0 = dpt[0] - y;
3267  double by1 = dpt[1] - y;
3268  double by2 = dpt[2] - y;
3269 
3270  double A01 = pt[0] - pt[1];
3271  double A02 = pt[0] - pt[2];
3272  double A12 = pt[1] - pt[2];
3273  double A03 = pt[0] - pt[3];
3274  double A13 = pt[1] - pt[3];
3275  double A23 = pt[2] - pt[3];
3276 
3277  double A012 = pt[0] + pt[1] + pt[2];
3278  double A013 = pt[0] + pt[1] + pt[3];
3279  double A023 = pt[0] + pt[2] + pt[3];
3280  double A123 = pt[1] + pt[2] + pt[3];
3281 
3282  double B01 = dpt[0] - dpt[1];
3283  double B02 = dpt[0] - dpt[2];
3284  double B12 = dpt[1] - dpt[2];
3285 
3286  double tx0 = (bx1*bx2)/(B01*B02);
3287  double tx1 = -(bx0*bx2)/(B01*B12);
3288  double tx2 = (bx0*bx1)/(B02*B12);
3289 
3290  double ty0 = (by1*by2)/(B01*B02);
3291  double ty1 = -(by0*by2)/(B01*B12);
3292  double ty2 = (by0*by1)/(B02*B12);
3293 
3294  // y = 0 (p[0])
3295  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
3296  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
3297  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
3298  // x = 1 (p[3])
3299  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
3300  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
3301  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
3302  // y = 1 (p[3])
3303  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
3304  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
3305  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
3306  // x = 0 (p[0])
3307  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
3308  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
3309  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
3310  // x = p[1] (interior)
3311  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
3312  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
3313  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
3314  // x = p[2] (interior)
3315  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
3316  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
3317  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
3318  // y = p[1] (interior)
3319  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
3320  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
3321  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
3322  // y = p[2] (interior)
3323  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
3324  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
3325  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
3326 }
3327 
3328 const double RT2QuadFiniteElement::nk[24][2] =
3329 {
3330  // y = 0
3331  {0,-1}, {0,-1}, {0,-1},
3332  // x = 1
3333  {1, 0}, {1, 0}, {1, 0},
3334  // y = 1
3335  {0, 1}, {0, 1}, {0, 1},
3336  // x = 0
3337  {-1,0}, {-1,0}, {-1,0},
3338  // x = p[1] (interior)
3339  {1, 0}, {1, 0}, {1, 0},
3340  // x = p[2] (interior)
3341  {1, 0}, {1, 0}, {1, 0},
3342  // y = p[1] (interior)
3343  {0, 1}, {0, 1}, {0, 1},
3344  // y = p[1] (interior)
3345  {0, 1}, {0, 1}, {0, 1}
3346 };
3347 
3350 {
3351  int k, j;
3352 #ifdef MFEM_THREAD_SAFE
3354  DenseMatrix Jinv(Dim);
3355 #endif
3356 
3357 #ifdef MFEM_DEBUG
3358  for (k = 0; k < 24; k++)
3359  {
3361  for (j = 0; j < 24; j++)
3362  {
3363  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3364  if (j == k) { d -= 1.0; }
3365  if (fabs(d) > 1.0e-12)
3366  {
3367  cerr << "RT2QuadFiniteElement::GetLocalInterpolation (...)\n"
3368  " k = " << k << ", j = " << j << ", d = " << d << endl;
3369  mfem_error();
3370  }
3371  }
3372  }
3373 #endif
3374 
3375  IntegrationPoint ip;
3376  ip.x = ip.y = 0.0;
3377  Trans.SetIntPoint (&ip);
3378  // Trans must be linear (more to have embedding?)
3379  // set Jinv = |J| J^{-t} = adj(J)^t
3380  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3381  double vk[2];
3382  Vector xk (vk, 2);
3383 
3384  for (k = 0; k < 24; k++)
3385  {
3386  Trans.Transform (Nodes.IntPoint (k), xk);
3387  ip.x = vk[0]; ip.y = vk[1];
3388  CalcVShape (ip, vshape);
3389  // vk = |J| J^{-t} nk
3390  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3391  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3392  for (j = 0; j < 24; j++)
3393  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3394  {
3395  I(k,j) = 0.0;
3396  }
3397  }
3398 }
3399 
3402 {
3403  double vk[2];
3404  Vector xk (vk, 2);
3405 #ifdef MFEM_THREAD_SAFE
3406  DenseMatrix Jinv(Dim);
3407 #endif
3408 
3409  for (int k = 0; k < 24; k++)
3410  {
3411  Trans.SetIntPoint (&Nodes.IntPoint (k));
3412  // set Jinv = |J| J^{-t} = adj(J)^t
3413  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3414 
3415  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3416  // xk^t |J| J^{-t} nk
3417  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3418  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3419  }
3420 }
3421 
3423  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
3424 {
3425  Nodes.IntPoint(0).x = 0.33333333333333333333;
3426  Nodes.IntPoint(1).x = 0.66666666666666666667;
3427 }
3428 
3430  Vector &shape) const
3431 {
3432  double x = ip.x;
3433 
3434  shape(0) = 2. - 3. * x;
3435  shape(1) = 3. * x - 1.;
3436 }
3437 
3439  DenseMatrix &dshape) const
3440 {
3441  dshape(0,0) = -3.;
3442  dshape(1,0) = 3.;
3443 }
3444 
3445 
3447  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
3448 {
3449  const double p = 0.11270166537925831148;
3450 
3451  Nodes.IntPoint(0).x = p;
3452  Nodes.IntPoint(1).x = 0.5;
3453  Nodes.IntPoint(2).x = 1.-p;
3454 }
3455 
3457  Vector &shape) const
3458 {
3459  const double p = 0.11270166537925831148;
3460  const double w = 1./((1-2*p)*(1-2*p));
3461  double x = ip.x;
3462 
3463  shape(0) = (2*x-1)*(x-1+p)*w;
3464  shape(1) = 4*(x-1+p)*(p-x)*w;
3465  shape(2) = (2*x-1)*(x-p)*w;
3466 }
3467 
3469  DenseMatrix &dshape) const
3470 {
3471  const double p = 0.11270166537925831148;
3472  const double w = 1./((1-2*p)*(1-2*p));
3473  double x = ip.x;
3474 
3475  dshape(0,0) = (-3+4*x+2*p)*w;
3476  dshape(1,0) = (4-8*x)*w;
3477  dshape(2,0) = (-1+4*x-2*p)*w;
3478 }
3479 
3480 
3482  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
3483 {
3484  int i, m = degree;
3485 
3486  Nodes.IntPoint(0).x = 0.0;
3487  Nodes.IntPoint(1).x = 1.0;
3488  for (i = 1; i < m; i++)
3489  {
3490  Nodes.IntPoint(i+1).x = double(i) / m;
3491  }
3492 
3493  rwk.SetSize(degree+1);
3494 #ifndef MFEM_THREAD_SAFE
3495  rxxk.SetSize(degree+1);
3496 #endif
3497 
3498  rwk(0) = 1.0;
3499  for (i = 1; i <= m; i++)
3500  {
3501  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
3502  }
3503  for (i = 0; i < m/2+1; i++)
3504  {
3505  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
3506  }
3507  for (i = m-1; i >= 0; i -= 2)
3508  {
3509  rwk(i) = -rwk(i);
3510  }
3511 }
3512 
3514  Vector &shape) const
3515 {
3516  double w, wk, x = ip.x;
3517  int i, k, m = GetOrder();
3518 
3519 #ifdef MFEM_THREAD_SAFE
3520  Vector rxxk(m+1);
3521 #endif
3522 
3523  k = (int) floor ( m * x + 0.5 );
3524  wk = 1.0;
3525  for (i = 0; i <= m; i++)
3526  if (i != k)
3527  {
3528  wk *= ( rxxk(i) = x - (double)(i) / m );
3529  }
3530  w = wk * ( rxxk(k) = x - (double)(k) / m );
3531 
3532  if (k != 0)
3533  {
3534  shape(0) = w * rwk(0) / rxxk(0);
3535  }
3536  else
3537  {
3538  shape(0) = wk * rwk(0);
3539  }
3540  if (k != m)
3541  {
3542  shape(1) = w * rwk(m) / rxxk(m);
3543  }
3544  else
3545  {
3546  shape(1) = wk * rwk(k);
3547  }
3548  for (i = 1; i < m; i++)
3549  if (i != k)
3550  {
3551  shape(i+1) = w * rwk(i) / rxxk(i);
3552  }
3553  else
3554  {
3555  shape(k+1) = wk * rwk(k);
3556  }
3557 }
3558 
3560  DenseMatrix &dshape) const
3561 {
3562  double s, srx, w, wk, x = ip.x;
3563  int i, k, m = GetOrder();
3564 
3565 #ifdef MFEM_THREAD_SAFE
3566  Vector rxxk(m+1);
3567 #endif
3568 
3569  k = (int) floor ( m * x + 0.5 );
3570  wk = 1.0;
3571  for (i = 0; i <= m; i++)
3572  if (i != k)
3573  {
3574  wk *= ( rxxk(i) = x - (double)(i) / m );
3575  }
3576  w = wk * ( rxxk(k) = x - (double)(k) / m );
3577 
3578  for (i = 0; i <= m; i++)
3579  {
3580  rxxk(i) = 1.0 / rxxk(i);
3581  }
3582  srx = 0.0;
3583  for (i = 0; i <= m; i++)
3584  if (i != k)
3585  {
3586  srx += rxxk(i);
3587  }
3588  s = w * srx + wk;
3589 
3590  if (k != 0)
3591  {
3592  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
3593  }
3594  else
3595  {
3596  dshape(0,0) = wk * srx * rwk(0);
3597  }
3598  if (k != m)
3599  {
3600  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
3601  }
3602  else
3603  {
3604  dshape(1,0) = wk * srx * rwk(k);
3605  }
3606  for (i = 1; i < m; i++)
3607  if (i != k)
3608  {
3609  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
3610  }
3611  else
3612  {
3613  dshape(k+1,0) = wk * srx * rwk(k);
3614  }
3615 }
3616 
3617 
3619  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
3620 {
3621  Nodes.IntPoint(0).x = 0.33333333333333333333;
3622  Nodes.IntPoint(0).y = 0.33333333333333333333;
3623  Nodes.IntPoint(0).z = 0.33333333333333333333;
3624 
3625  Nodes.IntPoint(1).x = 0.0;
3626  Nodes.IntPoint(1).y = 0.33333333333333333333;
3627  Nodes.IntPoint(1).z = 0.33333333333333333333;
3628 
3629  Nodes.IntPoint(2).x = 0.33333333333333333333;
3630  Nodes.IntPoint(2).y = 0.0;
3631  Nodes.IntPoint(2).z = 0.33333333333333333333;
3632 
3633  Nodes.IntPoint(3).x = 0.33333333333333333333;
3634  Nodes.IntPoint(3).y = 0.33333333333333333333;
3635  Nodes.IntPoint(3).z = 0.0;
3636 
3637 }
3638 
3640  Vector &shape) const
3641 {
3642  double L0, L1, L2, L3;
3643 
3644  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
3645  shape(0) = 1.0 - 3.0 * L0;
3646  shape(1) = 1.0 - 3.0 * L1;
3647  shape(2) = 1.0 - 3.0 * L2;
3648  shape(3) = 1.0 - 3.0 * L3;
3649 }
3650 
3652  DenseMatrix &dshape) const
3653 {
3654  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
3655  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
3656  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
3657  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
3658 }
3659 
3660 
3662  : NodalFiniteElement(3, Geometry::TETRAHEDRON , 1, 0)
3663 {
3664  Nodes.IntPoint(0).x = 0.25;
3665  Nodes.IntPoint(0).y = 0.25;
3666  Nodes.IntPoint(0).z = 0.25;
3667 }
3668 
3670  Vector &shape) const
3671 {
3672  shape(0) = 1.0;
3673 }
3674 
3676  DenseMatrix &dshape) const
3677 {
3678  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3679 }
3680 
3681 
3683  : NodalFiniteElement(3, Geometry::CUBE, 1, 0, FunctionSpace::Qk)
3684 {
3685  Nodes.IntPoint(0).x = 0.5;
3686  Nodes.IntPoint(0).y = 0.5;
3687  Nodes.IntPoint(0).z = 0.5;
3688 }
3689 
3691  Vector &shape) const
3692 {
3693  shape(0) = 1.0;
3694 }
3695 
3697  DenseMatrix &dshape) const
3698 {
3699  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3700 }
3701 
3702 
3704  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
3705  degree, FunctionSpace::Qk)
3706 {
3707  if (degree == 2)
3708  {
3709  I = new int[Dof];
3710  J = new int[Dof];
3711  K = new int[Dof];
3712  // nodes
3713  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3714  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3715  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3716  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3717  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3718  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3719  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3720  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3721  // edges
3722  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3723  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
3724  I[10] = 2; J[10] = 1; K[10] = 0;
3725  I[11] = 0; J[11] = 2; K[11] = 0;
3726  I[12] = 2; J[12] = 0; K[12] = 1;
3727  I[13] = 1; J[13] = 2; K[13] = 1;
3728  I[14] = 2; J[14] = 1; K[14] = 1;
3729  I[15] = 0; J[15] = 2; K[15] = 1;
3730  I[16] = 0; J[16] = 0; K[16] = 2;
3731  I[17] = 1; J[17] = 0; K[17] = 2;
3732  I[18] = 1; J[18] = 1; K[18] = 2;
3733  I[19] = 0; J[19] = 1; K[19] = 2;
3734  // faces
3735  I[20] = 2; J[20] = 2; K[20] = 0;
3736  I[21] = 2; J[21] = 0; K[21] = 2;
3737  I[22] = 1; J[22] = 2; K[22] = 2;
3738  I[23] = 2; J[23] = 1; K[23] = 2;
3739  I[24] = 0; J[24] = 2; K[24] = 2;
3740  I[25] = 2; J[25] = 2; K[25] = 1;
3741  // element
3742  I[26] = 2; J[26] = 2; K[26] = 2;
3743  }
3744  else if (degree == 3)
3745  {
3746  I = new int[Dof];
3747  J = new int[Dof];
3748  K = new int[Dof];
3749  // nodes
3750  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3751  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3752  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3753  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3754  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3755  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3756  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3757  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3758  // edges
3759  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3760  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
3761  I[10] = 1; J[10] = 2; K[10] = 0;
3762  I[11] = 1; J[11] = 3; K[11] = 0;
3763  I[12] = 2; J[12] = 1; K[12] = 0;
3764  I[13] = 3; J[13] = 1; K[13] = 0;
3765  I[14] = 0; J[14] = 2; K[14] = 0;
3766  I[15] = 0; J[15] = 3; K[15] = 0;
3767  I[16] = 2; J[16] = 0; K[16] = 1;
3768  I[17] = 3; J[17] = 0; K[17] = 1;
3769  I[18] = 1; J[18] = 2; K[18] = 1;
3770  I[19] = 1; J[19] = 3; K[19] = 1;
3771  I[20] = 2; J[20] = 1; K[20] = 1;
3772  I[21] = 3; J[21] = 1; K[21] = 1;
3773  I[22] = 0; J[22] = 2; K[22] = 1;
3774  I[23] = 0; J[23] = 3; K[23] = 1;
3775  I[24] = 0; J[24] = 0; K[24] = 2;
3776  I[25] = 0; J[25] = 0; K[25] = 3;
3777  I[26] = 1; J[26] = 0; K[26] = 2;
3778  I[27] = 1; J[27] = 0; K[27] = 3;
3779  I[28] = 1; J[28] = 1; K[28] = 2;
3780  I[29] = 1; J[29] = 1; K[29] = 3;
3781  I[30] = 0; J[30] = 1; K[30] = 2;
3782  I[31] = 0; J[31] = 1; K[31] = 3;
3783  // faces
3784  I[32] = 2; J[32] = 3; K[32] = 0;
3785  I[33] = 3; J[33] = 3; K[33] = 0;
3786  I[34] = 2; J[34] = 2; K[34] = 0;
3787  I[35] = 3; J[35] = 2; K[35] = 0;
3788  I[36] = 2; J[36] = 0; K[36] = 2;
3789  I[37] = 3; J[37] = 0; K[37] = 2;
3790  I[38] = 2; J[38] = 0; K[38] = 3;
3791  I[39] = 3; J[39] = 0; K[39] = 3;
3792  I[40] = 1; J[40] = 2; K[40] = 2;
3793  I[41] = 1; J[41] = 3; K[41] = 2;
3794  I[42] = 1; J[42] = 2; K[42] = 3;
3795  I[43] = 1; J[43] = 3; K[43] = 3;
3796  I[44] = 3; J[44] = 1; K[44] = 2;
3797  I[45] = 2; J[45] = 1; K[45] = 2;
3798  I[46] = 3; J[46] = 1; K[46] = 3;
3799  I[47] = 2; J[47] = 1; K[47] = 3;
3800  I[48] = 0; J[48] = 3; K[48] = 2;
3801  I[49] = 0; J[49] = 2; K[49] = 2;
3802  I[50] = 0; J[50] = 3; K[50] = 3;
3803  I[51] = 0; J[51] = 2; K[51] = 3;
3804  I[52] = 2; J[52] = 2; K[52] = 1;
3805  I[53] = 3; J[53] = 2; K[53] = 1;
3806  I[54] = 2; J[54] = 3; K[54] = 1;
3807  I[55] = 3; J[55] = 3; K[55] = 1;
3808  // element
3809  I[56] = 2; J[56] = 2; K[56] = 2;
3810  I[57] = 3; J[57] = 2; K[57] = 2;
3811  I[58] = 3; J[58] = 3; K[58] = 2;
3812  I[59] = 2; J[59] = 3; K[59] = 2;
3813  I[60] = 2; J[60] = 2; K[60] = 3;
3814  I[61] = 3; J[61] = 2; K[61] = 3;
3815  I[62] = 3; J[62] = 3; K[62] = 3;
3816  I[63] = 2; J[63] = 3; K[63] = 3;
3817  }
3818  else
3819  {
3820  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
3821  }
3822 
3823  fe1d = new Lagrange1DFiniteElement(degree);
3824  dof1d = fe1d -> GetDof();
3825 
3826 #ifndef MFEM_THREAD_SAFE
3827  shape1dx.SetSize(dof1d);
3828  shape1dy.SetSize(dof1d);
3829  shape1dz.SetSize(dof1d);
3830 
3831  dshape1dx.SetSize(dof1d,1);
3832  dshape1dy.SetSize(dof1d,1);
3833  dshape1dz.SetSize(dof1d,1);
3834 #endif
3835 
3836  for (int n = 0; n < Dof; n++)
3837  {
3838  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
3839  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
3840  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
3841  }
3842 }
3843 
3845  Vector &shape) const
3846 {
3847  IntegrationPoint ipy, ipz;
3848  ipy.x = ip.y;
3849  ipz.x = ip.z;
3850 
3851 #ifdef MFEM_THREAD_SAFE
3852  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
3853 #endif
3854 
3855  fe1d -> CalcShape(ip, shape1dx);
3856  fe1d -> CalcShape(ipy, shape1dy);
3857  fe1d -> CalcShape(ipz, shape1dz);
3858 
3859  for (int n = 0; n < Dof; n++)
3860  {
3861  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
3862  }
3863 }
3864 
3866  DenseMatrix &dshape) const
3867 {
3868  IntegrationPoint ipy, ipz;
3869  ipy.x = ip.y;
3870  ipz.x = ip.z;
3871 
3872 #ifdef MFEM_THREAD_SAFE
3873  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
3874  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
3875 #endif
3876 
3877  fe1d -> CalcShape(ip, shape1dx);
3878  fe1d -> CalcShape(ipy, shape1dy);
3879  fe1d -> CalcShape(ipz, shape1dz);
3880 
3881  fe1d -> CalcDShape(ip, dshape1dx);
3882  fe1d -> CalcDShape(ipy, dshape1dy);
3883  fe1d -> CalcDShape(ipz, dshape1dz);
3884 
3885  for (int n = 0; n < Dof; n++)
3886  {
3887  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
3888  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
3889  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
3890  }
3891 }
3892 
3894 {
3895  delete fe1d;
3896 
3897  delete [] I;
3898  delete [] J;
3899  delete [] K;
3900 }
3901 
3902 
3904  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
3905 {
3906  Nodes.IntPoint(0).x = 0.0;
3907  Nodes.IntPoint(1).x = 1.0;
3908  Nodes.IntPoint(2).x = 0.5;
3909 }
3910 
3912  Vector &shape) const
3913 {
3914  double x = ip.x;
3915 
3916  if (x <= 0.5)
3917  {
3918  shape(0) = 1.0 - 2.0 * x;
3919  shape(1) = 0.0;
3920  shape(2) = 2.0 * x;
3921  }
3922  else
3923  {
3924  shape(0) = 0.0;
3925  shape(1) = 2.0 * x - 1.0;
3926  shape(2) = 2.0 - 2.0 * x;
3927  }
3928 }
3929 
3931  DenseMatrix &dshape) const
3932 {
3933  double x = ip.x;
3934 
3935  if (x <= 0.5)
3936  {
3937  dshape(0,0) = - 2.0;
3938  dshape(1,0) = 0.0;
3939  dshape(2,0) = 2.0;
3940  }
3941  else
3942  {
3943  dshape(0,0) = 0.0;
3944  dshape(1,0) = 2.0;
3945  dshape(2,0) = - 2.0;
3946  }
3947 }
3948 
3950  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
3951 {
3952  Nodes.IntPoint(0).x = 0.0;
3953  Nodes.IntPoint(0).y = 0.0;
3954  Nodes.IntPoint(1).x = 1.0;
3955  Nodes.IntPoint(1).y = 0.0;
3956  Nodes.IntPoint(2).x = 0.0;
3957  Nodes.IntPoint(2).y = 1.0;
3958  Nodes.IntPoint(3).x = 0.5;
3959  Nodes.IntPoint(3).y = 0.0;
3960  Nodes.IntPoint(4).x = 0.5;
3961  Nodes.IntPoint(4).y = 0.5;
3962  Nodes.IntPoint(5).x = 0.0;
3963  Nodes.IntPoint(5).y = 0.5;
3964 }
3965 
3967  Vector &shape) const
3968 {
3969  int i;
3970 
3971  double L0, L1, L2;
3972  L0 = 2.0 * ( 1. - ip.x - ip.y );
3973  L1 = 2.0 * ( ip.x );
3974  L2 = 2.0 * ( ip.y );
3975 
3976  // The reference triangle is split in 4 triangles as follows:
3977  //
3978  // T0 - 0,3,5
3979  // T1 - 1,3,4
3980  // T2 - 2,4,5
3981  // T3 - 3,4,5
3982 
3983  for (i = 0; i < 6; i++)
3984  {
3985  shape(i) = 0.0;
3986  }
3987 
3988  if (L0 >= 1.0) // T0
3989  {
3990  shape(0) = L0 - 1.0;
3991  shape(3) = L1;
3992  shape(5) = L2;
3993  }
3994  else if (L1 >= 1.0) // T1
3995  {
3996  shape(3) = L0;
3997  shape(1) = L1 - 1.0;
3998  shape(4) = L2;
3999  }
4000  else if (L2 >= 1.0) // T2
4001  {
4002  shape(5) = L0;
4003  shape(4) = L1;
4004  shape(2) = L2 - 1.0;
4005  }
4006  else // T3
4007  {
4008  shape(3) = 1.0 - L2;
4009  shape(4) = 1.0 - L0;
4010  shape(5) = 1.0 - L1;
4011  }
4012 }
4013 
4015  DenseMatrix &dshape) const
4016 {
4017  int i,j;
4018 
4019  double L0, L1, L2;
4020  L0 = 2.0 * ( 1. - ip.x - ip.y );
4021  L1 = 2.0 * ( ip.x );
4022  L2 = 2.0 * ( ip.y );
4023 
4024  double DL0[2], DL1[2], DL2[2];
4025  DL0[0] = -2.0; DL0[1] = -2.0;
4026  DL1[0] = 2.0; DL1[1] = 0.0;
4027  DL2[0] = 0.0; DL2[1] = 2.0;
4028 
4029  for (i = 0; i < 6; i++)
4030  for (j = 0; j < 2; j++)
4031  {
4032  dshape(i,j) = 0.0;
4033  }
4034 
4035  if (L0 >= 1.0) // T0
4036  {
4037  for (j = 0; j < 2; j++)
4038  {
4039  dshape(0,j) = DL0[j];
4040  dshape(3,j) = DL1[j];
4041  dshape(5,j) = DL2[j];
4042  }
4043  }
4044  else if (L1 >= 1.0) // T1
4045  {
4046  for (j = 0; j < 2; j++)
4047  {
4048  dshape(3,j) = DL0[j];
4049  dshape(1,j) = DL1[j];
4050  dshape(4,j) = DL2[j];
4051  }
4052  }
4053  else if (L2 >= 1.0) // T2
4054  {
4055  for (j = 0; j < 2; j++)
4056  {
4057  dshape(5,j) = DL0[j];
4058  dshape(4,j) = DL1[j];
4059  dshape(2,j) = DL2[j];
4060  }
4061  }
4062  else // T3
4063  {
4064  for (j = 0; j < 2; j++)
4065  {
4066  dshape(3,j) = - DL2[j];
4067  dshape(4,j) = - DL0[j];
4068  dshape(5,j) = - DL1[j];
4069  }
4070  }
4071 }
4072 
4074  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
4075 {
4076  Nodes.IntPoint(0).x = 0.0;
4077  Nodes.IntPoint(0).y = 0.0;
4078  Nodes.IntPoint(0).z = 0.0;
4079  Nodes.IntPoint(1).x = 1.0;
4080  Nodes.IntPoint(1).y = 0.0;
4081  Nodes.IntPoint(1).z = 0.0;
4082  Nodes.IntPoint(2).x = 0.0;
4083  Nodes.IntPoint(2).y = 1.0;
4084  Nodes.IntPoint(2).z = 0.0;
4085  Nodes.IntPoint(3).x = 0.0;
4086  Nodes.IntPoint(3).y = 0.0;
4087  Nodes.IntPoint(3).z = 1.0;
4088  Nodes.IntPoint(4).x = 0.5;
4089  Nodes.IntPoint(4).y = 0.0;
4090  Nodes.IntPoint(4).z = 0.0;
4091  Nodes.IntPoint(5).x = 0.0;
4092  Nodes.IntPoint(5).y = 0.5;
4093  Nodes.IntPoint(5).z = 0.0;
4094  Nodes.IntPoint(6).x = 0.0;
4095  Nodes.IntPoint(6).y = 0.0;
4096  Nodes.IntPoint(6).z = 0.5;
4097  Nodes.IntPoint(7).x = 0.5;
4098  Nodes.IntPoint(7).y = 0.5;
4099  Nodes.IntPoint(7).z = 0.0;
4100  Nodes.IntPoint(8).x = 0.5;
4101  Nodes.IntPoint(8).y = 0.0;
4102  Nodes.IntPoint(8).z = 0.5;
4103  Nodes.IntPoint(9).x = 0.0;
4104  Nodes.IntPoint(9).y = 0.5;
4105  Nodes.IntPoint(9).z = 0.5;
4106 }
4107 
4109  Vector &shape) const
4110 {
4111  int i;
4112 
4113  double L0, L1, L2, L3, L4, L5;
4114  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4115  L1 = 2.0 * ( ip.x );
4116  L2 = 2.0 * ( ip.y );
4117  L3 = 2.0 * ( ip.z );
4118  L4 = 2.0 * ( ip.x + ip.y );
4119  L5 = 2.0 * ( ip.y + ip.z );
4120 
4121  // The reference tetrahedron is split in 8 tetrahedra as follows:
4122  //
4123  // T0 - 0,4,5,6
4124  // T1 - 1,4,7,8
4125  // T2 - 2,5,7,9
4126  // T3 - 3,6,8,9
4127  // T4 - 4,5,6,8
4128  // T5 - 4,5,7,8
4129  // T6 - 5,6,8,9
4130  // T7 - 5,7,8,9
4131 
4132  for (i = 0; i < 10; i++)
4133  {
4134  shape(i) = 0.0;
4135  }
4136 
4137  if (L0 >= 1.0) // T0
4138  {
4139  shape(0) = L0 - 1.0;
4140  shape(4) = L1;
4141  shape(5) = L2;
4142  shape(6) = L3;
4143  }
4144  else if (L1 >= 1.0) // T1
4145  {
4146  shape(4) = L0;
4147  shape(1) = L1 - 1.0;
4148  shape(7) = L2;
4149  shape(8) = L3;
4150  }
4151  else if (L2 >= 1.0) // T2
4152  {
4153  shape(5) = L0;
4154  shape(7) = L1;
4155  shape(2) = L2 - 1.0;
4156  shape(9) = L3;
4157  }
4158  else if (L3 >= 1.0) // T3
4159  {
4160  shape(6) = L0;
4161  shape(8) = L1;
4162  shape(9) = L2;
4163  shape(3) = L3 - 1.0;
4164  }
4165  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4166  {
4167  shape(4) = 1.0 - L5;
4168  shape(5) = L2;
4169  shape(6) = 1.0 - L4;
4170  shape(8) = 1.0 - L0;
4171  }
4172  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4173  {
4174  shape(4) = 1.0 - L5;
4175  shape(5) = 1.0 - L1;
4176  shape(7) = L4 - 1.0;
4177  shape(8) = L3;
4178  }
4179  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4180  {
4181  shape(5) = 1.0 - L3;
4182  shape(6) = 1.0 - L4;
4183  shape(8) = L1;
4184  shape(9) = L5 - 1.0;
4185  }
4186  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4187  {
4188  shape(5) = L0;
4189  shape(7) = L4 - 1.0;
4190  shape(8) = 1.0 - L2;
4191  shape(9) = L5 - 1.0;
4192  }
4193 }
4194 
4196  DenseMatrix &dshape) const
4197 {
4198  int i,j;
4199 
4200  double L0, L1, L2, L3, L4, L5;
4201  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4202  L1 = 2.0 * ( ip.x );
4203  L2 = 2.0 * ( ip.y );
4204  L3 = 2.0 * ( ip.z );
4205  L4 = 2.0 * ( ip.x + ip.y );
4206  L5 = 2.0 * ( ip.y + ip.z );
4207 
4208  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
4209  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
4210  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
4211  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
4212  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
4213  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
4214  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
4215 
4216  for (i = 0; i < 10; i++)
4217  for (j = 0; j < 3; j++)
4218  {
4219  dshape(i,j) = 0.0;
4220  }
4221 
4222  if (L0 >= 1.0) // T0
4223  {
4224  for (j = 0; j < 3; j++)
4225  {
4226  dshape(0,j) = DL0[j];
4227  dshape(4,j) = DL1[j];
4228  dshape(5,j) = DL2[j];
4229  dshape(6,j) = DL3[j];
4230  }
4231  }
4232  else if (L1 >= 1.0) // T1
4233  {
4234  for (j = 0; j < 3; j++)
4235  {
4236  dshape(4,j) = DL0[j];
4237  dshape(1,j) = DL1[j];
4238  dshape(7,j) = DL2[j];
4239  dshape(8,j) = DL3[j];
4240  }
4241  }
4242  else if (L2 >= 1.0) // T2
4243  {
4244  for (j = 0; j < 3; j++)
4245  {
4246  dshape(5,j) = DL0[j];
4247  dshape(7,j) = DL1[j];
4248  dshape(2,j) = DL2[j];
4249  dshape(9,j) = DL3[j];
4250  }
4251  }
4252  else if (L3 >= 1.0) // T3
4253  {
4254  for (j = 0; j < 3; j++)
4255  {
4256  dshape(6,j) = DL0[j];
4257  dshape(8,j) = DL1[j];
4258  dshape(9,j) = DL2[j];
4259  dshape(3,j) = DL3[j];
4260  }
4261  }
4262  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4263  {
4264  for (j = 0; j < 3; j++)
4265  {
4266  dshape(4,j) = - DL5[j];
4267  dshape(5,j) = DL2[j];
4268  dshape(6,j) = - DL4[j];
4269  dshape(8,j) = - DL0[j];
4270  }
4271  }
4272  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4273  {
4274  for (j = 0; j < 3; j++)
4275  {
4276  dshape(4,j) = - DL5[j];
4277  dshape(5,j) = - DL1[j];
4278  dshape(7,j) = DL4[j];
4279  dshape(8,j) = DL3[j];
4280  }
4281  }
4282  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4283  {
4284  for (j = 0; j < 3; j++)
4285  {
4286  dshape(5,j) = - DL3[j];
4287  dshape(6,j) = - DL4[j];
4288  dshape(8,j) = DL1[j];
4289  dshape(9,j) = DL5[j];
4290  }
4291  }
4292  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4293  {
4294  for (j = 0; j < 3; j++)
4295  {
4296  dshape(5,j) = DL0[j];
4297  dshape(7,j) = DL4[j];
4298  dshape(8,j) = - DL2[j];
4299  dshape(9,j) = DL5[j];
4300  }
4301  }
4302 }
4303 
4304 
4306  : NodalFiniteElement(2, Geometry::SQUARE , 9, 1, FunctionSpace::rQk)
4307 {
4308  Nodes.IntPoint(0).x = 0.0;
4309  Nodes.IntPoint(0).y = 0.0;
4310  Nodes.IntPoint(1).x = 1.0;
4311  Nodes.IntPoint(1).y = 0.0;
4312  Nodes.IntPoint(2).x = 1.0;
4313  Nodes.IntPoint(2).y = 1.0;
4314  Nodes.IntPoint(3).x = 0.0;
4315  Nodes.IntPoint(3).y = 1.0;
4316  Nodes.IntPoint(4).x = 0.5;
4317  Nodes.IntPoint(4).y = 0.0;
4318  Nodes.IntPoint(5).x = 1.0;
4319  Nodes.IntPoint(5).y = 0.5;
4320  Nodes.IntPoint(6).x = 0.5;
4321  Nodes.IntPoint(6).y = 1.0;
4322  Nodes.IntPoint(7).x = 0.0;
4323  Nodes.IntPoint(7).y = 0.5;
4324  Nodes.IntPoint(8).x = 0.5;
4325  Nodes.IntPoint(8).y = 0.5;
4326 }
4327 
4329  Vector &shape) const
4330 {
4331  int i;
4332  double x = ip.x, y = ip.y;
4333  double Lx, Ly;
4334  Lx = 2.0 * ( 1. - x );
4335  Ly = 2.0 * ( 1. - y );
4336 
4337  // The reference square is split in 4 squares as follows:
4338  //
4339  // T0 - 0,4,7,8
4340  // T1 - 1,4,5,8
4341  // T2 - 2,5,6,8
4342  // T3 - 3,6,7,8
4343 
4344  for (i = 0; i < 9; i++)
4345  {
4346  shape(i) = 0.0;
4347  }
4348 
4349  if ((x <= 0.5) && (y <= 0.5)) // T0
4350  {
4351  shape(0) = (Lx - 1.0) * (Ly - 1.0);
4352  shape(4) = (2.0 - Lx) * (Ly - 1.0);
4353  shape(8) = (2.0 - Lx) * (2.0 - Ly);
4354  shape(7) = (Lx - 1.0) * (2.0 - Ly);
4355  }
4356  else if ((x >= 0.5) && (y <= 0.5)) // T1
4357  {
4358  shape(4) = Lx * (Ly - 1.0);
4359  shape(1) = (1.0 - Lx) * (Ly - 1.0);
4360  shape(5) = (1.0 - Lx) * (2.0 - Ly);
4361  shape(8) = Lx * (2.0 - Ly);
4362  }
4363  else if ((x >= 0.5) && (y >= 0.5)) // T2
4364  {
4365  shape(8) = Lx * Ly ;
4366  shape(5) = (1.0 - Lx) * Ly ;
4367  shape(2) = (1.0 - Lx) * (1.0 - Ly);
4368  shape(6) = Lx * (1.0 - Ly);
4369  }
4370  else if ((x <= 0.5) && (y >= 0.5)) // T3
4371  {
4372  shape(7) = (Lx - 1.0) * Ly ;
4373  shape(8) = (2.0 - Lx) * Ly ;
4374  shape(6) = (2.0 - Lx) * (1.0 - Ly);
4375  shape(3) = (Lx - 1.0) * (1.0 - Ly);
4376  }
4377 }
4378 
4380  DenseMatrix &dshape) const
4381 {
4382  int i,j;
4383  double x = ip.x, y = ip.y;
4384  double Lx, Ly;
4385  Lx = 2.0 * ( 1. - x );
4386  Ly = 2.0 * ( 1. - y );
4387 
4388  for (i = 0; i < 9; i++)
4389  for (j = 0; j < 2; j++)
4390  {
4391  dshape(i,j) = 0.0;
4392  }
4393 
4394  if ((x <= 0.5) && (y <= 0.5)) // T0
4395  {
4396  dshape(0,0) = 2.0 * (1.0 - Ly);
4397  dshape(0,1) = 2.0 * (1.0 - Lx);
4398 
4399  dshape(4,0) = 2.0 * (Ly - 1.0);
4400  dshape(4,1) = -2.0 * (2.0 - Lx);
4401 
4402  dshape(8,0) = 2.0 * (2.0 - Ly);
4403  dshape(8,1) = 2.0 * (2.0 - Lx);
4404 
4405  dshape(7,0) = -2.0 * (2.0 - Ly);
4406  dshape(7,0) = 2.0 * (Lx - 1.0);
4407  }
4408  else if ((x >= 0.5) && (y <= 0.5)) // T1
4409  {
4410  dshape(4,0) = -2.0 * (Ly - 1.0);
4411  dshape(4,1) = -2.0 * Lx;
4412 
4413  dshape(1,0) = 2.0 * (Ly - 1.0);
4414  dshape(1,1) = -2.0 * (1.0 - Lx);
4415 
4416  dshape(5,0) = 2.0 * (2.0 - Ly);
4417  dshape(5,1) = 2.0 * (1.0 - Lx);
4418 
4419  dshape(8,0) = -2.0 * (2.0 - Ly);
4420  dshape(8,1) = 2.0 * Lx;
4421  }
4422  else if ((x >= 0.5) && (y >= 0.5)) // T2
4423  {
4424  dshape(8,0) = -2.0 * Ly;
4425  dshape(8,1) = -2.0 * Lx;
4426 
4427  dshape(5,0) = 2.0 * Ly;
4428  dshape(5,1) = -2.0 * (1.0 - Lx);
4429 
4430  dshape(2,0) = 2.0 * (1.0 - Ly);
4431  dshape(2,1) = 2.0 * (1.0 - Lx);
4432 
4433  dshape(6,0) = -2.0 * (1.0 - Ly);
4434  dshape(6,1) = 2.0 * Lx;
4435  }
4436  else if ((x <= 0.5) && (y >= 0.5)) // T3
4437  {
4438  dshape(7,0) = -2.0 * Ly;
4439  dshape(7,1) = -2.0 * (Lx - 1.0);
4440 
4441  dshape(8,0) = 2.0 * Ly ;
4442  dshape(8,1) = -2.0 * (2.0 - Lx);
4443 
4444  dshape(6,0) = 2.0 * (1.0 - Ly);
4445  dshape(6,1) = 2.0 * (2.0 - Lx);
4446 
4447  dshape(3,0) = -2.0 * (1.0 - Ly);
4448  dshape(3,1) = 2.0 * (Lx - 1.0);
4449  }
4450 }
4451 
4453  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
4454 {
4455  double I[27];
4456  double J[27];
4457  double K[27];
4458  // nodes
4459  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
4460  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
4461  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
4462  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
4463  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
4464  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
4465  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
4466  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
4467  // edges
4468  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
4469  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
4470  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
4471  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
4472  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
4473  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
4474  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
4475  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
4476  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
4477  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
4478  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
4479  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
4480  // faces
4481  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
4482  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
4483  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
4484  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
4485  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
4486  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
4487  // element
4488  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
4489 
4490  for (int n = 0; n < 27; n++)
4491  {
4492  Nodes.IntPoint(n).x = I[n];
4493  Nodes.IntPoint(n).y = J[n];
4494  Nodes.IntPoint(n).z = K[n];
4495  }
4496 }
4497 
4499  Vector &shape) const
4500 {
4501  int i, N[8];
4502  double Lx, Ly, Lz;
4503  double x = ip.x, y = ip.y, z = ip.z;
4504 
4505  for (i = 0; i < 27; i++)
4506  {
4507  shape(i) = 0.0;
4508  }
4509 
4510  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4511  {
4512  Lx = 1.0 - 2.0 * x;
4513  Ly = 1.0 - 2.0 * y;
4514  Lz = 1.0 - 2.0 * z;
4515 
4516  N[0] = 0;
4517  N[1] = 8;
4518  N[2] = 20;
4519  N[3] = 11;
4520  N[4] = 16;
4521  N[5] = 21;
4522  N[6] = 26;
4523  N[7] = 24;
4524  }
4525  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4526  {
4527  Lx = 2.0 - 2.0 * x;
4528  Ly = 1.0 - 2.0 * y;
4529  Lz = 1.0 - 2.0 * z;
4530 
4531  N[0] = 8;
4532  N[1] = 1;
4533  N[2] = 9;
4534  N[3] = 20;
4535  N[4] = 21;
4536  N[5] = 17;
4537  N[6] = 22;
4538  N[7] = 26;
4539  }
4540  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4541  {
4542  Lx = 2.0 - 2.0 * x;
4543  Ly = 2.0 - 2.0 * y;
4544  Lz = 1.0 - 2.0 * z;
4545 
4546  N[0] = 20;
4547  N[1] = 9;
4548  N[2] = 2;
4549  N[3] = 10;
4550  N[4] = 26;
4551  N[5] = 22;
4552  N[6] = 18;
4553  N[7] = 23;
4554  }
4555  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4556  {
4557  Lx = 1.0 - 2.0 * x;
4558  Ly = 2.0 - 2.0 * y;
4559  Lz = 1.0 - 2.0 * z;
4560 
4561  N[0] = 11;
4562  N[1] = 20;
4563  N[2] = 10;
4564  N[3] = 3;
4565  N[4] = 24;
4566  N[5] = 26;
4567  N[6] = 23;
4568  N[7] = 19;
4569  }
4570  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4571  {
4572  Lx = 1.0 - 2.0 * x;
4573  Ly = 1.0 - 2.0 * y;
4574  Lz = 2.0 - 2.0 * z;
4575 
4576  N[0] = 16;
4577  N[1] = 21;
4578  N[2] = 26;
4579  N[3] = 24;
4580  N[4] = 4;
4581  N[5] = 12;
4582  N[6] = 25;
4583  N[7] = 15;
4584  }
4585  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4586  {
4587  Lx = 2.0 - 2.0 * x;
4588  Ly = 1.0 - 2.0 * y;
4589  Lz = 2.0 - 2.0 * z;
4590 
4591  N[0] = 21;
4592  N[1] = 17;
4593  N[2] = 22;
4594  N[3] = 26;
4595  N[4] = 12;
4596  N[5] = 5;
4597  N[6] = 13;
4598  N[7] = 25;
4599  }
4600  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4601  {
4602  Lx = 2.0 - 2.0 * x;
4603  Ly = 2.0 - 2.0 * y;
4604  Lz = 2.0 - 2.0 * z;
4605 
4606  N[0] = 26;
4607  N[1] = 22;
4608  N[2] = 18;
4609  N[3] = 23;
4610  N[4] = 25;
4611  N[5] = 13;
4612  N[6] = 6;
4613  N[7] = 14;
4614  }
4615  else // T7
4616  {
4617  Lx = 1.0 - 2.0 * x;
4618  Ly = 2.0 - 2.0 * y;
4619  Lz = 2.0 - 2.0 * z;
4620 
4621  N[0] = 24;
4622  N[1] = 26;
4623  N[2] = 23;
4624  N[3] = 19;
4625  N[4] = 15;
4626  N[5] = 25;
4627  N[6] = 14;
4628  N[7] = 7;
4629  }
4630 
4631  shape(N[0]) = Lx * Ly * Lz;
4632  shape(N[1]) = (1 - Lx) * Ly * Lz;
4633  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
4634  shape(N[3]) = Lx * (1 - Ly) * Lz;
4635  shape(N[4]) = Lx * Ly * (1 - Lz);
4636  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
4637  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
4638  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
4639 }
4640 
4642  DenseMatrix &dshape) const
4643 {
4644  int i, j, N[8];
4645  double Lx, Ly, Lz;
4646  double x = ip.x, y = ip.y, z = ip.z;
4647 
4648  for (i = 0; i < 27; i++)
4649  for (j = 0; j < 3; j++)
4650  {
4651  dshape(i,j) = 0.0;
4652  }
4653 
4654  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4655  {
4656  Lx = 1.0 - 2.0 * x;
4657  Ly = 1.0 - 2.0 * y;
4658  Lz = 1.0 - 2.0 * z;
4659 
4660  N[0] = 0;
4661  N[1] = 8;
4662  N[2] = 20;
4663  N[3] = 11;
4664  N[4] = 16;
4665  N[5] = 21;
4666  N[6] = 26;
4667  N[7] = 24;
4668  }
4669  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4670  {
4671  Lx = 2.0 - 2.0 * x;
4672  Ly = 1.0 - 2.0 * y;
4673  Lz = 1.0 - 2.0 * z;
4674 
4675  N[0] = 8;
4676  N[1] = 1;
4677  N[2] = 9;
4678  N[3] = 20;
4679  N[4] = 21;
4680  N[5] = 17;
4681  N[6] = 22;
4682  N[7] = 26;
4683  }
4684  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4685  {
4686  Lx = 2.0 - 2.0 * x;
4687  Ly = 2.0 - 2.0 * y;
4688  Lz = 1.0 - 2.0 * z;
4689 
4690  N[0] = 20;
4691  N[1] = 9;
4692  N[2] = 2;
4693  N[3] = 10;
4694  N[4] = 26;
4695  N[5] = 22;
4696  N[6] = 18;
4697  N[7] = 23;
4698  }
4699  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4700  {
4701  Lx = 1.0 - 2.0 * x;
4702  Ly = 2.0 - 2.0 * y;
4703  Lz = 1.0 - 2.0 * z;
4704 
4705  N[0] = 11;
4706  N[1] = 20;
4707  N[2] = 10;
4708  N[3] = 3;
4709  N[4] = 24;
4710  N[5] = 26;
4711  N[6] = 23;
4712  N[7] = 19;
4713  }
4714  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4715  {
4716  Lx = 1.0 - 2.0 * x;
4717  Ly = 1.0 - 2.0 * y;
4718  Lz = 2.0 - 2.0 * z;
4719 
4720  N[0] = 16;
4721  N[1] = 21;
4722  N[2] = 26;
4723  N[3] = 24;
4724  N[4] = 4;
4725  N[5] = 12;
4726  N[6] = 25;
4727  N[7] = 15;
4728  }
4729  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4730  {
4731  Lx = 2.0 - 2.0 * x;
4732  Ly = 1.0 - 2.0 * y;
4733  Lz = 2.0 - 2.0 * z;
4734 
4735  N[0] = 21;
4736  N[1] = 17;
4737  N[2] = 22;
4738  N[3] = 26;
4739  N[4] = 12;
4740  N[5] = 5;
4741  N[6] = 13;
4742  N[7] = 25;
4743  }
4744  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4745  {
4746  Lx = 2.0 - 2.0 * x;
4747  Ly = 2.0 - 2.0 * y;
4748  Lz = 2.0 - 2.0 * z;
4749 
4750  N[0] = 26;
4751  N[1] = 22;
4752  N[2] = 18;
4753  N[3] = 23;
4754  N[4] = 25;
4755  N[5] = 13;
4756  N[6] = 6;
4757  N[7] = 14;
4758  }
4759  else // T7
4760  {
4761  Lx = 1.0 - 2.0 * x;
4762  Ly = 2.0 - 2.0 * y;
4763  Lz = 2.0 - 2.0 * z;
4764 
4765  N[0] = 24;
4766  N[1] = 26;
4767  N[2] = 23;
4768  N[3] = 19;
4769  N[4] = 15;
4770  N[5] = 25;
4771  N[6] = 14;
4772  N[7] = 7;
4773  }
4774 
4775  dshape(N[0],0) = -2.0 * Ly * Lz ;
4776  dshape(N[0],1) = -2.0 * Lx * Lz ;
4777  dshape(N[0],2) = -2.0 * Lx * Ly ;
4778 
4779  dshape(N[1],0) = 2.0 * Ly * Lz ;
4780  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
4781  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
4782 
4783  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
4784  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
4785  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
4786 
4787  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
4788  dshape(N[3],1) = 2.0 * Lx * Lz ;
4789  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
4790 
4791  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
4792  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
4793  dshape(N[4],2) = 2.0 * Lx * Ly ;
4794 
4795  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
4796  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
4797  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
4798 
4799  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
4800  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
4801  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
4802 
4803  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
4804  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
4805  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
4806 }
4807 
4808 
4810  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
4811 {
4812  // not real nodes ...
4813  Nodes.IntPoint(0).x = 0.5;
4814  Nodes.IntPoint(0).y = 0.0;
4815  Nodes.IntPoint(0).z = 0.0;
4816 
4817  Nodes.IntPoint(1).x = 1.0;
4818  Nodes.IntPoint(1).y = 0.5;
4819  Nodes.IntPoint(1).z = 0.0;
4820 
4821  Nodes.IntPoint(2).x = 0.5;
4822  Nodes.IntPoint(2).y = 1.0;
4823  Nodes.IntPoint(2).z = 0.0;
4824 
4825  Nodes.IntPoint(3).x = 0.0;
4826  Nodes.IntPoint(3).y = 0.5;
4827  Nodes.IntPoint(3).z = 0.0;
4828 
4829  Nodes.IntPoint(4).x = 0.5;
4830  Nodes.IntPoint(4).y = 0.0;
4831  Nodes.IntPoint(4).z = 1.0;
4832 
4833  Nodes.IntPoint(5).x = 1.0;
4834  Nodes.IntPoint(5).y = 0.5;
4835  Nodes.IntPoint(5).z = 1.0;
4836 
4837  Nodes.IntPoint(6).x = 0.5;
4838  Nodes.IntPoint(6).y = 1.0;
4839  Nodes.IntPoint(6).z = 1.0;
4840 
4841  Nodes.IntPoint(7).x = 0.0;
4842  Nodes.IntPoint(7).y = 0.5;
4843  Nodes.IntPoint(7).z = 1.0;
4844 
4845  Nodes.IntPoint(8).x = 0.0;
4846  Nodes.IntPoint(8).y = 0.0;
4847  Nodes.IntPoint(8).z = 0.5;
4848 
4849  Nodes.IntPoint(9).x = 1.0;
4850  Nodes.IntPoint(9).y = 0.0;
4851  Nodes.IntPoint(9).z = 0.5;
4852 
4853  Nodes.IntPoint(10).x= 1.0;
4854  Nodes.IntPoint(10).y= 1.0;
4855  Nodes.IntPoint(10).z= 0.5;
4856 
4857  Nodes.IntPoint(11).x= 0.0;
4858  Nodes.IntPoint(11).y= 1.0;
4859  Nodes.IntPoint(11).z= 0.5;
4860 }
4861 
4863  DenseMatrix &shape) const
4864 {
4865  double x = ip.x, y = ip.y, z = ip.z;
4866 
4867  shape(0,0) = (1. - y) * (1. - z);
4868  shape(0,1) = 0.;
4869  shape(0,2) = 0.;
4870 
4871  shape(2,0) = y * (1. - z);
4872  shape(2,1) = 0.;
4873  shape(2,2) = 0.;
4874 
4875  shape(4,0) = z * (1. - y);
4876  shape(4,1) = 0.;
4877  shape(4,2) = 0.;
4878 
4879  shape(6,0) = y * z;
4880  shape(6,1) = 0.;
4881  shape(6,2) = 0.;
4882 
4883  shape(1,0) = 0.;
4884  shape(1,1) = x * (1. - z);
4885  shape(1,2) = 0.;
4886 
4887  shape(3,0) = 0.;
4888  shape(3,1) = (1. - x) * (1. - z);
4889  shape(3,2) = 0.;
4890 
4891  shape(5,0) = 0.;
4892  shape(5,1) = x * z;
4893  shape(5,2) = 0.;
4894 
4895  shape(7,0) = 0.;
4896  shape(7,1) = (1. - x) * z;
4897  shape(7,2) = 0.;
4898 
4899  shape(8,0) = 0.;
4900  shape(8,1) = 0.;
4901  shape(8,2) = (1. - x) * (1. - y);
4902 
4903  shape(9,0) = 0.;
4904  shape(9,1) = 0.;
4905  shape(9,2) = x * (1. - y);
4906 
4907  shape(10,0) = 0.;
4908  shape(10,1) = 0.;
4909  shape(10,2) = x * y;
4910 
4911  shape(11,0) = 0.;
4912  shape(11,1) = 0.;
4913  shape(11,2) = y * (1. - x);
4914 
4915 }
4916 
4918  DenseMatrix &curl_shape)
4919 const
4920 {
4921  double x = ip.x, y = ip.y, z = ip.z;
4922 
4923  curl_shape(0,0) = 0.;
4924  curl_shape(0,1) = y - 1.;
4925  curl_shape(0,2) = 1. - z;
4926 
4927  curl_shape(2,0) = 0.;
4928  curl_shape(2,1) = -y;
4929  curl_shape(2,2) = z - 1.;
4930 
4931  curl_shape(4,0) = 0;
4932  curl_shape(4,1) = 1. - y;
4933  curl_shape(4,2) = z;
4934 
4935  curl_shape(6,0) = 0.;
4936  curl_shape(6,1) = y;
4937  curl_shape(6,2) = -z;
4938 
4939  curl_shape(1,0) = x;
4940  curl_shape(1,1) = 0.;
4941  curl_shape(1,2) = 1. - z;
4942 
4943  curl_shape(3,0) = 1. - x;
4944  curl_shape(3,1) = 0.;
4945  curl_shape(3,2) = z - 1.;
4946 
4947  curl_shape(5,0) = -x;
4948  curl_shape(5,1) = 0.;
4949  curl_shape(5,2) = z;
4950 
4951  curl_shape(7,0) = x - 1.;
4952  curl_shape(7,1) = 0.;
4953  curl_shape(7,2) = -z;
4954 
4955  curl_shape(8,0) = x - 1.;
4956  curl_shape(8,1) = 1. - y;
4957  curl_shape(8,2) = 0.;
4958 
4959  curl_shape(9,0) = -x;
4960  curl_shape(9,1) = y - 1.;
4961  curl_shape(9,2) = 0;
4962 
4963  curl_shape(10,0) = x;
4964  curl_shape(10,1) = -y;
4965  curl_shape(10,2) = 0.;
4966 
4967  curl_shape(11,0) = 1. - x;
4968  curl_shape(11,1) = y;
4969  curl_shape(11,2) = 0.;
4970 }
4971 
4972 const double Nedelec1HexFiniteElement::tk[12][3] =
4973 {
4974  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
4975  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
4976  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
4977 };
4978 
4981 {
4982  int k, j;
4983 #ifdef MFEM_THREAD_SAFE
4985 #endif
4986 
4987 #ifdef MFEM_DEBUG
4988  for (k = 0; k < 12; k++)
4989  {
4991  for (j = 0; j < 12; j++)
4992  {
4993  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
4994  vshape(j,2)*tk[k][2] );
4995  if (j == k) { d -= 1.0; }
4996  if (fabs(d) > 1.0e-12)
4997  {
4998  cerr << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
4999  " k = " << k << ", j = " << j << ", d = " << d << endl;
5000  mfem_error();
5001  }
5002  }
5003  }
5004 #endif
5005 
5006  IntegrationPoint ip;
5007  ip.x = ip.y = ip.z = 0.0;
5008  Trans.SetIntPoint (&ip);
5009  // Trans must be linear (more to have embedding?)
5010  const DenseMatrix &J = Trans.Jacobian();
5011  double vk[3];
5012  Vector xk (vk, 3);
5013 
5014  for (k = 0; k < 12; k++)
5015  {
5016  Trans.Transform (Nodes.IntPoint (k), xk);
5017  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5018  CalcVShape (ip, vshape);
5019  // vk = J tk
5020  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5021  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5022  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5023  for (j = 0; j < 12; j++)
5024  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5025  vshape(j,2)*vk[2])) < 1.0e-12)
5026  {
5027  I(k,j) = 0.0;
5028  }
5029  }
5030 }
5031 
5034  Vector &dofs) const
5035 {
5036  double vk[3];
5037  Vector xk (vk, 3);
5038 
5039  for (int k = 0; k < 12; k++)
5040  {
5041  Trans.SetIntPoint (&Nodes.IntPoint (k));
5042  const DenseMatrix &J = Trans.Jacobian();
5043 
5044  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5045  // xk^t J tk
5046  dofs(k) =
5047  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5048  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5049  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5050  }
5051 }
5052 
5053 
5055  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
5056 {
5057  // not real nodes ...
5058  Nodes.IntPoint(0).x = 0.5;
5059  Nodes.IntPoint(0).y = 0.0;
5060  Nodes.IntPoint(0).z = 0.0;
5061 
5062  Nodes.IntPoint(1).x = 0.0;
5063  Nodes.IntPoint(1).y = 0.5;
5064  Nodes.IntPoint(1).z = 0.0;
5065 
5066  Nodes.IntPoint(2).x = 0.0;
5067  Nodes.IntPoint(2).y = 0.0;
5068  Nodes.IntPoint(2).z = 0.5;
5069 
5070  Nodes.IntPoint(3).x = 0.5;
5071  Nodes.IntPoint(3).y = 0.5;
5072  Nodes.IntPoint(3).z = 0.0;
5073 
5074  Nodes.IntPoint(4).x = 0.5;
5075  Nodes.IntPoint(4).y = 0.0;
5076  Nodes.IntPoint(4).z = 0.5;
5077 
5078  Nodes.IntPoint(5).x = 0.0;
5079  Nodes.IntPoint(5).y = 0.5;
5080  Nodes.IntPoint(5).z = 0.5;
5081 }
5082 
5084  DenseMatrix &shape) const
5085 {
5086  double x = ip.x, y = ip.y, z = ip.z;
5087 
5088  shape(0,0) = 1. - y - z;
5089  shape(0,1) = x;
5090  shape(0,2) = x;
5091 
5092  shape(1,0) = y;
5093  shape(1,1) = 1. - x - z;
5094  shape(1,2) = y;
5095 
5096  shape(2,0) = z;
5097  shape(2,1) = z;
5098  shape(2,2) = 1. - x - y;
5099 
5100  shape(3,0) = -y;
5101  shape(3,1) = x;
5102  shape(3,2) = 0.;
5103 
5104  shape(4,0) = -z;
5105  shape(4,1) = 0.;
5106  shape(4,2) = x;
5107 
5108  shape(5,0) = 0.;
5109  shape(5,1) = -z;
5110  shape(5,2) = y;
5111 }
5112 
5114  DenseMatrix &curl_shape)
5115 const
5116 {
5117  curl_shape(0,0) = 0.;
5118  curl_shape(0,1) = -2.;
5119  curl_shape(0,2) = 2.;
5120 
5121  curl_shape(1,0) = 2.;
5122  curl_shape(1,1) = 0.;
5123  curl_shape(1,2) = -2.;
5124 
5125  curl_shape(2,0) = -2.;
5126  curl_shape(2,1) = 2.;
5127  curl_shape(2,2) = 0.;
5128 
5129  curl_shape(3,0) = 0.;
5130  curl_shape(3,1) = 0.;
5131  curl_shape(3,2) = 2.;
5132 
5133  curl_shape(4,0) = 0.;
5134  curl_shape(4,1) = -2.;
5135  curl_shape(4,2) = 0.;
5136 
5137  curl_shape(5,0) = 2.;
5138  curl_shape(5,1) = 0.;
5139  curl_shape(5,2) = 0.;
5140 }
5141 
5142 const double Nedelec1TetFiniteElement::tk[6][3] =
5143 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
5144 
5147 {
5148  int k, j;
5149 #ifdef MFEM_THREAD_SAFE
5151 #endif
5152 
5153 #ifdef MFEM_DEBUG
5154  for (k = 0; k < 6; k++)
5155  {
5157  for (j = 0; j < 6; j++)
5158  {
5159  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5160  vshape(j,2)*tk[k][2] );
5161  if (j == k) { d -= 1.0; }
5162  if (fabs(d) > 1.0e-12)
5163  {
5164  cerr << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
5165  " k = " << k << ", j = " << j << ", d = " << d << endl;
5166  mfem_error();
5167  }
5168  }
5169  }
5170 #endif
5171 
5172  IntegrationPoint ip;
5173  ip.x = ip.y = ip.z = 0.0;
5174  Trans.SetIntPoint (&ip);
5175  // Trans must be linear
5176  const DenseMatrix &J = Trans.Jacobian();
5177  double vk[3];
5178  Vector xk (vk, 3);
5179 
5180  for (k = 0; k < 6; k++)
5181  {
5182  Trans.Transform (Nodes.IntPoint (k), xk);
5183  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5184  CalcVShape (ip, vshape);
5185  // vk = J tk
5186  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5187  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5188  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5189  for (j = 0; j < 6; j++)
5190  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5191  vshape(j,2)*vk[2])) < 1.0e-12)
5192  {
5193  I(k,j) = 0.0;
5194  }
5195  }
5196 }
5197 
5200  Vector &dofs) const
5201 {
5202  double vk[3];
5203  Vector xk (vk, 3);
5204 
5205  for (int k = 0; k < 6; k++)
5206  {
5207  Trans.SetIntPoint (&Nodes.IntPoint (k));
5208  const DenseMatrix &J = Trans.Jacobian();
5209 
5210  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5211  // xk^t J tk
5212  dofs(k) =
5213  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5214  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5215  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5216  }
5217 }
5218 
5220  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
5221 {
5222  // not real nodes ...
5223  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
5224  Nodes.IntPoint(0).x = 0.5;
5225  Nodes.IntPoint(0).y = 0.5;
5226  Nodes.IntPoint(0).z = 0.0;
5227 
5228  Nodes.IntPoint(1).x = 0.5;
5229  Nodes.IntPoint(1).y = 0.0;
5230  Nodes.IntPoint(1).z = 0.5;
5231 
5232  Nodes.IntPoint(2).x = 1.0;
5233  Nodes.IntPoint(2).y = 0.5;
5234  Nodes.IntPoint(2).z = 0.5;
5235 
5236  Nodes.IntPoint(3).x = 0.5;
5237  Nodes.IntPoint(3).y = 1.0;
5238  Nodes.IntPoint(3).z = 0.5;
5239 
5240  Nodes.IntPoint(4).x = 0.0;
5241  Nodes.IntPoint(4).y = 0.5;
5242  Nodes.IntPoint(4).z = 0.5;
5243 
5244  Nodes.IntPoint(5).x = 0.5;
5245  Nodes.IntPoint(5).y = 0.5;
5246  Nodes.IntPoint(5).z = 1.0;
5247 }
5248 
5250  DenseMatrix &shape) const
5251 {
5252  double x = ip.x, y = ip.y, z = ip.z;
5253  // z = 0
5254  shape(0,0) = 0.;
5255  shape(0,1) = 0.;
5256  shape(0,2) = z - 1.;
5257  // y = 0
5258  shape(1,0) = 0.;
5259  shape(1,1) = y - 1.;
5260  shape(1,2) = 0.;
5261  // x = 1
5262  shape(2,0) = x;
5263  shape(2,1) = 0.;
5264  shape(2,2) = 0.;
5265  // y = 1
5266  shape(3,0) = 0.;
5267  shape(3,1) = y;
5268  shape(3,2) = 0.;
5269  // x = 0
5270  shape(4,0) = x - 1.;
5271  shape(4,1) = 0.;
5272  shape(4,2) = 0.;
5273  // z = 1
5274  shape(5,0) = 0.;
5275  shape(5,1) = 0.;
5276  shape(5,2) = z;
5277 }
5278 
5280  Vector &divshape) const
5281 {
5282  divshape(0) = 1.;
5283  divshape(1) = 1.;
5284  divshape(2) = 1.;
5285  divshape(3) = 1.;
5286  divshape(4) = 1.;
5287  divshape(5) = 1.;
5288 }
5289 
5290 const double RT0HexFiniteElement::nk[6][3] =
5291 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
5292 
5295 {
5296  int k, j;
5297 #ifdef MFEM_THREAD_SAFE
5299  DenseMatrix Jinv(Dim);
5300 #endif
5301 
5302 #ifdef MFEM_DEBUG
5303  for (k = 0; k < 6; k++)
5304  {
5306  for (j = 0; j < 6; j++)
5307  {
5308  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5309  vshape(j,2)*nk[k][2] );
5310  if (j == k) { d -= 1.0; }
5311  if (fabs(d) > 1.0e-12)
5312  {
5313  cerr << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5314  " k = " << k << ", j = " << j << ", d = " << d << endl;
5315  mfem_error();
5316  }
5317  }
5318  }
5319 #endif
5320 
5321  IntegrationPoint ip;
5322  ip.x = ip.y = ip.z = 0.0;
5323  Trans.SetIntPoint (&ip);
5324  // Trans must be linear
5325  // set Jinv = |J| J^{-t} = adj(J)^t
5326  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5327  double vk[3];
5328  Vector xk (vk, 3);
5329 
5330  for (k = 0; k < 6; k++)
5331  {
5332  Trans.Transform (Nodes.IntPoint (k), xk);
5333  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5334  CalcVShape (ip, vshape);
5335  // vk = |J| J^{-t} nk
5336  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5337  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5338  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5339  for (j = 0; j < 6; j++)
5340  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5341  vshape(j,2)*vk[2])) < 1.0e-12)
5342  {
5343  I(k,j) = 0.0;
5344  }
5345  }
5346 }
5347 
5350  Vector &dofs) const
5351 {
5352  double vk[3];
5353  Vector xk (vk, 3);
5354 #ifdef MFEM_THREAD_SAFE
5355  DenseMatrix Jinv(Dim);
5356 #endif
5357 
5358  for (int k = 0; k < 6; k++)
5359  {
5360  Trans.SetIntPoint (&Nodes.IntPoint (k));
5361  // set Jinv = |J| J^{-t} = adj(J)^t
5362  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5363 
5364  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5365  // xk^t |J| J^{-t} nk
5366  dofs(k) =
5367  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5368  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5369  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5370  }
5371 }
5372 
5374  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
5375 {
5376  // z = 0
5377  Nodes.IntPoint(2).x = 1./3.;
5378  Nodes.IntPoint(2).y = 1./3.;
5379  Nodes.IntPoint(2).z = 0.0;
5380  Nodes.IntPoint(3).x = 2./3.;
5381  Nodes.IntPoint(3).y = 1./3.;
5382  Nodes.IntPoint(3).z = 0.0;
5383  Nodes.IntPoint(0).x = 1./3.;
5384  Nodes.IntPoint(0).y = 2./3.;
5385  Nodes.IntPoint(0).z = 0.0;
5386  Nodes.IntPoint(1).x = 2./3.;
5387  Nodes.IntPoint(1).y = 2./3.;
5388  Nodes.IntPoint(1).z = 0.0;
5389  // y = 0
5390  Nodes.IntPoint(4).x = 1./3.;
5391  Nodes.IntPoint(4).y = 0.0;
5392  Nodes.IntPoint(4).z = 1./3.;
5393  Nodes.IntPoint(5).x = 2./3.;
5394  Nodes.IntPoint(5).y = 0.0;
5395  Nodes.IntPoint(5).z = 1./3.;
5396  Nodes.IntPoint(6).x = 1./3.;
5397  Nodes.IntPoint(6).y = 0.0;
5398  Nodes.IntPoint(6).z = 2./3.;
5399  Nodes.IntPoint(7).x = 2./3.;
5400  Nodes.IntPoint(7).y = 0.0;
5401  Nodes.IntPoint(7).z = 2./3.;
5402  // x = 1
5403  Nodes.IntPoint(8).x = 1.0;
5404  Nodes.IntPoint(8).y = 1./3.;
5405  Nodes.IntPoint(8).z = 1./3.;
5406  Nodes.IntPoint(9).x = 1.0;
5407  Nodes.IntPoint(9).y = 2./3.;
5408  Nodes.IntPoint(9).z = 1./3.;
5409  Nodes.IntPoint(10).x = 1.0;
5410  Nodes.IntPoint(10).y = 1./3.;
5411  Nodes.IntPoint(10).z = 2./3.;
5412  Nodes.IntPoint(11).x = 1.0;
5413  Nodes.IntPoint(11).y = 2./3.;
5414  Nodes.IntPoint(11).z = 2./3.;
5415  // y = 1
5416  Nodes.IntPoint(13).x = 1./3.;
5417  Nodes.IntPoint(13).y = 1.0;
5418  Nodes.IntPoint(13).z = 1./3.;
5419  Nodes.IntPoint(12).x = 2./3.;
5420  Nodes.IntPoint(12).y = 1.0;
5421  Nodes.IntPoint(12).z = 1./3.;
5422  Nodes.IntPoint(15).x = 1./3.;
5423  Nodes.IntPoint(15).y = 1.0;
5424  Nodes.IntPoint(15).z = 2./3.;
5425  Nodes.IntPoint(14).x = 2./3.;
5426  Nodes.IntPoint(14).y = 1.0;
5427  Nodes.IntPoint(14).z = 2./3.;
5428  // x = 0
5429  Nodes.IntPoint(17).x = 0.0;
5430  Nodes.IntPoint(17).y = 1./3.;
5431  Nodes.IntPoint(17).z = 1./3.;
5432  Nodes.IntPoint(16).x = 0.0;
5433  Nodes.IntPoint(16).y = 2./3.;
5434  Nodes.IntPoint(16).z = 1./3.;
5435  Nodes.IntPoint(19).x = 0.0;
5436  Nodes.IntPoint(19).y = 1./3.;
5437  Nodes.IntPoint(19).z = 2./3.;
5438  Nodes.IntPoint(18).x = 0.0;
5439  Nodes.IntPoint(18).y = 2./3.;
5440  Nodes.IntPoint(18).z = 2./3.;
5441  // z = 1
5442  Nodes.IntPoint(20).x = 1./3.;
5443  Nodes.IntPoint(20).y = 1./3.;
5444  Nodes.IntPoint(20).z = 1.0;
5445  Nodes.IntPoint(21).x = 2./3.;
5446  Nodes.IntPoint(21).y = 1./3.;
5447  Nodes.IntPoint(21).z = 1.0;
5448  Nodes.IntPoint(22).x = 1./3.;
5449  Nodes.IntPoint(22).y = 2./3.;
5450  Nodes.IntPoint(22).z = 1.0;
5451  Nodes.IntPoint(23).x = 2./3.;
5452  Nodes.IntPoint(23).y = 2./3.;
5453  Nodes.IntPoint(23).z = 1.0;
5454  // x = 0.5 (interior)
5455  Nodes.IntPoint(24).x = 0.5;
5456  Nodes.IntPoint(24).y = 1./3.;
5457  Nodes.IntPoint(24).z = 1./3.;
5458  Nodes.IntPoint(25).x = 0.5;
5459  Nodes.IntPoint(25).y = 1./3.;
5460  Nodes.IntPoint(25).z = 2./3.;
5461  Nodes.IntPoint(26).x = 0.5;
5462  Nodes.IntPoint(26).y = 2./3.;
5463  Nodes.IntPoint(26).z = 1./3.;
5464  Nodes.IntPoint(27).x = 0.5;
5465  Nodes.IntPoint(27).y = 2./3.;
5466  Nodes.IntPoint(27).z = 2./3.;
5467  // y = 0.5 (interior)
5468  Nodes.IntPoint(28).x = 1./3.;
5469  Nodes.IntPoint(28).y = 0.5;
5470  Nodes.IntPoint(28).z = 1./3.;
5471  Nodes.IntPoint(29).x = 1./3.;
5472  Nodes.IntPoint(29).y = 0.5;
5473  Nodes.IntPoint(29).z = 2./3.;
5474  Nodes.IntPoint(30).x = 2./3.;
5475  Nodes.IntPoint(30).y = 0.5;
5476  Nodes.IntPoint(30).z = 1./3.;
5477  Nodes.IntPoint(31).x = 2./3.;
5478  Nodes.IntPoint(31).y = 0.5;
5479  Nodes.IntPoint(31).z = 2./3.;
5480  // z = 0.5 (interior)
5481  Nodes.IntPoint(32).x = 1./3.;
5482  Nodes.IntPoint(32).y = 1./3.;
5483  Nodes.IntPoint(32).z = 0.5;
5484  Nodes.IntPoint(33).x = 1./3.;
5485  Nodes.IntPoint(33).y = 2./3.;
5486  Nodes.IntPoint(33).z = 0.5;
5487  Nodes.IntPoint(34).x = 2./3.;
5488  Nodes.IntPoint(34).y = 1./3.;
5489  Nodes.IntPoint(34).z = 0.5;
5490  Nodes.IntPoint(35).x = 2./3.;
5491  Nodes.IntPoint(35).y = 2./3.;
5492  Nodes.IntPoint(35).z = 0.5;
5493 }
5494 
5496  DenseMatrix &shape) const
5497 {
5498  double x = ip.x, y = ip.y, z = ip.z;
5499  // z = 0
5500  shape(2,0) = 0.;
5501  shape(2,1) = 0.;
5502  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5503  shape(3,0) = 0.;
5504  shape(3,1) = 0.;
5505  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5506  shape(0,0) = 0.;
5507  shape(0,1) = 0.;
5508  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5509  shape(1,0) = 0.;
5510  shape(1,1) = 0.;
5511  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5512  // y = 0
5513  shape(4,0) = 0.;
5514  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5515  shape(4,2) = 0.;
5516  shape(5,0) = 0.;
5517  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5518  shape(5,2) = 0.;
5519  shape(6,0) = 0.;
5520  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5521  shape(6,2) = 0.;
5522  shape(7,0) = 0.;
5523  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5524  shape(7,2) = 0.;
5525  // x = 1
5526  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5527  shape(8,1) = 0.;
5528  shape(8,2) = 0.;
5529  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5530  shape(9,1) = 0.;
5531  shape(9,2) = 0.;
5532  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5533  shape(10,1) = 0.;
5534  shape(10,2) = 0.;
5535  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5536  shape(11,1) = 0.;
5537  shape(11,2) = 0.;
5538  // y = 1
5539  shape(13,0) = 0.;
5540  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5541  shape(13,2) = 0.;
5542  shape(12,0) = 0.;
5543  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5544  shape(12,2) = 0.;
5545  shape(15,0) = 0.;
5546  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5547  shape(15,2) = 0.;
5548  shape(14,0) = 0.;
5549  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5550  shape(14,2) = 0.;
5551  // x = 0
5552  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5553  shape(17,1) = 0.;
5554  shape(17,2) = 0.;
5555  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5556  shape(16,1) = 0.;
5557  shape(16,2) = 0.;
5558  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5559  shape(19,1) = 0.;
5560  shape(19,2) = 0.;
5561  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5562  shape(18,1) = 0.;
5563  shape(18,2) = 0.;
5564  // z = 1
5565  shape(20,0) = 0.;
5566  shape(20,1) = 0.;
5567  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5568  shape(21,0) = 0.;
5569  shape(21,1) = 0.;
5570  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5571  shape(22,0) = 0.;
5572  shape(22,1) = 0.;
5573  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5574  shape(23,0) = 0.;
5575  shape(23,1) = 0.;
5576  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5577  // x = 0.5 (interior)
5578  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5579  shape(24,1) = 0.;
5580  shape(24,2) = 0.;
5581  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5582  shape(25,1) = 0.;
5583  shape(25,2) = 0.;
5584  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5585  shape(26,1) = 0.;
5586  shape(26,2) = 0.;
5587  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5588  shape(27,1) = 0.;
5589  shape(27,2) = 0.;
5590  // y = 0.5 (interior)
5591  shape(28,0) = 0.;
5592  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5593  shape(28,2) = 0.;
5594  shape(29,0) = 0.;
5595  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5596  shape(29,2) = 0.;
5597  shape(30,0) = 0.;
5598  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5599  shape(30,2) = 0.;
5600  shape(31,0) = 0.;
5601  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5602  shape(31,2) = 0.;
5603  // z = 0.5 (interior)
5604  shape(32,0) = 0.;
5605  shape(32,1) = 0.;
5606  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5607  shape(33,0) = 0.;
5608  shape(33,1) = 0.;
5609  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5610  shape(34,0) = 0.;
5611  shape(34,1) = 0.;
5612  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5613  shape(35,0) = 0.;
5614  shape(35,1) = 0.;
5615  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5616 }
5617 
5619  Vector &divshape) const
5620 {
5621  double x = ip.x, y = ip.y, z = ip.z;
5622  // z = 0
5623  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5624  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5625  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5626  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5627  // y = 0
5628  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5629  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5630  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5631  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5632  // x = 1
5633  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5634  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5635  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5636  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5637  // y = 1
5638  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5639  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5640  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5641  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5642  // x = 0
5643  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5644  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5645  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5646  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5647  // z = 1
5648  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5649  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5650  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5651  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5652  // x = 0.5 (interior)
5653  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5654  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5655  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5656  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5657  // y = 0.5 (interior)
5658  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5659  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5660  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5661  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5662  // z = 0.5 (interior)
5663  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5664  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5665  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5666  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5667 }
5668 
5669 const double RT1HexFiniteElement::nk[36][3] =
5670 {
5671  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
5672  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
5673  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5674  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5675  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
5676  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
5677  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5678  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5679  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
5680 };
5681 
5684 {
5685  int k, j;
5686 #ifdef MFEM_THREAD_SAFE
5688  DenseMatrix Jinv(Dim);
5689 #endif
5690 
5691 #ifdef MFEM_DEBUG
5692  for (k = 0; k < 36; k++)
5693  {
5695  for (j = 0; j < 36; j++)
5696  {
5697  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5698  vshape(j,2)*nk[k][2] );
5699  if (j == k) { d -= 1.0; }
5700  if (fabs(d) > 1.0e-12)
5701  {
5702  cerr << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5703  " k = " << k << ", j = " << j << ", d = " << d << endl;
5704  mfem_error();
5705  }
5706  }
5707  }
5708 #endif
5709 
5710  IntegrationPoint ip;
5711  ip.x = ip.y = ip.z = 0.0;
5712  Trans.SetIntPoint (&ip);
5713  // Trans must be linear
5714  // set Jinv = |J| J^{-t} = adj(J)^t
5715  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5716  double vk[3];
5717  Vector xk (vk, 3);
5718 
5719  for (k = 0; k < 36; k++)
5720  {
5721  Trans.Transform (Nodes.IntPoint (k), xk);
5722  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5723  CalcVShape (ip, vshape);
5724  // vk = |J| J^{-t} nk
5725  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5726  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5727  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5728  for (j = 0; j < 36; j++)
5729  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5730  vshape(j,2)*vk[2])) < 1.0e-12)
5731  {
5732  I(k,j) = 0.0;
5733  }
5734  }
5735 }
5736 
5739  Vector &dofs) const
5740 {
5741  double vk[3];
5742  Vector xk (vk, 3);
5743 #ifdef MFEM_THREAD_SAFE
5744  DenseMatrix Jinv(Dim);
5745 #endif
5746 
5747  for (int k = 0; k < 36; k++)
5748  {
5749  Trans.SetIntPoint (&Nodes.IntPoint (k));
5750  // set Jinv = |J| J^{-t} = adj(J)^t
5751  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5752 
5753  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5754  // xk^t |J| J^{-t} nk
5755  dofs(k) =
5756  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5757  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5758  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5759  }
5760 }
5761 
5763  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
5764 {
5765  // not real nodes ...
5766  Nodes.IntPoint(0).x = 0.33333333333333333333;
5767  Nodes.IntPoint(0).y = 0.33333333333333333333;
5768  Nodes.IntPoint(0).z = 0.33333333333333333333;
5769 
5770  Nodes.IntPoint(1).x = 0.0;
5771  Nodes.IntPoint(1).y = 0.33333333333333333333;
5772  Nodes.IntPoint(1).z = 0.33333333333333333333;
5773 
5774  Nodes.IntPoint(2).x = 0.33333333333333333333;
5775  Nodes.IntPoint(2).y = 0.0;
5776  Nodes.IntPoint(2).z = 0.33333333333333333333;
5777 
5778  Nodes.IntPoint(3).x = 0.33333333333333333333;
5779  Nodes.IntPoint(3).y = 0.33333333333333333333;
5780  Nodes.IntPoint(3).z = 0.0;
5781 }
5782 
5784  DenseMatrix &shape) const
5785 {
5786  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
5787 
5788  shape(0,0) = x2;
5789  shape(0,1) = y2;
5790  shape(0,2) = z2;
5791 
5792  shape(1,0) = x2 - 2.0;
5793  shape(1,1) = y2;
5794  shape(1,2) = z2;
5795 
5796  shape(2,0) = x2;
5797  shape(2,1) = y2 - 2.0;
5798  shape(2,2) = z2;
5799 
5800  shape(3,0) = x2;
5801  shape(3,1) = y2;
5802  shape(3,2) = z2 - 2.0;
5803 }
5804 
5806  Vector &divshape) const
5807 {
5808  divshape(0) = 6.0;
5809  divshape(1) = 6.0;
5810  divshape(2) = 6.0;
5811  divshape(3) = 6.0;
5812 }
5813 
5814 const double RT0TetFiniteElement::nk[4][3] =
5815 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
5816 
5819 {
5820  int k, j;
5821 #ifdef MFEM_THREAD_SAFE
5823  DenseMatrix Jinv(Dim);
5824 #endif
5825 
5826 #ifdef MFEM_DEBUG
5827  for (k = 0; k < 4; k++)
5828  {
5830  for (j = 0; j < 4; j++)
5831  {
5832  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5833  vshape(j,2)*nk[k][2] );
5834  if (j == k) { d -= 1.0; }
5835  if (fabs(d) > 1.0e-12)
5836  {
5837  cerr << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
5838  " k = " << k << ", j = " << j << ", d = " << d << endl;
5839  mfem_error();
5840  }
5841  }
5842  }
5843 #endif
5844 
5845  IntegrationPoint ip;
5846  ip.x = ip.y = ip.z = 0.0;
5847  Trans.SetIntPoint (&ip);
5848  // Trans must be linear
5849  // set Jinv = |J| J^{-t} = adj(J)^t
5850  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5851  double vk[3];
5852  Vector xk (vk, 3);
5853 
5854  for (k = 0; k < 4; k++)
5855  {
5856  Trans.Transform (Nodes.IntPoint (k), xk);
5857  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5858  CalcVShape (ip, vshape);
5859  // vk = |J| J^{-t} nk
5860  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5861  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5862  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5863  for (j = 0; j < 4; j++)
5864  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5865  vshape(j,2)*vk[2])) < 1.0e-12)
5866  {
5867  I(k,j) = 0.0;
5868  }
5869  }
5870 }
5871 
5874  Vector &dofs) const
5875 {
5876  double vk[3];
5877  Vector xk (vk, 3);
5878 #ifdef MFEM_THREAD_SAFE
5879  DenseMatrix Jinv(Dim);
5880 #endif
5881 
5882  for (int k = 0; k < 4; k++)
5883  {
5884  Trans.SetIntPoint (&Nodes.IntPoint (k));
5885  // set Jinv = |J| J^{-t} = adj(J)^t
5886  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5887 
5888  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5889  // xk^t |J| J^{-t} nk
5890  dofs(k) =
5891  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5892  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5893  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5894  }
5895 }
5896 
5898  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
5899 {
5900  Nodes.IntPoint(0).x = 0.5;
5901  Nodes.IntPoint(0).y = 0.5;
5902  Nodes.IntPoint(0).z = 0.0;
5903 
5904  Nodes.IntPoint(1).x = 0.5;
5905  Nodes.IntPoint(1).y = 0.0;
5906  Nodes.IntPoint(1).z = 0.5;
5907 
5908  Nodes.IntPoint(2).x = 1.0;
5909  Nodes.IntPoint(2).y = 0.5;
5910  Nodes.IntPoint(2).z = 0.5;
5911 
5912  Nodes.IntPoint(3).x = 0.5;
5913  Nodes.IntPoint(3).y = 1.0;
5914  Nodes.IntPoint(3).z = 0.5;
5915 
5916  Nodes.IntPoint(4).x = 0.0;
5917  Nodes.IntPoint(4).y = 0.5;
5918  Nodes.IntPoint(4).z = 0.5;
5919 
5920  Nodes.IntPoint(5).x = 0.5;
5921  Nodes.IntPoint(5).y = 0.5;
5922  Nodes.IntPoint(5).z = 1.0;
5923 }
5924 
5926  Vector &shape) const
5927 {
5928  double x = 2. * ip.x - 1.;
5929  double y = 2. * ip.y - 1.;
5930  double z = 2. * ip.z - 1.;
5931  double f5 = x * x - y * y;
5932  double f6 = y * y - z * z;
5933 
5934  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
5935  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
5936  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
5937  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
5938  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
5939  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
5940 }
5941 
5943  DenseMatrix &dshape) const
5944 {
5945  const double a = 2./3.;
5946 
5947  double xt = a * (1. - 2. * ip.x);
5948  double yt = a * (1. - 2. * ip.y);
5949  double zt = a * (1. - 2. * ip.z);
5950 
5951  dshape(0,0) = xt;
5952  dshape(0,1) = yt;
5953  dshape(0,2) = -1. - 2. * zt;
5954 
5955  dshape(1,0) = xt;
5956  dshape(1,1) = -1. - 2. * yt;
5957  dshape(1,2) = zt;
5958 
5959  dshape(2,0) = 1. - 2. * xt;
5960  dshape(2,1) = yt;
5961  dshape(2,2) = zt;
5962 
5963  dshape(3,0) = xt;
5964  dshape(3,1) = 1. - 2. * yt;
5965  dshape(3,2) = zt;
5966 
5967  dshape(4,0) = -1. - 2. * xt;
5968  dshape(4,1) = yt;
5969  dshape(4,2) = zt;
5970 
5971  dshape(5,0) = xt;
5972  dshape(5,1) = yt;
5973  dshape(5,2) = 1. - 2. * zt;
5974 }
5975 
5976 
5977 Poly_1D::Basis::Basis(const int p, const double *nodes, int _mode)
5978  : x(p + 1), w(p + 1)
5979 {
5980  mode = _mode;
5981  if (mode == 0)
5982  {
5983  DenseMatrix A(p + 1);
5984  for (int i = 0; i <= p; i++)
5985  {
5986  CalcBasis(p, nodes[i], x);
5987  for (int j = 0; j <= p; j++)
5988  {
5989  A(j, i) = x(j);
5990  }
5991  }
5992 
5993  Ai.Factor(A);
5994  // cout << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
5995  }
5996  else
5997  {
5998  x = nodes;
5999  w = 1.0;
6000  for (int i = 0; i <= p; i++)
6001  for (int j = 0; j < i; j++)
6002  {
6003  double xij = x(i) - x(j);
6004  w(i) *= xij;
6005  w(j) *= -xij;
6006  }
6007  for (int i = 0; i <= p; i++)
6008  {
6009  w(i) = 1.0/w(i);
6010  }
6011 
6012 #ifdef MFEM_DEBUG
6013  // Make sure the nodes are increasing
6014  for (int i = 0; i < p; i++)
6015  if (x(i) >= x(i+1))
6016  {
6017  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
6018  }
6019 #endif
6020  }
6021 }
6022 
6023 void Poly_1D::Basis::Eval(const double y, Vector &u) const
6024 {
6025  if (mode == 0)
6026  {
6027  CalcBasis(Ai.Width() - 1, y, x);
6028  Ai.Mult(x, u);
6029  }
6030  else
6031  {
6032  int i, k, p = x.Size() - 1;
6033  double l, lk;
6034 
6035  if (p == 0)
6036  {
6037  u(0) = 1.0;
6038  return;
6039  }
6040 
6041  lk = 1.0;
6042  for (k = 0; k < p; k++)
6043  if (y >= (x(k) + x(k+1))/2)
6044  {
6045  lk *= y - x(k);
6046  }
6047  else
6048  {
6049  for (i = k+1; i <= p; i++)
6050  {
6051  lk *= y - x(i);
6052  }
6053  break;
6054  }
6055  l = lk * (y - x(k));
6056 
6057  for (i = 0; i < k; i++)
6058  {
6059  u(i) = l * w(i) / (y - x(i));
6060  }
6061  u(k) = lk * w(k);
6062  for (i++; i <= p; i++)
6063  {
6064  u(i) = l * w(i) / (y - x(i));
6065  }
6066  }
6067 }
6068 
6069 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
6070 {
6071  if (mode == 0)
6072  {
6073  CalcBasis(Ai.Width() - 1, y, x, w);
6074  Ai.Mult(x, u);
6075  Ai.Mult(w, d);
6076  }
6077  else
6078  {
6079  int i, k, p = x.Size() - 1;
6080  double l, lp, lk, sk, si;
6081 
6082  if (p == 0)
6083  {
6084  u(0) = 1.0;
6085  d(0) = 0.0;
6086  return;
6087  }
6088 
6089  lk = 1.0;
6090  for (k = 0; k < p; k++)
6091  if (y >= (x(k) + x(k+1))/2)
6092  {
6093  lk *= y - x(k);
6094  }
6095  else
6096  {
6097  for (i = k+1; i <= p; i++)
6098  {
6099  lk *= y - x(i);
6100  }
6101  break;
6102  }
6103  l = lk * (y - x(k));
6104 
6105  sk = 0.0;
6106  for (i = 0; i < k; i++)
6107  {
6108  si = 1.0/(y - x(i));
6109  sk += si;
6110  u(i) = l * si * w(i);
6111  }
6112  u(k) = lk * w(k);
6113  for (i++; i <= p; i++)
6114  {
6115  si = 1.0/(y - x(i));
6116  sk += si;
6117  u(i) = l * si * w(i);
6118  }
6119  lp = l * sk + lk;
6120 
6121  for (i = 0; i < k; i++)
6122  {
6123  d(i) = (lp * w(i) - u(i))/(y - x(i));
6124  }
6125  d(k) = sk * u(k);
6126  for (i++; i <= p; i++)
6127  {
6128  d(i) = (lp * w(i) - u(i))/(y - x(i));
6129  }
6130  }
6131 }
6132 
6133 const int *Poly_1D::Binom(const int p)
6134 {
6135  if (binom.NumCols() <= p)
6136  {
6137  binom.SetSize(p + 1, p + 1);
6138  for (int i = 0; i <= p; i++)
6139  {
6140  binom(i,0) = binom(i,i) = 1;
6141  for (int j = 1; j < i; j++)
6142  {
6143  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
6144  }
6145  }
6146  }
6147  return binom[p];
6148 }
6149 
6150 void Poly_1D::UniformPoints(const int p, double *x)
6151 {
6152  if (p == 0)
6153  {
6154  x[0] = 0.5;
6155  }
6156  else
6157  {
6158  for (int i = 0; i <= p; i++)
6159  {
6160  x[i] = double(i)/p;
6161  }
6162  }
6163 }
6164 
6165 void Poly_1D::GaussPoints(const int p, double *x)
6166 {
6167  int m = (p+1)/2, odd_p = p%2;
6168 
6169  if (!odd_p)
6170  {
6171  x[m] = 0.5;
6172  }
6173 
6174  for (int i = 0; i < m; i++)
6175  {
6176  double z, y, p0, d0;
6177  z = cos(M_PI*(i + 0.75)/(p + 1.5));
6178 
6179  for (int k = 0; true; )
6180  {
6181  // compute p0, d0 -- P_{p+1}(z), P'_{p+1}(z) using
6182  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6183  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
6184  {
6185  double p1, p2;
6186  p2 = 1.;
6187  p1 = z;
6188  d0 = 1 - odd_p;
6189  for (int n = 1; true; n++)
6190  {
6191  p0 = ((2*n+1)*z*p1 - n*p2)/(n + 1);
6192  if (n%2 == odd_p)
6193  {
6194  d0 += (2*n+1)*p1;
6195  }
6196  if (n == p) { break; }
6197  p2 = p1;
6198  p1 = p0;
6199  }
6200  // d0 = (p + 1)*(z*p0 - p1)/(z*z - 1); // alternative formula
6201  }
6202 
6203  if (fabs(p0/d0) < 2e-16) { break; }
6204 
6205  if (++k == 5)
6206  {
6207  std::cout << "Poly_1D::GaussPoints : No convergence!"
6208  " p = " << p << ", i = " << i << ", p0/d0 = " << p0/d0
6209  << std::endl;
6210  break;
6211  }
6212 
6213  z = z - p0/d0;
6214  }
6215 
6216  // z = z - p0/d0; y = (1 - z)/2; // bad roundoff !!!
6217  y = ((1 - z) + p0/d0)/2;
6218 
6219  x[i] = y;
6220  x[p-i] = 1 - y;
6221  // the weight is: 1./(4*y*(1 - y)*d0*d0)
6222  }
6223 }
6224 
6225 void Poly_1D::GaussLobattoPoints(const int p, double *x)
6226 {
6227  if (p == 0)
6228  {
6229  x[0] = 0.5;
6230  }
6231  else
6232  {
6233  x[0] = 0.;
6234  x[p] = 1.;
6235  if (p == 1) { return; }
6236 
6237  // x[1],...,x[p-1] are the (shifted) roots of P'_p
6238  int m = (p - 1)/2, odd_p = p%2;
6239 
6240  if (!odd_p)
6241  {
6242  x[m+1] = 0.5;
6243  }
6244  for (int i = 0; i < m; )
6245  {
6246  double y, z, d0, s0;
6247  z = cos(M_PI*(i + 1)/p);
6248 
6249  for (int k = 0; true; )
6250  {
6251  // compute d0, s0 -- P'_p(z), P"_p(z)
6252  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6253  // P'_{n+1}(z) = (2*n+1)* P_n(z)+P'_{n-1}(z)
6254  // P"_{n+1}(z) = (2*n+1)*P'_n(z)+P"_{n-1}(z)
6255  {
6256  double p0, p1, p2, d1;
6257  p2 = 1.;
6258  p1 = z;
6259  d0 = odd_p;
6260  d1 = 1 - odd_p;
6261  s0 = 0;
6262  for (int n = 1; true; n++)
6263  {
6264  p0 = ((2*n+1)*z*p1 - n*p2)/(n + 1);
6265  if (n%2 != odd_p)
6266  {
6267  d0 += (2*n+1)*p1;
6268  s0 += (2*n+1)*d1;
6269  }
6270  else
6271  {
6272  d1 += (2*n+1)*p1;
6273  }
6274  if (n == p - 1) { break; }
6275  p2 = p1;
6276  p1 = p0;
6277  }
6278  }
6279 
6280  if (fabs(d0/s0) < 2e-16) { break; }
6281 
6282  if (++k == 6)
6283  {
6284  std::cout << "Poly_1D::GaussLobattoPoints : No convergence!"
6285  " p = " << p << ", i = " << i << ", d0/s0 = " << d0/s0
6286  << std::endl;
6287  break;
6288  }
6289 
6290  z = z - d0/s0;
6291  }
6292 
6293  y = ((1 - z) + d0/s0)/2;
6294 
6295  x[++i] = y;
6296  x[p-i] = 1 - y;
6297  }
6298  }
6299 }
6300 
6301 void Poly_1D::ChebyshevPoints(const int p, double *x)
6302 {
6303  for (int i = 0; i <= p; i++)
6304  {
6305  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
6306  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
6307  x[i] = s*s;
6308  }
6309 }
6310 
6311 void Poly_1D::CalcMono(const int p, const double x, double *u)
6312 {
6313  double xn;
6314  u[0] = xn = 1.;
6315  for (int n = 1; n <= p; n++)
6316  {
6317  u[n] = (xn *= x);
6318  }
6319 }
6320 
6321 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
6322 {
6323  double xn;
6324  u[0] = xn = 1.;
6325  d[0] = 0.;
6326  for (int n = 1; n <= p; n++)
6327  {
6328  d[n] = n * xn;
6329  u[n] = (xn *= x);
6330  }
6331 }
6332 
6333 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6334  double *u)
6335 {
6336  if (p == 0)
6337  {
6338  u[0] = 1.;
6339  }
6340  else
6341  {
6342  int i;
6343  const int *b = Binom(p);
6344  double z = x;
6345 
6346  for (i = 1; i < p; i++)
6347  {
6348  u[i] = b[i]*z;
6349  z *= x;
6350  }
6351  u[p] = z;
6352  z = y;
6353  for (i--; i > 0; i--)
6354  {
6355  u[i] *= z;
6356  z *= y;
6357  }
6358  u[0] = z;
6359  }
6360 }
6361 
6362 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6363  double *u, double *d)
6364 {
6365  if (p == 0)
6366  {
6367  u[0] = 1.;
6368  d[0] = 0.;
6369  }
6370  else
6371  {
6372  int i;
6373  const int *b = Binom(p);
6374  const double xpy = x + y, ptx = p*x;
6375  double z = 1.;
6376 
6377  for (i = 1; i < p; i++)
6378  {
6379  d[i] = b[i]*z*(i*xpy - ptx);
6380  z *= x;
6381  u[i] = b[i]*z;
6382  }
6383  d[p] = p*z;
6384  u[p] = z*x;
6385  z = 1.;
6386  for (i--; i > 0; i--)
6387  {
6388  d[i] *= z;
6389  z *= y;
6390  u[i] *= z;
6391  }
6392  d[0] = -p*z;
6393  u[0] = z*y;
6394  }
6395 }
6396 
6397 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
6398  double *d)
6399 {
6400  if (p == 0)
6401  {
6402  d[0] = 0.;
6403  }
6404  else
6405  {
6406  int i;
6407  const int *b = Binom(p);
6408  const double xpy = x + y, ptx = p*x;
6409  double z = 1.;
6410 
6411  for (i = 1; i < p; i++)
6412  {
6413  d[i] = b[i]*z*(i*xpy - ptx);
6414  z *= x;
6415  }
6416  d[p] = p*z;
6417  z = 1.;
6418  for (i--; i > 0; i--)
6419  {
6420  d[i] *= z;
6421  z *= y;
6422  }
6423  d[0] = -p*z;
6424  }
6425 }
6426 
6427 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
6428 {
6429  // use the recursive definition for [-1,1]:
6430  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6431  double z;
6432  u[0] = 1.;
6433  if (p == 0) { return; }
6434  u[1] = z = 2.*x - 1.;
6435  for (int n = 1; n < p; n++)
6436  {
6437  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6438  }
6439 }
6440 
6441 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
6442 {
6443  // use the recursive definition for [-1,1]:
6444  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6445  // for the derivative use, z in [-1,1]:
6446  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
6447  double z;
6448  u[0] = 1.;
6449  d[0] = 0.;
6450  if (p == 0) { return; }
6451  u[1] = z = 2.*x - 1.;
6452  d[1] = 2.;
6453  for (int n = 1; n < p; n++)
6454  {
6455  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6456  d[n+1] = (4*n + 2)*u[n] + d[n-1];
6457  }
6458 }
6459 
6460 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
6461 {
6462  // recursive definition, z in [-1,1]
6463  // T_0(z) = 1, T_1(z) = z
6464  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6465  double z;
6466  u[0] = 1.;
6467  if (p == 0) { return; }
6468  u[1] = z = 2.*x - 1.;
6469  for (int n = 1; n < p; n++)
6470  {
6471  u[n+1] = 2*z*u[n] - u[n-1];
6472  }
6473 }
6474 
6475 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
6476 {
6477  // recursive definition, z in [-1,1]
6478  // T_0(z) = 1, T_1(z) = z
6479  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6480  // T'_n(z) = n*U_{n-1}(z)
6481  // U_0(z) = 1 U_1(z) = 2*z
6482  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
6483  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
6484  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
6485  double z;
6486  u[0] = 1.;
6487  d[0] = 0.;
6488  if (p == 0) { return; }
6489  u[1] = z = 2.*x - 1.;
6490  d[1] = 2.;
6491  for (int n = 1; n < p; n++)
6492  {
6493  u[n+1] = 2*z*u[n] - u[n-1];
6494  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
6495  }
6496 }
6497 
6498 const double *Poly_1D::OpenPoints(const int p)
6499 {
6500  double *op;
6501 
6502  if (open_pts.Size() <= p)
6503  {
6504  int i = open_pts.Size();
6505  open_pts.SetSize(p + 1);
6506  for ( ; i < p; i++)
6507  {
6508  open_pts[i] = NULL;
6509  }
6510  goto alloc_open;
6511  }
6512  if ((op = open_pts[p]) != NULL)
6513  {
6514  return op;
6515  }
6516 alloc_open:
6517  open_pts[p] = op = new double[p + 1];
6518  GaussPoints(p, op);
6519  // ChebyshevPoints(p, op);
6520  return op;
6521 }
6522 
6523 const double *Poly_1D::ClosedPoints(const int p)
6524 {
6525  double *cp;
6526 
6527  if (closed_pts.Size() <= p)
6528  {
6529  int i = closed_pts.Size();
6530  closed_pts.SetSize(p + 1);
6531  for ( ; i < p; i++)
6532  {
6533  closed_pts[i] = NULL;
6534  }
6535  goto alloc_closed;
6536  }
6537  if ((cp = closed_pts[p]) != NULL)
6538  {
6539  return cp;
6540  }
6541 alloc_closed:
6542  closed_pts[p] = cp = new double[p + 1];
6543  GaussLobattoPoints(p, cp);
6544  // UniformPoints(p, cp);
6545  return cp;
6546 }
6547 
6549 {
6550  Basis *ob;
6551 
6552  if (open_basis.Size() <= p)
6553  {
6554  int i = open_basis.Size();
6555  open_basis.SetSize(p + 1);
6556  for ( ; i < p; i++)
6557  {
6558  open_basis[i] = NULL;
6559  }
6560  goto alloc_obasis;
6561  }
6562  if ((ob = open_basis[p]) != NULL)
6563  {
6564  return *ob;
6565  }
6566 alloc_obasis:
6567  open_basis[p] = ob = new Basis(p, OpenPoints(p));
6568  return *ob;
6569 }
6570 
6572 {
6573  Basis *cb;
6574 
6575  if (closed_basis.Size() <= p)
6576  {
6577  int i = closed_basis.Size();
6578  closed_basis.SetSize(p + 1);
6579  for ( ; i < p; i++)
6580  {
6581  closed_basis[i] = NULL;
6582  }
6583  goto alloc_cbasis;
6584  }
6585  if ((cb = closed_basis[p]) != NULL)
6586  {
6587  return *cb;
6588  }
6589 alloc_cbasis:
6590  closed_basis[p] = cb = new Basis(p, ClosedPoints(p));
6591  return *cb;
6592 }
6593 
6595 {
6596  for (int i = 0; i < open_pts.Size(); i++)
6597  {
6598  delete [] open_pts[i];
6599  }
6600  for (int i = 0; i < closed_pts.Size(); i++)
6601  {
6602  delete [] closed_pts[i];
6603  }
6604  for (int i = 0; i < open_basis.Size(); i++)
6605  {
6606  delete open_basis[i];
6607  }
6608  for (int i = 0; i < closed_basis.Size(); i++)
6609  {
6610  delete closed_basis[i];
6611  }
6612 }
6613 
6615 Array2D<int> Poly_1D::binom;
6616 
6617 
6619  : NodalFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
6620  basis1d(poly1d.ClosedBasis(p)),
6621  dof_map(Dof)
6622 {
6623  const double *cp = poly1d.ClosedPoints(p);
6624 
6625 #ifndef MFEM_THREAD_SAFE
6626  shape_x.SetSize(p+1);
6627  dshape_x.SetSize(p+1);
6628 #endif
6629 
6630  Nodes.IntPoint(0).x = cp[0];
6631  Nodes.IntPoint(1).x = cp[p];
6632  dof_map[0] = 0;
6633  dof_map[p] = 1;
6634  for (int i = 1; i < p; i++)
6635  {
6636  Nodes.IntPoint(i+1).x = cp[i];
6637  dof_map[i] = i+1;
6638  }
6639 }
6640 
6642  Vector &shape) const
6643 {
6644  const int p = Order;
6645 
6646 #ifdef MFEM_THREAD_SAFE
6647  Vector shape_x(p+1);
6648 #endif
6649 
6650  basis1d.Eval(ip.x, shape_x);
6651 
6652  shape(0) = shape_x(0);
6653  shape(1) = shape_x(p);
6654  for (int i = 1; i < p; i++)
6655  {
6656  shape(i+1) = shape_x(i);
6657  }
6658 }
6659 
6661  DenseMatrix &dshape) const
6662 {
6663  const int p = Order;
6664 
6665 #ifdef MFEM_THREAD_SAFE
6666  Vector shape_x(p+1), dshape_x(p+1);
6667 #endif
6668 
6669  basis1d.Eval(ip.x, shape_x, dshape_x);
6670 
6671  dshape(0,0) = dshape_x(0);
6672  dshape(1,0) = dshape_x(p);
6673  for (int i = 1; i < p; i++)
6674  {
6675  dshape(i+1,0) = dshape_x(i);
6676  }
6677 }
6678 
6679 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
6680 {
6681  const int p = Order;
6682  const double *cp = poly1d.ClosedPoints(p);
6683 
6684  switch (vertex)
6685  {
6686  case 0:
6687  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
6688  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
6689  for (int i = 1; i < p; i++)
6690  {
6691  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6692  }
6693  break;
6694 
6695  case 1:
6696  dofs(0) = poly1d.CalcDelta(p, cp[0]);
6697  dofs(1) = poly1d.CalcDelta(p, cp[p]);
6698  for (int i = 1; i < p; i++)
6699  {
6700  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
6701  }
6702  break;
6703  }
6704 }
6705 
6706 
6708  : NodalFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
6709  FunctionSpace::Qk),
6710  basis1d(poly1d.ClosedBasis(p)), dof_map((p + 1)*(p + 1))
6711 {
6712  const double *cp = poly1d.ClosedPoints(p);
6713 
6714  const int p1 = p + 1;
6715 
6716 #ifndef MFEM_THREAD_SAFE
6717  shape_x.SetSize(p1);
6718  shape_y.SetSize(p1);
6719  dshape_x.SetSize(p1);
6720  dshape_y.SetSize(p1);
6721 #endif
6722 
6723  // vertices
6724  dof_map[0 + 0*p1] = 0;
6725  dof_map[p + 0*p1] = 1;
6726  dof_map[p + p*p1] = 2;
6727  dof_map[0 + p*p1] = 3;
6728 
6729  // edges
6730  int o = 4;
6731  for (int i = 1; i < p; i++)
6732  {
6733  dof_map[i + 0*p1] = o++;
6734  }
6735  for (int i = 1; i < p; i++)
6736  {
6737  dof_map[p + i*p1] = o++;
6738  }
6739  for (int i = 1; i < p; i++)
6740  {
6741  dof_map[(p-i) + p*p1] = o++;
6742  }
6743  for (int i = 1; i < p; i++)
6744  {
6745  dof_map[0 + (p-i)*p1] = o++;
6746  }
6747 
6748  // interior
6749  for (int j = 1; j < p; j++)
6750  for (int i = 1; i < p; i++)
6751  {
6752  dof_map[i + j*p1] = o++;
6753  }
6754 
6755  o = 0;
6756  for (int j = 0; j <= p; j++)
6757  for (int i = 0; i <= p; i++)
6758  {
6759  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
6760  }
6761 }
6762 
6764  Vector &shape) const
6765 {
6766  const int p = Order;
6767 
6768 #ifdef MFEM_THREAD_SAFE
6769  Vector shape_x(p+1), shape_y(p+1);
6770 #endif
6771 
6772  basis1d.Eval(ip.x, shape_x);
6773  basis1d.Eval(ip.y, shape_y);
6774 
6775  for (int o = 0, j = 0; j <= p; j++)
6776  for (int i = 0; i <= p; i++)
6777  {
6778  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
6779  }
6780 }
6781 
6783  DenseMatrix &dshape) const
6784 {
6785  const int p = Order;
6786 
6787 #ifdef MFEM_THREAD_SAFE
6788  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
6789 #endif
6790 
6791  basis1d.Eval(ip.x, shape_x, dshape_x);
6792  basis1d.Eval(ip.y, shape_y, dshape_y);
6793 
6794  for (int o = 0, j = 0; j <= p; j++)
6795  for (int i = 0; i <= p; i++)
6796  {
6797  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
6798  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
6799  }
6800 }
6801 
6802 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
6803 {
6804  const int p = Order;
6805  const double *cp = poly1d.ClosedPoints(p);
6806 
6807 #ifdef MFEM_THREAD_SAFE
6808  Vector shape_x(p+1), shape_y(p+1);
6809 #endif
6810 
6811  for (int i = 0; i <= p; i++)
6812  {
6813  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6814  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
6815  }
6816 
6817  switch (vertex)
6818  {
6819  case 0:
6820  for (int o = 0, j = 0; j <= p; j++)
6821  for (int i = 0; i <= p; i++)
6822  {
6823  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
6824  }
6825  break;
6826  case 1:
6827  for (int o = 0, j = 0; j <= p; j++)
6828  for (int i = 0; i <= p; i++)
6829  {
6830  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
6831  }
6832  break;
6833  case 2:
6834  for (int o = 0, j = 0; j <= p; j++)
6835  for (int i = 0; i <= p; i++)
6836  {
6837  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
6838  }
6839  break;
6840  case 3:
6841  for (int o = 0, j = 0; j <= p; j++)
6842  for (int i = 0; i <= p; i++)
6843  {
6844  dofs(dof_map[o++]) = shape_x(i)*shape_y(j);
6845  }
6846  break;
6847  }
6848 }
6849 
6850 
6852  : NodalFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
6853  FunctionSpace::Qk),
6854  basis1d(poly1d.ClosedBasis(p)), dof_map((p + 1)*(p + 1)*(p + 1))
6855 {
6856  const double *cp = poly1d.ClosedPoints(p);
6857 
6858  const int p1 = p + 1;
6859 
6860 #ifndef MFEM_THREAD_SAFE
6861  shape_x.SetSize(p1);
6862  shape_y.SetSize(p1);
6863  shape_z.SetSize(p1);
6864  dshape_x.SetSize(p1);
6865  dshape_y.SetSize(p1);
6866  dshape_z.SetSize(p1);
6867 #endif
6868 
6869  // vertices
6870  dof_map[0 + (0 + 0*p1)*p1] = 0;
6871  dof_map[p + (0 + 0*p1)*p1] = 1;
6872  dof_map[p + (p + 0*p1)*p1] = 2;
6873  dof_map[0 + (p + 0*p1)*p1] = 3;
6874  dof_map[0 + (0 + p*p1)*p1] = 4;
6875  dof_map[p + (0 + p*p1)*p1] = 5;
6876  dof_map[p + (p + p*p1)*p1] = 6;
6877  dof_map[0 + (p + p*p1)*p1] = 7;
6878 
6879  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
6880  int o = 8;
6881  for (int i = 1; i < p; i++)
6882  {
6883  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
6884  }
6885  for (int i = 1; i < p; i++)
6886  {
6887  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
6888  }
6889  for (int i = 1; i < p; i++)
6890  {
6891  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
6892  }
6893  for (int i = 1; i < p; i++)
6894  {
6895  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
6896  }
6897  for (int i = 1; i < p; i++)
6898  {
6899  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
6900  }
6901  for (int i = 1; i < p; i++)
6902  {
6903  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
6904  }
6905  for (int i = 1; i < p; i++)
6906  {
6907  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
6908  }
6909  for (int i = 1; i < p; i++)
6910  {
6911  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
6912  }
6913  for (int i = 1; i < p; i++)
6914  {
6915  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
6916  }
6917  for (int i = 1; i < p; i++)
6918  {
6919  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
6920  }
6921  for (int i = 1; i < p; i++)
6922  {
6923  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
6924  }
6925  for (int i = 1; i < p; i++)
6926  {
6927  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
6928  }
6929 
6930  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
6931  for (int j = 1; j < p; j++)
6932  for (int i = 1; i < p; i++)
6933  {
6934  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
6935  }
6936  for (int j = 1; j < p; j++)
6937  for (int i = 1; i < p; i++)
6938  {
6939  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
6940  }
6941  for (int j = 1; j < p; j++)
6942  for (int i = 1; i < p; i++)
6943  {
6944  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
6945  }
6946  for (int j = 1; j < p; j++)
6947  for (int i = 1; i < p; i++)
6948  {
6949  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
6950  }
6951  for (int j = 1; j < p; j++)
6952  for (int i = 1; i < p; i++)
6953  {
6954  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
6955  }
6956  for (int j = 1; j < p; j++)
6957  for (int i = 1; i < p; i++)
6958  {
6959  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
6960  }
6961 
6962  // interior
6963  for (int k = 1; k < p; k++)
6964  for (int j = 1; j < p; j++)
6965  for (int i = 1; i < p; i++)
6966  {
6967  dof_map[i + (j + k*p1)*p1] = o++;
6968  }
6969 
6970  o = 0;
6971  for (int k = 0; k <= p; k++)
6972  for (int j = 0; j <= p; j++)
6973  for (int i = 0; i <= p; i++)
6974  {
6975  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
6976  }
6977 }
6978 
6980  Vector &shape) const
6981 {
6982  const int p = Order;
6983 
6984 #ifdef MFEM_THREAD_SAFE
6985  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
6986 #endif
6987 
6988  basis1d.Eval(ip.x, shape_x);
6989  basis1d.Eval(ip.y, shape_y);
6990  basis1d.Eval(ip.z, shape_z);
6991 
6992  for (int o = 0, k = 0; k <= p; k++)
6993  for (int j = 0; j <= p; j++)
6994  for (int i = 0; i <= p; i++)
6995  {
6996  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
6997  }
6998 }
6999 
7001  DenseMatrix &dshape) const
7002 {
7003  const int p = Order;
7004 
7005 #ifdef MFEM_THREAD_SAFE
7006  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7007  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7008 #endif
7009 
7010  basis1d.Eval(ip.x, shape_x, dshape_x);
7011  basis1d.Eval(ip.y, shape_y, dshape_y);
7012  basis1d.Eval(ip.z, shape_z, dshape_z);
7013 
7014  for (int o = 0, k = 0; k <= p; k++)
7015  for (int j = 0; j <= p; j++)
7016  for (int i = 0; i <= p; i++)
7017  {
7018  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7019  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7020  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7021  }
7022 }
7023 
7024 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7025 {
7026  const int p = Order;
7027  const double *cp = poly1d.ClosedPoints(p);
7028 
7029 #ifdef MFEM_THREAD_SAFE
7030  Vector shape_x(p+1), shape_y(p+1);
7031 #endif
7032 
7033  for (int i = 0; i <= p; i++)
7034  {
7035  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7036  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7037  }
7038 
7039  switch (vertex)
7040  {
7041  case 0:
7042  for (int o = 0, k = 0; k <= p; k++)
7043  for (int j = 0; j <= p; j++)
7044  for (int i = 0; i <= p; i++)
7045  {
7046  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
7047  }
7048  break;
7049  case 1:
7050  for (int o = 0, k = 0; k <= p; k++)
7051  for (int j = 0; j <= p; j++)
7052  for (int i = 0; i <= p; i++)
7053  {
7054  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
7055  }
7056  break;
7057  case 2:
7058  for (int o = 0, k = 0; k <= p; k++)
7059  for (int j = 0; j <= p; j++)
7060  for (int i = 0; i <= p; i++)
7061  {
7062  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
7063  }
7064  break;
7065  case 3:
7066  for (int o = 0, k = 0; k <= p; k++)
7067  for (int j = 0; j <= p; j++)
7068  for (int i = 0; i <= p; i++)
7069  {
7070  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
7071  }
7072  break;
7073  case 4:
7074  for (int o = 0, k = 0; k <= p; k++)
7075  for (int j = 0; j <= p; j++)
7076  for (int i = 0; i <= p; i++)
7077  {
7078  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
7079  }
7080  break;
7081  case 5:
7082  for (int o = 0, k = 0; k <= p; k++)
7083  for (int j = 0; j <= p; j++)
7084  for (int i = 0; i <= p; i++)
7085  {
7086  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
7087  }
7088  break;
7089  case 6:
7090  for (int o = 0, k = 0; k <= p; k++)
7091  for (int j = 0; j <= p; j++)
7092  for (int i = 0; i <= p; i++)
7093  {
7094  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
7095  }
7096  break;
7097  case 7:
7098  for (int o = 0, k = 0; k <= p; k++)
7099  for (int j = 0; j <= p; j++)
7100  for (int i = 0; i <= p; i++)
7101  {
7102  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
7103  }
7104  break;
7105  }
7106 }
7107 
7108 
7110  : PositiveFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
7111  dof_map(Dof)
7112 {
7113 #ifndef MFEM_THREAD_SAFE
7114  // thread private versions; see class header.
7115  shape_x.SetSize(p+1);
7116  dshape_x.SetSize(p+1);
7117 #endif
7118 
7119  // Endpoints need to be first in the list, so reorder them.
7120  Nodes.IntPoint(0).x = 0.0;
7121  Nodes.IntPoint(1).x = 1.0;
7122  dof_map[0] = 0;
7123  dof_map[p] = 1;
7124  for (int i = 1; i < p; i++)
7125  {
7126  Nodes.IntPoint(i+1).x = double(i)/p;
7127  dof_map[i] = i+1;
7128  }
7129 }
7130 
7132  Vector &shape) const
7133 {
7134  const int p = Order;
7135 
7136 #ifdef MFEM_THREAD_SAFE
7137  Vector shape_x(p+1);
7138 #endif
7139 
7140  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7141 
7142  // Endpoints need to be first in the list, so reorder them.
7143  shape(0) = shape_x(0);
7144  shape(1) = shape_x(p);
7145  for (int i = 1; i < p; i++)
7146  {
7147  shape(i+1) = shape_x(i);
7148  }
7149 }
7150 
7152  DenseMatrix &dshape) const
7153 {
7154  const int p = Order;
7155 
7156 #ifdef MFEM_THREAD_SAFE
7157  Vector shape_x(p+1), dshape_x(p+1);
7158 #endif
7159 
7160  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7161 
7162  // Endpoints need to be first in the list, so reorder them.
7163  dshape(0,0) = dshape_x(0);
7164  dshape(1,0) = dshape_x(p);
7165  for (int i = 1; i < p; i++)
7166  {
7167  dshape(i+1,0) = dshape_x(i);
7168  }
7169 }
7170 
7171 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7172 {
7173  dofs = 0.0;
7174  dofs[vertex] = 1.0;
7175 }
7176 
7177 
7179  : PositiveFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
7180  FunctionSpace::Qk),
7181  dof_map((p + 1)*(p + 1))
7182 {
7183  const int p1 = p + 1;
7184 
7185 #ifndef MFEM_THREAD_SAFE
7186  shape_x.SetSize(p1);
7187  shape_y.SetSize(p1);
7188  dshape_x.SetSize(p1);
7189  dshape_y.SetSize(p1);
7190 #endif
7191 
7192  // vertices must be the first ones in the list of DOF's for
7193  // this element. So we need to reorder the points.
7194  dof_map[0 + 0*p1] = 0;
7195  dof_map[p + 0*p1] = 1;
7196  dof_map[p + p*p1] = 2;
7197  dof_map[0 + p*p1] = 3;
7198 
7199  // edges
7200  int o = 4;
7201  for (int i = 1; i < p; i++)
7202  {
7203  dof_map[i + 0*p1] = o++;
7204  }
7205  for (int i = 1; i < p; i++)
7206  {
7207  dof_map[p + i*p1] = o++;
7208  }
7209  for (int i = 1; i < p; i++)
7210  {
7211  dof_map[(p-i) + p*p1] = o++;
7212  }
7213  for (int i = 1; i < p; i++)
7214  {
7215  dof_map[0 + (p-i)*p1] = o++;
7216  }
7217 
7218  // interior
7219  for (int j = 1; j < p; j++)
7220  for (int i = 1; i < p; i++)
7221  {
7222  dof_map[i + j*p1] = o++;
7223  }
7224 
7225  o = 0;
7226  for (int j = 0; j <= p; j++)
7227  for (int i = 0; i <= p; i++)
7228  {
7229  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
7230  }
7231 }
7232 
7234  Vector &shape) const
7235 {
7236  const int p = Order;
7237 
7238 #ifdef MFEM_THREAD_SAFE
7239  Vector shape_x(p+1), shape_y(p+1);
7240 #endif
7241 
7242  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7243  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7244 
7245  // Reorder so that vertices are at the beginning of the list
7246  for (int o = 0, j = 0; j <= p; j++)
7247  for (int i = 0; i <= p; i++)
7248  {
7249  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7250  }
7251 }
7252 
7254  DenseMatrix &dshape) const
7255 {
7256  const int p = Order;
7257 
7258 #ifdef MFEM_THREAD_SAFE
7259  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7260 #endif
7261 
7262  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7263  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7264 
7265  // Reorder so that vertices are at the beginning of the list
7266  for (int o = 0, j = 0; j <= p; j++)
7267  for (int i = 0; i <= p; i++)
7268  {
7269  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7270  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7271  }
7272 }
7273 
7275 {
7276  dofs = 0.0;
7277  dofs[vertex] = 1.0;
7278 }
7279 
7280 
7282  : PositiveFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
7283  FunctionSpace::Qk),
7284  dof_map((p + 1)*(p + 1)*(p + 1))
7285 {
7286  const int p1 = p + 1;
7287 
7288 #ifndef MFEM_THREAD_SAFE
7289  shape_x.SetSize(p1);
7290  shape_y.SetSize(p1);
7291  shape_z.SetSize(p1);
7292  dshape_x.SetSize(p1);
7293  dshape_y.SetSize(p1);
7294  dshape_z.SetSize(p1);
7295 #endif
7296 
7297  // vertices must be the first ones in the list of DOF's for
7298  // this element. So we need to reorder the points.
7299  dof_map[0 + (0 + 0*p1)*p1] = 0;
7300  dof_map[p + (0 + 0*p1)*p1] = 1;
7301  dof_map[p + (p + 0*p1)*p1] = 2;
7302  dof_map[0 + (p + 0*p1)*p1] = 3;
7303  dof_map[0 + (0 + p*p1)*p1] = 4;
7304  dof_map[p + (0 + p*p1)*p1] = 5;
7305  dof_map[p + (p + p*p1)*p1] = 6;
7306  dof_map[0 + (p + p*p1)*p1] = 7;
7307 
7308  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
7309  int o = 8;
7310  for (int i = 1; i < p; i++)
7311  {
7312  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
7313  }
7314  for (int i = 1; i < p; i++)
7315  {
7316  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
7317  }
7318  for (int i = 1; i < p; i++)
7319  {
7320  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
7321  }
7322  for (int i = 1; i < p; i++)
7323  {
7324  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
7325  }
7326  for (int i = 1; i < p; i++)
7327  {
7328  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
7329  }
7330  for (int i = 1; i < p; i++)
7331  {
7332  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
7333  }
7334  for (int i = 1; i < p; i++)
7335  {
7336  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
7337  }
7338  for (int i = 1; i < p; i++)
7339  {
7340  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
7341  }
7342  for (int i = 1; i < p; i++)
7343  {
7344  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
7345  }
7346  for (int i = 1; i < p; i++)
7347  {
7348  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
7349  }
7350  for (int i = 1; i < p; i++)
7351  {
7352  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
7353  }
7354  for (int i = 1; i < p; i++)
7355  {
7356  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
7357  }
7358 
7359  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7360  for (int j = 1; j < p; j++)
7361  for (int i = 1; i < p; i++)
7362  {
7363  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
7364  }
7365  for (int j = 1; j < p; j++)
7366  for (int i = 1; i < p; i++)
7367  {
7368  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
7369  }
7370  for (int j = 1; j < p; j++)
7371  for (int i = 1; i < p; i++)
7372  {
7373  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
7374  }
7375  for (int j = 1; j < p; j++)
7376  for (int i = 1; i < p; i++)
7377  {
7378  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
7379  }
7380  for (int j = 1; j < p; j++)
7381  for (int i = 1; i < p; i++)
7382  {
7383  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
7384  }
7385  for (int j = 1; j < p; j++)
7386  for (int i = 1; i < p; i++)
7387  {
7388  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
7389  }
7390 
7391  // interior
7392  for (int k = 1; k < p; k++)
7393  for (int j = 1; j < p; j++)
7394  for (int i = 1; i < p; i++)
7395  {
7396  dof_map[i + (j + k*p1)*p1] = o++;
7397  }
7398 
7399  o = 0;
7400  for (int k = 0; k <= p; k++)
7401  for (int j = 0; j <= p; j++)
7402  for (int i = 0; i <= p; i++)
7403  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
7404  double(k)/p);
7405 }
7406 
7408  Vector &shape) const
7409 {
7410  const int p = Order;
7411 
7412 #ifdef MFEM_THREAD_SAFE
7413  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7414 #endif
7415 
7416  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7417  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7418  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
7419 
7420  for (int o = 0, k = 0; k <= p; k++)
7421  for (int j = 0; j <= p; j++)
7422  for (int i = 0; i <= p; i++)
7423  {
7424  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7425  }
7426 }
7427 
7429  DenseMatrix &dshape) const
7430 {
7431  const int p = Order;
7432 
7433 #ifdef MFEM_THREAD_SAFE
7434  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7435  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7436 #endif
7437 
7438  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7439  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7440  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
7441 
7442  for (int o = 0, k = 0; k <= p; k++)
7443  for (int j = 0; j <= p; j++)
7444  for (int i = 0; i <= p; i++)
7445  {
7446  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7447  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7448  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7449  }
7450 }
7451 
7452 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7453 {
7454  dofs = 0.0;
7455  dofs[vertex] = 1.0;
7456 }
7457 
7458 
7460  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7461  FunctionSpace::Pk)
7462 {
7463  const double *cp = poly1d.ClosedPoints(p);
7464 
7465 #ifndef MFEM_THREAD_SAFE
7466  shape_x.SetSize(p + 1);
7467  shape_y.SetSize(p + 1);
7468  shape_l.SetSize(p + 1);
7469  dshape_x.SetSize(p + 1);
7470  dshape_y.SetSize(p + 1);
7471  dshape_l.SetSize(p + 1);
7472  u.SetSize(Dof);
7473  du.SetSize(Dof, Dim);
7474 #else
7475  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7476 #endif
7477 
7478  // vertices
7479  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
7480  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
7481  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
7482 
7483  // edges
7484  int o = 3;
7485  for (int i = 1; i < p; i++)
7486  {
7487  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
7488  }
7489  for (int i = 1; i < p; i++)
7490  {
7491  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
7492  }
7493  for (int i = 1; i < p; i++)
7494  {
7495  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
7496  }
7497 
7498  // interior
7499  for (int j = 1; j < p; j++)
7500  for (int i = 1; i + j < p; i++)
7501  {
7502  const double w = cp[i] + cp[j] + cp[p-i-j];
7503  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
7504  }
7505 
7506  DenseMatrix T(Dof);
7507  for (int k = 0; k < Dof; k++)
7508  {
7509  IntegrationPoint &ip = Nodes.IntPoint(k);
7510  poly1d.CalcBasis(p, ip.x, shape_x);
7511  poly1d.CalcBasis(p, ip.y, shape_y);
7512  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7513 
7514  o = 0;
7515  for (int j = 0; j <= p; j++)
7516  for (int i = 0; i + j <= p; i++)
7517  {
7518  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7519  }
7520  }
7521 
7522  Ti.Factor(T);
7523  // cout << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
7524 }
7525 
7527  Vector &shape) const
7528 {
7529  const int p = Order;
7530 
7531 #ifdef MFEM_THREAD_SAFE
7532  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
7533 #endif
7534 
7535  poly1d.CalcBasis(p, ip.x, shape_x);
7536  poly1d.CalcBasis(p, ip.y, shape_y);
7537  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7538 
7539  for (int o = 0, j = 0; j <= p; j++)
7540  for (int i = 0; i + j <= p; i++)
7541  {
7542  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7543  }
7544 
7545  Ti.Mult(u, shape);
7546 }
7547 
7549  DenseMatrix &dshape) const
7550 {
7551  const int p = Order;
7552 
7553 #ifdef MFEM_THREAD_SAFE
7554  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7555  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
7556  DenseMatrix du(Dof, Dim);
7557 #endif
7558 
7559  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7560  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7561  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
7562 
7563  for (int o = 0, j = 0; j <= p; j++)
7564  for (int i = 0; i + j <= p; i++)
7565  {
7566  int k = p - i - j;
7567  du(o,0) = ((dshape_x(i)* shape_l(k)) -
7568  ( shape_x(i)*dshape_l(k)))*shape_y(j);
7569  du(o,1) = ((dshape_y(j)* shape_l(k)) -
7570  ( shape_y(j)*dshape_l(k)))*shape_x(i);
7571  o++;
7572  }
7573 
7574  Ti.Mult(du, dshape);
7575 }
7576 
7577 
7579  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
7580  p, FunctionSpace::Pk)
7581 {
7582  const double *cp = poly1d.ClosedPoints(p);
7583 
7584 #ifndef MFEM_THREAD_SAFE
7585  shape_x.SetSize(p + 1);
7586  shape_y.SetSize(p + 1);
7587  shape_z.SetSize(p + 1);
7588  shape_l.SetSize(p + 1);
7589  dshape_x.SetSize(p + 1);
7590  dshape_y.SetSize(p + 1);
7591  dshape_z.SetSize(p + 1);
7592  dshape_l.SetSize(p + 1);
7593  u.SetSize(Dof);
7594  du.SetSize(Dof, Dim);
7595 #else
7596  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7597 #endif
7598 
7599  // vertices
7600  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
7601  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
7602  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
7603  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
7604 
7605  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7606  int o = 4;
7607  for (int i = 1; i < p; i++) // (0,1)
7608  {
7609  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
7610  }
7611  for (int i = 1; i < p; i++) // (0,2)
7612  {
7613  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
7614  }
7615  for (int i = 1; i < p; i++) // (0,3)
7616  {
7617  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
7618  }
7619  for (int i = 1; i < p; i++) // (1,2)
7620  {
7621  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
7622  }
7623  for (int i = 1; i < p; i++) // (1,3)
7624  {
7625  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
7626  }
7627  for (int i = 1; i < p; i++) // (2,3)
7628  {
7629  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
7630  }
7631 
7632  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7633  for (int j = 1; j < p; j++)
7634  for (int i = 1; i + j < p; i++) // (1,2,3)
7635  {
7636  double w = cp[i] + cp[j] + cp[p-i-j];
7637  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
7638  }
7639  for (int j = 1; j < p; j++)
7640  for (int i = 1; i + j < p; i++) // (0,3,2)
7641  {
7642  double w = cp[i] + cp[j] + cp[p-i-j];
7643  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
7644  }
7645  for (int j = 1; j < p; j++)
7646  for (int i = 1; i + j < p; i++) // (0,1,3)
7647  {
7648  double w = cp[i] + cp[j] + cp[p-i-j];
7649  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
7650  }
7651  for (int j = 1; j < p; j++)
7652  for (int i = 1; i + j < p; i++) // (0,2,1)
7653  {
7654  double w = cp[i] + cp[j] + cp[p-i-j];
7655  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
7656  }
7657 
7658  // interior
7659  for (int k = 1; k < p; k++)
7660  for (int j = 1; j + k < p; j++)
7661  for (int i = 1; i + j + k < p; i++)
7662  {
7663  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
7664  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
7665  }
7666 
7667  DenseMatrix T(Dof);
7668  for (int m = 0; m < Dof; m++)
7669  {
7670  IntegrationPoint &ip = Nodes.IntPoint(m);
7671  poly1d.CalcBasis(p, ip.x, shape_x);
7672  poly1d.CalcBasis(p, ip.y, shape_y);
7673  poly1d.CalcBasis(p, ip.z, shape_z);
7674  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7675 
7676  o = 0;
7677  for (int k = 0; k <= p; k++)
7678  for (int j = 0; j + k <= p; j++)
7679  for (int i = 0; i + j + k <= p; i++)
7680  {
7681  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7682  }
7683  }
7684 
7685  Ti.Factor(T);
7686  // cout << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
7687 }
7688 
7690  Vector &shape) const
7691 {
7692  const int p = Order;
7693 
7694 #ifdef MFEM_THREAD_SAFE
7695  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7696  Vector u(Dof);
7697 #endif
7698 
7699  poly1d.CalcBasis(p, ip.x, shape_x);
7700  poly1d.CalcBasis(p, ip.y, shape_y);
7701  poly1d.CalcBasis(p, ip.z, shape_z);
7702  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7703 
7704  for (int o = 0, k = 0; k <= p; k++)
7705  for (int j = 0; j + k <= p; j++)
7706  for (int i = 0; i + j + k <= p; i++)
7707  {
7708  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7709  }
7710 
7711  Ti.Mult(u, shape);
7712 }
7713 
7715  DenseMatrix &dshape) const
7716 {
7717  const int p = Order;
7718 
7719 #ifdef MFEM_THREAD_SAFE
7720  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7721  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
7722  DenseMatrix du(Dof, Dim);
7723 #endif
7724 
7725  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7726  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7727  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
7728  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
7729 
7730  for (int o = 0, k = 0; k <= p; k++)
7731  for (int j = 0; j + k <= p; j++)
7732  for (int i = 0; i + j + k <= p; i++)
7733  {
7734  int l = p - i - j - k;
7735  du(o,0) = ((dshape_x(i)* shape_l(l)) -
7736  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
7737  du(o,1) = ((dshape_y(j)* shape_l(l)) -
7738  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
7739  du(o,2) = ((dshape_z(k)* shape_l(l)) -
7740  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
7741  o++;
7742  }
7743 
7744  Ti.Mult(du, dshape);
7745 }
7746 
7747 
7749  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7750  FunctionSpace::Pk)
7751 {
7752 #ifndef MFEM_THREAD_SAFE
7753  m_shape.SetSize(Dof);
7754  dshape_1d.SetSize(p + 1);
7755  m_dshape.SetSize(Dof, Dim);
7756 #endif
7757  dof_map.SetSize(Dof);
7758 
7759  struct Index
7760  {
7761  int p2p3;
7762  Index(int p) { p2p3 = 2*p + 3; }
7763  int operator()(int i, int j) { return ((p2p3-j)*j)/2+i; }
7764  };
7765  Index idx(p);
7766 
7767  // vertices
7768  dof_map[idx(0,0)] = 0;
7769  Nodes.IntPoint(0).Set2(0., 0.);
7770  dof_map[idx(p,0)] = 1;
7771  Nodes.IntPoint(1).Set2(1., 0.);
7772  dof_map[idx(0,p)] = 2;
7773  Nodes.IntPoint(2).Set2(0., 1.);
7774 
7775  // edges
7776  int o = 3;
7777  for (int i = 1; i < p; i++)
7778  {
7779  dof_map[idx(i,0)] = o;
7780  Nodes.IntPoint(o++).Set2(double(i)/p, 0.);
7781  }
7782  for (int i = 1; i < p; i++)
7783  {
7784  dof_map[idx(p-i,i)] = o;
7785  Nodes.IntPoint(o++).Set2(double(p-i)/p, double(i)/p);
7786  }
7787  for (int i = 1; i < p; i++)
7788  {
7789  dof_map[idx(0,p-i)] = o;
7790  Nodes.IntPoint(o++).Set2(0., double(p-i)/p);
7791  }
7792 
7793  // interior
7794  for (int j = 1; j < p; j++)
7795  for (int i = 1; i + j < p; i++)
7796  {
7797  dof_map[idx(i,j)] = o;
7798  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
7799  }
7800 }
7801 
7802 // static method
7804  const int p, const double l1, const double l2, double *shape)
7805 {
7806  const double l3 = 1. - l1 - l2;
7807 
7808  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
7809  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
7810  // Another expression is given by the terms of the expansion:
7811  // (l1 + l2 + l3)^p =
7812  // \sum_{j=0}^p \binom{p}{j} l2^j
7813  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
7814  const int *bp = Poly_1D::Binom(p);
7815  double z = 1.;
7816  for (int o = 0, j = 0; j <= p; j++)
7817  {
7818  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape[o]);
7819  double s = bp[j]*z;
7820  for (int i = 0; i <= p - j; i++)
7821  {
7822  shape[o++] *= s;
7823  }
7824  z *= l2;
7825  }
7826 }
7827 
7828 // static method
7830  const int p, const double l1, const double l2,
7831  double *dshape_1d, double *dshape)
7832 {
7833  const int dof = ((p + 1)*(p + 2))/2;
7834  const double l3 = 1. - l1 - l2;
7835 
7836  const int *bp = Poly_1D::Binom(p);
7837  double z = 1.;
7838  for (int o = 0, j = 0; j <= p; j++)
7839  {
7840  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
7841  double s = bp[j]*z;
7842  for (int i = 0; i <= p - j; i++)
7843  {
7844  dshape[o++] = s*dshape_1d[i];
7845  }
7846  z *= l2;
7847  }
7848  z = 1.;
7849  for (int i = 0; i <= p; i++)
7850  {
7851  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
7852  double s = bp[i]*z;
7853  for (int o = i, j = 0; j <= p - i; j++)
7854  {
7855  dshape[dof + o] = s*dshape_1d[j];
7856  o += p + 1 - j;
7857  }
7858  z *= l1;
7859  }
7860 }
7861 
7863  Vector &shape) const
7864 {
7865 #ifdef MFEM_THREAD_SAFE
7866  Vector m_shape(Dof);
7867 #endif
7868  CalcShape(Order, ip.x, ip.y, m_shape.GetData());
7869  for (int i = 0; i < Dof; i++)
7870  {
7871  shape(dof_map[i]) = m_shape(i);
7872  }
7873 }
7874 
7876  DenseMatrix &dshape) const
7877 {
7878 #ifdef MFEM_THREAD_SAFE
7879  Vector dshape_1d(Order + 1);
7881 #endif
7882  CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(), m_dshape.Data());
7883  for (int d = 0; d < 2; d++)
7884  {
7885  for (int i = 0; i < Dof; i++)
7886  {
7887  dshape(dof_map[i],d) = m_dshape(i,d);
7888  }
7889  }
7890 }
7891 
7892 
7894  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
7895  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
7896 {
7897 #ifndef MFEM_THREAD_SAFE
7898  m_shape.SetSize(Dof);
7899  dshape_1d.SetSize(p + 1);
7900  m_dshape.SetSize(Dof, Dim);
7901 #endif
7902  dof_map.SetSize(Dof);
7903 
7904  struct Index
7905  {
7906  int p, dof;
7907  int tri(int k) { return (k*(k + 1))/2; }
7908  int tet(int k) { return (k*(k + 1)*(k + 2))/6; }
7909  Index(int p_) { p = p_; dof = tet(p + 1); }
7910  int operator()(int i, int j, int k)
7911  { return dof - tet(p - k) - tri(p + 1 - k - j) + i; }
7912  };
7913  Index idx(p);
7914 
7915  // vertices
7916  dof_map[idx(0,0,0)] = 0;
7917  Nodes.IntPoint(0).Set3(0., 0., 0.);
7918  dof_map[idx(p,0,0)] = 1;
7919  Nodes.IntPoint(1).Set3(1., 0., 0.);
7920  dof_map[idx(0,p,0)] = 2;
7921  Nodes.IntPoint(2).Set3(0., 1., 0.);
7922  dof_map[idx(0,0,p)] = 3;
7923  Nodes.IntPoint(3).Set3(0., 0., 1.);
7924 
7925  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7926  int o = 4;
7927  for (int i = 1; i < p; i++) // (0,1)
7928  {
7929  dof_map[idx(i,0,0)] = o;
7930  Nodes.IntPoint(o++).Set3(double(i)/p, 0., 0.);
7931  }
7932  for (int i = 1; i < p; i++) // (0,2)
7933  {
7934  dof_map[idx(0,i,0)] = o;
7935  Nodes.IntPoint(o++).Set3(0., double(i)/p, 0.);
7936  }
7937  for (int i = 1; i < p; i++) // (0,3)
7938  {
7939  dof_map[idx(0,0,i)] = o;
7940  Nodes.IntPoint(o++).Set3(0., 0., double(i)/p);
7941  }
7942  for (int i = 1; i < p; i++) // (1,2)
7943  {
7944  dof_map[idx(p-i,i,0)] = o;
7945  Nodes.IntPoint(o++).Set3(double(p-i)/p, double(i)/p, 0.);
7946  }
7947  for (int i = 1; i < p; i++) // (1,3)
7948  {
7949  dof_map[idx(p-i,0,i)] = o;
7950  Nodes.IntPoint(o++).Set3(double(p-i)/p, 0., double(i)/p);
7951  }
7952  for (int i = 1; i < p; i++) // (2,3)
7953  {
7954  dof_map[idx(0,p-i,i)] = o;
7955  Nodes.IntPoint(o++).Set3(0., double(p-i)/p, double(i)/p);
7956  }
7957 
7958  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7959  for (int j = 1; j < p; j++)
7960  for (int i = 1; i + j < p; i++) // (1,2,3)
7961  {
7962  dof_map[idx(p-i-j,i,j)] = o;
7963  Nodes.IntPoint(o++).Set3(double(p-i-j)/p, double(i)/p, double(j)/p);
7964  }
7965  for (int j = 1; j < p; j++)
7966  for (int i = 1; i + j < p; i++) // (0,3,2)
7967  {
7968  dof_map[idx(0,j,i)] = o;
7969  Nodes.IntPoint(o++).Set3(0., double(j)/p, double(i)/p);
7970  }
7971  for (int j = 1; j < p; j++)
7972  for (int i = 1; i + j < p; i++) // (0,1,3)
7973  {
7974  dof_map[idx(i,0,j)] = o;
7975  Nodes.IntPoint(o++).Set3(double(i)/p, 0., double(j)/p);
7976  }
7977  for (int j = 1; j < p; j++)
7978  for (int i = 1; i + j < p; i++) // (0,2,1)
7979  {
7980  dof_map[idx(j,i,0)] = o;
7981  Nodes.IntPoint(o++).Set3(double(j)/p, double(i)/p, 0.);
7982  }
7983 
7984  // interior
7985  for (int k = 1; k < p; k++)
7986  for (int j = 1; j + k < p; j++)
7987  for (int i = 1; i + j + k < p; i++)
7988  {
7989  dof_map[idx(i,j,k)] = o;
7990  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
7991  }
7992 }
7993 
7994 // static method
7996  const int p, const double l1, const double l2, const double l3,
7997  double *shape)
7998 {
7999  const double l4 = 1. - l1 - l2 - l3;
8000 
8001  // The basis functions are the terms in the expansion:
8002  // (l1 + l2 + l3 + l4)^p =
8003  // \sum_{k=0}^p \binom{p}{k} l3^k
8004  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8005  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8006  const int *bp = Poly_1D::Binom(p);
8007  double l3k = 1.;
8008  for (int o = 0, k = 0; k <= p; k++)
8009  {
8010  const int *bpk = Poly_1D::Binom(p - k);
8011  const double ek = bp[k]*l3k;
8012  double l2j = 1.;
8013  for (int j = 0; j <= p - k; j++)
8014  {
8015  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape[o]);
8016  double ekj = ek*bpk[j]*l2j;
8017  for (int i = 0; i <= p - k - j; i++)
8018  {
8019  shape[o++] *= ekj;
8020  }
8021  l2j *= l2;
8022  }
8023  l3k *= l3;
8024  }
8025 }
8026 
8027 // static method
8029  const int p, const double l1, const double l2, const double l3,
8030  double *dshape_1d, double *dshape)
8031 {
8032  const int dof = ((p + 1)*(p + 2)*(p + 3))/6;
8033  const double l4 = 1. - l1 - l2 - l3;
8034 
8035  // For the x derivatives, differentiate the terms of the expression:
8036  // \sum_{k=0}^p \binom{p}{k} l3^k
8037  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8038  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8039  const int *bp = Poly_1D::Binom(p);
8040  double l3k = 1.;
8041  for (int o = 0, k = 0; k <= p; k++)
8042  {
8043  const int *bpk = Poly_1D::Binom(p - k);
8044  const double ek = bp[k]*l3k;
8045  double l2j = 1.;
8046  for (int j = 0; j <= p - k; j++)
8047  {
8048  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
8049  double ekj = ek*bpk[j]*l2j;
8050  for (int i = 0; i <= p - k - j; i++)
8051  {
8052  dshape[o++] = dshape_1d[i]*ekj;
8053  }
8054  l2j *= l2;
8055  }
8056  l3k *= l3;
8057  }
8058  // For the y derivatives, differentiate the terms of the expression:
8059  // \sum_{k=0}^p \binom{p}{k} l3^k
8060  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
8061  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
8062  l3k = 1.;
8063  for (int ok = 0, k = 0; k <= p; k++)
8064  {
8065  const int *bpk = Poly_1D::Binom(p - k);
8066  const double ek = bp[k]*l3k;
8067  double l1i = 1.;
8068  for (int i = 0; i <= p - k; i++)
8069  {
8070  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
8071  double eki = ek*bpk[i]*l1i;
8072  int o = ok + i;
8073  for (int j = 0; j <= p - k - i; j++)
8074  {
8075  dshape[dof + o] = dshape_1d[j]*eki;
8076  o += p - k - j + 1;
8077  }
8078  l1i *= l1;
8079  }
8080  l3k *= l3;
8081  ok += ((p - k + 2)*(p - k + 1))/2;
8082  }
8083  // For the z derivatives, differentiate the terms of the expression:
8084  // \sum_{j=0}^p \binom{p}{j} l2^j
8085  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
8086  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
8087  double l2j = 1.;
8088  for (int j = 0; j <= p; j++)
8089  {
8090  const int *bpj = Poly_1D::Binom(p - j);
8091  const double ej = bp[j]*l2j;
8092  double l1i = 1.;
8093  for (int i = 0; i <= p - j; i++)
8094  {
8095  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
8096  double eji = ej*bpj[i]*l1i;
8097  int m = ((p + 2)*(p + 1))/2;
8098  int n = ((p - j + 2)*(p - j + 1))/2;
8099  for (int o = i, k = 0; k <= p - j - i; k++)
8100  {
8101  // m = ((p - k + 2)*(p - k + 1))/2;
8102  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
8103  o += m;
8104  dshape[2*dof + o - n] = dshape_1d[k]*eji;
8105  m -= p - k + 1;
8106  n -= p - k - j + 1;
8107  }
8108  l1i *= l1;
8109  }
8110  l2j *= l2;
8111  }
8112 }
8113 
8115  Vector &shape) const
8116 {
8117 #ifdef MFEM_THREAD_SAFE
8118  Vector m_shape(Dof);
8119 #endif
8120  CalcShape(Order, ip.x, ip.y, ip.z, m_shape.GetData());
8121  for (int i = 0; i < Dof; i++)
8122  {
8123  shape(dof_map[i]) = m_shape(i);
8124  }
8125 }
8126 
8128  DenseMatrix &dshape) const
8129 {
8130 #ifdef MFEM_THREAD_SAFE
8131  Vector dshape_1d(Order + 1);
8133 #endif
8134  CalcDShape(Order, ip.x, ip.y, ip.z, dshape_1d.GetData(), m_dshape.Data());
8135  for (int d = 0; d < 3; d++)
8136  {
8137  for (int i = 0; i < Dof; i++)
8138  {
8139  dshape(dof_map[i],d) = m_dshape(i,d);
8140  }
8141  }
8142 }
8143 
8144 
8145 L2_SegmentElement::L2_SegmentElement(const int p, const int _type)
8146  : NodalFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk)
8147 {
8148  const double *op;
8149 
8150  type = _type;
8151  switch (type)
8152  {
8153  case 0:
8154  basis1d = &poly1d.OpenBasis(p);
8155  op = poly1d.OpenPoints(p);
8156  break;
8157  case 1:
8158  default:
8159  basis1d = &poly1d.ClosedBasis(p);
8160  op = poly1d.ClosedPoints(p);
8161  }
8162 
8163 #ifndef MFEM_THREAD_SAFE
8164  shape_x.SetSize(p + 1);
8165  dshape_x.SetDataAndSize(NULL, p + 1);
8166 #endif
8167 
8168  for (int i = 0; i <= p; i++)
8169  {
8170  Nodes.IntPoint(i).x = op[i];
8171  }
8172 }
8173 
8175  Vector &shape) const
8176 {
8177  basis1d->Eval(ip.x, shape);
8178 }
8179 
8181  DenseMatrix &dshape) const
8182 {
8183 #ifdef MFEM_THREAD_SAFE
8184  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8185 #else
8186  dshape_x.SetData(dshape.Data());
8187 #endif
8188  basis1d->Eval(ip.x, shape_x, dshape_x);
8189 }
8190 
8192  Vector &dofs) const
8193 {
8194  const int p = Order;
8195  const double *op;
8196 
8197  switch (type)
8198  {
8199  case 0: op = poly1d.OpenPoints(p); break;
8200  case 1:
8201  default: op = poly1d.ClosedPoints(p);
8202  }
8203 
8204  switch (vertex)
8205  {
8206  case 0:
8207  for (int i = 0; i <= p; i++)
8208  {
8209  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8210  }
8211  break;
8212 
8213  case 1:
8214  for (int i = 0; i <= p; i++)
8215  {
8216  dofs(i) = poly1d.CalcDelta(p,op[i]);
8217  }
8218  break;
8219  }
8220 }
8221 
8222 
8224  : PositiveFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk)
8225 {
8226 #ifndef MFEM_THREAD_SAFE
8227  shape_x.SetSize(p + 1);
8228  dshape_x.SetDataAndSize(NULL, p + 1);
8229 #endif
8230 
8231  if (p == 0)
8232  {
8233  Nodes.IntPoint(0).x = 0.5;
8234  }
8235  else
8236  {
8237  for (int i = 0; i <= p; i++)
8238  {
8239  Nodes.IntPoint(i).x = double(i)/p;
8240  }
8241  }
8242 }
8243 
8245  Vector &shape) const
8246 {
8247  Poly_1D::CalcBernstein(Order, ip.x, shape);
8248 }
8249 
8251  DenseMatrix &dshape) const
8252 {
8253 #ifdef MFEM_THREAD_SAFE
8254  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8255 #else
8256  dshape_x.SetData(dshape.Data());
8257 #endif
8258  Poly_1D::CalcBernstein(Order, ip.x, shape_x, dshape_x);
8259 }
8260 
8261 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8262 {
8263  dofs = 0.0;
8264  dofs[vertex*Order] = 1.0;
8265 }
8266 
8267 
8269  : NodalFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
8270  FunctionSpace::Qk)
8271 {
8272  const double *op;
8273 
8274  type = _type;
8275  switch (type)
8276  {
8277  case 0:
8278  basis1d = &poly1d.OpenBasis(p);
8279  op = poly1d.OpenPoints(p);
8280  break;
8281  case 1:
8282  default:
8283  basis1d = &poly1d.ClosedBasis(p);
8284  op = poly1d.ClosedPoints(p);
8285  }
8286 
8287 #ifndef MFEM_THREAD_SAFE
8288  shape_x.SetSize(p + 1);
8289  shape_y.SetSize(p + 1);
8290  dshape_x.SetSize(p + 1);
8291  dshape_y.SetSize(p + 1);
8292 #endif
8293 
8294  for (int o = 0, j = 0; j <= p; j++)
8295  for (int i = 0; i <= p; i++)
8296  {
8297  Nodes.IntPoint(o++).Set2(op[i], op[j]);
8298  }
8299 }
8300 
8302  Vector &shape) const
8303 {
8304  const int p = Order;
8305 
8306 #ifdef MFEM_THREAD_SAFE
8307  Vector shape_x(p+1), shape_y(p+1);
8308 #endif
8309 
8310  basis1d->Eval(ip.x, shape_x);
8311  basis1d->Eval(ip.y, shape_y);
8312 
8313  for (int o = 0, j = 0; j <= p; j++)
8314  for (int i = 0; i <= p; i++)
8315  {
8316  shape(o++) = shape_x(i)*shape_y(j);
8317  }
8318 }
8319 
8321  DenseMatrix &dshape) const
8322 {
8323  const int p = Order;
8324 
8325 #ifdef MFEM_THREAD_SAFE
8326  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8327 #endif
8328 
8329  basis1d->Eval(ip.x, shape_x, dshape_x);
8330  basis1d->Eval(ip.y, shape_y, dshape_y);
8331 
8332  for (int o = 0, j = 0; j <= p; j++)
8333  for (int i = 0; i <= p; i++)
8334  {
8335  dshape(o,0) = dshape_x(i)* shape_y(j);
8336  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8337  }
8338 }
8339 
8340 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
8341 {
8342  const int p = Order;
8343  const double *op;
8344 
8345  switch (type)
8346  {
8347  case 0: op = poly1d.OpenPoints(p); break;
8348  case 1:
8349  default: op = poly1d.ClosedPoints(p);
8350  }
8351 
8352 #ifdef MFEM_THREAD_SAFE
8353  Vector shape_x(p+1), shape_y(p+1);
8354 #endif
8355 
8356  for (int i = 0; i <= p; i++)
8357  {
8358  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8359  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8360  }
8361 
8362  switch (vertex)
8363  {
8364  case 0:
8365  for (int o = 0, j = 0; j <= p; j++)
8366  for (int i = 0; i <= p; i++)
8367  {
8368  dofs[o++] = shape_x(i)*shape_x(j);
8369  }
8370  break;
8371  case 1:
8372  for (int o = 0, j = 0; j <= p; j++)
8373  for (int i = 0; i <= p; i++)
8374  {
8375  dofs[o++] = shape_y(i)*shape_x(j);
8376  }
8377  break;
8378  case 2:
8379  for (int o = 0, j = 0; j <= p; j++)
8380  for (int i = 0; i <= p; i++)
8381  {
8382  dofs[o++] = shape_y(i)*shape_y(j);
8383  }
8384  break;
8385  case 3:
8386  for (int o = 0, j = 0; j <= p; j++)
8387  for (int i = 0; i <= p; i++)
8388  {
8389  dofs[o++] = shape_x(i)*shape_y(j);
8390  }
8391  break;
8392  }
8393 }
8394 
8395 
8397  : PositiveFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
8398  FunctionSpace::Qk)
8399 {
8400 #ifndef MFEM_THREAD_SAFE
8401  shape_x.SetSize(p + 1);
8402  shape_y.SetSize(p + 1);
8403  dshape_x.SetSize(p + 1);
8404  dshape_y.SetSize(p + 1);
8405 #endif
8406 
8407  if (p == 0)
8408  {
8409  Nodes.IntPoint(0).Set2(0.5, 0.5);
8410  }
8411  else
8412  {
8413  for (int o = 0, j = 0; j <= p; j++)
8414  for (int i = 0; i <= p; i++)
8415  {
8416  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8417  }
8418  }
8419 }
8420 
8422  Vector &shape) const
8423 {
8424  const int p = Order;
8425 
8426 #ifdef MFEM_THREAD_SAFE
8427  Vector shape_x(p+1), shape_y(p+1);
8428 #endif
8429 
8430  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8431  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8432 
8433  for (int o = 0, j = 0; j <= p; j++)
8434  for (int i = 0; i <= p; i++)
8435  {
8436  shape(o++) = shape_x(i)*shape_y(j);
8437  }
8438 }
8439 
8441  DenseMatrix &dshape) const
8442 {
8443  const int p = Order;
8444 
8445 #ifdef MFEM_THREAD_SAFE
8446  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8447 #endif
8448 
8449  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8450  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8451 
8452  for (int o = 0, j = 0; j <= p; j++)
8453  for (int i = 0; i <= p; i++)
8454  {
8455  dshape(o,0) = dshape_x(i)* shape_y(j);
8456  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8457  }
8458 }
8459 
8461 {
8462  const int p = Order;
8463 
8464  dofs = 0.0;
8465  switch (vertex)
8466  {
8467  case 0: dofs[0] = 1.0; break;
8468  case 1: dofs[p] = 1.0; break;
8469  case 2: dofs[p*(p + 2)] = 1.0; break;
8470  case 3: dofs[p*(p + 1)] = 1.0; break;
8471  }
8472 }
8473 
8474 
8475 L2_HexahedronElement::L2_HexahedronElement(const int p, const int _type)
8476  : NodalFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
8477  FunctionSpace::Qk)
8478 {
8479  const double *op;
8480 
8481  type = _type;
8482  switch (type)
8483  {
8484  case 0:
8485  basis1d = &poly1d.OpenBasis(p);
8486  op = poly1d.OpenPoints(p);
8487  break;
8488  case 1:
8489  default:
8490  basis1d = &poly1d.ClosedBasis(p);
8491  op = poly1d.ClosedPoints(p);
8492  }
8493 
8494 #ifndef MFEM_THREAD_SAFE
8495  shape_x.SetSize(p + 1);
8496  shape_y.SetSize(p + 1);
8497  shape_z.SetSize(p + 1);
8498  dshape_x.SetSize(p + 1);
8499  dshape_y.SetSize(p + 1);
8500  dshape_z.SetSize(p + 1);
8501 #endif
8502 
8503  for (int o = 0, k = 0; k <= p; k++)
8504  for (int j = 0; j <= p; j++)
8505  for (int i = 0; i <= p; i++)
8506  {
8507  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
8508  }
8509 }
8510 
8512  Vector &shape) const
8513 {
8514  const int p = Order;
8515 
8516 #ifdef MFEM_THREAD_SAFE
8517  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8518 #endif
8519 
8520  basis1d->Eval(ip.x, shape_x);
8521  basis1d->Eval(ip.y, shape_y);
8522  basis1d->Eval(ip.z, shape_z);
8523 
8524  for (int o = 0, k = 0; k <= p; k++)
8525  for (int j = 0; j <= p; j++)
8526  for (int i = 0; i <= p; i++)
8527  {
8528  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8529  }
8530 }
8531 
8533  DenseMatrix &dshape) const
8534 {
8535  const int p = Order;
8536 
8537 #ifdef MFEM_THREAD_SAFE
8538  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8539  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8540 #endif
8541 
8542  basis1d->Eval(ip.x, shape_x, dshape_x);
8543  basis1d->Eval(ip.y, shape_y, dshape_y);
8544  basis1d->Eval(ip.z, shape_z, dshape_z);
8545 
8546  for (int o = 0, k = 0; k <= p; k++)
8547  for (int j = 0; j <= p; j++)
8548  for (int i = 0; i <= p; i++)
8549  {
8550  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8551  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8552  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8553  }
8554 }
8555 
8556 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8557 {
8558  const int p = Order;
8559  const double *op;
8560 
8561  switch (type)
8562  {
8563  case 0: op = poly1d.OpenPoints(p); break;
8564  case 1:
8565  default: op = poly1d.ClosedPoints(p);
8566  }
8567 
8568 #ifdef MFEM_THREAD_SAFE
8569  Vector shape_x(p+1), shape_y(p+1);
8570 #endif
8571 
8572  for (int i = 0; i <= p; i++)
8573  {
8574  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8575  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8576  }
8577 
8578  switch (vertex)
8579  {
8580  case 0:
8581  for (int o = 0, k = 0; k <= p; k++)
8582  for (int j = 0; j <= p; j++)
8583  for (int i = 0; i <= p; i++)
8584  {
8585  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
8586  }
8587  break;
8588  case 1:
8589  for (int o = 0, k = 0; k <= p; k++)
8590  for (int j = 0; j <= p; j++)
8591  for (int i = 0; i <= p; i++)
8592  {
8593  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
8594  }
8595  break;
8596  case 2:
8597  for (int o = 0, k = 0; k <= p; k++)
8598  for (int j = 0; j <= p; j++)
8599  for (int i = 0; i <= p; i++)
8600  {
8601  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
8602  }
8603  break;
8604  case 3:
8605  for (int o = 0, k = 0; k <= p; k++)
8606  for (int j = 0; j <= p; j++)
8607  for (int i = 0; i <= p; i++)
8608  {
8609  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
8610  }
8611  break;
8612  case 4:
8613  for (int o = 0, k = 0; k <= p; k++)
8614  for (int j = 0; j <= p; j++)
8615  for (int i = 0; i <= p; i++)
8616  {
8617  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
8618  }
8619  break;
8620  case 5:
8621  for (int o = 0, k = 0; k <= p; k++)
8622  for (int j = 0; j <= p; j++)
8623  for (int i = 0; i <= p; i++)
8624  {
8625  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
8626  }
8627  break;
8628  case 6:
8629  for (int o = 0, k = 0; k <= p; k++)
8630  for (int j = 0; j <= p; j++)
8631  for (int i = 0; i <= p; i++)
8632  {
8633  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
8634  }
8635  break;
8636  case 7:
8637  for (int o = 0, k = 0; k <= p; k++)
8638  for (int j = 0; j <= p; j++)
8639  for (int i = 0; i <= p; i++)
8640  {
8641  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
8642  }
8643  break;
8644  }
8645 }
8646 
8647 
8649  : PositiveFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
8650  FunctionSpace::Qk)
8651 {
8652 #ifndef MFEM_THREAD_SAFE
8653  shape_x.SetSize(p + 1);
8654  shape_y.SetSize(p + 1);
8655  shape_z.SetSize(p + 1);
8656  dshape_x.SetSize(p + 1);
8657  dshape_y.SetSize(p + 1);
8658  dshape_z.SetSize(p + 1);
8659 #endif
8660 
8661  if (p == 0)
8662  {
8663  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
8664  }
8665  else
8666  {
8667  for (int o = 0, k = 0; k <= p; k++)
8668  for (int j = 0; j <= p; j++)
8669  for (int i = 0; i <= p; i++)
8670  {
8671  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8672  }
8673  }
8674 }
8675 
8677  Vector &shape) const
8678 {
8679  const int p = Order;
8680 
8681 #ifdef MFEM_THREAD_SAFE
8682  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8683 #endif
8684 
8685  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8686  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8687  Poly_1D::CalcBernstein(p, ip.z, shape_z);
8688 
8689  for (int o = 0, k = 0; k <= p; k++)
8690  for (int j = 0; j <= p; j++)
8691  for (int i = 0; i <= p; i++)
8692  {
8693  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8694  }
8695 }
8696 
8698  DenseMatrix &dshape) const
8699 {
8700  const int p = Order;
8701 
8702 #ifdef MFEM_THREAD_SAFE
8703  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8704  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8705 #endif
8706 
8707  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8708  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8709  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
8710 
8711  for (int o = 0, k = 0; k <= p; k++)
8712  for (int j = 0; j <= p; j++)
8713  for (int i = 0; i <= p; i++)
8714  {
8715  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8716  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8717  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8718  }
8719 }
8720 
8721 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8722 {
8723  const int p = Order;
8724 
8725  dofs = 0.0;
8726  switch (vertex)
8727  {
8728  case 0: dofs[0] = 1.0; break;
8729  case 1: dofs[p] = 1.0; break;
8730  case 2: dofs[p*(p + 2)] = 1.0; break;
8731  case 3: dofs[p*(p + 1)] = 1.0; break;
8732  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
8733  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
8734  case 6: dofs[Dof - 1] = 1.0; break;
8735  case 7: dofs[Dof - p - 1] = 1.0; break;
8736  }
8737 }
8738 
8739 
8740 L2_TriangleElement::L2_TriangleElement(const int p, const int _type)
8741  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8742  FunctionSpace::Pk)
8743 {
8744  const double *op;
8745 
8746  type = _type;
8747  switch (type)
8748  {
8749  case 0: op = poly1d.OpenPoints(p); break;
8750  case 1:
8751  default: op = poly1d.ClosedPoints(p);
8752  }
8753 
8754 #ifndef MFEM_THREAD_SAFE
8755  shape_x.SetSize(p + 1);
8756  shape_y.SetSize(p + 1);
8757  shape_l.SetSize(p + 1);
8758  dshape_x.SetSize(p + 1);
8759  dshape_y.SetSize(p + 1);
8760  dshape_l.SetSize(p + 1);
8761  u.SetSize(Dof);
8762  du.SetSize(Dof, Dim);
8763 #else
8764  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8765 #endif
8766 
8767  for (int o = 0, j = 0; j <= p; j++)
8768  for (int i = 0; i + j <= p; i++)
8769  {
8770  double w = op[i] + op[j] + op[p-i-j];
8771  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
8772  }
8773 
8774  DenseMatrix T(Dof);
8775  for (int k = 0; k < Dof; k++)
8776  {
8777  IntegrationPoint &ip = Nodes.IntPoint(k);
8778  poly1d.CalcBasis(p, ip.x, shape_x);
8779  poly1d.CalcBasis(p, ip.y, shape_y);
8780  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8781 
8782  for (int o = 0, j = 0; j <= p; j++)
8783  for (int i = 0; i + j <= p; i++)
8784  {
8785  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8786  }
8787  }
8788 
8789  Ti.Factor(T);
8790  // cout << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
8791 }
8792 
8794  Vector &shape) const
8795 {
8796  const int p = Order;
8797 
8798 #ifdef MFEM_THREAD_SAFE
8799  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
8800 #endif
8801 
8802  poly1d.CalcBasis(p, ip.x, shape_x);
8803  poly1d.CalcBasis(p, ip.y, shape_y);
8804  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8805 
8806  for (int o = 0, j = 0; j <= p; j++)
8807  for (int i = 0; i + j <= p; i++)
8808  {
8809  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8810  }
8811 
8812  Ti.Mult(u, shape);
8813 }
8814 
8816  DenseMatrix &dshape) const
8817 {
8818  const int p = Order;
8819 
8820 #ifdef MFEM_THREAD_SAFE
8821  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8822  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8823  DenseMatrix du(Dof, Dim);
8824 #endif
8825 
8826  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8827  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8828  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
8829 
8830  for (int o = 0, j = 0; j <= p; j++)
8831  for (int i = 0; i + j <= p; i++)
8832  {
8833  int k = p - i - j;
8834  du(o,0) = ((dshape_x(i)* shape_l(k)) -
8835  ( shape_x(i)*dshape_l(k)))*shape_y(j);
8836  du(o,1) = ((dshape_y(j)* shape_l(k)) -
8837  ( shape_y(j)*dshape_l(k)))*shape_x(i);
8838  o++;
8839  }
8840 
8841  Ti.Mult(du, dshape);
8842 }
8843 
8844 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8845 {
8846  switch (vertex)
8847  {
8848  case 0:
8849  for (int i = 0; i < Dof; i++)
8850  {
8851  const IntegrationPoint &ip = Nodes.IntPoint(i);
8852  dofs[i] = pow(1.0 - ip.x - ip.y, Order);
8853  }
8854  break;
8855  case 1:
8856  for (int i = 0; i < Dof; i++)
8857  {
8858  const IntegrationPoint &ip = Nodes.IntPoint(i);
8859  dofs[i] = pow(ip.x, Order);
8860  }
8861  break;
8862  case 2:
8863  for (int i = 0; i < Dof; i++)
8864  {
8865  const IntegrationPoint &ip = Nodes.IntPoint(i);
8866  dofs[i] = pow(ip.y, Order);
8867  }
8868  break;
8869  }
8870 }
8871 
8872 
8874  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8875  FunctionSpace::Pk)
8876 {
8877 #ifndef MFEM_THREAD_SAFE
8878  dshape_1d.SetSize(p + 1);
8879 #endif
8880 
8881  if (p == 0)
8882  {
8883  Nodes.IntPoint(0).Set2(1./3, 1./3);
8884  }
8885  else
8886  {
8887  for (int o = 0, j = 0; j <= p; j++)
8888  for (int i = 0; i + j <= p; i++)
8889  {
8890  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8891  }
8892  }
8893 }
8894 
8896  Vector &shape) const
8897 {
8898  H1Pos_TriangleElement::CalcShape(Order, ip.x, ip.y, shape.GetData());
8899 }
8900 
8902  DenseMatrix &dshape) const
8903 {
8904 #ifdef MFEM_THREAD_SAFE
8905  Vector dshape_1d(Order + 1);
8906 #endif
8907 
8908  H1Pos_TriangleElement::CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(),
8909  dshape.Data());
8910 }
8911 
8912 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8913 {
8914  dofs = 0.0;
8915  switch (vertex)
8916  {
8917  case 0: dofs[0] = 1.0; break;
8918  case 1: dofs[Order] = 1.0; break;
8919  case 2: dofs[Dof-1] = 1.0; break;
8920  }
8921 }
8922 
8923 
8925  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
8926  p, FunctionSpace::Pk)
8927 {
8928  const double *op;
8929 
8930  type = _type;
8931  switch (type)
8932  {
8933  case 0: op = poly1d.OpenPoints(p); break;
8934  case 1:
8935  default: op = poly1d.ClosedPoints(p);
8936  }
8937 
8938 #ifndef MFEM_THREAD_SAFE
8939  shape_x.SetSize(p + 1);
8940  shape_y.SetSize(p + 1);
8941  shape_z.SetSize(p + 1);
8942  shape_l.SetSize(p + 1);
8943  dshape_x.SetSize(p + 1);
8944  dshape_y.SetSize(p + 1);
8945  dshape_z.SetSize(p + 1);
8946  dshape_l.SetSize(p + 1);
8947  u.SetSize(Dof);
8948  du.SetSize(Dof, Dim);
8949 #else
8950  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8951 #endif
8952 
8953  for (int o = 0, k = 0; k <= p; k++)
8954  for (int j = 0; j + k <= p; j++)
8955  for (int i = 0; i + j + k <= p; i++)
8956  {
8957  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
8958  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
8959  }
8960 
8961  DenseMatrix T(Dof);
8962  for (int m = 0; m < Dof; m++)
8963  {
8964  IntegrationPoint &ip = Nodes.IntPoint(m);
8965  poly1d.CalcBasis(p, ip.x, shape_x);
8966  poly1d.CalcBasis(p, ip.y, shape_y);
8967  poly1d.CalcBasis(p, ip.z, shape_z);
8968  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8969 
8970  for (int o = 0, k = 0; k <= p; k++)
8971  for (int j = 0; j + k <= p; j++)
8972  for (int i = 0; i + j + k <= p; i++)
8973  {
8974  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8975  }
8976  }
8977 
8978  Ti.Factor(T);
8979  // cout << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8980 }
8981 
8983  Vector &shape) const
8984 {
8985  const int p = Order;
8986 
8987 #ifdef MFEM_THREAD_SAFE
8988  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8989  Vector u(Dof);
8990 #endif
8991 
8992  poly1d.CalcBasis(p, ip.x, shape_x);
8993  poly1d.CalcBasis(p, ip.y, shape_y);
8994  poly1d.CalcBasis(p, ip.z, shape_z);
8995  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8996 
8997  for (int o = 0, k = 0; k <= p; k++)
8998  for (int j = 0; j + k <= p; j++)
8999  for (int i = 0; i + j + k <= p; i++)
9000  {
9001  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9002  }
9003 
9004  Ti.Mult(u, shape);
9005 }
9006 
9008  DenseMatrix &dshape) const
9009 {
9010  const int p = Order;
9011 
9012 #ifdef MFEM_THREAD_SAFE
9013  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9014  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
9015  DenseMatrix du(Dof, Dim);
9016 #endif
9017 
9018  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9019  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9020  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
9021  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
9022 
9023  for (int o = 0, k = 0; k <= p; k++)
9024  for (int j = 0; j + k <= p; j++)
9025  for (int i = 0; i + j + k <= p; i++)
9026  {
9027  int l = p - i - j - k;
9028  du(o,0) = ((dshape_x(i)* shape_l(l)) -
9029  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
9030  du(o,1) = ((dshape_y(j)* shape_l(l)) -
9031  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
9032  du(o,2) = ((dshape_z(k)* shape_l(l)) -
9033  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
9034  o++;
9035  }
9036 
9037  Ti.Mult(du, dshape);
9038 }
9039 
9040 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9041 {
9042  switch (vertex)
9043  {
9044  case 0:
9045  for (int i = 0; i < Dof; i++)
9046  {
9047  const IntegrationPoint &ip = Nodes.IntPoint(i);
9048  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, Order);
9049  }
9050  break;
9051  case 1:
9052  for (int i = 0; i < Dof; i++)
9053  {
9054  const IntegrationPoint &ip = Nodes.IntPoint(i);
9055  dofs[i] = pow(ip.x, Order);
9056  }
9057  break;
9058  case 2:
9059  for (int i = 0; i < Dof; i++)
9060  {
9061  const IntegrationPoint &ip = Nodes.IntPoint(i);
9062  dofs[i] = pow(ip.y, Order);
9063  }
9064  case 3:
9065  for (int i = 0; i < Dof; i++)
9066  {
9067  const IntegrationPoint &ip = Nodes.IntPoint(i);
9068  dofs[i] = pow(ip.z, Order);
9069  }
9070  break;
9071  }
9072 }
9073 
9074 
9076  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
9077  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
9078 {
9079 #ifndef MFEM_THREAD_SAFE
9080  dshape_1d.SetSize(p + 1);
9081 #endif
9082 
9083  if (p == 0)
9084  {
9085  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
9086  }
9087  else
9088  {
9089  for (int o = 0, k = 0; k <= p; k++)
9090  for (int j = 0; j + k <= p; j++)
9091  for (int i = 0; i + j + k <= p; i++)
9092  {
9093  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
9094  }
9095  }
9096 }
9097 
9099  Vector &shape) const
9100 {
9102  shape.GetData());
9103 }
9104 
9106  DenseMatrix &dshape) const
9107 {
9108 #ifdef MFEM_THREAD_SAFE
9109  Vector dshape_1d(Order + 1);
9110 #endif
9111 
9113  dshape_1d.GetData(), dshape.Data());
9114 }
9115 
9116 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9117 {
9118  dofs = 0.0;
9119  switch (vertex)
9120  {
9121  case 0: dofs[0] = 1.0; break;
9122  case 1: dofs[Order] = 1.0; break;
9123  case 2: dofs[(Order*(Order+3))/2] = 1.0; break;
9124  case 3: dofs[Dof-1] = 1.0; break;
9125  }
9126 }
9127 
9128 
9129 const double RT_QuadrilateralElement::nk[8] =
9130 { 0., -1., 1., 0., 0., 1., -1., 0. };
9131 
9133  : VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p + 1,
9134  H_DIV, FunctionSpace::Qk),
9135  cbasis1d(poly1d.ClosedBasis(p + 1)), obasis1d(poly1d.OpenBasis(p)),
9136  dof_map(Dof), dof2nk(Dof)
9137 {
9138  const double *cp = poly1d.ClosedPoints(p + 1);
9139  const double *op = poly1d.OpenPoints(p);
9140  const int dof2 = Dof/2;
9141 
9142 #ifndef MFEM_THREAD_SAFE
9143  shape_cx.SetSize(p + 2);
9144  shape_ox.SetSize(p + 1);
9145  shape_cy.SetSize(p + 2);
9146  shape_oy.SetSize(p + 1);
9147  dshape_cx.SetSize(p + 2);
9148  dshape_cy.SetSize(p + 2);
9149 #endif
9150 
9151  // edges
9152  int o = 0;
9153  for (int i = 0; i <= p; i++) // (0,1)
9154  {
9155  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
9156  }
9157  for (int i = 0; i <= p; i++) // (1,2)
9158  {
9159  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
9160  }
9161  for (int i = 0; i <= p; i++) // (2,3)
9162  {
9163  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
9164  }
9165  for (int i = 0; i <= p; i++) // (3,0)
9166  {
9167  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
9168  }
9169 
9170  // interior
9171  for (int j = 0; j <= p; j++) // x-components
9172  for (int i = 1; i <= p; i++)
9173  {
9174  dof_map[0*dof2 + i + j*(p + 2)] = o++;
9175  }
9176  for (int j = 1; j <= p; j++) // y-components
9177  for (int i = 0; i <= p; i++)
9178  {
9179  dof_map[1*dof2 + i + j*(p + 1)] = o++;
9180  }
9181 
9182  // dof orientations
9183  // x-components
9184  for (int j = 0; j <= p; j++)
9185  for (int i = 0; i <= p/2; i++)
9186  {
9187  int idx = 0*dof2 + i + j*(p + 2);
9188  dof_map[idx] = -1 - dof_map[idx];
9189  }
9190  if (p%2 == 1)
9191  for (int j = p/2 + 1; j <= p; j++)
9192  {
9193  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
9194  dof_map[idx] = -1 - dof_map[idx];
9195  }
9196  // y-components
9197  for (int j = 0; j <= p/2; j++)
9198  for (int i = 0; i <= p; i++)
9199  {
9200  int idx = 1*dof2 + i + j*(p + 1);
9201  dof_map[idx] = -1 - dof_map[idx];
9202  }
9203  if (p%2 == 1)
9204  for (int i = 0; i <= p/2; i++)
9205  {
9206  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
9207  dof_map[idx] = -1 - dof_map[idx];
9208  }
9209 
9210  o = 0;
9211  for (int j = 0; j <= p; j++)
9212  for (int i = 0; i <= p + 1; i++)
9213  {
9214  int idx;
9215  if ((idx = dof_map[o++]) < 0)
9216  {
9217  idx = -1 - idx;
9218  dof2nk[idx] = 3;
9219  }
9220  else
9221  {
9222  dof2nk[idx] = 1;
9223  }
9224  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
9225  }
9226  for (int j = 0; j <= p + 1; j++)
9227  for (int i = 0; i <= p; i++)
9228  {
9229  int idx;
9230  if ((idx = dof_map[o++]) < 0)
9231  {
9232  idx = -1 - idx;
9233  dof2nk[idx] = 0;
9234  }
9235  else
9236  {
9237  dof2nk[idx] = 2;
9238  }
9239  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
9240  }
9241 }
9242 
9244  DenseMatrix &shape) const
9245 {
9246  const int pp1 = Order;
9247 
9248 #ifdef MFEM_THREAD_SAFE
9249  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9250 #endif
9251 
9252  cbasis1d.Eval(ip.x, shape_cx);
9253  obasis1d.Eval(ip.x, shape_ox);
9254  cbasis1d.Eval(ip.y, shape_cy);
9255  obasis1d.Eval(ip.y, shape_oy);
9256 
9257  int o = 0;
9258  for (int j = 0; j < pp1; j++)
9259  for (int i = 0; i <= pp1; i++)
9260  {
9261  int idx, s;
9262  if ((idx = dof_map[o++]) < 0)
9263  {
9264  idx = -1 - idx, s = -1;
9265  }
9266  else
9267  {
9268  s = +1;
9269  }
9270  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
9271  shape(idx,1) = 0.;
9272  }
9273  for (int j = 0; j <= pp1; j++)
9274  for (int i = 0; i < pp1; i++)
9275  {
9276  int idx, s;
9277  if ((idx = dof_map[o++]) < 0)
9278  {
9279  idx = -1 - idx, s = -1;
9280  }
9281  else
9282  {
9283  s = +1;
9284  }
9285  shape(idx,0) = 0.;
9286  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
9287  }
9288 }
9289 
9291  Vector &divshape) const
9292 {
9293  const int pp1 = Order;
9294 
9295 #ifdef MFEM_THREAD_SAFE
9296  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9297  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
9298 #endif
9299 
9300  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9301  obasis1d.Eval(ip.x, shape_ox);
9302  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9303  obasis1d.Eval(ip.y, shape_oy);
9304 
9305  int o = 0;
9306  for (int j = 0; j < pp1; j++)
9307  for (int i = 0; i <= pp1; i++)
9308  {
9309  int idx, s;
9310  if ((idx = dof_map[o++]) < 0)
9311  {
9312  idx = -1 - idx, s = -1;
9313  }
9314  else
9315  {
9316  s = +1;
9317  }
9318  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
9319  }
9320  for (int j = 0; j <= pp1; j++)
9321  for (int i = 0; i < pp1; i++)
9322  {
9323  int idx, s;
9324  if ((idx = dof_map[o++]) < 0)
9325  {
9326  idx = -1 - idx, s = -1;
9327  }
9328  else
9329  {
9330  s = +1;
9331  }
9332  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
9333  }
9334 }
9335 
9336 
9337 const double RT_HexahedronElement::nk[18] =
9338 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
9339 
9341  : VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 1)*(p + 2), p + 1,
9342  H_DIV, FunctionSpace::Qk),
9343  cbasis1d(poly1d.ClosedBasis(p + 1)), obasis1d(poly1d.OpenBasis(p)),
9344  dof_map(Dof), dof2nk(Dof)
9345 {
9346  const double *cp = poly1d.ClosedPoints(p + 1);
9347  const double *op = poly1d.OpenPoints(p);
9348  const int dof3 = Dof/3;
9349 
9350 #ifndef MFEM_THREAD_SAFE
9351  shape_cx.SetSize(p + 2);
9352  shape_ox.SetSize(p + 1);
9353  shape_cy.SetSize(p + 2);
9354  shape_oy.SetSize(p + 1);
9355  shape_cz.SetSize(p + 2);
9356  shape_oz.SetSize(p + 1);
9357  dshape_cx.SetSize(p + 2);
9358  dshape_cy.SetSize(p + 2);
9359  dshape_cz.SetSize(p + 2);
9360 #endif
9361 
9362  // faces
9363  int o = 0;
9364  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
9365  for (int i = 0; i <= p; i++)
9366  {
9367  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
9368  }
9369  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
9370  for (int i = 0; i <= p; i++)
9371  {
9372  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
9373  }
9374  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
9375  for (int i = 0; i <= p; i++)
9376  {
9377  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
9378  }
9379  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
9380  for (int i = 0; i <= p; i++)
9381  {
9382  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
9383  }
9384  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
9385  for (int i = 0; i <= p; i++)
9386  {
9387  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
9388  }
9389  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
9390  for (int i = 0; i <= p; i++)
9391  {
9392  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
9393  }
9394 
9395  // interior
9396  // x-components
9397  for (int k = 0; k <= p; k++)
9398  for (int j = 0; j <= p; j++)
9399  for (int i = 1; i <= p; i++)
9400  {
9401  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
9402  }
9403  // y-components
9404  for (int k = 0; k <= p; k++)
9405  for (int j = 1; j <= p; j++)
9406  for (int i = 0; i <= p; i++)
9407  {
9408  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
9409  }
9410  // z-components
9411  for (int k = 1; k <= p; k++)
9412  for (int j = 0; j <= p; j++)
9413  for (int i = 0; i <= p; i++)
9414  {
9415  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
9416  }
9417 
9418  // dof orientations
9419  // for odd p, do not change the orientations in the mid-planes
9420  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
9421  // respectively.
9422  // x-components
9423  for (int k = 0; k <= p; k++)
9424  for (int j = 0; j <= p; j++)
9425  for (int i = 0; i <= p/2; i++)
9426  {
9427  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
9428  dof_map[idx] = -1 - dof_map[idx];
9429  }
9430  // y-components
9431  for (int k = 0; k <= p; k++)
9432  for (int j = 0; j <= p/2; j++)
9433  for (int i = 0; i <= p; i++)
9434  {
9435  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
9436  dof_map[idx] = -1 - dof_map[idx];
9437  }
9438  // z-components
9439  for (int k = 0; k <= p/2; k++)
9440  for (int j = 0; j <= p; j++)
9441  for (int i = 0; i <= p; i++)
9442  {
9443  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
9444  dof_map[idx] = -1 - dof_map[idx];
9445  }
9446 
9447  o = 0;
9448  // x-components
9449  for (int k = 0; k <= p; k++)
9450  for (int j = 0; j <= p; j++)
9451  for (int i = 0; i <= p + 1; i++)
9452  {
9453  int idx;
9454  if ((idx = dof_map[o++]) < 0)
9455  {
9456  idx = -1 - idx;
9457  dof2nk[idx] = 4;
9458  }
9459  else
9460  {
9461  dof2nk[idx] = 2;
9462  }
9463  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
9464  }
9465  // y-components
9466  for (int k = 0; k <= p; k++)
9467  for (int j = 0; j <= p + 1; j++)
9468  for (int i = 0; i <= p; i++)
9469  {
9470  int idx;
9471  if ((idx = dof_map[o++]) < 0)
9472  {
9473  idx = -1 - idx;
9474  dof2nk[idx] = 1;
9475  }
9476  else
9477  {
9478  dof2nk[idx] = 3;
9479  }
9480  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
9481  }
9482  // z-components
9483  for (int k = 0; k <= p + 1; k++)
9484  for (int j = 0; j <= p; j++)
9485  for (int i = 0; i <= p; i++)
9486  {
9487  int idx;
9488  if ((idx = dof_map[o++]) < 0)
9489  {
9490  idx = -1 - idx;
9491  dof2nk[idx] = 0;
9492  }
9493  else
9494  {
9495  dof2nk[idx] = 5;
9496  }
9497  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
9498  }
9499 }
9500 
9502  DenseMatrix &shape) const
9503 {
9504  const int pp1 = Order;
9505 
9506 #ifdef MFEM_THREAD_SAFE
9507  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9508  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9509 #endif
9510 
9511  cbasis1d.Eval(ip.x, shape_cx);
9512  obasis1d.Eval(ip.x, shape_ox);
9513  cbasis1d.Eval(ip.y, shape_cy);
9514  obasis1d.Eval(ip.y, shape_oy);
9515  cbasis1d.Eval(ip.z, shape_cz);
9516  obasis1d.Eval(ip.z, shape_oz);
9517 
9518  int o = 0;
9519  // x-components
9520  for (int k = 0; k < pp1; k++)
9521  for (int j = 0; j < pp1; j++)
9522  for (int i = 0; i <= pp1; i++)
9523  {
9524  int idx, s;
9525  if ((idx = dof_map[o++]) < 0)
9526  {
9527  idx = -1 - idx, s = -1;
9528  }
9529  else
9530  {
9531  s = +1;
9532  }
9533  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
9534  shape(idx,1) = 0.;
9535  shape(idx,2) = 0.;
9536  }
9537  // y-components
9538  for (int k = 0; k < pp1; k++)
9539  for (int j = 0; j <= pp1; j++)
9540  for (int i = 0; i < pp1; i++)
9541  {
9542  int idx, s;
9543  if ((idx = dof_map[o++]) < 0)
9544  {
9545  idx = -1 - idx, s = -1;
9546  }
9547  else
9548  {
9549  s = +1;
9550  }
9551  shape(idx,0) = 0.;
9552  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
9553  shape(idx,2) = 0.;
9554  }
9555  // z-components
9556  for (int k = 0; k <= pp1; k++)
9557  for (int j = 0; j < pp1; j++)
9558  for (int i = 0; i < pp1; i++)
9559  {
9560  int idx, s;
9561  if ((idx = dof_map[o++]) < 0)
9562  {
9563  idx = -1 - idx, s = -1;
9564  }
9565  else
9566  {
9567  s = +1;
9568  }
9569  shape(idx,0) = 0.;
9570  shape(idx,1) = 0.;
9571  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
9572  }
9573 }
9574 
9576  Vector &divshape) const
9577 {
9578  const int pp1 = Order;
9579 
9580 #ifdef MFEM_THREAD_SAFE
9581  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9582  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9583  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
9584 #endif
9585 
9586  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9587  obasis1d.Eval(ip.x, shape_ox);
9588  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9589  obasis1d.Eval(ip.y, shape_oy);
9590  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
9591  obasis1d.Eval(ip.z, shape_oz);
9592 
9593  int o = 0;
9594  // x-components
9595  for (int k = 0; k < pp1; k++)
9596  for (int j = 0; j < pp1; j++)
9597  for (int i = 0; i <= pp1; i++)
9598  {
9599  int idx, s;
9600  if ((idx = dof_map[o++]) < 0)
9601  {
9602  idx = -1 - idx, s = -1;
9603  }
9604  else
9605  {
9606  s = +1;
9607  }
9608  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
9609  }
9610  // y-components
9611  for (int k = 0; k < pp1; k++)
9612  for (int j = 0; j <= pp1; j++)
9613  for (int i = 0; i < pp1; i++)
9614  {
9615  int idx, s;
9616  if ((idx = dof_map[o++]) < 0)
9617  {
9618  idx = -1 - idx, s = -1;
9619  }
9620  else
9621  {
9622  s = +1;
9623  }
9624  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
9625  }
9626  // z-components
9627  for (int k = 0; k <= pp1; k++)
9628  for (int j = 0; j < pp1; j++)
9629  for (int i = 0; i < pp1; i++)
9630  {
9631  int idx, s;
9632  if ((idx = dof_map[o++]) < 0)
9633  {
9634  idx = -1 - idx, s = -1;
9635  }
9636  else
9637  {
9638  s = +1;
9639  }
9640  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
9641  }
9642 }
9643 
9644 
9645 const double RT_TriangleElement::nk[6] =
9646 { 0., -1., 1., 1., -1., 0. };
9647 
9648 const double RT_TriangleElement::c = 1./3.;
9649 
9651  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
9652  H_DIV, FunctionSpace::Pk), dof2nk(Dof)
9653 {
9654  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9655  const double *bop = poly1d.OpenPoints(p);
9656 
9657 #ifndef MFEM_THREAD_SAFE
9658  shape_x.SetSize(p + 1);
9659  shape_y.SetSize(p + 1);
9660  shape_l.SetSize(p + 1);
9661  dshape_x.SetSize(p + 1);
9662  dshape_y.SetSize(p + 1);
9663  dshape_l.SetSize(p + 1);
9664  u.SetSize(Dof, Dim);
9665  divu.SetSize(Dof);
9666 #else
9667  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9668 #endif
9669 
9670  // edges
9671  int o = 0;
9672  for (int i = 0; i <= p; i++) // (0,1)
9673  {
9674  Nodes.IntPoint(o).Set2(bop[i], 0.);
9675  dof2nk[o++] = 0;
9676  }
9677  for (int i = 0; i <= p; i++) // (1,2)
9678  {
9679  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
9680  dof2nk[o++] = 1;
9681  }
9682  for (int i = 0; i <= p; i++) // (2,0)
9683  {
9684  Nodes.IntPoint(o).Set2(0., bop[p-i]);
9685  dof2nk[o++] = 2;
9686  }
9687 
9688  // interior
9689  for (int j = 0; j < p; j++)
9690  for (int i = 0; i + j < p; i++)
9691  {
9692  double w = iop[i] + iop[j] + iop[p-1-i-j];
9693  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9694  dof2nk[o++] = 0;
9695  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9696  dof2nk[o++] = 2;
9697  }
9698 
9699  DenseMatrix T(Dof);
9700  for (int k = 0; k < Dof; k++)
9701  {
9702  const IntegrationPoint &ip = Nodes.IntPoint(k);
9703  poly1d.CalcBasis(p, ip.x, shape_x);
9704  poly1d.CalcBasis(p, ip.y, shape_y);
9705  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9706  const double *n_k = nk + 2*dof2nk[k];
9707 
9708  o = 0;
9709  for (int j = 0; j <= p; j++)
9710  for (int i = 0; i + j <= p; i++)
9711  {
9712  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9713  T(o++, k) = s*n_k[0];
9714  T(o++, k) = s*n_k[1];
9715  }
9716  for (int i = 0; i <= p; i++)
9717  {
9718  double s = shape_x(i)*shape_y(p-i);
9719  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
9720  }
9721  }
9722 
9723  Ti.Factor(T);
9724  // cout << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
9725 }
9726 
9728  DenseMatrix &shape) const
9729 {
9730  const int p = Order - 1;
9731 
9732 #ifdef MFEM_THREAD_SAFE
9733  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9734  DenseMatrix u(Dof, Dim);
9735 #endif
9736 
9737  poly1d.CalcBasis(p, ip.x, shape_x);
9738  poly1d.CalcBasis(p, ip.y, shape_y);
9739  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9740 
9741  int o = 0;
9742  for (int j = 0; j <= p; j++)
9743  for (int i = 0; i + j <= p; i++)
9744  {
9745  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9746  u(o,0) = s; u(o,1) = 0; o++;
9747  u(o,0) = 0; u(o,1) = s; o++;
9748  }
9749  for (int i = 0; i <= p; i++)
9750  {
9751  double s = shape_x(i)*shape_y(p-i);
9752  u(o,0) = (ip.x - c)*s;
9753  u(o,1) = (ip.y - c)*s;
9754  o++;
9755  }
9756 
9757  Ti.Mult(u, shape);
9758 }
9759 
9761  Vector &divshape) const
9762 {
9763  const int p = Order - 1;
9764 
9765 #ifdef MFEM_THREAD_SAFE
9766  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9767  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
9768  Vector divu(Dof);
9769 #endif
9770 
9771  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9772  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9773  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
9774 
9775  int o = 0;
9776  for (int j = 0; j <= p; j++)
9777  for (int i = 0; i + j <= p; i++)
9778  {
9779  int k = p - i - j;
9780  divu(o++) = (dshape_x(i)*shape_l(k) -
9781  shape_x(i)*dshape_l(k))*shape_y(j);
9782  divu(o++) = (dshape_y(j)*shape_l(k) -
9783  shape_y(j)*dshape_l(k))*shape_x(i);
9784  }
9785  for (int i = 0; i <= p; i++)
9786  {
9787  int j = p - i;
9788  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
9789  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
9790  }
9791 
9792  Ti.Mult(divu, divshape);
9793 }
9794 
9795 
9796 const double RT_TetrahedronElement::nk[12] =
9797 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
9798 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
9799 
9800 const double RT_TetrahedronElement::c = 1./4.;
9801 
9803  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
9804  p + 1, H_DIV, FunctionSpace::Pk), dof2nk(Dof)
9805 {
9806  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9807  const double *bop = poly1d.OpenPoints(p);
9808 
9809 #ifndef MFEM_THREAD_SAFE
9810  shape_x.SetSize(p + 1);
9811  shape_y.SetSize(p + 1);
9812  shape_z.SetSize(p + 1);
9813  shape_l.SetSize(p + 1);
9814  dshape_x.SetSize(p + 1);
9815  dshape_y.SetSize(p + 1);
9816  dshape_z.SetSize(p + 1);
9817  dshape_l.SetSize(p + 1);
9818  u.SetSize(Dof, Dim);
9819  divu.SetSize(Dof);
9820 #else
9821  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9822 #endif
9823 
9824  int o = 0;
9825  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
9826  // the constructor of H1_TetrahedronElement)
9827  for (int j = 0; j <= p; j++)
9828  for (int i = 0; i + j <= p; i++) // (1,2,3)
9829  {
9830  double w = bop[i] + bop[j] + bop[p-i-j];
9831  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
9832  dof2nk[o++] = 0;
9833  }
9834  for (int j = 0; j <= p; j++)
9835  for (int i = 0; i + j <= p; i++) // (0,3,2)
9836  {
9837  double w = bop[i] + bop[j] + bop[p-i-j];
9838  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
9839  dof2nk[o++] = 1;
9840  }
9841  for (int j = 0; j <= p; j++)
9842  for (int i = 0; i + j <= p; i++) // (0,1,3)
9843  {
9844  double w = bop[i] + bop[j] + bop[p-i-j];
9845  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
9846  dof2nk[o++] = 2;
9847  }
9848  for (int j = 0; j <= p; j++)
9849  for (int i = 0; i + j <= p; i++) // (0,2,1)
9850  {
9851  double w = bop[i] + bop[j] + bop[p-i-j];
9852  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
9853  dof2nk[o++] = 3;
9854  }
9855 
9856  // interior
9857  for (int k = 0; k < p; k++)
9858  for (int j = 0; j + k < p; j++)
9859  for (int i = 0; i + j + k < p; i++)
9860  {
9861  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
9862  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9863  dof2nk[o++] = 1;
9864  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9865  dof2nk[o++] = 2;
9866  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9867  dof2nk[o++] = 3;
9868  }
9869 
9870  DenseMatrix T(Dof);
9871  for (int m = 0; m < Dof; m++)
9872  {
9873  const IntegrationPoint &ip = Nodes.IntPoint(m);
9874  poly1d.CalcBasis(p, ip.x, shape_x);
9875  poly1d.CalcBasis(p, ip.y, shape_y);
9876  poly1d.CalcBasis(p, ip.z, shape_z);
9877  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9878  const double *nm = nk + 3*dof2nk[m];
9879 
9880  o = 0;
9881  for (int k = 0; k <= p; k++)
9882  for (int j = 0; j + k <= p; j++)
9883  for (int i = 0; i + j + k <= p; i++)
9884  {
9885  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9886  T(o++, m) = s * nm[0];
9887  T(o++, m) = s * nm[1];
9888  T(o++, m) = s * nm[2];
9889  }
9890  for (int j = 0; j <= p; j++)
9891  for (int i = 0; i + j <= p; i++)
9892  {
9893  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9894  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
9895  (ip.z - c)*nm[2]);
9896  }
9897  }
9898 
9899  Ti.Factor(T);
9900  // cout << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
9901 }
9902 
9904  DenseMatrix &shape) const
9905 {
9906  const int p = Order - 1;
9907 
9908 #ifdef MFEM_THREAD_SAFE
9909  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9910  DenseMatrix u(Dof, Dim);
9911 #endif
9912 
9913  poly1d.CalcBasis(p, ip.x, shape_x);
9914  poly1d.CalcBasis(p, ip.y, shape_y);
9915  poly1d.CalcBasis(p, ip.z, shape_z);
9916  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9917 
9918  int o = 0;
9919  for (int k = 0; k <= p; k++)
9920  for (int j = 0; j + k <= p; j++)
9921  for (int i = 0; i + j + k <= p; i++)
9922  {
9923  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9924  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
9925  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
9926  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
9927  }
9928  for (int j = 0; j <= p; j++)
9929  for (int i = 0; i + j <= p; i++)
9930  {
9931  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9932  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
9933  o++;
9934  }
9935 
9936  Ti.Mult(u, shape);
9937 }
9938 
9940  Vector &divshape) const
9941 {
9942  const int p = Order - 1;
9943 
9944 #ifdef MFEM_THREAD_SAFE
9945  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9946  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
9947  Vector divu(Dof);
9948 #endif
9949 
9950  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9951  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9952  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
9953  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
9954 
9955  int o = 0;
9956  for (int k = 0; k <= p; k++)
9957  for (int j = 0; j + k <= p; j++)
9958  for (int i = 0; i + j + k <= p; i++)
9959  {
9960  int l = p - i - j - k;
9961  divu(o++) = (dshape_x(i)*shape_l(l) -
9962  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
9963  divu(o++) = (dshape_y(j)*shape_l(l) -
9964  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
9965  divu(o++) = (dshape_z(k)*shape_l(l) -
9966  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
9967  }
9968  for (int j = 0; j <= p; j++)
9969  for (int i = 0; i + j <= p; i++)
9970  {
9971  int k = p - i - j;
9972  divu(o++) =
9973  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
9974  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
9975  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
9976  }
9977 
9978  Ti.Mult(divu, divshape);
9979 }
9980 
9981 
9982 const double ND_HexahedronElement::tk[18] =
9983 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
9984 
9986  : VectorFiniteElement(3, Geometry::CUBE, 3*p*(p + 1)*(p + 1), p,
9987  H_CURL, FunctionSpace::Qk),
9988  cbasis1d(poly1d.ClosedBasis(p)), obasis1d(poly1d.OpenBasis(p - 1)),
9989  dof_map(Dof), dof2tk(Dof)
9990 {
9991  const double *cp = poly1d.ClosedPoints(p);
9992  const double *op = poly1d.OpenPoints(p - 1);
9993  const int dof3 = Dof/3;
9994 
9995 #ifndef MFEM_THREAD_SAFE
9996  shape_cx.SetSize(p + 1);
9997  shape_ox.SetSize(p);
9998  shape_cy.SetSize(p + 1);
9999  shape_oy.SetSize(p);
10000  shape_cz.SetSize(p + 1);
10001  shape_oz.SetSize(p);
10002  dshape_cx.SetSize(p + 1);
10003  dshape_cy.SetSize(p + 1);
10004  dshape_cz.SetSize(p + 1);
10005 #endif
10006 
10007  // edges
10008  int o = 0;
10009  for (int i = 0; i < p; i++) // (0,1)
10010  {
10011  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
10012  }
10013  for (int i = 0; i < p; i++) // (1,2)
10014  {
10015  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
10016  }
10017  for (int i = 0; i < p; i++) // (3,2)
10018  {
10019  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
10020  }
10021  for (int i = 0; i < p; i++) // (0,3)
10022  {
10023  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
10024  }
10025  for (int i = 0; i < p; i++) // (4,5)
10026  {
10027  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
10028  }
10029  for (int i = 0; i < p; i++) // (5,6)
10030  {
10031  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
10032  }
10033  for (int i = 0; i < p; i++) // (7,6)
10034  {
10035  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
10036  }
10037  for (int i = 0; i < p; i++) // (4,7)
10038  {
10039  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
10040  }
10041  for (int i = 0; i < p; i++) // (0,4)
10042  {
10043  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
10044  }
10045  for (int i = 0; i < p; i++) // (1,5)
10046  {
10047  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
10048  }
10049  for (int i = 0; i < p; i++) // (2,6)
10050  {
10051  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
10052  }
10053  for (int i = 0; i < p; i++) // (3,7)
10054  {
10055  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
10056  }
10057 
10058  // faces
10059  // (3,2,1,0) -- bottom
10060  for (int j = 1; j < p; j++) // x - components
10061  for (int i = 0; i < p; i++)
10062  {
10063  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
10064  }
10065  for (int j = 0; j < p; j++) // y - components
10066  for (int i = 1; i < p; i++)
10067  {
10068  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
10069  }
10070  // (0,1,5,4) -- front
10071  for (int k = 1; k < p; k++) // x - components
10072  for (int i = 0; i < p; i++)
10073  {
10074  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
10075  }
10076  for (int k = 0; k < p; k++) // z - components
10077  for (int i = 1; i < p; i++ )
10078  {
10079  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
10080  }
10081  // (1,2,6,5) -- right
10082  for (int k = 1; k < p; k++) // y - components
10083  for (int j = 0; j < p; j++)
10084  {
10085  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
10086  }
10087  for (int k = 0; k < p; k++) // z - components
10088  for (int j = 1; j < p; j++)
10089  {
10090  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
10091  }
10092  // (2,3,7,6) -- back
10093  for (int k = 1; k < p; k++) // x - components
10094  for (int i = 0; i < p; i++)
10095  {
10096  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
10097  }
10098  for (int k = 0; k < p; k++) // z - components
10099  for (int i = 1; i < p; i++)
10100  {
10101  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
10102  }
10103  // (3,0,4,7) -- left
10104  for (int k = 1; k < p; k++) // y - components
10105  for (int j = 0; j < p; j++)
10106  {
10107  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
10108  }
10109  for (int k = 0; k < p; k++) // z - components
10110  for (int j = 1; j < p; j++)
10111  {
10112  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
10113  }
10114  // (4,5,6,7) -- top
10115  for (int j = 1; j < p; j++) // x - components
10116  for (int i = 0; i < p; i++)
10117  {
10118  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
10119  }
10120  for (int j = 0; j < p; j++) // y - components
10121  for (int i = 1; i < p; i++)
10122  {
10123  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
10124  }
10125 
10126  // interior
10127  // x-components
10128  for (int k = 1; k < p; k++)
10129  for (int j = 1; j < p; j++)
10130  for (int i = 0; i < p; i++)
10131  {
10132  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
10133  }
10134  // y-components
10135  for (int k = 1; k < p; k++)
10136  for (int j = 0; j < p; j++)
10137  for (int i = 1; i < p; i++)
10138  {
10139  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
10140  }
10141  // z-components
10142  for (int k = 0; k < p; k++)
10143  for (int j = 1; j < p; j++)
10144  for (int i = 1; i < p; i++)
10145  {
10146  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
10147  }
10148 
10149  // set dof2tk and Nodes
10150  o = 0;
10151  // x-components
10152  for (int k = 0; k <= p; k++)
10153  for (int j = 0; j <= p; j++)
10154  for (int i = 0; i < p; i++)
10155  {
10156  int idx;
10157  if ((idx = dof_map[o++]) < 0)
10158  {
10159  dof2tk[idx = -1 - idx] = 3;
10160  }
10161  else
10162  {
10163  dof2tk[idx] = 0;
10164  }
10165  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
10166  }
10167  // y-components
10168  for (int k = 0; k <= p; k++)
10169  for (int j = 0; j < p; j++)
10170  for (int i = 0; i <= p; i++)
10171  {
10172  int idx;
10173  if ((idx = dof_map[o++]) < 0)
10174  {
10175  dof2tk[idx = -1 - idx] = 4;
10176  }
10177  else
10178  {
10179  dof2tk[idx] = 1;
10180  }
10181  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
10182  }
10183  // z-components
10184  for (int k = 0; k < p; k++)
10185  for (int j = 0; j <= p; j++)
10186  for (int i = 0; i <= p; i++)
10187  {
10188  int idx;
10189  if ((idx = dof_map[o++]) < 0)
10190  {
10191  dof2tk[idx = -1 - idx] = 5;
10192  }
10193  else
10194  {
10195  dof2tk[idx] = 2;
10196  }
10197  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
10198  }
10199 }
10200 
10202  DenseMatrix &shape) const
10203 {
10204  const int p = Order;
10205 
10206 #ifdef MFEM_THREAD_SAFE
10207  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10208  Vector shape_cz(p + 1), shape_oz(p);
10209 #endif
10210 
10211  cbasis1d.Eval(ip.x, shape_cx);
10212  obasis1d.Eval(ip.x, shape_ox);
10213  cbasis1d.Eval(ip.y, shape_cy);
10214  obasis1d.Eval(ip.y, shape_oy);
10215  cbasis1d.Eval(ip.z, shape_cz);
10216  obasis1d.Eval(ip.z, shape_oz);
10217 
10218  int o = 0;
10219  // x-components
10220  for (int k = 0; k <= p; k++)
10221  for (int j = 0; j <= p; j++)
10222  for (int i = 0; i < p; i++)
10223  {
10224  int idx, s;
10225  if ((idx = dof_map[o++]) < 0)
10226  {
10227  idx = -1 - idx, s = -1;
10228  }
10229  else
10230  {
10231  s = +1;
10232  }
10233  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
10234  shape(idx,1) = 0.;
10235  shape(idx,2) = 0.;
10236  }
10237  // y-components
10238  for (int k = 0; k <= p; k++)
10239  for (int j = 0; j < p; j++)
10240  for (int i = 0; i <= p; i++)
10241  {
10242  int idx, s;
10243  if ((idx = dof_map[o++]) < 0)
10244  {
10245  idx = -1 - idx, s = -1;
10246  }
10247  else
10248  {
10249  s = +1;
10250  }
10251  shape(idx,0) = 0.;
10252  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
10253  shape(idx,2) = 0.;
10254  }
10255  // z-components
10256  for (int k = 0; k < p; k++)
10257  for (int j = 0; j <= p; j++)
10258  for (int i = 0; i <= p; i++)
10259  {
10260  int idx, s;
10261  if ((idx = dof_map[o++]) < 0)
10262  {
10263  idx = -1 - idx, s = -1;
10264  }
10265  else
10266  {
10267  s = +1;
10268  }
10269  shape(idx,0) = 0.;
10270  shape(idx,1) = 0.;
10271  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
10272  }
10273 }
10274 
10276  DenseMatrix &curl_shape) const
10277 {
10278  const int p = Order;
10279 
10280 #ifdef MFEM_THREAD_SAFE
10281  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10282  Vector shape_cz(p + 1), shape_oz(p);
10283  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
10284 #endif
10285 
10286  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10287  obasis1d.Eval(ip.x, shape_ox);
10288  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10289  obasis1d.Eval(ip.y, shape_oy);
10290  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
10291  obasis1d.Eval(ip.z, shape_oz);
10292 
10293  int o = 0;
10294  // x-components
10295  for (int k = 0; k <= p; k++)
10296  for (int j = 0; j <= p; j++)
10297  for (int i = 0; i < p; i++)
10298  {
10299  int idx, s;
10300  if ((idx = dof_map[o++]) < 0)
10301  {
10302  idx = -1 - idx, s = -1;
10303  }
10304  else
10305  {
10306  s = +1;
10307  }
10308  curl_shape(idx,0) = 0.;
10309  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
10310  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
10311  }
10312  // y-components
10313  for (int k = 0; k <= p; k++)
10314  for (int j = 0; j < p; j++)
10315  for (int i = 0; i <= p; i++)
10316  {
10317  int idx, s;
10318  if ((idx = dof_map[o++]) < 0)
10319  {
10320  idx = -1 - idx, s = -1;
10321  }
10322  else
10323  {
10324  s = +1;
10325  }
10326  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
10327  curl_shape(idx,1) = 0.;
10328  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
10329  }
10330  // z-components
10331  for (int k = 0; k < p; k++)
10332  for (int j = 0; j <= p; j++)
10333  for (int i = 0; i <= p; i++)
10334  {
10335  int idx, s;
10336  if ((idx = dof_map[o++]) < 0)
10337  {
10338  idx = -1 - idx, s = -1;
10339  }
10340  else
10341  {
10342  s = +1;
10343  }
10344  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
10345  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
10346  curl_shape(idx,2) = 0.;
10347  }
10348 }
10349 
10350 
10351 const double ND_QuadrilateralElement::tk[8] =
10352 { 1.,0., 0.,1., -1.,0., 0.,-1. };
10353 
10355  : VectorFiniteElement(2, Geometry::SQUARE, 2*p*(p + 1), p,
10356  H_CURL, FunctionSpace::Qk),
10357  cbasis1d(poly1d.ClosedBasis(p)), obasis1d(poly1d.OpenBasis(p - 1)),
10358  dof_map(Dof), dof2tk(Dof)
10359 {
10360  const double *cp = poly1d.ClosedPoints(p);
10361  const double *op = poly1d.OpenPoints(p - 1);
10362  const int dof2 = Dof/2;
10363 
10364 #ifndef MFEM_THREAD_SAFE
10365  shape_cx.SetSize(p + 1);
10366  shape_ox.SetSize(p);
10367  shape_cy.SetSize(p + 1);
10368  shape_oy.SetSize(p);
10369  dshape_cx.SetSize(p + 1);
10370  dshape_cy.SetSize(p + 1);
10371 #endif
10372 
10373  // edges
10374  int o = 0;
10375  for (int i = 0; i < p; i++) // (0,1)
10376  {
10377  dof_map[0*dof2 + i + 0*p] = o++;
10378  }
10379  for (int j = 0; j < p; j++) // (1,2)
10380  {
10381  dof_map[1*dof2 + p + j*(p + 1)] = o++;
10382  }
10383  for (int i = 0; i < p; i++) // (2,3)
10384  {
10385  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
10386  }
10387  for (int j = 0; j < p; j++) // (3,0)
10388  {
10389  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
10390  }
10391 
10392  // interior
10393  // x-components
10394  for (int j = 1; j < p; j++)
10395  for (int i = 0; i < p; i++)
10396  {
10397  dof_map[0*dof2 + i + j*p] = o++;
10398  }
10399  // y-components
10400  for (int j = 0; j < p; j++)
10401  for (int i = 1; i < p; i++)
10402  {
10403  dof_map[1*dof2 + i + j*(p + 1)] = o++;
10404  }
10405 
10406  // set dof2tk and Nodes
10407  o = 0;
10408  // x-components
10409  for (int j = 0; j <= p; j++)
10410  for (int i = 0; i < p; i++)
10411  {
10412  int idx;
10413  if ((idx = dof_map[o++]) < 0)
10414  {
10415  dof2tk[idx = -1 - idx] = 2;
10416  }
10417  else
10418  {
10419  dof2tk[idx] = 0;
10420  }
10421  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
10422  }
10423  // y-components
10424  for (int j = 0; j < p; j++)
10425  for (int i = 0; i <= p; i++)
10426  {
10427  int idx;
10428  if ((idx = dof_map[o++]) < 0)
10429  {
10430  dof2tk[idx = -1 - idx] = 3;
10431  }
10432  else
10433  {
10434  dof2tk[idx] = 1;
10435  }
10436  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
10437  }
10438 }
10439 
10441  DenseMatrix &shape) const
10442 {
10443  const int p = Order;
10444 
10445 #ifdef MFEM_THREAD_SAFE
10446  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10447 #endif
10448 
10449  cbasis1d.Eval(ip.x, shape_cx);
10450  obasis1d.Eval(ip.x, shape_ox);
10451  cbasis1d.Eval(ip.y, shape_cy);
10452  obasis1d.Eval(ip.y, shape_oy);
10453 
10454  int o = 0;
10455  // x-components
10456  for (int j = 0; j <= p; j++)
10457  for (int i = 0; i < p; i++)
10458  {
10459  int idx, s;
10460  if ((idx = dof_map[o++]) < 0)
10461  {
10462  idx = -1 - idx, s = -1;
10463  }
10464  else
10465  {
10466  s = +1;
10467  }
10468  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
10469  shape(idx,1) = 0.;
10470  }
10471  // y-components
10472  for (int j = 0; j < p; j++)
10473  for (int i = 0; i <= p; i++)
10474  {
10475  int idx, s;
10476  if ((idx = dof_map[o++]) < 0)
10477  {
10478  idx = -1 - idx, s = -1;
10479  }
10480  else
10481  {
10482  s = +1;
10483  }
10484  shape(idx,0) = 0.;
10485  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
10486  }
10487 }
10488 
10490  DenseMatrix &curl_shape) const
10491 {
10492  const int p = Order;
10493 
10494 #ifdef MFEM_THREAD_SAFE
10495  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10496  Vector dshape_cx(p + 1), dshape_cy(p + 1);
10497 #endif
10498 
10499  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10500  obasis1d.Eval(ip.x, shape_ox);
10501  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10502  obasis1d.Eval(ip.y, shape_oy);
10503 
10504  int o = 0;
10505  // x-components
10506  for (int j = 0; j <= p; j++)
10507  for (int i = 0; i < p; i++)
10508  {
10509  int idx, s;
10510  if ((idx = dof_map[o++]) < 0)
10511  {
10512  idx = -1 - idx, s = -1;
10513  }
10514  else
10515  {
10516  s = +1;
10517  }
10518  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
10519  }
10520  // y-components
10521  for (int j = 0; j < p; j++)
10522  for (int i = 0; i <= p; i++)
10523  {
10524  int idx, s;
10525  if ((idx = dof_map[o++]) < 0)
10526  {
10527  idx = -1 - idx, s = -1;
10528  }
10529  else
10530  {
10531  s = +1;
10532  }
10533  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
10534  }
10535 }
10536 
10537 
10538 const double ND_TetrahedronElement::tk[18] =
10539 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
10540 
10541 const double ND_TetrahedronElement::c = 1./4.;
10542 
10544  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
10545  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
10546 {
10547  const double *eop = poly1d.OpenPoints(p - 1);
10548  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10549  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
10550 
10551  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
10552 
10553 #ifndef MFEM_THREAD_SAFE
10554  shape_x.SetSize(p);
10555  shape_y.SetSize(p);
10556  shape_z.SetSize(p);
10557  shape_l.SetSize(p);
10558  dshape_x.SetSize(p);
10559  dshape_y.SetSize(p);
10560  dshape_z.SetSize(p);
10561  dshape_l.SetSize(p);
10562  u.SetSize(Dof, Dim);
10563 #else
10564  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10565 #endif
10566 
10567  int o = 0;
10568  // edges
10569  for (int i = 0; i < p; i++) // (0,1)
10570  {
10571  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
10572  dof2tk[o++] = 0;
10573  }
10574  for (int i = 0; i < p; i++) // (0,2)
10575  {
10576  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
10577  dof2tk[o++] = 1;
10578  }
10579  for (int i = 0; i < p; i++) // (0,3)
10580  {
10581  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
10582  dof2tk[o++] = 2;
10583  }
10584  for (int i = 0; i < p; i++) // (1,2)
10585  {
10586  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
10587  dof2tk[o++] = 3;
10588  }
10589  for (int i = 0; i < p; i++) // (1,3)
10590  {
10591  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
10592  dof2tk[o++] = 4;
10593  }
10594  for (int i = 0; i < p; i++) // (2,3)
10595  {
10596  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
10597  dof2tk[o++] = 5;
10598  }
10599 
10600  // faces
10601  for (int j = 0; j <= pm2; j++) // (1,2,3)
10602  for (int i = 0; i + j <= pm2; i++)
10603  {
10604  double w = fop[i] + fop[j] + fop[pm2-i-j];
10605  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10606  dof2tk[o++] = 3;
10607  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10608  dof2tk[o++] = 4;
10609  }
10610  for (int j = 0; j <= pm2; j++) // (0,3,2)
10611  for (int i = 0; i + j <= pm2; i++)
10612  {
10613  double w = fop[i] + fop[j] + fop[pm2-i-j];
10614  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10615  dof2tk[o++] = 2;
10616  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10617  dof2tk[o++] = 1;
10618  }
10619  for (int j = 0; j <= pm2; j++) // (0,1,3)
10620  for (int i = 0; i + j <= pm2; i++)
10621  {
10622  double w = fop[i] + fop[j] + fop[pm2-i-j];
10623  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10624  dof2tk[o++] = 0;
10625  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10626  dof2tk[o++] = 2;
10627  }
10628  for (int j = 0; j <= pm2; j++) // (0,2,1)
10629  for (int i = 0; i + j <= pm2; i++)
10630  {
10631  double w = fop[i] + fop[j] + fop[pm2-i-j];
10632  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10633  dof2tk[o++] = 1;
10634  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10635  dof2tk[o++] = 0;
10636  }
10637 
10638  // interior
10639  for (int k = 0; k <= pm3; k++)
10640  for (int j = 0; j + k <= pm3; j++)
10641  for (int i = 0; i + j + k <= pm3; i++)
10642  {
10643  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
10644  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10645  dof2tk[o++] = 0;
10646  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10647  dof2tk[o++] = 1;
10648  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10649  dof2tk[o++] = 2;
10650  }
10651 
10652  DenseMatrix T(Dof);
10653  for (int m = 0; m < Dof; m++)
10654  {
10655  const IntegrationPoint &ip = Nodes.IntPoint(m);
10656  const double *tm = tk + 3*dof2tk[m];
10657  o = 0;
10658 
10659  poly1d.CalcBasis(pm1, ip.x, shape_x);
10660  poly1d.CalcBasis(pm1, ip.y, shape_y);
10661  poly1d.CalcBasis(pm1, ip.z, shape_z);
10662  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10663 
10664  for (int k = 0; k <= pm1; k++)
10665  for (int j = 0; j + k <= pm1; j++)
10666  for (int i = 0; i + j + k <= pm1; i++)
10667  {
10668  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10669  T(o++, m) = s * tm[0];
10670  T(o++, m) = s * tm[1];
10671  T(o++, m) = s * tm[2];
10672  }
10673  for (int k = 0; k <= pm1; k++)
10674  for (int j = 0; j + k <= pm1; j++)
10675  {
10676  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10677  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10678  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
10679  }
10680  for (int k = 0; k <= pm1; k++)
10681  {
10682  T(o++, m) =
10683  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
10684  }
10685  }
10686 
10687  Ti.Factor(T);
10688  // cout << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
10689 }
10690 
10692  DenseMatrix &shape) const
10693 {
10694  const int pm1 = Order - 1;
10695 
10696 #ifdef MFEM_THREAD_SAFE
10697  const int p = Order;
10698  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10699  DenseMatrix u(Dof, Dim);
10700 #endif
10701 
10702  poly1d.CalcBasis(pm1, ip.x, shape_x);
10703  poly1d.CalcBasis(pm1, ip.y, shape_y);
10704  poly1d.CalcBasis(pm1, ip.z, shape_z);
10705  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10706 
10707  int n = 0;
10708  for (int k = 0; k <= pm1; k++)
10709  for (int j = 0; j + k <= pm1; j++)
10710  for (int i = 0; i + j + k <= pm1; i++)
10711  {
10712  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10713  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
10714  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
10715  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
10716  }
10717  for (int k = 0; k <= pm1; k++)
10718  for (int j = 0; j + k <= pm1; j++)
10719  {
10720  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10721  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
10722  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
10723  }
10724  for (int k = 0; k <= pm1; k++)
10725  {
10726  double s = shape_y(pm1-k)*shape_z(k);
10727  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
10728  }
10729 
10730  Ti.Mult(u, shape);
10731 }
10732 
10734  DenseMatrix &curl_shape) const
10735 {
10736  const int pm1 = Order - 1;
10737 
10738 #ifdef MFEM_THREAD_SAFE
10739  const int p = Order;
10740  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10741  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
10742  DenseMatrix u(Dof, Dim);
10743 #endif
10744 
10745  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10746  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10747  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
10748  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10749 
10750  int n = 0;
10751  for (int k = 0; k <= pm1; k++)
10752  for (int j = 0; j + k <= pm1; j++)
10753  for (int i = 0; i + j + k <= pm1; i++)
10754  {
10755  int l = pm1-i-j-k;
10756  const double dx = (dshape_x(i)*shape_l(l) -
10757  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
10758  const double dy = (dshape_y(j)*shape_l(l) -
10759  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
10760  const double dz = (dshape_z(k)*shape_l(l) -
10761  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
10762 
10763  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
10764  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
10765  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
10766  }
10767  for (int k = 0; k <= pm1; k++)
10768  for (int j = 0; j + k <= pm1; j++)
10769  {
10770  int i = pm1 - j - k;
10771  // s = shape_x(i)*shape_y(j)*shape_z(k);
10772  // curl of s*(ip.y - c, -(ip.x - c), 0):
10773  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
10774  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
10775  u(n,2) =
10776  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
10777  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
10778  n++;
10779  // curl of s*(ip.z - c, 0, -(ip.x - c)):
10780  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
10781  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
10782  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
10783  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
10784  n++;
10785  }
10786  for (int k = 0; k <= pm1; k++)
10787  {
10788  int j = pm1 - k;
10789  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
10790  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
10791  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
10792  u(n,1) = 0.;
10793  u(n,2) = 0.; n++;
10794  }
10795 
10796  Ti.Mult(u, curl_shape);
10797 }
10798 
10799 
10800 const double ND_TriangleElement::tk[8] =
10801 { 1.,0., -1.,1., 0.,-1., 0.,1. };
10802 
10803 const double ND_TriangleElement::c = 1./3.;
10804 
10806  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
10807  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
10808 {
10809  const double *eop = poly1d.OpenPoints(p - 1);
10810  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10811 
10812  const int pm1 = p - 1, pm2 = p - 2;
10813 
10814 #ifndef MFEM_THREAD_SAFE
10815  shape_x.SetSize(p);
10816  shape_y.SetSize(p);
10817  shape_l.SetSize(p);
10818  dshape_x.SetSize(p);
10819  dshape_y.SetSize(p);
10820  dshape_l.SetSize(p);
10821  u.SetSize(Dof, Dim);
10822  curlu.SetSize(Dof);
10823 #else
10824  Vector shape_x(p), shape_y(p), shape_l(p);
10825 #endif
10826 
10827  int n = 0;
10828  // edges
10829  for (int i = 0; i < p; i++) // (0,1)
10830  {
10831  Nodes.IntPoint(n).Set2(eop[i], 0.);
10832  dof2tk[n++] = 0;
10833  }
10834  for (int i = 0; i < p; i++) // (1,2)
10835  {
10836  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
10837  dof2tk[n++] = 1;
10838  }
10839  for (int i = 0; i < p; i++) // (2,0)
10840  {
10841  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
10842  dof2tk[n++] = 2;
10843  }
10844 
10845  // interior
10846  for (int j = 0; j <= pm2; j++)
10847  for (int i = 0; i + j <= pm2; i++)
10848  {
10849  double w = iop[i] + iop[j] + iop[pm2-i-j];
10850  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10851  dof2tk[n++] = 0;
10852  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10853  dof2tk[n++] = 3;
10854  }
10855 
10856  DenseMatrix T(Dof);
10857  for (int m = 0; m < Dof; m++)
10858  {
10859  const IntegrationPoint &ip = Nodes.IntPoint(m);
10860  const double *tm = tk + 2*dof2tk[m];
10861  n = 0;
10862 
10863  poly1d.CalcBasis(pm1, ip.x, shape_x);
10864  poly1d.CalcBasis(pm1, ip.y, shape_y);
10865  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10866 
10867  for (int j = 0; j <= pm1; j++)
10868  for (int i = 0; i + j <= pm1; i++)
10869  {
10870  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10871  T(n++, m) = s * tm[0];
10872  T(n++, m) = s * tm[1];
10873  }
10874  for (int j = 0; j <= pm1; j++)
10875  {
10876  T(n++, m) =
10877  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10878  }
10879  }
10880 
10881  Ti.Factor(T);
10882  // cout << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
10883 }
10884 
10886  DenseMatrix &shape) const
10887 {
10888  const int pm1 = Order - 1;
10889 
10890 #ifdef MFEM_THREAD_SAFE
10891  const int p = Order;
10892  Vector shape_x(p), shape_y(p), shape_l(p);
10893  DenseMatrix u(Dof, Dim);
10894 #endif
10895 
10896  poly1d.CalcBasis(pm1, ip.x, shape_x);
10897  poly1d.CalcBasis(pm1, ip.y, shape_y);
10898  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10899 
10900  int n = 0;
10901  for (int j = 0; j <= pm1; j++)
10902  for (int i = 0; i + j <= pm1; i++)
10903  {
10904  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10905  u(n,0) = s; u(n,1) = 0; n++;
10906  u(n,0) = 0; u(n,1) = s; n++;
10907  }
10908  for (int j = 0; j <= pm1; j++)
10909  {
10910  double s = shape_x(pm1-j)*shape_y(j);
10911  u(n,0) = s*(ip.y - c);
10912  u(n,1) = -s*(ip.x - c);
10913  n++;
10914  }
10915 
10916  Ti.Mult(u, shape);
10917 }
10918 
10920  DenseMatrix &curl_shape) const
10921 {
10922  const int pm1 = Order - 1;
10923 
10924 #ifdef MFEM_THREAD_SAFE
10925  const int p = Order;
10926  Vector shape_x(p), shape_y(p), shape_l(p);
10927  Vector dshape_x(p), dshape_y(p), dshape_l(p);
10928  Vector curlu(Dof);
10929 #endif
10930 
10931  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10932  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10933  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
10934 
10935  int n = 0;
10936  for (int j = 0; j <= pm1; j++)
10937  for (int i = 0; i + j <= pm1; i++)
10938  {
10939  int l = pm1-i-j;
10940  const double dx = (dshape_x(i)*shape_l(l) -
10941  shape_x(i)*dshape_l(l)) * shape_y(j);
10942  const double dy = (dshape_y(j)*shape_l(l) -
10943  shape_y(j)*dshape_l(l)) * shape_x(i);
10944 
10945  curlu(n++) = -dy;
10946  curlu(n++) = dx;
10947  }
10948 
10949  for (int j = 0; j <= pm1; j++)
10950  {
10951  int i = pm1 - j;
10952  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
10953  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
10954  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
10955  }
10956 
10957  Vector curl2d(curl_shape.Data(),Dof);
10958  Ti.Mult(curlu, curl2d);
10959 }
10960 
10961 
10962 const double ND_SegmentElement::tk[1] = { 1. };
10963 
10965  : VectorFiniteElement(1, Geometry::SEGMENT, p, p - 1,
10966  H_CURL, FunctionSpace::Pk),
10967  obasis1d(poly1d.OpenBasis(p - 1)), dof2tk(Dof)
10968 {
10969  const double *op = poly1d.OpenPoints(p - 1);
10970 
10971  // set dof2tk and Nodes
10972  for (int i = 0; i < p; i++)
10973  {
10974  dof2tk[i] = 0;
10975  Nodes.IntPoint(i).x = op[i];
10976  }
10977 }
10978 
10980  DenseMatrix &shape) const
10981 {
10982  Vector vshape(shape.Data(), Dof);
10983 
10984  obasis1d.Eval(ip.x, vshape);
10985 }
10986 
10987 
10989  Vector &shape) const
10990 {
10991  kv[0]->CalcShape(shape, ijk[0], ip.x);
10992 
10993  double sum = 0.0;
10994  for (int i = 0; i <= Order; i++)
10995  {
10996  sum += (shape(i) *= weights(i));
10997  }
10998 
10999  shape /= sum;
11000 }
11001 
11003  DenseMatrix &dshape) const
11004 {
11005  Vector grad(dshape.Data(), Dof);
11006 
11007  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
11008  kv[0]->CalcDShape(grad, ijk[0], ip.x);
11009 
11010  double sum = 0.0, dsum = 0.0;
11011  for (int i = 0; i <= Order; i++)
11012  {
11013  sum += (shape_x(i) *= weights(i));
11014  dsum += ( grad(i) *= weights(i));
11015  }
11016 
11017  sum = 1.0/sum;
11018  add(sum, grad, -dsum*sum*sum, shape_x, grad);
11019 }
11020 
11022  Vector &shape) const
11023 {
11024  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
11025  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
11026 
11027  double sum = 0.0;
11028  for (int o = 0, j = 0; j <= Order; j++)
11029  {
11030  const double sy = shape_y(j);
11031  for (int i = 0; i <= Order; i++, o++)
11032  {
11033  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
11034  }
11035  }
11036 
11037  shape /= sum;
11038 }
11039 
11041  DenseMatrix &dshape) const
11042 {
11043  double sum, dsum[2];
11044 
11045  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
11046  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
11047 
11048  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
11049  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
11050 
11051  sum = dsum[0] = dsum[1] = 0.0;
11052  for (int o = 0, j = 0; j <= Order; j++)
11053  {
11054  const double sy = shape_y(j), dsy = dshape_y(j);
11055  for (int i = 0; i <= Order; i++, o++)
11056  {
11057  sum += ( u(o) = shape_x(i)*sy*weights(o) );
11058 
11059  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
11060  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
11061  }
11062  }
11063 
11064  sum = 1.0/sum;
11065  dsum[0] *= sum*sum;
11066  dsum[1] *= sum*sum;
11067 
11068  for (int o = 0; o < Dof; o++)
11069  {
11070  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11071  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11072  }
11073 }
11074 
11076  Vector &shape) const
11077 {
11078  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
11079  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
11080  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
11081 
11082  double sum = 0.0;
11083  for (int o = 0, k = 0; k <= Order; k++)
11084  {
11085  const double sz = shape_z(k);
11086  for (int j = 0; j <= Order; j++)
11087  {
11088  const double sy_sz = shape_y(j)*sz;
11089  for (int i = 0; i <= Order; i++, o++)
11090  {
11091  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
11092  }
11093  }
11094  }
11095 
11096  shape /= sum;
11097 }
11098 
11100  DenseMatrix &dshape) const
11101 {
11102  double sum, dsum[3];
11103 
11104  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
11105  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
11106  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
11107 
11108  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
11109  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
11110  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
11111 
11112  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
11113  for (int o = 0, k = 0; k <= Order; k++)
11114  {
11115  const double sz = shape_z(k), dsz = dshape_z(k);
11116  for (int j = 0; j <= Order; j++)
11117  {
11118  const double sy_sz = shape_y(j)* sz;
11119  const double dsy_sz = dshape_y(j)* sz;
11120  const double sy_dsz = shape_y(j)*dsz;
11121  for (int i = 0; i <= Order; i++, o++)
11122  {
11123  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
11124 
11125  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
11126  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
11127  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
11128  }
11129  }
11130  }
11131 
11132  sum = 1.0/sum;
11133  dsum[0] *= sum*sum;
11134  dsum[1] *= sum*sum;
11135  dsum[2] *= sum*sum;
11136 
11137  for (int o = 0; o < Dof; o++)
11138  {
11139  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11140  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11141  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
11142  }
11143 }
11144 
11145 }
Abstract class for Finite Elements.
Definition: fe.hpp:44
RefinedLinear3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:4073
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1189
void Set(const double *p, const int dim)
Definition: intrules.hpp:32
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8301
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
Definition: densemat.cpp:3218
int Size() const
Logical size of the array.
Definition: array.hpp:109
RT_QuadrilateralElement(const int p)
Definition: fe.cpp:9132
DenseMatrix curlshape_J
Definition: fe.hpp:280
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5872
int GetDim() const
Returns the space dimension for the finite element.
Definition: fe.hpp:82
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7171
L2_TetrahedronElement(const int p, const int _type=0)
Definition: fe.cpp:8924
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2714
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3651
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:937
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8721
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:11040
Linear3DFiniteElement()
Construct a linear FE on tetrahedron.
Definition: fe.cpp:2112
static double CalcDelta(const int p, const double x)
Definition: fe.hpp:1279
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2896
H1_HexahedronElement(const int p)
Definition: fe.cpp:6851
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8460
int NumCols() const
Definition: array.hpp:267
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:9903
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:30
RefinedBiLinear2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4305
ND_QuadrilateralElement(const int p)
Definition: fe.cpp:10354
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1507
L2Pos_TriangleElement(const int p)
Definition: fe.cpp:8873
H1Pos_SegmentElement(const int p)
Definition: fe.cpp:7109
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:116
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:4917
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:75
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2350
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2129
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8912
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:2668
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2948
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1303
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7151
L2Pos_TetrahedronElement(const int p)
Definition: fe.cpp:9075
Array< KnotVector * > kv
Definition: fe.hpp:2058
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:372
void SetSize(int s)
Resize the vector if the new size is different.
Definition: vector.hpp:263
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:9290
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:4979
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3438
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:858
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:177
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1327
void LocalInterpolation_ND(const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:687
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1685
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1596
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:2433
static void UniformPoints(const int p, double *x)
Definition: fe.cpp:6150
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:451
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
evaluate derivatives of shape function - constant 0
Definition: fe.cpp:2083
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols.
Definition: operator.hpp:41
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:747
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6679
H1Pos_TetrahedronElement(const int p)
Definition: fe.cpp:7893
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:10988
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8320
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
Definition: densemat.cpp:271
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:35
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
Definition: densemat.cpp:2904
LagrangeHexFiniteElement(int degree)
Definition: fe.cpp:3703
int GetOrder() const
Returns the order of the finite element.
Definition: fe.hpp:91
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:2446
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3559
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3865
Data type dense matrix using column-major storage.
Definition: densemat.hpp:22
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3513
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:259
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:11002
Basis & OpenBasis(const int p)
Definition: fe.cpp:6548
const double * ClosedPoints(const int p)
Definition: fe.cpp:6523
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:9760
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5145
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:509
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2098
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1756
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:69
RefinedTriLinear3DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4452
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3690
Quadratic3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:2168
int GetMapType() const
Definition: fe.hpp:98
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8174
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:5495
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5682
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:3886
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:2545
const IntegrationPoint & GetIntPoint()
Definition: eltrans.hpp:37
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9040
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1808
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:9105
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2375
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2367
const IntegrationPoint & GetCenter(int GeomType)
Definition: geom.hpp:57
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8244
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:6763
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:547
H1Pos_HexahedronElement(const int p)
Definition: fe.cpp:7281
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:100
double * GetData() const
Definition: vector.hpp:90
static void CalcShape(const int p, const double x, const double y, const double z, double *shape)
Definition: fe.cpp:7995
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8982
RT_HexahedronElement(const int p)
Definition: fe.cpp:9340
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:819
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7253
Linear2DFiniteElement()
Construct a linear FE on triangle.
Definition: fe.cpp:761
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2225
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5817
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:259
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4641
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10885
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:728
L2_SegmentElement(const int p, const int _type=0)
Definition: fe.cpp:8145
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1828
L2Pos_HexahedronElement(const int p)
Definition: fe.cpp:8648
ND_TriangleElement(const int p)
Definition: fe.cpp:10805
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:9939
static void CalcDShape(const int p, const double x, const double y, const double z, double *dshape_1d, double *dshape)
Definition: fe.cpp:8028
static void CalcBasis(const int p, const double x, double *u)
Definition: fe.hpp:1263
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
evaluate shape function - constant 1
Definition: fe.cpp:2077
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1856
static void CalcBinomTerms(const int p, const double x, const double y, double *u)
Compute the terms in the expansion of the binomial (x + y)^p.
Definition: fe.cpp:6333
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:63
H1Pos_TriangleElement(const int p)
Definition: fe.cpp:7748
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:3150
Cubic3DFiniteElement()
Construct a cubic FE on tetrahedron.
Definition: fe.cpp:1903
Linear1DFiniteElement()
Construct a linear FE on interval.
Definition: fe.cpp:740
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4014
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:5805
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1376
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:3919
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:108
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:994
static void CalcShape(const int p, const double x, const double y, double *shape)
Definition: fe.cpp:7803
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2399
void SetSize(int m, int n)
Definition: array.hpp:264
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1996
Geometry Geometries
Definition: geom.cpp:544
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:231
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3456
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:488
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Definition: densemat.cpp:193
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:2976
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8180
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:954
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:965
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1213
ND_SegmentElement(const int p)
Definition: fe.cpp:10964
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
Definition: operator.hpp:35
H1_TriangleElement(const int p)
Definition: fe.cpp:7459
RefinedLinear1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:3903
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7024
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7274
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1480
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8815
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7526
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3930
void LocalInterpolation_RT(const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:651
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:3089
static void ChebyshevPoints(const int p, double *x)
Definition: fe.cpp:6301
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5942
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3675
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:5783
ND_TetrahedronElement(const int p)
Definition: fe.cpp:10543
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8901
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:734
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1771
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:566
const IntegrationRule & GetNodes() const
Definition: fe.hpp:113
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5032
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1035
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8556
DenseMatrix vshape
Definition: fe.hpp:280
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2203
L2Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:8396
P0SegmentFiniteElement(int Ord=0)
Definition: fe.cpp:2338
static void CalcDShape(const int p, const double x, const double y, double *dshape_1d, double *dshape)
Definition: fe.cpp:7829
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:2691
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:11075
DenseMatrix curlshape
Definition: fe.hpp:280
void Set2(const double x1, const double x2)
Definition: intrules.hpp:73
virtual double Weight()=0
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:9501
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:5083
int GetVDim()
Returns dimension of the vector.
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8793
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:9243
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1635
void SetData(double *d)
Definition: vector.hpp:69
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:3348
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:810
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2138
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:9575
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7689
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1059
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1137
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:630
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8895
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3012
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:11099
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1151
DenseMatrix m_dshape
Definition: fe.hpp:1466
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:10489
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8421
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:63
ND_HexahedronElement(const int p)
Definition: fe.cpp:9985
IntegrationRule Nodes
Definition: fe.hpp:48
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1021
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8676
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7131
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7452
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3400
double * Data() const
Returns vector of the elements.
Definition: densemat.hpp:77
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:10919
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:2560
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4328
H1_QuadrilateralElement(const int p)
Definition: fe.cpp:6707
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2457
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:385
DenseMatrix Jinv
Definition: fe.hpp:279
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8191
int GetDof() const
Returns the degrees of freedom in the FE space.
Definition: fe.hpp:88
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7714
Base class Coefficient that may optionally depend on time.
Definition: coefficient.hpp:31
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:905
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:5113
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:9098
void mfem_error(const char *msg)
Definition: error.cpp:23
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:331
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:772
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4498
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4195
static const int * Binom(const int p)
Definition: fe.cpp:6133
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:3250
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:44
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:840
static void GaussLobattoPoints(const int p, double *x)
Definition: fe.cpp:6225
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:9007
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10201
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2624
void SetDataAndSize(double *d, int s)
Definition: vector.hpp:71
FiniteElement(int D, int G, int Do, int O, int F=FunctionSpace::Pk)
Definition: fe.cpp:22
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1262
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2283
Quad1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:946
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7407
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:58
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:894
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:801
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:51
H1Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:7178
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:754
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8844
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7428
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8250
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2104
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8697
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:404
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:6979
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:929
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:3064
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10691
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:2824
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10440
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:288
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2572
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:531
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8261
RefinedLinear2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:3949
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const NodalFiniteElement &fine_fe) const
Definition: fe.cpp:125
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5737
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:158
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3911
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3639
Array< int > dof_map
Definition: fe.hpp:1468
RT_TetrahedronElement(const int p)
Definition: fe.cpp:9802
L2_TriangleElement(const int p, const int _type=0)
Definition: fe.cpp:8740
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5293
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3844
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:6660
H1_TetrahedronElement(const int p)
Definition: fe.cpp:7578
BiQuad2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:1166
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:2158
Basis & ClosedBasis(const int p)
Definition: fe.cpp:6571
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:2861
P0TriangleFiniteElement()
Construct P0 triangle finite element.
Definition: fe.cpp:2070
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2344
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
RT_TriangleElement(const int p)
Definition: fe.cpp:9650
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:6641
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10979
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:10275
void Eval(const double x, Vector &u) const
Definition: fe.cpp:6023
L2Pos_SegmentElement(const int p)
Definition: fe.cpp:8223
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4108
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5348
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
Definition: densemat.cpp:3398
Vector data type.
Definition: vector.hpp:33
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:5279
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:142
static void CalcBernstein(const int p, const double x, double *u)
Definition: fe.hpp:1298
virtual void Transform(const IntegrationPoint &, Vector &)=0
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7233
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8532
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1087
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:9727
Quad2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:1004
virtual int GetSpaceDim()=0
Describes the space on each element.
Definition: fe.hpp:27
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2299
const double * OpenPoints(const int p)
Definition: fe.cpp:6498
virtual const DenseMatrix & Jacobian()=0
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5198
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8440
static void GaussPoints(const int p, double *x)
Definition: fe.cpp:6165
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:10733
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3696
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:1405
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:780
H1_SegmentElement(const int p)
Definition: fe.cpp:6618
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1968
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2410
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:71
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6802
L2_HexahedronElement(const int p, const int _type=0)
Definition: fe.cpp:8475
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:5249
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3468
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4379
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:11021
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:566
int GetRangeType() const
Definition: fe.hpp:96
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:883
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2766
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3669
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7000
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:6782
Basis(const int p, const double *nodes, const int _mode=1)
Definition: fe.cpp:5977
static void CalcDBinomTerms(const int p, const double x, const double y, double *d)
Definition: fe.cpp:6397
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:4862
TriLinear3DFiniteElement()
Construct a tri-linear FE on cube.
Definition: fe.cpp:2247
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:87
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:984
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8511
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3966
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3429
BiLinear2DFiniteElement()
Construct a bilinear FE on quadrilateral.
Definition: fe.cpp:788
Poly_1D poly1d
Definition: fe.cpp:6614
L2_QuadrilateralElement(const int p, const int _type=0)
Definition: fe.cpp:8268
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5925
Lagrange1DFiniteElement(int degree)
Definition: fe.cpp:3481
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2509
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:5618
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9116
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8340
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:850
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7548
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:482
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:320