MFEM  v4.1.0
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-2020, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 // Finite Element classes
13 
14 #include "fe.hpp"
15 #include "fe_coll.hpp"
16 #include "../mesh/nurbs.hpp"
17 #include "bilininteg.hpp"
18 #include <cmath>
19 
20 namespace mfem
21 {
22 
23 using namespace std;
24 
25 FiniteElement::FiniteElement(int D, Geometry::Type G, int Do, int O, int F)
26  : Nodes(Do)
27 {
28  Dim = D ; GeomType = G ; Dof = Do ; Order = O ; FuncSpace = F;
29  RangeType = SCALAR;
30  MapType = VALUE;
31  DerivType = NONE;
34  for (int i = 0; i < Geometry::MaxDim; i++) { Orders[i] = -1; }
35 #ifndef MFEM_THREAD_SAFE
37 #endif
38 }
39 
41  const IntegrationPoint &ip, DenseMatrix &shape) const
42 {
43  mfem_error ("FiniteElement::CalcVShape (ip, ...)\n"
44  " is not implemented for this class!");
45 }
46 
49 {
50  mfem_error ("FiniteElement::CalcVShape (trans, ...)\n"
51  " is not implemented for this class!");
52 }
53 
55  const IntegrationPoint &ip, Vector &divshape) const
56 {
57  mfem_error ("FiniteElement::CalcDivShape (ip, ...)\n"
58  " is not implemented for this class!");
59 }
60 
62  ElementTransformation &Trans, Vector &div_shape) const
63 {
64  CalcDivShape(Trans.GetIntPoint(), div_shape);
65  div_shape *= (1.0 / Trans.Weight());
66 }
67 
69  DenseMatrix &curl_shape) const
70 {
71  mfem_error ("FiniteElement::CalcCurlShape (ip, ...)\n"
72  " is not implemented for this class!");
73 }
74 
76  DenseMatrix &curl_shape) const
77 {
78  switch (Dim)
79  {
80  case 3:
81  {
82 #ifdef MFEM_THREAD_SAFE
84 #endif
86  MultABt(vshape, Trans.Jacobian(), curl_shape);
87  curl_shape *= (1.0 / Trans.Weight());
88  break;
89  }
90  case 2:
91  // This is valid for both 2x2 and 3x2 Jacobians
92  CalcCurlShape(Trans.GetIntPoint(), curl_shape);
93  curl_shape *= (1.0 / Trans.Weight());
94  break;
95  default:
96  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
97  }
98 }
99 
100 void FiniteElement::GetFaceDofs(int face, int **dofs, int *ndofs) const
101 {
102  mfem_error ("FiniteElement::GetFaceDofs (...)");
103 }
104 
106  DenseMatrix &h) const
107 {
108  mfem_error ("FiniteElement::CalcHessian (...) is not overloaded !");
109 }
110 
112  DenseMatrix &I) const
113 {
114  mfem_error ("GetLocalInterpolation (...) is not overloaded !");
115 }
116 
118  DenseMatrix &) const
119 {
120  mfem_error("FiniteElement::GetLocalRestriction() is not overloaded !");
121 }
122 
125  DenseMatrix &I) const
126 {
127  MFEM_ABORT("method is not overloaded !");
128 }
129 
131  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
132 {
133  mfem_error ("FiniteElement::Project (...) is not overloaded !");
134 }
135 
138 {
139  mfem_error ("FiniteElement::Project (...) (vector) is not overloaded !");
140 }
141 
143  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
144 {
145  mfem_error("FiniteElement::ProjectMatrixCoefficient() is not overloaded !");
146 }
147 
148 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
149 {
150  mfem_error("FiniteElement::ProjectDelta(...) is not implemented for "
151  "this element!");
152 }
153 
156 {
157  mfem_error("FiniteElement::Project(...) (fe version) is not implemented "
158  "for this element!");
159 }
160 
163  DenseMatrix &grad) const
164 {
165  mfem_error("FiniteElement::ProjectGrad(...) is not implemented for "
166  "this element!");
167 }
168 
171  DenseMatrix &curl) const
172 {
173  mfem_error("FiniteElement::ProjectCurl(...) is not implemented for "
174  "this element!");
175 }
176 
179  DenseMatrix &div) const
180 {
181  mfem_error("FiniteElement::ProjectDiv(...) is not implemented for "
182  "this element!");
183 }
184 
186  Vector &shape) const
187 {
188  CalcShape(Trans.GetIntPoint(), shape);
189  if (MapType == INTEGRAL)
190  {
191  shape /= Trans.Weight();
192  }
193 }
194 
196  DenseMatrix &dshape) const
197 {
198  MFEM_ASSERT(MapType == VALUE, "");
199 #ifdef MFEM_THREAD_SAFE
201 #endif
202  CalcDShape(Trans.GetIntPoint(), vshape);
203  Mult(vshape, Trans.InverseJacobian(), dshape);
204 }
205 
207  Vector &Laplacian) const
208 {
209  MFEM_ASSERT(MapType == VALUE, "");
210 
211  // Simpler routine if mapping is affine
212  if (Trans.Hessian().FNorm2() < 1e-20)
213  {
214  CalcPhysLinLaplacian(Trans, Laplacian);
215  return;
216  }
217 
218  // Compute full Hessian first if non-affine
219  int size = (Dim*(Dim+1))/2;
220  DenseMatrix hess(Dof, size);
221  CalcPhysHessian(Trans,hess);
222 
223  if (Dim == 3)
224  {
225  for (int nd = 0; nd < Dof; nd++)
226  {
227  Laplacian[nd] = hess(nd,0) + hess(nd,4) + hess(nd,5);
228  }
229  }
230  else if (Dim == 2)
231  {
232  for (int nd = 0; nd < Dof; nd++)
233  {
234  Laplacian[nd] = hess(nd,0) + hess(nd,2);
235  }
236  }
237  else
238  {
239  for (int nd = 0; nd < Dof; nd++)
240  {
241  Laplacian[nd] = hess(nd,0);
242  }
243  }
244 }
245 
246 
247 // Assume a linear mapping
249  Vector &Laplacian) const
250 {
251  MFEM_ASSERT(MapType == VALUE, "");
252  int size = (Dim*(Dim+1))/2;
253  DenseMatrix hess(Dof, size);
254  DenseMatrix Gij(Dim,Dim);
255  Vector scale(size);
256 
257  CalcHessian (Trans.GetIntPoint(), hess);
258  MultAAt(Trans.InverseJacobian(), Gij);
259 
260  if (Dim == 3)
261  {
262  scale[0] = Gij(0,0);
263  scale[1] = 2*Gij(0,1);
264  scale[2] = 2*Gij(0,2);
265 
266  scale[3] = 2*Gij(1,2);
267  scale[4] = Gij(2,2);
268 
269  scale[5] = Gij(1,1);
270  }
271  else if (Dim == 2)
272  {
273  scale[0] = Gij(0,0);
274  scale[1] = 2*Gij(0,1);
275  scale[2] = Gij(1,1);
276  }
277  else
278  {
279  scale[0] = Gij(0,0);
280  }
281 
282  for (int nd = 0; nd < Dof; nd++)
283  {
284  Laplacian[nd] = 0.0;
285  for (int ii = 0; ii < size; ii++)
286  {
287  Laplacian[nd] += hess(nd,ii)*scale[ii];
288  }
289  }
290 
291 }
292 
294  DenseMatrix& Hessian) const
295 {
296  MFEM_ASSERT(MapType == VALUE, "");
297 
298  // Roll 2-Tensors in vectors and 4-Tensor in Matrix, exploiting symmetry
299  Array<int> map(Dim*Dim);
300  if (Dim == 3)
301  {
302  map[0] = 0;
303  map[1] = 1;
304  map[2] = 2;
305 
306  map[3] = 1;
307  map[4] = 5;
308  map[5] = 3;
309 
310  map[6] = 2;
311  map[7] = 3;
312  map[8] = 4;
313  }
314  else if (Dim == 2)
315  {
316  map[0] = 0;
317  map[1] = 1;
318 
319  map[2] = 1;
320  map[3] = 2;
321  }
322  else
323  {
324  map[0] = 0;
325  }
326 
327  // Hessian in ref coords
328  int size = (Dim*(Dim+1))/2;
329  DenseMatrix hess(Dof, size);
330  CalcHessian(Trans.GetIntPoint(), hess);
331 
332  // Gradient in physical coords
333  if (Trans.Hessian().FNorm2() > 1e-10)
334  {
335  DenseMatrix grad(Dof, Dim);
336  CalcPhysDShape(Trans, grad);
337  DenseMatrix gmap(Dof, size);
338  Mult(grad,Trans.Hessian(),gmap);
339  hess -= gmap;
340  }
341 
342  // LHM
343  DenseMatrix lhm(size,size);
344  DenseMatrix invJ = Trans.Jacobian();
345  lhm = 0.0;
346  for (int i = 0; i < Dim; i++)
347  {
348  for (int j = 0; j < Dim; j++)
349  {
350  for (int k = 0; k < Dim; k++)
351  {
352  for (int l = 0; l < Dim; l++)
353  {
354  lhm(map[i*Dim+j],map[k*Dim+l]) += invJ(i,k)*invJ(j,l);
355  }
356  }
357  }
358  }
359  // Correct multiplicity
360  Vector mult(size);
361  mult = 0.0;
362  for (int i = 0; i < Dim*Dim; i++) { mult[map[i]]++; }
363  lhm.InvRightScaling(mult);
364 
365  // Hessian in physical coords
366  lhm.Invert();
367  Mult( hess, lhm, Hessian);
368 }
369 
371  DofToQuad::Mode) const
372 {
373  mfem_error("FiniteElement::GetDofToQuad(...) is not implemented for "
374  "this element!");
375  return *dof2quad_array[0]; // suppress a warning
376 }
377 
379 {
380  for (int i = 0; i < dof2quad_array.Size(); i++)
381  {
382  delete dof2quad_array[i];
383  }
384 }
385 
386 
389  const ScalarFiniteElement &fine_fe) const
390 {
391  double v[Geometry::MaxDim];
392  Vector vv (v, Dim);
393  IntegrationPoint f_ip;
394 
395 #ifdef MFEM_THREAD_SAFE
396  Vector c_shape(Dof);
397 #endif
398 
399  MFEM_ASSERT(MapType == fine_fe.GetMapType(), "");
400 
401  I.SetSize(fine_fe.Dof, Dof);
402  for (int i = 0; i < fine_fe.Dof; i++)
403  {
404  Trans.Transform(fine_fe.Nodes.IntPoint(i), vv);
405  f_ip.Set(v, Dim);
406  CalcShape(f_ip, c_shape);
407  for (int j = 0; j < Dof; j++)
408  if (fabs(I(i,j) = c_shape(j)) < 1.0e-12)
409  {
410  I(i,j) = 0.0;
411  }
412  }
413  if (MapType == INTEGRAL)
414  {
415  // assuming Trans is linear; this should be ok for all refinement types
417  I *= Trans.Weight();
418  }
419 }
420 
423  const ScalarFiniteElement &fine_fe) const
424 {
425  // General "interpolation", defined by L2 projection
426 
427  double v[Geometry::MaxDim];
428  Vector vv (v, Dim);
429  IntegrationPoint f_ip;
430 
431  const int fs = fine_fe.GetDof(), cs = this->GetDof();
432  I.SetSize(fs, cs);
433  Vector fine_shape(fs), coarse_shape(cs);
434  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
435  const int ir_order = GetOrder() + fine_fe.GetOrder();
436  const IntegrationRule &ir = IntRules.Get(fine_fe.GetGeomType(), ir_order);
437 
438  for (int i = 0; i < ir.GetNPoints(); i++)
439  {
440  const IntegrationPoint &ip = ir.IntPoint(i);
441  fine_fe.CalcShape(ip, fine_shape);
442  Trans.Transform(ip, vv);
443  f_ip.Set(v, Dim);
444  this->CalcShape(f_ip, coarse_shape);
445 
446  AddMult_a_VVt(ip.weight, fine_shape, fine_mass);
447  AddMult_a_VWt(ip.weight, fine_shape, coarse_shape, fine_coarse_mass);
448  }
449 
450  DenseMatrixInverse fine_mass_inv(fine_mass);
451  fine_mass_inv.Mult(fine_coarse_mass, I);
452 
453  if (MapType == INTEGRAL)
454  {
455  // assuming Trans is linear; this should be ok for all refinement types
457  I *= Trans.Weight();
458  }
459 }
460 
462  DofToQuad::Mode mode) const
463 {
464  MFEM_VERIFY(mode == DofToQuad::FULL, "invalid mode requested");
465 
466  for (int i = 0; i < dof2quad_array.Size(); i++)
467  {
468  const DofToQuad &d2q = *dof2quad_array[i];
469  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
470  }
471 
472  DofToQuad *d2q = new DofToQuad;
473  const int nqpt = ir.GetNPoints();
474  d2q->FE = this;
475  d2q->IntRule = &ir;
476  d2q->mode = mode;
477  d2q->ndof = Dof;
478  d2q->nqpt = nqpt;
479  d2q->B.SetSize(nqpt*Dof);
480  d2q->Bt.SetSize(Dof*nqpt);
481  d2q->G.SetSize(nqpt*Dim*Dof);
482  d2q->Gt.SetSize(Dof*nqpt*Dim);
483 #ifdef MFEM_THREAD_SAFE
484  Vector c_shape(Dof);
485  DenseMatrix vshape(Dof, Dim);
486 #endif
487  for (int i = 0; i < nqpt; i++)
488  {
489  const IntegrationPoint &ip = ir.IntPoint(i);
490  CalcShape(ip, c_shape);
491  for (int j = 0; j < Dof; j++)
492  {
493  d2q->B[i+nqpt*j] = d2q->Bt[j+Dof*i] = c_shape(j);
494  }
495  CalcDShape(ip, vshape);
496  for (int d = 0; d < Dim; d++)
497  {
498  for (int j = 0; j < Dof; j++)
499  {
500  d2q->G[i+nqpt*(d+Dim*j)] = d2q->Gt[j+Dof*(i+nqpt*d)] = vshape(j,d);
501  }
502  }
503  }
504  dof2quad_array.Append(d2q);
505  return *d2q;
506 }
507 
508 // protected method
510  const TensorBasisElement &tb,
511  const IntegrationRule &ir, DofToQuad::Mode mode) const
512 {
513  MFEM_VERIFY(mode == DofToQuad::TENSOR, "invalid mode requested");
514 
515  for (int i = 0; i < dof2quad_array.Size(); i++)
516  {
517  const DofToQuad &d2q = *dof2quad_array[i];
518  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
519  }
520 
521  DofToQuad *d2q = new DofToQuad;
522  const Poly_1D::Basis &basis_1d = tb.GetBasis1D();
523  const int ndof = Order + 1;
524  const int nqpt = (int)floor(pow(ir.GetNPoints(), 1.0/Dim) + 0.5);
525  d2q->FE = this;
526  d2q->IntRule = &ir;
527  d2q->mode = mode;
528  d2q->ndof = ndof;
529  d2q->nqpt = nqpt;
530  d2q->B.SetSize(nqpt*ndof);
531  d2q->Bt.SetSize(ndof*nqpt);
532  d2q->G.SetSize(nqpt*ndof);
533  d2q->Gt.SetSize(ndof*nqpt);
534  Vector val(ndof), grad(ndof);
535  for (int i = 0; i < nqpt; i++)
536  {
537  // The first 'nqpt' points in 'ir' have the same x-coordinates as those
538  // of the 1D rule.
539  basis_1d.Eval(ir.IntPoint(i).x, val, grad);
540  for (int j = 0; j < ndof; j++)
541  {
542  d2q->B[i+nqpt*j] = d2q->Bt[j+ndof*i] = val(j);
543  d2q->G[i+nqpt*j] = d2q->Gt[j+ndof*i] = grad(j);
544  }
545  }
546  dof2quad_array.Append(d2q);
547  return *d2q;
548 }
549 
550 
553  DenseMatrix &curl) const
554 {
555  MFEM_ASSERT(GetMapType() == FiniteElement::INTEGRAL, "");
556 
557  DenseMatrix curl_shape(fe.GetDof(), 1);
558 
559  curl.SetSize(Dof, fe.GetDof());
560  for (int i = 0; i < Dof; i++)
561  {
562  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
563  for (int j = 0; j < fe.GetDof(); j++)
564  {
565  curl(i,j) = curl_shape(j,0);
566  }
567  }
568 }
569 
571  const IntegrationPoint &pt, Vector &x)
572 {
573  // invert a linear transform with one Newton step
574  IntegrationPoint p0;
575  p0.Set3(0, 0, 0);
576  trans.Transform(p0, x);
577 
578  double store[3];
579  Vector v(store, x.Size());
580  pt.Get(v, x.Size());
581  v -= x;
582 
583  trans.InverseJacobian().Mult(v, x);
584 }
585 
587  DenseMatrix &R) const
588 {
589  IntegrationPoint ipt;
590  Vector pt(&ipt.x, Dim);
591 
592 #ifdef MFEM_THREAD_SAFE
593  Vector c_shape(Dof);
594 #endif
595 
596  Trans.SetIntPoint(&Nodes[0]);
597 
598  for (int j = 0; j < Dof; j++)
599  {
600  InvertLinearTrans(Trans, Nodes[j], pt);
601  if (Geometries.CheckPoint(GeomType, ipt)) // do we need an epsilon here?
602  {
603  CalcShape(ipt, c_shape);
604  R.SetRow(j, c_shape);
605  }
606  else
607  {
608  // Set the whole row to avoid valgrind warnings in R.Threshold().
609  R.SetRow(j, infinity());
610  }
611  }
612  R.Threshold(1e-12);
613 }
614 
616  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
617 {
618  for (int i = 0; i < Dof; i++)
619  {
620  const IntegrationPoint &ip = Nodes.IntPoint(i);
621  // some coefficients expect that Trans.IntPoint is the same
622  // as the second argument of Eval
623  Trans.SetIntPoint(&ip);
624  dofs(i) = coeff.Eval (Trans, ip);
625  if (MapType == INTEGRAL)
626  {
627  dofs(i) *= Trans.Weight();
628  }
629  }
630 }
631 
634 {
635  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*Dof, "");
636  Vector x(vc.GetVDim());
637 
638  for (int i = 0; i < Dof; i++)
639  {
640  const IntegrationPoint &ip = Nodes.IntPoint(i);
641  Trans.SetIntPoint(&ip);
642  vc.Eval (x, Trans, ip);
643  if (MapType == INTEGRAL)
644  {
645  x *= Trans.Weight();
646  }
647  for (int j = 0; j < x.Size(); j++)
648  {
649  dofs(Dof*j+i) = x(j);
650  }
651  }
652 }
653 
655  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
656 {
657  // (mc.height x mc.width) @ DOFs -> (Dof x mc.width x mc.height) in dofs
658  MFEM_ASSERT(dofs.Size() == mc.GetHeight()*mc.GetWidth()*Dof, "");
659  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
660 
661  for (int k = 0; k < Dof; k++)
662  {
663  T.SetIntPoint(&Nodes.IntPoint(k));
664  mc.Eval(MQ, T, Nodes.IntPoint(k));
665  if (MapType == INTEGRAL) { MQ *= T.Weight(); }
666  for (int r = 0; r < MQ.Height(); r++)
667  {
668  for (int d = 0; d < MQ.Width(); d++)
669  {
670  dofs(k+Dof*(d+MQ.Width()*r)) = MQ(r,d);
671  }
672  }
673  }
674 }
675 
678 {
679  if (fe.GetRangeType() == SCALAR)
680  {
681  MFEM_ASSERT(MapType == fe.GetMapType(), "");
682 
683  Vector shape(fe.GetDof());
684 
685  I.SetSize(Dof, fe.GetDof());
686  for (int k = 0; k < Dof; k++)
687  {
688  fe.CalcShape(Nodes.IntPoint(k), shape);
689  for (int j = 0; j < shape.Size(); j++)
690  {
691  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
692  }
693  }
694  }
695  else
696  {
697  DenseMatrix vshape(fe.GetDof(), Trans.GetSpaceDim());
698 
699  I.SetSize(vshape.Width()*Dof, fe.GetDof());
700  for (int k = 0; k < Dof; k++)
701  {
702  Trans.SetIntPoint(&Nodes.IntPoint(k));
703  fe.CalcVShape(Trans, vshape);
704  if (MapType == INTEGRAL)
705  {
706  vshape *= Trans.Weight();
707  }
708  for (int j = 0; j < vshape.Height(); j++)
709  for (int d = 0; d < vshape.Width(); d++)
710  {
711  I(k+d*Dof,j) = vshape(j,d);
712  }
713  }
714  }
715 }
716 
719  DenseMatrix &grad) const
720 {
721  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
722  MFEM_ASSERT(Trans.GetSpaceDim() == Dim, "")
723 
724  DenseMatrix dshape(fe.GetDof(), Dim), grad_k(fe.GetDof(), Dim), Jinv(Dim);
725 
726  grad.SetSize(Dim*Dof, fe.GetDof());
727  for (int k = 0; k < Dof; k++)
728  {
729  const IntegrationPoint &ip = Nodes.IntPoint(k);
730  fe.CalcDShape(ip, dshape);
731  Trans.SetIntPoint(&ip);
732  CalcInverse(Trans.Jacobian(), Jinv);
733  Mult(dshape, Jinv, grad_k);
734  if (MapType == INTEGRAL)
735  {
736  grad_k *= Trans.Weight();
737  }
738  for (int j = 0; j < grad_k.Height(); j++)
739  for (int d = 0; d < Dim; d++)
740  {
741  grad(k+d*Dof,j) = grad_k(j,d);
742  }
743  }
744 }
745 
748  DenseMatrix &div) const
749 {
750  double detJ;
751  Vector div_shape(fe.GetDof());
752 
753  div.SetSize(Dof, fe.GetDof());
754  for (int k = 0; k < Dof; k++)
755  {
756  const IntegrationPoint &ip = Nodes.IntPoint(k);
757  fe.CalcDivShape(ip, div_shape);
758  if (MapType == VALUE)
759  {
760  Trans.SetIntPoint(&ip);
761  detJ = Trans.Weight();
762  for (int j = 0; j < div_shape.Size(); j++)
763  {
764  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
765  }
766  }
767  else
768  {
769  for (int j = 0; j < div_shape.Size(); j++)
770  {
771  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
772  }
773  }
774  }
775 }
776 
777 
779  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
780 {
781  for (int i = 0; i < Dof; i++)
782  {
783  const IntegrationPoint &ip = Nodes.IntPoint(i);
784  Trans.SetIntPoint(&ip);
785  dofs(i) = coeff.Eval(Trans, ip);
786  }
787 }
788 
791 {
792  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*Dof, "");
793  Vector x(vc.GetVDim());
794 
795  for (int i = 0; i < Dof; i++)
796  {
797  const IntegrationPoint &ip = Nodes.IntPoint(i);
798  Trans.SetIntPoint(&ip);
799  vc.Eval (x, Trans, ip);
800  for (int j = 0; j < x.Size(); j++)
801  {
802  dofs(Dof*j+i) = x(j);
803  }
804  }
805 }
806 
809 {
810  const NodalFiniteElement *nfe =
811  dynamic_cast<const NodalFiniteElement *>(&fe);
812 
813  if (nfe && Dof == nfe->GetDof())
814  {
815  nfe->Project(*this, Trans, I);
816  I.Invert();
817  }
818  else
819  {
820  // local L2 projection
821  DenseMatrix pos_mass, mixed_mass;
822  MassIntegrator mass_integ;
823 
824  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
825  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
826 
827  DenseMatrixInverse pos_mass_inv(pos_mass);
828  I.SetSize(Dof, fe.GetDof());
829  pos_mass_inv.Mult(mixed_mass, I);
830  }
831 }
832 
833 
834 void VectorFiniteElement::CalcShape (
835  const IntegrationPoint &ip, Vector &shape ) const
836 {
837  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
838  " VectorFiniteElements!");
839 }
840 
841 void VectorFiniteElement::CalcDShape (
842  const IntegrationPoint &ip, DenseMatrix &dshape ) const
843 {
844  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
845  " VectorFiniteElements!");
846 }
847 
849 {
850  switch (MapType)
851  {
852  case H_DIV:
853  DerivType = DIV;
856  break;
857  case H_CURL:
858  switch (Dim)
859  {
860  case 3: // curl: 3D H_CURL -> 3D H_DIV
861  DerivType = CURL;
864  break;
865  case 2:
866  // curl: 2D H_CURL -> INTEGRAL
867  DerivType = CURL;
870  break;
871  case 1:
872  DerivType = NONE;
875  break;
876  default:
877  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
878  }
879  break;
880  default:
881  MFEM_ABORT("Invalid MapType = " << MapType);
882  }
883 }
884 
886  ElementTransformation &Trans, DenseMatrix &shape) const
887 {
888  MFEM_ASSERT(MapType == H_DIV, "");
889 #ifdef MFEM_THREAD_SAFE
891 #endif
892  CalcVShape(Trans.GetIntPoint(), vshape);
893  MultABt(vshape, Trans.Jacobian(), shape);
894  shape *= (1.0 / Trans.Weight());
895 }
896 
898  ElementTransformation &Trans, DenseMatrix &shape) const
899 {
900  MFEM_ASSERT(MapType == H_CURL, "");
901 #ifdef MFEM_THREAD_SAFE
903 #endif
904  CalcVShape(Trans.GetIntPoint(), vshape);
905  Mult(vshape, Trans.InverseJacobian(), shape);
906 }
907 
909  const double *nk, const Array<int> &d2n,
911 {
912  double vk[Geometry::MaxDim];
913  const int sdim = Trans.GetSpaceDim();
914  MFEM_ASSERT(vc.GetVDim() == sdim, "");
915  Vector xk(vk, sdim);
916  const bool square_J = (Dim == sdim);
917 
918  for (int k = 0; k < Dof; k++)
919  {
920  Trans.SetIntPoint(&Nodes.IntPoint(k));
921  vc.Eval(xk, Trans, Nodes.IntPoint(k));
922  // dof_k = nk^t adj(J) xk
923  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*Dim);
924  if (!square_J) { dofs(k) /= Trans.Weight(); }
925  }
926 }
927 
929  const double *nk, const Array<int> &d2n,
930  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
931 {
932  // project the rows of the matrix coefficient in an RT space
933 
934  const int sdim = T.GetSpaceDim();
935  MFEM_ASSERT(mc.GetWidth() == sdim, "");
936  const bool square_J = (Dim == sdim);
937  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
938  Vector nk_phys(sdim), dofs_k(MQ.Height());
939  MFEM_ASSERT(dofs.Size() == Dof*MQ.Height(), "");
940 
941  for (int k = 0; k < Dof; k++)
942  {
943  T.SetIntPoint(&Nodes.IntPoint(k));
944  mc.Eval(MQ, T, Nodes.IntPoint(k));
945  // nk_phys = adj(J)^t nk
946  T.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, nk_phys);
947  if (!square_J) { nk_phys /= T.Weight(); }
948  MQ.Mult(nk_phys, dofs_k);
949  for (int r = 0; r < MQ.Height(); r++)
950  {
951  dofs(k+Dof*r) = dofs_k(r);
952  }
953  }
954 }
955 
957  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
959 {
960  if (fe.GetRangeType() == SCALAR)
961  {
962  double vk[Geometry::MaxDim];
963  Vector shape(fe.GetDof());
964  int sdim = Trans.GetSpaceDim();
965 
966  I.SetSize(Dof, sdim*fe.GetDof());
967  for (int k = 0; k < Dof; k++)
968  {
969  const IntegrationPoint &ip = Nodes.IntPoint(k);
970 
971  fe.CalcShape(ip, shape);
972  Trans.SetIntPoint(&ip);
973  Trans.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, vk);
974  if (fe.GetMapType() == INTEGRAL)
975  {
976  double w = 1.0/Trans.Weight();
977  for (int d = 0; d < Dim; d++)
978  {
979  vk[d] *= w;
980  }
981  }
982 
983  for (int j = 0; j < shape.Size(); j++)
984  {
985  double s = shape(j);
986  if (fabs(s) < 1e-12)
987  {
988  s = 0.0;
989  }
990  for (int d = 0; d < sdim; d++)
991  {
992  I(k,j+d*shape.Size()) = s*vk[d];
993  }
994  }
995  }
996  }
997  else
998  {
999  mfem_error("VectorFiniteElement::Project_RT (fe version)");
1000  }
1001 }
1002 
1004  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
1005  ElementTransformation &Trans, DenseMatrix &grad) const
1006 {
1007  if (Dim != 2)
1008  {
1009  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
1010  }
1011 
1012  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
1013  Vector grad_k(fe.GetDof());
1014  double tk[2];
1015 
1016  grad.SetSize(Dof, fe.GetDof());
1017  for (int k = 0; k < Dof; k++)
1018  {
1019  fe.CalcDShape(Nodes.IntPoint(k), dshape);
1020  tk[0] = nk[d2n[k]*Dim+1];
1021  tk[1] = -nk[d2n[k]*Dim];
1022  dshape.Mult(tk, grad_k);
1023  for (int j = 0; j < grad_k.Size(); j++)
1024  {
1025  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1026  }
1027  }
1028 }
1029 
1031  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1032  ElementTransformation &Trans, DenseMatrix &curl) const
1033 {
1034 #ifdef MFEM_THREAD_SAFE
1037  DenseMatrix J(Dim, Dim);
1038 #else
1039  curlshape.SetSize(fe.GetDof(), Dim);
1040  curlshape_J.SetSize(fe.GetDof(), Dim);
1041  J.SetSize(Dim, Dim);
1042 #endif
1043 
1044  Vector curl_k(fe.GetDof());
1045 
1046  curl.SetSize(Dof, fe.GetDof());
1047  for (int k = 0; k < Dof; k++)
1048  {
1049  const IntegrationPoint &ip = Nodes.IntPoint(k);
1050 
1051  // calculate J^t * J / |J|
1052  Trans.SetIntPoint(&ip);
1053  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
1054  J *= 1.0 / Trans.Weight();
1055 
1056  // transform curl of shapes (rows) by J^t * J / |J|
1057  fe.CalcCurlShape(ip, curlshape);
1058  Mult(curlshape, J, curlshape_J);
1059 
1060  curlshape_J.Mult(tk + d2t[k]*Dim, curl_k);
1061  for (int j = 0; j < curl_k.Size(); j++)
1062  {
1063  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
1064  }
1065  }
1066 }
1067 
1069  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
1070  ElementTransformation &Trans, DenseMatrix &curl) const
1071 {
1072  DenseMatrix curl_shape(fe.GetDof(), Dim);
1073  Vector curl_k(fe.GetDof());
1074 
1075  curl.SetSize(Dof, fe.GetDof());
1076  for (int k = 0; k < Dof; k++)
1077  {
1078  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
1079  curl_shape.Mult(nk + d2n[k]*Dim, curl_k);
1080  for (int j = 0; j < curl_k.Size(); j++)
1081  {
1082  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
1083  }
1084  }
1085 }
1086 
1088  const double *tk, const Array<int> &d2t,
1090 {
1091  double vk[Geometry::MaxDim];
1092  Vector xk(vk, vc.GetVDim());
1093 
1094  for (int k = 0; k < Dof; k++)
1095  {
1096  Trans.SetIntPoint(&Nodes.IntPoint(k));
1097 
1098  vc.Eval(xk, Trans, Nodes.IntPoint(k));
1099  // dof_k = xk^t J tk
1100  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*Dim, vk);
1101  }
1102 }
1103 
1105  const double *tk, const Array<int> &d2t,
1106  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
1107 {
1108  // project the rows of the matrix coefficient in an ND space
1109 
1110  const int sdim = T.GetSpaceDim();
1111  MFEM_ASSERT(mc.GetWidth() == sdim, "");
1112  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
1113  Vector tk_phys(sdim), dofs_k(MQ.Height());
1114  MFEM_ASSERT(dofs.Size() == Dof*MQ.Height(), "");
1115 
1116  for (int k = 0; k < Dof; k++)
1117  {
1118  T.SetIntPoint(&Nodes.IntPoint(k));
1119  mc.Eval(MQ, T, Nodes.IntPoint(k));
1120  // tk_phys = J tk
1121  T.Jacobian().Mult(tk + d2t[k]*Dim, tk_phys);
1122  MQ.Mult(tk_phys, dofs_k);
1123  for (int r = 0; r < MQ.Height(); r++)
1124  {
1125  dofs(k+Dof*r) = dofs_k(r);
1126  }
1127  }
1128 }
1129 
1131  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1133 {
1134  if (fe.GetRangeType() == SCALAR)
1135  {
1136  int sdim = Trans.GetSpaceDim();
1137  double vk[Geometry::MaxDim];
1138  Vector shape(fe.GetDof());
1139 
1140  I.SetSize(Dof, sdim*fe.GetDof());
1141  for (int k = 0; k < Dof; k++)
1142  {
1143  const IntegrationPoint &ip = Nodes.IntPoint(k);
1144 
1145  fe.CalcShape(ip, shape);
1146  Trans.SetIntPoint(&ip);
1147  Trans.Jacobian().Mult(tk + d2t[k]*Dim, vk);
1148  if (fe.GetMapType() == INTEGRAL)
1149  {
1150  double w = 1.0/Trans.Weight();
1151  for (int d = 0; d < sdim; d++)
1152  {
1153  vk[d] *= w;
1154  }
1155  }
1156 
1157  for (int j = 0; j < shape.Size(); j++)
1158  {
1159  double s = shape(j);
1160  if (fabs(s) < 1e-12)
1161  {
1162  s = 0.0;
1163  }
1164  for (int d = 0; d < sdim; d++)
1165  {
1166  I(k, j + d*shape.Size()) = s*vk[d];
1167  }
1168  }
1169  }
1170  }
1171  else
1172  {
1173  mfem_error("VectorFiniteElement::Project_ND (fe version)");
1174  }
1175 }
1176 
1178  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1179  ElementTransformation &Trans, DenseMatrix &grad) const
1180 {
1181  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
1182 
1183  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
1184  Vector grad_k(fe.GetDof());
1185 
1186  grad.SetSize(Dof, fe.GetDof());
1187  for (int k = 0; k < Dof; k++)
1188  {
1189  fe.CalcDShape(Nodes.IntPoint(k), dshape);
1190  dshape.Mult(tk + d2t[k]*Dim, grad_k);
1191  for (int j = 0; j < grad_k.Size(); j++)
1192  {
1193  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1194  }
1195  }
1196 }
1197 
1199  const VectorFiniteElement &cfe, const double *nk, const Array<int> &d2n,
1201 {
1202  MFEM_ASSERT(MapType == cfe.GetMapType(), "");
1203 
1204  double vk[Geometry::MaxDim];
1205  Vector xk(vk, Dim);
1206  IntegrationPoint ip;
1207 #ifdef MFEM_THREAD_SAFE
1208  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
1209 #else
1210  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
1211 #endif
1212  I.SetSize(Dof, vshape.Height());
1213 
1214  // assuming Trans is linear; this should be ok for all refinement types
1216  const DenseMatrix &adjJ = Trans.AdjugateJacobian();
1217  for (int k = 0; k < Dof; k++)
1218  {
1219  Trans.Transform(Nodes.IntPoint(k), xk);
1220  ip.Set3(vk);
1221  cfe.CalcVShape(ip, vshape);
1222  // xk = |J| J^{-t} n_k
1223  adjJ.MultTranspose(nk + d2n[k]*Dim, vk);
1224  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,Dof
1225  for (int j = 0; j < vshape.Height(); j++)
1226  {
1227  double Ikj = 0.;
1228  for (int i = 0; i < Dim; i++)
1229  {
1230  Ikj += vshape(j, i) * vk[i];
1231  }
1232  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1233  }
1234  }
1235 }
1236 
1238  const VectorFiniteElement &cfe, const double *tk, const Array<int> &d2t,
1240 {
1241  double vk[Geometry::MaxDim];
1242  Vector xk(vk, Dim);
1243  IntegrationPoint ip;
1244 #ifdef MFEM_THREAD_SAFE
1245  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
1246 #else
1247  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
1248 #endif
1249  I.SetSize(Dof, vshape.Height());
1250 
1251  // assuming Trans is linear; this should be ok for all refinement types
1253  const DenseMatrix &J = Trans.Jacobian();
1254  for (int k = 0; k < Dof; k++)
1255  {
1256  Trans.Transform(Nodes.IntPoint(k), xk);
1257  ip.Set3(vk);
1258  cfe.CalcVShape(ip, vshape);
1259  // xk = J t_k
1260  J.Mult(tk + d2t[k]*Dim, vk);
1261  // I_k = vshape_k.J.t_k, k=1,...,Dof
1262  for (int j = 0; j < vshape.Height(); j++)
1263  {
1264  double Ikj = 0.;
1265  for (int i = 0; i < Dim; i++)
1266  {
1267  Ikj += vshape(j, i) * vk[i];
1268  }
1269  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1270  }
1271  }
1272 }
1273 
1275  const double *nk, const Array<int> &d2n, ElementTransformation &Trans,
1276  DenseMatrix &R) const
1277 {
1278  double pt_data[Geometry::MaxDim];
1279  IntegrationPoint ip;
1280  Vector pt(pt_data, Dim);
1281 
1282 #ifdef MFEM_THREAD_SAFE
1284 #endif
1285 
1287  const DenseMatrix &J = Trans.Jacobian();
1288  const double weight = Trans.Weight();
1289  for (int j = 0; j < Dof; j++)
1290  {
1291  InvertLinearTrans(Trans, Nodes.IntPoint(j), pt);
1292  ip.Set(pt_data, Dim);
1293  if (Geometries.CheckPoint(GeomType, ip)) // do we need an epsilon here?
1294  {
1295  CalcVShape(ip, vshape);
1296  J.MultTranspose(nk+Dim*d2n[j], pt_data);
1297  pt /= weight;
1298  for (int k = 0; k < Dof; k++)
1299  {
1300  double R_jk = 0.0;
1301  for (int d = 0; d < Dim; d++)
1302  {
1303  R_jk += vshape(k,d)*pt_data[d];
1304  }
1305  R(j,k) = R_jk;
1306  }
1307  }
1308  else
1309  {
1310  // Set the whole row to avoid valgrind warnings in R.Threshold().
1311  R.SetRow(j, infinity());
1312  }
1313  }
1314  R.Threshold(1e-12);
1315 }
1316 
1318  const double *tk, const Array<int> &d2t, ElementTransformation &Trans,
1319  DenseMatrix &R) const
1320 {
1321  double pt_data[Geometry::MaxDim];
1322  IntegrationPoint ip;
1323  Vector pt(pt_data, Dim);
1324 
1325 #ifdef MFEM_THREAD_SAFE
1327 #endif
1328 
1330  const DenseMatrix &Jinv = Trans.InverseJacobian();
1331  for (int j = 0; j < Dof; j++)
1332  {
1333  InvertLinearTrans(Trans, Nodes.IntPoint(j), pt);
1334  ip.Set(pt_data, Dim);
1335  if (Geometries.CheckPoint(GeomType, ip)) // do we need an epsilon here?
1336  {
1337  CalcVShape(ip, vshape);
1338  Jinv.Mult(tk+Dim*d2t[j], pt_data);
1339  for (int k = 0; k < Dof; k++)
1340  {
1341  double R_jk = 0.0;
1342  for (int d = 0; d < Dim; d++)
1343  {
1344  R_jk += vshape(k,d)*pt_data[d];
1345  }
1346  R(j,k) = R_jk;
1347  }
1348  }
1349  else
1350  {
1351  // Set the whole row to avoid valgrind warnings in R.Threshold().
1352  R.SetRow(j, infinity());
1353  }
1354  }
1355  R.Threshold(1e-12);
1356 }
1357 
1358 
1360  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
1361 {
1362  Nodes.IntPoint(0).x = 0.0;
1363 }
1364 
1366  Vector &shape) const
1367 {
1368  shape(0) = 1.;
1369 }
1370 
1372  DenseMatrix &dshape) const
1373 {
1374  // dshape is (1 x 0) - nothing to compute
1375 }
1376 
1378  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
1379 {
1380  Nodes.IntPoint(0).x = 0.0;
1381  Nodes.IntPoint(1).x = 1.0;
1382 }
1383 
1385  Vector &shape) const
1386 {
1387  shape(0) = 1. - ip.x;
1388  shape(1) = ip.x;
1389 }
1390 
1392  DenseMatrix &dshape) const
1393 {
1394  dshape(0,0) = -1.;
1395  dshape(1,0) = 1.;
1396 }
1397 
1399  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
1400 {
1401  Nodes.IntPoint(0).x = 0.0;
1402  Nodes.IntPoint(0).y = 0.0;
1403  Nodes.IntPoint(1).x = 1.0;
1404  Nodes.IntPoint(1).y = 0.0;
1405  Nodes.IntPoint(2).x = 0.0;
1406  Nodes.IntPoint(2).y = 1.0;
1407 }
1408 
1410  Vector &shape) const
1411 {
1412  shape(0) = 1. - ip.x - ip.y;
1413  shape(1) = ip.x;
1414  shape(2) = ip.y;
1415 }
1416 
1418  DenseMatrix &dshape) const
1419 {
1420  dshape(0,0) = -1.; dshape(0,1) = -1.;
1421  dshape(1,0) = 1.; dshape(1,1) = 0.;
1422  dshape(2,0) = 0.; dshape(2,1) = 1.;
1423 }
1424 
1426  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1427 {
1428  Nodes.IntPoint(0).x = 0.0;
1429  Nodes.IntPoint(0).y = 0.0;
1430  Nodes.IntPoint(1).x = 1.0;
1431  Nodes.IntPoint(1).y = 0.0;
1432  Nodes.IntPoint(2).x = 1.0;
1433  Nodes.IntPoint(2).y = 1.0;
1434  Nodes.IntPoint(3).x = 0.0;
1435  Nodes.IntPoint(3).y = 1.0;
1436 }
1437 
1439  Vector &shape) const
1440 {
1441  shape(0) = (1. - ip.x) * (1. - ip.y) ;
1442  shape(1) = ip.x * (1. - ip.y) ;
1443  shape(2) = ip.x * ip.y ;
1444  shape(3) = (1. - ip.x) * ip.y ;
1445 }
1446 
1448  DenseMatrix &dshape) const
1449 {
1450  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
1451  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
1452  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
1453  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
1454 }
1455 
1457  const IntegrationPoint &ip, DenseMatrix &h) const
1458 {
1459  h(0,0) = 0.; h(0,1) = 1.; h(0,2) = 0.;
1460  h(1,0) = 0.; h(1,1) = -1.; h(1,2) = 0.;
1461  h(2,0) = 0.; h(2,1) = 1.; h(2,2) = 0.;
1462  h(3,0) = 0.; h(3,1) = -1.; h(3,2) = 0.;
1463 }
1464 
1465 
1467  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
1468 {
1469  Nodes.IntPoint(0).x = 1./6.;
1470  Nodes.IntPoint(0).y = 1./6.;
1471  Nodes.IntPoint(1).x = 2./3.;
1472  Nodes.IntPoint(1).y = 1./6.;
1473  Nodes.IntPoint(2).x = 1./6.;
1474  Nodes.IntPoint(2).y = 2./3.;
1475 }
1476 
1478  Vector &shape) const
1479 {
1480  const double x = ip.x, y = ip.y;
1481 
1482  shape(0) = 5./3. - 2. * (x + y);
1483  shape(1) = 2. * (x - 1./6.);
1484  shape(2) = 2. * (y - 1./6.);
1485 }
1486 
1488  DenseMatrix &dshape) const
1489 {
1490  dshape(0,0) = -2.; dshape(0,1) = -2.;
1491  dshape(1,0) = 2.; dshape(1,1) = 0.;
1492  dshape(2,0) = 0.; dshape(2,1) = 2.;
1493 }
1494 
1496 {
1497  dofs(vertex) = 2./3.;
1498  dofs((vertex+1)%3) = 1./6.;
1499  dofs((vertex+2)%3) = 1./6.;
1500 }
1501 
1502 
1503 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
1504 const double GaussBiLinear2DFiniteElement::p[] =
1505 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
1506 
1508  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1509 {
1510  Nodes.IntPoint(0).x = p[0];
1511  Nodes.IntPoint(0).y = p[0];
1512  Nodes.IntPoint(1).x = p[1];
1513  Nodes.IntPoint(1).y = p[0];
1514  Nodes.IntPoint(2).x = p[1];
1515  Nodes.IntPoint(2).y = p[1];
1516  Nodes.IntPoint(3).x = p[0];
1517  Nodes.IntPoint(3).y = p[1];
1518 }
1519 
1521  Vector &shape) const
1522 {
1523  const double x = ip.x, y = ip.y;
1524 
1525  shape(0) = 3. * (p[1] - x) * (p[1] - y);
1526  shape(1) = 3. * (x - p[0]) * (p[1] - y);
1527  shape(2) = 3. * (x - p[0]) * (y - p[0]);
1528  shape(3) = 3. * (p[1] - x) * (y - p[0]);
1529 }
1530 
1532  DenseMatrix &dshape) const
1533 {
1534  const double x = ip.x, y = ip.y;
1535 
1536  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
1537  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
1538  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
1539  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
1540 }
1541 
1543 {
1544 #if 1
1545  dofs(vertex) = p[1]*p[1];
1546  dofs((vertex+1)%4) = p[0]*p[1];
1547  dofs((vertex+2)%4) = p[0]*p[0];
1548  dofs((vertex+3)%4) = p[0]*p[1];
1549 #else
1550  dofs = 1.0;
1551 #endif
1552 }
1553 
1554 
1556  : NodalFiniteElement(2, Geometry::SQUARE, 3, 1, FunctionSpace::Qk)
1557 {
1558  Nodes.IntPoint(0).x = 0.0;
1559  Nodes.IntPoint(0).y = 0.0;
1560  Nodes.IntPoint(1).x = 1.0;
1561  Nodes.IntPoint(1).y = 0.0;
1562  Nodes.IntPoint(2).x = 0.0;
1563  Nodes.IntPoint(2).y = 1.0;
1564 }
1565 
1567  Vector &shape) const
1568 {
1569  shape(0) = 1. - ip.x - ip.y;
1570  shape(1) = ip.x;
1571  shape(2) = ip.y;
1572 }
1573 
1575  DenseMatrix &dshape) const
1576 {
1577  dshape(0,0) = -1.; dshape(0,1) = -1.;
1578  dshape(1,0) = 1.; dshape(1,1) = 0.;
1579  dshape(2,0) = 0.; dshape(2,1) = 1.;
1580 }
1581 
1582 
1584  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
1585 {
1586  Nodes.IntPoint(0).x = 0.0;
1587  Nodes.IntPoint(1).x = 1.0;
1588  Nodes.IntPoint(2).x = 0.5;
1589 }
1590 
1592  Vector &shape) const
1593 {
1594  double x = ip.x;
1595  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
1596 
1597  shape(0) = l1 * (-l3);
1598  shape(1) = l2 * l3;
1599  shape(2) = 4. * l1 * l2;
1600 }
1601 
1603  DenseMatrix &dshape) const
1604 {
1605  double x = ip.x;
1606 
1607  dshape(0,0) = 4. * x - 3.;
1608  dshape(1,0) = 4. * x - 1.;
1609  dshape(2,0) = 4. - 8. * x;
1610 }
1611 
1612 
1614  : PositiveFiniteElement(1, Geometry::SEGMENT, 3, 2)
1615 {
1616  Nodes.IntPoint(0).x = 0.0;
1617  Nodes.IntPoint(1).x = 1.0;
1618  Nodes.IntPoint(2).x = 0.5;
1619 }
1620 
1622  Vector &shape) const
1623 {
1624  const double x = ip.x, x1 = 1. - x;
1625 
1626  shape(0) = x1 * x1;
1627  shape(1) = x * x;
1628  shape(2) = 2. * x * x1;
1629 }
1630 
1632  DenseMatrix &dshape) const
1633 {
1634  const double x = ip.x;
1635 
1636  dshape(0,0) = 2. * x - 2.;
1637  dshape(1,0) = 2. * x;
1638  dshape(2,0) = 2. - 4. * x;
1639 }
1640 
1642  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1643 {
1644  Nodes.IntPoint(0).x = 0.0;
1645  Nodes.IntPoint(0).y = 0.0;
1646  Nodes.IntPoint(1).x = 1.0;
1647  Nodes.IntPoint(1).y = 0.0;
1648  Nodes.IntPoint(2).x = 0.0;
1649  Nodes.IntPoint(2).y = 1.0;
1650  Nodes.IntPoint(3).x = 0.5;
1651  Nodes.IntPoint(3).y = 0.0;
1652  Nodes.IntPoint(4).x = 0.5;
1653  Nodes.IntPoint(4).y = 0.5;
1654  Nodes.IntPoint(5).x = 0.0;
1655  Nodes.IntPoint(5).y = 0.5;
1656 }
1657 
1659  Vector &shape) const
1660 {
1661  double x = ip.x, y = ip.y;
1662  double l1 = 1.-x-y, l2 = x, l3 = y;
1663 
1664  shape(0) = l1 * (2. * l1 - 1.);
1665  shape(1) = l2 * (2. * l2 - 1.);
1666  shape(2) = l3 * (2. * l3 - 1.);
1667  shape(3) = 4. * l1 * l2;
1668  shape(4) = 4. * l2 * l3;
1669  shape(5) = 4. * l3 * l1;
1670 }
1671 
1673  DenseMatrix &dshape) const
1674 {
1675  double x = ip.x, y = ip.y;
1676 
1677  dshape(0,0) =
1678  dshape(0,1) = 4. * (x + y) - 3.;
1679 
1680  dshape(1,0) = 4. * x - 1.;
1681  dshape(1,1) = 0.;
1682 
1683  dshape(2,0) = 0.;
1684  dshape(2,1) = 4. * y - 1.;
1685 
1686  dshape(3,0) = -4. * (2. * x + y - 1.);
1687  dshape(3,1) = -4. * x;
1688 
1689  dshape(4,0) = 4. * y;
1690  dshape(4,1) = 4. * x;
1691 
1692  dshape(5,0) = -4. * y;
1693  dshape(5,1) = -4. * (x + 2. * y - 1.);
1694 }
1695 
1697  DenseMatrix &h) const
1698 {
1699  h(0,0) = 4.;
1700  h(0,1) = 4.;
1701  h(0,2) = 4.;
1702 
1703  h(1,0) = 4.;
1704  h(1,1) = 0.;
1705  h(1,2) = 0.;
1706 
1707  h(2,0) = 0.;
1708  h(2,1) = 0.;
1709  h(2,2) = 4.;
1710 
1711  h(3,0) = -8.;
1712  h(3,1) = -4.;
1713  h(3,2) = 0.;
1714 
1715  h(4,0) = 0.;
1716  h(4,1) = 4.;
1717  h(4,2) = 0.;
1718 
1719  h(5,0) = 0.;
1720  h(5,1) = -4.;
1721  h(5,2) = -8.;
1722 }
1723 
1724 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1725 {
1726 #if 0
1727  dofs = 1.;
1728 #else
1729  dofs = 0.;
1730  dofs(vertex) = 1.;
1731  switch (vertex)
1732  {
1733  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1734  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1735  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1736  }
1737 #endif
1738 }
1739 
1740 
1741 const double GaussQuad2DFiniteElement::p[] =
1742 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1743 
1745  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1746 {
1747  Nodes.IntPoint(0).x = p[0];
1748  Nodes.IntPoint(0).y = p[0];
1749  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1750  Nodes.IntPoint(1).y = p[0];
1751  Nodes.IntPoint(2).x = p[0];
1752  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1753  Nodes.IntPoint(3).x = p[1];
1754  Nodes.IntPoint(3).y = p[1];
1755  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1756  Nodes.IntPoint(4).y = p[1];
1757  Nodes.IntPoint(5).x = p[1];
1758  Nodes.IntPoint(5).y = 1. - 2. * p[1];
1759 
1760  for (int i = 0; i < 6; i++)
1761  {
1762  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
1763  A(0,i) = 1.;
1764  A(1,i) = x;
1765  A(2,i) = y;
1766  A(3,i) = x * x;
1767  A(4,i) = x * y;
1768  A(5,i) = y * y;
1769  }
1770 
1771  A.Invert();
1772 }
1773 
1775  Vector &shape) const
1776 {
1777  const double x = ip.x, y = ip.y;
1778  pol(0) = 1.;
1779  pol(1) = x;
1780  pol(2) = y;
1781  pol(3) = x * x;
1782  pol(4) = x * y;
1783  pol(5) = y * y;
1784 
1785  A.Mult(pol, shape);
1786 }
1787 
1789  DenseMatrix &dshape) const
1790 {
1791  const double x = ip.x, y = ip.y;
1792  D(0,0) = 0.; D(0,1) = 0.;
1793  D(1,0) = 1.; D(1,1) = 0.;
1794  D(2,0) = 0.; D(2,1) = 1.;
1795  D(3,0) = 2. * x; D(3,1) = 0.;
1796  D(4,0) = y; D(4,1) = x;
1797  D(5,0) = 0.; D(5,1) = 2. * y;
1798 
1799  Mult(A, D, dshape);
1800 }
1801 
1802 
1804  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1805 {
1806  Nodes.IntPoint(0).x = 0.0;
1807  Nodes.IntPoint(0).y = 0.0;
1808  Nodes.IntPoint(1).x = 1.0;
1809  Nodes.IntPoint(1).y = 0.0;
1810  Nodes.IntPoint(2).x = 1.0;
1811  Nodes.IntPoint(2).y = 1.0;
1812  Nodes.IntPoint(3).x = 0.0;
1813  Nodes.IntPoint(3).y = 1.0;
1814  Nodes.IntPoint(4).x = 0.5;
1815  Nodes.IntPoint(4).y = 0.0;
1816  Nodes.IntPoint(5).x = 1.0;
1817  Nodes.IntPoint(5).y = 0.5;
1818  Nodes.IntPoint(6).x = 0.5;
1819  Nodes.IntPoint(6).y = 1.0;
1820  Nodes.IntPoint(7).x = 0.0;
1821  Nodes.IntPoint(7).y = 0.5;
1822  Nodes.IntPoint(8).x = 0.5;
1823  Nodes.IntPoint(8).y = 0.5;
1824 }
1825 
1827  Vector &shape) const
1828 {
1829  double x = ip.x, y = ip.y;
1830  double l1x, l2x, l3x, l1y, l2y, l3y;
1831 
1832  l1x = (x - 1.) * (2. * x - 1);
1833  l2x = 4. * x * (1. - x);
1834  l3x = x * (2. * x - 1.);
1835  l1y = (y - 1.) * (2. * y - 1);
1836  l2y = 4. * y * (1. - y);
1837  l3y = y * (2. * y - 1.);
1838 
1839  shape(0) = l1x * l1y;
1840  shape(4) = l2x * l1y;
1841  shape(1) = l3x * l1y;
1842  shape(7) = l1x * l2y;
1843  shape(8) = l2x * l2y;
1844  shape(5) = l3x * l2y;
1845  shape(3) = l1x * l3y;
1846  shape(6) = l2x * l3y;
1847  shape(2) = l3x * l3y;
1848 }
1849 
1851  DenseMatrix &dshape) const
1852 {
1853  double x = ip.x, y = ip.y;
1854  double l1x, l2x, l3x, l1y, l2y, l3y;
1855  double d1x, d2x, d3x, d1y, d2y, d3y;
1856 
1857  l1x = (x - 1.) * (2. * x - 1);
1858  l2x = 4. * x * (1. - x);
1859  l3x = x * (2. * x - 1.);
1860  l1y = (y - 1.) * (2. * y - 1);
1861  l2y = 4. * y * (1. - y);
1862  l3y = y * (2. * y - 1.);
1863 
1864  d1x = 4. * x - 3.;
1865  d2x = 4. - 8. * x;
1866  d3x = 4. * x - 1.;
1867  d1y = 4. * y - 3.;
1868  d2y = 4. - 8. * y;
1869  d3y = 4. * y - 1.;
1870 
1871  dshape(0,0) = d1x * l1y;
1872  dshape(0,1) = l1x * d1y;
1873 
1874  dshape(4,0) = d2x * l1y;
1875  dshape(4,1) = l2x * d1y;
1876 
1877  dshape(1,0) = d3x * l1y;
1878  dshape(1,1) = l3x * d1y;
1879 
1880  dshape(7,0) = d1x * l2y;
1881  dshape(7,1) = l1x * d2y;
1882 
1883  dshape(8,0) = d2x * l2y;
1884  dshape(8,1) = l2x * d2y;
1885 
1886  dshape(5,0) = d3x * l2y;
1887  dshape(5,1) = l3x * d2y;
1888 
1889  dshape(3,0) = d1x * l3y;
1890  dshape(3,1) = l1x * d3y;
1891 
1892  dshape(6,0) = d2x * l3y;
1893  dshape(6,1) = l2x * d3y;
1894 
1895  dshape(2,0) = d3x * l3y;
1896  dshape(2,1) = l3x * d3y;
1897 }
1898 
1899 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1900 {
1901 #if 0
1902  dofs = 1.;
1903 #else
1904  dofs = 0.;
1905  dofs(vertex) = 1.;
1906  switch (vertex)
1907  {
1908  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
1909  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
1910  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
1911  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
1912  }
1913  dofs(8) = 1./16.;
1914 #endif
1915 }
1916 
1917 
1919  : ScalarFiniteElement(2, Geometry::SQUARE, (p*p + 3*p +6) / 2, p,
1920  FunctionSpace::Qk)
1921 {
1922  // Store the dof_map of the associated TensorBasisElement, which will be used
1923  // to create the serendipity dof map. Its size is larger than the size of
1924  // the serendipity element.
1925  TensorBasisElement tbeTemp =
1927  TensorBasisElement::DofMapType::Sr_DOF_MAP);
1928  const Array<int> tp_dof_map = tbeTemp.GetDofMap();
1929 
1930  const double *cp = poly1d.ClosedPoints(p, BasisType::GaussLobatto);
1931 
1932  // Fixing the Nodes is exactly the same as the H1_QuadrilateralElement
1933  // constructor except we only use those values of the associated tensor
1934  // product dof_map that are <= the number of serendipity Dofs e.g. only DoFs
1935  // 0-7 out of the 9 tensor product dofs (at quadratic order)
1936  int o = 0;
1937 
1938  for (int j = 0; j <= p; j++)
1939  {
1940  for (int i = 0; i <= p; i++)
1941  {
1942  if (tp_dof_map[o] < Nodes.Size())
1943  {
1944  Nodes.IntPoint(tp_dof_map[o]).x = cp[i];
1945  Nodes.IntPoint(tp_dof_map[o]).y = cp[j];
1946  }
1947  o++;
1948  }
1949  }
1950 }
1951 
1953  Vector &shape) const
1954 {
1955  int p = (this)->GetOrder();
1956  double x = ip.x, y = ip.y;
1957 
1959  Vector nodalX(p+1);
1960  Vector nodalY(p+1);
1961 
1962  edgeNodalBasis.Eval(x, nodalX);
1963  edgeNodalBasis.Eval(y, nodalY);
1964 
1965  // First, fix edge-based shape functions. Use a nodal interpolant for edge
1966  // points, weighted by the linear function that vanishes on opposite edge.
1967  for (int i = 0; i < p-1; i++)
1968  {
1969  shape(4 + 0*(p-1) + i) = (nodalX(i+1))*(1.-y); // south edge 0->1
1970  shape(4 + 1*(p-1) + i) = (nodalY(i+1))*x; // east edge 1->2
1971  shape(4 + 3*(p-1) - i - 1) = (nodalX(i+1)) * y; // north edge 3->2
1972  shape(4 + 4*(p-1) - i - 1) = (nodalY(i+1)) * (1. - x); // west edge 0->3
1973  }
1974 
1976  Vector bilinearsAtIP(4);
1977  bilinear.CalcShape(ip, bilinearsAtIP);
1978 
1979  const double *edgePts(poly1d.ClosedPoints(p, BasisType::GaussLobatto));
1980 
1981  // Next, set the shape function associated with vertex V, evaluated at (x,y)
1982  // to be: bilinear function associated to V, evaluated at (x,y) - sum (shape
1983  // function at edge point P, weighted by bilinear function for V evaluated at
1984  // P) where the sum is taken only for points P on edges incident to V.
1985 
1986  double vtx0fix =0;
1987  double vtx1fix =0;
1988  double vtx2fix =0;
1989  double vtx3fix =0;
1990  for (int i = 0; i<p-1; i++)
1991  {
1992  vtx0fix += (1-edgePts[i+1])*(shape(4 + i) +
1993  shape(4 + 4*(p-1) - i - 1)); // bot+left edge
1994  vtx1fix += (1-edgePts[i+1])*(shape(4 + 1*(p-1) + i) +
1995  shape(4 + (p-2)-i)); // right+bot edge
1996  vtx2fix += (1-edgePts[i+1])*(shape(4 + 2*(p-1) + i) +
1997  shape(1 + 2*p-i)); // top+right edge
1998  vtx3fix += (1-edgePts[i+1])*(shape(4 + 3*(p-1) + i) +
1999  shape(3*p - i)); // left+top edge
2000  }
2001  shape(0) = bilinearsAtIP(0) - vtx0fix;
2002  shape(1) = bilinearsAtIP(1) - vtx1fix;
2003  shape(2) = bilinearsAtIP(2) - vtx2fix;
2004  shape(3) = bilinearsAtIP(3) - vtx3fix;
2005 
2006  // Interior basis functions appear starting at order p=4. These are non-nodal
2007  // bubble functions.
2008  if (p > 3)
2009  {
2010  double *legX = new double[p-1];
2011  double *legY = new double[p-1];
2012  Poly_1D *storeLegendre = new Poly_1D();
2013 
2014  storeLegendre->CalcLegendre(p-2, x, legX);
2015  storeLegendre->CalcLegendre(p-2, y, legY);
2016 
2017  int interior_total = 0;
2018  for (int j = 4; j < p + 1; j++)
2019  {
2020  for (int k = 0; k < j-3; k++)
2021  {
2022  shape(4 + 4*(p-1) + interior_total)
2023  = legX[k] * legY[j-4-k] * x * (1. - x) * y * (1. - y);
2024  interior_total++;
2025  }
2026  }
2027 
2028  delete[] legX;
2029  delete[] legY;
2030  delete storeLegendre;
2031  }
2032 }
2033 
2035  DenseMatrix &dshape) const
2036 {
2037  int p = (this)->GetOrder();
2038  double x = ip.x, y = ip.y;
2039 
2041  Vector nodalX(p+1);
2042  Vector DnodalX(p+1);
2043  Vector nodalY(p+1);
2044  Vector DnodalY(p+1);
2045 
2046  edgeNodalBasis.Eval(x, nodalX, DnodalX);
2047  edgeNodalBasis.Eval(y, nodalY, DnodalY);
2048 
2049  for (int i = 0; i < p-1; i++)
2050  {
2051  dshape(4 + 0*(p-1) + i,0) = DnodalX(i+1) * (1.-y);
2052  dshape(4 + 0*(p-1) + i,1) = -nodalX(i+1);
2053  dshape(4 + 1*(p-1) + i,0) = nodalY(i+1);
2054  dshape(4 + 1*(p-1) + i,1) = DnodalY(i+1)*x;
2055  dshape(4 + 3*(p-1) - i - 1,0) = DnodalX(i+1)*y;
2056  dshape(4 + 3*(p-1) - i - 1,1) = nodalX(i+1);
2057  dshape(4 + 4*(p-1) - i - 1,0) = -nodalY(i+1);
2058  dshape(4 + 4*(p-1) - i - 1,1) = DnodalY(i+1) * (1.-x);
2059  }
2060 
2062  DenseMatrix DbilinearsAtIP(4);
2063  bilinear.CalcDShape(ip, DbilinearsAtIP);
2064 
2065  const double *edgePts(poly1d.ClosedPoints(p, BasisType::GaussLobatto));
2066 
2067  dshape(0,0) = DbilinearsAtIP(0,0);
2068  dshape(0,1) = DbilinearsAtIP(0,1);
2069  dshape(1,0) = DbilinearsAtIP(1,0);
2070  dshape(1,1) = DbilinearsAtIP(1,1);
2071  dshape(2,0) = DbilinearsAtIP(2,0);
2072  dshape(2,1) = DbilinearsAtIP(2,1);
2073  dshape(3,0) = DbilinearsAtIP(3,0);
2074  dshape(3,1) = DbilinearsAtIP(3,1);
2075 
2076  for (int i = 0; i<p-1; i++)
2077  {
2078  dshape(0,0) -= (1-edgePts[i+1])*(dshape(4 + 0*(p-1) + i, 0) +
2079  dshape(4 + 4*(p-1) - i - 1,0));
2080  dshape(0,1) -= (1-edgePts[i+1])*(dshape(4 + 0*(p-1) + i, 1) +
2081  dshape(4 + 4*(p-1) - i - 1,1));
2082  dshape(1,0) -= (1-edgePts[i+1])*(dshape(4 + 1*(p-1) + i, 0) +
2083  dshape(4 + (p-2)-i, 0));
2084  dshape(1,1) -= (1-edgePts[i+1])*(dshape(4 + 1*(p-1) + i, 1) +
2085  dshape(4 + (p-2)-i, 1));
2086  dshape(2,0) -= (1-edgePts[i+1])*(dshape(4 + 2*(p-1) + i, 0) +
2087  dshape(1 + 2*p-i, 0));
2088  dshape(2,1) -= (1-edgePts[i+1])*(dshape(4 + 2*(p-1) + i, 1) +
2089  dshape(1 + 2*p-i, 1));
2090  dshape(3,0) -= (1-edgePts[i+1])*(dshape(4 + 3*(p-1) + i, 0) +
2091  dshape(3*p - i, 0));
2092  dshape(3,1) -= (1-edgePts[i+1])*(dshape(4 + 3*(p-1) + i, 1) +
2093  dshape(3*p - i, 1));
2094  }
2095 
2096  if (p > 3)
2097  {
2098  double *legX = new double[p-1];
2099  double *legY = new double[p-1];
2100  double *DlegX = new double[p-1];
2101  double *DlegY = new double[p-1];
2102  Poly_1D *storeLegendre = new Poly_1D();
2103 
2104  storeLegendre->CalcLegendre(p-2, x, legX, DlegX);
2105  storeLegendre->CalcLegendre(p-2, y, legY, DlegY);
2106 
2107  int interior_total = 0;
2108  for (int j = 4; j < p + 1; j++)
2109  {
2110  for (int k = 0; k < j-3; k++)
2111  {
2112  dshape(4 + 4*(p-1) + interior_total, 0) =
2113  legY[j-4-k]*y*(1-y) * (DlegX[k]*x*(1-x) + legX[k]*(1-2*x));
2114  dshape(4 + 4*(p-1) + interior_total, 1) =
2115  legX[k]*x*(1-x) * (DlegY[j-4-k]*y*(1-y) + legY[j-4-k]*(1-2*y));
2116  interior_total++;
2117  }
2118  }
2119  delete[] legX;
2120  delete[] legY;
2121  delete[] DlegX;
2122  delete[] DlegY;
2123  delete storeLegendre;
2124  }
2125 }
2126 
2128  &Trans,
2129  DenseMatrix &I) const
2130 {
2131  // For p<=4, the basis is nodal; for p>4, the quad-interior functions are
2132  // non-nodal.
2133  if (Order <= 4)
2134  {
2135  NodalLocalInterpolation(Trans, I, *this);
2136  }
2137  else
2138  {
2139  ScalarLocalInterpolation(Trans, I, *this);
2140  }
2141 }
2142 
2143 
2145  : PositiveFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
2146 {
2147  Nodes.IntPoint(0).x = 0.0;
2148  Nodes.IntPoint(0).y = 0.0;
2149  Nodes.IntPoint(1).x = 1.0;
2150  Nodes.IntPoint(1).y = 0.0;
2151  Nodes.IntPoint(2).x = 1.0;
2152  Nodes.IntPoint(2).y = 1.0;
2153  Nodes.IntPoint(3).x = 0.0;
2154  Nodes.IntPoint(3).y = 1.0;
2155  Nodes.IntPoint(4).x = 0.5;
2156  Nodes.IntPoint(4).y = 0.0;
2157  Nodes.IntPoint(5).x = 1.0;
2158  Nodes.IntPoint(5).y = 0.5;
2159  Nodes.IntPoint(6).x = 0.5;
2160  Nodes.IntPoint(6).y = 1.0;
2161  Nodes.IntPoint(7).x = 0.0;
2162  Nodes.IntPoint(7).y = 0.5;
2163  Nodes.IntPoint(8).x = 0.5;
2164  Nodes.IntPoint(8).y = 0.5;
2165 }
2166 
2168  Vector &shape) const
2169 {
2170  double x = ip.x, y = ip.y;
2171  double l1x, l2x, l3x, l1y, l2y, l3y;
2172 
2173  l1x = (1. - x) * (1. - x);
2174  l2x = 2. * x * (1. - x);
2175  l3x = x * x;
2176  l1y = (1. - y) * (1. - y);
2177  l2y = 2. * y * (1. - y);
2178  l3y = y * y;
2179 
2180  shape(0) = l1x * l1y;
2181  shape(4) = l2x * l1y;
2182  shape(1) = l3x * l1y;
2183  shape(7) = l1x * l2y;
2184  shape(8) = l2x * l2y;
2185  shape(5) = l3x * l2y;
2186  shape(3) = l1x * l3y;
2187  shape(6) = l2x * l3y;
2188  shape(2) = l3x * l3y;
2189 }
2190 
2192  DenseMatrix &dshape) const
2193 {
2194  double x = ip.x, y = ip.y;
2195  double l1x, l2x, l3x, l1y, l2y, l3y;
2196  double d1x, d2x, d3x, d1y, d2y, d3y;
2197 
2198  l1x = (1. - x) * (1. - x);
2199  l2x = 2. * x * (1. - x);
2200  l3x = x * x;
2201  l1y = (1. - y) * (1. - y);
2202  l2y = 2. * y * (1. - y);
2203  l3y = y * y;
2204 
2205  d1x = 2. * x - 2.;
2206  d2x = 2. - 4. * x;
2207  d3x = 2. * x;
2208  d1y = 2. * y - 2.;
2209  d2y = 2. - 4. * y;
2210  d3y = 2. * y;
2211 
2212  dshape(0,0) = d1x * l1y;
2213  dshape(0,1) = l1x * d1y;
2214 
2215  dshape(4,0) = d2x * l1y;
2216  dshape(4,1) = l2x * d1y;
2217 
2218  dshape(1,0) = d3x * l1y;
2219  dshape(1,1) = l3x * d1y;
2220 
2221  dshape(7,0) = d1x * l2y;
2222  dshape(7,1) = l1x * d2y;
2223 
2224  dshape(8,0) = d2x * l2y;
2225  dshape(8,1) = l2x * d2y;
2226 
2227  dshape(5,0) = d3x * l2y;
2228  dshape(5,1) = l3x * d2y;
2229 
2230  dshape(3,0) = d1x * l3y;
2231  dshape(3,1) = l1x * d3y;
2232 
2233  dshape(6,0) = d2x * l3y;
2234  dshape(6,1) = l2x * d3y;
2235 
2236  dshape(2,0) = d3x * l3y;
2237  dshape(2,1) = l3x * d3y;
2238 }
2239 
2242 {
2243  double s[9];
2244  IntegrationPoint tr_ip;
2245  Vector xx(&tr_ip.x, 2), shape(s, 9);
2246 
2247  for (int i = 0; i < 9; i++)
2248  {
2249  Trans.Transform(Nodes.IntPoint(i), xx);
2250  CalcShape(tr_ip, shape);
2251  for (int j = 0; j < 9; j++)
2252  if (fabs(I(i,j) = s[j]) < 1.0e-12)
2253  {
2254  I(i,j) = 0.0;
2255  }
2256  }
2257  for (int i = 0; i < 9; i++)
2258  {
2259  double *d = &I(0,i);
2260  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2261  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2262  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2263  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2264  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2265  0.25 * (d[0] + d[1] + d[2] + d[3]);
2266  }
2267 }
2268 
2270  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
2271 {
2272  double *d = dofs;
2273 
2274  for (int i = 0; i < 9; i++)
2275  {
2276  const IntegrationPoint &ip = Nodes.IntPoint(i);
2277  Trans.SetIntPoint(&ip);
2278  d[i] = coeff.Eval(Trans, ip);
2279  }
2280  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2281  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2282  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2283  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2284  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2285  0.25 * (d[0] + d[1] + d[2] + d[3]);
2286 }
2287 
2290  Vector &dofs) const
2291 {
2292  double v[3];
2293  Vector x (v, vc.GetVDim());
2294 
2295  for (int i = 0; i < 9; i++)
2296  {
2297  const IntegrationPoint &ip = Nodes.IntPoint(i);
2298  Trans.SetIntPoint(&ip);
2299  vc.Eval (x, Trans, ip);
2300  for (int j = 0; j < x.Size(); j++)
2301  {
2302  dofs(9*j+i) = v[j];
2303  }
2304  }
2305  for (int j = 0; j < x.Size(); j++)
2306  {
2307  double *d = &dofs(9*j);
2308 
2309  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2310  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2311  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2312  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2313  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2314  0.25 * (d[0] + d[1] + d[2] + d[3]);
2315  }
2316 }
2317 
2318 
2320  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
2321 {
2322  const double p1 = 0.5*(1.-sqrt(3./5.));
2323 
2324  Nodes.IntPoint(0).x = p1;
2325  Nodes.IntPoint(0).y = p1;
2326  Nodes.IntPoint(4).x = 0.5;
2327  Nodes.IntPoint(4).y = p1;
2328  Nodes.IntPoint(1).x = 1.-p1;
2329  Nodes.IntPoint(1).y = p1;
2330  Nodes.IntPoint(7).x = p1;
2331  Nodes.IntPoint(7).y = 0.5;
2332  Nodes.IntPoint(8).x = 0.5;
2333  Nodes.IntPoint(8).y = 0.5;
2334  Nodes.IntPoint(5).x = 1.-p1;
2335  Nodes.IntPoint(5).y = 0.5;
2336  Nodes.IntPoint(3).x = p1;
2337  Nodes.IntPoint(3).y = 1.-p1;
2338  Nodes.IntPoint(6).x = 0.5;
2339  Nodes.IntPoint(6).y = 1.-p1;
2340  Nodes.IntPoint(2).x = 1.-p1;
2341  Nodes.IntPoint(2).y = 1.-p1;
2342 }
2343 
2345  Vector &shape) const
2346 {
2347  const double a = sqrt(5./3.);
2348  const double p1 = 0.5*(1.-sqrt(3./5.));
2349 
2350  double x = a*(ip.x-p1), y = a*(ip.y-p1);
2351  double l1x, l2x, l3x, l1y, l2y, l3y;
2352 
2353  l1x = (x - 1.) * (2. * x - 1);
2354  l2x = 4. * x * (1. - x);
2355  l3x = x * (2. * x - 1.);
2356  l1y = (y - 1.) * (2. * y - 1);
2357  l2y = 4. * y * (1. - y);
2358  l3y = y * (2. * y - 1.);
2359 
2360  shape(0) = l1x * l1y;
2361  shape(4) = l2x * l1y;
2362  shape(1) = l3x * l1y;
2363  shape(7) = l1x * l2y;
2364  shape(8) = l2x * l2y;
2365  shape(5) = l3x * l2y;
2366  shape(3) = l1x * l3y;
2367  shape(6) = l2x * l3y;
2368  shape(2) = l3x * l3y;
2369 }
2370 
2372  DenseMatrix &dshape) const
2373 {
2374  const double a = sqrt(5./3.);
2375  const double p1 = 0.5*(1.-sqrt(3./5.));
2376 
2377  double x = a*(ip.x-p1), y = a*(ip.y-p1);
2378  double l1x, l2x, l3x, l1y, l2y, l3y;
2379  double d1x, d2x, d3x, d1y, d2y, d3y;
2380 
2381  l1x = (x - 1.) * (2. * x - 1);
2382  l2x = 4. * x * (1. - x);
2383  l3x = x * (2. * x - 1.);
2384  l1y = (y - 1.) * (2. * y - 1);
2385  l2y = 4. * y * (1. - y);
2386  l3y = y * (2. * y - 1.);
2387 
2388  d1x = a * (4. * x - 3.);
2389  d2x = a * (4. - 8. * x);
2390  d3x = a * (4. * x - 1.);
2391  d1y = a * (4. * y - 3.);
2392  d2y = a * (4. - 8. * y);
2393  d3y = a * (4. * y - 1.);
2394 
2395  dshape(0,0) = d1x * l1y;
2396  dshape(0,1) = l1x * d1y;
2397 
2398  dshape(4,0) = d2x * l1y;
2399  dshape(4,1) = l2x * d1y;
2400 
2401  dshape(1,0) = d3x * l1y;
2402  dshape(1,1) = l3x * d1y;
2403 
2404  dshape(7,0) = d1x * l2y;
2405  dshape(7,1) = l1x * d2y;
2406 
2407  dshape(8,0) = d2x * l2y;
2408  dshape(8,1) = l2x * d2y;
2409 
2410  dshape(5,0) = d3x * l2y;
2411  dshape(5,1) = l3x * d2y;
2412 
2413  dshape(3,0) = d1x * l3y;
2414  dshape(3,1) = l1x * d3y;
2415 
2416  dshape(6,0) = d2x * l3y;
2417  dshape(6,1) = l2x * d3y;
2418 
2419  dshape(2,0) = d3x * l3y;
2420  dshape(2,1) = l3x * d3y;
2421 }
2422 
2424  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
2425 {
2426  Nodes.IntPoint(0).x = 0.;
2427  Nodes.IntPoint(0).y = 0.;
2428  Nodes.IntPoint(1).x = 1.;
2429  Nodes.IntPoint(1).y = 0.;
2430  Nodes.IntPoint(2).x = 1.;
2431  Nodes.IntPoint(2).y = 1.;
2432  Nodes.IntPoint(3).x = 0.;
2433  Nodes.IntPoint(3).y = 1.;
2434  Nodes.IntPoint(4).x = 1./3.;
2435  Nodes.IntPoint(4).y = 0.;
2436  Nodes.IntPoint(5).x = 2./3.;
2437  Nodes.IntPoint(5).y = 0.;
2438  Nodes.IntPoint(6).x = 1.;
2439  Nodes.IntPoint(6).y = 1./3.;
2440  Nodes.IntPoint(7).x = 1.;
2441  Nodes.IntPoint(7).y = 2./3.;
2442  Nodes.IntPoint(8).x = 2./3.;
2443  Nodes.IntPoint(8).y = 1.;
2444  Nodes.IntPoint(9).x = 1./3.;
2445  Nodes.IntPoint(9).y = 1.;
2446  Nodes.IntPoint(10).x = 0.;
2447  Nodes.IntPoint(10).y = 2./3.;
2448  Nodes.IntPoint(11).x = 0.;
2449  Nodes.IntPoint(11).y = 1./3.;
2450  Nodes.IntPoint(12).x = 1./3.;
2451  Nodes.IntPoint(12).y = 1./3.;
2452  Nodes.IntPoint(13).x = 2./3.;
2453  Nodes.IntPoint(13).y = 1./3.;
2454  Nodes.IntPoint(14).x = 1./3.;
2455  Nodes.IntPoint(14).y = 2./3.;
2456  Nodes.IntPoint(15).x = 2./3.;
2457  Nodes.IntPoint(15).y = 2./3.;
2458 }
2459 
2461  const IntegrationPoint &ip, Vector &shape) const
2462 {
2463  double x = ip.x, y = ip.y;
2464 
2465  double w1x, w2x, w3x, w1y, w2y, w3y;
2466  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2467 
2468  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2469  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2470 
2471  l0x = (- 4.5) * w1x * w2x * w3x;
2472  l1x = ( 13.5) * x * w2x * w3x;
2473  l2x = (-13.5) * x * w1x * w3x;
2474  l3x = ( 4.5) * x * w1x * w2x;
2475 
2476  l0y = (- 4.5) * w1y * w2y * w3y;
2477  l1y = ( 13.5) * y * w2y * w3y;
2478  l2y = (-13.5) * y * w1y * w3y;
2479  l3y = ( 4.5) * y * w1y * w2y;
2480 
2481  shape(0) = l0x * l0y;
2482  shape(1) = l3x * l0y;
2483  shape(2) = l3x * l3y;
2484  shape(3) = l0x * l3y;
2485  shape(4) = l1x * l0y;
2486  shape(5) = l2x * l0y;
2487  shape(6) = l3x * l1y;
2488  shape(7) = l3x * l2y;
2489  shape(8) = l2x * l3y;
2490  shape(9) = l1x * l3y;
2491  shape(10) = l0x * l2y;
2492  shape(11) = l0x * l1y;
2493  shape(12) = l1x * l1y;
2494  shape(13) = l2x * l1y;
2495  shape(14) = l1x * l2y;
2496  shape(15) = l2x * l2y;
2497 }
2498 
2500  const IntegrationPoint &ip, DenseMatrix &dshape) const
2501 {
2502  double x = ip.x, y = ip.y;
2503 
2504  double w1x, w2x, w3x, w1y, w2y, w3y;
2505  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2506  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
2507 
2508  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2509  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2510 
2511  l0x = (- 4.5) * w1x * w2x * w3x;
2512  l1x = ( 13.5) * x * w2x * w3x;
2513  l2x = (-13.5) * x * w1x * w3x;
2514  l3x = ( 4.5) * x * w1x * w2x;
2515 
2516  l0y = (- 4.5) * w1y * w2y * w3y;
2517  l1y = ( 13.5) * y * w2y * w3y;
2518  l2y = (-13.5) * y * w1y * w3y;
2519  l3y = ( 4.5) * y * w1y * w2y;
2520 
2521  d0x = -5.5 + ( 18. - 13.5 * x) * x;
2522  d1x = 9. + (-45. + 40.5 * x) * x;
2523  d2x = -4.5 + ( 36. - 40.5 * x) * x;
2524  d3x = 1. + (- 9. + 13.5 * x) * x;
2525 
2526  d0y = -5.5 + ( 18. - 13.5 * y) * y;
2527  d1y = 9. + (-45. + 40.5 * y) * y;
2528  d2y = -4.5 + ( 36. - 40.5 * y) * y;
2529  d3y = 1. + (- 9. + 13.5 * y) * y;
2530 
2531  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
2532  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
2533  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
2534  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
2535  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
2536  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
2537  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
2538  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
2539  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
2540  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
2541  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
2542  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
2543  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
2544  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
2545  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
2546  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
2547 }
2548 
2550  const IntegrationPoint &ip, DenseMatrix &h) const
2551 {
2552  double x = ip.x, y = ip.y;
2553 
2554  double w1x, w2x, w3x, w1y, w2y, w3y;
2555  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2556  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
2557  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
2558 
2559  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2560  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2561 
2562  l0x = (- 4.5) * w1x * w2x * w3x;
2563  l1x = ( 13.5) * x * w2x * w3x;
2564  l2x = (-13.5) * x * w1x * w3x;
2565  l3x = ( 4.5) * x * w1x * w2x;
2566 
2567  l0y = (- 4.5) * w1y * w2y * w3y;
2568  l1y = ( 13.5) * y * w2y * w3y;
2569  l2y = (-13.5) * y * w1y * w3y;
2570  l3y = ( 4.5) * y * w1y * w2y;
2571 
2572  d0x = -5.5 + ( 18. - 13.5 * x) * x;
2573  d1x = 9. + (-45. + 40.5 * x) * x;
2574  d2x = -4.5 + ( 36. - 40.5 * x) * x;
2575  d3x = 1. + (- 9. + 13.5 * x) * x;
2576 
2577  d0y = -5.5 + ( 18. - 13.5 * y) * y;
2578  d1y = 9. + (-45. + 40.5 * y) * y;
2579  d2y = -4.5 + ( 36. - 40.5 * y) * y;
2580  d3y = 1. + (- 9. + 13.5 * y) * y;
2581 
2582  h0x = -27. * x + 18.;
2583  h1x = 81. * x - 45.;
2584  h2x = -81. * x + 36.;
2585  h3x = 27. * x - 9.;
2586 
2587  h0y = -27. * y + 18.;
2588  h1y = 81. * y - 45.;
2589  h2y = -81. * y + 36.;
2590  h3y = 27. * y - 9.;
2591 
2592  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
2593  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
2594  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
2595  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
2596  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
2597  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
2598  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
2599  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
2600  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
2601  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
2602  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
2603  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
2604  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
2605  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
2606  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
2607  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
2608 }
2609 
2610 
2612  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
2613 {
2614  Nodes.IntPoint(0).x = 0.0;
2615  Nodes.IntPoint(1).x = 1.0;
2616  Nodes.IntPoint(2).x = 0.33333333333333333333;
2617  Nodes.IntPoint(3).x = 0.66666666666666666667;
2618 }
2619 
2621  Vector &shape) const
2622 {
2623  double x = ip.x;
2624  double l1 = x,
2625  l2 = (1.0-x),
2626  l3 = (0.33333333333333333333-x),
2627  l4 = (0.66666666666666666667-x);
2628 
2629  shape(0) = 4.5 * l2 * l3 * l4;
2630  shape(1) = 4.5 * l1 * l3 * l4;
2631  shape(2) = 13.5 * l1 * l2 * l4;
2632  shape(3) = -13.5 * l1 * l2 * l3;
2633 }
2634 
2636  DenseMatrix &dshape) const
2637 {
2638  double x = ip.x;
2639 
2640  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
2641  dshape(1,0) = 1. - x * (9. - 13.5 * x);
2642  dshape(2,0) = 9. - x * (45. - 40.5 * x);
2643  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
2644 }
2645 
2646 
2648  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
2649 {
2650  Nodes.IntPoint(0).x = 0.0;
2651  Nodes.IntPoint(0).y = 0.0;
2652  Nodes.IntPoint(1).x = 1.0;
2653  Nodes.IntPoint(1).y = 0.0;
2654  Nodes.IntPoint(2).x = 0.0;
2655  Nodes.IntPoint(2).y = 1.0;
2656  Nodes.IntPoint(3).x = 0.33333333333333333333;
2657  Nodes.IntPoint(3).y = 0.0;
2658  Nodes.IntPoint(4).x = 0.66666666666666666667;
2659  Nodes.IntPoint(4).y = 0.0;
2660  Nodes.IntPoint(5).x = 0.66666666666666666667;
2661  Nodes.IntPoint(5).y = 0.33333333333333333333;
2662  Nodes.IntPoint(6).x = 0.33333333333333333333;
2663  Nodes.IntPoint(6).y = 0.66666666666666666667;
2664  Nodes.IntPoint(7).x = 0.0;
2665  Nodes.IntPoint(7).y = 0.66666666666666666667;
2666  Nodes.IntPoint(8).x = 0.0;
2667  Nodes.IntPoint(8).y = 0.33333333333333333333;
2668  Nodes.IntPoint(9).x = 0.33333333333333333333;
2669  Nodes.IntPoint(9).y = 0.33333333333333333333;
2670 }
2671 
2673  Vector &shape) const
2674 {
2675  double x = ip.x, y = ip.y;
2676  double l1 = (-1. + x + y),
2677  lx = (-1. + 3.*x),
2678  ly = (-1. + 3.*y);
2679 
2680  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
2681  shape(1) = 0.5*x*(lx - 1.)*lx;
2682  shape(2) = 0.5*y*(-1. + ly)*ly;
2683  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
2684  shape(4) = -4.5*x*lx*l1;
2685  shape(5) = 4.5*x*lx*y;
2686  shape(6) = 4.5*x*y*ly;
2687  shape(7) = -4.5*y*l1*ly;
2688  shape(8) = 4.5*y*l1*(1. + 3.*l1);
2689  shape(9) = -27.*x*y*l1;
2690 }
2691 
2693  DenseMatrix &dshape) const
2694 {
2695  double x = ip.x, y = ip.y;
2696 
2697  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2698  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
2699  dshape(2,0) = 0.;
2700  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
2701  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
2702  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
2703  dshape(6,0) = 4.5*y*(-1. + 3.*y);
2704  dshape(7,0) = 4.5*(1. - 3.*y)*y;
2705  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
2706  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
2707 
2708  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2709  dshape(1,1) = 0.;
2710  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
2711  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
2712  dshape(4,1) = 4.5*(1. - 3.*x)*x;
2713  dshape(5,1) = 4.5*x*(-1. + 3.*x);
2714  dshape(6,1) = 4.5*x*(-1. + 6.*y);
2715  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
2716  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
2717  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
2718 }
2719 
2721  DenseMatrix &h) const
2722 {
2723  double x = ip.x, y = ip.y;
2724 
2725  h(0,0) = 18.-27.*(x+y);
2726  h(0,1) = 18.-27.*(x+y);
2727  h(0,2) = 18.-27.*(x+y);
2728 
2729  h(1,0) = -9.+27.*x;
2730  h(1,1) = 0.;
2731  h(1,2) = 0.;
2732 
2733  h(2,0) = 0.;
2734  h(2,1) = 0.;
2735  h(2,2) = -9.+27.*y;
2736 
2737  h(3,0) = -45.+81.*x+54.*y;
2738  h(3,1) = -22.5+54.*x+27.*y;
2739  h(3,2) = 27.*x;
2740 
2741  h(4,0) = 36.-81.*x-27.*y;
2742  h(4,1) = 4.5-27.*x;
2743  h(4,2) = 0.;
2744 
2745  h(5,0) = 27.*y;
2746  h(5,1) = -4.5+27.*x;
2747  h(5,2) = 0.;
2748 
2749  h(6,0) = 0.;
2750  h(6,1) = -4.5+27.*y;
2751  h(6,2) = 27.*x;
2752 
2753  h(7,0) = 0.;
2754  h(7,1) = 4.5-27.*y;
2755  h(7,2) = 36.-27.*x-81.*y;
2756 
2757  h(8,0) = 27.*y;
2758  h(8,1) = -22.5+27.*x+54.*y;
2759  h(8,2) = -45.+54.*x+81.*y;
2760 
2761  h(9,0) = -54.*y;
2762  h(9,1) = 27.-54.*(x+y);
2763  h(9,2) = -54.*x;
2764 }
2765 
2766 
2768  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
2769 {
2770  Nodes.IntPoint(0).x = 0;
2771  Nodes.IntPoint(0).y = 0;
2772  Nodes.IntPoint(0).z = 0;
2773  Nodes.IntPoint(1).x = 1.;
2774  Nodes.IntPoint(1).y = 0;
2775  Nodes.IntPoint(1).z = 0;
2776  Nodes.IntPoint(2).x = 0;
2777  Nodes.IntPoint(2).y = 1.;
2778  Nodes.IntPoint(2).z = 0;
2779  Nodes.IntPoint(3).x = 0;
2780  Nodes.IntPoint(3).y = 0;
2781  Nodes.IntPoint(3).z = 1.;
2782  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
2783  Nodes.IntPoint(4).y = 0;
2784  Nodes.IntPoint(4).z = 0;
2785  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
2786  Nodes.IntPoint(5).y = 0;
2787  Nodes.IntPoint(5).z = 0;
2788  Nodes.IntPoint(6).x = 0;
2789  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
2790  Nodes.IntPoint(6).z = 0;
2791  Nodes.IntPoint(7).x = 0;
2792  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
2793  Nodes.IntPoint(7).z = 0;
2794  Nodes.IntPoint(8).x = 0;
2795  Nodes.IntPoint(8).y = 0;
2796  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
2797  Nodes.IntPoint(9).x = 0;
2798  Nodes.IntPoint(9).y = 0;
2799  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
2800  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
2801  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
2802  Nodes.IntPoint(10).z = 0;
2803  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
2804  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
2805  Nodes.IntPoint(11).z = 0;
2806  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
2807  Nodes.IntPoint(12).y = 0;
2808  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
2809  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
2810  Nodes.IntPoint(13).y = 0;
2811  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
2812  Nodes.IntPoint(14).x = 0;
2813  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
2814  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
2815  Nodes.IntPoint(15).x = 0;
2816  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
2817  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
2818  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
2819  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
2820  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
2821  Nodes.IntPoint(17).x = 0;
2822  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
2823  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
2824  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
2825  Nodes.IntPoint(18).y = 0;
2826  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
2827  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
2828  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
2829  Nodes.IntPoint(19).z = 0;
2830 }
2831 
2833  Vector &shape) const
2834 {
2835  double x = ip.x, y = ip.y, z = ip.z;
2836 
2837  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
2838  (-1 + 3*x + 3*y + 3*z))/2.;
2839  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2840  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
2841  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
2842  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2843  shape(19) = -27*x*y*(-1 + x + y + z);
2844  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
2845  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
2846  shape(11) = (9*x*y*(-1 + 3*y))/2.;
2847  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
2848  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2849  shape(18) = -27*x*z*(-1 + x + y + z);
2850  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
2851  shape(17) = -27*y*z*(-1 + x + y + z);
2852  shape(16) = 27*x*y*z;
2853  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
2854  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
2855  shape(13) = (9*x*z*(-1 + 3*z))/2.;
2856  shape(15) = (9*y*z*(-1 + 3*z))/2.;
2857  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
2858 }
2859 
2861  DenseMatrix &dshape) const
2862 {
2863  double x = ip.x, y = ip.y, z = ip.z;
2864 
2865  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2866  x*(-4 + 6*y + 6*z)))/2.;
2867  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2868  x*(-4 + 6*y + 6*z)))/2.;
2869  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2870  x*(-4 + 6*y + 6*z)))/2.;
2871  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
2872  2*x*(-5 + 6*y + 6*z)))/2.;
2873  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2874  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2875  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
2876  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
2877  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
2878  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
2879  dshape(1,1) = 0;
2880  dshape(1,2) = 0;
2881  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2882  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
2883  x*(-5 + 12*y + 6*z)))/2.;
2884  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2885  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
2886  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
2887  dshape(19,2) = -27*x*y;
2888  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
2889  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
2890  dshape(10,2) = 0;
2891  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
2892  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
2893  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
2894  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
2895  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
2896  dshape(11,2) = 0;
2897  dshape(2,0) = 0;
2898  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
2899  dshape(2,2) = 0;
2900  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2901  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2902  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
2903  x*(-5 + 6*y + 12*z)))/2.;
2904  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
2905  dshape(18,1) = -27*x*z;
2906  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
2907  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
2908  dshape(12,1) = 0;
2909  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
2910  dshape(17,0) = -27*y*z;
2911  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
2912  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
2913  dshape(16,0) = 27*y*z;
2914  dshape(16,1) = 27*x*z;
2915  dshape(16,2) = 27*x*y;
2916  dshape(14,0) = 0;
2917  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
2918  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
2919  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
2920  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
2921  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
2922  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
2923  dshape(13,1) = 0;
2924  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
2925  dshape(15,0) = 0;
2926  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
2927  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
2928  dshape(3,0) = 0;
2929  dshape(3,1) = 0;
2930  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
2931 }
2932 
2933 
2935  : NodalFiniteElement(2, Geometry::TRIANGLE, 1, 0)
2936 {
2937  Nodes.IntPoint(0).x = 0.333333333333333333;
2938  Nodes.IntPoint(0).y = 0.333333333333333333;
2939 }
2940 
2942  Vector &shape) const
2943 {
2944  shape(0) = 1.0;
2945 }
2946 
2948  DenseMatrix &dshape) const
2949 {
2950  dshape(0,0) = 0.0;
2951  dshape(0,1) = 0.0;
2952 }
2953 
2954 
2956  : NodalFiniteElement(2, Geometry::SQUARE, 1, 0, FunctionSpace::Qk)
2957 {
2958  Nodes.IntPoint(0).x = 0.5;
2959  Nodes.IntPoint(0).y = 0.5;
2960 }
2961 
2963  Vector &shape) const
2964 {
2965  shape(0) = 1.0;
2966 }
2967 
2969  DenseMatrix &dshape) const
2970 {
2971  dshape(0,0) = 0.0;
2972  dshape(0,1) = 0.0;
2973 }
2974 
2975 
2977  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
2978 {
2979  Nodes.IntPoint(0).x = 0.0;
2980  Nodes.IntPoint(0).y = 0.0;
2981  Nodes.IntPoint(0).z = 0.0;
2982  Nodes.IntPoint(1).x = 1.0;
2983  Nodes.IntPoint(1).y = 0.0;
2984  Nodes.IntPoint(1).z = 0.0;
2985  Nodes.IntPoint(2).x = 0.0;
2986  Nodes.IntPoint(2).y = 1.0;
2987  Nodes.IntPoint(2).z = 0.0;
2988  Nodes.IntPoint(3).x = 0.0;
2989  Nodes.IntPoint(3).y = 0.0;
2990  Nodes.IntPoint(3).z = 1.0;
2991 }
2992 
2994  Vector &shape) const
2995 {
2996  shape(0) = 1. - ip.x - ip.y - ip.z;
2997  shape(1) = ip.x;
2998  shape(2) = ip.y;
2999  shape(3) = ip.z;
3000 }
3001 
3003  DenseMatrix &dshape) const
3004 {
3005  if (dshape.Height() == 4)
3006  {
3007  double *A = &dshape(0,0);
3008  A[0] = -1.; A[4] = -1.; A[8] = -1.;
3009  A[1] = 1.; A[5] = 0.; A[9] = 0.;
3010  A[2] = 0.; A[6] = 1.; A[10] = 0.;
3011  A[3] = 0.; A[7] = 0.; A[11] = 1.;
3012  }
3013  else
3014  {
3015  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
3016  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
3017  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
3018  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
3019  }
3020 }
3021 
3022 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
3023 const
3024 {
3025  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
3026 
3027  *ndofs = 3;
3028  *dofs = face_dofs[face];
3029 }
3030 
3031 
3033  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
3034 {
3035  Nodes.IntPoint(0).x = 0.0;
3036  Nodes.IntPoint(0).y = 0.0;
3037  Nodes.IntPoint(0).z = 0.0;
3038  Nodes.IntPoint(1).x = 1.0;
3039  Nodes.IntPoint(1).y = 0.0;
3040  Nodes.IntPoint(1).z = 0.0;
3041  Nodes.IntPoint(2).x = 0.0;
3042  Nodes.IntPoint(2).y = 1.0;
3043  Nodes.IntPoint(2).z = 0.0;
3044  Nodes.IntPoint(3).x = 0.0;
3045  Nodes.IntPoint(3).y = 0.0;
3046  Nodes.IntPoint(3).z = 1.0;
3047  Nodes.IntPoint(4).x = 0.5;
3048  Nodes.IntPoint(4).y = 0.0;
3049  Nodes.IntPoint(4).z = 0.0;
3050  Nodes.IntPoint(5).x = 0.0;
3051  Nodes.IntPoint(5).y = 0.5;
3052  Nodes.IntPoint(5).z = 0.0;
3053  Nodes.IntPoint(6).x = 0.0;
3054  Nodes.IntPoint(6).y = 0.0;
3055  Nodes.IntPoint(6).z = 0.5;
3056  Nodes.IntPoint(7).x = 0.5;
3057  Nodes.IntPoint(7).y = 0.5;
3058  Nodes.IntPoint(7).z = 0.0;
3059  Nodes.IntPoint(8).x = 0.5;
3060  Nodes.IntPoint(8).y = 0.0;
3061  Nodes.IntPoint(8).z = 0.5;
3062  Nodes.IntPoint(9).x = 0.0;
3063  Nodes.IntPoint(9).y = 0.5;
3064  Nodes.IntPoint(9).z = 0.5;
3065 }
3066 
3068  Vector &shape) const
3069 {
3070  double L0, L1, L2, L3;
3071 
3072  L0 = 1. - ip.x - ip.y - ip.z;
3073  L1 = ip.x;
3074  L2 = ip.y;
3075  L3 = ip.z;
3076 
3077  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
3078  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
3079  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
3080  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
3081  shape(4) = 4.0 * L0 * L1;
3082  shape(5) = 4.0 * L0 * L2;
3083  shape(6) = 4.0 * L0 * L3;
3084  shape(7) = 4.0 * L1 * L2;
3085  shape(8) = 4.0 * L1 * L3;
3086  shape(9) = 4.0 * L2 * L3;
3087 }
3088 
3090  DenseMatrix &dshape) const
3091 {
3092  double x, y, z, L0;
3093 
3094  x = ip.x;
3095  y = ip.y;
3096  z = ip.z;
3097  L0 = 1.0 - x - y - z;
3098 
3099  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
3100  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
3101  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
3102  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
3103  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
3104  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
3105  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
3106  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
3107  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
3108  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
3109 }
3110 
3112  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
3113 {
3114  Nodes.IntPoint(0).x = 0.0;
3115  Nodes.IntPoint(0).y = 0.0;
3116  Nodes.IntPoint(0).z = 0.0;
3117 
3118  Nodes.IntPoint(1).x = 1.0;
3119  Nodes.IntPoint(1).y = 0.0;
3120  Nodes.IntPoint(1).z = 0.0;
3121 
3122  Nodes.IntPoint(2).x = 1.0;
3123  Nodes.IntPoint(2).y = 1.0;
3124  Nodes.IntPoint(2).z = 0.0;
3125 
3126  Nodes.IntPoint(3).x = 0.0;
3127  Nodes.IntPoint(3).y = 1.0;
3128  Nodes.IntPoint(3).z = 0.0;
3129 
3130  Nodes.IntPoint(4).x = 0.0;
3131  Nodes.IntPoint(4).y = 0.0;
3132  Nodes.IntPoint(4).z = 1.0;
3133 
3134  Nodes.IntPoint(5).x = 1.0;
3135  Nodes.IntPoint(5).y = 0.0;
3136  Nodes.IntPoint(5).z = 1.0;
3137 
3138  Nodes.IntPoint(6).x = 1.0;
3139  Nodes.IntPoint(6).y = 1.0;
3140  Nodes.IntPoint(6).z = 1.0;
3141 
3142  Nodes.IntPoint(7).x = 0.0;
3143  Nodes.IntPoint(7).y = 1.0;
3144  Nodes.IntPoint(7).z = 1.0;
3145 }
3146 
3148  Vector &shape) const
3149 {
3150  double x = ip.x, y = ip.y, z = ip.z;
3151  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
3152 
3153  shape(0) = ox * oy * oz;
3154  shape(1) = x * oy * oz;
3155  shape(2) = x * y * oz;
3156  shape(3) = ox * y * oz;
3157  shape(4) = ox * oy * z;
3158  shape(5) = x * oy * z;
3159  shape(6) = x * y * z;
3160  shape(7) = ox * y * z;
3161 }
3162 
3164  DenseMatrix &dshape) const
3165 {
3166  double x = ip.x, y = ip.y, z = ip.z;
3167  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
3168 
3169  dshape(0,0) = - oy * oz;
3170  dshape(0,1) = - ox * oz;
3171  dshape(0,2) = - ox * oy;
3172 
3173  dshape(1,0) = oy * oz;
3174  dshape(1,1) = - x * oz;
3175  dshape(1,2) = - x * oy;
3176 
3177  dshape(2,0) = y * oz;
3178  dshape(2,1) = x * oz;
3179  dshape(2,2) = - x * y;
3180 
3181  dshape(3,0) = - y * oz;
3182  dshape(3,1) = ox * oz;
3183  dshape(3,2) = - ox * y;
3184 
3185  dshape(4,0) = - oy * z;
3186  dshape(4,1) = - ox * z;
3187  dshape(4,2) = ox * oy;
3188 
3189  dshape(5,0) = oy * z;
3190  dshape(5,1) = - x * z;
3191  dshape(5,2) = x * oy;
3192 
3193  dshape(6,0) = y * z;
3194  dshape(6,1) = x * z;
3195  dshape(6,2) = x * y;
3196 
3197  dshape(7,0) = - y * z;
3198  dshape(7,1) = ox * z;
3199  dshape(7,2) = ox * y;
3200 }
3201 
3202 
3204  : NodalFiniteElement(1, Geometry::SEGMENT, 1, Ord) // defaul Ord = 0
3205 {
3206  Nodes.IntPoint(0).x = 0.5;
3207 }
3208 
3210  Vector &shape) const
3211 {
3212  shape(0) = 1.0;
3213 }
3214 
3216  DenseMatrix &dshape) const
3217 {
3218  dshape(0,0) = 0.0;
3219 }
3220 
3222  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
3223 {
3224  Nodes.IntPoint(0).x = 0.5;
3225  Nodes.IntPoint(0).y = 0.0;
3226  Nodes.IntPoint(1).x = 0.5;
3227  Nodes.IntPoint(1).y = 0.5;
3228  Nodes.IntPoint(2).x = 0.0;
3229  Nodes.IntPoint(2).y = 0.5;
3230 }
3231 
3233  Vector &shape) const
3234 {
3235  shape(0) = 1.0 - 2.0 * ip.y;
3236  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
3237  shape(2) = 1.0 - 2.0 * ip.x;
3238 }
3239 
3241  DenseMatrix &dshape) const
3242 {
3243  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
3244  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
3245  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
3246 }
3247 
3249 // the FunctionSpace should be rotated (45 degrees) Q_1
3250 // i.e. the span of { 1, x, y, x^2 - y^2 }
3251  : NodalFiniteElement(2, Geometry::SQUARE, 4, 2, FunctionSpace::Qk)
3252 {
3253  Nodes.IntPoint(0).x = 0.5;
3254  Nodes.IntPoint(0).y = 0.0;
3255  Nodes.IntPoint(1).x = 1.0;
3256  Nodes.IntPoint(1).y = 0.5;
3257  Nodes.IntPoint(2).x = 0.5;
3258  Nodes.IntPoint(2).y = 1.0;
3259  Nodes.IntPoint(3).x = 0.0;
3260  Nodes.IntPoint(3).y = 0.5;
3261 }
3262 
3264  Vector &shape) const
3265 {
3266  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
3267 
3268  shape(0) = l2 * l3;
3269  shape(1) = l1 * l3;
3270  shape(2) = l1 * l4;
3271  shape(3) = l2 * l4;
3272 }
3273 
3275  DenseMatrix &dshape) const
3276 {
3277  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
3278 
3279  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
3280  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
3281  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
3282  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
3283 }
3284 
3285 
3287  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
3288 {
3289  Nodes.IntPoint(0).x = 0.5;
3290  Nodes.IntPoint(0).y = 0.0;
3291  Nodes.IntPoint(1).x = 0.5;
3292  Nodes.IntPoint(1).y = 0.5;
3293  Nodes.IntPoint(2).x = 0.0;
3294  Nodes.IntPoint(2).y = 0.5;
3295 }
3296 
3298  DenseMatrix &shape) const
3299 {
3300  double x = ip.x, y = ip.y;
3301 
3302  shape(0,0) = x;
3303  shape(0,1) = y - 1.;
3304  shape(1,0) = x;
3305  shape(1,1) = y;
3306  shape(2,0) = x - 1.;
3307  shape(2,1) = y;
3308 }
3309 
3311  Vector &divshape) const
3312 {
3313  divshape(0) = 2.;
3314  divshape(1) = 2.;
3315  divshape(2) = 2.;
3316 }
3317 
3318 const double RT0TriangleFiniteElement::nk[3][2] =
3319 { {0, -1}, {1, 1}, {-1, 0} };
3320 
3323 {
3324  int k, j;
3325 #ifdef MFEM_THREAD_SAFE
3327  DenseMatrix Jinv(Dim);
3328 #endif
3329 
3330 #ifdef MFEM_DEBUG
3331  for (k = 0; k < 3; k++)
3332  {
3334  for (j = 0; j < 3; j++)
3335  {
3336  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3337  if (j == k) { d -= 1.0; }
3338  if (fabs(d) > 1.0e-12)
3339  {
3340  mfem::err << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
3341  " k = " << k << ", j = " << j << ", d = " << d << endl;
3342  mfem_error();
3343  }
3344  }
3345  }
3346 #endif
3347 
3348  IntegrationPoint ip;
3349  ip.x = ip.y = 0.0;
3350  Trans.SetIntPoint (&ip);
3351  // Trans must be linear
3352  // set Jinv = |J| J^{-t} = adj(J)^t
3353  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3354  double vk[2];
3355  Vector xk (vk, 2);
3356 
3357  for (k = 0; k < 3; k++)
3358  {
3359  Trans.Transform (Nodes.IntPoint (k), xk);
3360  ip.x = vk[0]; ip.y = vk[1];
3361  CalcVShape (ip, vshape);
3362  // vk = |J| J^{-t} nk
3363  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3364  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3365  for (j = 0; j < 3; j++)
3366  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3367  {
3368  I(k,j) = 0.0;
3369  }
3370  }
3371 }
3372 
3375  Vector &dofs) const
3376 {
3377  double vk[2];
3378  Vector xk (vk, 2);
3379 #ifdef MFEM_THREAD_SAFE
3380  DenseMatrix Jinv(Dim);
3381 #endif
3382 
3383  for (int k = 0; k < 3; k++)
3384  {
3385  Trans.SetIntPoint (&Nodes.IntPoint (k));
3386  // set Jinv = |J| J^{-t} = adj(J)^t
3387  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3388 
3389  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3390  // xk^t |J| J^{-t} nk
3391  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3392  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3393  }
3394 }
3395 
3397  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
3398 {
3399  Nodes.IntPoint(0).x = 0.5;
3400  Nodes.IntPoint(0).y = 0.0;
3401  Nodes.IntPoint(1).x = 1.0;
3402  Nodes.IntPoint(1).y = 0.5;
3403  Nodes.IntPoint(2).x = 0.5;
3404  Nodes.IntPoint(2).y = 1.0;
3405  Nodes.IntPoint(3).x = 0.0;
3406  Nodes.IntPoint(3).y = 0.5;
3407 }
3408 
3410  DenseMatrix &shape) const
3411 {
3412  double x = ip.x, y = ip.y;
3413 
3414  shape(0,0) = 0;
3415  shape(0,1) = y - 1.;
3416  shape(1,0) = x;
3417  shape(1,1) = 0;
3418  shape(2,0) = 0;
3419  shape(2,1) = y;
3420  shape(3,0) = x - 1.;
3421  shape(3,1) = 0;
3422 }
3423 
3425  Vector &divshape) const
3426 {
3427  divshape(0) = 1.;
3428  divshape(1) = 1.;
3429  divshape(2) = 1.;
3430  divshape(3) = 1.;
3431 }
3432 
3433 const double RT0QuadFiniteElement::nk[4][2] =
3434 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
3435 
3438 {
3439  int k, j;
3440 #ifdef MFEM_THREAD_SAFE
3442  DenseMatrix Jinv(Dim);
3443 #endif
3444 
3445 #ifdef MFEM_DEBUG
3446  for (k = 0; k < 4; k++)
3447  {
3449  for (j = 0; j < 4; j++)
3450  {
3451  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3452  if (j == k) { d -= 1.0; }
3453  if (fabs(d) > 1.0e-12)
3454  {
3455  mfem::err << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
3456  " k = " << k << ", j = " << j << ", d = " << d << endl;
3457  mfem_error();
3458  }
3459  }
3460  }
3461 #endif
3462 
3463  IntegrationPoint ip;
3464  ip.x = ip.y = 0.0;
3465  Trans.SetIntPoint (&ip);
3466  // Trans must be linear (more to have embedding?)
3467  // set Jinv = |J| J^{-t} = adj(J)^t
3468  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3469  double vk[2];
3470  Vector xk (vk, 2);
3471 
3472  for (k = 0; k < 4; k++)
3473  {
3474  Trans.Transform (Nodes.IntPoint (k), xk);
3475  ip.x = vk[0]; ip.y = vk[1];
3476  CalcVShape (ip, vshape);
3477  // vk = |J| J^{-t} nk
3478  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3479  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3480  for (j = 0; j < 4; j++)
3481  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3482  {
3483  I(k,j) = 0.0;
3484  }
3485  }
3486 }
3487 
3490  Vector &dofs) const
3491 {
3492  double vk[2];
3493  Vector xk (vk, 2);
3494 #ifdef MFEM_THREAD_SAFE
3495  DenseMatrix Jinv(Dim);
3496 #endif
3497 
3498  for (int k = 0; k < 4; k++)
3499  {
3500  Trans.SetIntPoint (&Nodes.IntPoint (k));
3501  // set Jinv = |J| J^{-t} = adj(J)^t
3502  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3503 
3504  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3505  // xk^t |J| J^{-t} nk
3506  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3507  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3508  }
3509 }
3510 
3512  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
3513 {
3514  Nodes.IntPoint(0).x = 0.33333333333333333333;
3515  Nodes.IntPoint(0).y = 0.0;
3516  Nodes.IntPoint(1).x = 0.66666666666666666667;
3517  Nodes.IntPoint(1).y = 0.0;
3518  Nodes.IntPoint(2).x = 0.66666666666666666667;
3519  Nodes.IntPoint(2).y = 0.33333333333333333333;
3520  Nodes.IntPoint(3).x = 0.33333333333333333333;
3521  Nodes.IntPoint(3).y = 0.66666666666666666667;
3522  Nodes.IntPoint(4).x = 0.0;
3523  Nodes.IntPoint(4).y = 0.66666666666666666667;
3524  Nodes.IntPoint(5).x = 0.0;
3525  Nodes.IntPoint(5).y = 0.33333333333333333333;
3526  Nodes.IntPoint(6).x = 0.33333333333333333333;
3527  Nodes.IntPoint(6).y = 0.33333333333333333333;
3528  Nodes.IntPoint(7).x = 0.33333333333333333333;
3529  Nodes.IntPoint(7).y = 0.33333333333333333333;
3530 }
3531 
3533  DenseMatrix &shape) const
3534 {
3535  double x = ip.x, y = ip.y;
3536 
3537  shape(0,0) = -2 * x * (-1 + x + 2 * y);
3538  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
3539  shape(1,0) = 2 * x * (x - y);
3540  shape(1,1) = 2 * (x - y) * (-1 + y);
3541  shape(2,0) = 2 * x * (-1 + 2 * x + y);
3542  shape(2,1) = 2 * y * (-1 + 2 * x + y);
3543  shape(3,0) = 2 * x * (-1 + x + 2 * y);
3544  shape(3,1) = 2 * y * (-1 + x + 2 * y);
3545  shape(4,0) = -2 * (-1 + x) * (x - y);
3546  shape(4,1) = 2 * y * (-x + y);
3547  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
3548  shape(5,1) = -2 * y * (-1 + 2 * x + y);
3549  shape(6,0) = -3 * x * (-2 + 2 * x + y);
3550  shape(6,1) = -3 * y * (-1 + 2 * x + y);
3551  shape(7,0) = -3 * x * (-1 + x + 2 * y);
3552  shape(7,1) = -3 * y * (-2 + x + 2 * y);
3553 }
3554 
3556  Vector &divshape) const
3557 {
3558  double x = ip.x, y = ip.y;
3559 
3560  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
3561  divshape(1) = 2 + 6 * x - 6 * y;
3562  divshape(2) = -4 + 12 * x + 6 * y;
3563  divshape(3) = -4 + 6 * x + 12 * y;
3564  divshape(4) = 2 - 6 * x + 6 * y;
3565  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
3566  divshape(6) = -9 * (-1 + 2 * x + y);
3567  divshape(7) = -9 * (-1 + x + 2 * y);
3568 }
3569 
3570 const double RT1TriangleFiniteElement::nk[8][2] =
3571 {
3572  { 0,-1}, { 0,-1},
3573  { 1, 1}, { 1, 1},
3574  {-1, 0}, {-1, 0},
3575  { 1, 0}, { 0, 1}
3576 };
3577 
3580 {
3581  int k, j;
3582 #ifdef MFEM_THREAD_SAFE
3584  DenseMatrix Jinv(Dim);
3585 #endif
3586 
3587 #ifdef MFEM_DEBUG
3588  for (k = 0; k < 8; k++)
3589  {
3591  for (j = 0; j < 8; j++)
3592  {
3593  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3594  if (j == k) { d -= 1.0; }
3595  if (fabs(d) > 1.0e-12)
3596  {
3597  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3598  " k = " << k << ", j = " << j << ", d = " << d << endl;
3599  mfem_error();
3600  }
3601  }
3602  }
3603 #endif
3604 
3605  IntegrationPoint ip;
3606  ip.x = ip.y = 0.0;
3607  Trans.SetIntPoint (&ip);
3608  // Trans must be linear (more to have embedding?)
3609  // set Jinv = |J| J^{-t} = adj(J)^t
3610  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3611  double vk[2];
3612  Vector xk (vk, 2);
3613 
3614  for (k = 0; k < 8; k++)
3615  {
3616  Trans.Transform (Nodes.IntPoint (k), xk);
3617  ip.x = vk[0]; ip.y = vk[1];
3618  CalcVShape (ip, vshape);
3619  // vk = |J| J^{-t} nk
3620  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3621  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3622  for (j = 0; j < 8; j++)
3623  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3624  {
3625  I(k,j) = 0.0;
3626  }
3627  }
3628 }
3629 
3632 {
3633  double vk[2];
3634  Vector xk (vk, 2);
3635 #ifdef MFEM_THREAD_SAFE
3636  DenseMatrix Jinv(Dim);
3637 #endif
3638 
3639  for (int k = 0; k < 8; k++)
3640  {
3641  Trans.SetIntPoint (&Nodes.IntPoint (k));
3642  // set Jinv = |J| J^{-t} = adj(J)^t
3643  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3644 
3645  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3646  // xk^t |J| J^{-t} nk
3647  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3648  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3649  dofs(k) *= 0.5;
3650  }
3651 }
3652 
3654  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
3655 {
3656  // y = 0
3657  Nodes.IntPoint(0).x = 1./3.;
3658  Nodes.IntPoint(0).y = 0.0;
3659  Nodes.IntPoint(1).x = 2./3.;
3660  Nodes.IntPoint(1).y = 0.0;
3661  // x = 1
3662  Nodes.IntPoint(2).x = 1.0;
3663  Nodes.IntPoint(2).y = 1./3.;
3664  Nodes.IntPoint(3).x = 1.0;
3665  Nodes.IntPoint(3).y = 2./3.;
3666  // y = 1
3667  Nodes.IntPoint(4).x = 2./3.;
3668  Nodes.IntPoint(4).y = 1.0;
3669  Nodes.IntPoint(5).x = 1./3.;
3670  Nodes.IntPoint(5).y = 1.0;
3671  // x = 0
3672  Nodes.IntPoint(6).x = 0.0;
3673  Nodes.IntPoint(6).y = 2./3.;
3674  Nodes.IntPoint(7).x = 0.0;
3675  Nodes.IntPoint(7).y = 1./3.;
3676  // x = 0.5 (interior)
3677  Nodes.IntPoint(8).x = 0.5;
3678  Nodes.IntPoint(8).y = 1./3.;
3679  Nodes.IntPoint(9).x = 0.5;
3680  Nodes.IntPoint(9).y = 2./3.;
3681  // y = 0.5 (interior)
3682  Nodes.IntPoint(10).x = 1./3.;
3683  Nodes.IntPoint(10).y = 0.5;
3684  Nodes.IntPoint(11).x = 2./3.;
3685  Nodes.IntPoint(11).y = 0.5;
3686 }
3687 
3689  DenseMatrix &shape) const
3690 {
3691  double x = ip.x, y = ip.y;
3692 
3693  // y = 0
3694  shape(0,0) = 0;
3695  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
3696  shape(1,0) = 0;
3697  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
3698  // x = 1
3699  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
3700  shape(2,1) = 0;
3701  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
3702  shape(3,1) = 0;
3703  // y = 1
3704  shape(4,0) = 0;
3705  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
3706  shape(5,0) = 0;
3707  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
3708  // x = 0
3709  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
3710  shape(6,1) = 0;
3711  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
3712  shape(7,1) = 0;
3713  // x = 0.5 (interior)
3714  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
3715  shape(8,1) = 0;
3716  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
3717  shape(9,1) = 0;
3718  // y = 0.5 (interior)
3719  shape(10,0) = 0;
3720  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
3721  shape(11,0) = 0;
3722  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
3723 }
3724 
3726  Vector &divshape) const
3727 {
3728  double x = ip.x, y = ip.y;
3729 
3730  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
3731  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
3732  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
3733  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
3734  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
3735  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
3736  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
3737  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
3738  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
3739  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
3740  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
3741  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
3742 }
3743 
3744 const double RT1QuadFiniteElement::nk[12][2] =
3745 {
3746  // y = 0
3747  {0,-1}, {0,-1},
3748  // X = 1
3749  {1, 0}, {1, 0},
3750  // y = 1
3751  {0, 1}, {0, 1},
3752  // x = 0
3753  {-1,0}, {-1,0},
3754  // x = 0.5 (interior)
3755  {1, 0}, {1, 0},
3756  // y = 0.5 (interior)
3757  {0, 1}, {0, 1}
3758 };
3759 
3762 {
3763  int k, j;
3764 #ifdef MFEM_THREAD_SAFE
3766  DenseMatrix Jinv(Dim);
3767 #endif
3768 
3769 #ifdef MFEM_DEBUG
3770  for (k = 0; k < 12; k++)
3771  {
3773  for (j = 0; j < 12; j++)
3774  {
3775  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3776  if (j == k) { d -= 1.0; }
3777  if (fabs(d) > 1.0e-12)
3778  {
3779  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3780  " k = " << k << ", j = " << j << ", d = " << d << endl;
3781  mfem_error();
3782  }
3783  }
3784  }
3785 #endif
3786 
3787  IntegrationPoint ip;
3788  ip.x = ip.y = 0.0;
3789  Trans.SetIntPoint (&ip);
3790  // Trans must be linear (more to have embedding?)
3791  // set Jinv = |J| J^{-t} = adj(J)^t
3792  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3793  double vk[2];
3794  Vector xk (vk, 2);
3795 
3796  for (k = 0; k < 12; k++)
3797  {
3798  Trans.Transform (Nodes.IntPoint (k), xk);
3799  ip.x = vk[0]; ip.y = vk[1];
3800  CalcVShape (ip, vshape);
3801  // vk = |J| J^{-t} nk
3802  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3803  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3804  for (j = 0; j < 12; j++)
3805  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3806  {
3807  I(k,j) = 0.0;
3808  }
3809  }
3810 }
3811 
3814 {
3815  double vk[2];
3816  Vector xk (vk, 2);
3817 #ifdef MFEM_THREAD_SAFE
3818  DenseMatrix Jinv(Dim);
3819 #endif
3820 
3821  for (int k = 0; k < 12; k++)
3822  {
3823  Trans.SetIntPoint (&Nodes.IntPoint (k));
3824  // set Jinv = |J| J^{-t} = adj(J)^t
3825  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3826 
3827  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3828  // xk^t |J| J^{-t} nk
3829  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3830  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3831  }
3832 }
3833 
3834 const double RT2TriangleFiniteElement::M[15][15] =
3835 {
3836  {
3837  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
3838  0, 24.442740046346700787, -16.647580015448900262, -12.,
3839  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
3840  12., 30.590320061795601049, 15.295160030897800524
3841  },
3842  {
3843  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
3844  -15., 10.5
3845  },
3846  {
3847  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
3848  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
3849  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
3850  12., -6.5903200617956010489, -3.2951600308978005244
3851  },
3852  {
3853  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
3854  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
3855  0, -3.2951600308978005244
3856  },
3857  {
3858  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
3859  36., 10.5
3860  },
3861  {
3862  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
3863  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
3864  0, 15.295160030897800524
3865  },
3866  {
3867  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
3868  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
3869  -0.76209992275549868892, 4.1189500386222506555, -12.,
3870  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
3871  12.
3872  },
3873  {
3874  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
3875  -15., -15.
3876  },
3877  {
3878  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
3879  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
3880  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
3881  30.590320061795601049, 12.
3882  },
3883  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
3884  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
3885  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
3886  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
3887  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
3888  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
3889 };
3890 
3892  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
3893 {
3894  const double p = 0.11270166537925831148;
3895 
3896  Nodes.IntPoint(0).x = p;
3897  Nodes.IntPoint(0).y = 0.0;
3898  Nodes.IntPoint(1).x = 0.5;
3899  Nodes.IntPoint(1).y = 0.0;
3900  Nodes.IntPoint(2).x = 1.-p;
3901  Nodes.IntPoint(2).y = 0.0;
3902  Nodes.IntPoint(3).x = 1.-p;
3903  Nodes.IntPoint(3).y = p;
3904  Nodes.IntPoint(4).x = 0.5;
3905  Nodes.IntPoint(4).y = 0.5;
3906  Nodes.IntPoint(5).x = p;
3907  Nodes.IntPoint(5).y = 1.-p;
3908  Nodes.IntPoint(6).x = 0.0;
3909  Nodes.IntPoint(6).y = 1.-p;
3910  Nodes.IntPoint(7).x = 0.0;
3911  Nodes.IntPoint(7).y = 0.5;
3912  Nodes.IntPoint(8).x = 0.0;
3913  Nodes.IntPoint(8).y = p;
3914  Nodes.IntPoint(9).x = 0.25;
3915  Nodes.IntPoint(9).y = 0.25;
3916  Nodes.IntPoint(10).x = 0.25;
3917  Nodes.IntPoint(10).y = 0.25;
3918  Nodes.IntPoint(11).x = 0.5;
3919  Nodes.IntPoint(11).y = 0.25;
3920  Nodes.IntPoint(12).x = 0.5;
3921  Nodes.IntPoint(12).y = 0.25;
3922  Nodes.IntPoint(13).x = 0.25;
3923  Nodes.IntPoint(13).y = 0.5;
3924  Nodes.IntPoint(14).x = 0.25;
3925  Nodes.IntPoint(14).y = 0.5;
3926 }
3927 
3929  DenseMatrix &shape) const
3930 {
3931  double x = ip.x, y = ip.y;
3932 
3933  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
3934  x*x*y, x*y*y
3935  };
3936  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
3937  x*x*y, x*y*y, y*y*y
3938  };
3939 
3940  for (int i = 0; i < 15; i++)
3941  {
3942  double cx = 0.0, cy = 0.0;
3943  for (int j = 0; j < 15; j++)
3944  {
3945  cx += M[i][j] * Bx[j];
3946  cy += M[i][j] * By[j];
3947  }
3948  shape(i,0) = cx;
3949  shape(i,1) = cy;
3950  }
3951 }
3952 
3954  Vector &divshape) const
3955 {
3956  double x = ip.x, y = ip.y;
3957 
3958  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
3959  4.*x*x, 4.*x*y, 4.*y*y
3960  };
3961 
3962  for (int i = 0; i < 15; i++)
3963  {
3964  double div = 0.0;
3965  for (int j = 0; j < 15; j++)
3966  {
3967  div += M[i][j] * DivB[j];
3968  }
3969  divshape(i) = div;
3970  }
3971 }
3972 
3973 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
3974 
3975 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
3976 
3978  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
3979 {
3980  // y = 0 (pt[0])
3981  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
3982  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
3983  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
3984  // x = 1 (pt[3])
3985  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
3986  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
3987  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
3988  // y = 1 (pt[3])
3989  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
3990  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
3991  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
3992  // x = 0 (pt[0])
3993  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
3994  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
3995  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
3996  // x = pt[1] (interior)
3997  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
3998  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
3999  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
4000  // x = pt[2] (interior)
4001  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
4002  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
4003  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
4004  // y = pt[1] (interior)
4005  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
4006  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
4007  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
4008  // y = pt[2] (interior)
4009  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
4010  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
4011  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
4012 }
4013 
4015  DenseMatrix &shape) const
4016 {
4017  double x = ip.x, y = ip.y;
4018 
4019  double ax0 = pt[0] - x;
4020  double ax1 = pt[1] - x;
4021  double ax2 = pt[2] - x;
4022  double ax3 = pt[3] - x;
4023 
4024  double by0 = dpt[0] - y;
4025  double by1 = dpt[1] - y;
4026  double by2 = dpt[2] - y;
4027 
4028  double ay0 = pt[0] - y;
4029  double ay1 = pt[1] - y;
4030  double ay2 = pt[2] - y;
4031  double ay3 = pt[3] - y;
4032 
4033  double bx0 = dpt[0] - x;
4034  double bx1 = dpt[1] - x;
4035  double bx2 = dpt[2] - x;
4036 
4037  double A01 = pt[0] - pt[1];
4038  double A02 = pt[0] - pt[2];
4039  double A12 = pt[1] - pt[2];
4040  double A03 = pt[0] - pt[3];
4041  double A13 = pt[1] - pt[3];
4042  double A23 = pt[2] - pt[3];
4043 
4044  double B01 = dpt[0] - dpt[1];
4045  double B02 = dpt[0] - dpt[2];
4046  double B12 = dpt[1] - dpt[2];
4047 
4048  double tx0 = (bx1*bx2)/(B01*B02);
4049  double tx1 = -(bx0*bx2)/(B01*B12);
4050  double tx2 = (bx0*bx1)/(B02*B12);
4051 
4052  double ty0 = (by1*by2)/(B01*B02);
4053  double ty1 = -(by0*by2)/(B01*B12);
4054  double ty2 = (by0*by1)/(B02*B12);
4055 
4056  // y = 0 (p[0])
4057  shape(0, 0) = 0;
4058  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
4059  shape(1, 0) = 0;
4060  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
4061  shape(2, 0) = 0;
4062  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
4063  // x = 1 (p[3])
4064  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
4065  shape(3, 1) = 0;
4066  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
4067  shape(4, 1) = 0;
4068  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
4069  shape(5, 1) = 0;
4070  // y = 1 (p[3])
4071  shape(6, 0) = 0;
4072  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
4073  shape(7, 0) = 0;
4074  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
4075  shape(8, 0) = 0;
4076  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
4077  // x = 0 (p[0])
4078  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
4079  shape(9, 1) = 0;
4080  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
4081  shape(10, 1) = 0;
4082  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
4083  shape(11, 1) = 0;
4084  // x = p[1] (interior)
4085  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
4086  shape(12, 1) = 0;
4087  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
4088  shape(13, 1) = 0;
4089  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
4090  shape(14, 1) = 0;
4091  // x = p[2] (interior)
4092  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
4093  shape(15, 1) = 0;
4094  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
4095  shape(16, 1) = 0;
4096  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
4097  shape(17, 1) = 0;
4098  // y = p[1] (interior)
4099  shape(18, 0) = 0;
4100  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
4101  shape(19, 0) = 0;
4102  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
4103  shape(20, 0) = 0;
4104  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
4105  // y = p[2] (interior)
4106  shape(21, 0) = 0;
4107  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
4108  shape(22, 0) = 0;
4109  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
4110  shape(23, 0) = 0;
4111  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
4112 }
4113 
4115  Vector &divshape) const
4116 {
4117  double x = ip.x, y = ip.y;
4118 
4119  double a01 = pt[0]*pt[1];
4120  double a02 = pt[0]*pt[2];
4121  double a12 = pt[1]*pt[2];
4122  double a03 = pt[0]*pt[3];
4123  double a13 = pt[1]*pt[3];
4124  double a23 = pt[2]*pt[3];
4125 
4126  double bx0 = dpt[0] - x;
4127  double bx1 = dpt[1] - x;
4128  double bx2 = dpt[2] - x;
4129 
4130  double by0 = dpt[0] - y;
4131  double by1 = dpt[1] - y;
4132  double by2 = dpt[2] - y;
4133 
4134  double A01 = pt[0] - pt[1];
4135  double A02 = pt[0] - pt[2];
4136  double A12 = pt[1] - pt[2];
4137  double A03 = pt[0] - pt[3];
4138  double A13 = pt[1] - pt[3];
4139  double A23 = pt[2] - pt[3];
4140 
4141  double A012 = pt[0] + pt[1] + pt[2];
4142  double A013 = pt[0] + pt[1] + pt[3];
4143  double A023 = pt[0] + pt[2] + pt[3];
4144  double A123 = pt[1] + pt[2] + pt[3];
4145 
4146  double B01 = dpt[0] - dpt[1];
4147  double B02 = dpt[0] - dpt[2];
4148  double B12 = dpt[1] - dpt[2];
4149 
4150  double tx0 = (bx1*bx2)/(B01*B02);
4151  double tx1 = -(bx0*bx2)/(B01*B12);
4152  double tx2 = (bx0*bx1)/(B02*B12);
4153 
4154  double ty0 = (by1*by2)/(B01*B02);
4155  double ty1 = -(by0*by2)/(B01*B12);
4156  double ty2 = (by0*by1)/(B02*B12);
4157 
4158  // y = 0 (p[0])
4159  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
4160  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
4161  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
4162  // x = 1 (p[3])
4163  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
4164  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
4165  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
4166  // y = 1 (p[3])
4167  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
4168  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
4169  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
4170  // x = 0 (p[0])
4171  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
4172  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
4173  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
4174  // x = p[1] (interior)
4175  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
4176  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
4177  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
4178  // x = p[2] (interior)
4179  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
4180  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
4181  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
4182  // y = p[1] (interior)
4183  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
4184  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
4185  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
4186  // y = p[2] (interior)
4187  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
4188  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
4189  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
4190 }
4191 
4192 const double RT2QuadFiniteElement::nk[24][2] =
4193 {
4194  // y = 0
4195  {0,-1}, {0,-1}, {0,-1},
4196  // x = 1
4197  {1, 0}, {1, 0}, {1, 0},
4198  // y = 1
4199  {0, 1}, {0, 1}, {0, 1},
4200  // x = 0
4201  {-1,0}, {-1,0}, {-1,0},
4202  // x = p[1] (interior)
4203  {1, 0}, {1, 0}, {1, 0},
4204  // x = p[2] (interior)
4205  {1, 0}, {1, 0}, {1, 0},
4206  // y = p[1] (interior)
4207  {0, 1}, {0, 1}, {0, 1},
4208  // y = p[1] (interior)
4209  {0, 1}, {0, 1}, {0, 1}
4210 };
4211 
4214 {
4215  int k, j;
4216 #ifdef MFEM_THREAD_SAFE
4218  DenseMatrix Jinv(Dim);
4219 #endif
4220 
4221 #ifdef MFEM_DEBUG
4222  for (k = 0; k < 24; k++)
4223  {
4225  for (j = 0; j < 24; j++)
4226  {
4227  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
4228  if (j == k) { d -= 1.0; }
4229  if (fabs(d) > 1.0e-12)
4230  {
4231  mfem::err << "RT2QuadFiniteElement::GetLocalInterpolation (...)\n"
4232  " k = " << k << ", j = " << j << ", d = " << d << endl;
4233  mfem_error();
4234  }
4235  }
4236  }
4237 #endif
4238 
4239  IntegrationPoint ip;
4240  ip.x = ip.y = 0.0;
4241  Trans.SetIntPoint (&ip);
4242  // Trans must be linear (more to have embedding?)
4243  // set Jinv = |J| J^{-t} = adj(J)^t
4244  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
4245  double vk[2];
4246  Vector xk (vk, 2);
4247 
4248  for (k = 0; k < 24; k++)
4249  {
4250  Trans.Transform (Nodes.IntPoint (k), xk);
4251  ip.x = vk[0]; ip.y = vk[1];
4252  CalcVShape (ip, vshape);
4253  // vk = |J| J^{-t} nk
4254  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
4255  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
4256  for (j = 0; j < 24; j++)
4257  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
4258  {
4259  I(k,j) = 0.0;
4260  }
4261  }
4262 }
4263 
4266 {
4267  double vk[2];
4268  Vector xk (vk, 2);
4269 #ifdef MFEM_THREAD_SAFE
4270  DenseMatrix Jinv(Dim);
4271 #endif
4272 
4273  for (int k = 0; k < 24; k++)
4274  {
4275  Trans.SetIntPoint (&Nodes.IntPoint (k));
4276  // set Jinv = |J| J^{-t} = adj(J)^t
4277  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
4278 
4279  vc.Eval (xk, Trans, Nodes.IntPoint (k));
4280  // xk^t |J| J^{-t} nk
4281  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
4282  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
4283  }
4284 }
4285 
4287  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
4288 {
4289  Nodes.IntPoint(0).x = 0.33333333333333333333;
4290  Nodes.IntPoint(1).x = 0.66666666666666666667;
4291 }
4292 
4294  Vector &shape) const
4295 {
4296  double x = ip.x;
4297 
4298  shape(0) = 2. - 3. * x;
4299  shape(1) = 3. * x - 1.;
4300 }
4301 
4303  DenseMatrix &dshape) const
4304 {
4305  dshape(0,0) = -3.;
4306  dshape(1,0) = 3.;
4307 }
4308 
4309 
4311  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
4312 {
4313  const double p = 0.11270166537925831148;
4314 
4315  Nodes.IntPoint(0).x = p;
4316  Nodes.IntPoint(1).x = 0.5;
4317  Nodes.IntPoint(2).x = 1.-p;
4318 }
4319 
4321  Vector &shape) const
4322 {
4323  const double p = 0.11270166537925831148;
4324  const double w = 1./((1-2*p)*(1-2*p));
4325  double x = ip.x;
4326 
4327  shape(0) = (2*x-1)*(x-1+p)*w;
4328  shape(1) = 4*(x-1+p)*(p-x)*w;
4329  shape(2) = (2*x-1)*(x-p)*w;
4330 }
4331 
4333  DenseMatrix &dshape) const
4334 {
4335  const double p = 0.11270166537925831148;
4336  const double w = 1./((1-2*p)*(1-2*p));
4337  double x = ip.x;
4338 
4339  dshape(0,0) = (-3+4*x+2*p)*w;
4340  dshape(1,0) = (4-8*x)*w;
4341  dshape(2,0) = (-1+4*x-2*p)*w;
4342 }
4343 
4344 
4346  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
4347 {
4348  int i, m = degree;
4349 
4350  Nodes.IntPoint(0).x = 0.0;
4351  Nodes.IntPoint(1).x = 1.0;
4352  for (i = 1; i < m; i++)
4353  {
4354  Nodes.IntPoint(i+1).x = double(i) / m;
4355  }
4356 
4357  rwk.SetSize(degree+1);
4358 #ifndef MFEM_THREAD_SAFE
4359  rxxk.SetSize(degree+1);
4360 #endif
4361 
4362  rwk(0) = 1.0;
4363  for (i = 1; i <= m; i++)
4364  {
4365  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
4366  }
4367  for (i = 0; i < m/2+1; i++)
4368  {
4369  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
4370  }
4371  for (i = m-1; i >= 0; i -= 2)
4372  {
4373  rwk(i) = -rwk(i);
4374  }
4375 }
4376 
4378  Vector &shape) const
4379 {
4380  double w, wk, x = ip.x;
4381  int i, k, m = GetOrder();
4382 
4383 #ifdef MFEM_THREAD_SAFE
4384  Vector rxxk(m+1);
4385 #endif
4386 
4387  k = (int) floor ( m * x + 0.5 );
4388  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
4389 
4390  wk = 1.0;
4391  for (i = 0; i <= m; i++)
4392  if (i != k)
4393  {
4394  wk *= ( rxxk(i) = x - (double)(i) / m );
4395  }
4396  w = wk * ( rxxk(k) = x - (double)(k) / m );
4397 
4398  if (k != 0)
4399  {
4400  shape(0) = w * rwk(0) / rxxk(0);
4401  }
4402  else
4403  {
4404  shape(0) = wk * rwk(0);
4405  }
4406  if (k != m)
4407  {
4408  shape(1) = w * rwk(m) / rxxk(m);
4409  }
4410  else
4411  {
4412  shape(1) = wk * rwk(k);
4413  }
4414  for (i = 1; i < m; i++)
4415  if (i != k)
4416  {
4417  shape(i+1) = w * rwk(i) / rxxk(i);
4418  }
4419  else
4420  {
4421  shape(k+1) = wk * rwk(k);
4422  }
4423 }
4424 
4426  DenseMatrix &dshape) const
4427 {
4428  double s, srx, w, wk, x = ip.x;
4429  int i, k, m = GetOrder();
4430 
4431 #ifdef MFEM_THREAD_SAFE
4432  Vector rxxk(m+1);
4433 #endif
4434 
4435  k = (int) floor ( m * x + 0.5 );
4436  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
4437 
4438  wk = 1.0;
4439  for (i = 0; i <= m; i++)
4440  if (i != k)
4441  {
4442  wk *= ( rxxk(i) = x - (double)(i) / m );
4443  }
4444  w = wk * ( rxxk(k) = x - (double)(k) / m );
4445 
4446  for (i = 0; i <= m; i++)
4447  {
4448  rxxk(i) = 1.0 / rxxk(i);
4449  }
4450  srx = 0.0;
4451  for (i = 0; i <= m; i++)
4452  if (i != k)
4453  {
4454  srx += rxxk(i);
4455  }
4456  s = w * srx + wk;
4457 
4458  if (k != 0)
4459  {
4460  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
4461  }
4462  else
4463  {
4464  dshape(0,0) = wk * srx * rwk(0);
4465  }
4466  if (k != m)
4467  {
4468  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
4469  }
4470  else
4471  {
4472  dshape(1,0) = wk * srx * rwk(k);
4473  }
4474  for (i = 1; i < m; i++)
4475  if (i != k)
4476  {
4477  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
4478  }
4479  else
4480  {
4481  dshape(k+1,0) = wk * srx * rwk(k);
4482  }
4483 }
4484 
4485 
4487  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
4488 {
4489  Nodes.IntPoint(0).x = 0.33333333333333333333;
4490  Nodes.IntPoint(0).y = 0.33333333333333333333;
4491  Nodes.IntPoint(0).z = 0.33333333333333333333;
4492 
4493  Nodes.IntPoint(1).x = 0.0;
4494  Nodes.IntPoint(1).y = 0.33333333333333333333;
4495  Nodes.IntPoint(1).z = 0.33333333333333333333;
4496 
4497  Nodes.IntPoint(2).x = 0.33333333333333333333;
4498  Nodes.IntPoint(2).y = 0.0;
4499  Nodes.IntPoint(2).z = 0.33333333333333333333;
4500 
4501  Nodes.IntPoint(3).x = 0.33333333333333333333;
4502  Nodes.IntPoint(3).y = 0.33333333333333333333;
4503  Nodes.IntPoint(3).z = 0.0;
4504 
4505 }
4506 
4508  Vector &shape) const
4509 {
4510  double L0, L1, L2, L3;
4511 
4512  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
4513  shape(0) = 1.0 - 3.0 * L0;
4514  shape(1) = 1.0 - 3.0 * L1;
4515  shape(2) = 1.0 - 3.0 * L2;
4516  shape(3) = 1.0 - 3.0 * L3;
4517 }
4518 
4520  DenseMatrix &dshape) const
4521 {
4522  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
4523  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
4524  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
4525  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
4526 }
4527 
4528 
4530  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 1, 0)
4531 {
4532  Nodes.IntPoint(0).x = 0.25;
4533  Nodes.IntPoint(0).y = 0.25;
4534  Nodes.IntPoint(0).z = 0.25;
4535 }
4536 
4538  Vector &shape) const
4539 {
4540  shape(0) = 1.0;
4541 }
4542 
4544  DenseMatrix &dshape) const
4545 {
4546  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
4547 }
4548 
4549 
4551  : NodalFiniteElement(3, Geometry::CUBE, 1, 0, FunctionSpace::Qk)
4552 {
4553  Nodes.IntPoint(0).x = 0.5;
4554  Nodes.IntPoint(0).y = 0.5;
4555  Nodes.IntPoint(0).z = 0.5;
4556 }
4557 
4559  Vector &shape) const
4560 {
4561  shape(0) = 1.0;
4562 }
4563 
4565  DenseMatrix &dshape) const
4566 {
4567  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
4568 }
4569 
4570 
4572  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
4573  degree, FunctionSpace::Qk)
4574 {
4575  if (degree == 2)
4576  {
4577  I = new int[Dof];
4578  J = new int[Dof];
4579  K = new int[Dof];
4580  // nodes
4581  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
4582  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
4583  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
4584  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
4585  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
4586  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
4587  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
4588  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
4589  // edges
4590  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
4591  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
4592  I[10] = 2; J[10] = 1; K[10] = 0;
4593  I[11] = 0; J[11] = 2; K[11] = 0;
4594  I[12] = 2; J[12] = 0; K[12] = 1;
4595  I[13] = 1; J[13] = 2; K[13] = 1;
4596  I[14] = 2; J[14] = 1; K[14] = 1;
4597  I[15] = 0; J[15] = 2; K[15] = 1;
4598  I[16] = 0; J[16] = 0; K[16] = 2;
4599  I[17] = 1; J[17] = 0; K[17] = 2;
4600  I[18] = 1; J[18] = 1; K[18] = 2;
4601  I[19] = 0; J[19] = 1; K[19] = 2;
4602  // faces
4603  I[20] = 2; J[20] = 2; K[20] = 0;
4604  I[21] = 2; J[21] = 0; K[21] = 2;
4605  I[22] = 1; J[22] = 2; K[22] = 2;
4606  I[23] = 2; J[23] = 1; K[23] = 2;
4607  I[24] = 0; J[24] = 2; K[24] = 2;
4608  I[25] = 2; J[25] = 2; K[25] = 1;
4609  // element
4610  I[26] = 2; J[26] = 2; K[26] = 2;
4611  }
4612  else if (degree == 3)
4613  {
4614  I = new int[Dof];
4615  J = new int[Dof];
4616  K = new int[Dof];
4617  // nodes
4618  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
4619  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
4620  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
4621  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
4622  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
4623  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
4624  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
4625  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
4626  // edges
4627  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
4628  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
4629  I[10] = 1; J[10] = 2; K[10] = 0;
4630  I[11] = 1; J[11] = 3; K[11] = 0;
4631  I[12] = 2; J[12] = 1; K[12] = 0;
4632  I[13] = 3; J[13] = 1; K[13] = 0;
4633  I[14] = 0; J[14] = 2; K[14] = 0;
4634  I[15] = 0; J[15] = 3; K[15] = 0;
4635  I[16] = 2; J[16] = 0; K[16] = 1;
4636  I[17] = 3; J[17] = 0; K[17] = 1;
4637  I[18] = 1; J[18] = 2; K[18] = 1;
4638  I[19] = 1; J[19] = 3; K[19] = 1;
4639  I[20] = 2; J[20] = 1; K[20] = 1;
4640  I[21] = 3; J[21] = 1; K[21] = 1;
4641  I[22] = 0; J[22] = 2; K[22] = 1;
4642  I[23] = 0; J[23] = 3; K[23] = 1;
4643  I[24] = 0; J[24] = 0; K[24] = 2;
4644  I[25] = 0; J[25] = 0; K[25] = 3;
4645  I[26] = 1; J[26] = 0; K[26] = 2;
4646  I[27] = 1; J[27] = 0; K[27] = 3;
4647  I[28] = 1; J[28] = 1; K[28] = 2;
4648  I[29] = 1; J[29] = 1; K[29] = 3;
4649  I[30] = 0; J[30] = 1; K[30] = 2;
4650  I[31] = 0; J[31] = 1; K[31] = 3;
4651  // faces
4652  I[32] = 2; J[32] = 3; K[32] = 0;
4653  I[33] = 3; J[33] = 3; K[33] = 0;
4654  I[34] = 2; J[34] = 2; K[34] = 0;
4655  I[35] = 3; J[35] = 2; K[35] = 0;
4656  I[36] = 2; J[36] = 0; K[36] = 2;
4657  I[37] = 3; J[37] = 0; K[37] = 2;
4658  I[38] = 2; J[38] = 0; K[38] = 3;
4659  I[39] = 3; J[39] = 0; K[39] = 3;
4660  I[40] = 1; J[40] = 2; K[40] = 2;
4661  I[41] = 1; J[41] = 3; K[41] = 2;
4662  I[42] = 1; J[42] = 2; K[42] = 3;
4663  I[43] = 1; J[43] = 3; K[43] = 3;
4664  I[44] = 3; J[44] = 1; K[44] = 2;
4665  I[45] = 2; J[45] = 1; K[45] = 2;
4666  I[46] = 3; J[46] = 1; K[46] = 3;
4667  I[47] = 2; J[47] = 1; K[47] = 3;
4668  I[48] = 0; J[48] = 3; K[48] = 2;
4669  I[49] = 0; J[49] = 2; K[49] = 2;
4670  I[50] = 0; J[50] = 3; K[50] = 3;
4671  I[51] = 0; J[51] = 2; K[51] = 3;
4672  I[52] = 2; J[52] = 2; K[52] = 1;
4673  I[53] = 3; J[53] = 2; K[53] = 1;
4674  I[54] = 2; J[54] = 3; K[54] = 1;
4675  I[55] = 3; J[55] = 3; K[55] = 1;
4676  // element
4677  I[56] = 2; J[56] = 2; K[56] = 2;
4678  I[57] = 3; J[57] = 2; K[57] = 2;
4679  I[58] = 3; J[58] = 3; K[58] = 2;
4680  I[59] = 2; J[59] = 3; K[59] = 2;
4681  I[60] = 2; J[60] = 2; K[60] = 3;
4682  I[61] = 3; J[61] = 2; K[61] = 3;
4683  I[62] = 3; J[62] = 3; K[62] = 3;
4684  I[63] = 2; J[63] = 3; K[63] = 3;
4685  }
4686  else
4687  {
4688  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
4689  }
4690 
4691  fe1d = new Lagrange1DFiniteElement(degree);
4692  dof1d = fe1d -> GetDof();
4693 
4694 #ifndef MFEM_THREAD_SAFE
4695  shape1dx.SetSize(dof1d);
4696  shape1dy.SetSize(dof1d);
4697  shape1dz.SetSize(dof1d);
4698 
4699  dshape1dx.SetSize(dof1d,1);
4700  dshape1dy.SetSize(dof1d,1);
4701  dshape1dz.SetSize(dof1d,1);
4702 #endif
4703 
4704  for (int n = 0; n < Dof; n++)
4705  {
4706  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
4707  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
4708  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
4709  }
4710 }
4711 
4713  Vector &shape) const
4714 {
4715  IntegrationPoint ipy, ipz;
4716  ipy.x = ip.y;
4717  ipz.x = ip.z;
4718 
4719 #ifdef MFEM_THREAD_SAFE
4720  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4721 #endif
4722 
4723  fe1d -> CalcShape(ip, shape1dx);
4724  fe1d -> CalcShape(ipy, shape1dy);
4725  fe1d -> CalcShape(ipz, shape1dz);
4726 
4727  for (int n = 0; n < Dof; n++)
4728  {
4729  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
4730  }
4731 }
4732 
4734  DenseMatrix &dshape) const
4735 {
4736  IntegrationPoint ipy, ipz;
4737  ipy.x = ip.y;
4738  ipz.x = ip.z;
4739 
4740 #ifdef MFEM_THREAD_SAFE
4741  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4742  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
4743 #endif
4744 
4745  fe1d -> CalcShape(ip, shape1dx);
4746  fe1d -> CalcShape(ipy, shape1dy);
4747  fe1d -> CalcShape(ipz, shape1dz);
4748 
4749  fe1d -> CalcDShape(ip, dshape1dx);
4750  fe1d -> CalcDShape(ipy, dshape1dy);
4751  fe1d -> CalcDShape(ipz, dshape1dz);
4752 
4753  for (int n = 0; n < Dof; n++)
4754  {
4755  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
4756  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
4757  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
4758  }
4759 }
4760 
4762 {
4763  delete fe1d;
4764 
4765  delete [] I;
4766  delete [] J;
4767  delete [] K;
4768 }
4769 
4770 
4772  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
4773 {
4774  Nodes.IntPoint(0).x = 0.0;
4775  Nodes.IntPoint(1).x = 1.0;
4776  Nodes.IntPoint(2).x = 0.5;
4777 }
4778 
4780  Vector &shape) const
4781 {
4782  double x = ip.x;
4783 
4784  if (x <= 0.5)
4785  {
4786  shape(0) = 1.0 - 2.0 * x;
4787  shape(1) = 0.0;
4788  shape(2) = 2.0 * x;
4789  }
4790  else
4791  {
4792  shape(0) = 0.0;
4793  shape(1) = 2.0 * x - 1.0;
4794  shape(2) = 2.0 - 2.0 * x;
4795  }
4796 }
4797 
4799  DenseMatrix &dshape) const
4800 {
4801  double x = ip.x;
4802 
4803  if (x <= 0.5)
4804  {
4805  dshape(0,0) = - 2.0;
4806  dshape(1,0) = 0.0;
4807  dshape(2,0) = 2.0;
4808  }
4809  else
4810  {
4811  dshape(0,0) = 0.0;
4812  dshape(1,0) = 2.0;
4813  dshape(2,0) = - 2.0;
4814  }
4815 }
4816 
4818  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
4819 {
4820  Nodes.IntPoint(0).x = 0.0;
4821  Nodes.IntPoint(0).y = 0.0;
4822  Nodes.IntPoint(1).x = 1.0;
4823  Nodes.IntPoint(1).y = 0.0;
4824  Nodes.IntPoint(2).x = 0.0;
4825  Nodes.IntPoint(2).y = 1.0;
4826  Nodes.IntPoint(3).x = 0.5;
4827  Nodes.IntPoint(3).y = 0.0;
4828  Nodes.IntPoint(4).x = 0.5;
4829  Nodes.IntPoint(4).y = 0.5;
4830  Nodes.IntPoint(5).x = 0.0;
4831  Nodes.IntPoint(5).y = 0.5;
4832 }
4833 
4835  Vector &shape) const
4836 {
4837  int i;
4838 
4839  double L0, L1, L2;
4840  L0 = 2.0 * ( 1. - ip.x - ip.y );
4841  L1 = 2.0 * ( ip.x );
4842  L2 = 2.0 * ( ip.y );
4843 
4844  // The reference triangle is split in 4 triangles as follows:
4845  //
4846  // T0 - 0,3,5
4847  // T1 - 1,3,4
4848  // T2 - 2,4,5
4849  // T3 - 3,4,5
4850 
4851  for (i = 0; i < 6; i++)
4852  {
4853  shape(i) = 0.0;
4854  }
4855 
4856  if (L0 >= 1.0) // T0
4857  {
4858  shape(0) = L0 - 1.0;
4859  shape(3) = L1;
4860  shape(5) = L2;
4861  }
4862  else if (L1 >= 1.0) // T1
4863  {
4864  shape(3) = L0;
4865  shape(1) = L1 - 1.0;
4866  shape(4) = L2;
4867  }
4868  else if (L2 >= 1.0) // T2
4869  {
4870  shape(5) = L0;
4871  shape(4) = L1;
4872  shape(2) = L2 - 1.0;
4873  }
4874  else // T3
4875  {
4876  shape(3) = 1.0 - L2;
4877  shape(4) = 1.0 - L0;
4878  shape(5) = 1.0 - L1;
4879  }
4880 }
4881 
4883  DenseMatrix &dshape) const
4884 {
4885  int i,j;
4886 
4887  double L0, L1, L2;
4888  L0 = 2.0 * ( 1. - ip.x - ip.y );
4889  L1 = 2.0 * ( ip.x );
4890  L2 = 2.0 * ( ip.y );
4891 
4892  double DL0[2], DL1[2], DL2[2];
4893  DL0[0] = -2.0; DL0[1] = -2.0;
4894  DL1[0] = 2.0; DL1[1] = 0.0;
4895  DL2[0] = 0.0; DL2[1] = 2.0;
4896 
4897  for (i = 0; i < 6; i++)
4898  for (j = 0; j < 2; j++)
4899  {
4900  dshape(i,j) = 0.0;
4901  }
4902 
4903  if (L0 >= 1.0) // T0
4904  {
4905  for (j = 0; j < 2; j++)
4906  {
4907  dshape(0,j) = DL0[j];
4908  dshape(3,j) = DL1[j];
4909  dshape(5,j) = DL2[j];
4910  }
4911  }
4912  else if (L1 >= 1.0) // T1
4913  {
4914  for (j = 0; j < 2; j++)
4915  {
4916  dshape(3,j) = DL0[j];
4917  dshape(1,j) = DL1[j];
4918  dshape(4,j) = DL2[j];
4919  }
4920  }
4921  else if (L2 >= 1.0) // T2
4922  {
4923  for (j = 0; j < 2; j++)
4924  {
4925  dshape(5,j) = DL0[j];
4926  dshape(4,j) = DL1[j];
4927  dshape(2,j) = DL2[j];
4928  }
4929  }
4930  else // T3
4931  {
4932  for (j = 0; j < 2; j++)
4933  {
4934  dshape(3,j) = - DL2[j];
4935  dshape(4,j) = - DL0[j];
4936  dshape(5,j) = - DL1[j];
4937  }
4938  }
4939 }
4940 
4942  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
4943 {
4944  Nodes.IntPoint(0).x = 0.0;
4945  Nodes.IntPoint(0).y = 0.0;
4946  Nodes.IntPoint(0).z = 0.0;
4947  Nodes.IntPoint(1).x = 1.0;
4948  Nodes.IntPoint(1).y = 0.0;
4949  Nodes.IntPoint(1).z = 0.0;
4950  Nodes.IntPoint(2).x = 0.0;
4951  Nodes.IntPoint(2).y = 1.0;
4952  Nodes.IntPoint(2).z = 0.0;
4953  Nodes.IntPoint(3).x = 0.0;
4954  Nodes.IntPoint(3).y = 0.0;
4955  Nodes.IntPoint(3).z = 1.0;
4956  Nodes.IntPoint(4).x = 0.5;
4957  Nodes.IntPoint(4).y = 0.0;
4958  Nodes.IntPoint(4).z = 0.0;
4959  Nodes.IntPoint(5).x = 0.0;
4960  Nodes.IntPoint(5).y = 0.5;
4961  Nodes.IntPoint(5).z = 0.0;
4962  Nodes.IntPoint(6).x = 0.0;
4963  Nodes.IntPoint(6).y = 0.0;
4964  Nodes.IntPoint(6).z = 0.5;
4965  Nodes.IntPoint(7).x = 0.5;
4966  Nodes.IntPoint(7).y = 0.5;
4967  Nodes.IntPoint(7).z = 0.0;
4968  Nodes.IntPoint(8).x = 0.5;
4969  Nodes.IntPoint(8).y = 0.0;
4970  Nodes.IntPoint(8).z = 0.5;
4971  Nodes.IntPoint(9).x = 0.0;
4972  Nodes.IntPoint(9).y = 0.5;
4973  Nodes.IntPoint(9).z = 0.5;
4974 }
4975 
4977  Vector &shape) const
4978 {
4979  int i;
4980 
4981  double L0, L1, L2, L3, L4, L5;
4982  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4983  L1 = 2.0 * ( ip.x );
4984  L2 = 2.0 * ( ip.y );
4985  L3 = 2.0 * ( ip.z );
4986  L4 = 2.0 * ( ip.x + ip.y );
4987  L5 = 2.0 * ( ip.y + ip.z );
4988 
4989  // The reference tetrahedron is split in 8 tetrahedra as follows:
4990  //
4991  // T0 - 0,4,5,6
4992  // T1 - 1,4,7,8
4993  // T2 - 2,5,7,9
4994  // T3 - 3,6,8,9
4995  // T4 - 4,5,6,8
4996  // T5 - 4,5,7,8
4997  // T6 - 5,6,8,9
4998  // T7 - 5,7,8,9
4999 
5000  for (i = 0; i < 10; i++)
5001  {
5002  shape(i) = 0.0;
5003  }
5004 
5005  if (L0 >= 1.0) // T0
5006  {
5007  shape(0) = L0 - 1.0;
5008  shape(4) = L1;
5009  shape(5) = L2;
5010  shape(6) = L3;
5011  }
5012  else if (L1 >= 1.0) // T1
5013  {
5014  shape(4) = L0;
5015  shape(1) = L1 - 1.0;
5016  shape(7) = L2;
5017  shape(8) = L3;
5018  }
5019  else if (L2 >= 1.0) // T2
5020  {
5021  shape(5) = L0;
5022  shape(7) = L1;
5023  shape(2) = L2 - 1.0;
5024  shape(9) = L3;
5025  }
5026  else if (L3 >= 1.0) // T3
5027  {
5028  shape(6) = L0;
5029  shape(8) = L1;
5030  shape(9) = L2;
5031  shape(3) = L3 - 1.0;
5032  }
5033  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
5034  {
5035  shape(4) = 1.0 - L5;
5036  shape(5) = L2;
5037  shape(6) = 1.0 - L4;
5038  shape(8) = 1.0 - L0;
5039  }
5040  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
5041  {
5042  shape(4) = 1.0 - L5;
5043  shape(5) = 1.0 - L1;
5044  shape(7) = L4 - 1.0;
5045  shape(8) = L3;
5046  }
5047  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
5048  {
5049  shape(5) = 1.0 - L3;
5050  shape(6) = 1.0 - L4;
5051  shape(8) = L1;
5052  shape(9) = L5 - 1.0;
5053  }
5054  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
5055  {
5056  shape(5) = L0;
5057  shape(7) = L4 - 1.0;
5058  shape(8) = 1.0 - L2;
5059  shape(9) = L5 - 1.0;
5060  }
5061 }
5062 
5064  DenseMatrix &dshape) const
5065 {
5066  int i,j;
5067 
5068  double L0, L1, L2, L3, L4, L5;
5069  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
5070  L1 = 2.0 * ( ip.x );
5071  L2 = 2.0 * ( ip.y );
5072  L3 = 2.0 * ( ip.z );
5073  L4 = 2.0 * ( ip.x + ip.y );
5074  L5 = 2.0 * ( ip.y + ip.z );
5075 
5076  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
5077  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
5078  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
5079  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
5080  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
5081  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
5082  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
5083 
5084  for (i = 0; i < 10; i++)
5085  for (j = 0; j < 3; j++)
5086  {
5087  dshape(i,j) = 0.0;
5088  }
5089 
5090  if (L0 >= 1.0) // T0
5091  {
5092  for (j = 0; j < 3; j++)
5093  {
5094  dshape(0,j) = DL0[j];
5095  dshape(4,j) = DL1[j];
5096  dshape(5,j) = DL2[j];
5097  dshape(6,j) = DL3[j];
5098  }
5099  }
5100  else if (L1 >= 1.0) // T1
5101  {
5102  for (j = 0; j < 3; j++)
5103  {
5104  dshape(4,j) = DL0[j];
5105  dshape(1,j) = DL1[j];
5106  dshape(7,j) = DL2[j];
5107  dshape(8,j) = DL3[j];
5108  }
5109  }
5110  else if (L2 >= 1.0) // T2
5111  {
5112  for (j = 0; j < 3; j++)
5113  {
5114  dshape(5,j) = DL0[j];
5115  dshape(7,j) = DL1[j];
5116  dshape(2,j) = DL2[j];
5117  dshape(9,j) = DL3[j];
5118  }
5119  }
5120  else if (L3 >= 1.0) // T3
5121  {
5122  for (j = 0; j < 3; j++)
5123  {
5124  dshape(6,j) = DL0[j];
5125  dshape(8,j) = DL1[j];
5126  dshape(9,j) = DL2[j];
5127  dshape(3,j) = DL3[j];
5128  }
5129  }
5130  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
5131  {
5132  for (j = 0; j < 3; j++)
5133  {
5134  dshape(4,j) = - DL5[j];
5135  dshape(5,j) = DL2[j];
5136  dshape(6,j) = - DL4[j];
5137  dshape(8,j) = - DL0[j];
5138  }
5139  }
5140  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
5141  {
5142  for (j = 0; j < 3; j++)
5143  {
5144  dshape(4,j) = - DL5[j];
5145  dshape(5,j) = - DL1[j];
5146  dshape(7,j) = DL4[j];
5147  dshape(8,j) = DL3[j];
5148  }
5149  }
5150  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
5151  {
5152  for (j = 0; j < 3; j++)
5153  {
5154  dshape(5,j) = - DL3[j];
5155  dshape(6,j) = - DL4[j];
5156  dshape(8,j) = DL1[j];
5157  dshape(9,j) = DL5[j];
5158  }
5159  }
5160  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
5161  {
5162  for (j = 0; j < 3; j++)
5163  {
5164  dshape(5,j) = DL0[j];
5165  dshape(7,j) = DL4[j];
5166  dshape(8,j) = - DL2[j];
5167  dshape(9,j) = DL5[j];
5168  }
5169  }
5170 }
5171 
5172 
5174  : NodalFiniteElement(2, Geometry::SQUARE, 9, 1, FunctionSpace::rQk)
5175 {
5176  Nodes.IntPoint(0).x = 0.0;
5177  Nodes.IntPoint(0).y = 0.0;
5178  Nodes.IntPoint(1).x = 1.0;
5179  Nodes.IntPoint(1).y = 0.0;
5180  Nodes.IntPoint(2).x = 1.0;
5181  Nodes.IntPoint(2).y = 1.0;
5182  Nodes.IntPoint(3).x = 0.0;
5183  Nodes.IntPoint(3).y = 1.0;
5184  Nodes.IntPoint(4).x = 0.5;
5185  Nodes.IntPoint(4).y = 0.0;
5186  Nodes.IntPoint(5).x = 1.0;
5187  Nodes.IntPoint(5).y = 0.5;
5188  Nodes.IntPoint(6).x = 0.5;
5189  Nodes.IntPoint(6).y = 1.0;
5190  Nodes.IntPoint(7).x = 0.0;
5191  Nodes.IntPoint(7).y = 0.5;
5192  Nodes.IntPoint(8).x = 0.5;
5193  Nodes.IntPoint(8).y = 0.5;
5194 }
5195 
5197  Vector &shape) const
5198 {
5199  int i;
5200  double x = ip.x, y = ip.y;
5201  double Lx, Ly;
5202  Lx = 2.0 * ( 1. - x );
5203  Ly = 2.0 * ( 1. - y );
5204 
5205  // The reference square is split in 4 squares as follows:
5206  //
5207  // T0 - 0,4,7,8
5208  // T1 - 1,4,5,8
5209  // T2 - 2,5,6,8
5210  // T3 - 3,6,7,8
5211 
5212  for (i = 0; i < 9; i++)
5213  {
5214  shape(i) = 0.0;
5215  }
5216 
5217  if ((x <= 0.5) && (y <= 0.5)) // T0
5218  {
5219  shape(0) = (Lx - 1.0) * (Ly - 1.0);
5220  shape(4) = (2.0 - Lx) * (Ly - 1.0);
5221  shape(8) = (2.0 - Lx) * (2.0 - Ly);
5222  shape(7) = (Lx - 1.0) * (2.0 - Ly);
5223  }
5224  else if ((x >= 0.5) && (y <= 0.5)) // T1
5225  {
5226  shape(4) = Lx * (Ly - 1.0);
5227  shape(1) = (1.0 - Lx) * (Ly - 1.0);
5228  shape(5) = (1.0 - Lx) * (2.0 - Ly);
5229  shape(8) = Lx * (2.0 - Ly);
5230  }
5231  else if ((x >= 0.5) && (y >= 0.5)) // T2
5232  {
5233  shape(8) = Lx * Ly ;
5234  shape(5) = (1.0 - Lx) * Ly ;
5235  shape(2) = (1.0 - Lx) * (1.0 - Ly);
5236  shape(6) = Lx * (1.0 - Ly);
5237  }
5238  else if ((x <= 0.5) && (y >= 0.5)) // T3
5239  {
5240  shape(7) = (Lx - 1.0) * Ly ;
5241  shape(8) = (2.0 - Lx) * Ly ;
5242  shape(6) = (2.0 - Lx) * (1.0 - Ly);
5243  shape(3) = (Lx - 1.0) * (1.0 - Ly);
5244  }
5245 }
5246 
5248  DenseMatrix &dshape) const
5249 {
5250  int i,j;
5251  double x = ip.x, y = ip.y;
5252  double Lx, Ly;
5253  Lx = 2.0 * ( 1. - x );
5254  Ly = 2.0 * ( 1. - y );
5255 
5256  for (i = 0; i < 9; i++)
5257  for (j = 0; j < 2; j++)
5258  {
5259  dshape(i,j) = 0.0;
5260  }
5261 
5262  if ((x <= 0.5) && (y <= 0.5)) // T0
5263  {
5264  dshape(0,0) = 2.0 * (1.0 - Ly);
5265  dshape(0,1) = 2.0 * (1.0 - Lx);
5266 
5267  dshape(4,0) = 2.0 * (Ly - 1.0);
5268  dshape(4,1) = -2.0 * (2.0 - Lx);
5269 
5270  dshape(8,0) = 2.0 * (2.0 - Ly);
5271  dshape(8,1) = 2.0 * (2.0 - Lx);
5272 
5273  dshape(7,0) = -2.0 * (2.0 - Ly);
5274  dshape(7,0) = 2.0 * (Lx - 1.0);
5275  }
5276  else if ((x >= 0.5) && (y <= 0.5)) // T1
5277  {
5278  dshape(4,0) = -2.0 * (Ly - 1.0);
5279  dshape(4,1) = -2.0 * Lx;
5280 
5281  dshape(1,0) = 2.0 * (Ly - 1.0);
5282  dshape(1,1) = -2.0 * (1.0 - Lx);
5283 
5284  dshape(5,0) = 2.0 * (2.0 - Ly);
5285  dshape(5,1) = 2.0 * (1.0 - Lx);
5286 
5287  dshape(8,0) = -2.0 * (2.0 - Ly);
5288  dshape(8,1) = 2.0 * Lx;
5289  }
5290  else if ((x >= 0.5) && (y >= 0.5)) // T2
5291  {
5292  dshape(8,0) = -2.0 * Ly;
5293  dshape(8,1) = -2.0 * Lx;
5294 
5295  dshape(5,0) = 2.0 * Ly;
5296  dshape(5,1) = -2.0 * (1.0 - Lx);
5297 
5298  dshape(2,0) = 2.0 * (1.0 - Ly);
5299  dshape(2,1) = 2.0 * (1.0 - Lx);
5300 
5301  dshape(6,0) = -2.0 * (1.0 - Ly);
5302  dshape(6,1) = 2.0 * Lx;
5303  }
5304  else if ((x <= 0.5) && (y >= 0.5)) // T3
5305  {
5306  dshape(7,0) = -2.0 * Ly;
5307  dshape(7,1) = -2.0 * (Lx - 1.0);
5308 
5309  dshape(8,0) = 2.0 * Ly ;
5310  dshape(8,1) = -2.0 * (2.0 - Lx);
5311 
5312  dshape(6,0) = 2.0 * (1.0 - Ly);
5313  dshape(6,1) = 2.0 * (2.0 - Lx);
5314 
5315  dshape(3,0) = -2.0 * (1.0 - Ly);
5316  dshape(3,1) = 2.0 * (Lx - 1.0);
5317  }
5318 }
5319 
5321  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
5322 {
5323  double I[27];
5324  double J[27];
5325  double K[27];
5326  // nodes
5327  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
5328  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
5329  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
5330  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
5331  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
5332  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
5333  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
5334  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
5335  // edges
5336  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
5337  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
5338  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
5339  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
5340  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
5341  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
5342  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
5343  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
5344  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
5345  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
5346  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
5347  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
5348  // faces
5349  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
5350  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
5351  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
5352  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
5353  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
5354  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
5355  // element
5356  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
5357 
5358  for (int n = 0; n < 27; n++)
5359  {
5360  Nodes.IntPoint(n).x = I[n];
5361  Nodes.IntPoint(n).y = J[n];
5362  Nodes.IntPoint(n).z = K[n];
5363  }
5364 }
5365 
5367  Vector &shape) const
5368 {
5369  int i, N[8];
5370  double Lx, Ly, Lz;
5371  double x = ip.x, y = ip.y, z = ip.z;
5372 
5373  for (i = 0; i < 27; i++)
5374  {
5375  shape(i) = 0.0;
5376  }
5377 
5378  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
5379  {
5380  Lx = 1.0 - 2.0 * x;
5381  Ly = 1.0 - 2.0 * y;
5382  Lz = 1.0 - 2.0 * z;
5383 
5384  N[0] = 0;
5385  N[1] = 8;
5386  N[2] = 20;
5387  N[3] = 11;
5388  N[4] = 16;
5389  N[5] = 21;
5390  N[6] = 26;
5391  N[7] = 24;
5392  }
5393  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
5394  {
5395  Lx = 2.0 - 2.0 * x;
5396  Ly = 1.0 - 2.0 * y;
5397  Lz = 1.0 - 2.0 * z;
5398 
5399  N[0] = 8;
5400  N[1] = 1;
5401  N[2] = 9;
5402  N[3] = 20;
5403  N[4] = 21;
5404  N[5] = 17;
5405  N[6] = 22;
5406  N[7] = 26;
5407  }
5408  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
5409  {
5410  Lx = 2.0 - 2.0 * x;
5411  Ly = 2.0 - 2.0 * y;
5412  Lz = 1.0 - 2.0 * z;
5413 
5414  N[0] = 20;
5415  N[1] = 9;
5416  N[2] = 2;
5417  N[3] = 10;
5418  N[4] = 26;
5419  N[5] = 22;
5420  N[6] = 18;
5421  N[7] = 23;
5422  }
5423  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
5424  {
5425  Lx = 1.0 - 2.0 * x;
5426  Ly = 2.0 - 2.0 * y;
5427  Lz = 1.0 - 2.0 * z;
5428 
5429  N[0] = 11;
5430  N[1] = 20;
5431  N[2] = 10;
5432  N[3] = 3;
5433  N[4] = 24;
5434  N[5] = 26;
5435  N[6] = 23;
5436  N[7] = 19;
5437  }
5438  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
5439  {
5440  Lx = 1.0 - 2.0 * x;
5441  Ly = 1.0 - 2.0 * y;
5442  Lz = 2.0 - 2.0 * z;
5443 
5444  N[0] = 16;
5445  N[1] = 21;
5446  N[2] = 26;
5447  N[3] = 24;
5448  N[4] = 4;
5449  N[5] = 12;
5450  N[6] = 25;
5451  N[7] = 15;
5452  }
5453  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
5454  {
5455  Lx = 2.0 - 2.0 * x;
5456  Ly = 1.0 - 2.0 * y;
5457  Lz = 2.0 - 2.0 * z;
5458 
5459  N[0] = 21;
5460  N[1] = 17;
5461  N[2] = 22;
5462  N[3] = 26;
5463  N[4] = 12;
5464  N[5] = 5;
5465  N[6] = 13;
5466  N[7] = 25;
5467  }
5468  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
5469  {
5470  Lx = 2.0 - 2.0 * x;
5471  Ly = 2.0 - 2.0 * y;
5472  Lz = 2.0 - 2.0 * z;
5473 
5474  N[0] = 26;
5475  N[1] = 22;
5476  N[2] = 18;
5477  N[3] = 23;
5478  N[4] = 25;
5479  N[5] = 13;
5480  N[6] = 6;
5481  N[7] = 14;
5482  }
5483  else // T7
5484  {
5485  Lx = 1.0 - 2.0 * x;
5486  Ly = 2.0 - 2.0 * y;
5487  Lz = 2.0 - 2.0 * z;
5488 
5489  N[0] = 24;
5490  N[1] = 26;
5491  N[2] = 23;
5492  N[3] = 19;
5493  N[4] = 15;
5494  N[5] = 25;
5495  N[6] = 14;
5496  N[7] = 7;
5497  }
5498 
5499  shape(N[0]) = Lx * Ly * Lz;
5500  shape(N[1]) = (1 - Lx) * Ly * Lz;
5501  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
5502  shape(N[3]) = Lx * (1 - Ly) * Lz;
5503  shape(N[4]) = Lx * Ly * (1 - Lz);
5504  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
5505  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
5506  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
5507 }
5508 
5510  DenseMatrix &dshape) const
5511 {
5512  int i, j, N[8];
5513  double Lx, Ly, Lz;
5514  double x = ip.x, y = ip.y, z = ip.z;
5515 
5516  for (i = 0; i < 27; i++)
5517  for (j = 0; j < 3; j++)
5518  {
5519  dshape(i,j) = 0.0;
5520  }
5521 
5522  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
5523  {
5524  Lx = 1.0 - 2.0 * x;
5525  Ly = 1.0 - 2.0 * y;
5526  Lz = 1.0 - 2.0 * z;
5527 
5528  N[0] = 0;
5529  N[1] = 8;
5530  N[2] = 20;
5531  N[3] = 11;
5532  N[4] = 16;
5533  N[5] = 21;
5534  N[6] = 26;
5535  N[7] = 24;
5536  }
5537  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
5538  {
5539  Lx = 2.0 - 2.0 * x;
5540  Ly = 1.0 - 2.0 * y;
5541  Lz = 1.0 - 2.0 * z;
5542 
5543  N[0] = 8;
5544  N[1] = 1;
5545  N[2] = 9;
5546  N[3] = 20;
5547  N[4] = 21;
5548  N[5] = 17;
5549  N[6] = 22;
5550  N[7] = 26;
5551  }
5552  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
5553  {
5554  Lx = 2.0 - 2.0 * x;
5555  Ly = 2.0 - 2.0 * y;
5556  Lz = 1.0 - 2.0 * z;
5557 
5558  N[0] = 20;
5559  N[1] = 9;
5560  N[2] = 2;
5561  N[3] = 10;
5562  N[4] = 26;
5563  N[5] = 22;
5564  N[6] = 18;
5565  N[7] = 23;
5566  }
5567  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
5568  {
5569  Lx = 1.0 - 2.0 * x;
5570  Ly = 2.0 - 2.0 * y;
5571  Lz = 1.0 - 2.0 * z;
5572 
5573  N[0] = 11;
5574  N[1] = 20;
5575  N[2] = 10;
5576  N[3] = 3;
5577  N[4] = 24;
5578  N[5] = 26;
5579  N[6] = 23;
5580  N[7] = 19;
5581  }
5582  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
5583  {
5584  Lx = 1.0 - 2.0 * x;
5585  Ly = 1.0 - 2.0 * y;
5586  Lz = 2.0 - 2.0 * z;
5587 
5588  N[0] = 16;
5589  N[1] = 21;
5590  N[2] = 26;
5591  N[3] = 24;
5592  N[4] = 4;
5593  N[5] = 12;
5594  N[6] = 25;
5595  N[7] = 15;
5596  }
5597  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
5598  {
5599  Lx = 2.0 - 2.0 * x;
5600  Ly = 1.0 - 2.0 * y;
5601  Lz = 2.0 - 2.0 * z;
5602 
5603  N[0] = 21;
5604  N[1] = 17;
5605  N[2] = 22;
5606  N[3] = 26;
5607  N[4] = 12;
5608  N[5] = 5;
5609  N[6] = 13;
5610  N[7] = 25;
5611  }
5612  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
5613  {
5614  Lx = 2.0 - 2.0 * x;
5615  Ly = 2.0 - 2.0 * y;
5616  Lz = 2.0 - 2.0 * z;
5617 
5618  N[0] = 26;
5619  N[1] = 22;
5620  N[2] = 18;
5621  N[3] = 23;
5622  N[4] = 25;
5623  N[5] = 13;
5624  N[6] = 6;
5625  N[7] = 14;
5626  }
5627  else // T7
5628  {
5629  Lx = 1.0 - 2.0 * x;
5630  Ly = 2.0 - 2.0 * y;
5631  Lz = 2.0 - 2.0 * z;
5632 
5633  N[0] = 24;
5634  N[1] = 26;
5635  N[2] = 23;
5636  N[3] = 19;
5637  N[4] = 15;
5638  N[5] = 25;
5639  N[6] = 14;
5640  N[7] = 7;
5641  }
5642 
5643  dshape(N[0],0) = -2.0 * Ly * Lz ;
5644  dshape(N[0],1) = -2.0 * Lx * Lz ;
5645  dshape(N[0],2) = -2.0 * Lx * Ly ;
5646 
5647  dshape(N[1],0) = 2.0 * Ly * Lz ;
5648  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
5649  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
5650 
5651  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
5652  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
5653  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
5654 
5655  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
5656  dshape(N[3],1) = 2.0 * Lx * Lz ;
5657  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
5658 
5659  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
5660  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
5661  dshape(N[4],2) = 2.0 * Lx * Ly ;
5662 
5663  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
5664  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
5665  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
5666 
5667  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
5668  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
5669  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
5670 
5671  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
5672  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
5673  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
5674 }
5675 
5676 
5678  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
5679 {
5680  // not real nodes ...
5681  Nodes.IntPoint(0).x = 0.5;
5682  Nodes.IntPoint(0).y = 0.0;
5683  Nodes.IntPoint(0).z = 0.0;
5684 
5685  Nodes.IntPoint(1).x = 1.0;
5686  Nodes.IntPoint(1).y = 0.5;
5687  Nodes.IntPoint(1).z = 0.0;
5688 
5689  Nodes.IntPoint(2).x = 0.5;
5690  Nodes.IntPoint(2).y = 1.0;
5691  Nodes.IntPoint(2).z = 0.0;
5692 
5693  Nodes.IntPoint(3).x = 0.0;
5694  Nodes.IntPoint(3).y = 0.5;
5695  Nodes.IntPoint(3).z = 0.0;
5696 
5697  Nodes.IntPoint(4).x = 0.5;
5698  Nodes.IntPoint(4).y = 0.0;
5699  Nodes.IntPoint(4).z = 1.0;
5700 
5701  Nodes.IntPoint(5).x = 1.0;
5702  Nodes.IntPoint(5).y = 0.5;
5703  Nodes.IntPoint(5).z = 1.0;
5704 
5705  Nodes.IntPoint(6).x = 0.5;
5706  Nodes.IntPoint(6).y = 1.0;
5707  Nodes.IntPoint(6).z = 1.0;
5708 
5709  Nodes.IntPoint(7).x = 0.0;
5710  Nodes.IntPoint(7).y = 0.5;
5711  Nodes.IntPoint(7).z = 1.0;
5712 
5713  Nodes.IntPoint(8).x = 0.0;
5714  Nodes.IntPoint(8).y = 0.0;
5715  Nodes.IntPoint(8).z = 0.5;
5716 
5717  Nodes.IntPoint(9).x = 1.0;
5718  Nodes.IntPoint(9).y = 0.0;
5719  Nodes.IntPoint(9).z = 0.5;
5720 
5721  Nodes.IntPoint(10).x= 1.0;
5722  Nodes.IntPoint(10).y= 1.0;
5723  Nodes.IntPoint(10).z= 0.5;
5724 
5725  Nodes.IntPoint(11).x= 0.0;
5726  Nodes.IntPoint(11).y= 1.0;
5727  Nodes.IntPoint(11).z= 0.5;
5728 }
5729 
5731  DenseMatrix &shape) const
5732 {
5733  double x = ip.x, y = ip.y, z = ip.z;
5734 
5735  shape(0,0) = (1. - y) * (1. - z);
5736  shape(0,1) = 0.;
5737  shape(0,2) = 0.;
5738 
5739  shape(2,0) = y * (1. - z);
5740  shape(2,1) = 0.;
5741  shape(2,2) = 0.;
5742 
5743  shape(4,0) = z * (1. - y);
5744  shape(4,1) = 0.;
5745  shape(4,2) = 0.;
5746 
5747  shape(6,0) = y * z;
5748  shape(6,1) = 0.;
5749  shape(6,2) = 0.;
5750 
5751  shape(1,0) = 0.;
5752  shape(1,1) = x * (1. - z);
5753  shape(1,2) = 0.;
5754 
5755  shape(3,0) = 0.;
5756  shape(3,1) = (1. - x) * (1. - z);
5757  shape(3,2) = 0.;
5758 
5759  shape(5,0) = 0.;
5760  shape(5,1) = x * z;
5761  shape(5,2) = 0.;
5762 
5763  shape(7,0) = 0.;
5764  shape(7,1) = (1. - x) * z;
5765  shape(7,2) = 0.;
5766 
5767  shape(8,0) = 0.;
5768  shape(8,1) = 0.;
5769  shape(8,2) = (1. - x) * (1. - y);
5770 
5771  shape(9,0) = 0.;
5772  shape(9,1) = 0.;
5773  shape(9,2) = x * (1. - y);
5774 
5775  shape(10,0) = 0.;
5776  shape(10,1) = 0.;
5777  shape(10,2) = x * y;
5778 
5779  shape(11,0) = 0.;
5780  shape(11,1) = 0.;
5781  shape(11,2) = y * (1. - x);
5782 
5783 }
5784 
5786  DenseMatrix &curl_shape)
5787 const
5788 {
5789  double x = ip.x, y = ip.y, z = ip.z;
5790 
5791  curl_shape(0,0) = 0.;
5792  curl_shape(0,1) = y - 1.;
5793  curl_shape(0,2) = 1. - z;
5794 
5795  curl_shape(2,0) = 0.;
5796  curl_shape(2,1) = -y;
5797  curl_shape(2,2) = z - 1.;
5798 
5799  curl_shape(4,0) = 0;
5800  curl_shape(4,1) = 1. - y;
5801  curl_shape(4,2) = z;
5802 
5803  curl_shape(6,0) = 0.;
5804  curl_shape(6,1) = y;
5805  curl_shape(6,2) = -z;
5806 
5807  curl_shape(1,0) = x;
5808  curl_shape(1,1) = 0.;
5809  curl_shape(1,2) = 1. - z;
5810 
5811  curl_shape(3,0) = 1. - x;
5812  curl_shape(3,1) = 0.;
5813  curl_shape(3,2) = z - 1.;
5814 
5815  curl_shape(5,0) = -x;
5816  curl_shape(5,1) = 0.;
5817  curl_shape(5,2) = z;
5818 
5819  curl_shape(7,0) = x - 1.;
5820  curl_shape(7,1) = 0.;
5821  curl_shape(7,2) = -z;
5822 
5823  curl_shape(8,0) = x - 1.;
5824  curl_shape(8,1) = 1. - y;
5825  curl_shape(8,2) = 0.;
5826 
5827  curl_shape(9,0) = -x;
5828  curl_shape(9,1) = y - 1.;
5829  curl_shape(9,2) = 0;
5830 
5831  curl_shape(10,0) = x;
5832  curl_shape(10,1) = -y;
5833  curl_shape(10,2) = 0.;
5834 
5835  curl_shape(11,0) = 1. - x;
5836  curl_shape(11,1) = y;
5837  curl_shape(11,2) = 0.;
5838 }
5839 
5840 const double Nedelec1HexFiniteElement::tk[12][3] =
5841 {
5842  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5843  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5844  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
5845 };
5846 
5849 {
5850  int k, j;
5851 #ifdef MFEM_THREAD_SAFE
5853 #endif
5854 
5855 #ifdef MFEM_DEBUG
5856  for (k = 0; k < 12; k++)
5857  {
5859  for (j = 0; j < 12; j++)
5860  {
5861  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5862  vshape(j,2)*tk[k][2] );
5863  if (j == k) { d -= 1.0; }
5864  if (fabs(d) > 1.0e-12)
5865  {
5866  mfem::err << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
5867  " k = " << k << ", j = " << j << ", d = " << d << endl;
5868  mfem_error();
5869  }
5870  }
5871  }
5872 #endif
5873 
5874  IntegrationPoint ip;
5875  ip.x = ip.y = ip.z = 0.0;
5876  Trans.SetIntPoint (&ip);
5877  // Trans must be linear (more to have embedding?)
5878  const DenseMatrix &J = Trans.Jacobian();
5879  double vk[3];
5880  Vector xk (vk, 3);
5881 
5882  for (k = 0; k < 12; k++)
5883  {
5884  Trans.Transform (Nodes.IntPoint (k), xk);
5885  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5886  CalcVShape (ip, vshape);
5887  // vk = J tk
5888  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5889  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5890  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5891  for (j = 0; j < 12; j++)
5892  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5893  vshape(j,2)*vk[2])) < 1.0e-12)
5894  {
5895  I(k,j) = 0.0;
5896  }
5897  }
5898 }
5899 
5902  Vector &dofs) const
5903 {
5904  double vk[3];
5905  Vector xk (vk, 3);
5906 
5907  for (int k = 0; k < 12; k++)
5908  {
5909  Trans.SetIntPoint (&Nodes.IntPoint (k));
5910  const DenseMatrix &J = Trans.Jacobian();
5911 
5912  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5913  // xk^t J tk
5914  dofs(k) =
5915  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5916  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5917  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5918  }
5919 }
5920 
5921 
5923  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
5924 {
5925  // not real nodes ...
5926  Nodes.IntPoint(0).x = 0.5;
5927  Nodes.IntPoint(0).y = 0.0;
5928  Nodes.IntPoint(0).z = 0.0;
5929 
5930  Nodes.IntPoint(1).x = 0.0;
5931  Nodes.IntPoint(1).y = 0.5;
5932  Nodes.IntPoint(1).z = 0.0;
5933 
5934  Nodes.IntPoint(2).x = 0.0;
5935  Nodes.IntPoint(2).y = 0.0;
5936  Nodes.IntPoint(2).z = 0.5;
5937 
5938  Nodes.IntPoint(3).x = 0.5;
5939  Nodes.IntPoint(3).y = 0.5;
5940  Nodes.IntPoint(3).z = 0.0;
5941 
5942  Nodes.IntPoint(4).x = 0.5;
5943  Nodes.IntPoint(4).y = 0.0;
5944  Nodes.IntPoint(4).z = 0.5;
5945 
5946  Nodes.IntPoint(5).x = 0.0;
5947  Nodes.IntPoint(5).y = 0.5;
5948  Nodes.IntPoint(5).z = 0.5;
5949 }
5950 
5952  DenseMatrix &shape) const
5953 {
5954  double x = ip.x, y = ip.y, z = ip.z;
5955 
5956  shape(0,0) = 1. - y - z;
5957  shape(0,1) = x;
5958  shape(0,2) = x;
5959 
5960  shape(1,0) = y;
5961  shape(1,1) = 1. - x - z;
5962  shape(1,2) = y;
5963 
5964  shape(2,0) = z;
5965  shape(2,1) = z;
5966  shape(2,2) = 1. - x - y;
5967 
5968  shape(3,0) = -y;
5969  shape(3,1) = x;
5970  shape(3,2) = 0.;
5971 
5972  shape(4,0) = -z;
5973  shape(4,1) = 0.;
5974  shape(4,2) = x;
5975 
5976  shape(5,0) = 0.;
5977  shape(5,1) = -z;
5978  shape(5,2) = y;
5979 }
5980 
5982  DenseMatrix &curl_shape)
5983 const
5984 {
5985  curl_shape(0,0) = 0.;
5986  curl_shape(0,1) = -2.;
5987  curl_shape(0,2) = 2.;
5988 
5989  curl_shape(1,0) = 2.;
5990  curl_shape(1,1) = 0.;
5991  curl_shape(1,2) = -2.;
5992 
5993  curl_shape(2,0) = -2.;
5994  curl_shape(2,1) = 2.;
5995  curl_shape(2,2) = 0.;
5996 
5997  curl_shape(3,0) = 0.;
5998  curl_shape(3,1) = 0.;
5999  curl_shape(3,2) = 2.;
6000 
6001  curl_shape(4,0) = 0.;
6002  curl_shape(4,1) = -2.;
6003  curl_shape(4,2) = 0.;
6004 
6005  curl_shape(5,0) = 2.;
6006  curl_shape(5,1) = 0.;
6007  curl_shape(5,2) = 0.;
6008 }
6009 
6010 const double Nedelec1TetFiniteElement::tk[6][3] =
6011 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
6012 
6015 {
6016  int k, j;
6017 #ifdef MFEM_THREAD_SAFE
6019 #endif
6020 
6021 #ifdef MFEM_DEBUG
6022  for (k = 0; k < 6; k++)
6023  {
6025  for (j = 0; j < 6; j++)
6026  {
6027  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
6028  vshape(j,2)*tk[k][2] );
6029  if (j == k) { d -= 1.0; }
6030  if (fabs(d) > 1.0e-12)
6031  {
6032  mfem::err << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
6033  " k = " << k << ", j = " << j << ", d = " << d << endl;
6034  mfem_error();
6035  }
6036  }
6037  }
6038 #endif
6039 
6040  IntegrationPoint ip;
6041  ip.x = ip.y = ip.z = 0.0;
6042  Trans.SetIntPoint (&ip);
6043  // Trans must be linear
6044  const DenseMatrix &J = Trans.Jacobian();
6045  double vk[3];
6046  Vector xk (vk, 3);
6047 
6048  for (k = 0; k < 6; k++)
6049  {
6050  Trans.Transform (Nodes.IntPoint (k), xk);
6051  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6052  CalcVShape (ip, vshape);
6053  // vk = J tk
6054  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
6055  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
6056  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
6057  for (j = 0; j < 6; j++)
6058  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6059  vshape(j,2)*vk[2])) < 1.0e-12)
6060  {
6061  I(k,j) = 0.0;
6062  }
6063  }
6064 }
6065 
6068  Vector &dofs) const
6069 {
6070  double vk[3];
6071  Vector xk (vk, 3);
6072 
6073  for (int k = 0; k < 6; k++)
6074  {
6075  Trans.SetIntPoint (&Nodes.IntPoint (k));
6076  const DenseMatrix &J = Trans.Jacobian();
6077 
6078  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6079  // xk^t J tk
6080  dofs(k) =
6081  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
6082  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
6083  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
6084  }
6085 }
6086 
6088  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
6089 {
6090  // not real nodes ...
6091  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
6092  Nodes.IntPoint(0).x = 0.5;
6093  Nodes.IntPoint(0).y = 0.5;
6094  Nodes.IntPoint(0).z = 0.0;
6095 
6096  Nodes.IntPoint(1).x = 0.5;
6097  Nodes.IntPoint(1).y = 0.0;
6098  Nodes.IntPoint(1).z = 0.5;
6099 
6100  Nodes.IntPoint(2).x = 1.0;
6101  Nodes.IntPoint(2).y = 0.5;
6102  Nodes.IntPoint(2).z = 0.5;
6103 
6104  Nodes.IntPoint(3).x = 0.5;
6105  Nodes.IntPoint(3).y = 1.0;
6106  Nodes.IntPoint(3).z = 0.5;
6107 
6108  Nodes.IntPoint(4).x = 0.0;
6109  Nodes.IntPoint(4).y = 0.5;
6110  Nodes.IntPoint(4).z = 0.5;
6111 
6112  Nodes.IntPoint(5).x = 0.5;
6113  Nodes.IntPoint(5).y = 0.5;
6114  Nodes.IntPoint(5).z = 1.0;
6115 }
6116 
6118  DenseMatrix &shape) const
6119 {
6120  double x = ip.x, y = ip.y, z = ip.z;
6121  // z = 0
6122  shape(0,0) = 0.;
6123  shape(0,1) = 0.;
6124  shape(0,2) = z - 1.;
6125  // y = 0
6126  shape(1,0) = 0.;
6127  shape(1,1) = y - 1.;
6128  shape(1,2) = 0.;
6129  // x = 1
6130  shape(2,0) = x;
6131  shape(2,1) = 0.;
6132  shape(2,2) = 0.;
6133  // y = 1
6134  shape(3,0) = 0.;
6135  shape(3,1) = y;
6136  shape(3,2) = 0.;
6137  // x = 0
6138  shape(4,0) = x - 1.;
6139  shape(4,1) = 0.;
6140  shape(4,2) = 0.;
6141  // z = 1
6142  shape(5,0) = 0.;
6143  shape(5,1) = 0.;
6144  shape(5,2) = z;
6145 }
6146 
6148  Vector &divshape) const
6149 {
6150  divshape(0) = 1.;
6151  divshape(1) = 1.;
6152  divshape(2) = 1.;
6153  divshape(3) = 1.;
6154  divshape(4) = 1.;
6155  divshape(5) = 1.;
6156 }
6157 
6158 const double RT0HexFiniteElement::nk[6][3] =
6159 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
6160 
6163 {
6164  int k, j;
6165 #ifdef MFEM_THREAD_SAFE
6167  DenseMatrix Jinv(Dim);
6168 #endif
6169 
6170 #ifdef MFEM_DEBUG
6171  for (k = 0; k < 6; k++)
6172  {
6174  for (j = 0; j < 6; j++)
6175  {
6176  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6177  vshape(j,2)*nk[k][2] );
6178  if (j == k) { d -= 1.0; }
6179  if (fabs(d) > 1.0e-12)
6180  {
6181  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
6182  " k = " << k << ", j = " << j << ", d = " << d << endl;
6183  mfem_error();
6184  }
6185  }
6186  }
6187 #endif
6188 
6189  IntegrationPoint ip;
6190  ip.x = ip.y = ip.z = 0.0;
6191  Trans.SetIntPoint (&ip);
6192  // Trans must be linear
6193  // set Jinv = |J| J^{-t} = adj(J)^t
6194  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6195  double vk[3];
6196  Vector xk (vk, 3);
6197 
6198  for (k = 0; k < 6; k++)
6199  {
6200  Trans.Transform (Nodes.IntPoint (k), xk);
6201  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6202  CalcVShape (ip, vshape);
6203  // vk = |J| J^{-t} nk
6204  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6205  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6206  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6207  for (j = 0; j < 6; j++)
6208  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6209  vshape(j,2)*vk[2])) < 1.0e-12)
6210  {
6211  I(k,j) = 0.0;
6212  }
6213  }
6214 }
6215 
6218  Vector &dofs) const
6219 {
6220  double vk[3];
6221  Vector xk (vk, 3);
6222 #ifdef MFEM_THREAD_SAFE
6223  DenseMatrix Jinv(Dim);
6224 #endif
6225 
6226  for (int k = 0; k < 6; k++)
6227  {
6228  Trans.SetIntPoint (&Nodes.IntPoint (k));
6229  // set Jinv = |J| J^{-t} = adj(J)^t
6230  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6231 
6232  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6233  // xk^t |J| J^{-t} nk
6234  dofs(k) =
6235  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6236  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6237  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6238  }
6239 }
6240 
6242  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
6243 {
6244  // z = 0
6245  Nodes.IntPoint(2).x = 1./3.;
6246  Nodes.IntPoint(2).y = 1./3.;
6247  Nodes.IntPoint(2).z = 0.0;
6248  Nodes.IntPoint(3).x = 2./3.;
6249  Nodes.IntPoint(3).y = 1./3.;
6250  Nodes.IntPoint(3).z = 0.0;
6251  Nodes.IntPoint(0).x = 1./3.;
6252  Nodes.IntPoint(0).y = 2./3.;
6253  Nodes.IntPoint(0).z = 0.0;
6254  Nodes.IntPoint(1).x = 2./3.;
6255  Nodes.IntPoint(1).y = 2./3.;
6256  Nodes.IntPoint(1).z = 0.0;
6257  // y = 0
6258  Nodes.IntPoint(4).x = 1./3.;
6259  Nodes.IntPoint(4).y = 0.0;
6260  Nodes.IntPoint(4).z = 1./3.;
6261  Nodes.IntPoint(5).x = 2./3.;
6262  Nodes.IntPoint(5).y = 0.0;
6263  Nodes.IntPoint(5).z = 1./3.;
6264  Nodes.IntPoint(6).x = 1./3.;
6265  Nodes.IntPoint(6).y = 0.0;
6266  Nodes.IntPoint(6).z = 2./3.;
6267  Nodes.IntPoint(7).x = 2./3.;
6268  Nodes.IntPoint(7).y = 0.0;
6269  Nodes.IntPoint(7).z = 2./3.;
6270  // x = 1
6271  Nodes.IntPoint(8).x = 1.0;
6272  Nodes.IntPoint(8).y = 1./3.;
6273  Nodes.IntPoint(8).z = 1./3.;
6274  Nodes.IntPoint(9).x = 1.0;
6275  Nodes.IntPoint(9).y = 2./3.;
6276  Nodes.IntPoint(9).z = 1./3.;
6277  Nodes.IntPoint(10).x = 1.0;
6278  Nodes.IntPoint(10).y = 1./3.;
6279  Nodes.IntPoint(10).z = 2./3.;
6280  Nodes.IntPoint(11).x = 1.0;
6281  Nodes.IntPoint(11).y = 2./3.;
6282  Nodes.IntPoint(11).z = 2./3.;
6283  // y = 1
6284  Nodes.IntPoint(13).x = 1./3.;
6285  Nodes.IntPoint(13).y = 1.0;
6286  Nodes.IntPoint(13).z = 1./3.;
6287  Nodes.IntPoint(12).x = 2./3.;
6288  Nodes.IntPoint(12).y = 1.0;
6289  Nodes.IntPoint(12).z = 1./3.;
6290  Nodes.IntPoint(15).x = 1./3.;
6291  Nodes.IntPoint(15).y = 1.0;
6292  Nodes.IntPoint(15).z = 2./3.;
6293  Nodes.IntPoint(14).x = 2./3.;
6294  Nodes.IntPoint(14).y = 1.0;
6295  Nodes.IntPoint(14).z = 2./3.;
6296  // x = 0
6297  Nodes.IntPoint(17).x = 0.0;
6298  Nodes.IntPoint(17).y = 1./3.;
6299  Nodes.IntPoint(17).z = 1./3.;
6300  Nodes.IntPoint(16).x = 0.0;
6301  Nodes.IntPoint(16).y = 2./3.;
6302  Nodes.IntPoint(16).z = 1./3.;
6303  Nodes.IntPoint(19).x = 0.0;
6304  Nodes.IntPoint(19).y = 1./3.;
6305  Nodes.IntPoint(19).z = 2./3.;
6306  Nodes.IntPoint(18).x = 0.0;
6307  Nodes.IntPoint(18).y = 2./3.;
6308  Nodes.IntPoint(18).z = 2./3.;
6309  // z = 1
6310  Nodes.IntPoint(20).x = 1./3.;
6311  Nodes.IntPoint(20).y = 1./3.;
6312  Nodes.IntPoint(20).z = 1.0;
6313  Nodes.IntPoint(21).x = 2./3.;
6314  Nodes.IntPoint(21).y = 1./3.;
6315  Nodes.IntPoint(21).z = 1.0;
6316  Nodes.IntPoint(22).x = 1./3.;
6317  Nodes.IntPoint(22).y = 2./3.;
6318  Nodes.IntPoint(22).z = 1.0;
6319  Nodes.IntPoint(23).x = 2./3.;
6320  Nodes.IntPoint(23).y = 2./3.;
6321  Nodes.IntPoint(23).z = 1.0;
6322  // x = 0.5 (interior)
6323  Nodes.IntPoint(24).x = 0.5;
6324  Nodes.IntPoint(24).y = 1./3.;
6325  Nodes.IntPoint(24).z = 1./3.;
6326  Nodes.IntPoint(25).x = 0.5;
6327  Nodes.IntPoint(25).y = 1./3.;
6328  Nodes.IntPoint(25).z = 2./3.;
6329  Nodes.IntPoint(26).x = 0.5;
6330  Nodes.IntPoint(26).y = 2./3.;
6331  Nodes.IntPoint(26).z = 1./3.;
6332  Nodes.IntPoint(27).x = 0.5;
6333  Nodes.IntPoint(27).y = 2./3.;
6334  Nodes.IntPoint(27).z = 2./3.;
6335  // y = 0.5 (interior)
6336  Nodes.IntPoint(28).x = 1./3.;
6337  Nodes.IntPoint(28).y = 0.5;
6338  Nodes.IntPoint(28).z = 1./3.;
6339  Nodes.IntPoint(29).x = 1./3.;
6340  Nodes.IntPoint(29).y = 0.5;
6341  Nodes.IntPoint(29).z = 2./3.;
6342  Nodes.IntPoint(30).x = 2./3.;
6343  Nodes.IntPoint(30).y = 0.5;
6344  Nodes.IntPoint(30).z = 1./3.;
6345  Nodes.IntPoint(31).x = 2./3.;
6346  Nodes.IntPoint(31).y = 0.5;
6347  Nodes.IntPoint(31).z = 2./3.;
6348  // z = 0.5 (interior)
6349  Nodes.IntPoint(32).x = 1./3.;
6350  Nodes.IntPoint(32).y = 1./3.;
6351  Nodes.IntPoint(32).z = 0.5;
6352  Nodes.IntPoint(33).x = 1./3.;
6353  Nodes.IntPoint(33).y = 2./3.;
6354  Nodes.IntPoint(33).z = 0.5;
6355  Nodes.IntPoint(34).x = 2./3.;
6356  Nodes.IntPoint(34).y = 1./3.;
6357  Nodes.IntPoint(34).z = 0.5;
6358  Nodes.IntPoint(35).x = 2./3.;
6359  Nodes.IntPoint(35).y = 2./3.;
6360  Nodes.IntPoint(35).z = 0.5;
6361 }
6362 
6364  DenseMatrix &shape) const
6365 {
6366  double x = ip.x, y = ip.y, z = ip.z;
6367  // z = 0
6368  shape(2,0) = 0.;
6369  shape(2,1) = 0.;
6370  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6371  shape(3,0) = 0.;
6372  shape(3,1) = 0.;
6373  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6374  shape(0,0) = 0.;
6375  shape(0,1) = 0.;
6376  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6377  shape(1,0) = 0.;
6378  shape(1,1) = 0.;
6379  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6380  // y = 0
6381  shape(4,0) = 0.;
6382  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6383  shape(4,2) = 0.;
6384  shape(5,0) = 0.;
6385  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6386  shape(5,2) = 0.;
6387  shape(6,0) = 0.;
6388  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6389  shape(6,2) = 0.;
6390  shape(7,0) = 0.;
6391  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6392  shape(7,2) = 0.;
6393  // x = 1
6394  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6395  shape(8,1) = 0.;
6396  shape(8,2) = 0.;
6397  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6398  shape(9,1) = 0.;
6399  shape(9,2) = 0.;
6400  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6401  shape(10,1) = 0.;
6402  shape(10,2) = 0.;
6403  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6404  shape(11,1) = 0.;
6405  shape(11,2) = 0.;
6406  // y = 1
6407  shape(13,0) = 0.;
6408  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6409  shape(13,2) = 0.;
6410  shape(12,0) = 0.;
6411  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6412  shape(12,2) = 0.;
6413  shape(15,0) = 0.;
6414  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6415  shape(15,2) = 0.;
6416  shape(14,0) = 0.;
6417  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6418  shape(14,2) = 0.;
6419  // x = 0
6420  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6421  shape(17,1) = 0.;
6422  shape(17,2) = 0.;
6423  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6424  shape(16,1) = 0.;
6425  shape(16,2) = 0.;
6426  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6427  shape(19,1) = 0.;
6428  shape(19,2) = 0.;
6429  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6430  shape(18,1) = 0.;
6431  shape(18,2) = 0.;
6432  // z = 1
6433  shape(20,0) = 0.;
6434  shape(20,1) = 0.;
6435  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6436  shape(21,0) = 0.;
6437  shape(21,1) = 0.;
6438  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6439  shape(22,0) = 0.;
6440  shape(22,1) = 0.;
6441  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6442  shape(23,0) = 0.;
6443  shape(23,1) = 0.;
6444  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6445  // x = 0.5 (interior)
6446  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6447  shape(24,1) = 0.;
6448  shape(24,2) = 0.;
6449  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6450  shape(25,1) = 0.;
6451  shape(25,2) = 0.;
6452  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6453  shape(26,1) = 0.;
6454  shape(26,2) = 0.;
6455  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6456  shape(27,1) = 0.;
6457  shape(27,2) = 0.;
6458  // y = 0.5 (interior)
6459  shape(28,0) = 0.;
6460  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6461  shape(28,2) = 0.;
6462  shape(29,0) = 0.;
6463  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6464  shape(29,2) = 0.;
6465  shape(30,0) = 0.;
6466  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6467  shape(30,2) = 0.;
6468  shape(31,0) = 0.;
6469  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6470  shape(31,2) = 0.;
6471  // z = 0.5 (interior)
6472  shape(32,0) = 0.;
6473  shape(32,1) = 0.;
6474  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6475  shape(33,0) = 0.;
6476  shape(33,1) = 0.;
6477  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6478  shape(34,0) = 0.;
6479  shape(34,1) = 0.;
6480  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6481  shape(35,0) = 0.;
6482  shape(35,1) = 0.;
6483  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6484 }
6485 
6487  Vector &divshape) const
6488 {
6489  double x = ip.x, y = ip.y, z = ip.z;
6490  // z = 0
6491  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6492  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6493  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6494  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6495  // y = 0
6496  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6497  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6498  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6499  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6500  // x = 1
6501  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6502  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6503  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6504  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6505  // y = 1
6506  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6507  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6508  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6509  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6510  // x = 0
6511  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6512  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6513  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6514  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6515  // z = 1
6516  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6517  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6518  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6519  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6520  // x = 0.5 (interior)
6521  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6522  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6523  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6524  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6525  // y = 0.5 (interior)
6526  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6527  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6528  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6529  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6530  // z = 0.5 (interior)
6531  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6532  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6533  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6534  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6535 }
6536 
6537 const double RT1HexFiniteElement::nk[36][3] =
6538 {
6539  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
6540  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
6541  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
6542  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
6543  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
6544  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
6545  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
6546  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
6547  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
6548 };
6549 
6552 {
6553  int k, j;
6554 #ifdef MFEM_THREAD_SAFE
6556  DenseMatrix Jinv(Dim);
6557 #endif
6558 
6559 #ifdef MFEM_DEBUG
6560  for (k = 0; k < 36; k++)
6561  {
6563  for (j = 0; j < 36; j++)
6564  {
6565  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6566  vshape(j,2)*nk[k][2] );
6567  if (j == k) { d -= 1.0; }
6568  if (fabs(d) > 1.0e-12)
6569  {
6570  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
6571  " k = " << k << ", j = " << j << ", d = " << d << endl;
6572  mfem_error();
6573  }
6574  }
6575  }
6576 #endif
6577 
6578  IntegrationPoint ip;
6579  ip.x = ip.y = ip.z = 0.0;
6580  Trans.SetIntPoint (&ip);
6581  // Trans must be linear
6582  // set Jinv = |J| J^{-t} = adj(J)^t
6583  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6584  double vk[3];
6585  Vector xk (vk, 3);
6586 
6587  for (k = 0; k < 36; k++)
6588  {
6589  Trans.Transform (Nodes.IntPoint (k), xk);
6590  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6591  CalcVShape (ip, vshape);
6592  // vk = |J| J^{-t} nk
6593  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6594  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6595  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6596  for (j = 0; j < 36; j++)
6597  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6598  vshape(j,2)*vk[2])) < 1.0e-12)
6599  {
6600  I(k,j) = 0.0;
6601  }
6602  }
6603 }
6604 
6607  Vector &dofs) const
6608 {
6609  double vk[3];
6610  Vector xk (vk, 3);
6611 #ifdef MFEM_THREAD_SAFE
6612  DenseMatrix Jinv(Dim);
6613 #endif
6614 
6615  for (int k = 0; k < 36; k++)
6616  {
6617  Trans.SetIntPoint (&Nodes.IntPoint (k));
6618  // set Jinv = |J| J^{-t} = adj(J)^t
6619  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6620 
6621  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6622  // xk^t |J| J^{-t} nk
6623  dofs(k) =
6624  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6625  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6626  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6627  }
6628 }
6629 
6631  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
6632 {
6633  // not real nodes ...
6634  Nodes.IntPoint(0).x = 0.33333333333333333333;
6635  Nodes.IntPoint(0).y = 0.33333333333333333333;
6636  Nodes.IntPoint(0).z = 0.33333333333333333333;
6637 
6638  Nodes.IntPoint(1).x = 0.0;
6639  Nodes.IntPoint(1).y = 0.33333333333333333333;
6640  Nodes.IntPoint(1).z = 0.33333333333333333333;
6641 
6642  Nodes.IntPoint(2).x = 0.33333333333333333333;
6643  Nodes.IntPoint(2).y = 0.0;
6644  Nodes.IntPoint(2).z = 0.33333333333333333333;
6645 
6646  Nodes.IntPoint(3).x = 0.33333333333333333333;
6647  Nodes.IntPoint(3).y = 0.33333333333333333333;
6648  Nodes.IntPoint(3).z = 0.0;
6649 }
6650 
6652  DenseMatrix &shape) const
6653 {
6654  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
6655 
6656  shape(0,0) = x2;
6657  shape(0,1) = y2;
6658  shape(0,2) = z2;
6659 
6660  shape(1,0) = x2 - 2.0;
6661  shape(1,1) = y2;
6662  shape(1,2) = z2;
6663 
6664  shape(2,0) = x2;
6665  shape(2,1) = y2 - 2.0;
6666  shape(2,2) = z2;
6667 
6668  shape(3,0) = x2;
6669  shape(3,1) = y2;
6670  shape(3,2) = z2 - 2.0;
6671 }
6672 
6674  Vector &divshape) const
6675 {
6676  divshape(0) = 6.0;
6677  divshape(1) = 6.0;
6678  divshape(2) = 6.0;
6679  divshape(3) = 6.0;
6680 }
6681 
6682 const double RT0TetFiniteElement::nk[4][3] =
6683 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
6684 
6687 {
6688  int k, j;
6689 #ifdef MFEM_THREAD_SAFE
6691  DenseMatrix Jinv(Dim);
6692 #endif
6693 
6694 #ifdef MFEM_DEBUG
6695  for (k = 0; k < 4; k++)
6696  {
6698  for (j = 0; j < 4; j++)
6699  {
6700  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6701  vshape(j,2)*nk[k][2] );
6702  if (j == k) { d -= 1.0; }
6703  if (fabs(d) > 1.0e-12)
6704  {
6705  mfem::err << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
6706  " k = " << k << ", j = " << j << ", d = " << d << endl;
6707  mfem_error();
6708  }
6709  }
6710  }
6711 #endif
6712 
6713  IntegrationPoint ip;
6714  ip.x = ip.y = ip.z = 0.0;
6715  Trans.SetIntPoint (&ip);
6716  // Trans must be linear
6717  // set Jinv = |J| J^{-t} = adj(J)^t
6718  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6719  double vk[3];
6720  Vector xk (vk, 3);
6721 
6722  for (k = 0; k < 4; k++)
6723  {
6724  Trans.Transform (Nodes.IntPoint (k), xk);
6725  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6726  CalcVShape (ip, vshape);
6727  // vk = |J| J^{-t} nk
6728  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6729  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6730  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6731  for (j = 0; j < 4; j++)
6732  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6733  vshape(j,2)*vk[2])) < 1.0e-12)
6734  {
6735  I(k,j) = 0.0;
6736  }
6737  }
6738 }
6739 
6742  Vector &dofs) const
6743 {
6744  double vk[3];
6745  Vector xk (vk, 3);
6746 #ifdef MFEM_THREAD_SAFE
6747  DenseMatrix Jinv(Dim);
6748 #endif
6749 
6750  for (int k = 0; k < 4; k++)
6751  {
6752  Trans.SetIntPoint (&Nodes.IntPoint (k));
6753  // set Jinv = |J| J^{-t} = adj(J)^t
6754  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6755 
6756  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6757  // xk^t |J| J^{-t} nk
6758  dofs(k) =
6759  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6760  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6761  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6762  }
6763 }
6764 
6766  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
6767 {
6768  Nodes.IntPoint(0).x = 0.5;
6769  Nodes.IntPoint(0).y = 0.5;
6770  Nodes.IntPoint(0).z = 0.0;
6771 
6772  Nodes.IntPoint(1).x = 0.5;
6773  Nodes.IntPoint(1).y = 0.0;
6774  Nodes.IntPoint(1).z = 0.5;
6775 
6776  Nodes.IntPoint(2).x = 1.0;
6777  Nodes.IntPoint(2).y = 0.5;
6778  Nodes.IntPoint(2).z = 0.5;
6779 
6780  Nodes.IntPoint(3).x = 0.5;
6781  Nodes.IntPoint(3).y = 1.0;
6782  Nodes.IntPoint(3).z = 0.5;
6783 
6784  Nodes.IntPoint(4).x = 0.0;
6785  Nodes.IntPoint(4).y = 0.5;
6786  Nodes.IntPoint(4).z = 0.5;
6787 
6788  Nodes.IntPoint(5).x = 0.5;
6789  Nodes.IntPoint(5).y = 0.5;
6790  Nodes.IntPoint(5).z = 1.0;
6791 }
6792 
6794  Vector &shape) const
6795 {
6796  double x = 2. * ip.x - 1.;
6797  double y = 2. * ip.y - 1.;
6798  double z = 2. * ip.z - 1.;
6799  double f5 = x * x - y * y;
6800  double f6 = y * y - z * z;
6801 
6802  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
6803  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
6804  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
6805  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
6806  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
6807  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
6808 }
6809 
6811  DenseMatrix &dshape) const
6812 {
6813  const double a = 2./3.;
6814 
6815  double xt = a * (1. - 2. * ip.x);
6816  double yt = a * (1. - 2. * ip.y);
6817  double zt = a * (1. - 2. * ip.z);
6818 
6819  dshape(0,0) = xt;
6820  dshape(0,1) = yt;
6821  dshape(0,2) = -1. - 2. * zt;
6822 
6823  dshape(1,0) = xt;
6824  dshape(1,1) = -1. - 2. * yt;
6825  dshape(1,2) = zt;
6826 
6827  dshape(2,0) = 1. - 2. * xt;
6828  dshape(2,1) = yt;
6829  dshape(2,2) = zt;
6830 
6831  dshape(3,0) = xt;
6832  dshape(3,1) = 1. - 2. * yt;
6833  dshape(3,2) = zt;
6834 
6835  dshape(4,0) = -1. - 2. * xt;
6836  dshape(4,1) = yt;
6837  dshape(4,2) = zt;
6838 
6839  dshape(5,0) = xt;
6840  dshape(5,1) = yt;
6841  dshape(5,2) = 1. - 2. * zt;
6842 }
6843 
6844 
6845 Poly_1D::Basis::Basis(const int p, const double *nodes, EvalType etype)
6846  : etype(etype)
6847 {
6848  switch (etype)
6849  {
6850  case ChangeOfBasis:
6851  {
6852  x.SetSize(p + 1);
6853  w.SetSize(p + 1);
6854  DenseMatrix A(p + 1);
6855  for (int i = 0; i <= p; i++)
6856  {
6857  CalcBasis(p, nodes[i], A.GetColumn(i));
6858  }
6859  Ai.Factor(A);
6860  // mfem::out << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
6861  break;
6862  }
6863  case Barycentric:
6864  {
6865  x.SetSize(p + 1);
6866  w.SetSize(p + 1);
6867  x = nodes;
6868  w = 1.0;
6869  for (int i = 0; i <= p; i++)
6870  {
6871  for (int j = 0; j < i; j++)
6872  {
6873  double xij = x(i) - x(j);
6874  w(i) *= xij;
6875  w(j) *= -xij;
6876  }
6877  }
6878  for (int i = 0; i <= p; i++)
6879  {
6880  w(i) = 1.0/w(i);
6881  }
6882 
6883 #ifdef MFEM_DEBUG
6884  // Make sure the nodes are increasing
6885  for (int i = 0; i < p; i++)
6886  {
6887  if (x(i) >= x(i+1))
6888  {
6889  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
6890  }
6891  }
6892 #endif
6893  break;
6894  }
6895  case Positive:
6896  x.SetDataAndSize(NULL, p + 1); // use x to store (p + 1)
6897  break;
6898 
6899  default: break;
6900  }
6901 }
6902 
6903 void Poly_1D::Basis::Eval(const double y, Vector &u) const
6904 {
6905  switch (etype)
6906  {
6907  case ChangeOfBasis:
6908  {
6909  CalcBasis(Ai.Width() - 1, y, x);
6910  Ai.Mult(x, u);
6911  break;
6912  }
6913  case Barycentric:
6914  {
6915  int i, k, p = x.Size() - 1;
6916  double l, lk;
6917 
6918  if (p == 0)
6919  {
6920  u(0) = 1.0;
6921  return;
6922  }
6923 
6924  lk = 1.0;
6925  for (k = 0; k < p; k++)
6926  {
6927  if (y >= (x(k) + x(k+1))/2)
6928  {
6929  lk *= y - x(k);
6930  }
6931  else
6932  {
6933  for (i = k+1; i <= p; i++)
6934  {
6935  lk *= y - x(i);
6936  }
6937  break;
6938  }
6939  }
6940  l = lk * (y - x(k));
6941 
6942  for (i = 0; i < k; i++)
6943  {
6944  u(i) = l * w(i) / (y - x(i));
6945  }
6946  u(k) = lk * w(k);
6947  for (i++; i <= p; i++)
6948  {
6949  u(i) = l * w(i) / (y - x(i));
6950  }
6951  break;
6952  }
6953  case Positive:
6954  CalcBernstein(x.Size() - 1, y, u);
6955  break;
6956 
6957  default: break;
6958  }
6959 }
6960 
6961 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
6962 {
6963  switch (etype)
6964  {
6965  case ChangeOfBasis:
6966  {
6967  CalcBasis(Ai.Width() - 1, y, x, w);
6968  Ai.Mult(x, u);
6969  Ai.Mult(w, d);
6970  break;
6971  }
6972  case Barycentric:
6973  {
6974  int i, k, p = x.Size() - 1;
6975  double l, lp, lk, sk, si;
6976 
6977  if (p == 0)
6978  {
6979  u(0) = 1.0;
6980  d(0) = 0.0;
6981  return;
6982  }
6983 
6984  lk = 1.0;
6985  for (k = 0; k < p; k++)
6986  {
6987  if (y >= (x(k) + x(k+1))/2)
6988  {
6989  lk *= y - x(k);
6990  }
6991  else
6992  {
6993  for (i = k+1; i <= p; i++)
6994  {
6995  lk *= y - x(i);
6996  }
6997  break;
6998  }
6999  }
7000  l = lk * (y - x(k));
7001 
7002  sk = 0.0;
7003  for (i = 0; i < k; i++)
7004  {
7005  si = 1.0/(y - x(i));
7006  sk += si;
7007  u(i) = l * si * w(i);
7008  }
7009  u(k) = lk * w(k);
7010  for (i++; i <= p; i++)
7011  {
7012  si = 1.0/(y - x(i));
7013  sk += si;
7014  u(i) = l * si * w(i);
7015  }
7016  lp = l * sk + lk;
7017 
7018  for (i = 0; i < k; i++)
7019  {
7020  d(i) = (lp * w(i) - u(i))/(y - x(i));
7021  }
7022  d(k) = sk * u(k);
7023  for (i++; i <= p; i++)
7024  {
7025  d(i) = (lp * w(i) - u(i))/(y - x(i));
7026  }
7027  break;
7028  }
7029  case Positive:
7030  CalcBernstein(x.Size() - 1, y, u, d);
7031  break;
7032 
7033  default: break;
7034  }
7035 }
7036 
7037 const int *Poly_1D::Binom(const int p)
7038 {
7039  if (binom.NumCols() <= p)
7040  {
7041  binom.SetSize(p + 1, p + 1);
7042  for (int i = 0; i <= p; i++)
7043  {
7044  binom(i,0) = binom(i,i) = 1;
7045  for (int j = 1; j < i; j++)
7046  {
7047  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
7048  }
7049  }
7050  }
7051  return binom[p];
7052 }
7053 
7054 void Poly_1D::ChebyshevPoints(const int p, double *x)
7055 {
7056  for (int i = 0; i <= p; i++)
7057  {
7058  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
7059  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
7060  x[i] = s*s;
7061  }
7062 }
7063 
7064 void Poly_1D::CalcMono(const int p, const double x, double *u)
7065 {
7066  double xn;
7067  u[0] = xn = 1.;
7068  for (int n = 1; n <= p; n++)
7069  {
7070  u[n] = (xn *= x);
7071  }
7072 }
7073 
7074 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
7075 {
7076  double xn;
7077  u[0] = xn = 1.;
7078  d[0] = 0.;
7079  for (int n = 1; n <= p; n++)
7080  {
7081  d[n] = n * xn;
7082  u[n] = (xn *= x);
7083  }
7084 }
7085 
7086 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
7087  double *u)
7088 {
7089  if (p == 0)
7090  {
7091  u[0] = 1.;
7092  }
7093  else
7094  {
7095  int i;
7096  const int *b = Binom(p);
7097  double z = x;
7098 
7099  for (i = 1; i < p; i++)
7100  {
7101  u[i] = b[i]*z;
7102  z *= x;
7103  }
7104  u[p] = z;
7105  z = y;
7106  for (i--; i > 0; i--)
7107  {
7108  u[i] *= z;
7109  z *= y;
7110  }
7111  u[0] = z;
7112  }
7113 }
7114 
7115 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
7116  double *u, double *d)
7117 {
7118  if (p == 0)
7119  {
7120  u[0] = 1.;
7121  d[0] = 0.;
7122  }
7123  else
7124  {
7125  int i;
7126  const int *b = Binom(p);
7127  const double xpy = x + y, ptx = p*x;
7128  double z = 1.;
7129 
7130  for (i = 1; i < p; i++)
7131  {
7132  d[i] = b[i]*z*(i*xpy - ptx);
7133  z *= x;
7134  u[i] = b[i]*z;
7135  }
7136  d[p] = p*z;
7137  u[p] = z*x;
7138  z = 1.;
7139  for (i--; i > 0; i--)
7140  {
7141  d[i] *= z;
7142  z *= y;
7143  u[i] *= z;
7144  }
7145  d[0] = -p*z;
7146  u[0] = z*y;
7147  }
7148 }
7149 
7150 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
7151  double *d)
7152 {
7153  if (p == 0)
7154  {
7155  d[0] = 0.;
7156  }
7157  else
7158  {
7159  int i;
7160  const int *b = Binom(p);
7161  const double xpy = x + y, ptx = p*x;
7162  double z = 1.;
7163 
7164  for (i = 1; i < p; i++)
7165  {
7166  d[i] = b[i]*z*(i*xpy - ptx);
7167  z *= x;
7168  }
7169  d[p] = p*z;
7170  z = 1.;
7171  for (i--; i > 0; i--)
7172  {
7173  d[i] *= z;
7174  z *= y;
7175  }
7176  d[0] = -p*z;
7177  }
7178 }
7179 
7180 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
7181 {
7182  // use the recursive definition for [-1,1]:
7183  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
7184  double z;
7185  u[0] = 1.;
7186  if (p == 0) { return; }
7187  u[1] = z = 2.*x - 1.;
7188  for (int n = 1; n < p; n++)
7189  {
7190  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
7191  }
7192 }
7193 
7194 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
7195 {
7196  // use the recursive definition for [-1,1]:
7197  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
7198  // for the derivative use, z in [-1,1]:
7199  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
7200  double z;
7201  u[0] = 1.;
7202  d[0] = 0.;
7203  if (p == 0) { return; }
7204  u[1] = z = 2.*x - 1.;
7205  d[1] = 2.;
7206  for (int n = 1; n < p; n++)
7207  {
7208  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
7209  d[n+1] = (4*n + 2)*u[n] + d[n-1];
7210  }
7211 }
7212 
7213 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
7214 {
7215  // recursive definition, z in [-1,1]
7216  // T_0(z) = 1, T_1(z) = z
7217  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7218  double z;
7219  u[0] = 1.;
7220  if (p == 0) { return; }
7221  u[1] = z = 2.*x - 1.;
7222  for (int n = 1; n < p; n++)
7223  {
7224  u[n+1] = 2*z*u[n] - u[n-1];
7225  }
7226 }
7227 
7228 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
7229 {
7230  // recursive definition, z in [-1,1]
7231  // T_0(z) = 1, T_1(z) = z
7232  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7233  // T'_n(z) = n*U_{n-1}(z)
7234  // U_0(z) = 1 U_1(z) = 2*z
7235  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
7236  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
7237  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
7238  double z;
7239  u[0] = 1.;
7240  d[0] = 0.;
7241  if (p == 0) { return; }
7242  u[1] = z = 2.*x - 1.;
7243  d[1] = 2.;
7244  for (int n = 1; n < p; n++)
7245  {
7246  u[n+1] = 2*z*u[n] - u[n-1];
7247  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
7248  }
7249 }
7250 
7251 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d,
7252  double *dd)
7253 {
7254  // recursive definition, z in [-1,1]
7255  // T_0(z) = 1, T_1(z) = z
7256  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7257  // T'_n(z) = n*U_{n-1}(z)
7258  // U_0(z) = 1 U_1(z) = 2*z
7259  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
7260  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
7261  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
7262  // T''_{n+1}(z) = (n + 1)*(2*(n + 1)*T'_n(z) + z*T''_n(z)) / n
7263  double z;
7264  u[0] = 1.;
7265  d[0] = 0.;
7266  dd[0]= 0.;
7267  if (p == 0) { return; }
7268  u[1] = z = 2.*x - 1.;
7269  d[1] = 2.;
7270  dd[1] = 0;
7271  for (int n = 1; n < p; n++)
7272  {
7273  u[n+1] = 2*z*u[n] - u[n-1];
7274  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
7275  dd[n+1] = (n + 1)*(2.*(n + 1)*d[n] + z*dd[n])/n;
7276  }
7277 }
7278 
7279 const double *Poly_1D::GetPoints(const int p, const int btype)
7280 {
7281  BasisType::Check(btype);
7282  const int qtype = BasisType::GetQuadrature1D(btype);
7283 
7284  if (qtype == Quadrature1D::Invalid) { return NULL; }
7285 
7286  if (points_container.find(btype) == points_container.end())
7287  {
7288  points_container[btype] = new Array<double*>(h_mt);
7289  }
7290  Array<double*> &pts = *points_container[btype];
7291  if (pts.Size() <= p)
7292  {
7293  pts.SetSize(p + 1, NULL);
7294  }
7295  if (pts[p] == NULL)
7296  {
7297  pts[p] = new double[p + 1];
7298  quad_func.GivePolyPoints(p+1, pts[p], qtype);
7299  }
7300  return pts[p];
7301 }
7302 
7303 Poly_1D::Basis &Poly_1D::GetBasis(const int p, const int btype)
7304 {
7305  BasisType::Check(btype);
7306 
7307  if ( bases_container.find(btype) == bases_container.end() )
7308  {
7309  // we haven't been asked for basis or points of this type yet
7310  bases_container[btype] = new Array<Basis*>(h_mt);
7311  }
7312  Array<Basis*> &bases = *bases_container[btype];
7313  if (bases.Size() <= p)
7314  {
7315  bases.SetSize(p + 1, NULL);
7316  }
7317  if (bases[p] == NULL)
7318  {
7319  EvalType etype = (btype == BasisType::Positive) ? Positive : Barycentric;
7320  bases[p] = new Basis(p, GetPoints(p, btype), etype);
7321  }
7322  return *bases[p];
7323 }
7324 
7326 {
7327  for (PointsMap::iterator it = points_container.begin();
7328  it != points_container.end() ; ++it)
7329  {
7330  Array<double*>& pts = *it->second;
7331  for ( int i = 0 ; i < pts.Size() ; ++i )
7332  {
7333  delete [] pts[i];
7334  }
7335  delete it->second;
7336  }
7337 
7338  for (BasisMap::iterator it = bases_container.begin();
7339  it != bases_container.end() ; ++it)
7340  {
7341  Array<Basis*>& bases = *it->second;
7342  for ( int i = 0 ; i < bases.Size() ; ++i )
7343  {
7344  delete bases[i];
7345  }
7346  delete it->second;
7347  }
7348 }
7349 
7350 Array2D<int> Poly_1D::binom;
7352 
7353 
7354 TensorBasisElement::TensorBasisElement(const int dims, const int p,
7355  const int btype, const DofMapType dmtype)
7356  : b_type(btype),
7357  basis1d(poly1d.GetBasis(p, b_type))
7358 {
7359  if (dmtype == H1_DOF_MAP || dmtype == Sr_DOF_MAP)
7360  {
7361  switch (dims)
7362  {
7363  case 1:
7364  {
7365  dof_map.SetSize(p + 1);
7366  dof_map[0] = 0;
7367  dof_map[p] = 1;
7368  for (int i = 1; i < p; i++)
7369  {
7370  dof_map[i] = i+1;
7371  }
7372  break;
7373  }
7374  case 2:
7375  {
7376  const int p1 = p + 1;
7377  dof_map.SetSize(p1*p1);
7378 
7379  // vertices
7380  dof_map[0 + 0*p1] = 0;
7381  dof_map[p + 0*p1] = 1;
7382  dof_map[p + p*p1] = 2;
7383  dof_map[0 + p*p1] = 3;
7384 
7385  // edges
7386  int o = 4;
7387  for (int i = 1; i < p; i++)
7388  {
7389  dof_map[i + 0*p1] = o++;
7390  }
7391  for (int i = 1; i < p; i++)
7392  {
7393  dof_map[p + i*p1] = o++;
7394  }
7395  for (int i = 1; i < p; i++)
7396  {
7397  dof_map[(p-i) + p*p1] = o++;
7398  }
7399  for (int i = 1; i < p; i++)
7400  {
7401  dof_map[0 + (p-i)*p1] = o++;
7402  }
7403 
7404  // interior
7405  for (int j = 1; j < p; j++)
7406  {
7407  for (int i = 1; i < p; i++)
7408  {
7409  dof_map[i + j*p1] = o++;
7410  }
7411  }
7412  break;
7413  }
7414  case 3:
7415  {
7416  const int p1 = p + 1;
7417  dof_map.SetSize(p1*p1*p1);
7418 
7419  // vertices
7420  dof_map[0 + (0 + 0*p1)*p1] = 0;
7421  dof_map[p + (0 + 0*p1)*p1] = 1;
7422  dof_map[p + (p + 0*p1)*p1] = 2;
7423  dof_map[0 + (p + 0*p1)*p1] = 3;
7424  dof_map[0 + (0 + p*p1)*p1] = 4;
7425  dof_map[p + (0 + p*p1)*p1] = 5;
7426  dof_map[p + (p + p*p1)*p1] = 6;
7427  dof_map[0 + (p + p*p1)*p1] = 7;
7428 
7429  // edges (see Hexahedron::edges in mesh/hexahedron.cpp).
7430  // edges (see Constants<Geometry::CUBE>::Edges in fem/geom.cpp).
7431  int o = 8;
7432  for (int i = 1; i < p; i++)
7433  {
7434  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
7435  }
7436  for (int i = 1; i < p; i++)
7437  {
7438  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
7439  }
7440  for (int i = 1; i < p; i++)
7441  {
7442  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
7443  }
7444  for (int i = 1; i < p; i++)
7445  {
7446  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
7447  }
7448  for (int i = 1; i < p; i++)
7449  {
7450  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
7451  }
7452  for (int i = 1; i < p; i++)
7453  {
7454  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
7455  }
7456  for (int i = 1; i < p; i++)
7457  {
7458  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
7459  }
7460  for (int i = 1; i < p; i++)
7461  {
7462  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
7463  }
7464  for (int i = 1; i < p; i++)
7465  {
7466  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
7467  }
7468  for (int i = 1; i < p; i++)
7469  {
7470  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
7471  }
7472  for (int i = 1; i < p; i++)
7473  {
7474  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
7475  }
7476  for (int i = 1; i < p; i++)
7477  {
7478  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
7479  }
7480 
7481  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7482  for (int j = 1; j < p; j++)
7483  {
7484  for (int i = 1; i < p; i++)
7485  {
7486  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
7487  }
7488  }
7489  for (int j = 1; j < p; j++)
7490  {
7491  for (int i = 1; i < p; i++)
7492  {
7493  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
7494  }
7495  }
7496  for (int j = 1; j < p; j++)
7497  {
7498  for (int i = 1; i < p; i++)
7499  {
7500  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
7501  }
7502  }
7503  for (int j = 1; j < p; j++)
7504  {
7505  for (int i = 1; i < p; i++)
7506  {
7507  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
7508  }
7509  }
7510  for (int j = 1; j < p; j++)
7511  {
7512  for (int i = 1; i < p; i++)
7513  {
7514  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
7515  }
7516  }
7517  for (int j = 1; j < p; j++)
7518  {
7519  for (int i = 1; i < p; i++)
7520  {
7521  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
7522  }
7523  }
7524 
7525  // interior
7526  for (int k = 1; k < p; k++)
7527  {
7528  for (int j = 1; j < p; j++)
7529  {
7530  for (int i = 1; i < p; i++)
7531  {
7532  dof_map[i + (j + k*p1)*p1] = o++;
7533  }
7534  }
7535  }
7536  break;
7537  }
7538  default:
7539  MFEM_ABORT("invalid dimension: " << dims);
7540  break;
7541  }
7542  }
7543  else if (dmtype == L2_DOF_MAP)
7544  {
7545  // leave dof_map empty, indicating that the dofs are ordered
7546  // lexicographically, i.e. the dof_map is identity
7547  }
7548  else
7549  {
7550  MFEM_ABORT("invalid DofMapType: " << dmtype);
7551  }
7552 }
7553 
7554 
7556  const int p,
7557  const int btype,
7558  const DofMapType dmtype)
7559  : NodalFiniteElement(dims, GetTensorProductGeometry(dims), Pow(p + 1, dims),
7560  p, dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
7561  TensorBasisElement(dims, p, VerifyNodal(btype), dmtype) { }
7562 
7563 
7565  const int dims, const int p, const DofMapType dmtype)
7566  : PositiveFiniteElement(dims, GetTensorProductGeometry(dims),
7567  Pow(p + 1, dims), p,
7568  dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
7569  TensorBasisElement(dims, p, BasisType::Positive, dmtype) { }
7570 
7572  const int d,
7573  const int p,
7574  const int cbtype,
7575  const int obtype,
7576  const int M,
7577  const DofMapType dmtype)
7578  : VectorFiniteElement(dims, GetTensorProductGeometry(dims), d,
7579  p, M, FunctionSpace::Qk),
7580  TensorBasisElement(dims, p, VerifyNodal(cbtype), dmtype),
7581  cbasis1d(poly1d.GetBasis(p, VerifyClosed(cbtype))),
7582  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(obtype))) { }
7583 
7584 H1_SegmentElement::H1_SegmentElement(const int p, const int btype)
7585  : NodalTensorFiniteElement(1, p, VerifyClosed(btype), H1_DOF_MAP)
7586 {
7587  const double *cp = poly1d.ClosedPoints(p, b_type);
7588 
7589 #ifndef MFEM_THREAD_SAFE
7590  shape_x.SetSize(p+1);
7591  dshape_x.SetSize(p+1);
7592 #endif
7593 
7594  Nodes.IntPoint(0).x = cp[0];
7595  Nodes.IntPoint(1).x = cp[p];
7596  for (int i = 1; i < p; i++)
7597  {
7598  Nodes.IntPoint(i+1).x = cp[i];
7599  }
7600 }
7601 
7603  Vector &shape) const
7604 {
7605  const int p = Order;
7606 
7607 #ifdef MFEM_THREAD_SAFE
7608  Vector shape_x(p+1);
7609 #endif
7610 
7611  basis1d.Eval(ip.x, shape_x);
7612 
7613  shape(0) = shape_x(0);
7614  shape(1) = shape_x(p);
7615  for (int i = 1; i < p; i++)
7616  {
7617  shape(i+1) = shape_x(i);
7618  }
7619 }
7620 
7622  DenseMatrix &dshape) const
7623 {
7624  const int p = Order;
7625 
7626 #ifdef MFEM_THREAD_SAFE
7627  Vector shape_x(p+1), dshape_x(p+1);
7628 #endif
7629 
7630  basis1d.Eval(ip.x, shape_x, dshape_x);
7631 
7632  dshape(0,0) = dshape_x(0);
7633  dshape(1,0) = dshape_x(p);
7634  for (int i = 1; i < p; i++)
7635  {
7636  dshape(i+1,0) = dshape_x(i);
7637  }
7638 }
7639 
7640 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7641 {
7642  const int p = Order;
7643  const double *cp = poly1d.ClosedPoints(p, b_type);
7644 
7645  switch (vertex)
7646  {
7647  case 0:
7648  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
7649  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
7650  for (int i = 1; i < p; i++)
7651  {
7652  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7653  }
7654  break;
7655 
7656  case 1:
7657  dofs(0) = poly1d.CalcDelta(p, cp[0]);
7658  dofs(1) = poly1d.CalcDelta(p, cp[p]);
7659  for (int i = 1; i < p; i++)
7660  {
7661  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
7662  }
7663  break;
7664  }
7665 }
7666 
7667 
7669  : NodalTensorFiniteElement(2, p, VerifyClosed(btype), H1_DOF_MAP)
7670 {
7671  const double *cp = poly1d.ClosedPoints(p, b_type);
7672 
7673 #ifndef MFEM_THREAD_SAFE
7674  const int p1 = p + 1;
7675 
7676  shape_x.SetSize(p1);
7677  shape_y.SetSize(p1);
7678  dshape_x.SetSize(p1);
7679  dshape_y.SetSize(p1);
7680 #endif
7681 
7682  int o = 0;
7683  for (int j = 0; j <= p; j++)
7684  {
7685  for (int i = 0; i <= p; i++)
7686  {
7687  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
7688  }
7689  }
7690 }
7691 
7693  Vector &shape) const
7694 {
7695  const int p = Order;
7696 
7697 #ifdef MFEM_THREAD_SAFE
7698  Vector shape_x(p+1), shape_y(p+1);
7699 #endif
7700 
7701  basis1d.Eval(ip.x, shape_x);
7702  basis1d.Eval(ip.y, shape_y);
7703 
7704  for (int o = 0, j = 0; j <= p; j++)
7705  for (int i = 0; i <= p; i++)
7706  {
7707  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7708  }
7709 }
7710 
7712  DenseMatrix &dshape) const
7713 {
7714  const int p = Order;
7715 
7716 #ifdef MFEM_THREAD_SAFE
7717  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7718 #endif
7719 
7720  basis1d.Eval(ip.x, shape_x, dshape_x);
7721  basis1d.Eval(ip.y, shape_y, dshape_y);
7722 
7723  for (int o = 0, j = 0; j <= p; j++)
7724  {
7725  for (int i = 0; i <= p; i++)
7726  {
7727  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7728  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7729  }
7730  }
7731 }
7732 
7733 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
7734 {
7735  const int p = Order;
7736  const double *cp = poly1d.ClosedPoints(p, b_type);
7737 
7738 #ifdef MFEM_THREAD_SAFE
7739  Vector shape_x(p+1), shape_y(p+1);
7740 #endif
7741 
7742  for (int i = 0; i <= p; i++)
7743  {
7744  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7745  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7746  }
7747 
7748  switch (vertex)
7749  {
7750  case 0:
7751  for (int o = 0, j = 0; j <= p; j++)
7752  for (int i = 0; i <= p; i++)
7753  {
7754  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
7755  }
7756  break;
7757  case 1:
7758  for (int o = 0, j = 0; j <= p; j++)
7759  for (int i = 0; i <= p; i++)
7760  {
7761  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
7762  }
7763  break;
7764  case 2:
7765  for (int o = 0, j = 0; j <= p; j++)
7766  for (int i = 0; i <= p; i++)
7767  {
7768  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
7769  }
7770  break;
7771  case 3:
7772  for (int o = 0, j = 0; j <= p; j++)
7773  for (int i = 0; i <= p; i++)
7774  {
7775  dofs(dof_map[o++]) = shape_x(i)*shape_y(j);
7776  }
7777  break;
7778  }
7779 }
7780 
7781 
7782 H1_HexahedronElement::H1_HexahedronElement(const int p, const int btype)
7783  : NodalTensorFiniteElement(3, p, VerifyClosed(btype), H1_DOF_MAP)
7784 {
7785  const double *cp = poly1d.ClosedPoints(p, b_type);
7786 
7787 #ifndef MFEM_THREAD_SAFE
7788  const int p1 = p + 1;
7789 
7790  shape_x.SetSize(p1);
7791  shape_y.SetSize(p1);
7792  shape_z.SetSize(p1);
7793  dshape_x.SetSize(p1);
7794  dshape_y.SetSize(p1);
7795  dshape_z.SetSize(p1);
7796 #endif
7797 
7798  int o = 0;
7799  for (int k = 0; k <= p; k++)
7800  for (int j = 0; j <= p; j++)
7801  for (int i = 0; i <= p; i++)
7802  {
7803  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
7804  }
7805 }
7806 
7808  Vector &shape) const
7809 {
7810  const int p = Order;
7811 
7812 #ifdef MFEM_THREAD_SAFE
7813  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7814 #endif
7815 
7816  basis1d.Eval(ip.x, shape_x);
7817  basis1d.Eval(ip.y, shape_y);
7818  basis1d.Eval(ip.z, shape_z);
7819 
7820  for (int o = 0, k = 0; k <= p; k++)
7821  for (int j = 0; j <= p; j++)
7822  for (int i = 0; i <= p; i++)
7823  {
7824  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7825  }
7826 }
7827 
7829  DenseMatrix &dshape) const
7830 {
7831  const int p = Order;
7832 
7833 #ifdef MFEM_THREAD_SAFE
7834  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7835  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7836 #endif
7837 
7838  basis1d.Eval(ip.x, shape_x, dshape_x);
7839  basis1d.Eval(ip.y, shape_y, dshape_y);
7840  basis1d.Eval(ip.z, shape_z, dshape_z);
7841 
7842  for (int o = 0, k = 0; k <= p; k++)
7843  for (int j = 0; j <= p; j++)
7844  for (int i = 0; i <= p; i++)
7845  {
7846  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7847  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7848  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7849  }
7850 }
7851 
7852 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7853 {
7854  const int p = Order;
7855  const double *cp = poly1d.ClosedPoints(p,b_type);
7856 
7857 #ifdef MFEM_THREAD_SAFE
7858  Vector shape_x(p+1), shape_y(p+1);
7859 #endif
7860 
7861  for (int i = 0; i <= p; i++)
7862  {
7863  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7864  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7865  }
7866 
7867  switch (vertex)
7868  {
7869  case 0:
7870  for (int o = 0, k = 0; k <= p; k++)
7871  for (int j = 0; j <= p; j++)
7872  for (int i = 0; i <= p; i++)
7873  {
7874  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
7875  }
7876  break;
7877  case 1:
7878  for (int o = 0, k = 0; k <= p; k++)
7879  for (int j = 0; j <= p; j++)
7880  for (int i = 0; i <= p; i++)
7881  {
7882  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
7883  }
7884  break;
7885  case 2:
7886  for (int o = 0, k = 0; k <= p; k++)
7887  for (int j = 0; j <= p; j++)
7888  for (int i = 0; i <= p; i++)
7889  {
7890  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
7891  }
7892  break;
7893  case 3:
7894  for (int o = 0, k = 0; k <= p; k++)
7895  for (int j = 0; j <= p; j++)
7896  for (int i = 0; i <= p; i++)
7897  {
7898  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
7899  }
7900  break;
7901  case 4:
7902  for (int o = 0, k = 0; k <= p; k++)
7903  for (int j = 0; j <= p; j++)
7904  for (int i = 0; i <= p; i++)
7905  {
7906  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
7907  }
7908  break;
7909  case 5:
7910  for (int o = 0, k = 0; k <= p; k++)
7911  for (int j = 0; j <= p; j++)
7912  for (int i = 0; i <= p; i++)
7913  {
7914  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
7915  }
7916  break;
7917  case 6:
7918  for (int o = 0, k = 0; k <= p; k++)
7919  for (int j = 0; j <= p; j++)
7920  for (int i = 0; i <= p; i++)
7921  {
7922  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
7923  }
7924  break;
7925  case 7:
7926  for (int o = 0, k = 0; k <= p; k++)
7927  for (int j = 0; j <= p; j++)
7928  for (int i = 0; i <= p; i++)
7929  {
7930  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
7931  }
7932  break;
7933  }
7934 }
7935 
7936 
7938  : PositiveTensorFiniteElement(1, p, H1_DOF_MAP)
7939 {
7940 #ifndef MFEM_THREAD_SAFE
7941  // thread private versions; see class header.
7942  shape_x.SetSize(p+1);
7943  dshape_x.SetSize(p+1);
7944 #endif
7945 
7946  // Endpoints need to be first in the list, so reorder them.
7947  Nodes.IntPoint(0).x = 0.0;
7948  Nodes.IntPoint(1).x = 1.0;
7949  for (int i = 1; i < p; i++)
7950  {
7951  Nodes.IntPoint(i+1).x = double(i)/p;
7952  }
7953 }
7954 
7956  Vector &shape) const
7957 {
7958  const int p = Order;
7959 
7960 #ifdef MFEM_THREAD_SAFE
7961  Vector shape_x(p+1);
7962 #endif
7963 
7964  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7965 
7966  // Endpoints need to be first in the list, so reorder them.
7967  shape(0) = shape_x(0);
7968  shape(1) = shape_x(p);
7969  for (int i = 1; i < p; i++)
7970  {
7971  shape(i+1) = shape_x(i);
7972  }
7973 }
7974 
7976  DenseMatrix &dshape) const
7977 {
7978  const int p = Order;
7979 
7980 #ifdef MFEM_THREAD_SAFE
7981  Vector shape_x(p+1), dshape_x(p+1);
7982 #endif
7983 
7984  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7985 
7986  // Endpoints need to be first in the list, so reorder them.
7987  dshape(0,0) = dshape_x(0);
7988  dshape(1,0) = dshape_x(p);
7989  for (int i = 1; i < p; i++)
7990  {
7991  dshape(i+1,0) = dshape_x(i);
7992  }
7993 }
7994 
7995 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7996 {
7997  dofs = 0.0;
7998  dofs[vertex] = 1.0;
7999 }
8000 
8001 
8003  : PositiveTensorFiniteElement(2, p, H1_DOF_MAP)
8004 {
8005 #ifndef MFEM_THREAD_SAFE
8006  const int p1 = p + 1;
8007 
8008  shape_x.SetSize(p1);
8009  shape_y.SetSize(p1);
8010  dshape_x.SetSize(p1);
8011  dshape_y.SetSize(p1);
8012 #endif
8013 
8014  int o = 0;
8015  for (int j = 0; j <= p; j++)
8016  for (int i = 0; i <= p; i++)
8017  {
8018  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
8019  }
8020 }
8021 
8023  Vector &shape) const
8024 {
8025  const int p = Order;
8026 
8027 #ifdef MFEM_THREAD_SAFE
8028  Vector shape_x(p+1), shape_y(p+1);
8029 #endif
8030 
8031  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
8032  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
8033 
8034  // Reorder so that vertices are at the beginning of the list
8035  for (int o = 0, j = 0; j <= p; j++)
8036  for (int i = 0; i <= p; i++)
8037  {
8038  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
8039  }
8040 }
8041 
8043  DenseMatrix &dshape) const
8044 {
8045  const int p = Order;
8046 
8047 #ifdef MFEM_THREAD_SAFE
8048  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8049 #endif
8050 
8051  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
8052  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
8053 
8054  // Reorder so that vertices are at the beginning of the list
8055  for (int o = 0, j = 0; j <= p; j++)
8056  for (int i = 0; i <= p; i++)
8057  {
8058  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
8059  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
8060  }
8061 }
8062 
8064 {
8065  dofs = 0.0;
8066  dofs[vertex] = 1.0;
8067 }
8068 
8069 
8071  : PositiveTensorFiniteElement(3, p, H1_DOF_MAP)
8072 {
8073 #ifndef MFEM_THREAD_SAFE
8074  const int p1 = p + 1;
8075 
8076  shape_x.SetSize(p1);
8077  shape_y.SetSize(p1);
8078  shape_z.SetSize(p1);
8079  dshape_x.SetSize(p1);
8080  dshape_y.SetSize(p1);
8081  dshape_z.SetSize(p1);
8082 #endif
8083 
8084  int o = 0;
8085  for (int k = 0; k <= p; k++)
8086  for (int j = 0; j <= p; j++)
8087  for (int i = 0; i <= p; i++)
8088  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
8089  double(k)/p);
8090 }
8091 
8093  Vector &shape) const
8094 {
8095  const int p = Order;
8096 
8097 #ifdef MFEM_THREAD_SAFE
8098  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8099 #endif
8100 
8101  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
8102  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
8103  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
8104 
8105  for (int o = 0, k = 0; k <= p; k++)
8106  for (int j = 0; j <= p; j++)
8107  for (int i = 0; i <= p; i++)
8108  {
8109  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
8110  }
8111 }
8112 
8114  DenseMatrix &dshape) const
8115 {
8116  const int p = Order;
8117 
8118 #ifdef MFEM_THREAD_SAFE
8119  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8120  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8121 #endif
8122 
8123  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
8124  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
8125  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
8126 
8127  for (int o = 0, k = 0; k <= p; k++)
8128  for (int j = 0; j <= p; j++)
8129  for (int i = 0; i <= p; i++)
8130  {
8131  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
8132  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
8133  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8134  }
8135 }
8136 
8137 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8138 {
8139  dofs = 0.0;
8140  dofs[vertex] = 1.0;
8141 }
8142 
8143 
8144 H1_TriangleElement::H1_TriangleElement(const int p, const int btype)
8145  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8146  FunctionSpace::Pk)
8147 {
8148  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
8149 
8150 #ifndef MFEM_THREAD_SAFE
8151  shape_x.SetSize(p + 1);
8152  shape_y.SetSize(p + 1);
8153  shape_l.SetSize(p + 1);
8154  dshape_x.SetSize(p + 1);
8155  dshape_y.SetSize(p + 1);
8156  dshape_l.SetSize(p + 1);
8157  ddshape_x.SetSize(p + 1);
8158  ddshape_y.SetSize(p + 1);
8159  ddshape_l.SetSize(p + 1);
8160  u.SetSize(Dof);
8161  du.SetSize(Dof, Dim);
8162  ddu.SetSize(Dof, (Dim * (Dim + 1)) / 2 );
8163 #else
8164  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8165 #endif
8166 
8167  // vertices
8168  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
8169  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
8170  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
8171 
8172  // edges
8173  int o = 3;
8174  for (int i = 1; i < p; i++)
8175  {
8176  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
8177  }
8178  for (int i = 1; i < p; i++)
8179  {
8180  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
8181  }
8182  for (int i = 1; i < p; i++)
8183  {
8184  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
8185  }
8186 
8187  // interior
8188  for (int j = 1; j < p; j++)
8189  for (int i = 1; i + j < p; i++)
8190  {
8191  const double w = cp[i] + cp[j] + cp[p-i-j];
8192  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
8193  }
8194 
8195  DenseMatrix T(Dof);
8196  for (int k = 0; k < Dof; k++)
8197  {
8198  IntegrationPoint &ip = Nodes.IntPoint(k);
8199  poly1d.CalcBasis(p, ip.x, shape_x);
8200  poly1d.CalcBasis(p, ip.y, shape_y);
8201  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8202 
8203  o = 0;
8204  for (int j = 0; j <= p; j++)
8205  for (int i = 0; i + j <= p; i++)
8206  {
8207  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8208  }
8209  }
8210 
8211  Ti.Factor(T);
8212  // mfem::out << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
8213 }
8214 
8216  Vector &shape) const
8217 {
8218  const int p = Order;
8219 
8220 #ifdef MFEM_THREAD_SAFE
8221  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
8222 #endif
8223 
8224  poly1d.CalcBasis(p, ip.x, shape_x);
8225  poly1d.CalcBasis(p, ip.y, shape_y);
8226  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8227 
8228  for (int o = 0, j = 0; j <= p; j++)
8229  for (int i = 0; i + j <= p; i++)
8230  {
8231  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8232  }
8233 
8234  Ti.Mult(u, shape);
8235 }
8236 
8238  DenseMatrix &dshape) const
8239 {
8240  const int p = Order;
8241 
8242 #ifdef MFEM_THREAD_SAFE
8243  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8244  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8245  DenseMatrix du(Dof, Dim);
8246 #endif
8247 
8248  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8249  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8250  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
8251 
8252  for (int o = 0, j = 0; j <= p; j++)
8253  for (int i = 0; i + j <= p; i++)
8254  {
8255  int k = p - i - j;
8256  du(o,0) = ((dshape_x(i)* shape_l(k)) -
8257  ( shape_x(i)*dshape_l(k)))*shape_y(j);
8258  du(o,1) = ((dshape_y(j)* shape_l(k)) -
8259  ( shape_y(j)*dshape_l(k)))*shape_x(i);
8260  o++;
8261  }
8262 
8263  Ti.Mult(du, dshape);
8264 }
8265 
8267  DenseMatrix &ddshape) const
8268 {
8269  const int p = Order;
8270 #ifdef MFEM_THREAD_SAFE
8271  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8272  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8273  Vector ddshape_x(p + 1), ddshape_y(p + 1), ddshape_l(p + 1);
8274  DenseMatrix ddu(Dof, Dim);
8275 #endif
8276 
8277  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x, ddshape_x);
8278  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y, ddshape_y);
8279  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l, ddshape_l);
8280 
8281  for (int o = 0, j = 0; j <= p; j++)
8282  for (int i = 0; i + j <= p; i++)
8283  {
8284  int k = p - i - j;
8285  // u_xx, u_xy, u_yy
8286  ddu(o,0) = ((ddshape_x(i) * shape_l(k)) - 2. * (dshape_x(i) * dshape_l(k)) +
8287  (shape_x(i) * ddshape_l(k))) * shape_y(j);
8288  ddu(o,1) = (((shape_x(i) * ddshape_l(k)) - dshape_x(i) * dshape_l(k)) * shape_y(
8289  j)) + (((dshape_x(i) * shape_l(k)) - (shape_x(i) * dshape_l(k))) * dshape_y(j));
8290  ddu(o,2) = ((ddshape_y(j) * shape_l(k)) - 2. * (dshape_y(j) * dshape_l(k)) +
8291  (shape_y(j) * ddshape_l(k))) * shape_x(i);
8292  o++;
8293  }
8294 
8295  Ti.Mult(ddu, ddshape);
8296 }
8297 
8298 
8300  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
8301  p, FunctionSpace::Pk)
8302 {
8303  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
8304 
8305 #ifndef MFEM_THREAD_SAFE
8306  shape_x.SetSize(p + 1);
8307  shape_y.SetSize(p + 1);
8308  shape_z.SetSize(p + 1);
8309  shape_l.SetSize(p + 1);
8310  dshape_x.SetSize(p + 1);
8311  dshape_y.SetSize(p + 1);
8312  dshape_z.SetSize(p + 1);
8313  dshape_l.SetSize(p + 1);
8314  ddshape_x.SetSize(p + 1);
8315  ddshape_y.SetSize(p + 1);
8316  ddshape_z.SetSize(p + 1);
8317  ddshape_l.SetSize(p + 1);
8318  u.SetSize(Dof);
8319  du.SetSize(Dof, Dim);
8320  ddu.SetSize(Dof, (Dim * (Dim + 1)) / 2);
8321 #else
8322  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8323 #endif
8324 
8325  // vertices
8326  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
8327  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
8328  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
8329  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
8330 
8331  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
8332  int o = 4;
8333  for (int i = 1; i < p; i++) // (0,1)
8334  {
8335  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
8336  }
8337  for (int i = 1; i < p; i++) // (0,2)
8338  {
8339  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
8340  }
8341  for (int i = 1; i < p; i++) // (0,3)
8342  {
8343  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
8344  }
8345  for (int i = 1; i < p; i++) // (1,2)
8346  {
8347  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
8348  }
8349  for (int i = 1; i < p; i++) // (1,3)
8350  {
8351  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
8352  }
8353  for (int i = 1; i < p; i++) // (2,3)
8354  {
8355  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
8356  }
8357 
8358  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
8359  for (int j = 1; j < p; j++)
8360  for (int i = 1; i + j < p; i++) // (1,2,3)
8361  {
8362  double w = cp[i] + cp[j] + cp[p-i-j];
8363  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
8364  }
8365  for (int j = 1; j < p; j++)
8366  for (int i = 1; i + j < p; i++) // (0,3,2)
8367  {
8368  double w = cp[i] + cp[j] + cp[p-i-j];
8369  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
8370  }
8371  for (int j = 1; j < p; j++)
8372  for (int i = 1; i + j < p; i++) // (0,1,3)
8373  {
8374  double w = cp[i] + cp[j] + cp[p-i-j];
8375  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
8376  }
8377  for (int j = 1; j < p; j++)
8378  for (int i = 1; i + j < p; i++) // (0,2,1)
8379  {
8380  double w = cp[i] + cp[j] + cp[p-i-j];
8381  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
8382  }
8383 
8384  // interior
8385  for (int k = 1; k < p; k++)
8386  for (int j = 1; j + k < p; j++)
8387  for (int i = 1; i + j + k < p; i++)
8388  {
8389  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
8390  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
8391  }
8392 
8393  DenseMatrix T(Dof);
8394  for (int m = 0; m < Dof; m++)
8395  {
8396  IntegrationPoint &ip = Nodes.IntPoint(m);
8397  poly1d.CalcBasis(p, ip.x, shape_x);
8398  poly1d.CalcBasis(p, ip.y, shape_y);
8399  poly1d.CalcBasis(p, ip.z, shape_z);
8400  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8401 
8402  o = 0;
8403  for (int k = 0; k <= p; k++)
8404  for (int j = 0; j + k <= p; j++)
8405  for (int i = 0; i + j + k <= p; i++)
8406  {
8407  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8408  }
8409  }
8410 
8411  Ti.Factor(T);
8412  // mfem::out << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8413 }
8414 
8416  Vector &shape) const
8417 {
8418  const int p = Order;
8419 
8420 #ifdef MFEM_THREAD_SAFE
8421  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8422  Vector u(Dof);
8423 #endif
8424 
8425  poly1d.CalcBasis(p, ip.x, shape_x);
8426  poly1d.CalcBasis(p, ip.y, shape_y);
8427  poly1d.CalcBasis(p, ip.z, shape_z);
8428  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8429 
8430  for (int o = 0, k = 0; k <= p; k++)
8431  for (int j = 0; j + k <= p; j++)
8432  for (int i = 0; i + j + k <= p; i++)
8433  {
8434  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8435  }
8436 
8437  Ti.Mult(u, shape);
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), shape_z(p + 1), shape_l(p + 1);
8447  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8448  DenseMatrix du(Dof, Dim);
8449 #endif
8450 
8451  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8452  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8453  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
8454  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
8455 
8456  for (int o = 0, k = 0; k <= p; k++)
8457  for (int j = 0; j + k <= p; j++)
8458  for (int i = 0; i + j + k <= p; i++)
8459  {
8460  int l = p - i - j - k;
8461  du(o,0) = ((dshape_x(i)* shape_l(l)) -
8462  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
8463  du(o,1) = ((dshape_y(j)* shape_l(l)) -
8464  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
8465  du(o,2) = ((dshape_z(k)* shape_l(l)) -
8466  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
8467  o++;
8468  }
8469 
8470  Ti.Mult(du, dshape);
8471 }
8472 
8474  DenseMatrix &ddshape) const
8475 {
8476  const int p = Order;
8477 
8478 #ifdef MFEM_THREAD_SAFE
8479  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8480  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8481  Vector ddshape_x(p + 1), ddshape_y(p + 1), ddshape_z(p + 1), ddshape_l(p + 1);
8482  DenseMatrix ddu(Dof, ((Dim + 1) * Dim) / 2);
8483 #endif
8484 
8485  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x, ddshape_x);
8486  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y, ddshape_y);
8487  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z, ddshape_z);
8488  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l, ddshape_l);
8489 
8490  for (int o = 0, k = 0; k <= p; k++)
8491  for (int j = 0; j + k <= p; j++)
8492  for (int i = 0; i + j + k <= p; i++)
8493  {
8494  // u_xx, u_xy, u_xz, u_yy, u_yz, u_zz
8495  int l = p - i - j - k;
8496  ddu(o,0) = ((ddshape_x(i) * shape_l(l)) - 2. * (dshape_x(i) * dshape_l(l)) +
8497  (shape_x(i) * ddshape_l(l))) * shape_y(j) * shape_z(k);
8498  ddu(o,1) = ((dshape_y(j) * ((dshape_x(i) * shape_l(l)) -
8499  (shape_x(i) * dshape_l(l)))) +
8500  (shape_y(j) * ((ddshape_l(l) * shape_x(i)) -
8501  (dshape_x(i) * dshape_l(l)))))* shape_z(k);
8502  ddu(o,2) = ((dshape_z(k) * ((dshape_x(i) * shape_l(l)) -
8503  (shape_x(i) * dshape_l(l)))) +
8504  (shape_z(k) * ((ddshape_l(l) * shape_x(i)) -
8505  (dshape_x(i) * dshape_l(l)))))* shape_y(j);
8506  ddu(o,3) = ((ddshape_y(j) * shape_l(l)) - 2. * (dshape_y(j) * dshape_l(l)) +
8507  (shape_y(j) * ddshape_l(l))) * shape_x(i) * shape_z(k);
8508  ddu(o,4) = ((dshape_z(k) * ((dshape_y(j) * shape_l(l)) -
8509  (shape_y(j)*dshape_l(l))) ) +
8510  (shape_z(k)* ((ddshape_l(l)*shape_y(j)) -
8511  (dshape_y(j) * dshape_l(l)) ) ) )* shape_x(i);
8512  ddu(o,5) = ((ddshape_z(k) * shape_l(l)) - 2. * (dshape_z(k) * dshape_l(l)) +
8513  (shape_z(k) * ddshape_l(l))) * shape_y(j) * shape_x(i);
8514  o++;
8515  }
8516  Ti.Mult(ddu, ddshape);
8517 }
8518 
8520  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8521  FunctionSpace::Pk)
8522 {
8523 #ifndef MFEM_THREAD_SAFE
8524  m_shape.SetSize(Dof);
8525  dshape_1d.SetSize(p + 1);
8526  m_dshape.SetSize(Dof, Dim);
8527 #endif
8528  dof_map.SetSize(Dof);
8529 
8530  struct Index
8531  {
8532  int p2p3;
8533  Index(int p) { p2p3 = 2*p + 3; }
8534  int operator()(int i, int j) { return ((p2p3-j)*j)/2+i; }
8535  };
8536  Index idx(p);
8537 
8538  // vertices
8539  dof_map[idx(0,0)] = 0;
8540  Nodes.IntPoint(0).Set2(0., 0.);
8541  dof_map[idx(p,0)] = 1;
8542  Nodes.IntPoint(1).Set2(1., 0.);
8543  dof_map[idx(0,p)] = 2;
8544  Nodes.IntPoint(2).Set2(0., 1.);
8545 
8546  // edges
8547  int o = 3;
8548  for (int i = 1; i < p; i++)
8549  {
8550  dof_map[idx(i,0)] = o;
8551  Nodes.IntPoint(o++).Set2(double(i)/p, 0.);
8552  }
8553  for (int i = 1; i < p; i++)
8554  {
8555  dof_map[idx(p-i,i)] = o;
8556  Nodes.IntPoint(o++).Set2(double(p-i)/p, double(i)/p);
8557  }
8558  for (int i = 1; i < p; i++)
8559  {
8560  dof_map[idx(0,p-i)] = o;
8561  Nodes.IntPoint(o++).Set2(0., double(p-i)/p);
8562  }
8563 
8564  // interior
8565  for (int j = 1; j < p; j++)
8566  for (int i = 1; i + j < p; i++)
8567  {
8568  dof_map[idx(i,j)] = o;
8569  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8570  }
8571 }
8572 
8573 // static method
8575  const int p, const double l1, const double l2, double *shape)
8576 {
8577  const double l3 = 1. - l1 - l2;
8578 
8579  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
8580  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
8581  // Another expression is given by the terms of the expansion:
8582  // (l1 + l2 + l3)^p =
8583  // \sum_{j=0}^p \binom{p}{j} l2^j
8584  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
8585  const int *bp = Poly_1D::Binom(p);
8586  double z = 1.;
8587  for (int o = 0, j = 0; j <= p; j++)
8588  {
8589  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape[o]);
8590  double s = bp[j]*z;
8591  for (int i = 0; i <= p - j; i++)
8592  {
8593  shape[o++] *= s;
8594  }
8595  z *= l2;
8596  }
8597 }
8598 
8599 // static method
8601  const int p, const double l1, const double l2,
8602  double *dshape_1d, double *dshape)
8603 {
8604  const int dof = ((p + 1)*(p + 2))/2;
8605  const double l3 = 1. - l1 - l2;
8606 
8607  const int *bp = Poly_1D::Binom(p);
8608  double z = 1.;
8609  for (int o = 0, j = 0; j <= p; j++)
8610  {
8611  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
8612  double s = bp[j]*z;
8613  for (int i = 0; i <= p - j; i++)
8614  {
8615  dshape[o++] = s*dshape_1d[i];
8616  }
8617  z *= l2;
8618  }
8619  z = 1.;
8620  for (int i = 0; i <= p; i++)
8621  {
8622  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
8623  double s = bp[i]*z;
8624  for (int o = i, j = 0; j <= p - i; j++)
8625  {
8626  dshape[dof + o] = s*dshape_1d[j];
8627  o += p + 1 - j;
8628  }
8629  z *= l1;
8630  }
8631 }
8632 
8634  Vector &shape) const
8635 {
8636 #ifdef MFEM_THREAD_SAFE
8637  Vector m_shape(Dof);
8638 #endif
8639  CalcShape(Order, ip.x, ip.y, m_shape.GetData());
8640  for (int i = 0; i < Dof; i++)
8641  {
8642  shape(dof_map[i]) = m_shape(i);
8643  }
8644 }
8645 
8647  DenseMatrix &dshape) const
8648 {
8649 #ifdef MFEM_THREAD_SAFE
8650  Vector dshape_1d(Order + 1);
8652 #endif
8653  CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(), m_dshape.Data());
8654  for (int d = 0; d < 2; d++)
8655  {
8656  for (int i = 0; i < Dof; i++)
8657  {
8658  dshape(dof_map[i],d) = m_dshape(i,d);
8659  }
8660  }
8661 }
8662 
8663 
8665  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
8666  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
8667 {
8668 #ifndef MFEM_THREAD_SAFE
8669  m_shape.SetSize(Dof);
8670  dshape_1d.SetSize(p + 1);
8671  m_dshape.SetSize(Dof, Dim);
8672 #endif
8673  dof_map.SetSize(Dof);
8674 
8675  struct Index
8676  {
8677  int p, dof;
8678  int tri(int k) { return (k*(k + 1))/2; }
8679  int tet(int k) { return (k*(k + 1)*(k + 2))/6; }
8680  Index(int p_) { p = p_; dof = tet(p + 1); }
8681  int operator()(int i, int j, int k)
8682  { return dof - tet(p - k) - tri(p + 1 - k - j) + i; }
8683  };
8684  Index idx(p);
8685 
8686  // vertices
8687  dof_map[idx(0,0,0)] = 0;
8688  Nodes.IntPoint(0).Set3(0., 0., 0.);
8689  dof_map[idx(p,0,0)] = 1;
8690  Nodes.IntPoint(1).Set3(1., 0., 0.);
8691  dof_map[idx(0,p,0)] = 2;
8692  Nodes.IntPoint(2).Set3(0., 1., 0.);
8693  dof_map[idx(0,0,p)] = 3;
8694  Nodes.IntPoint(3).Set3(0., 0., 1.);
8695 
8696  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
8697  int o = 4;
8698  for (int i = 1; i < p; i++) // (0,1)
8699  {
8700  dof_map[idx(i,0,0)] = o;
8701  Nodes.IntPoint(o++).Set3(double(i)/p, 0., 0.);
8702  }
8703  for (int i = 1; i < p; i++) // (0,2)
8704  {
8705  dof_map[idx(0,i,0)] = o;
8706  Nodes.IntPoint(o++).Set3(0., double(i)/p, 0.);
8707  }
8708  for (int i = 1; i < p; i++) // (0,3)
8709  {
8710  dof_map[idx(0,0,i)] = o;
8711  Nodes.IntPoint(o++).Set3(0., 0., double(i)/p);
8712  }
8713  for (int i = 1; i < p; i++) // (1,2)
8714  {
8715  dof_map[idx(p-i,i,0)] = o;
8716  Nodes.IntPoint(o++).Set3(double(p-i)/p, double(i)/p, 0.);
8717  }
8718  for (int i = 1; i < p; i++) // (1,3)
8719  {
8720  dof_map[idx(p-i,0,i)] = o;
8721  Nodes.IntPoint(o++).Set3(double(p-i)/p, 0., double(i)/p);
8722  }
8723  for (int i = 1; i < p; i++) // (2,3)
8724  {
8725  dof_map[idx(0,p-i,i)] = o;
8726  Nodes.IntPoint(o++).Set3(0., double(p-i)/p, double(i)/p);
8727  }
8728 
8729  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
8730  for (int j = 1; j < p; j++)
8731  for (int i = 1; i + j < p; i++) // (1,2,3)
8732  {
8733  dof_map[idx(p-i-j,i,j)] = o;
8734  Nodes.IntPoint(o++).Set3(double(p-i-j)/p, double(i)/p, double(j)/p);
8735  }
8736  for (int j = 1; j < p; j++)
8737  for (int i = 1; i + j < p; i++) // (0,3,2)
8738  {
8739  dof_map[idx(0,j,i)] = o;
8740  Nodes.IntPoint(o++).Set3(0., double(j)/p, double(i)/p);
8741  }
8742  for (int j = 1; j < p; j++)
8743  for (int i = 1; i + j < p; i++) // (0,1,3)
8744  {
8745  dof_map[idx(i,0,j)] = o;
8746  Nodes.IntPoint(o++).Set3(double(i)/p, 0., double(j)/p);
8747  }
8748  for (int j = 1; j < p; j++)
8749  for (int i = 1; i + j < p; i++) // (0,2,1)
8750  {
8751  dof_map[idx(j,i,0)] = o;
8752  Nodes.IntPoint(o++).Set3(double(j)/p, double(i)/p, 0.);
8753  }
8754 
8755  // interior
8756  for (int k = 1; k < p; k++)
8757  for (int j = 1; j + k < p; j++)
8758  for (int i = 1; i + j + k < p; i++)
8759  {
8760  dof_map[idx(i,j,k)] = o;
8761  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8762  }
8763 }
8764 
8765 // static method
8767  const int p, const double l1, const double l2, const double l3,
8768  double *shape)
8769 {
8770  const double l4 = 1. - l1 - l2 - l3;
8771 
8772  // The basis functions are the terms in the expansion:
8773  // (l1 + l2 + l3 + l4)^p =
8774  // \sum_{k=0}^p \binom{p}{k} l3^k
8775  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8776  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8777  const int *bp = Poly_1D::Binom(p);
8778  double l3k = 1.;
8779  for (int o = 0, k = 0; k <= p; k++)
8780  {
8781  const int *bpk = Poly_1D::Binom(p - k);
8782  const double ek = bp[k]*l3k;
8783  double l2j = 1.;
8784  for (int j = 0; j <= p - k; j++)
8785  {
8786  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape[o]);
8787  double ekj = ek*bpk[j]*l2j;
8788  for (int i = 0; i <= p - k - j; i++)
8789  {
8790  shape[o++] *= ekj;
8791  }
8792  l2j *= l2;
8793  }
8794  l3k *= l3;
8795  }
8796 }
8797 
8798 // static method
8800  const int p, const double l1, const double l2, const double l3,
8801  double *dshape_1d, double *dshape)
8802 {
8803  const int dof = ((p + 1)*(p + 2)*(p + 3))/6;
8804  const double l4 = 1. - l1 - l2 - l3;
8805 
8806  // For the x derivatives, differentiate the terms of the expression:
8807  // \sum_{k=0}^p \binom{p}{k} l3^k
8808  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8809  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8810  const int *bp = Poly_1D::Binom(p);
8811  double l3k = 1.;
8812  for (int o = 0, k = 0; k <= p; k++)
8813  {
8814  const int *bpk = Poly_1D::Binom(p - k);
8815  const double ek = bp[k]*l3k;
8816  double l2j = 1.;
8817  for (int j = 0; j <= p - k; j++)
8818  {
8819  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
8820  double ekj = ek*bpk[j]*l2j;
8821  for (int i = 0; i <= p - k - j; i++)
8822  {
8823  dshape[o++] = dshape_1d[i]*ekj;
8824  }
8825  l2j *= l2;
8826  }
8827  l3k *= l3;
8828  }
8829  // For the y derivatives, differentiate the terms of the expression:
8830  // \sum_{k=0}^p \binom{p}{k} l3^k
8831  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
8832  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
8833  l3k = 1.;
8834  for (int ok = 0, k = 0; k <= p; k++)
8835  {
8836  const int *bpk = Poly_1D::Binom(p - k);
8837  const double ek = bp[k]*l3k;
8838  double l1i = 1.;
8839  for (int i = 0; i <= p - k; i++)
8840  {
8841  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
8842  double eki = ek*bpk[i]*l1i;
8843  int o = ok + i;
8844  for (int j = 0; j <= p - k - i; j++)
8845  {
8846  dshape[dof + o] = dshape_1d[j]*eki;
8847  o += p - k - j + 1;
8848  }
8849  l1i *= l1;
8850  }
8851  l3k *= l3;
8852  ok += ((p - k + 2)*(p - k + 1))/2;
8853  }
8854  // For the z derivatives, differentiate the terms of the expression:
8855  // \sum_{j=0}^p \binom{p}{j} l2^j
8856  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
8857  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
8858  double l2j = 1.;
8859  for (int j = 0; j <= p; j++)
8860  {
8861  const int *bpj = Poly_1D::Binom(p - j);
8862  const double ej = bp[j]*l2j;
8863  double l1i = 1.;
8864  for (int i = 0; i <= p - j; i++)
8865  {
8866  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
8867  double eji = ej*bpj[i]*l1i;
8868  int m = ((p + 2)*(p + 1))/2;
8869  int n = ((p - j + 2)*(p - j + 1))/2;
8870  for (int o = i, k = 0; k <= p - j - i; k++)
8871  {
8872  // m = ((p - k + 2)*(p - k + 1))/2;
8873  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
8874  o += m;
8875  dshape[2*dof + o - n] = dshape_1d[k]*eji;
8876  m -= p - k + 1;
8877  n -= p - k - j + 1;
8878  }
8879  l1i *= l1;
8880  }
8881  l2j *= l2;
8882  }
8883 }
8884 
8886  Vector &shape) const
8887 {
8888 #ifdef MFEM_THREAD_SAFE
8889  Vector m_shape(Dof);
8890 #endif
8891  CalcShape(Order, ip.x, ip.y, ip.z, m_shape.GetData());
8892  for (int i = 0; i < Dof; i++)
8893  {
8894  shape(dof_map[i]) = m_shape(i);
8895  }
8896 }
8897 
8899  DenseMatrix &dshape) const
8900 {
8901 #ifdef MFEM_THREAD_SAFE
8902  Vector dshape_1d(Order + 1);
8904 #endif
8905  CalcDShape(Order, ip.x, ip.y, ip.z, dshape_1d.GetData(), m_dshape.Data());
8906  for (int d = 0; d < 3; d++)
8907  {
8908  for (int i = 0; i < Dof; i++)
8909  {
8910  dshape(dof_map[i],d) = m_dshape(i,d);
8911  }
8912  }
8913 }
8914 
8915 
8917  const int btype)
8918  : NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
8919  p, FunctionSpace::Qk),
8920  TriangleFE(p, btype),
8921  SegmentFE(p, btype)
8922 {
8923 #ifndef MFEM_THREAD_SAFE
8924  t_shape.SetSize(TriangleFE.GetDof());
8925  s_shape.SetSize(SegmentFE.GetDof());
8926  t_dshape.SetSize(TriangleFE.GetDof(), 2);
8927  s_dshape.SetSize(SegmentFE.GetDof(), 1);
8928 #endif
8929 
8930  t_dof.SetSize(Dof);
8931  s_dof.SetSize(Dof);
8932 
8933  // Nodal DoFs
8934  t_dof[0] = 0; s_dof[0] = 0;
8935  t_dof[1] = 1; s_dof[1] = 0;
8936  t_dof[2] = 2; s_dof[2] = 0;
8937  t_dof[3] = 0; s_dof[3] = 1;
8938  t_dof[4] = 1; s_dof[4] = 1;
8939  t_dof[5] = 2; s_dof[5] = 1;
8940 
8941  // Edge DoFs
8942  int ne = p-1;
8943  for (int i=1; i<p; i++)
8944  {
8945  t_dof[5 + 0 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 0 * ne + i] = 0;
8946  t_dof[5 + 1 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 1 * ne + i] = 0;
8947  t_dof[5 + 2 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 2 * ne + i] = 0;
8948  t_dof[5 + 3 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 3 * ne + i] = 1;
8949  t_dof[5 + 4 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 4 * ne + i] = 1;
8950  t_dof[5 + 5 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 5 * ne + i] = 1;
8951  t_dof[5 + 6 * ne + i] = 0; s_dof[5 + 6 * ne + i] = i + 1;
8952  t_dof[5 + 7 * ne + i] = 1; s_dof[5 + 7 * ne + i] = i + 1;
8953  t_dof[5 + 8 * ne + i] = 2; s_dof[5 + 8 * ne + i] = i + 1;
8954  }
8955 
8956  // Triangular Face DoFs
8957  int k=0;
8958  int nt = (p-1)*(p-2)/2;
8959  for (int j=1; j<p; j++)
8960  {
8961  for (int i=1; i<p-j; i++)
8962  {
8963  int l = j - p + (((2 * p - 1) - i) * i) / 2;
8964  t_dof[6 + 9 * ne + k] = 3 * p + l; s_dof[6 + 9 * ne + k] = 0;
8965  t_dof[6 + 9 * ne + nt + k] = 3 * p + k; s_dof[6 + 9 * ne + nt + k] = 1;
8966  k++;
8967  }
8968  }
8969 
8970  // Quadrilateral Face DoFs
8971  k=0;
8972  int nq = (p-1)*(p-1);
8973  for (int j=1; j<p; j++)
8974  {
8975  for (int i=1; i<p; i++)
8976  {
8977  t_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 2 + 0 * ne + i;
8978  t_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 2 + 1 * ne + i;
8979  t_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 2 + 2 * ne + i;
8980 
8981  s_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 1 + j;
8982  s_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 1 + j;
8983  s_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 1 + j;
8984 
8985  k++;
8986  }
8987  }
8988 
8989  // Interior DoFs
8990  int m=0;
8991  for (int k=1; k<p; k++)
8992  {
8993  int l=0;
8994  for (int j=1; j<p; j++)
8995  {
8996  for (int i=1; i<j; i++)
8997  {
8998  t_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 3 * p + l;
8999  s_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 1 + k;
9000  l++; m++;
9001  }
9002  }
9003  }
9004 
9005  // Define Nodes
9006  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
9007  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
9008  for (int i=0; i<Dof; i++)
9009  {
9010  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
9011  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
9012  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
9013  }
9014 }
9015 
9017  Vector &shape) const
9018 {
9019 #ifdef MFEM_THREAD_SAFE
9020  Vector t_shape(TriangleFE.GetDof());
9021  Vector s_shape(SegmentFE.GetDof());
9022 #endif
9023 
9024  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9025 
9026  TriangleFE.CalcShape(ip, t_shape);
9027  SegmentFE.CalcShape(ipz, s_shape);
9028 
9029  for (int i=0; i<Dof; i++)
9030  {
9031  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
9032  }
9033 }
9034 
9036  DenseMatrix &dshape) const
9037 {
9038 #ifdef MFEM_THREAD_SAFE
9039  Vector t_shape(TriangleFE.GetDof());
9040  DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
9041  Vector s_shape(SegmentFE.GetDof());
9042  DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
9043 #endif
9044 
9045  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9046 
9047  TriangleFE.CalcShape(ip, t_shape);
9048  TriangleFE.CalcDShape(ip, t_dshape);
9049  SegmentFE.CalcShape(ipz, s_shape);
9050  SegmentFE.CalcDShape(ipz, s_dshape);
9051 
9052  for (int i=0; i<Dof; i++)
9053  {
9054  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
9055  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
9056  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
9057  }
9058 }
9059 
9060 
9062  : PositiveFiniteElement(3, Geometry::PRISM,
9063  ((p + 1)*(p + 1)*(p + 2))/2, p, FunctionSpace::Qk),
9064  TriangleFE(p),
9065  SegmentFE(p)
9066 {
9067 #ifndef MFEM_THREAD_SAFE
9072 #endif
9073 
9074  t_dof.SetSize(Dof);
9075  s_dof.SetSize(Dof);
9076 
9077  // Nodal DoFs
9078  t_dof[0] = 0; s_dof[0] = 0;
9079  t_dof[1] = 1; s_dof[1] = 0;
9080  t_dof[2] = 2; s_dof[2] = 0;
9081  t_dof[3] = 0; s_dof[3] = 1;
9082  t_dof[4] = 1; s_dof[4] = 1;
9083  t_dof[5] = 2; s_dof[5] = 1;
9084 
9085  // Edge DoFs
9086  int ne = p-1;
9087  for (int i=1; i<p; i++)
9088  {
9089  t_dof[5 + 0 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 0 * ne + i] = 0;
9090  t_dof[5 + 1 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 1 * ne + i] = 0;
9091  t_dof[5 + 2 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 2 * ne + i] = 0;
9092  t_dof[5 + 3 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 3 * ne + i] = 1;
9093  t_dof[5 + 4 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 4 * ne + i] = 1;
9094  t_dof[5 + 5 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 5 * ne + i] = 1;
9095  t_dof[5 + 6 * ne + i] = 0; s_dof[5 + 6 * ne + i] = i + 1;
9096  t_dof[5 + 7 * ne + i] = 1; s_dof[5 + 7 * ne + i] = i + 1;
9097  t_dof[5 + 8 * ne + i] = 2; s_dof[5 + 8 * ne + i] = i + 1;
9098  }
9099 
9100  // Triangular Face DoFs
9101  int k=0;
9102  int nt = (p-1)*(p-2)/2;
9103  for (int j=1; j<p; j++)
9104  {
9105  for (int i=1; i<j; i++)
9106  {
9107  t_dof[6 + 9 * ne + k] = 3 * p + k; s_dof[6 + 9 * ne + k] = 0;
9108  t_dof[6 + 9 * ne + nt + k] = 3 * p + k; s_dof[6 + 9 * ne + nt + k] = 1;
9109  k++;
9110  }
9111  }
9112 
9113  // Quadrilateral Face DoFs
9114  k=0;
9115  int nq = (p-1)*(p-1);
9116  for (int j=1; j<p; j++)
9117  {
9118  for (int i=1; i<p; i++)
9119  {
9120  t_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 2 + 0 * ne + i;
9121  t_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 2 + 1 * ne + i;
9122  t_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 2 + 2 * ne + i;
9123 
9124  s_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 1 + j;
9125  s_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 1 + j;
9126  s_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 1 + j;
9127 
9128  k++;
9129  }
9130  }
9131 
9132  // Interior DoFs
9133  int m=0;
9134  for (int k=1; k<p; k++)
9135  {
9136  int l=0;
9137  for (int j=1; j<p; j++)
9138  {
9139  for (int i=1; i<j; i++)
9140  {
9141  t_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 3 * p + l;
9142  s_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 1 + k;
9143  l++; m++;
9144  }
9145  }
9146  }
9147 
9148  // Define Nodes
9149  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
9150  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
9151  for (int i=0; i<Dof; i++)
9152  {
9153  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
9154  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
9155  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
9156  }
9157 }
9158 
9160  Vector &shape) const
9161 {
9162 #ifdef MFEM_THREAD_SAFE
9165 #endif
9166 
9167  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9168 
9170  SegmentFE.CalcShape(ipz, s_shape);
9171 
9172  for (int i=0; i<Dof; i++)
9173  {
9174  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
9175  }
9176 }
9177 
9179  DenseMatrix &dshape) const
9180 {
9181 #ifdef MFEM_THREAD_SAFE
9186 #endif
9187 
9188  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9189 
9192  SegmentFE.CalcShape(ipz, s_shape);
9194 
9195  for (int i=0; i<Dof; i++)
9196  {
9197  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
9198  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
9199  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
9200  }
9201 }
9202 
9203 
9204 L2_SegmentElement::L2_SegmentElement(const int p, const int btype)
9205  : NodalTensorFiniteElement(1, p, VerifyOpen(btype), L2_DOF_MAP)
9206 {
9207  const double *op = poly1d.OpenPoints(p, btype);
9208 
9209 #ifndef MFEM_THREAD_SAFE
9210  shape_x.SetSize(p + 1);
9211  dshape_x.SetDataAndSize(NULL, p + 1);
9212 #endif
9213 
9214  for (int i = 0; i <= p; i++)
9215  {
9216  Nodes.IntPoint(i).x = op[i];
9217  }
9218 }
9219 
9221  Vector &shape) const
9222 {
9223  basis1d.Eval(ip.x, shape);
9224 }
9225 
9227  DenseMatrix &dshape) const
9228 {
9229 #ifdef MFEM_THREAD_SAFE
9230  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
9231 #else
9232  dshape_x.SetData(dshape.Data());
9233 #endif
9234  basis1d.Eval(ip.x, shape_x, dshape_x);
9235 }
9236 
9237 void L2_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
9238 {
9239  const int p = Order;
9240  const double *op = poly1d.OpenPoints(p, b_type);
9241 
9242  switch (vertex)
9243  {
9244  case 0:
9245  for (int i = 0; i <= p; i++)
9246  {
9247  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9248  }
9249  break;
9250 
9251  case 1:
9252  for (int i = 0; i <= p; i++)
9253  {
9254  dofs(i) = poly1d.CalcDelta(p,op[i]);
9255  }
9256  break;
9257  }
9258 }
9259 
9260 
9262  : PositiveTensorFiniteElement(1, p, L2_DOF_MAP)
9263 {
9264 #ifndef MFEM_THREAD_SAFE
9265  shape_x.SetSize(p + 1);
9266  dshape_x.SetDataAndSize(NULL, p + 1);
9267 #endif
9268 
9269  if (p == 0)
9270  {
9271  Nodes.IntPoint(0).x = 0.5;
9272  }
9273  else
9274  {
9275  for (int i = 0; i <= p; i++)
9276  {
9277  Nodes.IntPoint(i).x = double(i)/p;
9278  }
9279  }
9280 }
9281 
9283  Vector &shape) const
9284 {
9285  Poly_1D::CalcBernstein(Order, ip.x, shape);
9286 }
9287 
9289  DenseMatrix &dshape) const
9290 {
9291 #ifdef MFEM_THREAD_SAFE
9292  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
9293 #else
9294  dshape_x.SetData(dshape.Data());
9295 #endif
9296  Poly_1D::CalcBernstein(Order, ip.x, shape_x, dshape_x);
9297 }
9298 
9299 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
9300 {
9301  dofs = 0.0;
9302  dofs[vertex*Order] = 1.0;
9303 }
9304 
9305 
9307  : NodalTensorFiniteElement(2, p, VerifyOpen(btype), L2_DOF_MAP)
9308 {
9309  const double *op = poly1d.OpenPoints(p, b_type);
9310 
9311 #ifndef MFEM_THREAD_SAFE
9312  shape_x.SetSize(p + 1);
9313  shape_y.SetSize(p + 1);
9314  dshape_x.SetSize(p + 1);
9315  dshape_y.SetSize(p + 1);
9316 #endif
9317 
9318  for (int o = 0, j = 0; j <= p; j++)
9319  for (int i = 0; i <= p; i++)
9320  {
9321  Nodes.IntPoint(o++).Set2(op[i], op[j]);
9322  }
9323 }
9324 
9326  Vector &shape) const
9327 {
9328  const int p = Order;
9329 
9330 #ifdef MFEM_THREAD_SAFE
9331  Vector shape_x(p+1), shape_y(p+1);
9332 #endif
9333 
9334  basis1d.Eval(ip.x, shape_x);
9335  basis1d.Eval(ip.y, shape_y);
9336 
9337  for (int o = 0, j = 0; j <= p; j++)
9338  for (int i = 0; i <= p; i++)
9339  {
9340  shape(o++) = shape_x(i)*shape_y(j);
9341  }
9342 }
9343 
9345  DenseMatrix &dshape) const
9346 {
9347  const int p = Order;
9348 
9349 #ifdef MFEM_THREAD_SAFE
9350  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
9351 #endif
9352 
9353  basis1d.Eval(ip.x, shape_x, dshape_x);
9354  basis1d.Eval(ip.y, shape_y, dshape_y);
9355 
9356  for (int o = 0, j = 0; j <= p; j++)
9357  for (int i = 0; i <= p; i++)
9358  {
9359  dshape(o,0) = dshape_x(i)* shape_y(j);
9360  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
9361  }
9362 }
9363 
9364 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
9365 {
9366  const int p = Order;
9367  const double *op = poly1d.OpenPoints(p, b_type);
9368 
9369 #ifdef MFEM_THREAD_SAFE
9370  Vector shape_x(p+1), shape_y(p+1);
9371 #endif
9372 
9373  for (int i = 0; i <= p; i++)
9374  {
9375  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9376  shape_y(i) = poly1d.CalcDelta(p,op[i]);
9377  }
9378 
9379  switch (vertex)
9380  {
9381  case 0:
9382  for (int o = 0, j = 0; j <= p; j++)
9383  for (int i = 0; i <= p; i++)
9384  {
9385  dofs[o++] = shape_x(i)*shape_x(j);
9386  }
9387  break;
9388  case 1:
9389  for (int o = 0, j = 0; j <= p; j++)
9390  for (int i = 0; i <= p; i++)
9391  {
9392  dofs[o++] = shape_y(i)*shape_x(j);
9393  }
9394  break;
9395  case 2:
9396  for (int o = 0, j = 0; j <= p; j++)
9397  for (int i = 0; i <= p; i++)
9398  {
9399  dofs[o++] = shape_y(i)*shape_y(j);
9400  }
9401  break;
9402  case 3:
9403  for (int o = 0, j = 0; j <= p; j++)
9404  for (int i = 0; i <= p; i++)
9405  {
9406  dofs[o++] = shape_x(i)*shape_y(j);
9407  }
9408  break;
9409  }
9410 }
9411 
9412 
9414  : PositiveTensorFiniteElement(2, p, L2_DOF_MAP)
9415 {
9416 #ifndef MFEM_THREAD_SAFE
9417  shape_x.SetSize(p + 1);
9418  shape_y.SetSize(p + 1);
9419  dshape_x.SetSize(p + 1);
9420  dshape_y.SetSize(p + 1);
9421 #endif
9422 
9423  if (p == 0)
9424  {
9425  Nodes.IntPoint(0).Set2(0.5, 0.5);
9426  }
9427  else
9428  {
9429  for (int o = 0, j = 0; j <= p; j++)
9430  for (int i = 0; i <= p; i++)
9431  {
9432  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
9433  }
9434  }
9435 }
9436 
9438  Vector &shape) const
9439 {
9440  const int p = Order;
9441 
9442 #ifdef MFEM_THREAD_SAFE
9443  Vector shape_x(p+1), shape_y(p+1);
9444 #endif
9445 
9446  Poly_1D::CalcBernstein(p, ip.x, shape_x);
9447  Poly_1D::CalcBernstein(p, ip.y, shape_y);
9448 
9449  for (int o = 0, j = 0; j <= p; j++)
9450  for (int i = 0; i <= p; i++)
9451  {
9452  shape(o++) = shape_x(i)*shape_y(j);
9453  }
9454 }
9455 
9457  DenseMatrix &dshape) const
9458 {
9459  const int p = Order;
9460 
9461 #ifdef MFEM_THREAD_SAFE
9462  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
9463 #endif
9464 
9465  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
9466  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
9467 
9468  for (int o = 0, j = 0; j <= p; j++)
9469  for (int i = 0; i <= p; i++)
9470  {
9471  dshape(o,0) = dshape_x(i)* shape_y(j);
9472  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
9473  }
9474 }
9475 
9477 {
9478  const int p = Order;
9479 
9480  dofs = 0.0;
9481  switch (vertex)
9482  {
9483  case 0: dofs[0] = 1.0; break;
9484  case 1: dofs[p] = 1.0; break;
9485  case 2: dofs[p*(p + 2)] = 1.0; break;
9486  case 3: dofs[p*(p + 1)] = 1.0; break;
9487  }
9488 }
9489 
9490 
9491 L2_HexahedronElement::L2_HexahedronElement(const int p, const int btype)
9492  : NodalTensorFiniteElement(3, p, VerifyOpen(btype), L2_DOF_MAP)
9493 {
9494  const double *op = poly1d.OpenPoints(p, btype);
9495 
9496 #ifndef MFEM_THREAD_SAFE
9497  shape_x.SetSize(p + 1);
9498  shape_y.SetSize(p + 1);
9499  shape_z.SetSize(p + 1);
9500  dshape_x.SetSize(p + 1);
9501  dshape_y.SetSize(p + 1);
9502  dshape_z.SetSize(p + 1);
9503 #endif
9504 
9505  for (int o = 0, k = 0; k <= p; k++)
9506  for (int j = 0; j <= p; j++)
9507  for (int i = 0; i <= p; i++)
9508  {
9509  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
9510  }
9511 }
9512 
9514  Vector &shape) const
9515 {
9516  const int p = Order;
9517 
9518 #ifdef MFEM_THREAD_SAFE
9519  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9520 #endif
9521 
9522  basis1d.Eval(ip.x, shape_x);
9523  basis1d.Eval(ip.y, shape_y);
9524  basis1d.Eval(ip.z, shape_z);
9525 
9526  for (int o = 0, k = 0; k <= p; k++)
9527  for (int j = 0; j <= p; j++)
9528  for (int i = 0; i <= p; i++)
9529  {
9530  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
9531  }
9532 }
9533 
9535  DenseMatrix &dshape) const
9536 {
9537  const int p = Order;
9538 
9539 #ifdef MFEM_THREAD_SAFE
9540  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9541  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
9542 #endif
9543 
9544  basis1d.Eval(ip.x, shape_x, dshape_x);
9545  basis1d.Eval(ip.y, shape_y, dshape_y);
9546  basis1d.Eval(ip.z, shape_z, dshape_z);
9547 
9548  for (int o = 0, k = 0; k <= p; k++)
9549  for (int j = 0; j <= p; j++)
9550  for (int i = 0; i <= p; i++)
9551  {
9552  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
9553  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
9554  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
9555  }
9556 }
9557 
9558 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9559 {
9560  const int p = Order;
9561  const double *op = poly1d.OpenPoints(p, b_type);
9562 
9563 #ifdef MFEM_THREAD_SAFE
9564  Vector shape_x(p+1), shape_y(p+1);
9565 #endif
9566 
9567  for (int i = 0; i <= p; i++)
9568  {
9569  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9570  shape_y(i) = poly1d.CalcDelta(p,op[i]);
9571  }
9572 
9573  switch (vertex)
9574  {
9575  case 0:
9576  for (int o = 0, k = 0; k <= p; k++)
9577  for (int j = 0; j <= p; j++)
9578  for (int i = 0; i <= p; i++)
9579  {
9580  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
9581  }
9582  break;
9583  case 1:
9584  for (int o = 0, k = 0; k <= p; k++)
9585  for (int j = 0; j <= p; j++)
9586  for (int i = 0; i <= p; i++)
9587  {
9588  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
9589  }
9590  break;
9591  case 2:
9592  for (int o = 0, k = 0; k <= p; k++)
9593  for (int j = 0; j <= p; j++)
9594  for (int i = 0; i <= p; i++)
9595  {
9596  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
9597  }
9598  break;
9599  case 3:
9600  for (int o = 0, k = 0; k <= p; k++)
9601  for (int j = 0; j <= p; j++)
9602  for (int i = 0; i <= p; i++)
9603  {
9604  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
9605  }
9606  break;
9607  case 4:
9608  for (int o = 0, k = 0; k <= p; k++)
9609  for (int j = 0; j <= p; j++)
9610  for (int i = 0; i <= p; i++)
9611  {
9612  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
9613  }
9614  break;
9615  case 5:
9616  for (int o = 0, k = 0; k <= p; k++)
9617  for (int j = 0; j <= p; j++)
9618  for (int i = 0; i <= p; i++)
9619  {
9620  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
9621  }
9622  break;
9623  case 6:
9624  for (int o = 0, k = 0; k <= p; k++)
9625  for (int j = 0; j <= p; j++)
9626  for (int i = 0; i <= p; i++)
9627  {
9628  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
9629  }
9630  break;
9631  case 7:
9632  for (int o = 0, k = 0; k <= p; k++)
9633  for (int j = 0; j <= p; j++)
9634  for (int i = 0; i <= p; i++)
9635  {
9636  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
9637  }
9638  break;
9639  }
9640 }
9641 
9642 
9644  : PositiveTensorFiniteElement(3, p, L2_DOF_MAP)
9645 {
9646 #ifndef MFEM_THREAD_SAFE
9647  shape_x.SetSize(p + 1);
9648  shape_y.SetSize(p + 1);
9649  shape_z.SetSize(p + 1);
9650  dshape_x.SetSize(p + 1);
9651  dshape_y.SetSize(p + 1);
9652  dshape_z.SetSize(p + 1);
9653 #endif
9654 
9655  if (p == 0)
9656  {
9657  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
9658  }
9659  else
9660  {
9661  for (int o = 0, k = 0; k <= p; k++)
9662  for (int j = 0; j <= p; j++)
9663  for (int i = 0; i <= p; i++)
9664  {
9665  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
9666  }
9667  }
9668 }
9669 
9671  Vector &shape) const
9672 {
9673  const int p = Order;
9674 
9675 #ifdef MFEM_THREAD_SAFE
9676  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9677 #endif
9678 
9679  Poly_1D::CalcBernstein(p, ip.x, shape_x);
9680  Poly_1D::CalcBernstein(p, ip.y, shape_y);
9681  Poly_1D::CalcBernstein(p, ip.z, shape_z);
9682 
9683  for (int o = 0, k = 0; k <= p; k++)
9684  for (int j = 0; j <= p; j++)
9685  for (int i = 0; i <= p; i++)
9686  {
9687  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
9688  }
9689 }
9690 
9692  DenseMatrix &dshape) const
9693 {
9694  const int p = Order;
9695 
9696 #ifdef MFEM_THREAD_SAFE
9697  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9698  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
9699 #endif
9700 
9701  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
9702  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
9703  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
9704 
9705  for (int o = 0, k = 0; k <= p; k++)
9706  for (int j = 0; j <= p; j++)
9707  for (int i = 0; i <= p; i++)
9708  {
9709  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
9710  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
9711  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
9712  }
9713 }
9714 
9715 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9716 {
9717  const int p = Order;
9718 
9719  dofs = 0.0;
9720  switch (vertex)
9721  {
9722  case 0: dofs[0] = 1.0; break;
9723  case 1: dofs[p] = 1.0; break;
9724  case 2: dofs[p*(p + 2)] = 1.0; break;
9725  case 3: dofs[p*(p + 1)] = 1.0; break;
9726  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
9727  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
9728  case 6: dofs[Dof - 1] = 1.0; break;
9729  case 7: dofs[Dof - p - 1] = 1.0; break;
9730  }
9731 }
9732 
9733 
9734 L2_TriangleElement::L2_TriangleElement(const int p, const int btype)
9735  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
9736  FunctionSpace::Pk)
9737 {
9738  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
9739 
9740 #ifndef MFEM_THREAD_SAFE
9741  shape_x.SetSize(p + 1);
9742  shape_y.SetSize(p + 1);
9743  shape_l.SetSize(p + 1);
9744  dshape_x.SetSize(p + 1);
9745  dshape_y.SetSize(p + 1);
9746  dshape_l.SetSize(p + 1);
9747  u.SetSize(Dof);
9748  du.SetSize(Dof, Dim);
9749 #else
9750  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9751 #endif
9752 
9753  for (int o = 0, j = 0; j <= p; j++)
9754  for (int i = 0; i + j <= p; i++)
9755  {
9756  double w = op[i] + op[j] + op[p-i-j];
9757  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
9758  }
9759 
9760  DenseMatrix T(Dof);
9761  for (int k = 0; k < Dof; k++)
9762  {
9763  IntegrationPoint &ip = Nodes.IntPoint(k);
9764  poly1d.CalcBasis(p, ip.x, shape_x);
9765  poly1d.CalcBasis(p, ip.y, shape_y);
9766  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9767 
9768  for (int o = 0, j = 0; j <= p; j++)
9769  for (int i = 0; i + j <= p; i++)
9770  {
9771  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9772  }
9773  }
9774 
9775  Ti.Factor(T);
9776  // mfem::out << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
9777 }
9778 
9780  Vector &shape) const
9781 {
9782  const int p = Order;
9783 
9784 #ifdef MFEM_THREAD_SAFE
9785  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
9786 #endif
9787 
9788  poly1d.CalcBasis(p, ip.x, shape_x);
9789  poly1d.CalcBasis(p, ip.y, shape_y);
9790  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9791 
9792  for (int o = 0, j = 0; j <= p; j++)
9793  for (int i = 0; i + j <= p; i++)
9794  {
9795  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9796  }
9797 
9798  Ti.Mult(u, shape);
9799 }
9800 
9802  DenseMatrix &dshape) const
9803 {
9804  const int p = Order;
9805 
9806 #ifdef MFEM_THREAD_SAFE
9807  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9808  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
9809  DenseMatrix du(Dof, Dim);
9810 #endif
9811 
9812  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9813  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9814  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
9815 
9816  for (int o = 0, j = 0; j <= p; j++)
9817  for (int i = 0; i + j <= p; i++)
9818  {
9819  int k = p - i - j;
9820  du(o,0) = ((dshape_x(i)* shape_l(k)) -
9821  ( shape_x(i)*dshape_l(k)))*shape_y(j);
9822  du(o,1) = ((dshape_y(j)* shape_l(k)) -
9823  ( shape_y(j)*dshape_l(k)))*shape_x(i);
9824  o++;
9825  }
9826 
9827  Ti.Mult(du, dshape);
9828 }
9829 
9830 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
9831 {
9832  switch (vertex)
9833  {
9834  case 0:
9835  for (int i = 0; i < Dof; i++)
9836  {
9837  const IntegrationPoint &ip = Nodes.IntPoint(i);
9838  dofs[i] = pow(1.0 - ip.x - ip.y, Order);
9839  }
9840  break;
9841  case 1:
9842  for (int i = 0; i < Dof; i++)
9843  {
9844  const IntegrationPoint &ip = Nodes.IntPoint(i);
9845  dofs[i] = pow(ip.x, Order);
9846  }
9847  break;
9848  case 2:
9849  for (int i = 0; i < Dof; i++)
9850  {
9851  const IntegrationPoint &ip = Nodes.IntPoint(i);
9852  dofs[i] = pow(ip.y, Order);
9853  }
9854  break;
9855  }
9856 }
9857 
9858 
9860  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
9861  FunctionSpace::Pk)
9862 {
9863 #ifndef MFEM_THREAD_SAFE
9864  dshape_1d.SetSize(p + 1);
9865 #endif
9866 
9867  if (p == 0)
9868  {
9869  Nodes.IntPoint(0).Set2(1./3, 1./3);
9870  }
9871  else
9872  {
9873  for (int o = 0, j = 0; j <= p; j++)
9874  for (int i = 0; i + j <= p; i++)
9875  {
9876  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
9877  }
9878  }
9879 }
9880 
9882  Vector &shape) const
9883 {
9884  H1Pos_TriangleElement::CalcShape(Order, ip.x, ip.y, shape.GetData());
9885 }
9886 
9888  DenseMatrix &dshape) const
9889 {
9890 #ifdef MFEM_THREAD_SAFE
9891  Vector dshape_1d(Order + 1);
9892 #endif
9893 
9894  H1Pos_TriangleElement::CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(),
9895  dshape.Data());
9896 }
9897 
9898 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
9899 {
9900  dofs = 0.0;
9901  switch (vertex)
9902  {
9903  case 0: dofs[0] = 1.0; break;
9904  case 1: dofs[Order] = 1.0; break;
9905  case 2: dofs[Dof-1] = 1.0; break;
9906  }
9907 }
9908 
9909 
9911  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
9912  p, FunctionSpace::Pk)
9913 {
9914  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
9915 
9916 #ifndef MFEM_THREAD_SAFE
9917  shape_x.SetSize(p + 1);
9918  shape_y.SetSize(p + 1);
9919  shape_z.SetSize(p + 1);
9920  shape_l.SetSize(p + 1);
9921  dshape_x.SetSize(p + 1);
9922  dshape_y.SetSize(p + 1);
9923  dshape_z.SetSize(p + 1);
9924  dshape_l.SetSize(p + 1);
9925  u.SetSize(Dof);
9926  du.SetSize(Dof, Dim);
9927 #else
9928  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9929 #endif
9930 
9931  for (int o = 0, k = 0; k <= p; k++)
9932  for (int j = 0; j + k <= p; j++)
9933  for (int i = 0; i + j + k <= p; i++)
9934  {
9935  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
9936  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
9937  }
9938 
9939  DenseMatrix T(Dof);
9940  for (int m = 0; m < Dof; m++)
9941  {
9942  IntegrationPoint &ip = Nodes.IntPoint(m);
9943  poly1d.CalcBasis(p, ip.x, shape_x);
9944  poly1d.CalcBasis(p, ip.y, shape_y);
9945  poly1d.CalcBasis(p, ip.z, shape_z);
9946  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9947 
9948  for (int o = 0, k = 0; k <= p; k++)
9949  for (int j = 0; j + k <= p; j++)
9950  for (int i = 0; i + j + k <= p; i++)
9951  {
9952  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9953  }
9954  }
9955 
9956  Ti.Factor(T);
9957  // mfem::out << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
9958 }
9959 
9961  Vector &shape) const
9962 {
9963  const int p = Order;
9964 
9965 #ifdef MFEM_THREAD_SAFE
9966  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9967  Vector u(Dof);
9968 #endif
9969 
9970  poly1d.CalcBasis(p, ip.x, shape_x);
9971  poly1d.CalcBasis(p, ip.y, shape_y);
9972  poly1d.CalcBasis(p, ip.z, shape_z);
9973  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9974 
9975  for (int o = 0, k = 0; k <= p; k++)
9976  for (int j = 0; j + k <= p; j++)
9977  for (int i = 0; i + j + k <= p; i++)
9978  {
9979  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9980  }
9981 
9982  Ti.Mult(u, shape);
9983 }
9984 
9986  DenseMatrix &dshape) const
9987 {
9988  const int p = Order;
9989 
9990 #ifdef MFEM_THREAD_SAFE
9991  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9992  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
9993  DenseMatrix du(Dof, Dim);
9994 #endif
9995 
9996  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9997  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9998  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
9999  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10000 
10001  for (int o = 0, k = 0; k <= p; k++)
10002  for (int j = 0; j + k <= p; j++)
10003  for (int i = 0; i + j + k <= p; i++)
10004  {
10005  int l = p - i - j - k;
10006  du(o,0) = ((dshape_x(i)* shape_l(l)) -
10007  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
10008  du(o,1) = ((dshape_y(j)* shape_l(l)) -
10009  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
10010  du(o,2) = ((dshape_z(k)* shape_l(l)) -
10011  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
10012  o++;
10013  }
10014 
10015  Ti.Mult(du, dshape);
10016 }
10017 
10018 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
10019 {
10020  switch (vertex)
10021  {
10022  case 0:
10023  for (int i = 0; i < Dof; i++)
10024  {
10025  const IntegrationPoint &ip = Nodes.IntPoint(i);
10026  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, Order);
10027  }
10028  break;
10029  case 1:
10030  for (int i = 0; i < Dof; i++)
10031  {
10032  const IntegrationPoint &ip = Nodes.IntPoint(i);
10033  dofs[i] = pow(ip.x, Order);
10034  }
10035  break;
10036  case 2:
10037  for (int i = 0; i < Dof; i++)
10038  {
10039  const IntegrationPoint &ip = Nodes.IntPoint(i);
10040  dofs[i] = pow(ip.y, Order);
10041  }
10042  break;
10043  case 3:
10044  for (int i = 0; i < Dof; i++)
10045  {
10046  const IntegrationPoint &ip = Nodes.IntPoint(i);
10047  dofs[i] = pow(ip.z, Order);
10048  }
10049  break;
10050  }
10051 }
10052 
10053 
10055  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
10056  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
10057 {
10058 #ifndef MFEM_THREAD_SAFE
10059  dshape_1d.SetSize(p + 1);
10060 #endif
10061 
10062  if (p == 0)
10063  {
10064  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
10065  }
10066  else
10067  {
10068  for (int o = 0, k = 0; k <= p; k++)
10069  for (int j = 0; j + k <= p; j++)
10070  for (int i = 0; i + j + k <= p; i++)
10071  {
10072  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
10073  }
10074  }
10075 }
10076 
10078  Vector &shape) const
10079 {
10081  shape.GetData());
10082 }
10083 
10085  DenseMatrix &dshape) const
10086 {
10087 #ifdef MFEM_THREAD_SAFE
10088  Vector dshape_1d(Order + 1);
10089 #endif
10090 
10092  dshape_1d.GetData(), dshape.Data());
10093 }
10094 
10095 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
10096 {
10097  dofs = 0.0;
10098  switch (vertex)
10099  {
10100  case 0: dofs[0] = 1.0; break;
10101  case 1: dofs[Order] = 1.0; break;
10102  case 2: dofs[(Order*(Order+3))/2] = 1.0; break;
10103  case 3: dofs[Dof-1] = 1.0; break;
10104  }
10105 }
10106 
10107 
10108 L2_WedgeElement::L2_WedgeElement(const int p, const int btype)
10109  : NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
10110  p, FunctionSpace::Qk),
10111  TriangleFE(p, btype),
10112  SegmentFE(p, btype)
10113 {
10114 #ifndef MFEM_THREAD_SAFE
10115  t_shape.SetSize(TriangleFE.GetDof());
10116  s_shape.SetSize(SegmentFE.GetDof());
10117  t_dshape.SetSize(TriangleFE.GetDof(), 2);
10118  s_dshape.SetSize(SegmentFE.GetDof(), 1);
10119 #endif
10120 
10121  t_dof.SetSize(Dof);
10122  s_dof.SetSize(Dof);
10123 
10124  // Interior DoFs
10125  int m=0;
10126  for (int k=0; k<=p; k++)
10127  {
10128  int l=0;
10129  for (int j=0; j<=p; j++)
10130  {
10131  for (int i=0; i<=j; i++)
10132  {
10133  t_dof[m] = l;
10134  s_dof[m] = k;
10135  l++; m++;
10136  }
10137  }
10138  }
10139 
10140  // Define Nodes
10141  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
10142  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
10143  for (int i=0; i<Dof; i++)
10144  {
10145  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
10146  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
10147  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
10148  }
10149 }
10150 
10152  Vector &shape) const
10153 {
10154 #ifdef MFEM_THREAD_SAFE
10155  Vector t_shape(TriangleFE.GetDof());
10156  Vector s_shape(SegmentFE.GetDof());
10157 #endif
10158 
10159  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10160 
10161  TriangleFE.CalcShape(ip, t_shape);
10162  SegmentFE.CalcShape(ipz, s_shape);
10163 
10164  for (int i=0; i<Dof; i++)
10165  {
10166  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
10167  }
10168 }
10169 
10171  DenseMatrix &dshape) const
10172 {
10173 #ifdef MFEM_THREAD_SAFE
10174  Vector t_shape(TriangleFE.GetDof());
10175  DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
10176  Vector s_shape(SegmentFE.GetDof());
10177  DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
10178 #endif
10179 
10180  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10181 
10182  TriangleFE.CalcShape(ip, t_shape);
10183  TriangleFE.CalcDShape(ip, t_dshape);
10184  SegmentFE.CalcShape(ipz, s_shape);
10185  SegmentFE.CalcDShape(ipz, s_dshape);
10186 
10187  for (int i=0; i<Dof; i++)
10188  {
10189  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
10190  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
10191  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
10192  }
10193 }
10194 
10195 
10197  : PositiveFiniteElement(3, Geometry::PRISM,
10198  ((p + 1)*(p + 1)*(p + 2))/2, p, FunctionSpace::Qk),
10199  TriangleFE(p),
10200  SegmentFE(p)
10201 {
10202 #ifndef MFEM_THREAD_SAFE
10207 #endif
10208 
10209  t_dof.SetSize(Dof);
10210  s_dof.SetSize(Dof);
10211 
10212  // Interior DoFs
10213  int m=0;
10214  for (int k=0; k<=p; k++)
10215  {
10216  int l=0;
10217  for (int j=0; j<=p; j++)
10218  {
10219  for (int i=0; i<=j; i++)
10220  {
10221  t_dof[m] = l;
10222  s_dof[m] = k;
10223  l++; m++;
10224  }
10225  }
10226  }
10227 
10228  // Define Nodes
10229  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
10230  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
10231  for (int i=0; i<Dof; i++)
10232  {
10233  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
10234  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
10235  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
10236  }
10237 }
10238 
10240  Vector &shape) const
10241 {
10242 #ifdef MFEM_THREAD_SAFE
10245 #endif
10246 
10247  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10248 
10250  SegmentFE.CalcShape(ipz, s_shape);
10251 
10252  for (int i=0; i<Dof; i++)
10253  {
10254  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
10255  }
10256 }
10257 
10259  DenseMatrix &dshape) const
10260 {
10261 #ifdef MFEM_THREAD_SAFE
10266 #endif
10267 
10268  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10269 
10272  SegmentFE.CalcShape(ipz, s_shape);
10274 
10275  for (int i=0; i<Dof; i++)
10276  {
10277  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
10278  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
10279  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
10280  }
10281 }
10282 
10283 
10284 const double RT_QuadrilateralElement::nk[8] =
10285 { 0., -1., 1., 0., 0., 1., -1., 0. };
10286 
10288  const int cb_type,
10289  const int ob_type)
10290  : VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p + 1,
10291  H_DIV, FunctionSpace::Qk),
10292  cbasis1d(poly1d.GetBasis(p + 1, VerifyClosed(cb_type))),
10293  obasis1d(poly1d.GetBasis(p, VerifyOpen(ob_type))),
10294  dof_map(Dof), dof2nk(Dof)
10295 {
10296  const double *cp = poly1d.ClosedPoints(p + 1, cb_type);
10297  const double *op = poly1d.OpenPoints(p, ob_type);
10298  const int dof2 = Dof/2;
10299 
10300 #ifndef MFEM_THREAD_SAFE
10301  shape_cx.SetSize(p + 2);
10302  shape_ox.SetSize(p + 1);
10303  shape_cy.SetSize(p + 2);
10304  shape_oy.SetSize(p + 1);
10305  dshape_cx.SetSize(p + 2);
10306  dshape_cy.SetSize(p + 2);
10307 #endif
10308 
10309  // edges
10310  int o = 0;
10311  for (int i = 0; i <= p; i++) // (0,1)
10312  {
10313  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
10314  }
10315  for (int i = 0; i <= p; i++) // (1,2)
10316  {
10317  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
10318  }
10319  for (int i = 0; i <= p; i++) // (2,3)
10320  {
10321  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
10322  }
10323  for (int i = 0; i <= p; i++) // (3,0)
10324  {
10325  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
10326  }
10327 
10328  // interior
10329  for (int j = 0; j <= p; j++) // x-components
10330  for (int i = 1; i <= p; i++)
10331  {
10332  dof_map[0*dof2 + i + j*(p + 2)] = o++;
10333  }
10334  for (int j = 1; j <= p; j++) // y-components
10335  for (int i = 0; i <= p; i++)
10336  {
10337  dof_map[1*dof2 + i + j*(p + 1)] = o++;
10338  }
10339 
10340  // dof orientations
10341  // x-components
10342  for (int j = 0; j <= p; j++)
10343  for (int i = 0; i <= p/2; i++)
10344  {
10345  int idx = 0*dof2 + i + j*(p + 2);
10346  dof_map[idx] = -1 - dof_map[idx];
10347  }
10348  if (p%2 == 1)
10349  for (int j = p/2 + 1; j <= p; j++)
10350  {
10351  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
10352  dof_map[idx] = -1 - dof_map[idx];
10353  }
10354  // y-components
10355  for (int j = 0; j <= p/2; j++)
10356  for (int i = 0; i <= p; i++)
10357  {
10358  int idx = 1*dof2 + i + j*(p + 1);
10359  dof_map[idx] = -1 - dof_map[idx];
10360  }
10361  if (p%2 == 1)
10362  for (int i = 0; i <= p/2; i++)
10363  {
10364  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
10365  dof_map[idx] = -1 - dof_map[idx];
10366  }
10367 
10368  o = 0;
10369  for (int j = 0; j <= p; j++)
10370  for (int i = 0; i <= p + 1; i++)
10371  {
10372  int idx;
10373  if ((idx = dof_map[o++]) < 0)
10374  {
10375  idx = -1 - idx;
10376  dof2nk[idx] = 3;
10377  }
10378  else
10379  {
10380  dof2nk[idx] = 1;
10381  }
10382  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
10383  }
10384  for (int j = 0; j <= p + 1; j++)
10385  for (int i = 0; i <= p; i++)
10386  {
10387  int idx;
10388  if ((idx = dof_map[o++]) < 0)
10389  {
10390  idx = -1 - idx;
10391  dof2nk[idx] = 0;
10392  }
10393  else
10394  {
10395  dof2nk[idx] = 2;
10396  }
10397  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
10398  }
10399 }
10400 
10402  DenseMatrix &shape) const
10403 {
10404  const int pp1 = Order;
10405 
10406 #ifdef MFEM_THREAD_SAFE
10407  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10408 #endif
10409 
10410  cbasis1d.Eval(ip.x, shape_cx);
10411  obasis1d.Eval(ip.x, shape_ox);
10412  cbasis1d.Eval(ip.y, shape_cy);
10413  obasis1d.Eval(ip.y, shape_oy);
10414 
10415  int o = 0;
10416  for (int j = 0; j < pp1; j++)
10417  for (int i = 0; i <= pp1; i++)
10418  {
10419  int idx, s;
10420  if ((idx = dof_map[o++]) < 0)
10421  {
10422  idx = -1 - idx, s = -1;
10423  }
10424  else
10425  {
10426  s = +1;
10427  }
10428  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
10429  shape(idx,1) = 0.;
10430  }
10431  for (int j = 0; j <= pp1; j++)
10432  for (int i = 0; i < pp1; i++)
10433  {
10434  int idx, s;
10435  if ((idx = dof_map[o++]) < 0)
10436  {
10437  idx = -1 - idx, s = -1;
10438  }
10439  else
10440  {
10441  s = +1;
10442  }
10443  shape(idx,0) = 0.;
10444  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
10445  }
10446 }
10447 
10449  Vector &divshape) const
10450 {
10451  const int pp1 = Order;
10452 
10453 #ifdef MFEM_THREAD_SAFE
10454  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10455  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
10456 #endif
10457 
10458  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10459  obasis1d.Eval(ip.x, shape_ox);
10460  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10461  obasis1d.Eval(ip.y, shape_oy);
10462 
10463  int o = 0;
10464  for (int j = 0; j < pp1; j++)
10465  for (int i = 0; i <= pp1; i++)
10466  {
10467  int idx, s;
10468  if ((idx = dof_map[o++]) < 0)
10469  {
10470  idx = -1 - idx, s = -1;
10471  }
10472  else
10473  {
10474  s = +1;
10475  }
10476  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
10477  }
10478  for (int j = 0; j <= pp1; j++)
10479  for (int i = 0; i < pp1; i++)
10480  {
10481  int idx, s;
10482  if ((idx = dof_map[o++]) < 0)
10483  {
10484  idx = -1 - idx, s = -1;
10485  }
10486  else
10487  {
10488  s = +1;
10489  }
10490  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
10491  }
10492 }
10493 
10494 
10495 const double RT_HexahedronElement::nk[18] =
10496 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
10497 
10499  const int cb_type,
10500  const int ob_type)
10501  : VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 1)*(p + 2), p + 1,
10502  H_DIV, FunctionSpace::Qk),
10503  cbasis1d(poly1d.GetBasis(p + 1, VerifyClosed(cb_type))),
10504  obasis1d(poly1d.GetBasis(p, VerifyOpen(ob_type))),
10505  dof_map(Dof), dof2nk(Dof)
10506 {
10507  const double *cp = poly1d.ClosedPoints(p + 1, cb_type);
10508  const double *op = poly1d.OpenPoints(p, ob_type);
10509  const int dof3 = Dof/3;
10510 
10511 #ifndef MFEM_THREAD_SAFE
10512  shape_cx.SetSize(p + 2);
10513  shape_ox.SetSize(p + 1);
10514  shape_cy.SetSize(p + 2);
10515  shape_oy.SetSize(p + 1);
10516  shape_cz.SetSize(p + 2);
10517  shape_oz.SetSize(p + 1);
10518  dshape_cx.SetSize(p + 2);
10519  dshape_cy.SetSize(p + 2);
10520  dshape_cz.SetSize(p + 2);
10521 #endif
10522 
10523  // faces
10524  int o = 0;
10525  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
10526  for (int i = 0; i <= p; i++)
10527  {
10528  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
10529  }
10530  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
10531  for (int i = 0; i <= p; i++)
10532  {
10533  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
10534  }
10535  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
10536  for (int i = 0; i <= p; i++)
10537  {
10538  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
10539  }
10540  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
10541  for (int i = 0; i <= p; i++)
10542  {
10543  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
10544  }
10545  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
10546  for (int i = 0; i <= p; i++)
10547  {
10548  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
10549  }
10550  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
10551  for (int i = 0; i <= p; i++)
10552  {
10553  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
10554  }
10555 
10556  // interior
10557  // x-components
10558  for (int k = 0; k <= p; k++)
10559  for (int j = 0; j <= p; j++)
10560  for (int i = 1; i <= p; i++)
10561  {
10562  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
10563  }
10564  // y-components
10565  for (int k = 0; k <= p; k++)
10566  for (int j = 1; j <= p; j++)
10567  for (int i = 0; i <= p; i++)
10568  {
10569  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
10570  }
10571  // z-components
10572  for (int k = 1; k <= p; k++)
10573  for (int j = 0; j <= p; j++)
10574  for (int i = 0; i <= p; i++)
10575  {
10576  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
10577  }
10578 
10579  // dof orientations
10580  // for odd p, do not change the orientations in the mid-planes
10581  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
10582  // respectively.
10583  // x-components
10584  for (int k = 0; k <= p; k++)
10585  for (int j = 0; j <= p; j++)
10586  for (int i = 0; i <= p/2; i++)
10587  {
10588  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
10589  dof_map[idx] = -1 - dof_map[idx];
10590  }
10591  // y-components
10592  for (int k = 0; k <= p; k++)
10593  for (int j = 0; j <= p/2; j++)
10594  for (int i = 0; i <= p; i++)
10595  {
10596  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
10597  dof_map[idx] = -1 - dof_map[idx];
10598  }
10599  // z-components
10600  for (int k = 0; k <= p/2; k++)
10601  for (int j = 0; j <= p; j++)
10602  for (int i = 0; i <= p; i++)
10603  {
10604  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
10605  dof_map[idx] = -1 - dof_map[idx];
10606  }
10607 
10608  o = 0;
10609  // x-components
10610  for (int k = 0; k <= p; k++)
10611  for (int j = 0; j <= p; j++)
10612  for (int i = 0; i <= p + 1; i++)
10613  {
10614  int idx;
10615  if ((idx = dof_map[o++]) < 0)
10616  {
10617  idx = -1 - idx;
10618  dof2nk[idx] = 4;
10619  }
10620  else
10621  {
10622  dof2nk[idx] = 2;
10623  }
10624  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
10625  }
10626  // y-components
10627  for (int k = 0; k <= p; k++)
10628  for (int j = 0; j <= p + 1; j++)
10629  for (int i = 0; i <= p; i++)
10630  {
10631  int idx;
10632  if ((idx = dof_map[o++]) < 0)
10633  {
10634  idx = -1 - idx;
10635  dof2nk[idx] = 1;
10636  }
10637  else
10638  {
10639  dof2nk[idx] = 3;
10640  }
10641  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
10642  }
10643  // z-components
10644  for (int k = 0; k <= p + 1; k++)
10645  for (int j = 0; j <= p; j++)
10646  for (int i = 0; i <= p; i++)
10647  {
10648  int idx;
10649  if ((idx = dof_map[o++]) < 0)
10650  {
10651  idx = -1 - idx;
10652  dof2nk[idx] = 0;
10653  }
10654  else
10655  {
10656  dof2nk[idx] = 5;
10657  }
10658  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
10659  }
10660 }
10661 
10663  DenseMatrix &shape) const
10664 {
10665  const int pp1 = Order;
10666 
10667 #ifdef MFEM_THREAD_SAFE
10668  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10669  Vector shape_cz(pp1 + 1), shape_oz(pp1);
10670 #endif
10671 
10672  cbasis1d.Eval(ip.x, shape_cx);
10673  obasis1d.Eval(ip.x, shape_ox);
10674  cbasis1d.Eval(ip.y, shape_cy);
10675  obasis1d.Eval(ip.y, shape_oy);
10676  cbasis1d.Eval(ip.z, shape_cz);
10677  obasis1d.Eval(ip.z, shape_oz);
10678 
10679  int o = 0;
10680  // x-components
10681  for (int k = 0; k < pp1; k++)
10682  for (int j = 0; j < pp1; j++)
10683  for (int i = 0; i <= pp1; i++)
10684  {
10685  int idx, s;
10686  if ((idx = dof_map[o++]) < 0)
10687  {
10688  idx = -1 - idx, s = -1;
10689  }
10690  else
10691  {
10692  s = +1;
10693  }
10694  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
10695  shape(idx,1) = 0.;
10696  shape(idx,2) = 0.;
10697  }
10698  // y-components
10699  for (int k = 0; k < pp1; k++)
10700  for (int j = 0; j <= pp1; j++)
10701  for (int i = 0; i < pp1; i++)
10702  {
10703  int idx, s;
10704  if ((idx = dof_map[o++]) < 0)
10705  {
10706  idx = -1 - idx, s = -1;
10707  }
10708  else
10709  {
10710  s = +1;
10711  }
10712  shape(idx,0) = 0.;
10713  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
10714  shape(idx,2) = 0.;
10715  }
10716  // z-components
10717  for (int k = 0; k <= pp1; k++)
10718  for (int j = 0; j < pp1; j++)
10719  for (int i = 0; i < pp1; i++)
10720  {
10721  int idx, s;
10722  if ((idx = dof_map[o++]) < 0)
10723  {
10724  idx = -1 - idx, s = -1;
10725  }
10726  else
10727  {
10728  s = +1;
10729  }
10730  shape(idx,0) = 0.;
10731  shape(idx,1) = 0.;
10732  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
10733  }
10734 }
10735 
10737  Vector &divshape) const
10738 {
10739  const int pp1 = Order;
10740 
10741 #ifdef MFEM_THREAD_SAFE
10742  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10743  Vector shape_cz(pp1 + 1), shape_oz(pp1);
10744  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
10745 #endif
10746 
10747  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10748  obasis1d.Eval(ip.x, shape_ox);
10749  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10750  obasis1d.Eval(ip.y, shape_oy);
10751  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
10752  obasis1d.Eval(ip.z, shape_oz);
10753 
10754  int o = 0;
10755  // x-components
10756  for (int k = 0; k < pp1; k++)
10757  for (int j = 0; j < pp1; j++)
10758  for (int i = 0; i <= pp1; i++)
10759  {
10760  int idx, s;
10761  if ((idx = dof_map[o++]) < 0)
10762  {
10763  idx = -1 - idx, s = -1;
10764  }
10765  else
10766  {
10767  s = +1;
10768  }
10769  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
10770  }
10771  // y-components
10772  for (int k = 0; k < pp1; k++)
10773  for (int j = 0; j <= pp1; j++)
10774  for (int i = 0; i < pp1; i++)
10775  {
10776  int idx, s;
10777  if ((idx = dof_map[o++]) < 0)
10778  {
10779  idx = -1 - idx, s = -1;
10780  }
10781  else
10782  {
10783  s = +1;
10784  }
10785  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
10786  }
10787  // z-components
10788  for (int k = 0; k <= pp1; k++)
10789  for (int j = 0; j < pp1; j++)
10790  for (int i = 0; i < pp1; i++)
10791  {
10792  int idx, s;
10793  if ((idx = dof_map[o++]) < 0)
10794  {
10795  idx = -1 - idx, s = -1;
10796  }
10797  else
10798  {
10799  s = +1;
10800  }
10801  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
10802  }
10803 }
10804 
10805 
10806 const double RT_TriangleElement::nk[6] =
10807 { 0., -1., 1., 1., -1., 0. };
10808 
10809 const double RT_TriangleElement::c = 1./3.;
10810 
10812  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
10813  H_DIV, FunctionSpace::Pk),
10814  dof2nk(Dof)
10815 {
10816  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
10817  const double *bop = poly1d.OpenPoints(p);
10818 
10819 #ifndef MFEM_THREAD_SAFE
10820  shape_x.SetSize(p + 1);
10821  shape_y.SetSize(p + 1);
10822  shape_l.SetSize(p + 1);
10823  dshape_x.SetSize(p + 1);
10824  dshape_y.SetSize(p + 1);
10825  dshape_l.SetSize(p + 1);
10826  u.SetSize(Dof, Dim);
10827  divu.SetSize(Dof);
10828 #else
10829  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10830 #endif
10831 
10832  // edges
10833  int o = 0;
10834  for (int i = 0; i <= p; i++) // (0,1)
10835  {
10836  Nodes.IntPoint(o).Set2(bop[i], 0.);
10837  dof2nk[o++] = 0;
10838  }
10839  for (int i = 0; i <= p; i++) // (1,2)
10840  {
10841  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
10842  dof2nk[o++] = 1;
10843  }
10844  for (int i = 0; i <= p; i++) // (2,0)
10845  {
10846  Nodes.IntPoint(o).Set2(0., bop[p-i]);
10847  dof2nk[o++] = 2;
10848  }
10849 
10850  // interior
10851  for (int j = 0; j < p; j++)
10852  for (int i = 0; i + j < p; i++)
10853  {
10854  double w = iop[i] + iop[j] + iop[p-1-i-j];
10855  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
10856  dof2nk[o++] = 0;
10857  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
10858  dof2nk[o++] = 2;
10859  }
10860 
10861  DenseMatrix T(Dof);
10862  for (int k = 0; k < Dof; k++)
10863  {
10864  const IntegrationPoint &ip = Nodes.IntPoint(k);
10865  poly1d.CalcBasis(p, ip.x, shape_x);
10866  poly1d.CalcBasis(p, ip.y, shape_y);
10867  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
10868  const double *n_k = nk + 2*dof2nk[k];
10869 
10870  o = 0;
10871  for (int j = 0; j <= p; j++)
10872  for (int i = 0; i + j <= p; i++)
10873  {
10874  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
10875  T(o++, k) = s*n_k[0];
10876  T(o++, k) = s*n_k[1];
10877  }
10878  for (int i = 0; i <= p; i++)
10879  {
10880  double s = shape_x(i)*shape_y(p-i);
10881  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
10882  }
10883  }
10884 
10885  Ti.Factor(T);
10886  // mfem::out << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
10887 }
10888 
10890  DenseMatrix &shape) const
10891 {
10892  const int p = Order - 1;
10893 
10894 #ifdef MFEM_THREAD_SAFE
10895  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10896  DenseMatrix u(Dof, Dim);
10897 #endif
10898 
10899  poly1d.CalcBasis(p, ip.x, shape_x);
10900  poly1d.CalcBasis(p, ip.y, shape_y);
10901  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
10902 
10903  int o = 0;
10904  for (int j = 0; j <= p; j++)
10905  for (int i = 0; i + j <= p; i++)
10906  {
10907  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
10908  u(o,0) = s; u(o,1) = 0; o++;
10909  u(o,0) = 0; u(o,1) = s; o++;
10910  }
10911  for (int i = 0; i <= p; i++)
10912  {
10913  double s = shape_x(i)*shape_y(p-i);
10914  u(o,0) = (ip.x - c)*s;
10915  u(o,1) = (ip.y - c)*s;
10916  o++;
10917  }
10918 
10919  Ti.Mult(u, shape);
10920 }
10921 
10923  Vector &divshape) const
10924 {
10925  const int p = Order - 1;
10926 
10927 #ifdef MFEM_THREAD_SAFE
10928  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10929  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
10930  Vector divu(Dof);
10931 #endif
10932 
10933  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
10934  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
10935  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
10936 
10937  int o = 0;
10938  for (int j = 0; j <= p; j++)
10939  for (int i = 0; i + j <= p; i++)
10940  {
10941  int k = p - i - j;
10942  divu(o++) = (dshape_x(i)*shape_l(k) -
10943  shape_x(i)*dshape_l(k))*shape_y(j);
10944  divu(o++) = (dshape_y(j)*shape_l(k) -
10945  shape_y(j)*dshape_l(k))*shape_x(i);
10946  }
10947  for (int i = 0; i <= p; i++)
10948  {
10949  int j = p - i;
10950  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
10951  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
10952  }
10953 
10954  Ti.Mult(divu, divshape);
10955 }
10956 
10957 
10958 const double RT_TetrahedronElement::nk[12] =
10959 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
10960 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
10961 
10962 const double RT_TetrahedronElement::c = 1./4.;
10963 
10965  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
10966  p + 1, H_DIV, FunctionSpace::Pk),
10967  dof2nk(Dof)
10968 {
10969  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
10970  const double *bop = poly1d.OpenPoints(p);
10971 
10972 #ifndef MFEM_THREAD_SAFE
10973  shape_x.SetSize(p + 1);
10974  shape_y.SetSize(p + 1);
10975  shape_z.SetSize(p + 1);
10976  shape_l.SetSize(p + 1);
10977  dshape_x.SetSize(p + 1);
10978  dshape_y.SetSize(p + 1);
10979  dshape_z.SetSize(p + 1);
10980  dshape_l.SetSize(p + 1);
10981  u.SetSize(Dof, Dim);
10982  divu.SetSize(Dof);
10983 #else
10984  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10985 #endif
10986 
10987  int o = 0;
10988  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
10989  // the constructor of H1_TetrahedronElement)
10990  for (int j = 0; j <= p; j++)
10991  for (int i = 0; i + j <= p; i++) // (1,2,3)
10992  {
10993  double w = bop[i] + bop[j] + bop[p-i-j];
10994  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
10995  dof2nk[o++] = 0;
10996  }
10997  for (int j = 0; j <= p; j++)
10998  for (int i = 0; i + j <= p; i++) // (0,3,2)
10999  {
11000  double w = bop[i] + bop[j] + bop[p-i-j];
11001  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
11002  dof2nk[o++] = 1;
11003  }
11004  for (int j = 0; j <= p; j++)
11005  for (int i = 0; i + j <= p; i++) // (0,1,3)
11006  {
11007  double w = bop[i] + bop[j] + bop[p-i-j];
11008  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
11009  dof2nk[o++] = 2;
11010  }
11011  for (int j = 0; j <= p; j++)
11012  for (int i = 0; i + j <= p; i++) // (0,2,1)
11013  {
11014  double w = bop[i] + bop[j] + bop[p-i-j];
11015  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
11016  dof2nk[o++] = 3;
11017  }
11018 
11019  // interior
11020  for (int k = 0; k < p; k++)
11021  for (int j = 0; j + k < p; j++)
11022  for (int i = 0; i + j + k < p; i++)
11023  {
11024  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
11025  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11026  dof2nk[o++] = 1;
11027  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11028  dof2nk[o++] = 2;
11029  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11030  dof2nk[o++] = 3;
11031  }
11032 
11033  DenseMatrix T(Dof);
11034  for (int m = 0; m < Dof; m++)
11035  {
11036  const IntegrationPoint &ip = Nodes.IntPoint(m);
11037  poly1d.CalcBasis(p, ip.x, shape_x);
11038  poly1d.CalcBasis(p, ip.y, shape_y);
11039  poly1d.CalcBasis(p, ip.z, shape_z);
11040  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
11041  const double *nm = nk + 3*dof2nk[m];
11042 
11043  o = 0;
11044  for (int k = 0; k <= p; k++)
11045  for (int j = 0; j + k <= p; j++)
11046  for (int i = 0; i + j + k <= p; i++)
11047  {
11048  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
11049  T(o++, m) = s * nm[0];
11050  T(o++, m) = s * nm[1];
11051  T(o++, m) = s * nm[2];
11052  }
11053  for (int j = 0; j <= p; j++)
11054  for (int i = 0; i + j <= p; i++)
11055  {
11056  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
11057  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
11058  (ip.z - c)*nm[2]);
11059  }
11060  }
11061 
11062  Ti.Factor(T);
11063  // mfem::out << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
11064 }
11065 
11067  DenseMatrix &shape) const
11068 {
11069  const int p = Order - 1;
11070 
11071 #ifdef MFEM_THREAD_SAFE
11072  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
11073  DenseMatrix u(Dof, Dim);
11074 #endif
11075 
11076  poly1d.CalcBasis(p, ip.x, shape_x);
11077  poly1d.CalcBasis(p, ip.y, shape_y);
11078  poly1d.CalcBasis(p, ip.z, shape_z);
11079  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
11080 
11081  int o = 0;
11082  for (int k = 0; k <= p; k++)
11083  for (int j = 0; j + k <= p; j++)
11084  for (int i = 0; i + j + k <= p; i++)
11085  {
11086  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
11087  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
11088  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
11089  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
11090  }
11091  for (int j = 0; j <= p; j++)
11092  for (int i = 0; i + j <= p; i++)
11093  {
11094  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
11095  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
11096  o++;
11097  }
11098 
11099  Ti.Mult(u, shape);
11100 }
11101 
11103  Vector &divshape) const
11104 {
11105  const int p = Order - 1;
11106 
11107 #ifdef MFEM_THREAD_SAFE
11108  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
11109  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
11110  Vector divu(Dof);
11111 #endif
11112 
11113  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
11114  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
11115  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
11116  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
11117 
11118  int o = 0;
11119  for (int k = 0; k <= p; k++)
11120  for (int j = 0; j + k <= p; j++)
11121  for (int i = 0; i + j + k <= p; i++)
11122  {
11123  int l = p - i - j - k;
11124  divu(o++) = (dshape_x(i)*shape_l(l) -
11125  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
11126  divu(o++) = (dshape_y(j)*shape_l(l) -
11127  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
11128  divu(o++) = (dshape_z(k)*shape_l(l) -
11129  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
11130  }
11131  for (int j = 0; j <= p; j++)
11132  for (int i = 0; i + j <= p; i++)
11133  {
11134  int k = p - i - j;
11135  divu(o++) =
11136  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
11137  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
11138  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
11139  }
11140 
11141  Ti.Mult(divu, divshape);
11142 }
11143 
11144 
11145 const double ND_HexahedronElement::tk[18] =
11146 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
11147 
11149  const int cb_type, const int ob_type)
11150  : VectorTensorFiniteElement(3, 3*p*(p + 1)*(p + 1), p, cb_type, ob_type,
11151  H_CURL, DofMapType::L2_DOF_MAP),
11152  dof2tk(Dof)
11153 {
11154  dof_map.SetSize(Dof);
11155 
11156  const double *cp = poly1d.ClosedPoints(p, cb_type);
11157  const double *op = poly1d.OpenPoints(p - 1, ob_type);
11158  const int dof3 = Dof/3;
11159 
11160 #ifndef MFEM_THREAD_SAFE
11161  shape_cx.SetSize(p + 1);
11162  shape_ox.SetSize(p);
11163  shape_cy.SetSize(p + 1);
11164  shape_oy.SetSize(p);
11165  shape_cz.SetSize(p + 1);
11166  shape_oz.SetSize(p);
11167  dshape_cx.SetSize(p + 1);
11168  dshape_cy.SetSize(p + 1);
11169  dshape_cz.SetSize(p + 1);
11170 #endif
11171 
11172  // edges
11173  int o = 0;
11174  for (int i = 0; i < p; i++) // (0,1)
11175  {
11176  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
11177  }
11178  for (int i = 0; i < p; i++) // (1,2)
11179  {
11180  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
11181  }
11182  for (int i = 0; i < p; i++) // (3,2)
11183  {
11184  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
11185  }
11186  for (int i = 0; i < p; i++) // (0,3)
11187  {
11188  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
11189  }
11190  for (int i = 0; i < p; i++) // (4,5)
11191  {
11192  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
11193  }
11194  for (int i = 0; i < p; i++) // (5,6)
11195  {
11196  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
11197  }
11198  for (int i = 0; i < p; i++) // (7,6)
11199  {
11200  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
11201  }
11202  for (int i = 0; i < p; i++) // (4,7)
11203  {
11204  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
11205  }
11206  for (int i = 0; i < p; i++) // (0,4)
11207  {
11208  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
11209  }
11210  for (int i = 0; i < p; i++) // (1,5)
11211  {
11212  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
11213  }
11214  for (int i = 0; i < p; i++) // (2,6)
11215  {
11216  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
11217  }
11218  for (int i = 0; i < p; i++) // (3,7)
11219  {
11220  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
11221  }
11222 
11223  // faces
11224  // (3,2,1,0) -- bottom
11225  for (int j = 1; j < p; j++) // x - components
11226  for (int i = 0; i < p; i++)
11227  {
11228  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
11229  }
11230  for (int j = 0; j < p; j++) // y - components
11231  for (int i = 1; i < p; i++)
11232  {
11233  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
11234  }
11235  // (0,1,5,4) -- front
11236  for (int k = 1; k < p; k++) // x - components
11237  for (int i = 0; i < p; i++)
11238  {
11239  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
11240  }
11241  for (int k = 0; k < p; k++) // z - components
11242  for (int i = 1; i < p; i++ )
11243  {
11244  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
11245  }
11246  // (1,2,6,5) -- right
11247  for (int k = 1; k < p; k++) // y - components
11248  for (int j = 0; j < p; j++)
11249  {
11250  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
11251  }
11252  for (int k = 0; k < p; k++) // z - components
11253  for (int j = 1; j < p; j++)
11254  {
11255  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
11256  }
11257  // (2,3,7,6) -- back
11258  for (int k = 1; k < p; k++) // x - components
11259  for (int i = 0; i < p; i++)
11260  {
11261  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
11262  }
11263  for (int k = 0; k < p; k++) // z - components
11264  for (int i = 1; i < p; i++)
11265  {
11266  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
11267  }
11268  // (3,0,4,7) -- left
11269  for (int k = 1; k < p; k++) // y - components
11270  for (int j = 0; j < p; j++)
11271  {
11272  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
11273  }
11274  for (int k = 0; k < p; k++) // z - components
11275  for (int j = 1; j < p; j++)
11276  {
11277  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
11278  }
11279  // (4,5,6,7) -- top
11280  for (int j = 1; j < p; j++) // x - components
11281  for (int i = 0; i < p; i++)
11282  {
11283  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
11284  }
11285  for (int j = 0; j < p; j++) // y - components
11286  for (int i = 1; i < p; i++)
11287  {
11288  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
11289  }
11290 
11291  // interior
11292  // x-components
11293  for (int k = 1; k < p; k++)
11294  for (int j = 1; j < p; j++)
11295  for (int i = 0; i < p; i++)
11296  {
11297  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
11298  }
11299  // y-components
11300  for (int k = 1; k < p; k++)
11301  for (int j = 0; j < p; j++)
11302  for (int i = 1; i < p; i++)
11303  {
11304  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
11305  }
11306  // z-components
11307  for (int k = 0; k < p; k++)
11308  for (int j = 1; j < p; j++)
11309  for (int i = 1; i < p; i++)
11310  {
11311  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
11312  }
11313 
11314  // set dof2tk and Nodes
11315  o = 0;
11316  // x-components
11317  for (int k = 0; k <= p; k++)
11318  for (int j = 0; j <= p; j++)
11319  for (int i = 0; i < p; i++)
11320  {
11321  int idx;
11322  if ((idx = dof_map[o++]) < 0)
11323  {
11324  dof2tk[idx = -1 - idx] = 3;
11325  }
11326  else
11327  {
11328  dof2tk[idx] = 0;
11329  }
11330  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
11331  }
11332  // y-components
11333  for (int k = 0; k <= p; k++)
11334  for (int j = 0; j < p; j++)
11335  for (int i = 0; i <= p; i++)
11336  {
11337  int idx;
11338  if ((idx = dof_map[o++]) < 0)
11339  {
11340  dof2tk[idx = -1 - idx] = 4;
11341  }
11342  else
11343  {
11344  dof2tk[idx] = 1;
11345  }
11346  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
11347  }
11348  // z-components
11349  for (int k = 0; k < p; k++)
11350  for (int j = 0; j <= p; j++)
11351  for (int i = 0; i <= p; i++)
11352  {
11353  int idx;
11354  if ((idx = dof_map[o++]) < 0)
11355  {
11356  dof2tk[idx = -1 - idx] = 5;
11357  }
11358  else
11359  {
11360  dof2tk[idx] = 2;
11361  }
11362  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
11363  }
11364 }
11365 
11367  DenseMatrix &shape) const
11368 {
11369  const int p = Order;
11370 
11371 #ifdef MFEM_THREAD_SAFE
11372  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11373  Vector shape_cz(p + 1), shape_oz(p);
11374 #endif
11375 
11376  cbasis1d.Eval(ip.x, shape_cx);
11377  obasis1d.Eval(ip.x, shape_ox);
11378  cbasis1d.Eval(ip.y, shape_cy);
11379  obasis1d.Eval(ip.y, shape_oy);
11380  cbasis1d.Eval(ip.z, shape_cz);
11381  obasis1d.Eval(ip.z, shape_oz);
11382 
11383  int o = 0;
11384  // x-components
11385  for (int k = 0; k <= p; k++)
11386  for (int j = 0; j <= p; j++)
11387  for (int i = 0; i < p; i++)
11388  {
11389  int idx, s;
11390  if ((idx = dof_map[o++]) < 0)
11391  {
11392  idx = -1 - idx, s = -1;
11393  }
11394  else
11395  {
11396  s = +1;
11397  }
11398  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
11399  shape(idx,1) = 0.;
11400  shape(idx,2) = 0.;
11401  }
11402  // y-components
11403  for (int k = 0; k <= p; k++)
11404  for (int j = 0; j < p; j++)
11405  for (int i = 0; i <= p; i++)
11406  {
11407  int idx, s;
11408  if ((idx = dof_map[o++]) < 0)
11409  {
11410  idx = -1 - idx, s = -1;
11411  }
11412  else
11413  {
11414  s = +1;
11415  }
11416  shape(idx,0) = 0.;
11417  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
11418  shape(idx,2) = 0.;
11419  }
11420  // z-components
11421  for (int k = 0; k < p; k++)
11422  for (int j = 0; j <= p; j++)
11423  for (int i = 0; i <= p; i++)
11424  {
11425  int idx, s;
11426  if ((idx = dof_map[o++]) < 0)
11427  {
11428  idx = -1 - idx, s = -1;
11429  }
11430  else
11431  {
11432  s = +1;
11433  }
11434  shape(idx,0) = 0.;
11435  shape(idx,1) = 0.;
11436  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
11437  }
11438 }
11439 
11441  DenseMatrix &curl_shape) const
11442 {
11443  const int p = Order;
11444 
11445 #ifdef MFEM_THREAD_SAFE
11446  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11447  Vector shape_cz(p + 1), shape_oz(p);
11448  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
11449 #endif
11450 
11451  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11452  obasis1d.Eval(ip.x, shape_ox);
11453  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11454  obasis1d.Eval(ip.y, shape_oy);
11455  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
11456  obasis1d.Eval(ip.z, shape_oz);
11457 
11458  int o = 0;
11459  // x-components
11460  for (int k = 0; k <= p; k++)
11461  for (int j = 0; j <= p; j++)
11462  for (int i = 0; i < p; i++)
11463  {
11464  int idx, s;
11465  if ((idx = dof_map[o++]) < 0)
11466  {
11467  idx = -1 - idx, s = -1;
11468  }
11469  else
11470  {
11471  s = +1;
11472  }
11473  curl_shape(idx,0) = 0.;
11474  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
11475  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
11476  }
11477  // y-components
11478  for (int k = 0; k <= p; k++)
11479  for (int j = 0; j < p; j++)
11480  for (int i = 0; i <= p; i++)
11481  {
11482  int idx, s;
11483  if ((idx = dof_map[o++]) < 0)
11484  {
11485  idx = -1 - idx, s = -1;
11486  }
11487  else
11488  {
11489  s = +1;
11490  }
11491  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
11492  curl_shape(idx,1) = 0.;
11493  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
11494  }
11495  // z-components
11496  for (int k = 0; k < p; k++)
11497  for (int j = 0; j <= p; j++)
11498  for (int i = 0; i <= p; i++)
11499  {
11500  int idx, s;
11501  if ((idx = dof_map[o++]) < 0)
11502  {
11503  idx = -1 - idx, s = -1;
11504  }
11505  else
11506  {
11507  s = +1;
11508  }
11509  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
11510  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
11511  curl_shape(idx,2) = 0.;
11512  }
11513 }
11514 
11516  const IntegrationRule &ir,
11517  DofToQuad::Mode mode) const
11518 {
11519  MFEM_VERIFY(mode != DofToQuad::FULL, "invalid mode requested");
11520 
11521  return GetTensorDofToQuad(ir, mode, true);
11522 }
11523 
11525  const IntegrationRule &ir,
11526  DofToQuad::Mode mode) const
11527 {
11528  MFEM_VERIFY(mode != DofToQuad::FULL, "invalid mode requested");
11529 
11530  return GetTensorDofToQuad(ir, mode, false);
11531 }
11532 
11534  const IntegrationRule &ir,
11535  DofToQuad::Mode mode,
11536  const bool closed) const
11537 {
11538  MFEM_VERIFY(mode == DofToQuad::TENSOR, "invalid mode requested");
11539 
11540  for (int i = 0; i < closed ? dof2quad_array.Size() : dof2quad_array_open.Size();
11541  i++)
11542  {
11543  const DofToQuad &d2q = closed ? *dof2quad_array[i] : *dof2quad_array_open[i];
11544  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
11545  }
11546 
11547  DofToQuad *d2q = new DofToQuad;
11548  const int ndof = closed ? Order + 1 : Order;
11549  const int nqpt = (int)floor(pow(ir.GetNPoints(), 1.0/Dim) + 0.5);
11550  d2q->FE = this;
11551  d2q->IntRule = &ir;
11552  d2q->mode = mode;
11553  d2q->ndof = ndof;
11554  d2q->nqpt = nqpt;
11555  d2q->B.SetSize(nqpt*ndof);
11556  d2q->Bt.SetSize(ndof*nqpt);
11557  d2q->G.SetSize(nqpt*ndof);
11558  d2q->Gt.SetSize(ndof*nqpt);
11559  Vector val(ndof), grad(ndof);
11560  for (int i = 0; i < nqpt; i++)
11561  {
11562  // The first 'nqpt' points in 'ir' have the same x-coordinates as those
11563  // of the 1D rule.
11564 
11565  if (closed)
11566  {
11567  cbasis1d.Eval(ir.IntPoint(i).x, val, grad);
11568  }
11569  else
11570  {
11571  obasis1d.Eval(ir.IntPoint(i).x, val, grad);
11572  }
11573 
11574  for (int j = 0; j < ndof; j++)
11575  {
11576  d2q->B[i+nqpt*j] = d2q->Bt[j+ndof*i] = val(j);
11577  d2q->G[i+nqpt*j] = d2q->Gt[j+ndof*i] = grad(j);
11578  }
11579  }
11580 
11581  if (closed)
11582  {
11583  dof2quad_array.Append(d2q);
11584  }
11585  else
11586  {
11587  dof2quad_array_open.Append(d2q);
11588  }
11589 
11590  return *d2q;
11591 }
11592 
11593 const double ND_QuadrilateralElement::tk[8] =
11594 { 1.,0., 0.,1., -1.,0., 0.,-1. };
11595 
11597  const int cb_type,
11598  const int ob_type)
11599  : VectorTensorFiniteElement(2, 2*p*(p + 1), p, cb_type, ob_type,
11600  H_CURL, DofMapType::L2_DOF_MAP),
11601  dof2tk(Dof)
11602 {
11603  dof_map.SetSize(Dof);
11604 
11605  const double *cp = poly1d.ClosedPoints(p, cb_type);
11606  const double *op = poly1d.OpenPoints(p - 1, ob_type);
11607  const int dof2 = Dof/2;
11608 
11609 #ifndef MFEM_THREAD_SAFE
11610  shape_cx.SetSize(p + 1);
11611  shape_ox.SetSize(p);
11612  shape_cy.SetSize(p + 1);
11613  shape_oy.SetSize(p);
11614  dshape_cx.SetSize(p + 1);
11615  dshape_cy.SetSize(p + 1);
11616 #endif
11617 
11618  // edges
11619  int o = 0;
11620  for (int i = 0; i < p; i++) // (0,1)
11621  {
11622  dof_map[0*dof2 + i + 0*p] = o++;
11623  }
11624  for (int j = 0; j < p; j++) // (1,2)
11625  {
11626  dof_map[1*dof2 + p + j*(p + 1)] = o++;
11627  }
11628  for (int i = 0; i < p; i++) // (2,3)
11629  {
11630  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
11631  }
11632  for (int j = 0; j < p; j++) // (3,0)
11633  {
11634  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
11635  }
11636 
11637  // interior
11638  // x-components
11639  for (int j = 1; j < p; j++)
11640  for (int i = 0; i < p; i++)
11641  {
11642  dof_map[0*dof2 + i + j*p] = o++;
11643  }
11644  // y-components
11645  for (int j = 0; j < p; j++)
11646  for (int i = 1; i < p; i++)
11647  {
11648  dof_map[1*dof2 + i + j*(p + 1)] = o++;
11649  }
11650 
11651  // set dof2tk and Nodes
11652  o = 0;
11653  // x-components
11654  for (int j = 0; j <= p; j++)
11655  for (int i = 0; i < p; i++)
11656  {
11657  int idx;
11658  if ((idx = dof_map[o++]) < 0)
11659  {
11660  dof2tk[idx = -1 - idx] = 2;
11661  }
11662  else
11663  {
11664  dof2tk[idx] = 0;
11665  }
11666  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
11667  }
11668  // y-components
11669  for (int j = 0; j < p; j++)
11670  for (int i = 0; i <= p; i++)
11671  {
11672  int idx;
11673  if ((idx = dof_map[o++]) < 0)
11674  {
11675  dof2tk[idx = -1 - idx] = 3;
11676  }
11677  else
11678  {
11679  dof2tk[idx] = 1;
11680  }
11681  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
11682  }
11683 }
11684 
11686  DenseMatrix &shape) const
11687 {
11688  const int p = Order;
11689 
11690 #ifdef MFEM_THREAD_SAFE
11691  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11692 #endif
11693 
11694  cbasis1d.Eval(ip.x, shape_cx);
11695  obasis1d.Eval(ip.x, shape_ox);
11696  cbasis1d.Eval(ip.y, shape_cy);
11697  obasis1d.Eval(ip.y, shape_oy);
11698 
11699  int o = 0;
11700  // x-components
11701  for (int j = 0; j <= p; j++)
11702  for (int i = 0; i < p; i++)
11703  {
11704  int idx, s;
11705  if ((idx = dof_map[o++]) < 0)
11706  {
11707  idx = -1 - idx, s = -1;
11708  }
11709  else
11710  {
11711  s = +1;
11712  }
11713  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
11714  shape(idx,1) = 0.;
11715  }
11716  // y-components
11717  for (int j = 0; j < p; j++)
11718  for (int i = 0; i <= p; i++)
11719  {
11720  int idx, s;
11721  if ((idx = dof_map[o++]) < 0)
11722  {
11723  idx = -1 - idx, s = -1;
11724  }
11725  else
11726  {
11727  s = +1;
11728  }
11729  shape(idx,0) = 0.;
11730  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
11731  }
11732 }
11733 
11735  DenseMatrix &curl_shape) const
11736 {
11737  const int p = Order;
11738 
11739 #ifdef MFEM_THREAD_SAFE
11740  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11741  Vector dshape_cx(p + 1), dshape_cy(p + 1);
11742 #endif
11743 
11744  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11745  obasis1d.Eval(ip.x, shape_ox);
11746  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11747  obasis1d.Eval(ip.y, shape_oy);
11748 
11749  int o = 0;
11750  // x-components
11751  for (int j = 0; j <= p; j++)
11752  for (int i = 0; i < p; i++)
11753  {
11754  int idx, s;
11755  if ((idx = dof_map[o++]) < 0)
11756  {
11757  idx = -1 - idx, s = -1;
11758  }
11759  else
11760  {
11761  s = +1;
11762  }
11763  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
11764  }
11765  // y-components
11766  for (int j = 0; j < p; j++)
11767  for (int i = 0; i <= p; i++)
11768  {
11769  int idx, s;
11770  if ((idx = dof_map[o++]) < 0)
11771  {
11772  idx = -1 - idx, s = -1;
11773  }
11774  else
11775  {
11776  s = +1;
11777  }
11778  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
11779  }
11780 }
11781 
11782 
11783 const double ND_TetrahedronElement::tk[18] =
11784 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
11785 
11786 const double ND_TetrahedronElement::c = 1./4.;
11787 
11789  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
11790  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
11791 {
11792  const double *eop = poly1d.OpenPoints(p - 1);
11793  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
11794  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
11795 
11796  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
11797 
11798 #ifndef MFEM_THREAD_SAFE
11799  shape_x.SetSize(p);
11800  shape_y.SetSize(p);
11801  shape_z.SetSize(p);
11802  shape_l.SetSize(p);
11803  dshape_x.SetSize(p);
11804  dshape_y.SetSize(p);
11805  dshape_z.SetSize(p);
11806  dshape_l.SetSize(p);
11807  u.SetSize(Dof, Dim);
11808 #else
11809  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
11810 #endif
11811 
11812  int o = 0;
11813  // edges
11814  for (int i = 0; i < p; i++) // (0,1)
11815  {
11816  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
11817  dof2tk[o++] = 0;
11818  }
11819  for (int i = 0; i < p; i++) // (0,2)
11820  {
11821  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
11822  dof2tk[o++] = 1;
11823  }
11824  for (int i = 0; i < p; i++) // (0,3)
11825  {
11826  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
11827  dof2tk[o++] = 2;
11828  }
11829  for (int i = 0; i < p; i++) // (1,2)
11830  {
11831  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
11832  dof2tk[o++] = 3;
11833  }
11834  for (int i = 0; i < p; i++) // (1,3)
11835  {
11836  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
11837  dof2tk[o++] = 4;
11838  }
11839  for (int i = 0; i < p; i++) // (2,3)
11840  {
11841  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
11842  dof2tk[o++] = 5;
11843  }
11844 
11845  // faces
11846  for (int j = 0; j <= pm2; j++) // (1,2,3)
11847  for (int i = 0; i + j <= pm2; i++)
11848  {
11849  double w = fop[i] + fop[j] + fop[pm2-i-j];
11850  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
11851  dof2tk[o++] = 3;
11852  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
11853  dof2tk[o++] = 4;
11854  }
11855  for (int j = 0; j <= pm2; j++) // (0,3,2)
11856  for (int i = 0; i + j <= pm2; i++)
11857  {
11858  double w = fop[i] + fop[j] + fop[pm2-i-j];
11859  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
11860  dof2tk[o++] = 2;
11861  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
11862  dof2tk[o++] = 1;
11863  }
11864  for (int j = 0; j <= pm2; j++) // (0,1,3)
11865  for (int i = 0; i + j <= pm2; i++)
11866  {
11867  double w = fop[i] + fop[j] + fop[pm2-i-j];
11868  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
11869  dof2tk[o++] = 0;
11870  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
11871  dof2tk[o++] = 2;
11872  }
11873  for (int j = 0; j <= pm2; j++) // (0,2,1)
11874  for (int i = 0; i + j <= pm2; i++)
11875  {
11876  double w = fop[i] + fop[j] + fop[pm2-i-j];
11877  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
11878  dof2tk[o++] = 1;
11879  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
11880  dof2tk[o++] = 0;
11881  }
11882 
11883  // interior
11884  for (int k = 0; k <= pm3; k++)
11885  for (int j = 0; j + k <= pm3; j++)
11886  for (int i = 0; i + j + k <= pm3; i++)
11887  {
11888  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
11889  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11890  dof2tk[o++] = 0;
11891  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11892  dof2tk[o++] = 1;
11893  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11894  dof2tk[o++] = 2;
11895  }
11896 
11897  DenseMatrix T(Dof);
11898  for (int m = 0; m < Dof; m++)
11899  {
11900  const IntegrationPoint &ip = Nodes.IntPoint(m);
11901  const double *tm = tk + 3*dof2tk[m];
11902  o = 0;
11903 
11904  poly1d.CalcBasis(pm1, ip.x, shape_x);
11905  poly1d.CalcBasis(pm1, ip.y, shape_y);
11906  poly1d.CalcBasis(pm1, ip.z, shape_z);
11907  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
11908 
11909  for (int k = 0; k <= pm1; k++)
11910  for (int j = 0; j + k <= pm1; j++)
11911  for (int i = 0; i + j + k <= pm1; i++)
11912  {
11913  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
11914  T(o++, m) = s * tm[0];
11915  T(o++, m) = s * tm[1];
11916  T(o++, m) = s * tm[2];
11917  }
11918  for (int k = 0; k <= pm1; k++)
11919  for (int j = 0; j + k <= pm1; j++)
11920  {
11921  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
11922  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
11923  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
11924  }
11925  for (int k = 0; k <= pm1; k++)
11926  {
11927  T(o++, m) =
11928  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
11929  }
11930  }
11931 
11932  Ti.Factor(T);
11933  // mfem::out << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
11934 }
11935 
11937  DenseMatrix &shape) const
11938 {
11939  const int pm1 = Order - 1;
11940 
11941 #ifdef MFEM_THREAD_SAFE
11942  const int p = Order;
11943  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
11944  DenseMatrix u(Dof, Dim);
11945 #endif
11946 
11947  poly1d.CalcBasis(pm1, ip.x, shape_x);
11948  poly1d.CalcBasis(pm1, ip.y, shape_y);
11949  poly1d.CalcBasis(pm1, ip.z, shape_z);
11950  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
11951 
11952  int n = 0;
11953  for (int k = 0; k <= pm1; k++)
11954  for (int j = 0; j + k <= pm1; j++)
11955  for (int i = 0; i + j + k <= pm1; i++)
11956  {
11957  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
11958  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
11959  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
11960  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
11961  }
11962  for (int k = 0; k <= pm1; k++)
11963  for (int j = 0; j + k <= pm1; j++)
11964  {
11965  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
11966  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
11967  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
11968  }
11969  for (int k = 0; k <= pm1; k++)
11970  {
11971  double s = shape_y(pm1-k)*shape_z(k);
11972  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
11973  }
11974 
11975  Ti.Mult(u, shape);
11976 }
11977 
11979  DenseMatrix &curl_shape) const
11980 {
11981  const int pm1 = Order - 1;
11982 
11983 #ifdef MFEM_THREAD_SAFE
11984  const int p = Order;
11985  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
11986  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
11987  DenseMatrix u(Dof, Dim);
11988 #endif
11989 
11990  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
11991  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
11992  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
11993  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
11994 
11995  int n = 0;
11996  for (int k = 0; k <= pm1; k++)
11997  for (int j = 0; j + k <= pm1; j++)
11998  for (int i = 0; i + j + k <= pm1; i++)
11999  {
12000  int l = pm1-i-j-k;
12001  const double dx = (dshape_x(i)*shape_l(l) -
12002  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
12003  const double dy = (dshape_y(j)*shape_l(l) -
12004  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
12005  const double dz = (dshape_z(k)*shape_l(l) -
12006  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
12007 
12008  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
12009  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
12010  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
12011  }
12012  for (int k = 0; k <= pm1; k++)
12013  for (int j = 0; j + k <= pm1; j++)
12014  {
12015  int i = pm1 - j - k;
12016  // s = shape_x(i)*shape_y(j)*shape_z(k);
12017  // curl of s*(ip.y - c, -(ip.x - c), 0):
12018  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
12019  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
12020  u(n,2) =
12021  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
12022  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
12023  n++;
12024  // curl of s*(ip.z - c, 0, -(ip.x - c)):
12025  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
12026  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
12027  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
12028  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
12029  n++;
12030  }
12031  for (int k = 0; k <= pm1; k++)
12032  {
12033  int j = pm1 - k;
12034  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
12035  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
12036  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
12037  u(n,1) = 0.;
12038  u(n,2) = 0.; n++;
12039  }
12040 
12041  Ti.Mult(u, curl_shape);
12042 }
12043 
12044 
12045 const double ND_TriangleElement::tk[8] =
12046 { 1.,0., -1.,1., 0.,-1., 0.,1. };
12047 
12048 const double ND_TriangleElement::c = 1./3.;
12049 
12051  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
12052  H_CURL, FunctionSpace::Pk),
12053  dof2tk(Dof)
12054 {
12055  const double *eop = poly1d.OpenPoints(p - 1);
12056  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
12057 
12058  const int pm1 = p - 1, pm2 = p - 2;
12059 
12060 #ifndef MFEM_THREAD_SAFE
12061  shape_x.SetSize(p);
12062  shape_y.SetSize(p);
12063  shape_l.SetSize(p);
12064  dshape_x.SetSize(p);
12065  dshape_y.SetSize(p);
12066  dshape_l.SetSize(p);
12067  u.SetSize(Dof, Dim);
12068  curlu.SetSize(Dof);
12069 #else
12070  Vector shape_x(p), shape_y(p), shape_l(p);
12071 #endif
12072 
12073  int n = 0;
12074  // edges
12075  for (int i = 0; i < p; i++) // (0,1)
12076  {
12077  Nodes.IntPoint(n).Set2(eop[i], 0.);
12078  dof2tk[n++] = 0;
12079  }
12080  for (int i = 0; i < p; i++) // (1,2)
12081  {
12082  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
12083  dof2tk[n++] = 1;
12084  }
12085  for (int i = 0; i < p; i++) // (2,0)
12086  {
12087  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
12088  dof2tk[n++] = 2;
12089  }
12090 
12091  // interior
12092  for (int j = 0; j <= pm2; j++)
12093  for (int i = 0; i + j <= pm2; i++)
12094  {
12095  double w = iop[i] + iop[j] + iop[pm2-i-j];
12096  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
12097  dof2tk[n++] = 0;
12098  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
12099  dof2tk[n++] = 3;
12100  }
12101 
12102  DenseMatrix T(Dof);
12103  for (int m = 0; m < Dof; m++)
12104  {
12105  const IntegrationPoint &ip = Nodes.IntPoint(m);
12106  const double *tm = tk + 2*dof2tk[m];
12107  n = 0;
12108 
12109  poly1d.CalcBasis(pm1, ip.x, shape_x);
12110  poly1d.CalcBasis(pm1, ip.y, shape_y);
12111  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
12112 
12113  for (int j = 0; j <= pm1; j++)
12114  for (int i = 0; i + j <= pm1; i++)
12115  {
12116  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
12117  T(n++, m) = s * tm[0];
12118  T(n++, m) = s * tm[1];
12119  }
12120  for (int j = 0; j <= pm1; j++)
12121  {
12122  T(n++, m) =
12123  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
12124  }
12125  }
12126 
12127  Ti.Factor(T);
12128  // mfem::out << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
12129 }
12130 
12132  DenseMatrix &shape) const
12133 {
12134  const int pm1 = Order - 1;
12135 
12136 #ifdef MFEM_THREAD_SAFE
12137  const int p = Order;
12138  Vector shape_x(p), shape_y(p), shape_l(p);
12139  DenseMatrix u(Dof, Dim);
12140 #endif
12141 
12142  poly1d.CalcBasis(pm1, ip.x, shape_x);
12143  poly1d.CalcBasis(pm1, ip.y, shape_y);
12144  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
12145 
12146  int n = 0;
12147  for (int j = 0; j <= pm1; j++)
12148  for (int i = 0; i + j <= pm1; i++)
12149  {
12150  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
12151  u(n,0) = s; u(n,1) = 0; n++;
12152  u(n,0) = 0; u(n,1) = s; n++;
12153  }
12154  for (int j = 0; j <= pm1; j++)
12155  {
12156  double s = shape_x(pm1-j)*shape_y(j);
12157  u(n,0) = s*(ip.y - c);
12158  u(n,1) = -s*(ip.x - c);
12159  n++;
12160  }
12161 
12162  Ti.Mult(u, shape);
12163 }
12164 
12166  DenseMatrix &curl_shape) const
12167 {
12168  const int pm1 = Order - 1;
12169 
12170 #ifdef MFEM_THREAD_SAFE
12171  const int p = Order;
12172  Vector shape_x(p), shape_y(p), shape_l(p);
12173  Vector dshape_x(p), dshape_y(p), dshape_l(p);
12174  Vector curlu(Dof);
12175 #endif
12176 
12177  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
12178  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
12179  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
12180 
12181  int n = 0;
12182  for (int j = 0; j <= pm1; j++)
12183  for (int i = 0; i + j <= pm1; i++)
12184  {
12185  int l = pm1-i-j;
12186  const double dx = (dshape_x(i)*shape_l(l) -
12187  shape_x(i)*dshape_l(l)) * shape_y(j);
12188  const double dy = (dshape_y(j)*shape_l(l) -
12189  shape_y(j)*dshape_l(l)) * shape_x(i);
12190 
12191  curlu(n++) = -dy;
12192  curlu(n++) = dx;
12193  }
12194 
12195  for (int j = 0; j <= pm1; j++)
12196  {
12197  int i = pm1 - j;
12198  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
12199  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
12200  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
12201  }
12202 
12203  Vector curl2d(curl_shape.Data(),Dof);
12204  Ti.Mult(curlu, curl2d);
12205 }
12206 
12207 
12208 const double ND_SegmentElement::tk[1] = { 1. };
12209 
12210 ND_SegmentElement::ND_SegmentElement(const int p, const int ob_type)
12211  : VectorFiniteElement(1, Geometry::SEGMENT, p, p - 1,
12212  H_CURL, FunctionSpace::Pk),
12213  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(ob_type))),
12214  dof2tk(Dof)
12215 {
12216  const double *op = poly1d.OpenPoints(p - 1, ob_type);
12217 
12218  // set dof2tk and Nodes
12219  for (int i = 0; i < p; i++)
12220  {
12221  dof2tk[i] = 0;
12222  Nodes.IntPoint(i).x = op[i];
12223  }
12224 }
12225 
12227  DenseMatrix &shape) const
12228 {
12229  Vector vshape(shape.Data(), Dof);
12230 
12231  obasis1d.Eval(ip.x, vshape);
12232 }
12233 
12235 {
12236  Order = kv[0]->GetOrder();
12237  Dof = Order + 1;
12238 
12239  weights.SetSize(Dof);
12240  shape_x.SetSize(Dof);
12241 }
12242 
12244  Vector &shape) const
12245 {
12246  kv[0]->CalcShape(shape, ijk[0], ip.x);
12247 
12248  double sum = 0.0;
12249  for (int i = 0; i <= Order; i++)
12250  {
12251  sum += (shape(i) *= weights(i));
12252  }
12253 
12254  shape /= sum;
12255 }
12256 
12258  DenseMatrix &dshape) const
12259 {
12260  Vector grad(dshape.Data(), Dof);
12261 
12262  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
12263  kv[0]->CalcDShape(grad, ijk[0], ip.x);
12264 
12265  double sum = 0.0, dsum = 0.0;
12266  for (int i = 0; i <= Order; i++)
12267  {
12268  sum += (shape_x(i) *= weights(i));
12269  dsum += ( grad(i) *= weights(i));
12270  }
12271 
12272  sum = 1.0/sum;
12273  add(sum, grad, -dsum*sum*sum, shape_x, grad);
12274 }
12275 
12277  DenseMatrix &hessian) const
12278 {
12279  Vector grad(Dof);
12280  Vector hess(hessian.Data(), Dof);
12281 
12282  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
12283  kv[0]->CalcDShape(grad, ijk[0], ip.x);
12284  kv[0]->CalcD2Shape(hess, ijk[0], ip.x);
12285 
12286  double sum = 0.0, dsum = 0.0, d2sum = 0.0;
12287  for (int i = 0; i <= Order; i++)
12288  {
12289  sum += (shape_x(i) *= weights(i));
12290  dsum += ( grad(i) *= weights(i));
12291  d2sum += ( hess(i) *= weights(i));
12292  }
12293 
12294  sum = 1.0/sum;
12295  add(sum, hess, -2*dsum*sum*sum, grad, hess);
12296  add(1.0, hess, (-d2sum + 2*dsum*dsum*sum)*sum*sum, shape_x, hess);
12297 }
12298 
12299 
12301 {
12302  Orders[0] = kv[0]->GetOrder();
12303  Orders[1] = kv[1]->GetOrder();
12304  shape_x.SetSize(Orders[0]+1);
12305  shape_y.SetSize(Orders[1]+1);
12306  dshape_x.SetSize(Orders[0]+1);
12307  dshape_y.SetSize(Orders[1]+1);
12308  d2shape_x.SetSize(Orders[0]+1);
12309  d2shape_y.SetSize(Orders[1]+1);
12310 
12311  Order = max(Orders[0], Orders[1]);
12312  Dof = (Orders[0] + 1)*(Orders[1] + 1);
12313  u.SetSize(Dof);
12314  du.SetSize(Dof);
12315  weights.SetSize(Dof);
12316 }
12317 
12319  Vector &shape) const
12320 {
12321  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
12322  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
12323 
12324  double sum = 0.0;
12325  for (int o = 0, j = 0; j <= Orders[1]; j++)
12326  {
12327  const double sy = shape_y(j);
12328  for (int i = 0; i <= Orders[0]; i++, o++)
12329  {
12330  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
12331  }
12332  }
12333 
12334  shape /= sum;
12335 }
12336 
12338  DenseMatrix &dshape) const
12339 {
12340  double sum, dsum[2];
12341 
12342  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
12343  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
12344 
12345  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
12346  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
12347 
12348  sum = dsum[0] = dsum[1] = 0.0;
12349  for (int o = 0, j = 0; j <= Orders[1]; j++)
12350  {
12351  const double sy = shape_y(j), dsy = dshape_y(j);
12352  for (int i = 0; i <= Orders[0]; i++, o++)
12353  {
12354  sum += ( u(o) = shape_x(i)*sy*weights(o) );
12355 
12356  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
12357  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
12358  }
12359  }
12360 
12361  sum = 1.0/sum;
12362  dsum[0] *= sum*sum;
12363  dsum[1] *= sum*sum;
12364 
12365  for (int o = 0; o < Dof; o++)
12366  {
12367  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
12368  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
12369  }
12370 }
12371 
12373  DenseMatrix &hessian) const
12374 {
12375  double sum, dsum[2], d2sum[3];
12376 
12377  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
12378  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
12379 
12380  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
12381  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
12382 
12383  kv[0]->CalcD2Shape(d2shape_x, ijk[0], ip.x);
12384  kv[1]->CalcD2Shape(d2shape_y, ijk[1], ip.y);
12385 
12386  sum = dsum[0] = dsum[1] = 0.0;
12387  d2sum[0] = d2sum[1] = d2sum[2] = 0.0;
12388  for (int o = 0, j = 0; j <= Orders[1]; j++)
12389  {
12390  const double sy = shape_y(j), dsy = dshape_y(j), d2sy = d2shape_y(j);
12391  for (int i = 0; i <= Orders[0]; i++, o++)
12392  {
12393  const double sx = shape_x(i), dsx = dshape_x(i), d2sx = d2shape_x(i);
12394  sum += ( u(o) = sx*sy*weights(o) );
12395 
12396  dsum[0] += ( du(o,0) = dsx*sy*weights(o) );
12397  dsum[1] += ( du(o,1) = sx*dsy*weights(o) );
12398 
12399  d2sum[0] += ( hessian(o,0) = d2sx*sy*weights(o) );
12400  d2sum[1] += ( hessian(o,1) = dsx*dsy*weights(o) );
12401  d2sum[2] += ( hessian(o,2) = sx*d2sy*weights(o) );
12402  }
12403  }
12404 
12405  sum = 1.0/sum;
12406  dsum[0] *= sum;
12407  dsum[1] *= sum;
12408 
12409  d2sum[0] *= sum;
12410  d2sum[1] *= sum;
12411  d2sum[2] *= sum;
12412 
12413  for (int o = 0; o < Dof; o++)
12414  {
12415  hessian(o,0) = hessian(o,0)*sum
12416  - 2*du(o,0)*sum*dsum[0]
12417  + u[o]*sum*(2*dsum[0]*dsum[0] - d2sum[0]);
12418 
12419  hessian(o,1) = hessian(o,1)*sum
12420  - du(o,0)*sum*dsum[1]
12421  - du(o,1)*sum*dsum[0]
12422  + u[o]*sum*(2*dsum[0]*dsum[1] - d2sum[1]);
12423 
12424  hessian(o,2) = hessian(o,2)*sum
12425  - 2*du(o,1)*sum*dsum[1]
12426  + u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[2]);
12427  }
12428 }
12429 
12430 
12432 {
12433  Orders[0] = kv[0]->GetOrder();
12434  Orders[1] = kv[1]->GetOrder();
12435  Orders[2] = kv[2]->GetOrder();
12436  shape_x.SetSize(Orders[0]+1);
12437  shape_y.SetSize(Orders[1]+1);
12438  shape_z.SetSize(Orders[2]+1);
12439 
12440  dshape_x.SetSize(Orders[0]+1);
12441  dshape_y.SetSize(Orders[1]+1);
12442  dshape_z.SetSize(Orders[2]+1);
12443 
12444  d2shape_x.SetSize(Orders[0]+1);
12445  d2shape_y.SetSize(Orders[1]+1);
12446  d2shape_z.SetSize(Orders[2]+1);
12447 
12448  Order = max(max(Orders[0], Orders[1]), Orders[2]);
12449  Dof = (Orders[0] + 1)*(Orders[1] + 1)*(Orders[2] + 1);
12450  u.SetSize(Dof);
12451  du.SetSize(Dof);
12452  weights.SetSize(Dof);
12453 }
12454 
12456  Vector &shape) const
12457 {
12458  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
12459  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
12460  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
12461 
12462  double sum = 0.0;
12463  for (int o = 0, k = 0; k <= Orders[2]; k++)
12464  {
12465  const double sz = shape_z(k);
12466  for (int j = 0; j <= Orders[1]; j++)
12467  {
12468  const double sy_sz = shape_y(j)*sz;
12469  for (int i = 0; i <= Orders[0]; i++, o++)
12470  {
12471  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
12472  }
12473  }
12474  }
12475 
12476  shape /= sum;
12477 }
12478 
12480  DenseMatrix &dshape) const
12481 {
12482  double sum, dsum[3];
12483 
12484  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
12485  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
12486  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
12487 
12488  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
12489  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
12490  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
12491 
12492  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
12493  for (int o = 0, k = 0; k <= Orders[2]; k++)
12494  {
12495  const double sz = shape_z(k), dsz = dshape_z(k);
12496  for (int j = 0; j <= Orders[1]; j++)
12497  {
12498  const double sy_sz = shape_y(j)* sz;
12499  const double dsy_sz = dshape_y(j)* sz;
12500  const double sy_dsz = shape_y(j)*dsz;
12501  for (int i = 0; i <= Orders[0]; i++, o++)
12502  {
12503  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
12504 
12505  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
12506  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
12507  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
12508  }
12509  }
12510  }
12511 
12512  sum = 1.0/sum;
12513  dsum[0] *= sum*sum;
12514  dsum[1] *= sum*sum;
12515  dsum[2] *= sum*sum;
12516 
12517  for (int o = 0; o < Dof; o++)
12518  {
12519  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
12520  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
12521  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
12522  }
12523 }
12524 
12526  DenseMatrix &hessian) const
12527 {
12528  double sum, dsum[3], d2sum[6];
12529 
12530  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
12531  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
12532  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
12533 
12534  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
12535  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
12536  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
12537 
12538  kv[0]->CalcD2Shape(d2shape_x, ijk[0], ip.x);
12539  kv[1]->CalcD2Shape(d2shape_y, ijk[1], ip.y);
12540  kv[2]->CalcD2Shape(d2shape_z, ijk[2], ip.z);
12541 
12542  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
12543  d2sum[0] = d2sum[1] = d2sum[2] = d2sum[3] = d2sum[4] = d2sum[5] = 0.0;
12544 
12545  for (int o = 0, k = 0; k <= Orders[2]; k++)
12546  {
12547  const double sz = shape_z(k), dsz = dshape_z(k), d2sz = d2shape_z(k);
12548  for (int j = 0; j <= Orders[1]; j++)
12549  {
12550  const double sy = shape_y(j), dsy = dshape_y(j), d2sy = d2shape_y(j);
12551  for (int i = 0; i <= Orders[0]; i++, o++)
12552  {
12553  const double sx = shape_x(i), dsx = dshape_x(i), d2sx = d2shape_x(i);
12554  sum += ( u(o) = sx*sy*sz*weights(o) );
12555 
12556  dsum[0] += ( du(o,0) = dsx*sy*sz*weights(o) );
12557  dsum[1] += ( du(o,1) = sx*dsy*sz*weights(o) );
12558  dsum[2] += ( du(o,2) = sx*sy*dsz*weights(o) );
12559 
12560  d2sum[0] += ( hessian(o,0) = d2sx*sy*sz*weights(o) );
12561  d2sum[1] += ( hessian(o,1) = dsx*dsy*sz*weights(o) );
12562  d2sum[2] += ( hessian(o,2) = dsx*sy*dsz*weights(o) );
12563 
12564  d2sum[3] += ( hessian(o,3) = sx*dsy*dsz*weights(o) );
12565 
12566  d2sum[4] += ( hessian(o,4) = sx*sy*d2sz*weights(o) );
12567  d2sum[5] += ( hessian(o,5) = sx*d2sy*sz*weights(o) );
12568  }
12569  }
12570  }
12571 
12572  sum = 1.0/sum;
12573  dsum[0] *= sum;
12574  dsum[1] *= sum;
12575  dsum[2] *= sum;
12576 
12577  d2sum[0] *= sum;
12578  d2sum[1] *= sum;
12579  d2sum[2] *= sum;
12580 
12581  d2sum[3] *= sum;
12582  d2sum[4] *= sum;
12583  d2sum[5] *= sum;
12584 
12585  for (int o = 0; o < Dof; o++)
12586  {
12587  hessian(o,0) = hessian(o,0)*sum
12588  - 2*du(o,0)*sum*dsum[0]
12589  + u[o]*sum*(2*dsum[0]*dsum[0] - d2sum[0]);
12590 
12591  hessian(o,1) = hessian(o,1)*sum
12592  - du(o,0)*sum*dsum[1]
12593  - du(o,1)*sum*dsum[0]
12594  + u[o]*sum*(2*dsum[0]*dsum[1] - d2sum[1]);
12595 
12596  hessian(o,2) = hessian(o,2)*sum
12597  - du(o,0)*sum*dsum[2]
12598  - du(o,2)*sum*dsum[0]
12599  + u[o]*sum*(2*dsum[0]*dsum[2] - d2sum[2]);
12600 
12601  hessian(o,3) = hessian(o,3)*sum
12602  - du(o,1)*sum*dsum[2]
12603  - du(o,2)*sum*dsum[1]
12604  + u[o]*sum*(2*dsum[1]*dsum[2] - d2sum[3]);
12605 
12606  hessian(o,4) = hessian(o,4)*sum
12607  - 2*du(o,2)*sum*dsum[2]
12608  + u[o]*sum*(2*dsum[2]*dsum[2] - d2sum[4]);
12609 
12610  hessian(o,5) = hessian(o,5)*sum
12611  - 2*du(o,1)*sum*dsum[1]
12612  + u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[5]);
12613 
12614  }
12615 }
12616 
12617 // Global object definitions
12618 
12619 // Object declared in mesh/triangle.hpp.
12620 // Defined here to ensure it is constructed before 'Geometries'.
12622 
12623 // Object declared in mesh/tetrahedron.hpp.
12624 // Defined here to ensure it is constructed before 'Geometries'.
12626 
12627 // Object declared in mesh/wedge.hpp.
12628 // Defined here to ensure it is constructed after 'poly1d' and before
12629 // 'Geometries'.
12630 // TODO: define as thread_local to prevent race conditions in GLVis, because
12631 // there is no "LinearWedgeFiniteElement" and WedgeFE is in turn used from two
12632 // different threads for different things in GLVis. We also don't want to turn
12633 // MFEM_THREAD_SAFE on globally. (See PR #731)
12635 
12636 // Object declared in geom.hpp.
12637 // Construct 'Geometries' after 'TriangleFE', 'TetrahedronFE', and 'WedgeFE'.
12639 
12640 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:245
Abstract class for Finite Elements.
Definition: fe.hpp:232
RefinedLinear3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:4941
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &hessian) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:12276
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1826
void Set(const double *p, const int dim)
Definition: intrules.hpp:37
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9325
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:2391
ND_SegmentElement(const int p, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:12210
int Size() const
Logical size of the array.
Definition: array.hpp:124
const DenseMatrix & AdjugateJacobian()
Definition: eltrans.hpp:79
For scalar fields; preserves point values.
Definition: fe.hpp:276
DenseMatrix curlshape_J
Definition: fe.hpp:720
void Get(double *p, const int dim) const
Definition: intrules.hpp:51
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:6740
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:308
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7995
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:3578
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:4519
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1574
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:90
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:2127
L2Pos_WedgeElement(const int p)
Definition: fe.cpp:10196
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9715
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:12337
Linear3DFiniteElement()
Construct a linear FE on tetrahedron.
Definition: fe.cpp:2976
static int Check(int b_type)
If the input does not represents a valid BasisType, abort with an error; otherwise return the input...
Definition: fe.hpp:45
virtual void CalcPhysLinLaplacian(ElementTransformation &Trans, Vector &Laplacian) const
Definition: fe.cpp:248
static double CalcDelta(const int p, const double x)
Definition: fe.hpp:1794
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:3760
No derivatives implemented.
Definition: fe.hpp:291
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9476
void ProjectMatrixCoefficient_RT(const double *nk, const Array< int > &d2n, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:928
int NumCols() const
Definition: array.hpp:338
void ProjectMatrixCoefficient_ND(const double *tk, const Array< int > &d2t, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:1104
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:11066
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:40
RefinedBiLinear2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:5173
const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:11515
NodalTensorFiniteElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:7555
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2371
void LocalInterpolation_RT(const VectorFiniteElement &cfe, const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1198
L2Pos_TriangleElement(const int p)
Definition: fe.cpp:9859
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:890
H1Pos_SegmentElement(const int p)
Definition: fe.cpp:7937
Basis(const int p, const double *nodes, EvalType etype=Barycentric)
Create a nodal or positive (Bernstein) basis.
Definition: fe.cpp:6845
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Definition: fe.hpp:154
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:177
void SetRow(int r, const double *row)
Definition: densemat.cpp:1790
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
Definition: densemat.cpp:356
Geometry::Type GeomType
Geometry::Type of the reference element.
Definition: fe.hpp:236
virtual void CalcPhysHessian(ElementTransformation &Trans, DenseMatrix &Hessian) const
Evaluate the Hessian of all shape functions of a scalar finite element in reference space at the give...
Definition: fe.cpp:293
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:5785
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:130
Array< const KnotVector * > kv
Definition: fe.hpp:2908
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:3215
void CalcPhysDivShape(ElementTransformation &Trans, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in physical space at the po...
Definition: fe.cpp:61
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2993
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9898
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:3532
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3812
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:2167
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:7975
PositiveTensorFiniteElement(const int dims, const int p, const DofMapType dmtype)
Definition: fe.cpp:7564
void GivePolyPoints(const int np, double *pts, const int type)
Definition: intrules.cpp:621
L2Pos_TetrahedronElement(const int p)
Definition: fe.cpp:10054
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9178
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:654
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:885
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:407
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:10448
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:5847
virtual void CalcPhysLaplacian(ElementTransformation &Trans, Vector &Laplacian) const
Evaluate the Laplacian of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:206
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:4302
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1495
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:615
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2191
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:2549
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:2460
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:3297
FiniteElement(int D, Geometry::Type G, int Do, int O, int F=FunctionSpace::Pk)
Definition: fe.cpp:25
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:476
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
evaluate derivatives of shape function - constant 0
Definition: fe.cpp:2947
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:63
H1Pos_SegmentElement SegmentFE
Definition: fe.hpp:2198
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1384
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7640
virtual void Eval(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the matrix coefficient in the element described by T at the point ip, storing the result in ...
H1Pos_TetrahedronElement(const int p)
Definition: fe.cpp:8664
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:12243
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9344
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
Definition: densemat.cpp:297
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:56
LagrangeHexFiniteElement(int degree)
Definition: fe.cpp:4571
TensorBasisElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:7354
L2_SegmentElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9204
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition: fe.hpp:318
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:3310
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1952
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:4425
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:4733
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Definition: fe.hpp:166
Data type dense matrix using column-major storage.
Definition: densemat.hpp:23
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4377
int Size() const
Returns the size of the vector.
Definition: vector.hpp:157
Array< double > Gt
Transpose of G.
Definition: fe.hpp:205
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:717
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:12257
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
Definition: fe.hpp:162
static int GetQuadrature1D(int b_type)
Get the corresponding Quadrature1D constant, when that makes sense; otherwise return Quadrature1D::In...
Definition: fe.hpp:61
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:10922
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:10258
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:6013
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:1030
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:2962
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:12234
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:2620
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:111
const DenseMatrix & InverseJacobian()
Definition: eltrans.hpp:82
RefinedTriLinear3DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:5320
DenseMatrix vshape
Definition: fe.hpp:245
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4558
Quadratic3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:3032
int GetMapType() const
Definition: fe.hpp:334
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9220
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:6363
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:6550
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:3238
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:3409
const IntegrationPoint & GetIntPoint()
Definition: eltrans.hpp:58
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:10018
static void CalcLegendre(const int p, const double x, double *u)
Definition: fe.cpp:7180
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
Nodal interpolation.
Definition: fe.cpp:387
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:2672
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:10084
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:3240
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:3232
const IntegrationPoint & GetCenter(int GeomType)
Return the center of the given Geometry::Type, GeomType.
Definition: geom.hpp:70
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9282
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:7692
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:1068
H1Pos_HexahedronElement(const int p)
Definition: fe.cpp:8070
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:161
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:166
static void CalcShape(const int p, const double x, const double y, const double z, double *shape)
Definition: fe.cpp:8766
const DofToQuad & GetTensorDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode, const bool closed) const
Definition: fe.cpp:11533
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9960
Implements CalcDivShape methods.
Definition: fe.hpp:293
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:1456
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:8042
Linear2DFiniteElement()
Construct a linear FE on triangle.
Definition: fe.cpp:1398
const double * ClosedPoints(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.hpp:1754
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:3089
Possible basis types. Note that not all elements can use all BasisType(s).
Definition: fe.hpp:27
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:6685
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:238
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5509
H1_HexahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7782
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:12131
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1365
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2692
void CalcPhysCurlShape(ElementTransformation &Trans, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in physical space at the point de...
Definition: fe.cpp:75
L2Pos_HexahedronElement(const int p)
Definition: fe.cpp:9643
ND_TriangleElement(const int p)
Definition: fe.cpp:12050
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:11102
static void CalcDShape(const int p, const double x, const double y, const double z, double *dshape_1d, double *dshape)
Definition: fe.cpp:8799
static void CalcBasis(const int p, const double x, double *u)
Definition: fe.hpp:1770
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
evaluate shape function - constant 1
Definition: fe.cpp:2941
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:2720
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:7086
const double * GetPoints(const int p, const int btype)
Get the coordinates of the points of the given BasisType, btype.
Definition: fe.cpp:7279
H1Pos_TriangleElement(const int p)
Definition: fe.cpp:8519
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:4014
Poly_1D::Basis & obasis1d
Definition: fe.hpp:1917
Cubic3DFiniteElement()
Construct a cubic FE on tetrahedron.
Definition: fe.cpp:2767
Linear1DFiniteElement()
Construct a linear FE on interval.
Definition: fe.cpp:1377
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4882
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:6673
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:2240
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:3278
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:169
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:311
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1631
static void CalcShape(const int p, const double x, const double y, double *shape)
Definition: fe.cpp:8574
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:3263
VectorTensorFiniteElement(const int dims, const int d, const int p, const int cbtype, const int obtype, const int M, const DofMapType dmtype)
Definition: fe.cpp:7571
Array< int > s_dof
Definition: fe.hpp:2419
void SetSize(int m, int n)
Definition: array.hpp:335
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2860
Geometry Geometries
Definition: fe.cpp:12638
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:248
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4320
Implements CalcCurlShape methods.
Definition: fe.hpp:294
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:787
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Definition: densemat.cpp:201
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:2161
int Dof
Number of degrees of freedom.
Definition: fe.hpp:240
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9226
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1591
Poly_1D::Basis & cbasis1d
Definition: fe.hpp:1917
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1602
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1850
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:57
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9035
RefinedLinear1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:4771
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7852
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8063
ND_HexahedronElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:11148
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:2344
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9801
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:8215
Poly_1D::Basis & basis1d
Definition: fe.hpp:1828
For scalar fields; preserves volume integrals.
Definition: fe.hpp:277
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4798
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
Definition: error.cpp:153
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:3953
static void ChebyshevPoints(const int p, double *x)
Definition: fe.cpp:7054
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
Definition: densemat.cpp:2821
double b
Definition: lissajous.cpp:42
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint, using the method SetIntPoint().
Definition: eltrans.hpp:71
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:6810
H1Pos_WedgeElement(const int p)
Definition: fe.cpp:9061
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:4543
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:6651
int GetSpaceDim() const
Get the dimension of the target (physical) space.
Definition: eltrans.hpp:100
ND_TetrahedronElement(const int p)
Definition: fe.cpp:11788
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9887
Array< int > t_dof
Definition: fe.hpp:2419
Mode mode
Describes the contents of the B, Bt, G, and Gt arrays, see Mode.
Definition: fe.hpp:158
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
H1_QuadrilateralElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7668
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1371
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2635
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:635
class FiniteElement * FE
The FiniteElement that created and owns this object.
Definition: fe.hpp:133
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2034
const IntegrationRule & GetNodes() const
Definition: fe.hpp:367
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5900
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1672
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9558
static int VerifyOpen(int b_type)
Definition: fe.hpp:563
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:3067
L2Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:9413
const int * ijk
Definition: fe.hpp:2909
P0SegmentFiniteElement(int Ord=0)
Definition: fe.cpp:3203
static void CalcDShape(const int p, const double x, const double y, double *dshape_1d, double *dshape)
Definition: fe.cpp:8600
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:10151
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:3555
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:12455
DenseMatrix curlshape
Definition: fe.hpp:720
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
Definition: densemat.cpp:2843
Class for linear FE on tetrahedron.
Definition: fe.hpp:1124
H1_SegmentElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7584
void Set2(const double x1, const double x2)
Definition: intrules.hpp:80
virtual ~FiniteElement()
Definition: fe.cpp:378
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:10662
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:5951
void CalcPhysDShape(ElementTransformation &Trans, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in physical space at the poi...
Definition: fe.cpp:195
Class for linear FE on triangle.
Definition: fe.hpp:844
int GetVDim()
Returns dimension of the vector.
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9779
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:10401
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2499
L2_QuadrilateralElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9306
void SetData(double *d)
Definition: vector.hpp:118
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:4212
Basis & GetBasis(const int p, const int btype)
Get a Poly_1D::Basis object of the given degree and BasisType, btype.
Definition: fe.cpp:7303
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1447
void GetColumn(int c, Vector &col) const
Definition: densemat.cpp:1287
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3002
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:10736
const double * OpenPoints(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.hpp:1751
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:8415
void trans(const Vector &x, Vector &p)
Definition: toroid.cpp:239
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:1696
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9016
class H1_WedgeElement WedgeFE
L2_WedgeElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:10108
void ScalarLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
&quot;Interpolation&quot; defined through local L2-projection.
Definition: fe.cpp:421
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1774
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:1177
L2_TetrahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9910
static const int MaxDim
Definition: geom.hpp:42
Array< int > t_dof
Definition: fe.hpp:2195
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9881
void Threshold(double eps)
Replace small entries, abs(a_ij) &lt;= eps, with zero.
Definition: densemat.cpp:1820
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:2197
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:12479
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1788
DenseMatrix m_dshape
Definition: fe.hpp:2097
int Dim
Dimension of reference space.
Definition: fe.hpp:235
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:11734
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9437
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:70
IntegrationRule Nodes
Definition: fe.hpp:243
Array< int > dof_map
Definition: fe.hpp:1827
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1658
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9670
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:7955
Array< double > Bt
Transpose of B.
Definition: fe.hpp:183
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8137
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:4264
int Orders[Geometry::MaxDim]
Anisotropic orders.
Definition: fe.hpp:242
double * Data() const
Returns the matrix data array.
Definition: densemat.hpp:96
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:12165
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:3424
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5196
void LocalInterpolation_ND(const VectorFiniteElement &cfe, const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1237
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &ddshape) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:8473
H1Pos_TriangleElement TriangleFE
Definition: fe.hpp:2197
ND_QuadrilateralElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:11596
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:3321
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:897
DenseMatrix Jinv
Definition: fe.hpp:719
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9237
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:314
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:8440
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Definition: globals.hpp:71
Base class Coefficient that may optionally depend on time.
Definition: coefficient.hpp:31
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1542
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:5981
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &Hessian) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:105
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:10077
void CalcPhysShape(ElementTransformation &Trans, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in physical space at the point ...
Definition: fe.cpp:185
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:635
DenseMatrix t_dshape
Definition: fe.hpp:2193
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1409
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5366
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:5063
DenseMatrix t_dshape
Definition: fe.hpp:2417
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
Definition: densemat.cpp:2329
static const int * Binom(const int p)
Get a pointer to an array containing the binomial coefficients &quot;p choose k&quot; for k=0,...,p for the given p.
Definition: fe.cpp:7037
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:4114
DenseMatrix s_dshape
Definition: fe.hpp:2193
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:54
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1477
H1_TetrahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:8299
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:12431
DenseMatrix s_dshape
Definition: fe.hpp:2417
Structure representing the matrices/tensors needed to evaluate (in reference space) the values...
Definition: fe.hpp:128
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:10239
class Linear3DFiniteElement TetrahedronFE
Definition: fe.cpp:12625
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9985
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:11366
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3488
L2Pos_TriangleElement TriangleFE
Definition: fe.hpp:2421
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:125
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1899
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3147
Linear2DFiniteElement TriangleFE
Definition: fe.cpp:12621
Class for bilinear FE on quadrilateral.
Definition: fe.hpp:866
Array< double > B
Basis functions evaluated at quadrature points.
Definition: fe.hpp:177
const Array< int > & GetDofMap() const
Get an Array&lt;int&gt; that maps lexicographically ordered indices to the indices of the respective nodes/...
Definition: fe.hpp:1850
Quad1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:1583
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:8092
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:100
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:370
double a
Definition: lissajous.cpp:41
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1531
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1438
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:68
H1Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:8002
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:10170
void LocalRestriction_ND(const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &R) const
Definition: fe.cpp:1317
H1_TriangleElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:8144
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1391
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9830
Mode
Type of data stored in the arrays B, Bt, G, and Gt.
Definition: fe.hpp:141
Full multidimensional representation which does not use tensor product structure. The ordering of the...
Definition: fe.hpp:146
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:142
L2Pos_SegmentElement SegmentFE
Definition: fe.hpp:2422
const Poly_1D::Basis & GetBasis1D() const
Definition: fe.hpp:1844
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:8113
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9288
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2968
const DofToQuad & GetDofToQuadOpen(const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:11524
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9691
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:908
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:7807
Array< DofToQuad * > dof2quad_array
Container for all DofToQuad objects created by the FiniteElement.
Definition: fe.hpp:250
H1_WedgeElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:8916
Array< int > s_dof
Definition: fe.hpp:2195
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1566
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:3928
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:11936
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:3688
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:11685
static int VerifyClosed(int b_type)
Definition: fe.hpp:557
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:746
int DerivRangeType
Definition: fe.hpp:237
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:3436
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:819
virtual void GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs. ...
Definition: fe.cpp:117
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9299
RefinedLinear2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:4817
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:6605
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:551
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4779
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4507
Array< double > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
Definition: fe.hpp:198
Array< int > dof_map
Definition: fe.hpp:2099
RT_TetrahedronElement(const int p)
Definition: fe.cpp:10964
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:6161
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4712
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:7621
double infinity()
Define a shortcut for std::numeric_limits&lt;double&gt;::infinity()
Definition: vector.hpp:42
BiQuad2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:1803
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:3022
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:3725
P0TriangleFiniteElement()
Construct P0 triangle finite element.
Definition: fe.cpp:2934
static int VerifyNodal(int b_type)
Definition: fe.hpp:568
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:3209
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the coefficient in the element described by T at the point ip.
H1Ser_QuadrilateralElement(const int p)
Definition: fe.cpp:1918
RT_TriangleElement(const int p)
Definition: fe.cpp:10811
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:7602
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:12226
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:11440
void Eval(const double x, Vector &u) const
Definition: fe.cpp:6903
L2Pos_SegmentElement(const int p)
Definition: fe.cpp:9261
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &hessian) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:12525
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4976
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:6216
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:2648
void InvertLinearTrans(ElementTransformation &trans, const IntegrationPoint &pt, Vector &x)
Definition: fe.cpp:570
Vector data type.
Definition: vector.hpp:48
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:6147
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:173
static void CalcBernstein(const int p, const double x, double *u)
Definition: fe.hpp:1810
virtual void Transform(const IntegrationPoint &, Vector &)=0
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:12300
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:8022
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9534
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1724
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:10889
Quad2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:1641
void LocalRestriction_RT(const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &R) const
Definition: fe.cpp:1274
static bool CheckPoint(int GeomType, const IntegrationPoint &ip)
Check if the given point is inside the given reference element.
Definition: geom.cpp:348
Describes the space on each element.
Definition: fe.hpp:210
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3163
Bernstein polynomials.
Definition: fe.hpp:35
void pts(int iphi, int t, double x[])
virtual void GetTransferMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
Return interpolation matrix, I, which maps dofs from a coarse element, fe, to the fine dofs on this f...
Definition: fe.cpp:123
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:6066
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9456
const DenseMatrix & Hessian()
Definition: eltrans.hpp:74
RT_HexahedronElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:10498
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:11978
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:4564
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2269
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1417
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:2832
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &ddshape) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:8266
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:3274
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:90
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7733
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:6117
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:4332
RT_QuadrilateralElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:10287
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:461
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5247
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:12318
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:1087
int GetRangeType() const
Definition: fe.hpp:330
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1520
double FNorm2() const
Compute the square of the Frobenius norm of the matrix.
Definition: densemat.hpp:227
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:376
int Order
Order/degree of the shape functions.
Definition: fe.hpp:240
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3630
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9159
Linear1DFiniteElement SegmentFE
Definition: segment.cpp:49
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4537
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:7828
L2_HexahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9491
virtual void GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs. ...
Definition: fe.cpp:586
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:7711
static void CalcDBinomTerms(const int p, const double x, const double y, double *d)
Definition: fe.cpp:7150
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:5730
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &hessian) const
Evaluate the Hessians of all shape functions of a scalar finite element in reference space at the giv...
Definition: fe.cpp:12372
const IntegrationRule * IntRule
IntegrationRule that defines the quadrature points at which the basis functions of the FE are evaluat...
Definition: fe.hpp:138
TriLinear3DFiniteElement()
Construct a tri-linear FE on cube.
Definition: fe.cpp:3111
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:148
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1621
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:9513
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4834
const DofToQuad & GetTensorDofToQuad(const class TensorBasisElement &tb, const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:509
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4293
L2_TriangleElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9734
BiLinear2DFiniteElement()
Construct a bilinear FE on quadrilateral.
Definition: fe.cpp:1425
Poly_1D poly1d
Definition: fe.cpp:7351
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:6793
Lagrange1DFiniteElement(int degree)
Definition: fe.cpp:4345
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3373
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:6486
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:10095
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9364
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1487
const int ir_order
Definition: ex1.cpp:44
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:8237
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:1003
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:778