MFEM  v4.2.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 ; geom_type = G ; dof = Do ; order = O ; func_space = F;
30  map_type = VALUE;
31  deriv_type = 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  Vector &dofs) const
144 {
145  mfem_error ("FiniteElement::ProjectFromNodes() (vector) is not overloaded!");
146 }
147 
149  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
150 {
151  mfem_error("FiniteElement::ProjectMatrixCoefficient() is not overloaded !");
152 }
153 
154 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
155 {
156  mfem_error("FiniteElement::ProjectDelta(...) is not implemented for "
157  "this element!");
158 }
159 
162 {
163  mfem_error("FiniteElement::Project(...) (fe version) is not implemented "
164  "for this element!");
165 }
166 
169  DenseMatrix &grad) const
170 {
171  mfem_error("FiniteElement::ProjectGrad(...) is not implemented for "
172  "this element!");
173 }
174 
177  DenseMatrix &curl) const
178 {
179  mfem_error("FiniteElement::ProjectCurl(...) is not implemented for "
180  "this element!");
181 }
182 
185  DenseMatrix &div) const
186 {
187  mfem_error("FiniteElement::ProjectDiv(...) is not implemented for "
188  "this element!");
189 }
190 
192  Vector &shape) const
193 {
194  CalcShape(Trans.GetIntPoint(), shape);
195  if (map_type == INTEGRAL)
196  {
197  shape /= Trans.Weight();
198  }
199 }
200 
202  DenseMatrix &dshape) const
203 {
204  MFEM_ASSERT(map_type == VALUE, "");
205 #ifdef MFEM_THREAD_SAFE
207 #endif
208  CalcDShape(Trans.GetIntPoint(), vshape);
209  Mult(vshape, Trans.InverseJacobian(), dshape);
210 }
211 
213  Vector &Laplacian) const
214 {
215  MFEM_ASSERT(map_type == VALUE, "");
216 
217  // Simpler routine if mapping is affine
218  if (Trans.Hessian().FNorm2() < 1e-20)
219  {
220  CalcPhysLinLaplacian(Trans, Laplacian);
221  return;
222  }
223 
224  // Compute full Hessian first if non-affine
225  int size = (dim*(dim+1))/2;
226  DenseMatrix hess(dof, size);
227  CalcPhysHessian(Trans,hess);
228 
229  if (dim == 3)
230  {
231  for (int nd = 0; nd < dof; nd++)
232  {
233  Laplacian[nd] = hess(nd,0) + hess(nd,4) + hess(nd,5);
234  }
235  }
236  else if (dim == 2)
237  {
238  for (int nd = 0; nd < dof; nd++)
239  {
240  Laplacian[nd] = hess(nd,0) + hess(nd,2);
241  }
242  }
243  else
244  {
245  for (int nd = 0; nd < dof; nd++)
246  {
247  Laplacian[nd] = hess(nd,0);
248  }
249  }
250 }
251 
252 
253 // Assume a linear mapping
255  Vector &Laplacian) const
256 {
257  MFEM_ASSERT(map_type == VALUE, "");
258  int size = (dim*(dim+1))/2;
259  DenseMatrix hess(dof, size);
260  DenseMatrix Gij(dim,dim);
261  Vector scale(size);
262 
263  CalcHessian (Trans.GetIntPoint(), hess);
264  MultAAt(Trans.InverseJacobian(), Gij);
265 
266  if (dim == 3)
267  {
268  scale[0] = Gij(0,0);
269  scale[1] = 2*Gij(0,1);
270  scale[2] = 2*Gij(0,2);
271 
272  scale[3] = 2*Gij(1,2);
273  scale[4] = Gij(2,2);
274 
275  scale[5] = Gij(1,1);
276  }
277  else if (dim == 2)
278  {
279  scale[0] = Gij(0,0);
280  scale[1] = 2*Gij(0,1);
281  scale[2] = Gij(1,1);
282  }
283  else
284  {
285  scale[0] = Gij(0,0);
286  }
287 
288  for (int nd = 0; nd < dof; nd++)
289  {
290  Laplacian[nd] = 0.0;
291  for (int ii = 0; ii < size; ii++)
292  {
293  Laplacian[nd] += hess(nd,ii)*scale[ii];
294  }
295  }
296 
297 }
298 
300  DenseMatrix& Hessian) const
301 {
302  MFEM_ASSERT(map_type == VALUE, "");
303 
304  // Roll 2-Tensors in vectors and 4-Tensor in Matrix, exploiting symmetry
305  Array<int> map(dim*dim);
306  if (dim == 3)
307  {
308  map[0] = 0;
309  map[1] = 1;
310  map[2] = 2;
311 
312  map[3] = 1;
313  map[4] = 5;
314  map[5] = 3;
315 
316  map[6] = 2;
317  map[7] = 3;
318  map[8] = 4;
319  }
320  else if (dim == 2)
321  {
322  map[0] = 0;
323  map[1] = 1;
324 
325  map[2] = 1;
326  map[3] = 2;
327  }
328  else
329  {
330  map[0] = 0;
331  }
332 
333  // Hessian in ref coords
334  int size = (dim*(dim+1))/2;
335  DenseMatrix hess(dof, size);
336  CalcHessian(Trans.GetIntPoint(), hess);
337 
338  // Gradient in physical coords
339  if (Trans.Hessian().FNorm2() > 1e-10)
340  {
341  DenseMatrix grad(dof, dim);
342  CalcPhysDShape(Trans, grad);
343  DenseMatrix gmap(dof, size);
344  Mult(grad,Trans.Hessian(),gmap);
345  hess -= gmap;
346  }
347 
348  // LHM
349  DenseMatrix lhm(size,size);
350  DenseMatrix invJ = Trans.Jacobian();
351  lhm = 0.0;
352  for (int i = 0; i < dim; i++)
353  {
354  for (int j = 0; j < dim; j++)
355  {
356  for (int k = 0; k < dim; k++)
357  {
358  for (int l = 0; l < dim; l++)
359  {
360  lhm(map[i*dim+j],map[k*dim+l]) += invJ(i,k)*invJ(j,l);
361  }
362  }
363  }
364  }
365  // Correct multiplicity
366  Vector mult(size);
367  mult = 0.0;
368  for (int i = 0; i < dim*dim; i++) { mult[map[i]]++; }
369  lhm.InvRightScaling(mult);
370 
371  // Hessian in physical coords
372  lhm.Invert();
373  Mult( hess, lhm, Hessian);
374 }
375 
377  DofToQuad::Mode) const
378 {
379  mfem_error("FiniteElement::GetDofToQuad(...) is not implemented for "
380  "this element!");
381  return *dof2quad_array[0]; // suppress a warning
382 }
383 
385 {
386  for (int i = 0; i < dof2quad_array.Size(); i++)
387  {
388  delete dof2quad_array[i];
389  }
390 }
391 
392 
395  const ScalarFiniteElement &fine_fe) const
396 {
397  double v[Geometry::MaxDim];
398  Vector vv (v, dim);
399  IntegrationPoint f_ip;
400 
401 #ifdef MFEM_THREAD_SAFE
402  Vector c_shape(dof);
403 #endif
404 
405  MFEM_ASSERT(map_type == fine_fe.GetMapType(), "");
406 
407  I.SetSize(fine_fe.dof, dof);
408  for (int i = 0; i < fine_fe.dof; i++)
409  {
410  Trans.Transform(fine_fe.Nodes.IntPoint(i), vv);
411  f_ip.Set(v, dim);
412  CalcShape(f_ip, c_shape);
413  for (int j = 0; j < dof; j++)
414  if (fabs(I(i,j) = c_shape(j)) < 1.0e-12)
415  {
416  I(i,j) = 0.0;
417  }
418  }
419  if (map_type == INTEGRAL)
420  {
421  // assuming Trans is linear; this should be ok for all refinement types
423  I *= Trans.Weight();
424  }
425 }
426 
429  const ScalarFiniteElement &fine_fe) const
430 {
431  // General "interpolation", defined by L2 projection
432 
433  double v[Geometry::MaxDim];
434  Vector vv (v, dim);
435  IntegrationPoint f_ip;
436 
437  const int fs = fine_fe.GetDof(), cs = this->GetDof();
438  I.SetSize(fs, cs );
439  Vector fine_shape(fs), coarse_shape(cs);
440  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
441  const int ir_order = GetOrder() + fine_fe.GetOrder();
442  const IntegrationRule &ir = IntRules.Get(fine_fe.GetGeomType(), ir_order);
443 
444  for (int i = 0; i < ir.GetNPoints(); i++)
445  {
446  const IntegrationPoint &ip = ir.IntPoint(i);
447  fine_fe.CalcShape(ip, fine_shape);
448  Trans.Transform(ip, vv);
449  f_ip.Set(v, dim);
450  this->CalcShape(f_ip, coarse_shape);
451 
452  AddMult_a_VVt(ip.weight, fine_shape, fine_mass);
453  AddMult_a_VWt(ip.weight, fine_shape, coarse_shape, fine_coarse_mass);
454  }
455 
456  DenseMatrixInverse fine_mass_inv(fine_mass);
457  fine_mass_inv.Mult(fine_coarse_mass, I);
458 
459  if (map_type == INTEGRAL)
460  {
461  // assuming Trans is linear; this should be ok for all refinement types
463  I *= Trans.Weight();
464  }
465 }
466 
468  DofToQuad::Mode mode) const
469 {
470  MFEM_VERIFY(mode == DofToQuad::FULL, "invalid mode requested");
471 
472  for (int i = 0; i < dof2quad_array.Size(); i++)
473  {
474  const DofToQuad &d2q = *dof2quad_array[i];
475  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
476  }
477 
478  DofToQuad *d2q = new DofToQuad;
479  const int nqpt = ir.GetNPoints();
480  d2q->FE = this;
481  d2q->IntRule = &ir;
482  d2q->mode = mode;
483  d2q->ndof = dof;
484  d2q->nqpt = nqpt;
485  d2q->B.SetSize(nqpt*dof);
486  d2q->Bt.SetSize(dof*nqpt);
487  d2q->G.SetSize(nqpt*dim*dof);
488  d2q->Gt.SetSize(dof*nqpt*dim);
489 #ifdef MFEM_THREAD_SAFE
490  Vector c_shape(dof);
491  DenseMatrix vshape(dof, dim);
492 #endif
493  for (int i = 0; i < nqpt; i++)
494  {
495  const IntegrationPoint &ip = ir.IntPoint(i);
496  CalcShape(ip, c_shape);
497  for (int j = 0; j < dof; j++)
498  {
499  d2q->B[i+nqpt*j] = d2q->Bt[j+dof*i] = c_shape(j);
500  }
501  CalcDShape(ip, vshape);
502  for (int d = 0; d < dim; d++)
503  {
504  for (int j = 0; j < dof; j++)
505  {
506  d2q->G[i+nqpt*(d+dim*j)] = d2q->Gt[j+dof*(i+nqpt*d)] = vshape(j,d);
507  }
508  }
509  }
510  dof2quad_array.Append(d2q);
511  return *d2q;
512 }
513 
514 // protected method
516  const TensorBasisElement &tb,
517  const IntegrationRule &ir, DofToQuad::Mode mode) const
518 {
519  MFEM_VERIFY(mode == DofToQuad::TENSOR, "invalid mode requested");
520 
521  for (int i = 0; i < dof2quad_array.Size(); i++)
522  {
523  const DofToQuad &d2q = *dof2quad_array[i];
524  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
525  }
526 
527  DofToQuad *d2q = new DofToQuad;
528  const Poly_1D::Basis &basis_1d = tb.GetBasis1D();
529  const int ndof = order + 1;
530  const int nqpt = (int)floor(pow(ir.GetNPoints(), 1.0/dim) + 0.5);
531  d2q->FE = this;
532  d2q->IntRule = &ir;
533  d2q->mode = mode;
534  d2q->ndof = ndof;
535  d2q->nqpt = nqpt;
536  d2q->B.SetSize(nqpt*ndof);
537  d2q->Bt.SetSize(ndof*nqpt);
538  d2q->G.SetSize(nqpt*ndof);
539  d2q->Gt.SetSize(ndof*nqpt);
540  Vector val(ndof), grad(ndof);
541  for (int i = 0; i < nqpt; i++)
542  {
543  // The first 'nqpt' points in 'ir' have the same x-coordinates as those
544  // of the 1D rule.
545  basis_1d.Eval(ir.IntPoint(i).x, val, grad);
546  for (int j = 0; j < ndof; j++)
547  {
548  d2q->B[i+nqpt*j] = d2q->Bt[j+ndof*i] = val(j);
549  d2q->G[i+nqpt*j] = d2q->Gt[j+ndof*i] = grad(j);
550  }
551  }
552  dof2quad_array.Append(d2q);
553  return *d2q;
554 }
555 
556 
559  DenseMatrix &curl) const
560 {
561  MFEM_ASSERT(GetMapType() == FiniteElement::INTEGRAL, "");
562 
563  DenseMatrix curl_shape(fe.GetDof(), 1);
564 
565  curl.SetSize(dof, fe.GetDof());
566  for (int i = 0; i < dof; i++)
567  {
568  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
569  for (int j = 0; j < fe.GetDof(); j++)
570  {
571  curl(i,j) = curl_shape(j,0);
572  }
573  }
574 }
575 
577  const IntegrationPoint &pt, Vector &x)
578 {
579  // invert a linear transform with one Newton step
580  IntegrationPoint p0;
581  p0.Set3(0, 0, 0);
582  trans.Transform(p0, x);
583 
584  double store[3];
585  Vector v(store, x.Size());
586  pt.Get(v, x.Size());
587  v -= x;
588 
589  trans.InverseJacobian().Mult(v, x);
590 }
591 
593  DenseMatrix &R) const
594 {
595  IntegrationPoint ipt;
596  Vector pt(&ipt.x, dim);
597 
598 #ifdef MFEM_THREAD_SAFE
599  Vector c_shape(dof);
600 #endif
601 
602  Trans.SetIntPoint(&Nodes[0]);
603 
604  for (int j = 0; j < dof; j++)
605  {
606  InvertLinearTrans(Trans, Nodes[j], pt);
607  if (Geometries.CheckPoint(geom_type, ipt)) // do we need an epsilon here?
608  {
609  CalcShape(ipt, c_shape);
610  R.SetRow(j, c_shape);
611  }
612  else
613  {
614  // Set the whole row to avoid valgrind warnings in R.Threshold().
615  R.SetRow(j, infinity());
616  }
617  }
618  R.Threshold(1e-12);
619 }
620 
622  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
623 {
624  for (int i = 0; i < dof; i++)
625  {
626  const IntegrationPoint &ip = Nodes.IntPoint(i);
627  // some coefficients expect that Trans.IntPoint is the same
628  // as the second argument of Eval
629  Trans.SetIntPoint(&ip);
630  dofs(i) = coeff.Eval (Trans, ip);
631  if (map_type == INTEGRAL)
632  {
633  dofs(i) *= Trans.Weight();
634  }
635  }
636 }
637 
640 {
641  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*dof, "");
642  Vector x(vc.GetVDim());
643 
644  for (int i = 0; i < dof; i++)
645  {
646  const IntegrationPoint &ip = Nodes.IntPoint(i);
647  Trans.SetIntPoint(&ip);
648  vc.Eval (x, Trans, ip);
649  if (map_type == INTEGRAL)
650  {
651  x *= Trans.Weight();
652  }
653  for (int j = 0; j < x.Size(); j++)
654  {
655  dofs(dof*j+i) = x(j);
656  }
657  }
658 }
659 
661  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
662 {
663  // (mc.height x mc.width) @ DOFs -> (dof x mc.width x mc.height) in dofs
664  MFEM_ASSERT(dofs.Size() == mc.GetHeight()*mc.GetWidth()*dof, "");
665  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
666 
667  for (int k = 0; k < dof; k++)
668  {
669  T.SetIntPoint(&Nodes.IntPoint(k));
670  mc.Eval(MQ, T, Nodes.IntPoint(k));
671  if (map_type == INTEGRAL) { MQ *= T.Weight(); }
672  for (int r = 0; r < MQ.Height(); r++)
673  {
674  for (int d = 0; d < MQ.Width(); d++)
675  {
676  dofs(k+dof*(d+MQ.Width()*r)) = MQ(r,d);
677  }
678  }
679  }
680 }
681 
684 {
685  if (fe.GetRangeType() == SCALAR)
686  {
687  MFEM_ASSERT(map_type == fe.GetMapType(), "");
688 
689  Vector shape(fe.GetDof());
690 
691  I.SetSize(dof, fe.GetDof());
692  for (int k = 0; k < dof; k++)
693  {
694  fe.CalcShape(Nodes.IntPoint(k), shape);
695  for (int j = 0; j < shape.Size(); j++)
696  {
697  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
698  }
699  }
700  }
701  else
702  {
703  DenseMatrix vshape(fe.GetDof(), Trans.GetSpaceDim());
704 
705  I.SetSize(vshape.Width()*dof, fe.GetDof());
706  for (int k = 0; k < dof; k++)
707  {
708  Trans.SetIntPoint(&Nodes.IntPoint(k));
709  fe.CalcVShape(Trans, vshape);
710  if (map_type == INTEGRAL)
711  {
712  vshape *= Trans.Weight();
713  }
714  for (int j = 0; j < vshape.Height(); j++)
715  for (int d = 0; d < vshape.Width(); d++)
716  {
717  I(k+d*dof,j) = vshape(j,d);
718  }
719  }
720  }
721 }
722 
725  DenseMatrix &grad) const
726 {
727  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
728  MFEM_ASSERT(Trans.GetSpaceDim() == dim, "")
729 
730  DenseMatrix dshape(fe.GetDof(), dim), grad_k(fe.GetDof(), dim), Jinv(dim);
731 
732  grad.SetSize(dim*dof, fe.GetDof());
733  for (int k = 0; k < dof; k++)
734  {
735  const IntegrationPoint &ip = Nodes.IntPoint(k);
736  fe.CalcDShape(ip, dshape);
737  Trans.SetIntPoint(&ip);
738  CalcInverse(Trans.Jacobian(), Jinv);
739  Mult(dshape, Jinv, grad_k);
740  if (map_type == INTEGRAL)
741  {
742  grad_k *= Trans.Weight();
743  }
744  for (int j = 0; j < grad_k.Height(); j++)
745  for (int d = 0; d < dim; d++)
746  {
747  grad(k+d*dof,j) = grad_k(j,d);
748  }
749  }
750 }
751 
754  DenseMatrix &div) const
755 {
756  double detJ;
757  Vector div_shape(fe.GetDof());
758 
759  div.SetSize(dof, fe.GetDof());
760  for (int k = 0; k < dof; k++)
761  {
762  const IntegrationPoint &ip = Nodes.IntPoint(k);
763  fe.CalcDivShape(ip, div_shape);
764  if (map_type == VALUE)
765  {
766  Trans.SetIntPoint(&ip);
767  detJ = Trans.Weight();
768  for (int j = 0; j < div_shape.Size(); j++)
769  {
770  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
771  }
772  }
773  else
774  {
775  for (int j = 0; j < div_shape.Size(); j++)
776  {
777  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
778  }
779  }
780  }
781 }
782 
783 
785  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
786 {
787  for (int i = 0; i < dof; i++)
788  {
789  const IntegrationPoint &ip = Nodes.IntPoint(i);
790  Trans.SetIntPoint(&ip);
791  dofs(i) = coeff.Eval(Trans, ip);
792  }
793 }
794 
797 {
798  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*dof, "");
799  Vector x(vc.GetVDim());
800 
801  for (int i = 0; i < dof; i++)
802  {
803  const IntegrationPoint &ip = Nodes.IntPoint(i);
804  Trans.SetIntPoint(&ip);
805  vc.Eval (x, Trans, ip);
806  for (int j = 0; j < x.Size(); j++)
807  {
808  dofs(dof*j+i) = x(j);
809  }
810  }
811 }
812 
815 {
816  const NodalFiniteElement *nfe =
817  dynamic_cast<const NodalFiniteElement *>(&fe);
818 
819  if (nfe && dof == nfe->GetDof())
820  {
821  nfe->Project(*this, Trans, I);
822  I.Invert();
823  }
824  else
825  {
826  // local L2 projection
827  DenseMatrix pos_mass, mixed_mass;
828  MassIntegrator mass_integ;
829 
830  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
831  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
832 
833  DenseMatrixInverse pos_mass_inv(pos_mass);
834  I.SetSize(dof, fe.GetDof());
835  pos_mass_inv.Mult(mixed_mass, I);
836  }
837 }
838 
839 
840 void VectorFiniteElement::CalcShape (
841  const IntegrationPoint &ip, Vector &shape ) const
842 {
843  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
844  " VectorFiniteElements!");
845 }
846 
847 void VectorFiniteElement::CalcDShape (
848  const IntegrationPoint &ip, DenseMatrix &dshape ) const
849 {
850  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
851  " VectorFiniteElements!");
852 }
853 
855 {
856  switch (map_type)
857  {
858  case H_DIV:
859  deriv_type = DIV;
862  break;
863  case H_CURL:
864  switch (dim)
865  {
866  case 3: // curl: 3D H_CURL -> 3D H_DIV
867  deriv_type = CURL;
870  break;
871  case 2:
872  // curl: 2D H_CURL -> INTEGRAL
873  deriv_type = CURL;
876  break;
877  case 1:
878  deriv_type = NONE;
881  break;
882  default:
883  MFEM_ABORT("Invalid dimension, Dim = " << dim);
884  }
885  break;
886  default:
887  MFEM_ABORT("Invalid MapType = " << map_type);
888  }
889 }
890 
892  ElementTransformation &Trans, DenseMatrix &shape) const
893 {
894  MFEM_ASSERT(map_type == H_DIV, "");
895 #ifdef MFEM_THREAD_SAFE
897 #endif
898  CalcVShape(Trans.GetIntPoint(), vshape);
899  MultABt(vshape, Trans.Jacobian(), shape);
900  shape *= (1.0 / Trans.Weight());
901 }
902 
904  ElementTransformation &Trans, DenseMatrix &shape) const
905 {
906  MFEM_ASSERT(map_type == H_CURL, "");
907 #ifdef MFEM_THREAD_SAFE
909 #endif
910  CalcVShape(Trans.GetIntPoint(), vshape);
911  Mult(vshape, Trans.InverseJacobian(), shape);
912 }
913 
915  const double *nk, const Array<int> &d2n,
917 {
918  double vk[Geometry::MaxDim];
919  const int sdim = Trans.GetSpaceDim();
920  MFEM_ASSERT(vc.GetVDim() == sdim, "");
921  Vector xk(vk, sdim);
922  const bool square_J = (dim == sdim);
923 
924  for (int k = 0; k < dof; k++)
925  {
926  Trans.SetIntPoint(&Nodes.IntPoint(k));
927  vc.Eval(xk, Trans, Nodes.IntPoint(k));
928  // dof_k = nk^t adj(J) xk
929  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*dim);
930  if (!square_J) { dofs(k) /= Trans.Weight(); }
931  }
932 }
933 
935  const double *nk, const Array<int> &d2n,
936  Vector &vc, ElementTransformation &Trans, Vector &dofs) const
937 {
938  const int sdim = Trans.GetSpaceDim();
939  const bool square_J = (dim == sdim);
940 
941  for (int k = 0; k < dof; k++)
942  {
943  Trans.SetIntPoint(&Nodes.IntPoint(k));
944  // dof_k = nk^t adj(J) xk
945  Vector vk(vc.GetData()+k*sdim, sdim);
946  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*dim);
947  if (!square_J) { dofs(k) /= Trans.Weight(); }
948  }
949 }
950 
952  const double *nk, const Array<int> &d2n,
953  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
954 {
955  // project the rows of the matrix coefficient in an RT space
956 
957  const int sdim = T.GetSpaceDim();
958  MFEM_ASSERT(mc.GetWidth() == sdim, "");
959  const bool square_J = (dim == sdim);
960  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
961  Vector nk_phys(sdim), dofs_k(MQ.Height());
962  MFEM_ASSERT(dofs.Size() == dof*MQ.Height(), "");
963 
964  for (int k = 0; k < dof; k++)
965  {
966  T.SetIntPoint(&Nodes.IntPoint(k));
967  mc.Eval(MQ, T, Nodes.IntPoint(k));
968  // nk_phys = adj(J)^t nk
969  T.AdjugateJacobian().MultTranspose(nk + d2n[k]*dim, nk_phys);
970  if (!square_J) { nk_phys /= T.Weight(); }
971  MQ.Mult(nk_phys, dofs_k);
972  for (int r = 0; r < MQ.Height(); r++)
973  {
974  dofs(k+dof*r) = dofs_k(r);
975  }
976  }
977 }
978 
980  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
982 {
983  if (fe.GetRangeType() == SCALAR)
984  {
985  double vk[Geometry::MaxDim];
986  Vector shape(fe.GetDof());
987  int sdim = Trans.GetSpaceDim();
988 
989  I.SetSize(dof, sdim*fe.GetDof());
990  for (int k = 0; k < dof; k++)
991  {
992  const IntegrationPoint &ip = Nodes.IntPoint(k);
993 
994  fe.CalcShape(ip, shape);
995  Trans.SetIntPoint(&ip);
996  Trans.AdjugateJacobian().MultTranspose(nk + d2n[k]*dim, vk);
997  if (fe.GetMapType() == INTEGRAL)
998  {
999  double w = 1.0/Trans.Weight();
1000  for (int d = 0; d < dim; d++)
1001  {
1002  vk[d] *= w;
1003  }
1004  }
1005 
1006  for (int j = 0; j < shape.Size(); j++)
1007  {
1008  double s = shape(j);
1009  if (fabs(s) < 1e-12)
1010  {
1011  s = 0.0;
1012  }
1013  for (int d = 0; d < sdim; d++)
1014  {
1015  I(k,j+d*shape.Size()) = s*vk[d];
1016  }
1017  }
1018  }
1019  }
1020  else
1021  {
1022  mfem_error("VectorFiniteElement::Project_RT (fe version)");
1023  }
1024 }
1025 
1027  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
1028  ElementTransformation &Trans, DenseMatrix &grad) const
1029 {
1030  if (dim != 2)
1031  {
1032  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
1033  }
1034 
1035  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
1036  Vector grad_k(fe.GetDof());
1037  double tk[2];
1038 
1039  grad.SetSize(dof, fe.GetDof());
1040  for (int k = 0; k < dof; k++)
1041  {
1042  fe.CalcDShape(Nodes.IntPoint(k), dshape);
1043  tk[0] = nk[d2n[k]*dim+1];
1044  tk[1] = -nk[d2n[k]*dim];
1045  dshape.Mult(tk, grad_k);
1046  for (int j = 0; j < grad_k.Size(); j++)
1047  {
1048  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1049  }
1050  }
1051 }
1052 
1054  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1055  ElementTransformation &Trans, DenseMatrix &curl) const
1056 {
1057 #ifdef MFEM_THREAD_SAFE
1060  DenseMatrix J(dim, dim);
1061 #else
1062  curlshape.SetSize(fe.GetDof(), dim);
1063  curlshape_J.SetSize(fe.GetDof(), dim);
1064  J.SetSize(dim, dim);
1065 #endif
1066 
1067  Vector curl_k(fe.GetDof());
1068 
1069  curl.SetSize(dof, fe.GetDof());
1070  for (int k = 0; k < dof; k++)
1071  {
1072  const IntegrationPoint &ip = Nodes.IntPoint(k);
1073 
1074  // calculate J^t * J / |J|
1075  Trans.SetIntPoint(&ip);
1076  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
1077  J *= 1.0 / Trans.Weight();
1078 
1079  // transform curl of shapes (rows) by J^t * J / |J|
1080  fe.CalcCurlShape(ip, curlshape);
1081  Mult(curlshape, J, curlshape_J);
1082 
1083  curlshape_J.Mult(tk + d2t[k]*dim, curl_k);
1084  for (int j = 0; j < curl_k.Size(); j++)
1085  {
1086  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
1087  }
1088  }
1089 }
1090 
1092  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
1093  ElementTransformation &Trans, DenseMatrix &curl) const
1094 {
1095  DenseMatrix curl_shape(fe.GetDof(), dim);
1096  Vector curl_k(fe.GetDof());
1097 
1098  curl.SetSize(dof, fe.GetDof());
1099  for (int k = 0; k < dof; k++)
1100  {
1101  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
1102  curl_shape.Mult(nk + d2n[k]*dim, curl_k);
1103  for (int j = 0; j < curl_k.Size(); j++)
1104  {
1105  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
1106  }
1107  }
1108 }
1109 
1111  const double *tk, const Array<int> &d2t,
1113 {
1114  double vk[Geometry::MaxDim];
1115  Vector xk(vk, vc.GetVDim());
1116 
1117  for (int k = 0; k < dof; k++)
1118  {
1119  Trans.SetIntPoint(&Nodes.IntPoint(k));
1120 
1121  vc.Eval(xk, Trans, Nodes.IntPoint(k));
1122  // dof_k = xk^t J tk
1123  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*dim, vk);
1124  }
1125 }
1126 
1128  const double *tk, const Array<int> &d2t,
1129  Vector &vc, ElementTransformation &Trans, Vector &dofs) const
1130 {
1131  for (int k = 0; k < dof; k++)
1132  {
1133  Trans.SetIntPoint(&Nodes.IntPoint(k));
1134  Vector vk(vc.GetData()+k*dim, dim);
1135  // dof_k = xk^t J tk
1136  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*dim, vk);
1137  }
1138 }
1139 
1141  const double *tk, const Array<int> &d2t,
1142  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
1143 {
1144  // project the rows of the matrix coefficient in an ND space
1145 
1146  const int sdim = T.GetSpaceDim();
1147  MFEM_ASSERT(mc.GetWidth() == sdim, "");
1148  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
1149  Vector tk_phys(sdim), dofs_k(MQ.Height());
1150  MFEM_ASSERT(dofs.Size() == dof*MQ.Height(), "");
1151 
1152  for (int k = 0; k < dof; k++)
1153  {
1154  T.SetIntPoint(&Nodes.IntPoint(k));
1155  mc.Eval(MQ, T, Nodes.IntPoint(k));
1156  // tk_phys = J tk
1157  T.Jacobian().Mult(tk + d2t[k]*dim, tk_phys);
1158  MQ.Mult(tk_phys, dofs_k);
1159  for (int r = 0; r < MQ.Height(); r++)
1160  {
1161  dofs(k+dof*r) = dofs_k(r);
1162  }
1163  }
1164 }
1165 
1167  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1169 {
1170  if (fe.GetRangeType() == SCALAR)
1171  {
1172  int sdim = Trans.GetSpaceDim();
1173  double vk[Geometry::MaxDim];
1174  Vector shape(fe.GetDof());
1175 
1176  I.SetSize(dof, sdim*fe.GetDof());
1177  for (int k = 0; k < dof; k++)
1178  {
1179  const IntegrationPoint &ip = Nodes.IntPoint(k);
1180 
1181  fe.CalcShape(ip, shape);
1182  Trans.SetIntPoint(&ip);
1183  Trans.Jacobian().Mult(tk + d2t[k]*dim, vk);
1184  if (fe.GetMapType() == INTEGRAL)
1185  {
1186  double w = 1.0/Trans.Weight();
1187  for (int d = 0; d < sdim; d++)
1188  {
1189  vk[d] *= w;
1190  }
1191  }
1192 
1193  for (int j = 0; j < shape.Size(); j++)
1194  {
1195  double s = shape(j);
1196  if (fabs(s) < 1e-12)
1197  {
1198  s = 0.0;
1199  }
1200  for (int d = 0; d < sdim; d++)
1201  {
1202  I(k, j + d*shape.Size()) = s*vk[d];
1203  }
1204  }
1205  }
1206  }
1207  else
1208  {
1209  mfem_error("VectorFiniteElement::Project_ND (fe version)");
1210  }
1211 }
1212 
1214  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1215  ElementTransformation &Trans, DenseMatrix &grad) const
1216 {
1217  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
1218 
1219  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
1220  Vector grad_k(fe.GetDof());
1221 
1222  grad.SetSize(dof, fe.GetDof());
1223  for (int k = 0; k < dof; k++)
1224  {
1225  fe.CalcDShape(Nodes.IntPoint(k), dshape);
1226  dshape.Mult(tk + d2t[k]*dim, grad_k);
1227  for (int j = 0; j < grad_k.Size(); j++)
1228  {
1229  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1230  }
1231  }
1232 }
1233 
1235  const VectorFiniteElement &cfe, const double *nk, const Array<int> &d2n,
1237 {
1238  MFEM_ASSERT(map_type == cfe.GetMapType(), "");
1239 
1240  double vk[Geometry::MaxDim];
1241  Vector xk(vk, dim);
1242  IntegrationPoint ip;
1243 #ifdef MFEM_THREAD_SAFE
1244  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
1245 #else
1246  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
1247 #endif
1248  I.SetSize(dof, vshape.Height());
1249 
1250  // assuming Trans is linear; this should be ok for all refinement types
1252  const DenseMatrix &adjJ = Trans.AdjugateJacobian();
1253  for (int k = 0; k < dof; k++)
1254  {
1255  Trans.Transform(Nodes.IntPoint(k), xk);
1256  ip.Set3(vk);
1257  cfe.CalcVShape(ip, vshape);
1258  // xk = |J| J^{-t} n_k
1259  adjJ.MultTranspose(nk + d2n[k]*dim, vk);
1260  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,dof
1261  for (int j = 0; j < vshape.Height(); j++)
1262  {
1263  double Ikj = 0.;
1264  for (int i = 0; i < dim; i++)
1265  {
1266  Ikj += vshape(j, i) * vk[i];
1267  }
1268  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1269  }
1270  }
1271 }
1272 
1274  const VectorFiniteElement &cfe, const double *tk, const Array<int> &d2t,
1276 {
1277  double vk[Geometry::MaxDim];
1278  Vector xk(vk, dim);
1279  IntegrationPoint ip;
1280 #ifdef MFEM_THREAD_SAFE
1281  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
1282 #else
1283  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
1284 #endif
1285  I.SetSize(dof, vshape.Height());
1286 
1287  // assuming Trans is linear; this should be ok for all refinement types
1289  const DenseMatrix &J = Trans.Jacobian();
1290  for (int k = 0; k < dof; k++)
1291  {
1292  Trans.Transform(Nodes.IntPoint(k), xk);
1293  ip.Set3(vk);
1294  cfe.CalcVShape(ip, vshape);
1295  // xk = J t_k
1296  J.Mult(tk + d2t[k]*dim, vk);
1297  // I_k = vshape_k.J.t_k, k=1,...,Dof
1298  for (int j = 0; j < vshape.Height(); j++)
1299  {
1300  double Ikj = 0.;
1301  for (int i = 0; i < dim; i++)
1302  {
1303  Ikj += vshape(j, i) * vk[i];
1304  }
1305  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1306  }
1307  }
1308 }
1309 
1311  const double *nk, const Array<int> &d2n, ElementTransformation &Trans,
1312  DenseMatrix &R) const
1313 {
1314  double pt_data[Geometry::MaxDim];
1315  IntegrationPoint ip;
1316  Vector pt(pt_data, dim);
1317 
1318 #ifdef MFEM_THREAD_SAFE
1320 #endif
1321 
1323  const DenseMatrix &J = Trans.Jacobian();
1324  const double weight = Trans.Weight();
1325  for (int j = 0; j < dof; j++)
1326  {
1327  InvertLinearTrans(Trans, Nodes.IntPoint(j), pt);
1328  ip.Set(pt_data, dim);
1329  if (Geometries.CheckPoint(geom_type, ip)) // do we need an epsilon here?
1330  {
1331  CalcVShape(ip, vshape);
1332  J.MultTranspose(nk+dim*d2n[j], pt_data);
1333  pt /= weight;
1334  for (int k = 0; k < dof; k++)
1335  {
1336  double R_jk = 0.0;
1337  for (int d = 0; d < dim; d++)
1338  {
1339  R_jk += vshape(k,d)*pt_data[d];
1340  }
1341  R(j,k) = R_jk;
1342  }
1343  }
1344  else
1345  {
1346  // Set the whole row to avoid valgrind warnings in R.Threshold().
1347  R.SetRow(j, infinity());
1348  }
1349  }
1350  R.Threshold(1e-12);
1351 }
1352 
1354  const double *tk, const Array<int> &d2t, ElementTransformation &Trans,
1355  DenseMatrix &R) const
1356 {
1357  double pt_data[Geometry::MaxDim];
1358  IntegrationPoint ip;
1359  Vector pt(pt_data, dim);
1360 
1361 #ifdef MFEM_THREAD_SAFE
1363 #endif
1364 
1366  const DenseMatrix &Jinv = Trans.InverseJacobian();
1367  for (int j = 0; j < dof; j++)
1368  {
1369  InvertLinearTrans(Trans, Nodes.IntPoint(j), pt);
1370  ip.Set(pt_data, dim);
1371  if (Geometries.CheckPoint(geom_type, ip)) // do we need an epsilon here?
1372  {
1373  CalcVShape(ip, vshape);
1374  Jinv.Mult(tk+dim*d2t[j], pt_data);
1375  for (int k = 0; k < dof; k++)
1376  {
1377  double R_jk = 0.0;
1378  for (int d = 0; d < dim; d++)
1379  {
1380  R_jk += vshape(k,d)*pt_data[d];
1381  }
1382  R(j,k) = R_jk;
1383  }
1384  }
1385  else
1386  {
1387  // Set the whole row to avoid valgrind warnings in R.Threshold().
1388  R.SetRow(j, infinity());
1389  }
1390  }
1391  R.Threshold(1e-12);
1392 }
1393 
1394 
1396  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
1397 {
1398  Nodes.IntPoint(0).x = 0.0;
1399 }
1400 
1402  Vector &shape) const
1403 {
1404  shape(0) = 1.;
1405 }
1406 
1408  DenseMatrix &dshape) const
1409 {
1410  // dshape is (1 x 0) - nothing to compute
1411 }
1412 
1414  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
1415 {
1416  Nodes.IntPoint(0).x = 0.0;
1417  Nodes.IntPoint(1).x = 1.0;
1418 }
1419 
1421  Vector &shape) const
1422 {
1423  shape(0) = 1. - ip.x;
1424  shape(1) = ip.x;
1425 }
1426 
1428  DenseMatrix &dshape) const
1429 {
1430  dshape(0,0) = -1.;
1431  dshape(1,0) = 1.;
1432 }
1433 
1435  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
1436 {
1437  Nodes.IntPoint(0).x = 0.0;
1438  Nodes.IntPoint(0).y = 0.0;
1439  Nodes.IntPoint(1).x = 1.0;
1440  Nodes.IntPoint(1).y = 0.0;
1441  Nodes.IntPoint(2).x = 0.0;
1442  Nodes.IntPoint(2).y = 1.0;
1443 }
1444 
1446  Vector &shape) const
1447 {
1448  shape(0) = 1. - ip.x - ip.y;
1449  shape(1) = ip.x;
1450  shape(2) = ip.y;
1451 }
1452 
1454  DenseMatrix &dshape) const
1455 {
1456  dshape(0,0) = -1.; dshape(0,1) = -1.;
1457  dshape(1,0) = 1.; dshape(1,1) = 0.;
1458  dshape(2,0) = 0.; dshape(2,1) = 1.;
1459 }
1460 
1462  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1463 {
1464  Nodes.IntPoint(0).x = 0.0;
1465  Nodes.IntPoint(0).y = 0.0;
1466  Nodes.IntPoint(1).x = 1.0;
1467  Nodes.IntPoint(1).y = 0.0;
1468  Nodes.IntPoint(2).x = 1.0;
1469  Nodes.IntPoint(2).y = 1.0;
1470  Nodes.IntPoint(3).x = 0.0;
1471  Nodes.IntPoint(3).y = 1.0;
1472 }
1473 
1475  Vector &shape) const
1476 {
1477  shape(0) = (1. - ip.x) * (1. - ip.y) ;
1478  shape(1) = ip.x * (1. - ip.y) ;
1479  shape(2) = ip.x * ip.y ;
1480  shape(3) = (1. - ip.x) * ip.y ;
1481 }
1482 
1484  DenseMatrix &dshape) const
1485 {
1486  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
1487  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
1488  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
1489  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
1490 }
1491 
1493  const IntegrationPoint &ip, DenseMatrix &h) const
1494 {
1495  h(0,0) = 0.; h(0,1) = 1.; h(0,2) = 0.;
1496  h(1,0) = 0.; h(1,1) = -1.; h(1,2) = 0.;
1497  h(2,0) = 0.; h(2,1) = 1.; h(2,2) = 0.;
1498  h(3,0) = 0.; h(3,1) = -1.; h(3,2) = 0.;
1499 }
1500 
1501 
1503  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
1504 {
1505  Nodes.IntPoint(0).x = 1./6.;
1506  Nodes.IntPoint(0).y = 1./6.;
1507  Nodes.IntPoint(1).x = 2./3.;
1508  Nodes.IntPoint(1).y = 1./6.;
1509  Nodes.IntPoint(2).x = 1./6.;
1510  Nodes.IntPoint(2).y = 2./3.;
1511 }
1512 
1514  Vector &shape) const
1515 {
1516  const double x = ip.x, y = ip.y;
1517 
1518  shape(0) = 5./3. - 2. * (x + y);
1519  shape(1) = 2. * (x - 1./6.);
1520  shape(2) = 2. * (y - 1./6.);
1521 }
1522 
1524  DenseMatrix &dshape) const
1525 {
1526  dshape(0,0) = -2.; dshape(0,1) = -2.;
1527  dshape(1,0) = 2.; dshape(1,1) = 0.;
1528  dshape(2,0) = 0.; dshape(2,1) = 2.;
1529 }
1530 
1532 {
1533  dofs(vertex) = 2./3.;
1534  dofs((vertex+1)%3) = 1./6.;
1535  dofs((vertex+2)%3) = 1./6.;
1536 }
1537 
1538 
1539 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
1540 const double GaussBiLinear2DFiniteElement::p[] =
1541 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
1542 
1544  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1545 {
1546  Nodes.IntPoint(0).x = p[0];
1547  Nodes.IntPoint(0).y = p[0];
1548  Nodes.IntPoint(1).x = p[1];
1549  Nodes.IntPoint(1).y = p[0];
1550  Nodes.IntPoint(2).x = p[1];
1551  Nodes.IntPoint(2).y = p[1];
1552  Nodes.IntPoint(3).x = p[0];
1553  Nodes.IntPoint(3).y = p[1];
1554 }
1555 
1557  Vector &shape) const
1558 {
1559  const double x = ip.x, y = ip.y;
1560 
1561  shape(0) = 3. * (p[1] - x) * (p[1] - y);
1562  shape(1) = 3. * (x - p[0]) * (p[1] - y);
1563  shape(2) = 3. * (x - p[0]) * (y - p[0]);
1564  shape(3) = 3. * (p[1] - x) * (y - p[0]);
1565 }
1566 
1568  DenseMatrix &dshape) const
1569 {
1570  const double x = ip.x, y = ip.y;
1571 
1572  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
1573  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
1574  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
1575  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
1576 }
1577 
1579 {
1580 #if 1
1581  dofs(vertex) = p[1]*p[1];
1582  dofs((vertex+1)%4) = p[0]*p[1];
1583  dofs((vertex+2)%4) = p[0]*p[0];
1584  dofs((vertex+3)%4) = p[0]*p[1];
1585 #else
1586  dofs = 1.0;
1587 #endif
1588 }
1589 
1590 
1592  : NodalFiniteElement(2, Geometry::SQUARE, 3, 1, FunctionSpace::Qk)
1593 {
1594  Nodes.IntPoint(0).x = 0.0;
1595  Nodes.IntPoint(0).y = 0.0;
1596  Nodes.IntPoint(1).x = 1.0;
1597  Nodes.IntPoint(1).y = 0.0;
1598  Nodes.IntPoint(2).x = 0.0;
1599  Nodes.IntPoint(2).y = 1.0;
1600 }
1601 
1603  Vector &shape) const
1604 {
1605  shape(0) = 1. - ip.x - ip.y;
1606  shape(1) = ip.x;
1607  shape(2) = ip.y;
1608 }
1609 
1611  DenseMatrix &dshape) const
1612 {
1613  dshape(0,0) = -1.; dshape(0,1) = -1.;
1614  dshape(1,0) = 1.; dshape(1,1) = 0.;
1615  dshape(2,0) = 0.; dshape(2,1) = 1.;
1616 }
1617 
1618 
1620  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
1621 {
1622  Nodes.IntPoint(0).x = 0.0;
1623  Nodes.IntPoint(1).x = 1.0;
1624  Nodes.IntPoint(2).x = 0.5;
1625 }
1626 
1628  Vector &shape) const
1629 {
1630  double x = ip.x;
1631  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
1632 
1633  shape(0) = l1 * (-l3);
1634  shape(1) = l2 * l3;
1635  shape(2) = 4. * l1 * l2;
1636 }
1637 
1639  DenseMatrix &dshape) const
1640 {
1641  double x = ip.x;
1642 
1643  dshape(0,0) = 4. * x - 3.;
1644  dshape(1,0) = 4. * x - 1.;
1645  dshape(2,0) = 4. - 8. * x;
1646 }
1647 
1648 
1650  : PositiveFiniteElement(1, Geometry::SEGMENT, 3, 2)
1651 {
1652  Nodes.IntPoint(0).x = 0.0;
1653  Nodes.IntPoint(1).x = 1.0;
1654  Nodes.IntPoint(2).x = 0.5;
1655 }
1656 
1658  Vector &shape) const
1659 {
1660  const double x = ip.x, x1 = 1. - x;
1661 
1662  shape(0) = x1 * x1;
1663  shape(1) = x * x;
1664  shape(2) = 2. * x * x1;
1665 }
1666 
1668  DenseMatrix &dshape) const
1669 {
1670  const double x = ip.x;
1671 
1672  dshape(0,0) = 2. * x - 2.;
1673  dshape(1,0) = 2. * x;
1674  dshape(2,0) = 2. - 4. * x;
1675 }
1676 
1678  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1679 {
1680  Nodes.IntPoint(0).x = 0.0;
1681  Nodes.IntPoint(0).y = 0.0;
1682  Nodes.IntPoint(1).x = 1.0;
1683  Nodes.IntPoint(1).y = 0.0;
1684  Nodes.IntPoint(2).x = 0.0;
1685  Nodes.IntPoint(2).y = 1.0;
1686  Nodes.IntPoint(3).x = 0.5;
1687  Nodes.IntPoint(3).y = 0.0;
1688  Nodes.IntPoint(4).x = 0.5;
1689  Nodes.IntPoint(4).y = 0.5;
1690  Nodes.IntPoint(5).x = 0.0;
1691  Nodes.IntPoint(5).y = 0.5;
1692 }
1693 
1695  Vector &shape) const
1696 {
1697  double x = ip.x, y = ip.y;
1698  double l1 = 1.-x-y, l2 = x, l3 = y;
1699 
1700  shape(0) = l1 * (2. * l1 - 1.);
1701  shape(1) = l2 * (2. * l2 - 1.);
1702  shape(2) = l3 * (2. * l3 - 1.);
1703  shape(3) = 4. * l1 * l2;
1704  shape(4) = 4. * l2 * l3;
1705  shape(5) = 4. * l3 * l1;
1706 }
1707 
1709  DenseMatrix &dshape) const
1710 {
1711  double x = ip.x, y = ip.y;
1712 
1713  dshape(0,0) =
1714  dshape(0,1) = 4. * (x + y) - 3.;
1715 
1716  dshape(1,0) = 4. * x - 1.;
1717  dshape(1,1) = 0.;
1718 
1719  dshape(2,0) = 0.;
1720  dshape(2,1) = 4. * y - 1.;
1721 
1722  dshape(3,0) = -4. * (2. * x + y - 1.);
1723  dshape(3,1) = -4. * x;
1724 
1725  dshape(4,0) = 4. * y;
1726  dshape(4,1) = 4. * x;
1727 
1728  dshape(5,0) = -4. * y;
1729  dshape(5,1) = -4. * (x + 2. * y - 1.);
1730 }
1731 
1733  DenseMatrix &h) const
1734 {
1735  h(0,0) = 4.;
1736  h(0,1) = 4.;
1737  h(0,2) = 4.;
1738 
1739  h(1,0) = 4.;
1740  h(1,1) = 0.;
1741  h(1,2) = 0.;
1742 
1743  h(2,0) = 0.;
1744  h(2,1) = 0.;
1745  h(2,2) = 4.;
1746 
1747  h(3,0) = -8.;
1748  h(3,1) = -4.;
1749  h(3,2) = 0.;
1750 
1751  h(4,0) = 0.;
1752  h(4,1) = 4.;
1753  h(4,2) = 0.;
1754 
1755  h(5,0) = 0.;
1756  h(5,1) = -4.;
1757  h(5,2) = -8.;
1758 }
1759 
1760 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1761 {
1762 #if 0
1763  dofs = 1.;
1764 #else
1765  dofs = 0.;
1766  dofs(vertex) = 1.;
1767  switch (vertex)
1768  {
1769  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1770  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1771  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1772  }
1773 #endif
1774 }
1775 
1776 
1777 const double GaussQuad2DFiniteElement::p[] =
1778 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1779 
1781  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1782 {
1783  Nodes.IntPoint(0).x = p[0];
1784  Nodes.IntPoint(0).y = p[0];
1785  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1786  Nodes.IntPoint(1).y = p[0];
1787  Nodes.IntPoint(2).x = p[0];
1788  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1789  Nodes.IntPoint(3).x = p[1];
1790  Nodes.IntPoint(3).y = p[1];
1791  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1792  Nodes.IntPoint(4).y = p[1];
1793  Nodes.IntPoint(5).x = p[1];
1794  Nodes.IntPoint(5).y = 1. - 2. * p[1];
1795 
1796  for (int i = 0; i < 6; i++)
1797  {
1798  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
1799  A(0,i) = 1.;
1800  A(1,i) = x;
1801  A(2,i) = y;
1802  A(3,i) = x * x;
1803  A(4,i) = x * y;
1804  A(5,i) = y * y;
1805  }
1806 
1807  A.Invert();
1808 }
1809 
1811  Vector &shape) const
1812 {
1813  const double x = ip.x, y = ip.y;
1814  pol(0) = 1.;
1815  pol(1) = x;
1816  pol(2) = y;
1817  pol(3) = x * x;
1818  pol(4) = x * y;
1819  pol(5) = y * y;
1820 
1821  A.Mult(pol, shape);
1822 }
1823 
1825  DenseMatrix &dshape) const
1826 {
1827  const double x = ip.x, y = ip.y;
1828  D(0,0) = 0.; D(0,1) = 0.;
1829  D(1,0) = 1.; D(1,1) = 0.;
1830  D(2,0) = 0.; D(2,1) = 1.;
1831  D(3,0) = 2. * x; D(3,1) = 0.;
1832  D(4,0) = y; D(4,1) = x;
1833  D(5,0) = 0.; D(5,1) = 2. * y;
1834 
1835  Mult(A, D, dshape);
1836 }
1837 
1838 
1840  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1841 {
1842  Nodes.IntPoint(0).x = 0.0;
1843  Nodes.IntPoint(0).y = 0.0;
1844  Nodes.IntPoint(1).x = 1.0;
1845  Nodes.IntPoint(1).y = 0.0;
1846  Nodes.IntPoint(2).x = 1.0;
1847  Nodes.IntPoint(2).y = 1.0;
1848  Nodes.IntPoint(3).x = 0.0;
1849  Nodes.IntPoint(3).y = 1.0;
1850  Nodes.IntPoint(4).x = 0.5;
1851  Nodes.IntPoint(4).y = 0.0;
1852  Nodes.IntPoint(5).x = 1.0;
1853  Nodes.IntPoint(5).y = 0.5;
1854  Nodes.IntPoint(6).x = 0.5;
1855  Nodes.IntPoint(6).y = 1.0;
1856  Nodes.IntPoint(7).x = 0.0;
1857  Nodes.IntPoint(7).y = 0.5;
1858  Nodes.IntPoint(8).x = 0.5;
1859  Nodes.IntPoint(8).y = 0.5;
1860 }
1861 
1863  Vector &shape) const
1864 {
1865  double x = ip.x, y = ip.y;
1866  double l1x, l2x, l3x, l1y, l2y, l3y;
1867 
1868  l1x = (x - 1.) * (2. * x - 1);
1869  l2x = 4. * x * (1. - x);
1870  l3x = x * (2. * x - 1.);
1871  l1y = (y - 1.) * (2. * y - 1);
1872  l2y = 4. * y * (1. - y);
1873  l3y = y * (2. * y - 1.);
1874 
1875  shape(0) = l1x * l1y;
1876  shape(4) = l2x * l1y;
1877  shape(1) = l3x * l1y;
1878  shape(7) = l1x * l2y;
1879  shape(8) = l2x * l2y;
1880  shape(5) = l3x * l2y;
1881  shape(3) = l1x * l3y;
1882  shape(6) = l2x * l3y;
1883  shape(2) = l3x * l3y;
1884 }
1885 
1887  DenseMatrix &dshape) const
1888 {
1889  double x = ip.x, y = ip.y;
1890  double l1x, l2x, l3x, l1y, l2y, l3y;
1891  double d1x, d2x, d3x, d1y, d2y, d3y;
1892 
1893  l1x = (x - 1.) * (2. * x - 1);
1894  l2x = 4. * x * (1. - x);
1895  l3x = x * (2. * x - 1.);
1896  l1y = (y - 1.) * (2. * y - 1);
1897  l2y = 4. * y * (1. - y);
1898  l3y = y * (2. * y - 1.);
1899 
1900  d1x = 4. * x - 3.;
1901  d2x = 4. - 8. * x;
1902  d3x = 4. * x - 1.;
1903  d1y = 4. * y - 3.;
1904  d2y = 4. - 8. * y;
1905  d3y = 4. * y - 1.;
1906 
1907  dshape(0,0) = d1x * l1y;
1908  dshape(0,1) = l1x * d1y;
1909 
1910  dshape(4,0) = d2x * l1y;
1911  dshape(4,1) = l2x * d1y;
1912 
1913  dshape(1,0) = d3x * l1y;
1914  dshape(1,1) = l3x * d1y;
1915 
1916  dshape(7,0) = d1x * l2y;
1917  dshape(7,1) = l1x * d2y;
1918 
1919  dshape(8,0) = d2x * l2y;
1920  dshape(8,1) = l2x * d2y;
1921 
1922  dshape(5,0) = d3x * l2y;
1923  dshape(5,1) = l3x * d2y;
1924 
1925  dshape(3,0) = d1x * l3y;
1926  dshape(3,1) = l1x * d3y;
1927 
1928  dshape(6,0) = d2x * l3y;
1929  dshape(6,1) = l2x * d3y;
1930 
1931  dshape(2,0) = d3x * l3y;
1932  dshape(2,1) = l3x * d3y;
1933 }
1934 
1935 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1936 {
1937 #if 0
1938  dofs = 1.;
1939 #else
1940  dofs = 0.;
1941  dofs(vertex) = 1.;
1942  switch (vertex)
1943  {
1944  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
1945  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
1946  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
1947  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
1948  }
1949  dofs(8) = 1./16.;
1950 #endif
1951 }
1952 
1953 
1955  : ScalarFiniteElement(2, Geometry::SQUARE, (p*p + 3*p +6) / 2, p,
1956  FunctionSpace::Qk)
1957 {
1958  // Store the dof_map of the associated TensorBasisElement, which will be used
1959  // to create the serendipity dof map. Its size is larger than the size of
1960  // the serendipity element.
1961  TensorBasisElement tbeTemp =
1963  TensorBasisElement::DofMapType::Sr_DOF_MAP);
1964  const Array<int> tp_dof_map = tbeTemp.GetDofMap();
1965 
1966  const double *cp = poly1d.ClosedPoints(p, BasisType::GaussLobatto);
1967 
1968  // Fixing the Nodes is exactly the same as the H1_QuadrilateralElement
1969  // constructor except we only use those values of the associated tensor
1970  // product dof_map that are <= the number of serendipity Dofs e.g. only DoFs
1971  // 0-7 out of the 9 tensor product dofs (at quadratic order)
1972  int o = 0;
1973 
1974  for (int j = 0; j <= p; j++)
1975  {
1976  for (int i = 0; i <= p; i++)
1977  {
1978  if (tp_dof_map[o] < Nodes.Size())
1979  {
1980  Nodes.IntPoint(tp_dof_map[o]).x = cp[i];
1981  Nodes.IntPoint(tp_dof_map[o]).y = cp[j];
1982  }
1983  o++;
1984  }
1985  }
1986 }
1987 
1989  Vector &shape) const
1990 {
1991  int p = (this)->GetOrder();
1992  double x = ip.x, y = ip.y;
1993 
1995  Vector nodalX(p+1);
1996  Vector nodalY(p+1);
1997 
1998  edgeNodalBasis.Eval(x, nodalX);
1999  edgeNodalBasis.Eval(y, nodalY);
2000 
2001  // First, fix edge-based shape functions. Use a nodal interpolant for edge
2002  // points, weighted by the linear function that vanishes on opposite edge.
2003  for (int i = 0; i < p-1; i++)
2004  {
2005  shape(4 + 0*(p-1) + i) = (nodalX(i+1))*(1.-y); // south edge 0->1
2006  shape(4 + 1*(p-1) + i) = (nodalY(i+1))*x; // east edge 1->2
2007  shape(4 + 3*(p-1) - i - 1) = (nodalX(i+1)) * y; // north edge 3->2
2008  shape(4 + 4*(p-1) - i - 1) = (nodalY(i+1)) * (1. - x); // west edge 0->3
2009  }
2010 
2012  Vector bilinearsAtIP(4);
2013  bilinear.CalcShape(ip, bilinearsAtIP);
2014 
2015  const double *edgePts(poly1d.ClosedPoints(p, BasisType::GaussLobatto));
2016 
2017  // Next, set the shape function associated with vertex V, evaluated at (x,y)
2018  // to be: bilinear function associated to V, evaluated at (x,y) - sum (shape
2019  // function at edge point P, weighted by bilinear function for V evaluated at
2020  // P) where the sum is taken only for points P on edges incident to V.
2021 
2022  double vtx0fix =0;
2023  double vtx1fix =0;
2024  double vtx2fix =0;
2025  double vtx3fix =0;
2026  for (int i = 0; i<p-1; i++)
2027  {
2028  vtx0fix += (1-edgePts[i+1])*(shape(4 + i) +
2029  shape(4 + 4*(p-1) - i - 1)); // bot+left edge
2030  vtx1fix += (1-edgePts[i+1])*(shape(4 + 1*(p-1) + i) +
2031  shape(4 + (p-2)-i)); // right+bot edge
2032  vtx2fix += (1-edgePts[i+1])*(shape(4 + 2*(p-1) + i) +
2033  shape(1 + 2*p-i)); // top+right edge
2034  vtx3fix += (1-edgePts[i+1])*(shape(4 + 3*(p-1) + i) +
2035  shape(3*p - i)); // left+top edge
2036  }
2037  shape(0) = bilinearsAtIP(0) - vtx0fix;
2038  shape(1) = bilinearsAtIP(1) - vtx1fix;
2039  shape(2) = bilinearsAtIP(2) - vtx2fix;
2040  shape(3) = bilinearsAtIP(3) - vtx3fix;
2041 
2042  // Interior basis functions appear starting at order p=4. These are non-nodal
2043  // bubble functions.
2044  if (p > 3)
2045  {
2046  double *legX = new double[p-1];
2047  double *legY = new double[p-1];
2048  Poly_1D *storeLegendre = new Poly_1D();
2049 
2050  storeLegendre->CalcLegendre(p-2, x, legX);
2051  storeLegendre->CalcLegendre(p-2, y, legY);
2052 
2053  int interior_total = 0;
2054  for (int j = 4; j < p + 1; j++)
2055  {
2056  for (int k = 0; k < j-3; k++)
2057  {
2058  shape(4 + 4*(p-1) + interior_total)
2059  = legX[k] * legY[j-4-k] * x * (1. - x) * y * (1. - y);
2060  interior_total++;
2061  }
2062  }
2063 
2064  delete[] legX;
2065  delete[] legY;
2066  delete storeLegendre;
2067  }
2068 }
2069 
2071  DenseMatrix &dshape) const
2072 {
2073  int p = (this)->GetOrder();
2074  double x = ip.x, y = ip.y;
2075 
2077  Vector nodalX(p+1);
2078  Vector DnodalX(p+1);
2079  Vector nodalY(p+1);
2080  Vector DnodalY(p+1);
2081 
2082  edgeNodalBasis.Eval(x, nodalX, DnodalX);
2083  edgeNodalBasis.Eval(y, nodalY, DnodalY);
2084 
2085  for (int i = 0; i < p-1; i++)
2086  {
2087  dshape(4 + 0*(p-1) + i,0) = DnodalX(i+1) * (1.-y);
2088  dshape(4 + 0*(p-1) + i,1) = -nodalX(i+1);
2089  dshape(4 + 1*(p-1) + i,0) = nodalY(i+1);
2090  dshape(4 + 1*(p-1) + i,1) = DnodalY(i+1)*x;
2091  dshape(4 + 3*(p-1) - i - 1,0) = DnodalX(i+1)*y;
2092  dshape(4 + 3*(p-1) - i - 1,1) = nodalX(i+1);
2093  dshape(4 + 4*(p-1) - i - 1,0) = -nodalY(i+1);
2094  dshape(4 + 4*(p-1) - i - 1,1) = DnodalY(i+1) * (1.-x);
2095  }
2096 
2098  DenseMatrix DbilinearsAtIP(4);
2099  bilinear.CalcDShape(ip, DbilinearsAtIP);
2100 
2101  const double *edgePts(poly1d.ClosedPoints(p, BasisType::GaussLobatto));
2102 
2103  dshape(0,0) = DbilinearsAtIP(0,0);
2104  dshape(0,1) = DbilinearsAtIP(0,1);
2105  dshape(1,0) = DbilinearsAtIP(1,0);
2106  dshape(1,1) = DbilinearsAtIP(1,1);
2107  dshape(2,0) = DbilinearsAtIP(2,0);
2108  dshape(2,1) = DbilinearsAtIP(2,1);
2109  dshape(3,0) = DbilinearsAtIP(3,0);
2110  dshape(3,1) = DbilinearsAtIP(3,1);
2111 
2112  for (int i = 0; i<p-1; i++)
2113  {
2114  dshape(0,0) -= (1-edgePts[i+1])*(dshape(4 + 0*(p-1) + i, 0) +
2115  dshape(4 + 4*(p-1) - i - 1,0));
2116  dshape(0,1) -= (1-edgePts[i+1])*(dshape(4 + 0*(p-1) + i, 1) +
2117  dshape(4 + 4*(p-1) - i - 1,1));
2118  dshape(1,0) -= (1-edgePts[i+1])*(dshape(4 + 1*(p-1) + i, 0) +
2119  dshape(4 + (p-2)-i, 0));
2120  dshape(1,1) -= (1-edgePts[i+1])*(dshape(4 + 1*(p-1) + i, 1) +
2121  dshape(4 + (p-2)-i, 1));
2122  dshape(2,0) -= (1-edgePts[i+1])*(dshape(4 + 2*(p-1) + i, 0) +
2123  dshape(1 + 2*p-i, 0));
2124  dshape(2,1) -= (1-edgePts[i+1])*(dshape(4 + 2*(p-1) + i, 1) +
2125  dshape(1 + 2*p-i, 1));
2126  dshape(3,0) -= (1-edgePts[i+1])*(dshape(4 + 3*(p-1) + i, 0) +
2127  dshape(3*p - i, 0));
2128  dshape(3,1) -= (1-edgePts[i+1])*(dshape(4 + 3*(p-1) + i, 1) +
2129  dshape(3*p - i, 1));
2130  }
2131 
2132  if (p > 3)
2133  {
2134  double *legX = new double[p-1];
2135  double *legY = new double[p-1];
2136  double *DlegX = new double[p-1];
2137  double *DlegY = new double[p-1];
2138  Poly_1D *storeLegendre = new Poly_1D();
2139 
2140  storeLegendre->CalcLegendre(p-2, x, legX, DlegX);
2141  storeLegendre->CalcLegendre(p-2, y, legY, DlegY);
2142 
2143  int interior_total = 0;
2144  for (int j = 4; j < p + 1; j++)
2145  {
2146  for (int k = 0; k < j-3; k++)
2147  {
2148  dshape(4 + 4*(p-1) + interior_total, 0) =
2149  legY[j-4-k]*y*(1-y) * (DlegX[k]*x*(1-x) + legX[k]*(1-2*x));
2150  dshape(4 + 4*(p-1) + interior_total, 1) =
2151  legX[k]*x*(1-x) * (DlegY[j-4-k]*y*(1-y) + legY[j-4-k]*(1-2*y));
2152  interior_total++;
2153  }
2154  }
2155  delete[] legX;
2156  delete[] legY;
2157  delete[] DlegX;
2158  delete[] DlegY;
2159  delete storeLegendre;
2160  }
2161 }
2162 
2164  &Trans,
2165  DenseMatrix &I) const
2166 {
2167  // For p<=4, the basis is nodal; for p>4, the quad-interior functions are
2168  // non-nodal.
2169  if (order <= 4)
2170  {
2171  NodalLocalInterpolation(Trans, I, *this);
2172  }
2173  else
2174  {
2175  ScalarLocalInterpolation(Trans, I, *this);
2176  }
2177 }
2178 
2179 
2181  : PositiveFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
2182 {
2183  Nodes.IntPoint(0).x = 0.0;
2184  Nodes.IntPoint(0).y = 0.0;
2185  Nodes.IntPoint(1).x = 1.0;
2186  Nodes.IntPoint(1).y = 0.0;
2187  Nodes.IntPoint(2).x = 1.0;
2188  Nodes.IntPoint(2).y = 1.0;
2189  Nodes.IntPoint(3).x = 0.0;
2190  Nodes.IntPoint(3).y = 1.0;
2191  Nodes.IntPoint(4).x = 0.5;
2192  Nodes.IntPoint(4).y = 0.0;
2193  Nodes.IntPoint(5).x = 1.0;
2194  Nodes.IntPoint(5).y = 0.5;
2195  Nodes.IntPoint(6).x = 0.5;
2196  Nodes.IntPoint(6).y = 1.0;
2197  Nodes.IntPoint(7).x = 0.0;
2198  Nodes.IntPoint(7).y = 0.5;
2199  Nodes.IntPoint(8).x = 0.5;
2200  Nodes.IntPoint(8).y = 0.5;
2201 }
2202 
2204  Vector &shape) const
2205 {
2206  double x = ip.x, y = ip.y;
2207  double l1x, l2x, l3x, l1y, l2y, l3y;
2208 
2209  l1x = (1. - x) * (1. - x);
2210  l2x = 2. * x * (1. - x);
2211  l3x = x * x;
2212  l1y = (1. - y) * (1. - y);
2213  l2y = 2. * y * (1. - y);
2214  l3y = y * y;
2215 
2216  shape(0) = l1x * l1y;
2217  shape(4) = l2x * l1y;
2218  shape(1) = l3x * l1y;
2219  shape(7) = l1x * l2y;
2220  shape(8) = l2x * l2y;
2221  shape(5) = l3x * l2y;
2222  shape(3) = l1x * l3y;
2223  shape(6) = l2x * l3y;
2224  shape(2) = l3x * l3y;
2225 }
2226 
2228  DenseMatrix &dshape) const
2229 {
2230  double x = ip.x, y = ip.y;
2231  double l1x, l2x, l3x, l1y, l2y, l3y;
2232  double d1x, d2x, d3x, d1y, d2y, d3y;
2233 
2234  l1x = (1. - x) * (1. - x);
2235  l2x = 2. * x * (1. - x);
2236  l3x = x * x;
2237  l1y = (1. - y) * (1. - y);
2238  l2y = 2. * y * (1. - y);
2239  l3y = y * y;
2240 
2241  d1x = 2. * x - 2.;
2242  d2x = 2. - 4. * x;
2243  d3x = 2. * x;
2244  d1y = 2. * y - 2.;
2245  d2y = 2. - 4. * y;
2246  d3y = 2. * y;
2247 
2248  dshape(0,0) = d1x * l1y;
2249  dshape(0,1) = l1x * d1y;
2250 
2251  dshape(4,0) = d2x * l1y;
2252  dshape(4,1) = l2x * d1y;
2253 
2254  dshape(1,0) = d3x * l1y;
2255  dshape(1,1) = l3x * d1y;
2256 
2257  dshape(7,0) = d1x * l2y;
2258  dshape(7,1) = l1x * d2y;
2259 
2260  dshape(8,0) = d2x * l2y;
2261  dshape(8,1) = l2x * d2y;
2262 
2263  dshape(5,0) = d3x * l2y;
2264  dshape(5,1) = l3x * d2y;
2265 
2266  dshape(3,0) = d1x * l3y;
2267  dshape(3,1) = l1x * d3y;
2268 
2269  dshape(6,0) = d2x * l3y;
2270  dshape(6,1) = l2x * d3y;
2271 
2272  dshape(2,0) = d3x * l3y;
2273  dshape(2,1) = l3x * d3y;
2274 }
2275 
2278 {
2279  double s[9];
2280  IntegrationPoint tr_ip;
2281  Vector xx(&tr_ip.x, 2), shape(s, 9);
2282 
2283  for (int i = 0; i < 9; i++)
2284  {
2285  Trans.Transform(Nodes.IntPoint(i), xx);
2286  CalcShape(tr_ip, shape);
2287  for (int j = 0; j < 9; j++)
2288  if (fabs(I(i,j) = s[j]) < 1.0e-12)
2289  {
2290  I(i,j) = 0.0;
2291  }
2292  }
2293  for (int i = 0; i < 9; i++)
2294  {
2295  double *d = &I(0,i);
2296  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2297  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2298  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2299  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2300  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2301  0.25 * (d[0] + d[1] + d[2] + d[3]);
2302  }
2303 }
2304 
2306  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
2307 {
2308  double *d = dofs;
2309 
2310  for (int i = 0; i < 9; i++)
2311  {
2312  const IntegrationPoint &ip = Nodes.IntPoint(i);
2313  Trans.SetIntPoint(&ip);
2314  d[i] = coeff.Eval(Trans, ip);
2315  }
2316  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2317  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2318  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2319  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2320  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2321  0.25 * (d[0] + d[1] + d[2] + d[3]);
2322 }
2323 
2326  Vector &dofs) const
2327 {
2328  double v[3];
2329  Vector x (v, vc.GetVDim());
2330 
2331  for (int i = 0; i < 9; i++)
2332  {
2333  const IntegrationPoint &ip = Nodes.IntPoint(i);
2334  Trans.SetIntPoint(&ip);
2335  vc.Eval (x, Trans, ip);
2336  for (int j = 0; j < x.Size(); j++)
2337  {
2338  dofs(9*j+i) = v[j];
2339  }
2340  }
2341  for (int j = 0; j < x.Size(); j++)
2342  {
2343  double *d = &dofs(9*j);
2344 
2345  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2346  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2347  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2348  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2349  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2350  0.25 * (d[0] + d[1] + d[2] + d[3]);
2351  }
2352 }
2353 
2354 
2356  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
2357 {
2358  const double p1 = 0.5*(1.-sqrt(3./5.));
2359 
2360  Nodes.IntPoint(0).x = p1;
2361  Nodes.IntPoint(0).y = p1;
2362  Nodes.IntPoint(4).x = 0.5;
2363  Nodes.IntPoint(4).y = p1;
2364  Nodes.IntPoint(1).x = 1.-p1;
2365  Nodes.IntPoint(1).y = p1;
2366  Nodes.IntPoint(7).x = p1;
2367  Nodes.IntPoint(7).y = 0.5;
2368  Nodes.IntPoint(8).x = 0.5;
2369  Nodes.IntPoint(8).y = 0.5;
2370  Nodes.IntPoint(5).x = 1.-p1;
2371  Nodes.IntPoint(5).y = 0.5;
2372  Nodes.IntPoint(3).x = p1;
2373  Nodes.IntPoint(3).y = 1.-p1;
2374  Nodes.IntPoint(6).x = 0.5;
2375  Nodes.IntPoint(6).y = 1.-p1;
2376  Nodes.IntPoint(2).x = 1.-p1;
2377  Nodes.IntPoint(2).y = 1.-p1;
2378 }
2379 
2381  Vector &shape) const
2382 {
2383  const double a = sqrt(5./3.);
2384  const double p1 = 0.5*(1.-sqrt(3./5.));
2385 
2386  double x = a*(ip.x-p1), y = a*(ip.y-p1);
2387  double l1x, l2x, l3x, l1y, l2y, l3y;
2388 
2389  l1x = (x - 1.) * (2. * x - 1);
2390  l2x = 4. * x * (1. - x);
2391  l3x = x * (2. * x - 1.);
2392  l1y = (y - 1.) * (2. * y - 1);
2393  l2y = 4. * y * (1. - y);
2394  l3y = y * (2. * y - 1.);
2395 
2396  shape(0) = l1x * l1y;
2397  shape(4) = l2x * l1y;
2398  shape(1) = l3x * l1y;
2399  shape(7) = l1x * l2y;
2400  shape(8) = l2x * l2y;
2401  shape(5) = l3x * l2y;
2402  shape(3) = l1x * l3y;
2403  shape(6) = l2x * l3y;
2404  shape(2) = l3x * l3y;
2405 }
2406 
2408  DenseMatrix &dshape) const
2409 {
2410  const double a = sqrt(5./3.);
2411  const double p1 = 0.5*(1.-sqrt(3./5.));
2412 
2413  double x = a*(ip.x-p1), y = a*(ip.y-p1);
2414  double l1x, l2x, l3x, l1y, l2y, l3y;
2415  double d1x, d2x, d3x, d1y, d2y, d3y;
2416 
2417  l1x = (x - 1.) * (2. * x - 1);
2418  l2x = 4. * x * (1. - x);
2419  l3x = x * (2. * x - 1.);
2420  l1y = (y - 1.) * (2. * y - 1);
2421  l2y = 4. * y * (1. - y);
2422  l3y = y * (2. * y - 1.);
2423 
2424  d1x = a * (4. * x - 3.);
2425  d2x = a * (4. - 8. * x);
2426  d3x = a * (4. * x - 1.);
2427  d1y = a * (4. * y - 3.);
2428  d2y = a * (4. - 8. * y);
2429  d3y = a * (4. * y - 1.);
2430 
2431  dshape(0,0) = d1x * l1y;
2432  dshape(0,1) = l1x * d1y;
2433 
2434  dshape(4,0) = d2x * l1y;
2435  dshape(4,1) = l2x * d1y;
2436 
2437  dshape(1,0) = d3x * l1y;
2438  dshape(1,1) = l3x * d1y;
2439 
2440  dshape(7,0) = d1x * l2y;
2441  dshape(7,1) = l1x * d2y;
2442 
2443  dshape(8,0) = d2x * l2y;
2444  dshape(8,1) = l2x * d2y;
2445 
2446  dshape(5,0) = d3x * l2y;
2447  dshape(5,1) = l3x * d2y;
2448 
2449  dshape(3,0) = d1x * l3y;
2450  dshape(3,1) = l1x * d3y;
2451 
2452  dshape(6,0) = d2x * l3y;
2453  dshape(6,1) = l2x * d3y;
2454 
2455  dshape(2,0) = d3x * l3y;
2456  dshape(2,1) = l3x * d3y;
2457 }
2458 
2460  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
2461 {
2462  Nodes.IntPoint(0).x = 0.;
2463  Nodes.IntPoint(0).y = 0.;
2464  Nodes.IntPoint(1).x = 1.;
2465  Nodes.IntPoint(1).y = 0.;
2466  Nodes.IntPoint(2).x = 1.;
2467  Nodes.IntPoint(2).y = 1.;
2468  Nodes.IntPoint(3).x = 0.;
2469  Nodes.IntPoint(3).y = 1.;
2470  Nodes.IntPoint(4).x = 1./3.;
2471  Nodes.IntPoint(4).y = 0.;
2472  Nodes.IntPoint(5).x = 2./3.;
2473  Nodes.IntPoint(5).y = 0.;
2474  Nodes.IntPoint(6).x = 1.;
2475  Nodes.IntPoint(6).y = 1./3.;
2476  Nodes.IntPoint(7).x = 1.;
2477  Nodes.IntPoint(7).y = 2./3.;
2478  Nodes.IntPoint(8).x = 2./3.;
2479  Nodes.IntPoint(8).y = 1.;
2480  Nodes.IntPoint(9).x = 1./3.;
2481  Nodes.IntPoint(9).y = 1.;
2482  Nodes.IntPoint(10).x = 0.;
2483  Nodes.IntPoint(10).y = 2./3.;
2484  Nodes.IntPoint(11).x = 0.;
2485  Nodes.IntPoint(11).y = 1./3.;
2486  Nodes.IntPoint(12).x = 1./3.;
2487  Nodes.IntPoint(12).y = 1./3.;
2488  Nodes.IntPoint(13).x = 2./3.;
2489  Nodes.IntPoint(13).y = 1./3.;
2490  Nodes.IntPoint(14).x = 1./3.;
2491  Nodes.IntPoint(14).y = 2./3.;
2492  Nodes.IntPoint(15).x = 2./3.;
2493  Nodes.IntPoint(15).y = 2./3.;
2494 }
2495 
2497  const IntegrationPoint &ip, Vector &shape) const
2498 {
2499  double x = ip.x, y = ip.y;
2500 
2501  double w1x, w2x, w3x, w1y, w2y, w3y;
2502  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2503 
2504  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2505  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2506 
2507  l0x = (- 4.5) * w1x * w2x * w3x;
2508  l1x = ( 13.5) * x * w2x * w3x;
2509  l2x = (-13.5) * x * w1x * w3x;
2510  l3x = ( 4.5) * x * w1x * w2x;
2511 
2512  l0y = (- 4.5) * w1y * w2y * w3y;
2513  l1y = ( 13.5) * y * w2y * w3y;
2514  l2y = (-13.5) * y * w1y * w3y;
2515  l3y = ( 4.5) * y * w1y * w2y;
2516 
2517  shape(0) = l0x * l0y;
2518  shape(1) = l3x * l0y;
2519  shape(2) = l3x * l3y;
2520  shape(3) = l0x * l3y;
2521  shape(4) = l1x * l0y;
2522  shape(5) = l2x * l0y;
2523  shape(6) = l3x * l1y;
2524  shape(7) = l3x * l2y;
2525  shape(8) = l2x * l3y;
2526  shape(9) = l1x * l3y;
2527  shape(10) = l0x * l2y;
2528  shape(11) = l0x * l1y;
2529  shape(12) = l1x * l1y;
2530  shape(13) = l2x * l1y;
2531  shape(14) = l1x * l2y;
2532  shape(15) = l2x * l2y;
2533 }
2534 
2536  const IntegrationPoint &ip, DenseMatrix &dshape) const
2537 {
2538  double x = ip.x, y = ip.y;
2539 
2540  double w1x, w2x, w3x, w1y, w2y, w3y;
2541  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2542  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
2543 
2544  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2545  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2546 
2547  l0x = (- 4.5) * w1x * w2x * w3x;
2548  l1x = ( 13.5) * x * w2x * w3x;
2549  l2x = (-13.5) * x * w1x * w3x;
2550  l3x = ( 4.5) * x * w1x * w2x;
2551 
2552  l0y = (- 4.5) * w1y * w2y * w3y;
2553  l1y = ( 13.5) * y * w2y * w3y;
2554  l2y = (-13.5) * y * w1y * w3y;
2555  l3y = ( 4.5) * y * w1y * w2y;
2556 
2557  d0x = -5.5 + ( 18. - 13.5 * x) * x;
2558  d1x = 9. + (-45. + 40.5 * x) * x;
2559  d2x = -4.5 + ( 36. - 40.5 * x) * x;
2560  d3x = 1. + (- 9. + 13.5 * x) * x;
2561 
2562  d0y = -5.5 + ( 18. - 13.5 * y) * y;
2563  d1y = 9. + (-45. + 40.5 * y) * y;
2564  d2y = -4.5 + ( 36. - 40.5 * y) * y;
2565  d3y = 1. + (- 9. + 13.5 * y) * y;
2566 
2567  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
2568  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
2569  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
2570  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
2571  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
2572  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
2573  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
2574  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
2575  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
2576  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
2577  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
2578  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
2579  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
2580  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
2581  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
2582  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
2583 }
2584 
2586  const IntegrationPoint &ip, DenseMatrix &h) const
2587 {
2588  double x = ip.x, y = ip.y;
2589 
2590  double w1x, w2x, w3x, w1y, w2y, w3y;
2591  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2592  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
2593  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
2594 
2595  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2596  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2597 
2598  l0x = (- 4.5) * w1x * w2x * w3x;
2599  l1x = ( 13.5) * x * w2x * w3x;
2600  l2x = (-13.5) * x * w1x * w3x;
2601  l3x = ( 4.5) * x * w1x * w2x;
2602 
2603  l0y = (- 4.5) * w1y * w2y * w3y;
2604  l1y = ( 13.5) * y * w2y * w3y;
2605  l2y = (-13.5) * y * w1y * w3y;
2606  l3y = ( 4.5) * y * w1y * w2y;
2607 
2608  d0x = -5.5 + ( 18. - 13.5 * x) * x;
2609  d1x = 9. + (-45. + 40.5 * x) * x;
2610  d2x = -4.5 + ( 36. - 40.5 * x) * x;
2611  d3x = 1. + (- 9. + 13.5 * x) * x;
2612 
2613  d0y = -5.5 + ( 18. - 13.5 * y) * y;
2614  d1y = 9. + (-45. + 40.5 * y) * y;
2615  d2y = -4.5 + ( 36. - 40.5 * y) * y;
2616  d3y = 1. + (- 9. + 13.5 * y) * y;
2617 
2618  h0x = -27. * x + 18.;
2619  h1x = 81. * x - 45.;
2620  h2x = -81. * x + 36.;
2621  h3x = 27. * x - 9.;
2622 
2623  h0y = -27. * y + 18.;
2624  h1y = 81. * y - 45.;
2625  h2y = -81. * y + 36.;
2626  h3y = 27. * y - 9.;
2627 
2628  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
2629  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
2630  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
2631  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
2632  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
2633  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
2634  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
2635  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
2636  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
2637  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
2638  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
2639  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
2640  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
2641  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
2642  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
2643  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
2644 }
2645 
2646 
2648  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
2649 {
2650  Nodes.IntPoint(0).x = 0.0;
2651  Nodes.IntPoint(1).x = 1.0;
2652  Nodes.IntPoint(2).x = 0.33333333333333333333;
2653  Nodes.IntPoint(3).x = 0.66666666666666666667;
2654 }
2655 
2657  Vector &shape) const
2658 {
2659  double x = ip.x;
2660  double l1 = x,
2661  l2 = (1.0-x),
2662  l3 = (0.33333333333333333333-x),
2663  l4 = (0.66666666666666666667-x);
2664 
2665  shape(0) = 4.5 * l2 * l3 * l4;
2666  shape(1) = 4.5 * l1 * l3 * l4;
2667  shape(2) = 13.5 * l1 * l2 * l4;
2668  shape(3) = -13.5 * l1 * l2 * l3;
2669 }
2670 
2672  DenseMatrix &dshape) const
2673 {
2674  double x = ip.x;
2675 
2676  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
2677  dshape(1,0) = 1. - x * (9. - 13.5 * x);
2678  dshape(2,0) = 9. - x * (45. - 40.5 * x);
2679  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
2680 }
2681 
2682 
2684  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
2685 {
2686  Nodes.IntPoint(0).x = 0.0;
2687  Nodes.IntPoint(0).y = 0.0;
2688  Nodes.IntPoint(1).x = 1.0;
2689  Nodes.IntPoint(1).y = 0.0;
2690  Nodes.IntPoint(2).x = 0.0;
2691  Nodes.IntPoint(2).y = 1.0;
2692  Nodes.IntPoint(3).x = 0.33333333333333333333;
2693  Nodes.IntPoint(3).y = 0.0;
2694  Nodes.IntPoint(4).x = 0.66666666666666666667;
2695  Nodes.IntPoint(4).y = 0.0;
2696  Nodes.IntPoint(5).x = 0.66666666666666666667;
2697  Nodes.IntPoint(5).y = 0.33333333333333333333;
2698  Nodes.IntPoint(6).x = 0.33333333333333333333;
2699  Nodes.IntPoint(6).y = 0.66666666666666666667;
2700  Nodes.IntPoint(7).x = 0.0;
2701  Nodes.IntPoint(7).y = 0.66666666666666666667;
2702  Nodes.IntPoint(8).x = 0.0;
2703  Nodes.IntPoint(8).y = 0.33333333333333333333;
2704  Nodes.IntPoint(9).x = 0.33333333333333333333;
2705  Nodes.IntPoint(9).y = 0.33333333333333333333;
2706 }
2707 
2709  Vector &shape) const
2710 {
2711  double x = ip.x, y = ip.y;
2712  double l1 = (-1. + x + y),
2713  lx = (-1. + 3.*x),
2714  ly = (-1. + 3.*y);
2715 
2716  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
2717  shape(1) = 0.5*x*(lx - 1.)*lx;
2718  shape(2) = 0.5*y*(-1. + ly)*ly;
2719  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
2720  shape(4) = -4.5*x*lx*l1;
2721  shape(5) = 4.5*x*lx*y;
2722  shape(6) = 4.5*x*y*ly;
2723  shape(7) = -4.5*y*l1*ly;
2724  shape(8) = 4.5*y*l1*(1. + 3.*l1);
2725  shape(9) = -27.*x*y*l1;
2726 }
2727 
2729  DenseMatrix &dshape) const
2730 {
2731  double x = ip.x, y = ip.y;
2732 
2733  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2734  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
2735  dshape(2,0) = 0.;
2736  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
2737  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
2738  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
2739  dshape(6,0) = 4.5*y*(-1. + 3.*y);
2740  dshape(7,0) = 4.5*(1. - 3.*y)*y;
2741  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
2742  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
2743 
2744  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2745  dshape(1,1) = 0.;
2746  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
2747  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
2748  dshape(4,1) = 4.5*(1. - 3.*x)*x;
2749  dshape(5,1) = 4.5*x*(-1. + 3.*x);
2750  dshape(6,1) = 4.5*x*(-1. + 6.*y);
2751  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
2752  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
2753  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
2754 }
2755 
2757  DenseMatrix &h) const
2758 {
2759  double x = ip.x, y = ip.y;
2760 
2761  h(0,0) = 18.-27.*(x+y);
2762  h(0,1) = 18.-27.*(x+y);
2763  h(0,2) = 18.-27.*(x+y);
2764 
2765  h(1,0) = -9.+27.*x;
2766  h(1,1) = 0.;
2767  h(1,2) = 0.;
2768 
2769  h(2,0) = 0.;
2770  h(2,1) = 0.;
2771  h(2,2) = -9.+27.*y;
2772 
2773  h(3,0) = -45.+81.*x+54.*y;
2774  h(3,1) = -22.5+54.*x+27.*y;
2775  h(3,2) = 27.*x;
2776 
2777  h(4,0) = 36.-81.*x-27.*y;
2778  h(4,1) = 4.5-27.*x;
2779  h(4,2) = 0.;
2780 
2781  h(5,0) = 27.*y;
2782  h(5,1) = -4.5+27.*x;
2783  h(5,2) = 0.;
2784 
2785  h(6,0) = 0.;
2786  h(6,1) = -4.5+27.*y;
2787  h(6,2) = 27.*x;
2788 
2789  h(7,0) = 0.;
2790  h(7,1) = 4.5-27.*y;
2791  h(7,2) = 36.-27.*x-81.*y;
2792 
2793  h(8,0) = 27.*y;
2794  h(8,1) = -22.5+27.*x+54.*y;
2795  h(8,2) = -45.+54.*x+81.*y;
2796 
2797  h(9,0) = -54.*y;
2798  h(9,1) = 27.-54.*(x+y);
2799  h(9,2) = -54.*x;
2800 }
2801 
2802 
2804  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
2805 {
2806  Nodes.IntPoint(0).x = 0;
2807  Nodes.IntPoint(0).y = 0;
2808  Nodes.IntPoint(0).z = 0;
2809  Nodes.IntPoint(1).x = 1.;
2810  Nodes.IntPoint(1).y = 0;
2811  Nodes.IntPoint(1).z = 0;
2812  Nodes.IntPoint(2).x = 0;
2813  Nodes.IntPoint(2).y = 1.;
2814  Nodes.IntPoint(2).z = 0;
2815  Nodes.IntPoint(3).x = 0;
2816  Nodes.IntPoint(3).y = 0;
2817  Nodes.IntPoint(3).z = 1.;
2818  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
2819  Nodes.IntPoint(4).y = 0;
2820  Nodes.IntPoint(4).z = 0;
2821  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
2822  Nodes.IntPoint(5).y = 0;
2823  Nodes.IntPoint(5).z = 0;
2824  Nodes.IntPoint(6).x = 0;
2825  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
2826  Nodes.IntPoint(6).z = 0;
2827  Nodes.IntPoint(7).x = 0;
2828  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
2829  Nodes.IntPoint(7).z = 0;
2830  Nodes.IntPoint(8).x = 0;
2831  Nodes.IntPoint(8).y = 0;
2832  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
2833  Nodes.IntPoint(9).x = 0;
2834  Nodes.IntPoint(9).y = 0;
2835  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
2836  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
2837  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
2838  Nodes.IntPoint(10).z = 0;
2839  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
2840  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
2841  Nodes.IntPoint(11).z = 0;
2842  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
2843  Nodes.IntPoint(12).y = 0;
2844  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
2845  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
2846  Nodes.IntPoint(13).y = 0;
2847  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
2848  Nodes.IntPoint(14).x = 0;
2849  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
2850  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
2851  Nodes.IntPoint(15).x = 0;
2852  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
2853  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
2854  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
2855  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
2856  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
2857  Nodes.IntPoint(17).x = 0;
2858  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
2859  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
2860  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
2861  Nodes.IntPoint(18).y = 0;
2862  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
2863  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
2864  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
2865  Nodes.IntPoint(19).z = 0;
2866 }
2867 
2869  Vector &shape) const
2870 {
2871  double x = ip.x, y = ip.y, z = ip.z;
2872 
2873  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
2874  (-1 + 3*x + 3*y + 3*z))/2.;
2875  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2876  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
2877  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
2878  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2879  shape(19) = -27*x*y*(-1 + x + y + z);
2880  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
2881  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
2882  shape(11) = (9*x*y*(-1 + 3*y))/2.;
2883  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
2884  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2885  shape(18) = -27*x*z*(-1 + x + y + z);
2886  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
2887  shape(17) = -27*y*z*(-1 + x + y + z);
2888  shape(16) = 27*x*y*z;
2889  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
2890  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
2891  shape(13) = (9*x*z*(-1 + 3*z))/2.;
2892  shape(15) = (9*y*z*(-1 + 3*z))/2.;
2893  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
2894 }
2895 
2897  DenseMatrix &dshape) const
2898 {
2899  double x = ip.x, y = ip.y, z = ip.z;
2900 
2901  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2902  x*(-4 + 6*y + 6*z)))/2.;
2903  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2904  x*(-4 + 6*y + 6*z)))/2.;
2905  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2906  x*(-4 + 6*y + 6*z)))/2.;
2907  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
2908  2*x*(-5 + 6*y + 6*z)))/2.;
2909  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2910  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2911  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
2912  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
2913  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
2914  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
2915  dshape(1,1) = 0;
2916  dshape(1,2) = 0;
2917  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2918  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
2919  x*(-5 + 12*y + 6*z)))/2.;
2920  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2921  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
2922  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
2923  dshape(19,2) = -27*x*y;
2924  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
2925  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
2926  dshape(10,2) = 0;
2927  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
2928  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
2929  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
2930  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
2931  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
2932  dshape(11,2) = 0;
2933  dshape(2,0) = 0;
2934  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
2935  dshape(2,2) = 0;
2936  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2937  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2938  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
2939  x*(-5 + 6*y + 12*z)))/2.;
2940  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
2941  dshape(18,1) = -27*x*z;
2942  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
2943  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
2944  dshape(12,1) = 0;
2945  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
2946  dshape(17,0) = -27*y*z;
2947  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
2948  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
2949  dshape(16,0) = 27*y*z;
2950  dshape(16,1) = 27*x*z;
2951  dshape(16,2) = 27*x*y;
2952  dshape(14,0) = 0;
2953  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
2954  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
2955  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
2956  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
2957  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
2958  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
2959  dshape(13,1) = 0;
2960  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
2961  dshape(15,0) = 0;
2962  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
2963  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
2964  dshape(3,0) = 0;
2965  dshape(3,1) = 0;
2966  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
2967 }
2968 
2969 
2971  : NodalFiniteElement(2, Geometry::TRIANGLE, 1, 0)
2972 {
2973  Nodes.IntPoint(0).x = 0.333333333333333333;
2974  Nodes.IntPoint(0).y = 0.333333333333333333;
2975 }
2976 
2978  Vector &shape) const
2979 {
2980  shape(0) = 1.0;
2981 }
2982 
2984  DenseMatrix &dshape) const
2985 {
2986  dshape(0,0) = 0.0;
2987  dshape(0,1) = 0.0;
2988 }
2989 
2990 
2992  : NodalFiniteElement(2, Geometry::SQUARE, 1, 0, FunctionSpace::Qk)
2993 {
2994  Nodes.IntPoint(0).x = 0.5;
2995  Nodes.IntPoint(0).y = 0.5;
2996 }
2997 
2999  Vector &shape) const
3000 {
3001  shape(0) = 1.0;
3002 }
3003 
3005  DenseMatrix &dshape) const
3006 {
3007  dshape(0,0) = 0.0;
3008  dshape(0,1) = 0.0;
3009 }
3010 
3011 
3013  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
3014 {
3015  Nodes.IntPoint(0).x = 0.0;
3016  Nodes.IntPoint(0).y = 0.0;
3017  Nodes.IntPoint(0).z = 0.0;
3018  Nodes.IntPoint(1).x = 1.0;
3019  Nodes.IntPoint(1).y = 0.0;
3020  Nodes.IntPoint(1).z = 0.0;
3021  Nodes.IntPoint(2).x = 0.0;
3022  Nodes.IntPoint(2).y = 1.0;
3023  Nodes.IntPoint(2).z = 0.0;
3024  Nodes.IntPoint(3).x = 0.0;
3025  Nodes.IntPoint(3).y = 0.0;
3026  Nodes.IntPoint(3).z = 1.0;
3027 }
3028 
3030  Vector &shape) const
3031 {
3032  shape(0) = 1. - ip.x - ip.y - ip.z;
3033  shape(1) = ip.x;
3034  shape(2) = ip.y;
3035  shape(3) = ip.z;
3036 }
3037 
3039  DenseMatrix &dshape) const
3040 {
3041  if (dshape.Height() == 4)
3042  {
3043  double *A = &dshape(0,0);
3044  A[0] = -1.; A[4] = -1.; A[8] = -1.;
3045  A[1] = 1.; A[5] = 0.; A[9] = 0.;
3046  A[2] = 0.; A[6] = 1.; A[10] = 0.;
3047  A[3] = 0.; A[7] = 0.; A[11] = 1.;
3048  }
3049  else
3050  {
3051  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
3052  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
3053  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
3054  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
3055  }
3056 }
3057 
3058 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
3059 const
3060 {
3061  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
3062 
3063  *ndofs = 3;
3064  *dofs = face_dofs[face];
3065 }
3066 
3067 
3069  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
3070 {
3071  Nodes.IntPoint(0).x = 0.0;
3072  Nodes.IntPoint(0).y = 0.0;
3073  Nodes.IntPoint(0).z = 0.0;
3074  Nodes.IntPoint(1).x = 1.0;
3075  Nodes.IntPoint(1).y = 0.0;
3076  Nodes.IntPoint(1).z = 0.0;
3077  Nodes.IntPoint(2).x = 0.0;
3078  Nodes.IntPoint(2).y = 1.0;
3079  Nodes.IntPoint(2).z = 0.0;
3080  Nodes.IntPoint(3).x = 0.0;
3081  Nodes.IntPoint(3).y = 0.0;
3082  Nodes.IntPoint(3).z = 1.0;
3083  Nodes.IntPoint(4).x = 0.5;
3084  Nodes.IntPoint(4).y = 0.0;
3085  Nodes.IntPoint(4).z = 0.0;
3086  Nodes.IntPoint(5).x = 0.0;
3087  Nodes.IntPoint(5).y = 0.5;
3088  Nodes.IntPoint(5).z = 0.0;
3089  Nodes.IntPoint(6).x = 0.0;
3090  Nodes.IntPoint(6).y = 0.0;
3091  Nodes.IntPoint(6).z = 0.5;
3092  Nodes.IntPoint(7).x = 0.5;
3093  Nodes.IntPoint(7).y = 0.5;
3094  Nodes.IntPoint(7).z = 0.0;
3095  Nodes.IntPoint(8).x = 0.5;
3096  Nodes.IntPoint(8).y = 0.0;
3097  Nodes.IntPoint(8).z = 0.5;
3098  Nodes.IntPoint(9).x = 0.0;
3099  Nodes.IntPoint(9).y = 0.5;
3100  Nodes.IntPoint(9).z = 0.5;
3101 }
3102 
3104  Vector &shape) const
3105 {
3106  double L0, L1, L2, L3;
3107 
3108  L0 = 1. - ip.x - ip.y - ip.z;
3109  L1 = ip.x;
3110  L2 = ip.y;
3111  L3 = ip.z;
3112 
3113  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
3114  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
3115  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
3116  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
3117  shape(4) = 4.0 * L0 * L1;
3118  shape(5) = 4.0 * L0 * L2;
3119  shape(6) = 4.0 * L0 * L3;
3120  shape(7) = 4.0 * L1 * L2;
3121  shape(8) = 4.0 * L1 * L3;
3122  shape(9) = 4.0 * L2 * L3;
3123 }
3124 
3126  DenseMatrix &dshape) const
3127 {
3128  double x, y, z, L0;
3129 
3130  x = ip.x;
3131  y = ip.y;
3132  z = ip.z;
3133  L0 = 1.0 - x - y - z;
3134 
3135  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
3136  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
3137  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
3138  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
3139  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
3140  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
3141  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
3142  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
3143  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
3144  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
3145 }
3146 
3148  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
3149 {
3150  Nodes.IntPoint(0).x = 0.0;
3151  Nodes.IntPoint(0).y = 0.0;
3152  Nodes.IntPoint(0).z = 0.0;
3153 
3154  Nodes.IntPoint(1).x = 1.0;
3155  Nodes.IntPoint(1).y = 0.0;
3156  Nodes.IntPoint(1).z = 0.0;
3157 
3158  Nodes.IntPoint(2).x = 1.0;
3159  Nodes.IntPoint(2).y = 1.0;
3160  Nodes.IntPoint(2).z = 0.0;
3161 
3162  Nodes.IntPoint(3).x = 0.0;
3163  Nodes.IntPoint(3).y = 1.0;
3164  Nodes.IntPoint(3).z = 0.0;
3165 
3166  Nodes.IntPoint(4).x = 0.0;
3167  Nodes.IntPoint(4).y = 0.0;
3168  Nodes.IntPoint(4).z = 1.0;
3169 
3170  Nodes.IntPoint(5).x = 1.0;
3171  Nodes.IntPoint(5).y = 0.0;
3172  Nodes.IntPoint(5).z = 1.0;
3173 
3174  Nodes.IntPoint(6).x = 1.0;
3175  Nodes.IntPoint(6).y = 1.0;
3176  Nodes.IntPoint(6).z = 1.0;
3177 
3178  Nodes.IntPoint(7).x = 0.0;
3179  Nodes.IntPoint(7).y = 1.0;
3180  Nodes.IntPoint(7).z = 1.0;
3181 }
3182 
3184  Vector &shape) const
3185 {
3186  double x = ip.x, y = ip.y, z = ip.z;
3187  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
3188 
3189  shape(0) = ox * oy * oz;
3190  shape(1) = x * oy * oz;
3191  shape(2) = x * y * oz;
3192  shape(3) = ox * y * oz;
3193  shape(4) = ox * oy * z;
3194  shape(5) = x * oy * z;
3195  shape(6) = x * y * z;
3196  shape(7) = ox * y * z;
3197 }
3198 
3200  DenseMatrix &dshape) const
3201 {
3202  double x = ip.x, y = ip.y, z = ip.z;
3203  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
3204 
3205  dshape(0,0) = - oy * oz;
3206  dshape(0,1) = - ox * oz;
3207  dshape(0,2) = - ox * oy;
3208 
3209  dshape(1,0) = oy * oz;
3210  dshape(1,1) = - x * oz;
3211  dshape(1,2) = - x * oy;
3212 
3213  dshape(2,0) = y * oz;
3214  dshape(2,1) = x * oz;
3215  dshape(2,2) = - x * y;
3216 
3217  dshape(3,0) = - y * oz;
3218  dshape(3,1) = ox * oz;
3219  dshape(3,2) = - ox * y;
3220 
3221  dshape(4,0) = - oy * z;
3222  dshape(4,1) = - ox * z;
3223  dshape(4,2) = ox * oy;
3224 
3225  dshape(5,0) = oy * z;
3226  dshape(5,1) = - x * z;
3227  dshape(5,2) = x * oy;
3228 
3229  dshape(6,0) = y * z;
3230  dshape(6,1) = x * z;
3231  dshape(6,2) = x * y;
3232 
3233  dshape(7,0) = - y * z;
3234  dshape(7,1) = ox * z;
3235  dshape(7,2) = ox * y;
3236 }
3237 
3238 
3240  : NodalFiniteElement(1, Geometry::SEGMENT, 1, Ord) // default Ord = 0
3241 {
3242  Nodes.IntPoint(0).x = 0.5;
3243 }
3244 
3246  Vector &shape) const
3247 {
3248  shape(0) = 1.0;
3249 }
3250 
3252  DenseMatrix &dshape) const
3253 {
3254  dshape(0,0) = 0.0;
3255 }
3256 
3258  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
3259 {
3260  Nodes.IntPoint(0).x = 0.5;
3261  Nodes.IntPoint(0).y = 0.0;
3262  Nodes.IntPoint(1).x = 0.5;
3263  Nodes.IntPoint(1).y = 0.5;
3264  Nodes.IntPoint(2).x = 0.0;
3265  Nodes.IntPoint(2).y = 0.5;
3266 }
3267 
3269  Vector &shape) const
3270 {
3271  shape(0) = 1.0 - 2.0 * ip.y;
3272  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
3273  shape(2) = 1.0 - 2.0 * ip.x;
3274 }
3275 
3277  DenseMatrix &dshape) const
3278 {
3279  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
3280  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
3281  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
3282 }
3283 
3285 // the FunctionSpace should be rotated (45 degrees) Q_1
3286 // i.e. the span of { 1, x, y, x^2 - y^2 }
3287  : NodalFiniteElement(2, Geometry::SQUARE, 4, 2, FunctionSpace::Qk)
3288 {
3289  Nodes.IntPoint(0).x = 0.5;
3290  Nodes.IntPoint(0).y = 0.0;
3291  Nodes.IntPoint(1).x = 1.0;
3292  Nodes.IntPoint(1).y = 0.5;
3293  Nodes.IntPoint(2).x = 0.5;
3294  Nodes.IntPoint(2).y = 1.0;
3295  Nodes.IntPoint(3).x = 0.0;
3296  Nodes.IntPoint(3).y = 0.5;
3297 }
3298 
3300  Vector &shape) const
3301 {
3302  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
3303 
3304  shape(0) = l2 * l3;
3305  shape(1) = l1 * l3;
3306  shape(2) = l1 * l4;
3307  shape(3) = l2 * l4;
3308 }
3309 
3311  DenseMatrix &dshape) const
3312 {
3313  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
3314 
3315  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
3316  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
3317  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
3318  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
3319 }
3320 
3321 
3323  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
3324 {
3325  Nodes.IntPoint(0).x = 0.5;
3326  Nodes.IntPoint(0).y = 0.0;
3327  Nodes.IntPoint(1).x = 0.5;
3328  Nodes.IntPoint(1).y = 0.5;
3329  Nodes.IntPoint(2).x = 0.0;
3330  Nodes.IntPoint(2).y = 0.5;
3331 }
3332 
3334  DenseMatrix &shape) const
3335 {
3336  double x = ip.x, y = ip.y;
3337 
3338  shape(0,0) = x;
3339  shape(0,1) = y - 1.;
3340  shape(1,0) = x;
3341  shape(1,1) = y;
3342  shape(2,0) = x - 1.;
3343  shape(2,1) = y;
3344 }
3345 
3347  Vector &divshape) const
3348 {
3349  divshape(0) = 2.;
3350  divshape(1) = 2.;
3351  divshape(2) = 2.;
3352 }
3353 
3354 const double RT0TriangleFiniteElement::nk[3][2] =
3355 { {0, -1}, {1, 1}, {-1, 0} };
3356 
3359 {
3360  int k, j;
3361 #ifdef MFEM_THREAD_SAFE
3363  DenseMatrix Jinv(dim);
3364 #endif
3365 
3366 #ifdef MFEM_DEBUG
3367  for (k = 0; k < 3; k++)
3368  {
3370  for (j = 0; j < 3; j++)
3371  {
3372  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3373  if (j == k) { d -= 1.0; }
3374  if (fabs(d) > 1.0e-12)
3375  {
3376  mfem::err << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
3377  " k = " << k << ", j = " << j << ", d = " << d << endl;
3378  mfem_error();
3379  }
3380  }
3381  }
3382 #endif
3383 
3384  IntegrationPoint ip;
3385  ip.x = ip.y = 0.0;
3386  Trans.SetIntPoint (&ip);
3387  // Trans must be linear
3388  // set Jinv = |J| J^{-t} = adj(J)^t
3389  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3390  double vk[2];
3391  Vector xk (vk, 2);
3392 
3393  for (k = 0; k < 3; k++)
3394  {
3395  Trans.Transform (Nodes.IntPoint (k), xk);
3396  ip.x = vk[0]; ip.y = vk[1];
3397  CalcVShape (ip, vshape);
3398  // vk = |J| J^{-t} nk
3399  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3400  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3401  for (j = 0; j < 3; j++)
3402  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3403  {
3404  I(k,j) = 0.0;
3405  }
3406  }
3407 }
3408 
3411  Vector &dofs) const
3412 {
3413  double vk[2];
3414  Vector xk (vk, 2);
3415 #ifdef MFEM_THREAD_SAFE
3416  DenseMatrix Jinv(dim);
3417 #endif
3418 
3419  for (int k = 0; k < 3; k++)
3420  {
3421  Trans.SetIntPoint (&Nodes.IntPoint (k));
3422  // set Jinv = |J| J^{-t} = adj(J)^t
3423  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3424 
3425  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3426  // xk^t |J| J^{-t} nk
3427  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3428  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3429  }
3430 }
3431 
3433  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
3434 {
3435  Nodes.IntPoint(0).x = 0.5;
3436  Nodes.IntPoint(0).y = 0.0;
3437  Nodes.IntPoint(1).x = 1.0;
3438  Nodes.IntPoint(1).y = 0.5;
3439  Nodes.IntPoint(2).x = 0.5;
3440  Nodes.IntPoint(2).y = 1.0;
3441  Nodes.IntPoint(3).x = 0.0;
3442  Nodes.IntPoint(3).y = 0.5;
3443 }
3444 
3446  DenseMatrix &shape) const
3447 {
3448  double x = ip.x, y = ip.y;
3449 
3450  shape(0,0) = 0;
3451  shape(0,1) = y - 1.;
3452  shape(1,0) = x;
3453  shape(1,1) = 0;
3454  shape(2,0) = 0;
3455  shape(2,1) = y;
3456  shape(3,0) = x - 1.;
3457  shape(3,1) = 0;
3458 }
3459 
3461  Vector &divshape) const
3462 {
3463  divshape(0) = 1.;
3464  divshape(1) = 1.;
3465  divshape(2) = 1.;
3466  divshape(3) = 1.;
3467 }
3468 
3469 const double RT0QuadFiniteElement::nk[4][2] =
3470 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
3471 
3474 {
3475  int k, j;
3476 #ifdef MFEM_THREAD_SAFE
3478  DenseMatrix Jinv(dim);
3479 #endif
3480 
3481 #ifdef MFEM_DEBUG
3482  for (k = 0; k < 4; k++)
3483  {
3485  for (j = 0; j < 4; j++)
3486  {
3487  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3488  if (j == k) { d -= 1.0; }
3489  if (fabs(d) > 1.0e-12)
3490  {
3491  mfem::err << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
3492  " k = " << k << ", j = " << j << ", d = " << d << endl;
3493  mfem_error();
3494  }
3495  }
3496  }
3497 #endif
3498 
3499  IntegrationPoint ip;
3500  ip.x = ip.y = 0.0;
3501  Trans.SetIntPoint (&ip);
3502  // Trans must be linear (more to have embedding?)
3503  // set Jinv = |J| J^{-t} = adj(J)^t
3504  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3505  double vk[2];
3506  Vector xk (vk, 2);
3507 
3508  for (k = 0; k < 4; k++)
3509  {
3510  Trans.Transform (Nodes.IntPoint (k), xk);
3511  ip.x = vk[0]; ip.y = vk[1];
3512  CalcVShape (ip, vshape);
3513  // vk = |J| J^{-t} nk
3514  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3515  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3516  for (j = 0; j < 4; j++)
3517  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3518  {
3519  I(k,j) = 0.0;
3520  }
3521  }
3522 }
3523 
3526  Vector &dofs) const
3527 {
3528  double vk[2];
3529  Vector xk (vk, 2);
3530 #ifdef MFEM_THREAD_SAFE
3531  DenseMatrix Jinv(dim);
3532 #endif
3533 
3534  for (int k = 0; k < 4; k++)
3535  {
3536  Trans.SetIntPoint (&Nodes.IntPoint (k));
3537  // set Jinv = |J| J^{-t} = adj(J)^t
3538  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3539 
3540  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3541  // xk^t |J| J^{-t} nk
3542  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3543  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3544  }
3545 }
3546 
3548  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
3549 {
3550  Nodes.IntPoint(0).x = 0.33333333333333333333;
3551  Nodes.IntPoint(0).y = 0.0;
3552  Nodes.IntPoint(1).x = 0.66666666666666666667;
3553  Nodes.IntPoint(1).y = 0.0;
3554  Nodes.IntPoint(2).x = 0.66666666666666666667;
3555  Nodes.IntPoint(2).y = 0.33333333333333333333;
3556  Nodes.IntPoint(3).x = 0.33333333333333333333;
3557  Nodes.IntPoint(3).y = 0.66666666666666666667;
3558  Nodes.IntPoint(4).x = 0.0;
3559  Nodes.IntPoint(4).y = 0.66666666666666666667;
3560  Nodes.IntPoint(5).x = 0.0;
3561  Nodes.IntPoint(5).y = 0.33333333333333333333;
3562  Nodes.IntPoint(6).x = 0.33333333333333333333;
3563  Nodes.IntPoint(6).y = 0.33333333333333333333;
3564  Nodes.IntPoint(7).x = 0.33333333333333333333;
3565  Nodes.IntPoint(7).y = 0.33333333333333333333;
3566 }
3567 
3569  DenseMatrix &shape) const
3570 {
3571  double x = ip.x, y = ip.y;
3572 
3573  shape(0,0) = -2 * x * (-1 + x + 2 * y);
3574  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
3575  shape(1,0) = 2 * x * (x - y);
3576  shape(1,1) = 2 * (x - y) * (-1 + y);
3577  shape(2,0) = 2 * x * (-1 + 2 * x + y);
3578  shape(2,1) = 2 * y * (-1 + 2 * x + y);
3579  shape(3,0) = 2 * x * (-1 + x + 2 * y);
3580  shape(3,1) = 2 * y * (-1 + x + 2 * y);
3581  shape(4,0) = -2 * (-1 + x) * (x - y);
3582  shape(4,1) = 2 * y * (-x + y);
3583  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
3584  shape(5,1) = -2 * y * (-1 + 2 * x + y);
3585  shape(6,0) = -3 * x * (-2 + 2 * x + y);
3586  shape(6,1) = -3 * y * (-1 + 2 * x + y);
3587  shape(7,0) = -3 * x * (-1 + x + 2 * y);
3588  shape(7,1) = -3 * y * (-2 + x + 2 * y);
3589 }
3590 
3592  Vector &divshape) const
3593 {
3594  double x = ip.x, y = ip.y;
3595 
3596  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
3597  divshape(1) = 2 + 6 * x - 6 * y;
3598  divshape(2) = -4 + 12 * x + 6 * y;
3599  divshape(3) = -4 + 6 * x + 12 * y;
3600  divshape(4) = 2 - 6 * x + 6 * y;
3601  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
3602  divshape(6) = -9 * (-1 + 2 * x + y);
3603  divshape(7) = -9 * (-1 + x + 2 * y);
3604 }
3605 
3606 const double RT1TriangleFiniteElement::nk[8][2] =
3607 {
3608  { 0,-1}, { 0,-1},
3609  { 1, 1}, { 1, 1},
3610  {-1, 0}, {-1, 0},
3611  { 1, 0}, { 0, 1}
3612 };
3613 
3616 {
3617  int k, j;
3618 #ifdef MFEM_THREAD_SAFE
3620  DenseMatrix Jinv(dim);
3621 #endif
3622 
3623 #ifdef MFEM_DEBUG
3624  for (k = 0; k < 8; k++)
3625  {
3627  for (j = 0; j < 8; j++)
3628  {
3629  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3630  if (j == k) { d -= 1.0; }
3631  if (fabs(d) > 1.0e-12)
3632  {
3633  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3634  " k = " << k << ", j = " << j << ", d = " << d << endl;
3635  mfem_error();
3636  }
3637  }
3638  }
3639 #endif
3640 
3641  IntegrationPoint ip;
3642  ip.x = ip.y = 0.0;
3643  Trans.SetIntPoint (&ip);
3644  // Trans must be linear (more to have embedding?)
3645  // set Jinv = |J| J^{-t} = adj(J)^t
3646  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3647  double vk[2];
3648  Vector xk (vk, 2);
3649 
3650  for (k = 0; k < 8; k++)
3651  {
3652  Trans.Transform (Nodes.IntPoint (k), xk);
3653  ip.x = vk[0]; ip.y = vk[1];
3654  CalcVShape (ip, vshape);
3655  // vk = |J| J^{-t} nk
3656  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3657  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3658  for (j = 0; j < 8; j++)
3659  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3660  {
3661  I(k,j) = 0.0;
3662  }
3663  }
3664 }
3665 
3668 {
3669  double vk[2];
3670  Vector xk (vk, 2);
3671 #ifdef MFEM_THREAD_SAFE
3672  DenseMatrix Jinv(dim);
3673 #endif
3674 
3675  for (int k = 0; k < 8; k++)
3676  {
3677  Trans.SetIntPoint (&Nodes.IntPoint (k));
3678  // set Jinv = |J| J^{-t} = adj(J)^t
3679  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3680 
3681  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3682  // xk^t |J| J^{-t} nk
3683  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3684  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3685  dofs(k) *= 0.5;
3686  }
3687 }
3688 
3690  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
3691 {
3692  // y = 0
3693  Nodes.IntPoint(0).x = 1./3.;
3694  Nodes.IntPoint(0).y = 0.0;
3695  Nodes.IntPoint(1).x = 2./3.;
3696  Nodes.IntPoint(1).y = 0.0;
3697  // x = 1
3698  Nodes.IntPoint(2).x = 1.0;
3699  Nodes.IntPoint(2).y = 1./3.;
3700  Nodes.IntPoint(3).x = 1.0;
3701  Nodes.IntPoint(3).y = 2./3.;
3702  // y = 1
3703  Nodes.IntPoint(4).x = 2./3.;
3704  Nodes.IntPoint(4).y = 1.0;
3705  Nodes.IntPoint(5).x = 1./3.;
3706  Nodes.IntPoint(5).y = 1.0;
3707  // x = 0
3708  Nodes.IntPoint(6).x = 0.0;
3709  Nodes.IntPoint(6).y = 2./3.;
3710  Nodes.IntPoint(7).x = 0.0;
3711  Nodes.IntPoint(7).y = 1./3.;
3712  // x = 0.5 (interior)
3713  Nodes.IntPoint(8).x = 0.5;
3714  Nodes.IntPoint(8).y = 1./3.;
3715  Nodes.IntPoint(9).x = 0.5;
3716  Nodes.IntPoint(9).y = 2./3.;
3717  // y = 0.5 (interior)
3718  Nodes.IntPoint(10).x = 1./3.;
3719  Nodes.IntPoint(10).y = 0.5;
3720  Nodes.IntPoint(11).x = 2./3.;
3721  Nodes.IntPoint(11).y = 0.5;
3722 }
3723 
3725  DenseMatrix &shape) const
3726 {
3727  double x = ip.x, y = ip.y;
3728 
3729  // y = 0
3730  shape(0,0) = 0;
3731  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
3732  shape(1,0) = 0;
3733  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
3734  // x = 1
3735  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
3736  shape(2,1) = 0;
3737  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
3738  shape(3,1) = 0;
3739  // y = 1
3740  shape(4,0) = 0;
3741  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
3742  shape(5,0) = 0;
3743  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
3744  // x = 0
3745  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
3746  shape(6,1) = 0;
3747  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
3748  shape(7,1) = 0;
3749  // x = 0.5 (interior)
3750  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
3751  shape(8,1) = 0;
3752  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
3753  shape(9,1) = 0;
3754  // y = 0.5 (interior)
3755  shape(10,0) = 0;
3756  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
3757  shape(11,0) = 0;
3758  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
3759 }
3760 
3762  Vector &divshape) const
3763 {
3764  double x = ip.x, y = ip.y;
3765 
3766  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
3767  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
3768  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
3769  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
3770  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
3771  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
3772  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
3773  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
3774  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
3775  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
3776  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
3777  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
3778 }
3779 
3780 const double RT1QuadFiniteElement::nk[12][2] =
3781 {
3782  // y = 0
3783  {0,-1}, {0,-1},
3784  // X = 1
3785  {1, 0}, {1, 0},
3786  // y = 1
3787  {0, 1}, {0, 1},
3788  // x = 0
3789  {-1,0}, {-1,0},
3790  // x = 0.5 (interior)
3791  {1, 0}, {1, 0},
3792  // y = 0.5 (interior)
3793  {0, 1}, {0, 1}
3794 };
3795 
3798 {
3799  int k, j;
3800 #ifdef MFEM_THREAD_SAFE
3802  DenseMatrix Jinv(dim);
3803 #endif
3804 
3805 #ifdef MFEM_DEBUG
3806  for (k = 0; k < 12; k++)
3807  {
3809  for (j = 0; j < 12; j++)
3810  {
3811  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3812  if (j == k) { d -= 1.0; }
3813  if (fabs(d) > 1.0e-12)
3814  {
3815  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3816  " k = " << k << ", j = " << j << ", d = " << d << endl;
3817  mfem_error();
3818  }
3819  }
3820  }
3821 #endif
3822 
3823  IntegrationPoint ip;
3824  ip.x = ip.y = 0.0;
3825  Trans.SetIntPoint (&ip);
3826  // Trans must be linear (more to have embedding?)
3827  // set Jinv = |J| J^{-t} = adj(J)^t
3828  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3829  double vk[2];
3830  Vector xk (vk, 2);
3831 
3832  for (k = 0; k < 12; k++)
3833  {
3834  Trans.Transform (Nodes.IntPoint (k), xk);
3835  ip.x = vk[0]; ip.y = vk[1];
3836  CalcVShape (ip, vshape);
3837  // vk = |J| J^{-t} nk
3838  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3839  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3840  for (j = 0; j < 12; j++)
3841  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3842  {
3843  I(k,j) = 0.0;
3844  }
3845  }
3846 }
3847 
3850 {
3851  double vk[2];
3852  Vector xk (vk, 2);
3853 #ifdef MFEM_THREAD_SAFE
3854  DenseMatrix Jinv(dim);
3855 #endif
3856 
3857  for (int k = 0; k < 12; k++)
3858  {
3859  Trans.SetIntPoint (&Nodes.IntPoint (k));
3860  // set Jinv = |J| J^{-t} = adj(J)^t
3861  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3862 
3863  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3864  // xk^t |J| J^{-t} nk
3865  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3866  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3867  }
3868 }
3869 
3870 const double RT2TriangleFiniteElement::M[15][15] =
3871 {
3872  {
3873  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
3874  0, 24.442740046346700787, -16.647580015448900262, -12.,
3875  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
3876  12., 30.590320061795601049, 15.295160030897800524
3877  },
3878  {
3879  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
3880  -15., 10.5
3881  },
3882  {
3883  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
3884  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
3885  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
3886  12., -6.5903200617956010489, -3.2951600308978005244
3887  },
3888  {
3889  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
3890  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
3891  0, -3.2951600308978005244
3892  },
3893  {
3894  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
3895  36., 10.5
3896  },
3897  {
3898  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
3899  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
3900  0, 15.295160030897800524
3901  },
3902  {
3903  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
3904  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
3905  -0.76209992275549868892, 4.1189500386222506555, -12.,
3906  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
3907  12.
3908  },
3909  {
3910  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
3911  -15., -15.
3912  },
3913  {
3914  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
3915  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
3916  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
3917  30.590320061795601049, 12.
3918  },
3919  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
3920  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
3921  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
3922  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
3923  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
3924  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
3925 };
3926 
3928  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
3929 {
3930  const double p = 0.11270166537925831148;
3931 
3932  Nodes.IntPoint(0).x = p;
3933  Nodes.IntPoint(0).y = 0.0;
3934  Nodes.IntPoint(1).x = 0.5;
3935  Nodes.IntPoint(1).y = 0.0;
3936  Nodes.IntPoint(2).x = 1.-p;
3937  Nodes.IntPoint(2).y = 0.0;
3938  Nodes.IntPoint(3).x = 1.-p;
3939  Nodes.IntPoint(3).y = p;
3940  Nodes.IntPoint(4).x = 0.5;
3941  Nodes.IntPoint(4).y = 0.5;
3942  Nodes.IntPoint(5).x = p;
3943  Nodes.IntPoint(5).y = 1.-p;
3944  Nodes.IntPoint(6).x = 0.0;
3945  Nodes.IntPoint(6).y = 1.-p;
3946  Nodes.IntPoint(7).x = 0.0;
3947  Nodes.IntPoint(7).y = 0.5;
3948  Nodes.IntPoint(8).x = 0.0;
3949  Nodes.IntPoint(8).y = p;
3950  Nodes.IntPoint(9).x = 0.25;
3951  Nodes.IntPoint(9).y = 0.25;
3952  Nodes.IntPoint(10).x = 0.25;
3953  Nodes.IntPoint(10).y = 0.25;
3954  Nodes.IntPoint(11).x = 0.5;
3955  Nodes.IntPoint(11).y = 0.25;
3956  Nodes.IntPoint(12).x = 0.5;
3957  Nodes.IntPoint(12).y = 0.25;
3958  Nodes.IntPoint(13).x = 0.25;
3959  Nodes.IntPoint(13).y = 0.5;
3960  Nodes.IntPoint(14).x = 0.25;
3961  Nodes.IntPoint(14).y = 0.5;
3962 }
3963 
3965  DenseMatrix &shape) const
3966 {
3967  double x = ip.x, y = ip.y;
3968 
3969  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
3970  x*x*y, x*y*y
3971  };
3972  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
3973  x*x*y, x*y*y, y*y*y
3974  };
3975 
3976  for (int i = 0; i < 15; i++)
3977  {
3978  double cx = 0.0, cy = 0.0;
3979  for (int j = 0; j < 15; j++)
3980  {
3981  cx += M[i][j] * Bx[j];
3982  cy += M[i][j] * By[j];
3983  }
3984  shape(i,0) = cx;
3985  shape(i,1) = cy;
3986  }
3987 }
3988 
3990  Vector &divshape) const
3991 {
3992  double x = ip.x, y = ip.y;
3993 
3994  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
3995  4.*x*x, 4.*x*y, 4.*y*y
3996  };
3997 
3998  for (int i = 0; i < 15; i++)
3999  {
4000  double div = 0.0;
4001  for (int j = 0; j < 15; j++)
4002  {
4003  div += M[i][j] * DivB[j];
4004  }
4005  divshape(i) = div;
4006  }
4007 }
4008 
4009 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
4010 
4011 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
4012 
4014  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
4015 {
4016  // y = 0 (pt[0])
4017  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
4018  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
4019  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
4020  // x = 1 (pt[3])
4021  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
4022  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
4023  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
4024  // y = 1 (pt[3])
4025  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
4026  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
4027  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
4028  // x = 0 (pt[0])
4029  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
4030  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
4031  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
4032  // x = pt[1] (interior)
4033  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
4034  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
4035  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
4036  // x = pt[2] (interior)
4037  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
4038  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
4039  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
4040  // y = pt[1] (interior)
4041  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
4042  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
4043  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
4044  // y = pt[2] (interior)
4045  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
4046  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
4047  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
4048 }
4049 
4051  DenseMatrix &shape) const
4052 {
4053  double x = ip.x, y = ip.y;
4054 
4055  double ax0 = pt[0] - x;
4056  double ax1 = pt[1] - x;
4057  double ax2 = pt[2] - x;
4058  double ax3 = pt[3] - x;
4059 
4060  double by0 = dpt[0] - y;
4061  double by1 = dpt[1] - y;
4062  double by2 = dpt[2] - y;
4063 
4064  double ay0 = pt[0] - y;
4065  double ay1 = pt[1] - y;
4066  double ay2 = pt[2] - y;
4067  double ay3 = pt[3] - y;
4068 
4069  double bx0 = dpt[0] - x;
4070  double bx1 = dpt[1] - x;
4071  double bx2 = dpt[2] - x;
4072 
4073  double A01 = pt[0] - pt[1];
4074  double A02 = pt[0] - pt[2];
4075  double A12 = pt[1] - pt[2];
4076  double A03 = pt[0] - pt[3];
4077  double A13 = pt[1] - pt[3];
4078  double A23 = pt[2] - pt[3];
4079 
4080  double B01 = dpt[0] - dpt[1];
4081  double B02 = dpt[0] - dpt[2];
4082  double B12 = dpt[1] - dpt[2];
4083 
4084  double tx0 = (bx1*bx2)/(B01*B02);
4085  double tx1 = -(bx0*bx2)/(B01*B12);
4086  double tx2 = (bx0*bx1)/(B02*B12);
4087 
4088  double ty0 = (by1*by2)/(B01*B02);
4089  double ty1 = -(by0*by2)/(B01*B12);
4090  double ty2 = (by0*by1)/(B02*B12);
4091 
4092  // y = 0 (p[0])
4093  shape(0, 0) = 0;
4094  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
4095  shape(1, 0) = 0;
4096  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
4097  shape(2, 0) = 0;
4098  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
4099  // x = 1 (p[3])
4100  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
4101  shape(3, 1) = 0;
4102  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
4103  shape(4, 1) = 0;
4104  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
4105  shape(5, 1) = 0;
4106  // y = 1 (p[3])
4107  shape(6, 0) = 0;
4108  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
4109  shape(7, 0) = 0;
4110  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
4111  shape(8, 0) = 0;
4112  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
4113  // x = 0 (p[0])
4114  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
4115  shape(9, 1) = 0;
4116  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
4117  shape(10, 1) = 0;
4118  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
4119  shape(11, 1) = 0;
4120  // x = p[1] (interior)
4121  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
4122  shape(12, 1) = 0;
4123  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
4124  shape(13, 1) = 0;
4125  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
4126  shape(14, 1) = 0;
4127  // x = p[2] (interior)
4128  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
4129  shape(15, 1) = 0;
4130  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
4131  shape(16, 1) = 0;
4132  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
4133  shape(17, 1) = 0;
4134  // y = p[1] (interior)
4135  shape(18, 0) = 0;
4136  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
4137  shape(19, 0) = 0;
4138  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
4139  shape(20, 0) = 0;
4140  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
4141  // y = p[2] (interior)
4142  shape(21, 0) = 0;
4143  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
4144  shape(22, 0) = 0;
4145  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
4146  shape(23, 0) = 0;
4147  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
4148 }
4149 
4151  Vector &divshape) const
4152 {
4153  double x = ip.x, y = ip.y;
4154 
4155  double a01 = pt[0]*pt[1];
4156  double a02 = pt[0]*pt[2];
4157  double a12 = pt[1]*pt[2];
4158  double a03 = pt[0]*pt[3];
4159  double a13 = pt[1]*pt[3];
4160  double a23 = pt[2]*pt[3];
4161 
4162  double bx0 = dpt[0] - x;
4163  double bx1 = dpt[1] - x;
4164  double bx2 = dpt[2] - x;
4165 
4166  double by0 = dpt[0] - y;
4167  double by1 = dpt[1] - y;
4168  double by2 = dpt[2] - y;
4169 
4170  double A01 = pt[0] - pt[1];
4171  double A02 = pt[0] - pt[2];
4172  double A12 = pt[1] - pt[2];
4173  double A03 = pt[0] - pt[3];
4174  double A13 = pt[1] - pt[3];
4175  double A23 = pt[2] - pt[3];
4176 
4177  double A012 = pt[0] + pt[1] + pt[2];
4178  double A013 = pt[0] + pt[1] + pt[3];
4179  double A023 = pt[0] + pt[2] + pt[3];
4180  double A123 = pt[1] + pt[2] + pt[3];
4181 
4182  double B01 = dpt[0] - dpt[1];
4183  double B02 = dpt[0] - dpt[2];
4184  double B12 = dpt[1] - dpt[2];
4185 
4186  double tx0 = (bx1*bx2)/(B01*B02);
4187  double tx1 = -(bx0*bx2)/(B01*B12);
4188  double tx2 = (bx0*bx1)/(B02*B12);
4189 
4190  double ty0 = (by1*by2)/(B01*B02);
4191  double ty1 = -(by0*by2)/(B01*B12);
4192  double ty2 = (by0*by1)/(B02*B12);
4193 
4194  // y = 0 (p[0])
4195  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
4196  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
4197  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
4198  // x = 1 (p[3])
4199  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
4200  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
4201  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
4202  // y = 1 (p[3])
4203  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
4204  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
4205  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
4206  // x = 0 (p[0])
4207  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
4208  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
4209  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
4210  // x = p[1] (interior)
4211  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
4212  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
4213  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
4214  // x = p[2] (interior)
4215  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
4216  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
4217  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
4218  // y = p[1] (interior)
4219  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
4220  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
4221  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
4222  // y = p[2] (interior)
4223  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
4224  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
4225  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
4226 }
4227 
4228 const double RT2QuadFiniteElement::nk[24][2] =
4229 {
4230  // y = 0
4231  {0,-1}, {0,-1}, {0,-1},
4232  // x = 1
4233  {1, 0}, {1, 0}, {1, 0},
4234  // y = 1
4235  {0, 1}, {0, 1}, {0, 1},
4236  // x = 0
4237  {-1,0}, {-1,0}, {-1,0},
4238  // x = p[1] (interior)
4239  {1, 0}, {1, 0}, {1, 0},
4240  // x = p[2] (interior)
4241  {1, 0}, {1, 0}, {1, 0},
4242  // y = p[1] (interior)
4243  {0, 1}, {0, 1}, {0, 1},
4244  // y = p[1] (interior)
4245  {0, 1}, {0, 1}, {0, 1}
4246 };
4247 
4250 {
4251  int k, j;
4252 #ifdef MFEM_THREAD_SAFE
4254  DenseMatrix Jinv(dim);
4255 #endif
4256 
4257 #ifdef MFEM_DEBUG
4258  for (k = 0; k < 24; k++)
4259  {
4261  for (j = 0; j < 24; j++)
4262  {
4263  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
4264  if (j == k) { d -= 1.0; }
4265  if (fabs(d) > 1.0e-12)
4266  {
4267  mfem::err << "RT2QuadFiniteElement::GetLocalInterpolation (...)\n"
4268  " k = " << k << ", j = " << j << ", d = " << d << endl;
4269  mfem_error();
4270  }
4271  }
4272  }
4273 #endif
4274 
4275  IntegrationPoint ip;
4276  ip.x = ip.y = 0.0;
4277  Trans.SetIntPoint (&ip);
4278  // Trans must be linear (more to have embedding?)
4279  // set Jinv = |J| J^{-t} = adj(J)^t
4280  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
4281  double vk[2];
4282  Vector xk (vk, 2);
4283 
4284  for (k = 0; k < 24; k++)
4285  {
4286  Trans.Transform (Nodes.IntPoint (k), xk);
4287  ip.x = vk[0]; ip.y = vk[1];
4288  CalcVShape (ip, vshape);
4289  // vk = |J| J^{-t} nk
4290  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
4291  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
4292  for (j = 0; j < 24; j++)
4293  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
4294  {
4295  I(k,j) = 0.0;
4296  }
4297  }
4298 }
4299 
4302 {
4303  double vk[2];
4304  Vector xk (vk, 2);
4305 #ifdef MFEM_THREAD_SAFE
4306  DenseMatrix Jinv(dim);
4307 #endif
4308 
4309  for (int k = 0; k < 24; k++)
4310  {
4311  Trans.SetIntPoint (&Nodes.IntPoint (k));
4312  // set Jinv = |J| J^{-t} = adj(J)^t
4313  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
4314 
4315  vc.Eval (xk, Trans, Nodes.IntPoint (k));
4316  // xk^t |J| J^{-t} nk
4317  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
4318  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
4319  }
4320 }
4321 
4323  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
4324 {
4325  Nodes.IntPoint(0).x = 0.33333333333333333333;
4326  Nodes.IntPoint(1).x = 0.66666666666666666667;
4327 }
4328 
4330  Vector &shape) const
4331 {
4332  double x = ip.x;
4333 
4334  shape(0) = 2. - 3. * x;
4335  shape(1) = 3. * x - 1.;
4336 }
4337 
4339  DenseMatrix &dshape) const
4340 {
4341  dshape(0,0) = -3.;
4342  dshape(1,0) = 3.;
4343 }
4344 
4345 
4347  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
4348 {
4349  const double p = 0.11270166537925831148;
4350 
4351  Nodes.IntPoint(0).x = p;
4352  Nodes.IntPoint(1).x = 0.5;
4353  Nodes.IntPoint(2).x = 1.-p;
4354 }
4355 
4357  Vector &shape) const
4358 {
4359  const double p = 0.11270166537925831148;
4360  const double w = 1./((1-2*p)*(1-2*p));
4361  double x = ip.x;
4362 
4363  shape(0) = (2*x-1)*(x-1+p)*w;
4364  shape(1) = 4*(x-1+p)*(p-x)*w;
4365  shape(2) = (2*x-1)*(x-p)*w;
4366 }
4367 
4369  DenseMatrix &dshape) const
4370 {
4371  const double p = 0.11270166537925831148;
4372  const double w = 1./((1-2*p)*(1-2*p));
4373  double x = ip.x;
4374 
4375  dshape(0,0) = (-3+4*x+2*p)*w;
4376  dshape(1,0) = (4-8*x)*w;
4377  dshape(2,0) = (-1+4*x-2*p)*w;
4378 }
4379 
4380 
4382  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
4383 {
4384  int i, m = degree;
4385 
4386  Nodes.IntPoint(0).x = 0.0;
4387  Nodes.IntPoint(1).x = 1.0;
4388  for (i = 1; i < m; i++)
4389  {
4390  Nodes.IntPoint(i+1).x = double(i) / m;
4391  }
4392 
4393  rwk.SetSize(degree+1);
4394 #ifndef MFEM_THREAD_SAFE
4395  rxxk.SetSize(degree+1);
4396 #endif
4397 
4398  rwk(0) = 1.0;
4399  for (i = 1; i <= m; i++)
4400  {
4401  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
4402  }
4403  for (i = 0; i < m/2+1; i++)
4404  {
4405  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
4406  }
4407  for (i = m-1; i >= 0; i -= 2)
4408  {
4409  rwk(i) = -rwk(i);
4410  }
4411 }
4412 
4414  Vector &shape) const
4415 {
4416  double w, wk, x = ip.x;
4417  int i, k, m = GetOrder();
4418 
4419 #ifdef MFEM_THREAD_SAFE
4420  Vector rxxk(m+1);
4421 #endif
4422 
4423  k = (int) floor ( m * x + 0.5 );
4424  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
4425 
4426  wk = 1.0;
4427  for (i = 0; i <= m; i++)
4428  if (i != k)
4429  {
4430  wk *= ( rxxk(i) = x - (double)(i) / m );
4431  }
4432  w = wk * ( rxxk(k) = x - (double)(k) / m );
4433 
4434  if (k != 0)
4435  {
4436  shape(0) = w * rwk(0) / rxxk(0);
4437  }
4438  else
4439  {
4440  shape(0) = wk * rwk(0);
4441  }
4442  if (k != m)
4443  {
4444  shape(1) = w * rwk(m) / rxxk(m);
4445  }
4446  else
4447  {
4448  shape(1) = wk * rwk(k);
4449  }
4450  for (i = 1; i < m; i++)
4451  if (i != k)
4452  {
4453  shape(i+1) = w * rwk(i) / rxxk(i);
4454  }
4455  else
4456  {
4457  shape(k+1) = wk * rwk(k);
4458  }
4459 }
4460 
4462  DenseMatrix &dshape) const
4463 {
4464  double s, srx, w, wk, x = ip.x;
4465  int i, k, m = GetOrder();
4466 
4467 #ifdef MFEM_THREAD_SAFE
4468  Vector rxxk(m+1);
4469 #endif
4470 
4471  k = (int) floor ( m * x + 0.5 );
4472  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
4473 
4474  wk = 1.0;
4475  for (i = 0; i <= m; i++)
4476  if (i != k)
4477  {
4478  wk *= ( rxxk(i) = x - (double)(i) / m );
4479  }
4480  w = wk * ( rxxk(k) = x - (double)(k) / m );
4481 
4482  for (i = 0; i <= m; i++)
4483  {
4484  rxxk(i) = 1.0 / rxxk(i);
4485  }
4486  srx = 0.0;
4487  for (i = 0; i <= m; i++)
4488  if (i != k)
4489  {
4490  srx += rxxk(i);
4491  }
4492  s = w * srx + wk;
4493 
4494  if (k != 0)
4495  {
4496  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
4497  }
4498  else
4499  {
4500  dshape(0,0) = wk * srx * rwk(0);
4501  }
4502  if (k != m)
4503  {
4504  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
4505  }
4506  else
4507  {
4508  dshape(1,0) = wk * srx * rwk(k);
4509  }
4510  for (i = 1; i < m; i++)
4511  if (i != k)
4512  {
4513  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
4514  }
4515  else
4516  {
4517  dshape(k+1,0) = wk * srx * rwk(k);
4518  }
4519 }
4520 
4521 
4523  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
4524 {
4525  Nodes.IntPoint(0).x = 0.33333333333333333333;
4526  Nodes.IntPoint(0).y = 0.33333333333333333333;
4527  Nodes.IntPoint(0).z = 0.33333333333333333333;
4528 
4529  Nodes.IntPoint(1).x = 0.0;
4530  Nodes.IntPoint(1).y = 0.33333333333333333333;
4531  Nodes.IntPoint(1).z = 0.33333333333333333333;
4532 
4533  Nodes.IntPoint(2).x = 0.33333333333333333333;
4534  Nodes.IntPoint(2).y = 0.0;
4535  Nodes.IntPoint(2).z = 0.33333333333333333333;
4536 
4537  Nodes.IntPoint(3).x = 0.33333333333333333333;
4538  Nodes.IntPoint(3).y = 0.33333333333333333333;
4539  Nodes.IntPoint(3).z = 0.0;
4540 
4541 }
4542 
4544  Vector &shape) const
4545 {
4546  double L0, L1, L2, L3;
4547 
4548  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
4549  shape(0) = 1.0 - 3.0 * L0;
4550  shape(1) = 1.0 - 3.0 * L1;
4551  shape(2) = 1.0 - 3.0 * L2;
4552  shape(3) = 1.0 - 3.0 * L3;
4553 }
4554 
4556  DenseMatrix &dshape) const
4557 {
4558  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
4559  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
4560  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
4561  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
4562 }
4563 
4564 
4566  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 1, 0)
4567 {
4568  Nodes.IntPoint(0).x = 0.25;
4569  Nodes.IntPoint(0).y = 0.25;
4570  Nodes.IntPoint(0).z = 0.25;
4571 }
4572 
4574  Vector &shape) const
4575 {
4576  shape(0) = 1.0;
4577 }
4578 
4580  DenseMatrix &dshape) const
4581 {
4582  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
4583 }
4584 
4585 
4587  : NodalFiniteElement(3, Geometry::CUBE, 1, 0, FunctionSpace::Qk)
4588 {
4589  Nodes.IntPoint(0).x = 0.5;
4590  Nodes.IntPoint(0).y = 0.5;
4591  Nodes.IntPoint(0).z = 0.5;
4592 }
4593 
4595  Vector &shape) const
4596 {
4597  shape(0) = 1.0;
4598 }
4599 
4601  DenseMatrix &dshape) const
4602 {
4603  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
4604 }
4605 
4606 
4608  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
4609  degree, FunctionSpace::Qk)
4610 {
4611  if (degree == 2)
4612  {
4613  I = new int[dof];
4614  J = new int[dof];
4615  K = new int[dof];
4616  // nodes
4617  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
4618  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
4619  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
4620  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
4621  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
4622  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
4623  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
4624  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
4625  // edges
4626  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
4627  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
4628  I[10] = 2; J[10] = 1; K[10] = 0;
4629  I[11] = 0; J[11] = 2; K[11] = 0;
4630  I[12] = 2; J[12] = 0; K[12] = 1;
4631  I[13] = 1; J[13] = 2; K[13] = 1;
4632  I[14] = 2; J[14] = 1; K[14] = 1;
4633  I[15] = 0; J[15] = 2; K[15] = 1;
4634  I[16] = 0; J[16] = 0; K[16] = 2;
4635  I[17] = 1; J[17] = 0; K[17] = 2;
4636  I[18] = 1; J[18] = 1; K[18] = 2;
4637  I[19] = 0; J[19] = 1; K[19] = 2;
4638  // faces
4639  I[20] = 2; J[20] = 2; K[20] = 0;
4640  I[21] = 2; J[21] = 0; K[21] = 2;
4641  I[22] = 1; J[22] = 2; K[22] = 2;
4642  I[23] = 2; J[23] = 1; K[23] = 2;
4643  I[24] = 0; J[24] = 2; K[24] = 2;
4644  I[25] = 2; J[25] = 2; K[25] = 1;
4645  // element
4646  I[26] = 2; J[26] = 2; K[26] = 2;
4647  }
4648  else if (degree == 3)
4649  {
4650  I = new int[dof];
4651  J = new int[dof];
4652  K = new int[dof];
4653  // nodes
4654  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
4655  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
4656  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
4657  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
4658  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
4659  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
4660  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
4661  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
4662  // edges
4663  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
4664  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
4665  I[10] = 1; J[10] = 2; K[10] = 0;
4666  I[11] = 1; J[11] = 3; K[11] = 0;
4667  I[12] = 2; J[12] = 1; K[12] = 0;
4668  I[13] = 3; J[13] = 1; K[13] = 0;
4669  I[14] = 0; J[14] = 2; K[14] = 0;
4670  I[15] = 0; J[15] = 3; K[15] = 0;
4671  I[16] = 2; J[16] = 0; K[16] = 1;
4672  I[17] = 3; J[17] = 0; K[17] = 1;
4673  I[18] = 1; J[18] = 2; K[18] = 1;
4674  I[19] = 1; J[19] = 3; K[19] = 1;
4675  I[20] = 2; J[20] = 1; K[20] = 1;
4676  I[21] = 3; J[21] = 1; K[21] = 1;
4677  I[22] = 0; J[22] = 2; K[22] = 1;
4678  I[23] = 0; J[23] = 3; K[23] = 1;
4679  I[24] = 0; J[24] = 0; K[24] = 2;
4680  I[25] = 0; J[25] = 0; K[25] = 3;
4681  I[26] = 1; J[26] = 0; K[26] = 2;
4682  I[27] = 1; J[27] = 0; K[27] = 3;
4683  I[28] = 1; J[28] = 1; K[28] = 2;
4684  I[29] = 1; J[29] = 1; K[29] = 3;
4685  I[30] = 0; J[30] = 1; K[30] = 2;
4686  I[31] = 0; J[31] = 1; K[31] = 3;
4687  // faces
4688  I[32] = 2; J[32] = 3; K[32] = 0;
4689  I[33] = 3; J[33] = 3; K[33] = 0;
4690  I[34] = 2; J[34] = 2; K[34] = 0;
4691  I[35] = 3; J[35] = 2; K[35] = 0;
4692  I[36] = 2; J[36] = 0; K[36] = 2;
4693  I[37] = 3; J[37] = 0; K[37] = 2;
4694  I[38] = 2; J[38] = 0; K[38] = 3;
4695  I[39] = 3; J[39] = 0; K[39] = 3;
4696  I[40] = 1; J[40] = 2; K[40] = 2;
4697  I[41] = 1; J[41] = 3; K[41] = 2;
4698  I[42] = 1; J[42] = 2; K[42] = 3;
4699  I[43] = 1; J[43] = 3; K[43] = 3;
4700  I[44] = 3; J[44] = 1; K[44] = 2;
4701  I[45] = 2; J[45] = 1; K[45] = 2;
4702  I[46] = 3; J[46] = 1; K[46] = 3;
4703  I[47] = 2; J[47] = 1; K[47] = 3;
4704  I[48] = 0; J[48] = 3; K[48] = 2;
4705  I[49] = 0; J[49] = 2; K[49] = 2;
4706  I[50] = 0; J[50] = 3; K[50] = 3;
4707  I[51] = 0; J[51] = 2; K[51] = 3;
4708  I[52] = 2; J[52] = 2; K[52] = 1;
4709  I[53] = 3; J[53] = 2; K[53] = 1;
4710  I[54] = 2; J[54] = 3; K[54] = 1;
4711  I[55] = 3; J[55] = 3; K[55] = 1;
4712  // element
4713  I[56] = 2; J[56] = 2; K[56] = 2;
4714  I[57] = 3; J[57] = 2; K[57] = 2;
4715  I[58] = 3; J[58] = 3; K[58] = 2;
4716  I[59] = 2; J[59] = 3; K[59] = 2;
4717  I[60] = 2; J[60] = 2; K[60] = 3;
4718  I[61] = 3; J[61] = 2; K[61] = 3;
4719  I[62] = 3; J[62] = 3; K[62] = 3;
4720  I[63] = 2; J[63] = 3; K[63] = 3;
4721  }
4722  else
4723  {
4724  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
4725  }
4726 
4727  fe1d = new Lagrange1DFiniteElement(degree);
4728  dof1d = fe1d -> GetDof();
4729 
4730 #ifndef MFEM_THREAD_SAFE
4731  shape1dx.SetSize(dof1d);
4732  shape1dy.SetSize(dof1d);
4733  shape1dz.SetSize(dof1d);
4734 
4735  dshape1dx.SetSize(dof1d,1);
4736  dshape1dy.SetSize(dof1d,1);
4737  dshape1dz.SetSize(dof1d,1);
4738 #endif
4739 
4740  for (int n = 0; n < dof; n++)
4741  {
4742  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
4743  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
4744  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
4745  }
4746 }
4747 
4749  Vector &shape) const
4750 {
4751  IntegrationPoint ipy, ipz;
4752  ipy.x = ip.y;
4753  ipz.x = ip.z;
4754 
4755 #ifdef MFEM_THREAD_SAFE
4756  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4757 #endif
4758 
4759  fe1d -> CalcShape(ip, shape1dx);
4760  fe1d -> CalcShape(ipy, shape1dy);
4761  fe1d -> CalcShape(ipz, shape1dz);
4762 
4763  for (int n = 0; n < dof; n++)
4764  {
4765  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
4766  }
4767 }
4768 
4770  DenseMatrix &dshape) const
4771 {
4772  IntegrationPoint ipy, ipz;
4773  ipy.x = ip.y;
4774  ipz.x = ip.z;
4775 
4776 #ifdef MFEM_THREAD_SAFE
4777  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4778  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
4779 #endif
4780 
4781  fe1d -> CalcShape(ip, shape1dx);
4782  fe1d -> CalcShape(ipy, shape1dy);
4783  fe1d -> CalcShape(ipz, shape1dz);
4784 
4785  fe1d -> CalcDShape(ip, dshape1dx);
4786  fe1d -> CalcDShape(ipy, dshape1dy);
4787  fe1d -> CalcDShape(ipz, dshape1dz);
4788 
4789  for (int n = 0; n < dof; n++)
4790  {
4791  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
4792  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
4793  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
4794  }
4795 }
4796 
4798 {
4799  delete fe1d;
4800 
4801  delete [] I;
4802  delete [] J;
4803  delete [] K;
4804 }
4805 
4806 
4808  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
4809 {
4810  Nodes.IntPoint(0).x = 0.0;
4811  Nodes.IntPoint(1).x = 1.0;
4812  Nodes.IntPoint(2).x = 0.5;
4813 }
4814 
4816  Vector &shape) const
4817 {
4818  double x = ip.x;
4819 
4820  if (x <= 0.5)
4821  {
4822  shape(0) = 1.0 - 2.0 * x;
4823  shape(1) = 0.0;
4824  shape(2) = 2.0 * x;
4825  }
4826  else
4827  {
4828  shape(0) = 0.0;
4829  shape(1) = 2.0 * x - 1.0;
4830  shape(2) = 2.0 - 2.0 * x;
4831  }
4832 }
4833 
4835  DenseMatrix &dshape) const
4836 {
4837  double x = ip.x;
4838 
4839  if (x <= 0.5)
4840  {
4841  dshape(0,0) = - 2.0;
4842  dshape(1,0) = 0.0;
4843  dshape(2,0) = 2.0;
4844  }
4845  else
4846  {
4847  dshape(0,0) = 0.0;
4848  dshape(1,0) = 2.0;
4849  dshape(2,0) = - 2.0;
4850  }
4851 }
4852 
4854  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
4855 {
4856  Nodes.IntPoint(0).x = 0.0;
4857  Nodes.IntPoint(0).y = 0.0;
4858  Nodes.IntPoint(1).x = 1.0;
4859  Nodes.IntPoint(1).y = 0.0;
4860  Nodes.IntPoint(2).x = 0.0;
4861  Nodes.IntPoint(2).y = 1.0;
4862  Nodes.IntPoint(3).x = 0.5;
4863  Nodes.IntPoint(3).y = 0.0;
4864  Nodes.IntPoint(4).x = 0.5;
4865  Nodes.IntPoint(4).y = 0.5;
4866  Nodes.IntPoint(5).x = 0.0;
4867  Nodes.IntPoint(5).y = 0.5;
4868 }
4869 
4871  Vector &shape) const
4872 {
4873  int i;
4874 
4875  double L0, L1, L2;
4876  L0 = 2.0 * ( 1. - ip.x - ip.y );
4877  L1 = 2.0 * ( ip.x );
4878  L2 = 2.0 * ( ip.y );
4879 
4880  // The reference triangle is split in 4 triangles as follows:
4881  //
4882  // T0 - 0,3,5
4883  // T1 - 1,3,4
4884  // T2 - 2,4,5
4885  // T3 - 3,4,5
4886 
4887  for (i = 0; i < 6; i++)
4888  {
4889  shape(i) = 0.0;
4890  }
4891 
4892  if (L0 >= 1.0) // T0
4893  {
4894  shape(0) = L0 - 1.0;
4895  shape(3) = L1;
4896  shape(5) = L2;
4897  }
4898  else if (L1 >= 1.0) // T1
4899  {
4900  shape(3) = L0;
4901  shape(1) = L1 - 1.0;
4902  shape(4) = L2;
4903  }
4904  else if (L2 >= 1.0) // T2
4905  {
4906  shape(5) = L0;
4907  shape(4) = L1;
4908  shape(2) = L2 - 1.0;
4909  }
4910  else // T3
4911  {
4912  shape(3) = 1.0 - L2;
4913  shape(4) = 1.0 - L0;
4914  shape(5) = 1.0 - L1;
4915  }
4916 }
4917 
4919  DenseMatrix &dshape) const
4920 {
4921  int i,j;
4922 
4923  double L0, L1, L2;
4924  L0 = 2.0 * ( 1. - ip.x - ip.y );
4925  L1 = 2.0 * ( ip.x );
4926  L2 = 2.0 * ( ip.y );
4927 
4928  double DL0[2], DL1[2], DL2[2];
4929  DL0[0] = -2.0; DL0[1] = -2.0;
4930  DL1[0] = 2.0; DL1[1] = 0.0;
4931  DL2[0] = 0.0; DL2[1] = 2.0;
4932 
4933  for (i = 0; i < 6; i++)
4934  for (j = 0; j < 2; j++)
4935  {
4936  dshape(i,j) = 0.0;
4937  }
4938 
4939  if (L0 >= 1.0) // T0
4940  {
4941  for (j = 0; j < 2; j++)
4942  {
4943  dshape(0,j) = DL0[j];
4944  dshape(3,j) = DL1[j];
4945  dshape(5,j) = DL2[j];
4946  }
4947  }
4948  else if (L1 >= 1.0) // T1
4949  {
4950  for (j = 0; j < 2; j++)
4951  {
4952  dshape(3,j) = DL0[j];
4953  dshape(1,j) = DL1[j];
4954  dshape(4,j) = DL2[j];
4955  }
4956  }
4957  else if (L2 >= 1.0) // T2
4958  {
4959  for (j = 0; j < 2; j++)
4960  {
4961  dshape(5,j) = DL0[j];
4962  dshape(4,j) = DL1[j];
4963  dshape(2,j) = DL2[j];
4964  }
4965  }
4966  else // T3
4967  {
4968  for (j = 0; j < 2; j++)
4969  {
4970  dshape(3,j) = - DL2[j];
4971  dshape(4,j) = - DL0[j];
4972  dshape(5,j) = - DL1[j];
4973  }
4974  }
4975 }
4976 
4978  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
4979 {
4980  Nodes.IntPoint(0).x = 0.0;
4981  Nodes.IntPoint(0).y = 0.0;
4982  Nodes.IntPoint(0).z = 0.0;
4983  Nodes.IntPoint(1).x = 1.0;
4984  Nodes.IntPoint(1).y = 0.0;
4985  Nodes.IntPoint(1).z = 0.0;
4986  Nodes.IntPoint(2).x = 0.0;
4987  Nodes.IntPoint(2).y = 1.0;
4988  Nodes.IntPoint(2).z = 0.0;
4989  Nodes.IntPoint(3).x = 0.0;
4990  Nodes.IntPoint(3).y = 0.0;
4991  Nodes.IntPoint(3).z = 1.0;
4992  Nodes.IntPoint(4).x = 0.5;
4993  Nodes.IntPoint(4).y = 0.0;
4994  Nodes.IntPoint(4).z = 0.0;
4995  Nodes.IntPoint(5).x = 0.0;
4996  Nodes.IntPoint(5).y = 0.5;
4997  Nodes.IntPoint(5).z = 0.0;
4998  Nodes.IntPoint(6).x = 0.0;
4999  Nodes.IntPoint(6).y = 0.0;
5000  Nodes.IntPoint(6).z = 0.5;
5001  Nodes.IntPoint(7).x = 0.5;
5002  Nodes.IntPoint(7).y = 0.5;
5003  Nodes.IntPoint(7).z = 0.0;
5004  Nodes.IntPoint(8).x = 0.5;
5005  Nodes.IntPoint(8).y = 0.0;
5006  Nodes.IntPoint(8).z = 0.5;
5007  Nodes.IntPoint(9).x = 0.0;
5008  Nodes.IntPoint(9).y = 0.5;
5009  Nodes.IntPoint(9).z = 0.5;
5010 }
5011 
5013  Vector &shape) const
5014 {
5015  int i;
5016 
5017  double L0, L1, L2, L3, L4, L5;
5018  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
5019  L1 = 2.0 * ( ip.x );
5020  L2 = 2.0 * ( ip.y );
5021  L3 = 2.0 * ( ip.z );
5022  L4 = 2.0 * ( ip.x + ip.y );
5023  L5 = 2.0 * ( ip.y + ip.z );
5024 
5025  // The reference tetrahedron is split in 8 tetrahedra as follows:
5026  //
5027  // T0 - 0,4,5,6
5028  // T1 - 1,4,7,8
5029  // T2 - 2,5,7,9
5030  // T3 - 3,6,8,9
5031  // T4 - 4,5,6,8
5032  // T5 - 4,5,7,8
5033  // T6 - 5,6,8,9
5034  // T7 - 5,7,8,9
5035 
5036  for (i = 0; i < 10; i++)
5037  {
5038  shape(i) = 0.0;
5039  }
5040 
5041  if (L0 >= 1.0) // T0
5042  {
5043  shape(0) = L0 - 1.0;
5044  shape(4) = L1;
5045  shape(5) = L2;
5046  shape(6) = L3;
5047  }
5048  else if (L1 >= 1.0) // T1
5049  {
5050  shape(4) = L0;
5051  shape(1) = L1 - 1.0;
5052  shape(7) = L2;
5053  shape(8) = L3;
5054  }
5055  else if (L2 >= 1.0) // T2
5056  {
5057  shape(5) = L0;
5058  shape(7) = L1;
5059  shape(2) = L2 - 1.0;
5060  shape(9) = L3;
5061  }
5062  else if (L3 >= 1.0) // T3
5063  {
5064  shape(6) = L0;
5065  shape(8) = L1;
5066  shape(9) = L2;
5067  shape(3) = L3 - 1.0;
5068  }
5069  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
5070  {
5071  shape(4) = 1.0 - L5;
5072  shape(5) = L2;
5073  shape(6) = 1.0 - L4;
5074  shape(8) = 1.0 - L0;
5075  }
5076  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
5077  {
5078  shape(4) = 1.0 - L5;
5079  shape(5) = 1.0 - L1;
5080  shape(7) = L4 - 1.0;
5081  shape(8) = L3;
5082  }
5083  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
5084  {
5085  shape(5) = 1.0 - L3;
5086  shape(6) = 1.0 - L4;
5087  shape(8) = L1;
5088  shape(9) = L5 - 1.0;
5089  }
5090  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
5091  {
5092  shape(5) = L0;
5093  shape(7) = L4 - 1.0;
5094  shape(8) = 1.0 - L2;
5095  shape(9) = L5 - 1.0;
5096  }
5097 }
5098 
5100  DenseMatrix &dshape) const
5101 {
5102  int i,j;
5103 
5104  double L0, L1, L2, L3, L4, L5;
5105  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
5106  L1 = 2.0 * ( ip.x );
5107  L2 = 2.0 * ( ip.y );
5108  L3 = 2.0 * ( ip.z );
5109  L4 = 2.0 * ( ip.x + ip.y );
5110  L5 = 2.0 * ( ip.y + ip.z );
5111 
5112  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
5113  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
5114  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
5115  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
5116  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
5117  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
5118  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
5119 
5120  for (i = 0; i < 10; i++)
5121  for (j = 0; j < 3; j++)
5122  {
5123  dshape(i,j) = 0.0;
5124  }
5125 
5126  if (L0 >= 1.0) // T0
5127  {
5128  for (j = 0; j < 3; j++)
5129  {
5130  dshape(0,j) = DL0[j];
5131  dshape(4,j) = DL1[j];
5132  dshape(5,j) = DL2[j];
5133  dshape(6,j) = DL3[j];
5134  }
5135  }
5136  else if (L1 >= 1.0) // T1
5137  {
5138  for (j = 0; j < 3; j++)
5139  {
5140  dshape(4,j) = DL0[j];
5141  dshape(1,j) = DL1[j];
5142  dshape(7,j) = DL2[j];
5143  dshape(8,j) = DL3[j];
5144  }
5145  }
5146  else if (L2 >= 1.0) // T2
5147  {
5148  for (j = 0; j < 3; j++)
5149  {
5150  dshape(5,j) = DL0[j];
5151  dshape(7,j) = DL1[j];
5152  dshape(2,j) = DL2[j];
5153  dshape(9,j) = DL3[j];
5154  }
5155  }
5156  else if (L3 >= 1.0) // T3
5157  {
5158  for (j = 0; j < 3; j++)
5159  {
5160  dshape(6,j) = DL0[j];
5161  dshape(8,j) = DL1[j];
5162  dshape(9,j) = DL2[j];
5163  dshape(3,j) = DL3[j];
5164  }
5165  }
5166  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
5167  {
5168  for (j = 0; j < 3; j++)
5169  {
5170  dshape(4,j) = - DL5[j];
5171  dshape(5,j) = DL2[j];
5172  dshape(6,j) = - DL4[j];
5173  dshape(8,j) = - DL0[j];
5174  }
5175  }
5176  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
5177  {
5178  for (j = 0; j < 3; j++)
5179  {
5180  dshape(4,j) = - DL5[j];
5181  dshape(5,j) = - DL1[j];
5182  dshape(7,j) = DL4[j];
5183  dshape(8,j) = DL3[j];
5184  }
5185  }
5186  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
5187  {
5188  for (j = 0; j < 3; j++)
5189  {
5190  dshape(5,j) = - DL3[j];
5191  dshape(6,j) = - DL4[j];
5192  dshape(8,j) = DL1[j];
5193  dshape(9,j) = DL5[j];
5194  }
5195  }
5196  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
5197  {
5198  for (j = 0; j < 3; j++)
5199  {
5200  dshape(5,j) = DL0[j];
5201  dshape(7,j) = DL4[j];
5202  dshape(8,j) = - DL2[j];
5203  dshape(9,j) = DL5[j];
5204  }
5205  }
5206 }
5207 
5208 
5210  : NodalFiniteElement(2, Geometry::SQUARE, 9, 1, FunctionSpace::rQk)
5211 {
5212  Nodes.IntPoint(0).x = 0.0;
5213  Nodes.IntPoint(0).y = 0.0;
5214  Nodes.IntPoint(1).x = 1.0;
5215  Nodes.IntPoint(1).y = 0.0;
5216  Nodes.IntPoint(2).x = 1.0;
5217  Nodes.IntPoint(2).y = 1.0;
5218  Nodes.IntPoint(3).x = 0.0;
5219  Nodes.IntPoint(3).y = 1.0;
5220  Nodes.IntPoint(4).x = 0.5;
5221  Nodes.IntPoint(4).y = 0.0;
5222  Nodes.IntPoint(5).x = 1.0;
5223  Nodes.IntPoint(5).y = 0.5;
5224  Nodes.IntPoint(6).x = 0.5;
5225  Nodes.IntPoint(6).y = 1.0;
5226  Nodes.IntPoint(7).x = 0.0;
5227  Nodes.IntPoint(7).y = 0.5;
5228  Nodes.IntPoint(8).x = 0.5;
5229  Nodes.IntPoint(8).y = 0.5;
5230 }
5231 
5233  Vector &shape) const
5234 {
5235  int i;
5236  double x = ip.x, y = ip.y;
5237  double Lx, Ly;
5238  Lx = 2.0 * ( 1. - x );
5239  Ly = 2.0 * ( 1. - y );
5240 
5241  // The reference square is split in 4 squares as follows:
5242  //
5243  // T0 - 0,4,7,8
5244  // T1 - 1,4,5,8
5245  // T2 - 2,5,6,8
5246  // T3 - 3,6,7,8
5247 
5248  for (i = 0; i < 9; i++)
5249  {
5250  shape(i) = 0.0;
5251  }
5252 
5253  if ((x <= 0.5) && (y <= 0.5)) // T0
5254  {
5255  shape(0) = (Lx - 1.0) * (Ly - 1.0);
5256  shape(4) = (2.0 - Lx) * (Ly - 1.0);
5257  shape(8) = (2.0 - Lx) * (2.0 - Ly);
5258  shape(7) = (Lx - 1.0) * (2.0 - Ly);
5259  }
5260  else if ((x >= 0.5) && (y <= 0.5)) // T1
5261  {
5262  shape(4) = Lx * (Ly - 1.0);
5263  shape(1) = (1.0 - Lx) * (Ly - 1.0);
5264  shape(5) = (1.0 - Lx) * (2.0 - Ly);
5265  shape(8) = Lx * (2.0 - Ly);
5266  }
5267  else if ((x >= 0.5) && (y >= 0.5)) // T2
5268  {
5269  shape(8) = Lx * Ly ;
5270  shape(5) = (1.0 - Lx) * Ly ;
5271  shape(2) = (1.0 - Lx) * (1.0 - Ly);
5272  shape(6) = Lx * (1.0 - Ly);
5273  }
5274  else if ((x <= 0.5) && (y >= 0.5)) // T3
5275  {
5276  shape(7) = (Lx - 1.0) * Ly ;
5277  shape(8) = (2.0 - Lx) * Ly ;
5278  shape(6) = (2.0 - Lx) * (1.0 - Ly);
5279  shape(3) = (Lx - 1.0) * (1.0 - Ly);
5280  }
5281 }
5282 
5284  DenseMatrix &dshape) const
5285 {
5286  int i,j;
5287  double x = ip.x, y = ip.y;
5288  double Lx, Ly;
5289  Lx = 2.0 * ( 1. - x );
5290  Ly = 2.0 * ( 1. - y );
5291 
5292  for (i = 0; i < 9; i++)
5293  for (j = 0; j < 2; j++)
5294  {
5295  dshape(i,j) = 0.0;
5296  }
5297 
5298  if ((x <= 0.5) && (y <= 0.5)) // T0
5299  {
5300  dshape(0,0) = 2.0 * (1.0 - Ly);
5301  dshape(0,1) = 2.0 * (1.0 - Lx);
5302 
5303  dshape(4,0) = 2.0 * (Ly - 1.0);
5304  dshape(4,1) = -2.0 * (2.0 - Lx);
5305 
5306  dshape(8,0) = 2.0 * (2.0 - Ly);
5307  dshape(8,1) = 2.0 * (2.0 - Lx);
5308 
5309  dshape(7,0) = -2.0 * (2.0 - Ly);
5310  dshape(7,0) = 2.0 * (Lx - 1.0);
5311  }
5312  else if ((x >= 0.5) && (y <= 0.5)) // T1
5313  {
5314  dshape(4,0) = -2.0 * (Ly - 1.0);
5315  dshape(4,1) = -2.0 * Lx;
5316 
5317  dshape(1,0) = 2.0 * (Ly - 1.0);
5318  dshape(1,1) = -2.0 * (1.0 - Lx);
5319 
5320  dshape(5,0) = 2.0 * (2.0 - Ly);
5321  dshape(5,1) = 2.0 * (1.0 - Lx);
5322 
5323  dshape(8,0) = -2.0 * (2.0 - Ly);
5324  dshape(8,1) = 2.0 * Lx;
5325  }
5326  else if ((x >= 0.5) && (y >= 0.5)) // T2
5327  {
5328  dshape(8,0) = -2.0 * Ly;
5329  dshape(8,1) = -2.0 * Lx;
5330 
5331  dshape(5,0) = 2.0 * Ly;
5332  dshape(5,1) = -2.0 * (1.0 - Lx);
5333 
5334  dshape(2,0) = 2.0 * (1.0 - Ly);
5335  dshape(2,1) = 2.0 * (1.0 - Lx);
5336 
5337  dshape(6,0) = -2.0 * (1.0 - Ly);
5338  dshape(6,1) = 2.0 * Lx;
5339  }
5340  else if ((x <= 0.5) && (y >= 0.5)) // T3
5341  {
5342  dshape(7,0) = -2.0 * Ly;
5343  dshape(7,1) = -2.0 * (Lx - 1.0);
5344 
5345  dshape(8,0) = 2.0 * Ly ;
5346  dshape(8,1) = -2.0 * (2.0 - Lx);
5347 
5348  dshape(6,0) = 2.0 * (1.0 - Ly);
5349  dshape(6,1) = 2.0 * (2.0 - Lx);
5350 
5351  dshape(3,0) = -2.0 * (1.0 - Ly);
5352  dshape(3,1) = 2.0 * (Lx - 1.0);
5353  }
5354 }
5355 
5357  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
5358 {
5359  double I[27];
5360  double J[27];
5361  double K[27];
5362  // nodes
5363  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
5364  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
5365  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
5366  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
5367  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
5368  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
5369  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
5370  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
5371  // edges
5372  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
5373  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
5374  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
5375  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
5376  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
5377  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
5378  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
5379  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
5380  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
5381  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
5382  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
5383  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
5384  // faces
5385  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
5386  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
5387  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
5388  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
5389  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
5390  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
5391  // element
5392  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
5393 
5394  for (int n = 0; n < 27; n++)
5395  {
5396  Nodes.IntPoint(n).x = I[n];
5397  Nodes.IntPoint(n).y = J[n];
5398  Nodes.IntPoint(n).z = K[n];
5399  }
5400 }
5401 
5403  Vector &shape) const
5404 {
5405  int i, N[8];
5406  double Lx, Ly, Lz;
5407  double x = ip.x, y = ip.y, z = ip.z;
5408 
5409  for (i = 0; i < 27; i++)
5410  {
5411  shape(i) = 0.0;
5412  }
5413 
5414  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
5415  {
5416  Lx = 1.0 - 2.0 * x;
5417  Ly = 1.0 - 2.0 * y;
5418  Lz = 1.0 - 2.0 * z;
5419 
5420  N[0] = 0;
5421  N[1] = 8;
5422  N[2] = 20;
5423  N[3] = 11;
5424  N[4] = 16;
5425  N[5] = 21;
5426  N[6] = 26;
5427  N[7] = 24;
5428  }
5429  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
5430  {
5431  Lx = 2.0 - 2.0 * x;
5432  Ly = 1.0 - 2.0 * y;
5433  Lz = 1.0 - 2.0 * z;
5434 
5435  N[0] = 8;
5436  N[1] = 1;
5437  N[2] = 9;
5438  N[3] = 20;
5439  N[4] = 21;
5440  N[5] = 17;
5441  N[6] = 22;
5442  N[7] = 26;
5443  }
5444  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
5445  {
5446  Lx = 2.0 - 2.0 * x;
5447  Ly = 2.0 - 2.0 * y;
5448  Lz = 1.0 - 2.0 * z;
5449 
5450  N[0] = 20;
5451  N[1] = 9;
5452  N[2] = 2;
5453  N[3] = 10;
5454  N[4] = 26;
5455  N[5] = 22;
5456  N[6] = 18;
5457  N[7] = 23;
5458  }
5459  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
5460  {
5461  Lx = 1.0 - 2.0 * x;
5462  Ly = 2.0 - 2.0 * y;
5463  Lz = 1.0 - 2.0 * z;
5464 
5465  N[0] = 11;
5466  N[1] = 20;
5467  N[2] = 10;
5468  N[3] = 3;
5469  N[4] = 24;
5470  N[5] = 26;
5471  N[6] = 23;
5472  N[7] = 19;
5473  }
5474  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
5475  {
5476  Lx = 1.0 - 2.0 * x;
5477  Ly = 1.0 - 2.0 * y;
5478  Lz = 2.0 - 2.0 * z;
5479 
5480  N[0] = 16;
5481  N[1] = 21;
5482  N[2] = 26;
5483  N[3] = 24;
5484  N[4] = 4;
5485  N[5] = 12;
5486  N[6] = 25;
5487  N[7] = 15;
5488  }
5489  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
5490  {
5491  Lx = 2.0 - 2.0 * x;
5492  Ly = 1.0 - 2.0 * y;
5493  Lz = 2.0 - 2.0 * z;
5494 
5495  N[0] = 21;
5496  N[1] = 17;
5497  N[2] = 22;
5498  N[3] = 26;
5499  N[4] = 12;
5500  N[5] = 5;
5501  N[6] = 13;
5502  N[7] = 25;
5503  }
5504  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
5505  {
5506  Lx = 2.0 - 2.0 * x;
5507  Ly = 2.0 - 2.0 * y;
5508  Lz = 2.0 - 2.0 * z;
5509 
5510  N[0] = 26;
5511  N[1] = 22;
5512  N[2] = 18;
5513  N[3] = 23;
5514  N[4] = 25;
5515  N[5] = 13;
5516  N[6] = 6;
5517  N[7] = 14;
5518  }
5519  else // T7
5520  {
5521  Lx = 1.0 - 2.0 * x;
5522  Ly = 2.0 - 2.0 * y;
5523  Lz = 2.0 - 2.0 * z;
5524 
5525  N[0] = 24;
5526  N[1] = 26;
5527  N[2] = 23;
5528  N[3] = 19;
5529  N[4] = 15;
5530  N[5] = 25;
5531  N[6] = 14;
5532  N[7] = 7;
5533  }
5534 
5535  shape(N[0]) = Lx * Ly * Lz;
5536  shape(N[1]) = (1 - Lx) * Ly * Lz;
5537  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
5538  shape(N[3]) = Lx * (1 - Ly) * Lz;
5539  shape(N[4]) = Lx * Ly * (1 - Lz);
5540  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
5541  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
5542  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
5543 }
5544 
5546  DenseMatrix &dshape) const
5547 {
5548  int i, j, N[8];
5549  double Lx, Ly, Lz;
5550  double x = ip.x, y = ip.y, z = ip.z;
5551 
5552  for (i = 0; i < 27; i++)
5553  for (j = 0; j < 3; j++)
5554  {
5555  dshape(i,j) = 0.0;
5556  }
5557 
5558  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
5559  {
5560  Lx = 1.0 - 2.0 * x;
5561  Ly = 1.0 - 2.0 * y;
5562  Lz = 1.0 - 2.0 * z;
5563 
5564  N[0] = 0;
5565  N[1] = 8;
5566  N[2] = 20;
5567  N[3] = 11;
5568  N[4] = 16;
5569  N[5] = 21;
5570  N[6] = 26;
5571  N[7] = 24;
5572  }
5573  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
5574  {
5575  Lx = 2.0 - 2.0 * x;
5576  Ly = 1.0 - 2.0 * y;
5577  Lz = 1.0 - 2.0 * z;
5578 
5579  N[0] = 8;
5580  N[1] = 1;
5581  N[2] = 9;
5582  N[3] = 20;
5583  N[4] = 21;
5584  N[5] = 17;
5585  N[6] = 22;
5586  N[7] = 26;
5587  }
5588  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
5589  {
5590  Lx = 2.0 - 2.0 * x;
5591  Ly = 2.0 - 2.0 * y;
5592  Lz = 1.0 - 2.0 * z;
5593 
5594  N[0] = 20;
5595  N[1] = 9;
5596  N[2] = 2;
5597  N[3] = 10;
5598  N[4] = 26;
5599  N[5] = 22;
5600  N[6] = 18;
5601  N[7] = 23;
5602  }
5603  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
5604  {
5605  Lx = 1.0 - 2.0 * x;
5606  Ly = 2.0 - 2.0 * y;
5607  Lz = 1.0 - 2.0 * z;
5608 
5609  N[0] = 11;
5610  N[1] = 20;
5611  N[2] = 10;
5612  N[3] = 3;
5613  N[4] = 24;
5614  N[5] = 26;
5615  N[6] = 23;
5616  N[7] = 19;
5617  }
5618  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
5619  {
5620  Lx = 1.0 - 2.0 * x;
5621  Ly = 1.0 - 2.0 * y;
5622  Lz = 2.0 - 2.0 * z;
5623 
5624  N[0] = 16;
5625  N[1] = 21;
5626  N[2] = 26;
5627  N[3] = 24;
5628  N[4] = 4;
5629  N[5] = 12;
5630  N[6] = 25;
5631  N[7] = 15;
5632  }
5633  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
5634  {
5635  Lx = 2.0 - 2.0 * x;
5636  Ly = 1.0 - 2.0 * y;
5637  Lz = 2.0 - 2.0 * z;
5638 
5639  N[0] = 21;
5640  N[1] = 17;
5641  N[2] = 22;
5642  N[3] = 26;
5643  N[4] = 12;
5644  N[5] = 5;
5645  N[6] = 13;
5646  N[7] = 25;
5647  }
5648  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
5649  {
5650  Lx = 2.0 - 2.0 * x;
5651  Ly = 2.0 - 2.0 * y;
5652  Lz = 2.0 - 2.0 * z;
5653 
5654  N[0] = 26;
5655  N[1] = 22;
5656  N[2] = 18;
5657  N[3] = 23;
5658  N[4] = 25;
5659  N[5] = 13;
5660  N[6] = 6;
5661  N[7] = 14;
5662  }
5663  else // T7
5664  {
5665  Lx = 1.0 - 2.0 * x;
5666  Ly = 2.0 - 2.0 * y;
5667  Lz = 2.0 - 2.0 * z;
5668 
5669  N[0] = 24;
5670  N[1] = 26;
5671  N[2] = 23;
5672  N[3] = 19;
5673  N[4] = 15;
5674  N[5] = 25;
5675  N[6] = 14;
5676  N[7] = 7;
5677  }
5678 
5679  dshape(N[0],0) = -2.0 * Ly * Lz ;
5680  dshape(N[0],1) = -2.0 * Lx * Lz ;
5681  dshape(N[0],2) = -2.0 * Lx * Ly ;
5682 
5683  dshape(N[1],0) = 2.0 * Ly * Lz ;
5684  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
5685  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
5686 
5687  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
5688  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
5689  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
5690 
5691  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
5692  dshape(N[3],1) = 2.0 * Lx * Lz ;
5693  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
5694 
5695  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
5696  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
5697  dshape(N[4],2) = 2.0 * Lx * Ly ;
5698 
5699  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
5700  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
5701  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
5702 
5703  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
5704  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
5705  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
5706 
5707  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
5708  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
5709  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
5710 }
5711 
5712 
5714  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
5715 {
5716  // not real nodes ...
5717  Nodes.IntPoint(0).x = 0.5;
5718  Nodes.IntPoint(0).y = 0.0;
5719  Nodes.IntPoint(0).z = 0.0;
5720 
5721  Nodes.IntPoint(1).x = 1.0;
5722  Nodes.IntPoint(1).y = 0.5;
5723  Nodes.IntPoint(1).z = 0.0;
5724 
5725  Nodes.IntPoint(2).x = 0.5;
5726  Nodes.IntPoint(2).y = 1.0;
5727  Nodes.IntPoint(2).z = 0.0;
5728 
5729  Nodes.IntPoint(3).x = 0.0;
5730  Nodes.IntPoint(3).y = 0.5;
5731  Nodes.IntPoint(3).z = 0.0;
5732 
5733  Nodes.IntPoint(4).x = 0.5;
5734  Nodes.IntPoint(4).y = 0.0;
5735  Nodes.IntPoint(4).z = 1.0;
5736 
5737  Nodes.IntPoint(5).x = 1.0;
5738  Nodes.IntPoint(5).y = 0.5;
5739  Nodes.IntPoint(5).z = 1.0;
5740 
5741  Nodes.IntPoint(6).x = 0.5;
5742  Nodes.IntPoint(6).y = 1.0;
5743  Nodes.IntPoint(6).z = 1.0;
5744 
5745  Nodes.IntPoint(7).x = 0.0;
5746  Nodes.IntPoint(7).y = 0.5;
5747  Nodes.IntPoint(7).z = 1.0;
5748 
5749  Nodes.IntPoint(8).x = 0.0;
5750  Nodes.IntPoint(8).y = 0.0;
5751  Nodes.IntPoint(8).z = 0.5;
5752 
5753  Nodes.IntPoint(9).x = 1.0;
5754  Nodes.IntPoint(9).y = 0.0;
5755  Nodes.IntPoint(9).z = 0.5;
5756 
5757  Nodes.IntPoint(10).x= 1.0;
5758  Nodes.IntPoint(10).y= 1.0;
5759  Nodes.IntPoint(10).z= 0.5;
5760 
5761  Nodes.IntPoint(11).x= 0.0;
5762  Nodes.IntPoint(11).y= 1.0;
5763  Nodes.IntPoint(11).z= 0.5;
5764 }
5765 
5767  DenseMatrix &shape) const
5768 {
5769  double x = ip.x, y = ip.y, z = ip.z;
5770 
5771  shape(0,0) = (1. - y) * (1. - z);
5772  shape(0,1) = 0.;
5773  shape(0,2) = 0.;
5774 
5775  shape(2,0) = y * (1. - z);
5776  shape(2,1) = 0.;
5777  shape(2,2) = 0.;
5778 
5779  shape(4,0) = z * (1. - y);
5780  shape(4,1) = 0.;
5781  shape(4,2) = 0.;
5782 
5783  shape(6,0) = y * z;
5784  shape(6,1) = 0.;
5785  shape(6,2) = 0.;
5786 
5787  shape(1,0) = 0.;
5788  shape(1,1) = x * (1. - z);
5789  shape(1,2) = 0.;
5790 
5791  shape(3,0) = 0.;
5792  shape(3,1) = (1. - x) * (1. - z);
5793  shape(3,2) = 0.;
5794 
5795  shape(5,0) = 0.;
5796  shape(5,1) = x * z;
5797  shape(5,2) = 0.;
5798 
5799  shape(7,0) = 0.;
5800  shape(7,1) = (1. - x) * z;
5801  shape(7,2) = 0.;
5802 
5803  shape(8,0) = 0.;
5804  shape(8,1) = 0.;
5805  shape(8,2) = (1. - x) * (1. - y);
5806 
5807  shape(9,0) = 0.;
5808  shape(9,1) = 0.;
5809  shape(9,2) = x * (1. - y);
5810 
5811  shape(10,0) = 0.;
5812  shape(10,1) = 0.;
5813  shape(10,2) = x * y;
5814 
5815  shape(11,0) = 0.;
5816  shape(11,1) = 0.;
5817  shape(11,2) = y * (1. - x);
5818 
5819 }
5820 
5822  DenseMatrix &curl_shape)
5823 const
5824 {
5825  double x = ip.x, y = ip.y, z = ip.z;
5826 
5827  curl_shape(0,0) = 0.;
5828  curl_shape(0,1) = y - 1.;
5829  curl_shape(0,2) = 1. - z;
5830 
5831  curl_shape(2,0) = 0.;
5832  curl_shape(2,1) = -y;
5833  curl_shape(2,2) = z - 1.;
5834 
5835  curl_shape(4,0) = 0;
5836  curl_shape(4,1) = 1. - y;
5837  curl_shape(4,2) = z;
5838 
5839  curl_shape(6,0) = 0.;
5840  curl_shape(6,1) = y;
5841  curl_shape(6,2) = -z;
5842 
5843  curl_shape(1,0) = x;
5844  curl_shape(1,1) = 0.;
5845  curl_shape(1,2) = 1. - z;
5846 
5847  curl_shape(3,0) = 1. - x;
5848  curl_shape(3,1) = 0.;
5849  curl_shape(3,2) = z - 1.;
5850 
5851  curl_shape(5,0) = -x;
5852  curl_shape(5,1) = 0.;
5853  curl_shape(5,2) = z;
5854 
5855  curl_shape(7,0) = x - 1.;
5856  curl_shape(7,1) = 0.;
5857  curl_shape(7,2) = -z;
5858 
5859  curl_shape(8,0) = x - 1.;
5860  curl_shape(8,1) = 1. - y;
5861  curl_shape(8,2) = 0.;
5862 
5863  curl_shape(9,0) = -x;
5864  curl_shape(9,1) = y - 1.;
5865  curl_shape(9,2) = 0;
5866 
5867  curl_shape(10,0) = x;
5868  curl_shape(10,1) = -y;
5869  curl_shape(10,2) = 0.;
5870 
5871  curl_shape(11,0) = 1. - x;
5872  curl_shape(11,1) = y;
5873  curl_shape(11,2) = 0.;
5874 }
5875 
5876 const double Nedelec1HexFiniteElement::tk[12][3] =
5877 {
5878  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5879  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5880  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
5881 };
5882 
5885 {
5886  int k, j;
5887 #ifdef MFEM_THREAD_SAFE
5889 #endif
5890 
5891 #ifdef MFEM_DEBUG
5892  for (k = 0; k < 12; k++)
5893  {
5895  for (j = 0; j < 12; j++)
5896  {
5897  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5898  vshape(j,2)*tk[k][2] );
5899  if (j == k) { d -= 1.0; }
5900  if (fabs(d) > 1.0e-12)
5901  {
5902  mfem::err << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
5903  " k = " << k << ", j = " << j << ", d = " << d << endl;
5904  mfem_error();
5905  }
5906  }
5907  }
5908 #endif
5909 
5910  IntegrationPoint ip;
5911  ip.x = ip.y = ip.z = 0.0;
5912  Trans.SetIntPoint (&ip);
5913  // Trans must be linear (more to have embedding?)
5914  const DenseMatrix &J = Trans.Jacobian();
5915  double vk[3];
5916  Vector xk (vk, 3);
5917 
5918  for (k = 0; k < 12; k++)
5919  {
5920  Trans.Transform (Nodes.IntPoint (k), xk);
5921  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5922  CalcVShape (ip, vshape);
5923  // vk = J tk
5924  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5925  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5926  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5927  for (j = 0; j < 12; j++)
5928  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5929  vshape(j,2)*vk[2])) < 1.0e-12)
5930  {
5931  I(k,j) = 0.0;
5932  }
5933  }
5934 }
5935 
5938  Vector &dofs) const
5939 {
5940  double vk[3];
5941  Vector xk (vk, 3);
5942 
5943  for (int k = 0; k < 12; k++)
5944  {
5945  Trans.SetIntPoint (&Nodes.IntPoint (k));
5946  const DenseMatrix &J = Trans.Jacobian();
5947 
5948  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5949  // xk^t J tk
5950  dofs(k) =
5951  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5952  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5953  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5954  }
5955 }
5956 
5957 
5959  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
5960 {
5961  // not real nodes ...
5962  Nodes.IntPoint(0).x = 0.5;
5963  Nodes.IntPoint(0).y = 0.0;
5964  Nodes.IntPoint(0).z = 0.0;
5965 
5966  Nodes.IntPoint(1).x = 0.0;
5967  Nodes.IntPoint(1).y = 0.5;
5968  Nodes.IntPoint(1).z = 0.0;
5969 
5970  Nodes.IntPoint(2).x = 0.0;
5971  Nodes.IntPoint(2).y = 0.0;
5972  Nodes.IntPoint(2).z = 0.5;
5973 
5974  Nodes.IntPoint(3).x = 0.5;
5975  Nodes.IntPoint(3).y = 0.5;
5976  Nodes.IntPoint(3).z = 0.0;
5977 
5978  Nodes.IntPoint(4).x = 0.5;
5979  Nodes.IntPoint(4).y = 0.0;
5980  Nodes.IntPoint(4).z = 0.5;
5981 
5982  Nodes.IntPoint(5).x = 0.0;
5983  Nodes.IntPoint(5).y = 0.5;
5984  Nodes.IntPoint(5).z = 0.5;
5985 }
5986 
5988  DenseMatrix &shape) const
5989 {
5990  double x = ip.x, y = ip.y, z = ip.z;
5991 
5992  shape(0,0) = 1. - y - z;
5993  shape(0,1) = x;
5994  shape(0,2) = x;
5995 
5996  shape(1,0) = y;
5997  shape(1,1) = 1. - x - z;
5998  shape(1,2) = y;
5999 
6000  shape(2,0) = z;
6001  shape(2,1) = z;
6002  shape(2,2) = 1. - x - y;
6003 
6004  shape(3,0) = -y;
6005  shape(3,1) = x;
6006  shape(3,2) = 0.;
6007 
6008  shape(4,0) = -z;
6009  shape(4,1) = 0.;
6010  shape(4,2) = x;
6011 
6012  shape(5,0) = 0.;
6013  shape(5,1) = -z;
6014  shape(5,2) = y;
6015 }
6016 
6018  DenseMatrix &curl_shape)
6019 const
6020 {
6021  curl_shape(0,0) = 0.;
6022  curl_shape(0,1) = -2.;
6023  curl_shape(0,2) = 2.;
6024 
6025  curl_shape(1,0) = 2.;
6026  curl_shape(1,1) = 0.;
6027  curl_shape(1,2) = -2.;
6028 
6029  curl_shape(2,0) = -2.;
6030  curl_shape(2,1) = 2.;
6031  curl_shape(2,2) = 0.;
6032 
6033  curl_shape(3,0) = 0.;
6034  curl_shape(3,1) = 0.;
6035  curl_shape(3,2) = 2.;
6036 
6037  curl_shape(4,0) = 0.;
6038  curl_shape(4,1) = -2.;
6039  curl_shape(4,2) = 0.;
6040 
6041  curl_shape(5,0) = 2.;
6042  curl_shape(5,1) = 0.;
6043  curl_shape(5,2) = 0.;
6044 }
6045 
6046 const double Nedelec1TetFiniteElement::tk[6][3] =
6047 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
6048 
6051 {
6052  int k, j;
6053 #ifdef MFEM_THREAD_SAFE
6055 #endif
6056 
6057 #ifdef MFEM_DEBUG
6058  for (k = 0; k < 6; k++)
6059  {
6061  for (j = 0; j < 6; j++)
6062  {
6063  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
6064  vshape(j,2)*tk[k][2] );
6065  if (j == k) { d -= 1.0; }
6066  if (fabs(d) > 1.0e-12)
6067  {
6068  mfem::err << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
6069  " k = " << k << ", j = " << j << ", d = " << d << endl;
6070  mfem_error();
6071  }
6072  }
6073  }
6074 #endif
6075 
6076  IntegrationPoint ip;
6077  ip.x = ip.y = ip.z = 0.0;
6078  Trans.SetIntPoint (&ip);
6079  // Trans must be linear
6080  const DenseMatrix &J = Trans.Jacobian();
6081  double vk[3];
6082  Vector xk (vk, 3);
6083 
6084  for (k = 0; k < 6; k++)
6085  {
6086  Trans.Transform (Nodes.IntPoint (k), xk);
6087  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6088  CalcVShape (ip, vshape);
6089  // vk = J tk
6090  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
6091  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
6092  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
6093  for (j = 0; j < 6; j++)
6094  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6095  vshape(j,2)*vk[2])) < 1.0e-12)
6096  {
6097  I(k,j) = 0.0;
6098  }
6099  }
6100 }
6101 
6104  Vector &dofs) const
6105 {
6106  double vk[3];
6107  Vector xk (vk, 3);
6108 
6109  for (int k = 0; k < 6; k++)
6110  {
6111  Trans.SetIntPoint (&Nodes.IntPoint (k));
6112  const DenseMatrix &J = Trans.Jacobian();
6113 
6114  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6115  // xk^t J tk
6116  dofs(k) =
6117  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
6118  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
6119  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
6120  }
6121 }
6122 
6124  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
6125 {
6126  // not real nodes ...
6127  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
6128  Nodes.IntPoint(0).x = 0.5;
6129  Nodes.IntPoint(0).y = 0.5;
6130  Nodes.IntPoint(0).z = 0.0;
6131 
6132  Nodes.IntPoint(1).x = 0.5;
6133  Nodes.IntPoint(1).y = 0.0;
6134  Nodes.IntPoint(1).z = 0.5;
6135 
6136  Nodes.IntPoint(2).x = 1.0;
6137  Nodes.IntPoint(2).y = 0.5;
6138  Nodes.IntPoint(2).z = 0.5;
6139 
6140  Nodes.IntPoint(3).x = 0.5;
6141  Nodes.IntPoint(3).y = 1.0;
6142  Nodes.IntPoint(3).z = 0.5;
6143 
6144  Nodes.IntPoint(4).x = 0.0;
6145  Nodes.IntPoint(4).y = 0.5;
6146  Nodes.IntPoint(4).z = 0.5;
6147 
6148  Nodes.IntPoint(5).x = 0.5;
6149  Nodes.IntPoint(5).y = 0.5;
6150  Nodes.IntPoint(5).z = 1.0;
6151 }
6152 
6154  DenseMatrix &shape) const
6155 {
6156  double x = ip.x, y = ip.y, z = ip.z;
6157  // z = 0
6158  shape(0,0) = 0.;
6159  shape(0,1) = 0.;
6160  shape(0,2) = z - 1.;
6161  // y = 0
6162  shape(1,0) = 0.;
6163  shape(1,1) = y - 1.;
6164  shape(1,2) = 0.;
6165  // x = 1
6166  shape(2,0) = x;
6167  shape(2,1) = 0.;
6168  shape(2,2) = 0.;
6169  // y = 1
6170  shape(3,0) = 0.;
6171  shape(3,1) = y;
6172  shape(3,2) = 0.;
6173  // x = 0
6174  shape(4,0) = x - 1.;
6175  shape(4,1) = 0.;
6176  shape(4,2) = 0.;
6177  // z = 1
6178  shape(5,0) = 0.;
6179  shape(5,1) = 0.;
6180  shape(5,2) = z;
6181 }
6182 
6184  Vector &divshape) const
6185 {
6186  divshape(0) = 1.;
6187  divshape(1) = 1.;
6188  divshape(2) = 1.;
6189  divshape(3) = 1.;
6190  divshape(4) = 1.;
6191  divshape(5) = 1.;
6192 }
6193 
6194 const double RT0HexFiniteElement::nk[6][3] =
6195 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
6196 
6199 {
6200  int k, j;
6201 #ifdef MFEM_THREAD_SAFE
6203  DenseMatrix Jinv(dim);
6204 #endif
6205 
6206 #ifdef MFEM_DEBUG
6207  for (k = 0; k < 6; k++)
6208  {
6210  for (j = 0; j < 6; j++)
6211  {
6212  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6213  vshape(j,2)*nk[k][2] );
6214  if (j == k) { d -= 1.0; }
6215  if (fabs(d) > 1.0e-12)
6216  {
6217  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
6218  " k = " << k << ", j = " << j << ", d = " << d << endl;
6219  mfem_error();
6220  }
6221  }
6222  }
6223 #endif
6224 
6225  IntegrationPoint ip;
6226  ip.x = ip.y = ip.z = 0.0;
6227  Trans.SetIntPoint (&ip);
6228  // Trans must be linear
6229  // set Jinv = |J| J^{-t} = adj(J)^t
6230  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6231  double vk[3];
6232  Vector xk (vk, 3);
6233 
6234  for (k = 0; k < 6; k++)
6235  {
6236  Trans.Transform (Nodes.IntPoint (k), xk);
6237  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6238  CalcVShape (ip, vshape);
6239  // vk = |J| J^{-t} nk
6240  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6241  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6242  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6243  for (j = 0; j < 6; j++)
6244  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6245  vshape(j,2)*vk[2])) < 1.0e-12)
6246  {
6247  I(k,j) = 0.0;
6248  }
6249  }
6250 }
6251 
6254  Vector &dofs) const
6255 {
6256  double vk[3];
6257  Vector xk (vk, 3);
6258 #ifdef MFEM_THREAD_SAFE
6259  DenseMatrix Jinv(dim);
6260 #endif
6261 
6262  for (int k = 0; k < 6; k++)
6263  {
6264  Trans.SetIntPoint (&Nodes.IntPoint (k));
6265  // set Jinv = |J| J^{-t} = adj(J)^t
6266  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6267 
6268  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6269  // xk^t |J| J^{-t} nk
6270  dofs(k) =
6271  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6272  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6273  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6274  }
6275 }
6276 
6278  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
6279 {
6280  // z = 0
6281  Nodes.IntPoint(2).x = 1./3.;
6282  Nodes.IntPoint(2).y = 1./3.;
6283  Nodes.IntPoint(2).z = 0.0;
6284  Nodes.IntPoint(3).x = 2./3.;
6285  Nodes.IntPoint(3).y = 1./3.;
6286  Nodes.IntPoint(3).z = 0.0;
6287  Nodes.IntPoint(0).x = 1./3.;
6288  Nodes.IntPoint(0).y = 2./3.;
6289  Nodes.IntPoint(0).z = 0.0;
6290  Nodes.IntPoint(1).x = 2./3.;
6291  Nodes.IntPoint(1).y = 2./3.;
6292  Nodes.IntPoint(1).z = 0.0;
6293  // y = 0
6294  Nodes.IntPoint(4).x = 1./3.;
6295  Nodes.IntPoint(4).y = 0.0;
6296  Nodes.IntPoint(4).z = 1./3.;
6297  Nodes.IntPoint(5).x = 2./3.;
6298  Nodes.IntPoint(5).y = 0.0;
6299  Nodes.IntPoint(5).z = 1./3.;
6300  Nodes.IntPoint(6).x = 1./3.;
6301  Nodes.IntPoint(6).y = 0.0;
6302  Nodes.IntPoint(6).z = 2./3.;
6303  Nodes.IntPoint(7).x = 2./3.;
6304  Nodes.IntPoint(7).y = 0.0;
6305  Nodes.IntPoint(7).z = 2./3.;
6306  // x = 1
6307  Nodes.IntPoint(8).x = 1.0;
6308  Nodes.IntPoint(8).y = 1./3.;
6309  Nodes.IntPoint(8).z = 1./3.;
6310  Nodes.IntPoint(9).x = 1.0;
6311  Nodes.IntPoint(9).y = 2./3.;
6312  Nodes.IntPoint(9).z = 1./3.;
6313  Nodes.IntPoint(10).x = 1.0;
6314  Nodes.IntPoint(10).y = 1./3.;
6315  Nodes.IntPoint(10).z = 2./3.;
6316  Nodes.IntPoint(11).x = 1.0;
6317  Nodes.IntPoint(11).y = 2./3.;
6318  Nodes.IntPoint(11).z = 2./3.;
6319  // y = 1
6320  Nodes.IntPoint(13).x = 1./3.;
6321  Nodes.IntPoint(13).y = 1.0;
6322  Nodes.IntPoint(13).z = 1./3.;
6323  Nodes.IntPoint(12).x = 2./3.;
6324  Nodes.IntPoint(12).y = 1.0;
6325  Nodes.IntPoint(12).z = 1./3.;
6326  Nodes.IntPoint(15).x = 1./3.;
6327  Nodes.IntPoint(15).y = 1.0;
6328  Nodes.IntPoint(15).z = 2./3.;
6329  Nodes.IntPoint(14).x = 2./3.;
6330  Nodes.IntPoint(14).y = 1.0;
6331  Nodes.IntPoint(14).z = 2./3.;
6332  // x = 0
6333  Nodes.IntPoint(17).x = 0.0;
6334  Nodes.IntPoint(17).y = 1./3.;
6335  Nodes.IntPoint(17).z = 1./3.;
6336  Nodes.IntPoint(16).x = 0.0;
6337  Nodes.IntPoint(16).y = 2./3.;
6338  Nodes.IntPoint(16).z = 1./3.;
6339  Nodes.IntPoint(19).x = 0.0;
6340  Nodes.IntPoint(19).y = 1./3.;
6341  Nodes.IntPoint(19).z = 2./3.;
6342  Nodes.IntPoint(18).x = 0.0;
6343  Nodes.IntPoint(18).y = 2./3.;
6344  Nodes.IntPoint(18).z = 2./3.;
6345  // z = 1
6346  Nodes.IntPoint(20).x = 1./3.;
6347  Nodes.IntPoint(20).y = 1./3.;
6348  Nodes.IntPoint(20).z = 1.0;
6349  Nodes.IntPoint(21).x = 2./3.;
6350  Nodes.IntPoint(21).y = 1./3.;
6351  Nodes.IntPoint(21).z = 1.0;
6352  Nodes.IntPoint(22).x = 1./3.;
6353  Nodes.IntPoint(22).y = 2./3.;
6354  Nodes.IntPoint(22).z = 1.0;
6355  Nodes.IntPoint(23).x = 2./3.;
6356  Nodes.IntPoint(23).y = 2./3.;
6357  Nodes.IntPoint(23).z = 1.0;
6358  // x = 0.5 (interior)
6359  Nodes.IntPoint(24).x = 0.5;
6360  Nodes.IntPoint(24).y = 1./3.;
6361  Nodes.IntPoint(24).z = 1./3.;
6362  Nodes.IntPoint(25).x = 0.5;
6363  Nodes.IntPoint(25).y = 1./3.;
6364  Nodes.IntPoint(25).z = 2./3.;
6365  Nodes.IntPoint(26).x = 0.5;
6366  Nodes.IntPoint(26).y = 2./3.;
6367  Nodes.IntPoint(26).z = 1./3.;
6368  Nodes.IntPoint(27).x = 0.5;
6369  Nodes.IntPoint(27).y = 2./3.;
6370  Nodes.IntPoint(27).z = 2./3.;
6371  // y = 0.5 (interior)
6372  Nodes.IntPoint(28).x = 1./3.;
6373  Nodes.IntPoint(28).y = 0.5;
6374  Nodes.IntPoint(28).z = 1./3.;
6375  Nodes.IntPoint(29).x = 1./3.;
6376  Nodes.IntPoint(29).y = 0.5;
6377  Nodes.IntPoint(29).z = 2./3.;
6378  Nodes.IntPoint(30).x = 2./3.;
6379  Nodes.IntPoint(30).y = 0.5;
6380  Nodes.IntPoint(30).z = 1./3.;
6381  Nodes.IntPoint(31).x = 2./3.;
6382  Nodes.IntPoint(31).y = 0.5;
6383  Nodes.IntPoint(31).z = 2./3.;
6384  // z = 0.5 (interior)
6385  Nodes.IntPoint(32).x = 1./3.;
6386  Nodes.IntPoint(32).y = 1./3.;
6387  Nodes.IntPoint(32).z = 0.5;
6388  Nodes.IntPoint(33).x = 1./3.;
6389  Nodes.IntPoint(33).y = 2./3.;
6390  Nodes.IntPoint(33).z = 0.5;
6391  Nodes.IntPoint(34).x = 2./3.;
6392  Nodes.IntPoint(34).y = 1./3.;
6393  Nodes.IntPoint(34).z = 0.5;
6394  Nodes.IntPoint(35).x = 2./3.;
6395  Nodes.IntPoint(35).y = 2./3.;
6396  Nodes.IntPoint(35).z = 0.5;
6397 }
6398 
6400  DenseMatrix &shape) const
6401 {
6402  double x = ip.x, y = ip.y, z = ip.z;
6403  // z = 0
6404  shape(2,0) = 0.;
6405  shape(2,1) = 0.;
6406  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6407  shape(3,0) = 0.;
6408  shape(3,1) = 0.;
6409  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6410  shape(0,0) = 0.;
6411  shape(0,1) = 0.;
6412  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6413  shape(1,0) = 0.;
6414  shape(1,1) = 0.;
6415  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6416  // y = 0
6417  shape(4,0) = 0.;
6418  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6419  shape(4,2) = 0.;
6420  shape(5,0) = 0.;
6421  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6422  shape(5,2) = 0.;
6423  shape(6,0) = 0.;
6424  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6425  shape(6,2) = 0.;
6426  shape(7,0) = 0.;
6427  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6428  shape(7,2) = 0.;
6429  // x = 1
6430  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6431  shape(8,1) = 0.;
6432  shape(8,2) = 0.;
6433  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6434  shape(9,1) = 0.;
6435  shape(9,2) = 0.;
6436  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6437  shape(10,1) = 0.;
6438  shape(10,2) = 0.;
6439  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6440  shape(11,1) = 0.;
6441  shape(11,2) = 0.;
6442  // y = 1
6443  shape(13,0) = 0.;
6444  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6445  shape(13,2) = 0.;
6446  shape(12,0) = 0.;
6447  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6448  shape(12,2) = 0.;
6449  shape(15,0) = 0.;
6450  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6451  shape(15,2) = 0.;
6452  shape(14,0) = 0.;
6453  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6454  shape(14,2) = 0.;
6455  // x = 0
6456  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6457  shape(17,1) = 0.;
6458  shape(17,2) = 0.;
6459  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6460  shape(16,1) = 0.;
6461  shape(16,2) = 0.;
6462  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6463  shape(19,1) = 0.;
6464  shape(19,2) = 0.;
6465  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6466  shape(18,1) = 0.;
6467  shape(18,2) = 0.;
6468  // z = 1
6469  shape(20,0) = 0.;
6470  shape(20,1) = 0.;
6471  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6472  shape(21,0) = 0.;
6473  shape(21,1) = 0.;
6474  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6475  shape(22,0) = 0.;
6476  shape(22,1) = 0.;
6477  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6478  shape(23,0) = 0.;
6479  shape(23,1) = 0.;
6480  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6481  // x = 0.5 (interior)
6482  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6483  shape(24,1) = 0.;
6484  shape(24,2) = 0.;
6485  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6486  shape(25,1) = 0.;
6487  shape(25,2) = 0.;
6488  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6489  shape(26,1) = 0.;
6490  shape(26,2) = 0.;
6491  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6492  shape(27,1) = 0.;
6493  shape(27,2) = 0.;
6494  // y = 0.5 (interior)
6495  shape(28,0) = 0.;
6496  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6497  shape(28,2) = 0.;
6498  shape(29,0) = 0.;
6499  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6500  shape(29,2) = 0.;
6501  shape(30,0) = 0.;
6502  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6503  shape(30,2) = 0.;
6504  shape(31,0) = 0.;
6505  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6506  shape(31,2) = 0.;
6507  // z = 0.5 (interior)
6508  shape(32,0) = 0.;
6509  shape(32,1) = 0.;
6510  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6511  shape(33,0) = 0.;
6512  shape(33,1) = 0.;
6513  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6514  shape(34,0) = 0.;
6515  shape(34,1) = 0.;
6516  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6517  shape(35,0) = 0.;
6518  shape(35,1) = 0.;
6519  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6520 }
6521 
6523  Vector &divshape) const
6524 {
6525  double x = ip.x, y = ip.y, z = ip.z;
6526  // z = 0
6527  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6528  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6529  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6530  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6531  // y = 0
6532  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6533  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6534  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6535  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6536  // x = 1
6537  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6538  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6539  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6540  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6541  // y = 1
6542  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6543  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6544  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6545  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6546  // x = 0
6547  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6548  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6549  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6550  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6551  // z = 1
6552  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6553  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6554  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6555  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6556  // x = 0.5 (interior)
6557  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6558  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6559  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6560  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6561  // y = 0.5 (interior)
6562  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6563  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6564  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6565  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6566  // z = 0.5 (interior)
6567  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6568  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6569  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6570  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6571 }
6572 
6573 const double RT1HexFiniteElement::nk[36][3] =
6574 {
6575  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
6576  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
6577  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
6578  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
6579  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
6580  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
6581  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
6582  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
6583  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
6584 };
6585 
6588 {
6589  int k, j;
6590 #ifdef MFEM_THREAD_SAFE
6592  DenseMatrix Jinv(dim);
6593 #endif
6594 
6595 #ifdef MFEM_DEBUG
6596  for (k = 0; k < 36; k++)
6597  {
6599  for (j = 0; j < 36; j++)
6600  {
6601  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6602  vshape(j,2)*nk[k][2] );
6603  if (j == k) { d -= 1.0; }
6604  if (fabs(d) > 1.0e-12)
6605  {
6606  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
6607  " k = " << k << ", j = " << j << ", d = " << d << endl;
6608  mfem_error();
6609  }
6610  }
6611  }
6612 #endif
6613 
6614  IntegrationPoint ip;
6615  ip.x = ip.y = ip.z = 0.0;
6616  Trans.SetIntPoint (&ip);
6617  // Trans must be linear
6618  // set Jinv = |J| J^{-t} = adj(J)^t
6619  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6620  double vk[3];
6621  Vector xk (vk, 3);
6622 
6623  for (k = 0; k < 36; k++)
6624  {
6625  Trans.Transform (Nodes.IntPoint (k), xk);
6626  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6627  CalcVShape (ip, vshape);
6628  // vk = |J| J^{-t} nk
6629  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6630  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6631  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6632  for (j = 0; j < 36; j++)
6633  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6634  vshape(j,2)*vk[2])) < 1.0e-12)
6635  {
6636  I(k,j) = 0.0;
6637  }
6638  }
6639 }
6640 
6643  Vector &dofs) const
6644 {
6645  double vk[3];
6646  Vector xk (vk, 3);
6647 #ifdef MFEM_THREAD_SAFE
6648  DenseMatrix Jinv(dim);
6649 #endif
6650 
6651  for (int k = 0; k < 36; k++)
6652  {
6653  Trans.SetIntPoint (&Nodes.IntPoint (k));
6654  // set Jinv = |J| J^{-t} = adj(J)^t
6655  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6656 
6657  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6658  // xk^t |J| J^{-t} nk
6659  dofs(k) =
6660  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6661  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6662  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6663  }
6664 }
6665 
6667  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
6668 {
6669  // not real nodes ...
6670  Nodes.IntPoint(0).x = 0.33333333333333333333;
6671  Nodes.IntPoint(0).y = 0.33333333333333333333;
6672  Nodes.IntPoint(0).z = 0.33333333333333333333;
6673 
6674  Nodes.IntPoint(1).x = 0.0;
6675  Nodes.IntPoint(1).y = 0.33333333333333333333;
6676  Nodes.IntPoint(1).z = 0.33333333333333333333;
6677 
6678  Nodes.IntPoint(2).x = 0.33333333333333333333;
6679  Nodes.IntPoint(2).y = 0.0;
6680  Nodes.IntPoint(2).z = 0.33333333333333333333;
6681 
6682  Nodes.IntPoint(3).x = 0.33333333333333333333;
6683  Nodes.IntPoint(3).y = 0.33333333333333333333;
6684  Nodes.IntPoint(3).z = 0.0;
6685 }
6686 
6688  DenseMatrix &shape) const
6689 {
6690  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
6691 
6692  shape(0,0) = x2;
6693  shape(0,1) = y2;
6694  shape(0,2) = z2;
6695 
6696  shape(1,0) = x2 - 2.0;
6697  shape(1,1) = y2;
6698  shape(1,2) = z2;
6699 
6700  shape(2,0) = x2;
6701  shape(2,1) = y2 - 2.0;
6702  shape(2,2) = z2;
6703 
6704  shape(3,0) = x2;
6705  shape(3,1) = y2;
6706  shape(3,2) = z2 - 2.0;
6707 }
6708 
6710  Vector &divshape) const
6711 {
6712  divshape(0) = 6.0;
6713  divshape(1) = 6.0;
6714  divshape(2) = 6.0;
6715  divshape(3) = 6.0;
6716 }
6717 
6718 const double RT0TetFiniteElement::nk[4][3] =
6719 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
6720 
6723 {
6724  int k, j;
6725 #ifdef MFEM_THREAD_SAFE
6727  DenseMatrix Jinv(dim);
6728 #endif
6729 
6730 #ifdef MFEM_DEBUG
6731  for (k = 0; k < 4; k++)
6732  {
6734  for (j = 0; j < 4; j++)
6735  {
6736  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6737  vshape(j,2)*nk[k][2] );
6738  if (j == k) { d -= 1.0; }
6739  if (fabs(d) > 1.0e-12)
6740  {
6741  mfem::err << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
6742  " k = " << k << ", j = " << j << ", d = " << d << endl;
6743  mfem_error();
6744  }
6745  }
6746  }
6747 #endif
6748 
6749  IntegrationPoint ip;
6750  ip.x = ip.y = ip.z = 0.0;
6751  Trans.SetIntPoint (&ip);
6752  // Trans must be linear
6753  // set Jinv = |J| J^{-t} = adj(J)^t
6754  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6755  double vk[3];
6756  Vector xk (vk, 3);
6757 
6758  for (k = 0; k < 4; k++)
6759  {
6760  Trans.Transform (Nodes.IntPoint (k), xk);
6761  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6762  CalcVShape (ip, vshape);
6763  // vk = |J| J^{-t} nk
6764  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6765  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6766  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6767  for (j = 0; j < 4; j++)
6768  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6769  vshape(j,2)*vk[2])) < 1.0e-12)
6770  {
6771  I(k,j) = 0.0;
6772  }
6773  }
6774 }
6775 
6778  Vector &dofs) const
6779 {
6780  double vk[3];
6781  Vector xk (vk, 3);
6782 #ifdef MFEM_THREAD_SAFE
6783  DenseMatrix Jinv(dim);
6784 #endif
6785 
6786  for (int k = 0; k < 4; k++)
6787  {
6788  Trans.SetIntPoint (&Nodes.IntPoint (k));
6789  // set Jinv = |J| J^{-t} = adj(J)^t
6790  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6791 
6792  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6793  // xk^t |J| J^{-t} nk
6794  dofs(k) =
6795  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6796  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6797  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6798  }
6799 }
6800 
6802  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
6803 {
6804  Nodes.IntPoint(0).x = 0.5;
6805  Nodes.IntPoint(0).y = 0.5;
6806  Nodes.IntPoint(0).z = 0.0;
6807 
6808  Nodes.IntPoint(1).x = 0.5;
6809  Nodes.IntPoint(1).y = 0.0;
6810  Nodes.IntPoint(1).z = 0.5;
6811 
6812  Nodes.IntPoint(2).x = 1.0;
6813  Nodes.IntPoint(2).y = 0.5;
6814  Nodes.IntPoint(2).z = 0.5;
6815 
6816  Nodes.IntPoint(3).x = 0.5;
6817  Nodes.IntPoint(3).y = 1.0;
6818  Nodes.IntPoint(3).z = 0.5;
6819 
6820  Nodes.IntPoint(4).x = 0.0;
6821  Nodes.IntPoint(4).y = 0.5;
6822  Nodes.IntPoint(4).z = 0.5;
6823 
6824  Nodes.IntPoint(5).x = 0.5;
6825  Nodes.IntPoint(5).y = 0.5;
6826  Nodes.IntPoint(5).z = 1.0;
6827 }
6828 
6830  Vector &shape) const
6831 {
6832  double x = 2. * ip.x - 1.;
6833  double y = 2. * ip.y - 1.;
6834  double z = 2. * ip.z - 1.;
6835  double f5 = x * x - y * y;
6836  double f6 = y * y - z * z;
6837 
6838  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
6839  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
6840  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
6841  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
6842  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
6843  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
6844 }
6845 
6847  DenseMatrix &dshape) const
6848 {
6849  const double a = 2./3.;
6850 
6851  double xt = a * (1. - 2. * ip.x);
6852  double yt = a * (1. - 2. * ip.y);
6853  double zt = a * (1. - 2. * ip.z);
6854 
6855  dshape(0,0) = xt;
6856  dshape(0,1) = yt;
6857  dshape(0,2) = -1. - 2. * zt;
6858 
6859  dshape(1,0) = xt;
6860  dshape(1,1) = -1. - 2. * yt;
6861  dshape(1,2) = zt;
6862 
6863  dshape(2,0) = 1. - 2. * xt;
6864  dshape(2,1) = yt;
6865  dshape(2,2) = zt;
6866 
6867  dshape(3,0) = xt;
6868  dshape(3,1) = 1. - 2. * yt;
6869  dshape(3,2) = zt;
6870 
6871  dshape(4,0) = -1. - 2. * xt;
6872  dshape(4,1) = yt;
6873  dshape(4,2) = zt;
6874 
6875  dshape(5,0) = xt;
6876  dshape(5,1) = yt;
6877  dshape(5,2) = 1. - 2. * zt;
6878 }
6879 
6880 
6881 Poly_1D::Basis::Basis(const int p, const double *nodes, EvalType etype)
6882  : etype(etype)
6883 {
6884  switch (etype)
6885  {
6886  case ChangeOfBasis:
6887  {
6888  x.SetSize(p + 1);
6889  w.SetSize(p + 1);
6890  DenseMatrix A(p + 1);
6891  for (int i = 0; i <= p; i++)
6892  {
6893  CalcBasis(p, nodes[i], A.GetColumn(i));
6894  }
6895  Ai.Factor(A);
6896  // mfem::out << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
6897  break;
6898  }
6899  case Barycentric:
6900  {
6901  x.SetSize(p + 1);
6902  w.SetSize(p + 1);
6903  x = nodes;
6904  w = 1.0;
6905  for (int i = 0; i <= p; i++)
6906  {
6907  for (int j = 0; j < i; j++)
6908  {
6909  double xij = x(i) - x(j);
6910  w(i) *= xij;
6911  w(j) *= -xij;
6912  }
6913  }
6914  for (int i = 0; i <= p; i++)
6915  {
6916  w(i) = 1.0/w(i);
6917  }
6918 
6919 #ifdef MFEM_DEBUG
6920  // Make sure the nodes are increasing
6921  for (int i = 0; i < p; i++)
6922  {
6923  if (x(i) >= x(i+1))
6924  {
6925  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
6926  }
6927  }
6928 #endif
6929  break;
6930  }
6931  case Positive:
6932  x.SetDataAndSize(NULL, p + 1); // use x to store (p + 1)
6933  break;
6934 
6935  default: break;
6936  }
6937 }
6938 
6939 void Poly_1D::Basis::Eval(const double y, Vector &u) const
6940 {
6941  switch (etype)
6942  {
6943  case ChangeOfBasis:
6944  {
6945  CalcBasis(Ai.Width() - 1, y, x);
6946  Ai.Mult(x, u);
6947  break;
6948  }
6949  case Barycentric:
6950  {
6951  int i, k, p = x.Size() - 1;
6952  double l, lk;
6953 
6954  if (p == 0)
6955  {
6956  u(0) = 1.0;
6957  return;
6958  }
6959 
6960  lk = 1.0;
6961  for (k = 0; k < p; k++)
6962  {
6963  if (y >= (x(k) + x(k+1))/2)
6964  {
6965  lk *= y - x(k);
6966  }
6967  else
6968  {
6969  for (i = k+1; i <= p; i++)
6970  {
6971  lk *= y - x(i);
6972  }
6973  break;
6974  }
6975  }
6976  l = lk * (y - x(k));
6977 
6978  for (i = 0; i < k; i++)
6979  {
6980  u(i) = l * w(i) / (y - x(i));
6981  }
6982  u(k) = lk * w(k);
6983  for (i++; i <= p; i++)
6984  {
6985  u(i) = l * w(i) / (y - x(i));
6986  }
6987  break;
6988  }
6989  case Positive:
6990  CalcBernstein(x.Size() - 1, y, u);
6991  break;
6992 
6993  default: break;
6994  }
6995 }
6996 
6997 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
6998 {
6999  switch (etype)
7000  {
7001  case ChangeOfBasis:
7002  {
7003  CalcBasis(Ai.Width() - 1, y, x, w);
7004  Ai.Mult(x, u);
7005  Ai.Mult(w, d);
7006  break;
7007  }
7008  case Barycentric:
7009  {
7010  int i, k, p = x.Size() - 1;
7011  double l, lp, lk, sk, si;
7012 
7013  if (p == 0)
7014  {
7015  u(0) = 1.0;
7016  d(0) = 0.0;
7017  return;
7018  }
7019 
7020  lk = 1.0;
7021  for (k = 0; k < p; k++)
7022  {
7023  if (y >= (x(k) + x(k+1))/2)
7024  {
7025  lk *= y - x(k);
7026  }
7027  else
7028  {
7029  for (i = k+1; i <= p; i++)
7030  {
7031  lk *= y - x(i);
7032  }
7033  break;
7034  }
7035  }
7036  l = lk * (y - x(k));
7037 
7038  sk = 0.0;
7039  for (i = 0; i < k; i++)
7040  {
7041  si = 1.0/(y - x(i));
7042  sk += si;
7043  u(i) = l * si * w(i);
7044  }
7045  u(k) = lk * w(k);
7046  for (i++; i <= p; i++)
7047  {
7048  si = 1.0/(y - x(i));
7049  sk += si;
7050  u(i) = l * si * w(i);
7051  }
7052  lp = l * sk + lk;
7053 
7054  for (i = 0; i < k; i++)
7055  {
7056  d(i) = (lp * w(i) - u(i))/(y - x(i));
7057  }
7058  d(k) = sk * u(k);
7059  for (i++; i <= p; i++)
7060  {
7061  d(i) = (lp * w(i) - u(i))/(y - x(i));
7062  }
7063  break;
7064  }
7065  case Positive:
7066  CalcBernstein(x.Size() - 1, y, u, d);
7067  break;
7068 
7069  default: break;
7070  }
7071 }
7072 
7073 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d,
7074  Vector &d2) const
7075 {
7076  MFEM_VERIFY(etype == Barycentric,
7077  "Basis::Eval with second order derivatives not implemented for"
7078  " etype = " << etype);
7079  switch (etype)
7080  {
7081  case ChangeOfBasis:
7082  {
7083  CalcBasis(Ai.Width() - 1, y, x, w);
7084  Ai.Mult(x, u);
7085  Ai.Mult(w, d);
7086  // set d2 (not implemented yet)
7087  break;
7088  }
7089  case Barycentric:
7090  {
7091  int i, k, p = x.Size() - 1;
7092  double l, lp, lp2, lk, sk, si, sk2;
7093 
7094  if (p == 0)
7095  {
7096  u(0) = 1.0;
7097  d(0) = 0.0;
7098  d2(0) = 0.0;
7099  return;
7100  }
7101 
7102  lk = 1.0;
7103  for (k = 0; k < p; k++)
7104  {
7105  if (y >= (x(k) + x(k+1))/2)
7106  {
7107  lk *= y - x(k);
7108  }
7109  else
7110  {
7111  for (i = k+1; i <= p; i++)
7112  {
7113  lk *= y - x(i);
7114  }
7115  break;
7116  }
7117  }
7118  l = lk * (y - x(k));
7119 
7120  sk = 0.0;
7121  sk2 = 0.0;
7122  for (i = 0; i < k; i++)
7123  {
7124  si = 1.0/(y - x(i));
7125  sk += si;
7126  sk2 -= si * si;
7127  u(i) = l * si * w(i);
7128  }
7129  u(k) = lk * w(k);
7130  for (i++; i <= p; i++)
7131  {
7132  si = 1.0/(y - x(i));
7133  sk += si;
7134  sk2 -= si * si;
7135  u(i) = l * si * w(i);
7136  }
7137  lp = l * sk + lk;
7138  lp2 = lp * sk + l * sk2 + sk * lk;
7139 
7140  for (i = 0; i < k; i++)
7141  {
7142  d(i) = (lp * w(i) - u(i))/(y - x(i));
7143  d2(i) = (lp2 * w(i) - 2 * d(i))/(y - x(i));
7144  }
7145  d(k) = sk * u(k);
7146  d2(k) = sk2 * u(k) + sk * d(k);
7147  for (i++; i <= p; i++)
7148  {
7149  d(i) = (lp * w(i) - u(i))/(y - x(i));
7150  d2(i) = (lp2 * w(i) - 2 * d(i))/(y - x(i));
7151  }
7152  break;
7153  }
7154  case Positive:
7155  CalcBernstein(x.Size() - 1, y, u, d);
7156  break;
7157 
7158  default: break;
7159  }
7160 }
7161 
7162 const int *Poly_1D::Binom(const int p)
7163 {
7164  if (binom.NumCols() <= p)
7165  {
7166  binom.SetSize(p + 1, p + 1);
7167  for (int i = 0; i <= p; i++)
7168  {
7169  binom(i,0) = binom(i,i) = 1;
7170  for (int j = 1; j < i; j++)
7171  {
7172  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
7173  }
7174  }
7175  }
7176  return binom[p];
7177 }
7178 
7179 void Poly_1D::ChebyshevPoints(const int p, double *x)
7180 {
7181  for (int i = 0; i <= p; i++)
7182  {
7183  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
7184  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
7185  x[i] = s*s;
7186  }
7187 }
7188 
7189 void Poly_1D::CalcMono(const int p, const double x, double *u)
7190 {
7191  double xn;
7192  u[0] = xn = 1.;
7193  for (int n = 1; n <= p; n++)
7194  {
7195  u[n] = (xn *= x);
7196  }
7197 }
7198 
7199 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
7200 {
7201  double xn;
7202  u[0] = xn = 1.;
7203  d[0] = 0.;
7204  for (int n = 1; n <= p; n++)
7205  {
7206  d[n] = n * xn;
7207  u[n] = (xn *= x);
7208  }
7209 }
7210 
7211 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
7212  double *u)
7213 {
7214  if (p == 0)
7215  {
7216  u[0] = 1.;
7217  }
7218  else
7219  {
7220  int i;
7221  const int *b = Binom(p);
7222  double z = x;
7223 
7224  for (i = 1; i < p; i++)
7225  {
7226  u[i] = b[i]*z;
7227  z *= x;
7228  }
7229  u[p] = z;
7230  z = y;
7231  for (i--; i > 0; i--)
7232  {
7233  u[i] *= z;
7234  z *= y;
7235  }
7236  u[0] = z;
7237  }
7238 }
7239 
7240 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
7241  double *u, double *d)
7242 {
7243  if (p == 0)
7244  {
7245  u[0] = 1.;
7246  d[0] = 0.;
7247  }
7248  else
7249  {
7250  int i;
7251  const int *b = Binom(p);
7252  const double xpy = x + y, ptx = p*x;
7253  double z = 1.;
7254 
7255  for (i = 1; i < p; i++)
7256  {
7257  d[i] = b[i]*z*(i*xpy - ptx);
7258  z *= x;
7259  u[i] = b[i]*z;
7260  }
7261  d[p] = p*z;
7262  u[p] = z*x;
7263  z = 1.;
7264  for (i--; i > 0; i--)
7265  {
7266  d[i] *= z;
7267  z *= y;
7268  u[i] *= z;
7269  }
7270  d[0] = -p*z;
7271  u[0] = z*y;
7272  }
7273 }
7274 
7275 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
7276  double *d)
7277 {
7278  if (p == 0)
7279  {
7280  d[0] = 0.;
7281  }
7282  else
7283  {
7284  int i;
7285  const int *b = Binom(p);
7286  const double xpy = x + y, ptx = p*x;
7287  double z = 1.;
7288 
7289  for (i = 1; i < p; i++)
7290  {
7291  d[i] = b[i]*z*(i*xpy - ptx);
7292  z *= x;
7293  }
7294  d[p] = p*z;
7295  z = 1.;
7296  for (i--; i > 0; i--)
7297  {
7298  d[i] *= z;
7299  z *= y;
7300  }
7301  d[0] = -p*z;
7302  }
7303 }
7304 
7305 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
7306 {
7307  // use the recursive definition for [-1,1]:
7308  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
7309  double z;
7310  u[0] = 1.;
7311  if (p == 0) { return; }
7312  u[1] = z = 2.*x - 1.;
7313  for (int n = 1; n < p; n++)
7314  {
7315  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
7316  }
7317 }
7318 
7319 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
7320 {
7321  // use the recursive definition for [-1,1]:
7322  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
7323  // for the derivative use, z in [-1,1]:
7324  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
7325  double z;
7326  u[0] = 1.;
7327  d[0] = 0.;
7328  if (p == 0) { return; }
7329  u[1] = z = 2.*x - 1.;
7330  d[1] = 2.;
7331  for (int n = 1; n < p; n++)
7332  {
7333  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
7334  d[n+1] = (4*n + 2)*u[n] + d[n-1];
7335  }
7336 }
7337 
7338 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
7339 {
7340  // recursive definition, z in [-1,1]
7341  // T_0(z) = 1, T_1(z) = z
7342  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7343  double z;
7344  u[0] = 1.;
7345  if (p == 0) { return; }
7346  u[1] = z = 2.*x - 1.;
7347  for (int n = 1; n < p; n++)
7348  {
7349  u[n+1] = 2*z*u[n] - u[n-1];
7350  }
7351 }
7352 
7353 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
7354 {
7355  // recursive definition, z in [-1,1]
7356  // T_0(z) = 1, T_1(z) = z
7357  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7358  // T'_n(z) = n*U_{n-1}(z)
7359  // U_0(z) = 1 U_1(z) = 2*z
7360  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
7361  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
7362  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
7363  double z;
7364  u[0] = 1.;
7365  d[0] = 0.;
7366  if (p == 0) { return; }
7367  u[1] = z = 2.*x - 1.;
7368  d[1] = 2.;
7369  for (int n = 1; n < p; n++)
7370  {
7371  u[n+1] = 2*z*u[n] - u[n-1];
7372  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
7373  }
7374 }
7375 
7376 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d,
7377  double *dd)
7378 {
7379  // recursive definition, z in [-1,1]
7380  // T_0(z) = 1, T_1(z) = z
7381  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7382  // T'_n(z) = n*U_{n-1}(z)
7383  // U_0(z) = 1 U_1(z) = 2*z
7384  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
7385  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
7386  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
7387  // T''_{n+1}(z) = (n + 1)*(2*(n + 1)*T'_n(z) + z*T''_n(z)) / n
7388  double z;
7389  u[0] = 1.;
7390  d[0] = 0.;
7391  dd[0]= 0.;
7392  if (p == 0) { return; }
7393  u[1] = z = 2.*x - 1.;
7394  d[1] = 2.;
7395  dd[1] = 0;
7396  for (int n = 1; n < p; n++)
7397  {
7398  u[n+1] = 2*z*u[n] - u[n-1];
7399  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
7400  dd[n+1] = (n + 1)*(2.*(n + 1)*d[n] + z*dd[n])/n;
7401  }
7402 }
7403 
7404 const double *Poly_1D::GetPoints(const int p, const int btype)
7405 {
7406  BasisType::Check(btype);
7407  const int qtype = BasisType::GetQuadrature1D(btype);
7408 
7409  if (qtype == Quadrature1D::Invalid) { return NULL; }
7410 
7411  if (points_container.find(btype) == points_container.end())
7412  {
7413  points_container[btype] = new Array<double*>(h_mt);
7414  }
7415  Array<double*> &pts = *points_container[btype];
7416  if (pts.Size() <= p)
7417  {
7418  pts.SetSize(p + 1, NULL);
7419  }
7420  if (pts[p] == NULL)
7421  {
7422  pts[p] = new double[p + 1];
7423  quad_func.GivePolyPoints(p+1, pts[p], qtype);
7424  }
7425  return pts[p];
7426 }
7427 
7428 Poly_1D::Basis &Poly_1D::GetBasis(const int p, const int btype)
7429 {
7430  BasisType::Check(btype);
7431 
7432  if ( bases_container.find(btype) == bases_container.end() )
7433  {
7434  // we haven't been asked for basis or points of this type yet
7435  bases_container[btype] = new Array<Basis*>(h_mt);
7436  }
7437  Array<Basis*> &bases = *bases_container[btype];
7438  if (bases.Size() <= p)
7439  {
7440  bases.SetSize(p + 1, NULL);
7441  }
7442  if (bases[p] == NULL)
7443  {
7444  EvalType etype = (btype == BasisType::Positive) ? Positive : Barycentric;
7445  bases[p] = new Basis(p, GetPoints(p, btype), etype);
7446  }
7447  return *bases[p];
7448 }
7449 
7451 {
7452  for (PointsMap::iterator it = points_container.begin();
7453  it != points_container.end() ; ++it)
7454  {
7455  Array<double*>& pts = *it->second;
7456  for ( int i = 0 ; i < pts.Size() ; ++i )
7457  {
7458  delete [] pts[i];
7459  }
7460  delete it->second;
7461  }
7462 
7463  for (BasisMap::iterator it = bases_container.begin();
7464  it != bases_container.end() ; ++it)
7465  {
7466  Array<Basis*>& bases = *it->second;
7467  for ( int i = 0 ; i < bases.Size() ; ++i )
7468  {
7469  delete bases[i];
7470  }
7471  delete it->second;
7472  }
7473 }
7474 
7475 Array2D<int> Poly_1D::binom;
7477 
7478 
7479 TensorBasisElement::TensorBasisElement(const int dims, const int p,
7480  const int btype, const DofMapType dmtype)
7481  : b_type(btype),
7482  basis1d(poly1d.GetBasis(p, b_type))
7483 {
7484  if (dmtype == H1_DOF_MAP || dmtype == Sr_DOF_MAP)
7485  {
7486  switch (dims)
7487  {
7488  case 1:
7489  {
7490  dof_map.SetSize(p + 1);
7491  dof_map[0] = 0;
7492  dof_map[p] = 1;
7493  for (int i = 1; i < p; i++)
7494  {
7495  dof_map[i] = i+1;
7496  }
7497  break;
7498  }
7499  case 2:
7500  {
7501  const int p1 = p + 1;
7502  dof_map.SetSize(p1*p1);
7503 
7504  // vertices
7505  dof_map[0 + 0*p1] = 0;
7506  dof_map[p + 0*p1] = 1;
7507  dof_map[p + p*p1] = 2;
7508  dof_map[0 + p*p1] = 3;
7509 
7510  // edges
7511  int o = 4;
7512  for (int i = 1; i < p; i++)
7513  {
7514  dof_map[i + 0*p1] = o++;
7515  }
7516  for (int i = 1; i < p; i++)
7517  {
7518  dof_map[p + i*p1] = o++;
7519  }
7520  for (int i = 1; i < p; i++)
7521  {
7522  dof_map[(p-i) + p*p1] = o++;
7523  }
7524  for (int i = 1; i < p; i++)
7525  {
7526  dof_map[0 + (p-i)*p1] = o++;
7527  }
7528 
7529  // interior
7530  for (int j = 1; j < p; j++)
7531  {
7532  for (int i = 1; i < p; i++)
7533  {
7534  dof_map[i + j*p1] = o++;
7535  }
7536  }
7537  break;
7538  }
7539  case 3:
7540  {
7541  const int p1 = p + 1;
7542  dof_map.SetSize(p1*p1*p1);
7543 
7544  // vertices
7545  dof_map[0 + (0 + 0*p1)*p1] = 0;
7546  dof_map[p + (0 + 0*p1)*p1] = 1;
7547  dof_map[p + (p + 0*p1)*p1] = 2;
7548  dof_map[0 + (p + 0*p1)*p1] = 3;
7549  dof_map[0 + (0 + p*p1)*p1] = 4;
7550  dof_map[p + (0 + p*p1)*p1] = 5;
7551  dof_map[p + (p + p*p1)*p1] = 6;
7552  dof_map[0 + (p + p*p1)*p1] = 7;
7553 
7554  // edges (see Hexahedron::edges in mesh/hexahedron.cpp).
7555  // edges (see Constants<Geometry::CUBE>::Edges in fem/geom.cpp).
7556  int o = 8;
7557  for (int i = 1; i < p; i++)
7558  {
7559  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
7560  }
7561  for (int i = 1; i < p; i++)
7562  {
7563  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
7564  }
7565  for (int i = 1; i < p; i++)
7566  {
7567  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
7568  }
7569  for (int i = 1; i < p; i++)
7570  {
7571  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
7572  }
7573  for (int i = 1; i < p; i++)
7574  {
7575  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
7576  }
7577  for (int i = 1; i < p; i++)
7578  {
7579  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
7580  }
7581  for (int i = 1; i < p; i++)
7582  {
7583  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
7584  }
7585  for (int i = 1; i < p; i++)
7586  {
7587  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
7588  }
7589  for (int i = 1; i < p; i++)
7590  {
7591  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
7592  }
7593  for (int i = 1; i < p; i++)
7594  {
7595  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
7596  }
7597  for (int i = 1; i < p; i++)
7598  {
7599  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
7600  }
7601  for (int i = 1; i < p; i++)
7602  {
7603  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
7604  }
7605 
7606  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7607  for (int j = 1; j < p; j++)
7608  {
7609  for (int i = 1; i < p; i++)
7610  {
7611  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
7612  }
7613  }
7614  for (int j = 1; j < p; j++)
7615  {
7616  for (int i = 1; i < p; i++)
7617  {
7618  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
7619  }
7620  }
7621  for (int j = 1; j < p; j++)
7622  {
7623  for (int i = 1; i < p; i++)
7624  {
7625  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
7626  }
7627  }
7628  for (int j = 1; j < p; j++)
7629  {
7630  for (int i = 1; i < p; i++)
7631  {
7632  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
7633  }
7634  }
7635  for (int j = 1; j < p; j++)
7636  {
7637  for (int i = 1; i < p; i++)
7638  {
7639  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
7640  }
7641  }
7642  for (int j = 1; j < p; j++)
7643  {
7644  for (int i = 1; i < p; i++)
7645  {
7646  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
7647  }
7648  }
7649 
7650  // interior
7651  for (int k = 1; k < p; k++)
7652  {
7653  for (int j = 1; j < p; j++)
7654  {
7655  for (int i = 1; i < p; i++)
7656  {
7657  dof_map[i + (j + k*p1)*p1] = o++;
7658  }
7659  }
7660  }
7661  break;
7662  }
7663  default:
7664  MFEM_ABORT("invalid dimension: " << dims);
7665  break;
7666  }
7667  }
7668  else if (dmtype == L2_DOF_MAP)
7669  {
7670  // leave dof_map empty, indicating that the dofs are ordered
7671  // lexicographically, i.e. the dof_map is identity
7672  }
7673  else
7674  {
7675  MFEM_ABORT("invalid DofMapType: " << dmtype);
7676  }
7677 }
7678 
7679 
7681  const int p,
7682  const int btype,
7683  const DofMapType dmtype)
7684  : NodalFiniteElement(dims, GetTensorProductGeometry(dims), Pow(p + 1, dims),
7685  p, dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
7686  TensorBasisElement(dims, p, VerifyNodal(btype), dmtype) { }
7687 
7688 
7690  const int dims, const int p, const DofMapType dmtype)
7691  : PositiveFiniteElement(dims, GetTensorProductGeometry(dims),
7692  Pow(p + 1, dims), p,
7693  dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
7694  TensorBasisElement(dims, p, BasisType::Positive, dmtype) { }
7695 
7697  const int d,
7698  const int p,
7699  const int cbtype,
7700  const int obtype,
7701  const int M,
7702  const DofMapType dmtype)
7703  : VectorFiniteElement(dims, GetTensorProductGeometry(dims), d,
7704  p, M, FunctionSpace::Qk),
7705  TensorBasisElement(dims, p, VerifyNodal(cbtype), dmtype),
7706  cbasis1d(poly1d.GetBasis(p, VerifyClosed(cbtype))),
7707  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(obtype))) { }
7708 
7709 H1_SegmentElement::H1_SegmentElement(const int p, const int btype)
7710  : NodalTensorFiniteElement(1, p, VerifyClosed(btype), H1_DOF_MAP)
7711 {
7712  const double *cp = poly1d.ClosedPoints(p, b_type);
7713 
7714 #ifndef MFEM_THREAD_SAFE
7715  shape_x.SetSize(p+1);
7716  dshape_x.SetSize(p+1);
7717  d2shape_x.SetSize(p+1);
7718 #endif
7719 
7720  Nodes.IntPoint(0).x = cp[0];
7721  Nodes.IntPoint(1).x = cp[p];
7722  for (int i = 1; i < p; i++)
7723  {
7724  Nodes.IntPoint(i+1).x = cp[i];
7725  }
7726 }
7727 
7729  Vector &shape) const
7730 {
7731  const int p = order;
7732 
7733 #ifdef MFEM_THREAD_SAFE
7734  Vector shape_x(p+1);
7735 #endif
7736 
7737  basis1d.Eval(ip.x, shape_x);
7738 
7739  shape(0) = shape_x(0);
7740  shape(1) = shape_x(p);
7741  for (int i = 1; i < p; i++)
7742  {
7743  shape(i+1) = shape_x(i);
7744  }
7745 }
7746 
7748  DenseMatrix &dshape) const
7749 {
7750  const int p = order;
7751 
7752 #ifdef MFEM_THREAD_SAFE
7753  Vector shape_x(p+1), dshape_x(p+1);
7754 #endif
7755 
7756  basis1d.Eval(ip.x, shape_x, dshape_x);
7757 
7758  dshape(0,0) = dshape_x(0);
7759  dshape(1,0) = dshape_x(p);
7760  for (int i = 1; i < p; i++)
7761  {
7762  dshape(i+1,0) = dshape_x(i);
7763  }
7764 }
7765 
7767  DenseMatrix &Hessian) const
7768 {
7769  const int p = order;
7770 
7771 #ifdef MFEM_THREAD_SAFE
7772  Vector shape_x(p+1), dshape_x(p+1), d2shape_x(p+1);
7773 #endif
7774 
7775  basis1d.Eval(ip.x, shape_x, dshape_x, d2shape_x);
7776 
7777  Hessian(0,0) = d2shape_x(0);
7778  Hessian(1,0) = d2shape_x(p);
7779  for (int i = 1; i < p; i++)
7780  {
7781  Hessian(i+1,0) = d2shape_x(i);
7782  }
7783 }
7784 
7785 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7786 {
7787  const int p = order;
7788  const double *cp = poly1d.ClosedPoints(p, b_type);
7789 
7790  switch (vertex)
7791  {
7792  case 0:
7793  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
7794  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
7795  for (int i = 1; i < p; i++)
7796  {
7797  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7798  }
7799  break;
7800 
7801  case 1:
7802  dofs(0) = poly1d.CalcDelta(p, cp[0]);
7803  dofs(1) = poly1d.CalcDelta(p, cp[p]);
7804  for (int i = 1; i < p; i++)
7805  {
7806  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
7807  }
7808  break;
7809  }
7810 }
7811 
7812 
7814  : NodalTensorFiniteElement(2, p, VerifyClosed(btype), H1_DOF_MAP)
7815 {
7816  const double *cp = poly1d.ClosedPoints(p, b_type);
7817 
7818 #ifndef MFEM_THREAD_SAFE
7819  const int p1 = p + 1;
7820 
7821  shape_x.SetSize(p1);
7822  shape_y.SetSize(p1);
7823  dshape_x.SetSize(p1);
7824  dshape_y.SetSize(p1);
7825  d2shape_x.SetSize(p1);
7826  d2shape_y.SetSize(p1);
7827 #endif
7828 
7829  int o = 0;
7830  for (int j = 0; j <= p; j++)
7831  {
7832  for (int i = 0; i <= p; i++)
7833  {
7834  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
7835  }
7836  }
7837 }
7838 
7840  Vector &shape) const
7841 {
7842  const int p = order;
7843 
7844 #ifdef MFEM_THREAD_SAFE
7845  Vector shape_x(p+1), shape_y(p+1);
7846 #endif
7847 
7848  basis1d.Eval(ip.x, shape_x);
7849  basis1d.Eval(ip.y, shape_y);
7850 
7851  for (int o = 0, j = 0; j <= p; j++)
7852  for (int i = 0; i <= p; i++)
7853  {
7854  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7855  }
7856 }
7857 
7859  DenseMatrix &dshape) const
7860 {
7861  const int p = order;
7862 
7863 #ifdef MFEM_THREAD_SAFE
7864  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7865 #endif
7866 
7867  basis1d.Eval(ip.x, shape_x, dshape_x);
7868  basis1d.Eval(ip.y, shape_y, dshape_y);
7869 
7870  for (int o = 0, j = 0; j <= p; j++)
7871  {
7872  for (int i = 0; i <= p; i++)
7873  {
7874  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7875  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7876  }
7877  }
7878 }
7879 
7881  DenseMatrix &Hessian) const
7882 {
7883  const int p = order;
7884 
7885 #ifdef MFEM_THREAD_SAFE
7886  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1),
7887  d2shape_x(p+1), d2shape_y(p+1);
7888 #endif
7889 
7890  basis1d.Eval(ip.x, shape_x, dshape_x, d2shape_x);
7891  basis1d.Eval(ip.y, shape_y, dshape_y, d2shape_y);
7892 
7893  for (int o = 0, j = 0; j <= p; j++)
7894  {
7895  for (int i = 0; i <= p; i++)
7896  {
7897  Hessian(dof_map[o],0) = d2shape_x(i)* shape_y(j);
7898  Hessian(dof_map[o],1) = dshape_x(i)* dshape_y(j);
7899  Hessian(dof_map[o],2) = shape_x(i)*d2shape_y(j); o++;
7900  }
7901  }
7902 }
7903 
7904 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
7905 {
7906  const int p = order;
7907  const double *cp = poly1d.ClosedPoints(p, b_type);
7908 
7909 #ifdef MFEM_THREAD_SAFE
7910  Vector shape_x(p+1), shape_y(p+1);
7911 #endif
7912 
7913  for (int i = 0; i <= p; i++)
7914  {
7915  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7916  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7917  }
7918 
7919  switch (vertex)
7920  {
7921  case 0:
7922  for (int o = 0, j = 0; j <= p; j++)
7923  for (int i = 0; i <= p; i++)
7924  {
7925  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
7926  }
7927  break;
7928  case 1:
7929  for (int o = 0, j = 0; j <= p; j++)
7930  for (int i = 0; i <= p; i++)
7931  {
7932  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
7933  }
7934  break;
7935  case 2:
7936  for (int o = 0, j = 0; j <= p; j++)
7937  for (int i = 0; i <= p; i++)
7938  {
7939  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
7940  }
7941  break;
7942  case 3:
7943  for (int o = 0, j = 0; j <= p; j++)
7944  for (int i = 0; i <= p; i++)
7945  {
7946  dofs(dof_map[o++]) = shape_x(i)*shape_y(j);
7947  }
7948  break;
7949  }
7950 }
7951 
7952 
7953 H1_HexahedronElement::H1_HexahedronElement(const int p, const int btype)
7954  : NodalTensorFiniteElement(3, p, VerifyClosed(btype), H1_DOF_MAP)
7955 {
7956  const double *cp = poly1d.ClosedPoints(p, b_type);
7957 
7958 #ifndef MFEM_THREAD_SAFE
7959  const int p1 = p + 1;
7960 
7961  shape_x.SetSize(p1);
7962  shape_y.SetSize(p1);
7963  shape_z.SetSize(p1);
7964  dshape_x.SetSize(p1);
7965  dshape_y.SetSize(p1);
7966  dshape_z.SetSize(p1);
7967  d2shape_x.SetSize(p1);
7968  d2shape_y.SetSize(p1);
7969  d2shape_z.SetSize(p1);
7970 #endif
7971 
7972  int o = 0;
7973  for (int k = 0; k <= p; k++)
7974  for (int j = 0; j <= p; j++)
7975  for (int i = 0; i <= p; i++)
7976  {
7977  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
7978  }
7979 }
7980 
7982  Vector &shape) const
7983 {
7984  const int p = order;
7985 
7986 #ifdef MFEM_THREAD_SAFE
7987  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7988 #endif
7989 
7990  basis1d.Eval(ip.x, shape_x);
7991  basis1d.Eval(ip.y, shape_y);
7992  basis1d.Eval(ip.z, shape_z);
7993 
7994  for (int o = 0, k = 0; k <= p; k++)
7995  for (int j = 0; j <= p; j++)
7996  for (int i = 0; i <= p; i++)
7997  {
7998  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7999  }
8000 }
8001 
8003  DenseMatrix &dshape) const
8004 {
8005  const int p = order;
8006 
8007 #ifdef MFEM_THREAD_SAFE
8008  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8009  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8010 #endif
8011 
8012  basis1d.Eval(ip.x, shape_x, dshape_x);
8013  basis1d.Eval(ip.y, shape_y, dshape_y);
8014  basis1d.Eval(ip.z, shape_z, dshape_z);
8015 
8016  for (int o = 0, k = 0; k <= p; k++)
8017  for (int j = 0; j <= p; j++)
8018  for (int i = 0; i <= p; i++)
8019  {
8020  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
8021  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
8022  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8023  }
8024 }
8025 
8027  DenseMatrix &Hessian) const
8028 {
8029  const int p = order;
8030 
8031 #ifdef MFEM_THREAD_SAFE
8032  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8033  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8034  Vector d2shape_x(p+1), d2shape_y(p+1), d2shape_z(p+1);
8035 #endif
8036 
8037  basis1d.Eval(ip.x, shape_x, dshape_x, d2shape_x);
8038  basis1d.Eval(ip.y, shape_y, dshape_y, d2shape_y);
8039  basis1d.Eval(ip.z, shape_z, dshape_z, d2shape_z);
8040 
8041  for (int o = 0, k = 0; k <= p; k++)
8042  for (int j = 0; j <= p; j++)
8043  for (int i = 0; i <= p; i++)
8044  {
8045  Hessian(dof_map[o],0) = d2shape_x(i)* shape_y(j)* shape_z(k);
8046  Hessian(dof_map[o],1) = dshape_x(i)* dshape_y(j)* shape_z(k);
8047  Hessian(dof_map[o],2) = dshape_x(i)* shape_y(j)* dshape_z(k);
8048  Hessian(dof_map[o],3) = shape_x(i)*d2shape_y(j)* shape_z(k);
8049  Hessian(dof_map[o],4) = shape_x(i)* dshape_y(j)* dshape_z(k);
8050  Hessian(dof_map[o],5) = shape_x(i)* shape_y(j)*d2shape_z(k);
8051  o++;
8052  }
8053 }
8054 
8055 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8056 {
8057  const int p = order;
8058  const double *cp = poly1d.ClosedPoints(p,b_type);
8059 
8060 #ifdef MFEM_THREAD_SAFE
8061  Vector shape_x(p+1), shape_y(p+1);
8062 #endif
8063 
8064  for (int i = 0; i <= p; i++)
8065  {
8066  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
8067  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
8068  }
8069 
8070  switch (vertex)
8071  {
8072  case 0:
8073  for (int o = 0, k = 0; k <= p; k++)
8074  for (int j = 0; j <= p; j++)
8075  for (int i = 0; i <= p; i++)
8076  {
8077  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
8078  }
8079  break;
8080  case 1:
8081  for (int o = 0, k = 0; k <= p; k++)
8082  for (int j = 0; j <= p; j++)
8083  for (int i = 0; i <= p; i++)
8084  {
8085  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
8086  }
8087  break;
8088  case 2:
8089  for (int o = 0, k = 0; k <= p; k++)
8090  for (int j = 0; j <= p; j++)
8091  for (int i = 0; i <= p; i++)
8092  {
8093  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
8094  }
8095  break;
8096  case 3:
8097  for (int o = 0, k = 0; k <= p; k++)
8098  for (int j = 0; j <= p; j++)
8099  for (int i = 0; i <= p; i++)
8100  {
8101  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
8102  }
8103  break;
8104  case 4:
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  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
8110  }
8111  break;
8112  case 5:
8113  for (int o = 0, k = 0; k <= p; k++)
8114  for (int j = 0; j <= p; j++)
8115  for (int i = 0; i <= p; i++)
8116  {
8117  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
8118  }
8119  break;
8120  case 6:
8121  for (int o = 0, k = 0; k <= p; k++)
8122  for (int j = 0; j <= p; j++)
8123  for (int i = 0; i <= p; i++)
8124  {
8125  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
8126  }
8127  break;
8128  case 7:
8129  for (int o = 0, k = 0; k <= p; k++)
8130  for (int j = 0; j <= p; j++)
8131  for (int i = 0; i <= p; i++)
8132  {
8133  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
8134  }
8135  break;
8136  }
8137 }
8138 
8139 
8141  : PositiveTensorFiniteElement(1, p, H1_DOF_MAP)
8142 {
8143 #ifndef MFEM_THREAD_SAFE
8144  // thread private versions; see class header.
8145  shape_x.SetSize(p+1);
8146  dshape_x.SetSize(p+1);
8147 #endif
8148 
8149  // Endpoints need to be first in the list, so reorder them.
8150  Nodes.IntPoint(0).x = 0.0;
8151  Nodes.IntPoint(1).x = 1.0;
8152  for (int i = 1; i < p; i++)
8153  {
8154  Nodes.IntPoint(i+1).x = double(i)/p;
8155  }
8156 }
8157 
8159  Vector &shape) const
8160 {
8161  const int p = order;
8162 
8163 #ifdef MFEM_THREAD_SAFE
8164  Vector shape_x(p+1);
8165 #endif
8166 
8167  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
8168 
8169  // Endpoints need to be first in the list, so reorder them.
8170  shape(0) = shape_x(0);
8171  shape(1) = shape_x(p);
8172  for (int i = 1; i < p; i++)
8173  {
8174  shape(i+1) = shape_x(i);
8175  }
8176 }
8177 
8179  DenseMatrix &dshape) const
8180 {
8181  const int p = order;
8182 
8183 #ifdef MFEM_THREAD_SAFE
8184  Vector shape_x(p+1), dshape_x(p+1);
8185 #endif
8186 
8187  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
8188 
8189  // Endpoints need to be first in the list, so reorder them.
8190  dshape(0,0) = dshape_x(0);
8191  dshape(1,0) = dshape_x(p);
8192  for (int i = 1; i < p; i++)
8193  {
8194  dshape(i+1,0) = dshape_x(i);
8195  }
8196 }
8197 
8198 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8199 {
8200  dofs = 0.0;
8201  dofs[vertex] = 1.0;
8202 }
8203 
8204 
8206  : PositiveTensorFiniteElement(2, p, H1_DOF_MAP)
8207 {
8208 #ifndef MFEM_THREAD_SAFE
8209  const int p1 = p + 1;
8210 
8211  shape_x.SetSize(p1);
8212  shape_y.SetSize(p1);
8213  dshape_x.SetSize(p1);
8214  dshape_y.SetSize(p1);
8215 #endif
8216 
8217  int o = 0;
8218  for (int j = 0; j <= p; j++)
8219  for (int i = 0; i <= p; i++)
8220  {
8221  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
8222  }
8223 }
8224 
8226  Vector &shape) const
8227 {
8228  const int p = order;
8229 
8230 #ifdef MFEM_THREAD_SAFE
8231  Vector shape_x(p+1), shape_y(p+1);
8232 #endif
8233 
8234  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
8235  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
8236 
8237  // Reorder so that vertices are at the beginning of the list
8238  for (int o = 0, j = 0; j <= p; j++)
8239  for (int i = 0; i <= p; i++)
8240  {
8241  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
8242  }
8243 }
8244 
8246  DenseMatrix &dshape) const
8247 {
8248  const int p = order;
8249 
8250 #ifdef MFEM_THREAD_SAFE
8251  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8252 #endif
8253 
8254  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
8255  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
8256 
8257  // Reorder so that vertices are at the beginning of the list
8258  for (int o = 0, j = 0; j <= p; j++)
8259  for (int i = 0; i <= p; i++)
8260  {
8261  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
8262  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
8263  }
8264 }
8265 
8267 {
8268  dofs = 0.0;
8269  dofs[vertex] = 1.0;
8270 }
8271 
8272 
8274  : PositiveTensorFiniteElement(3, p, H1_DOF_MAP)
8275 {
8276 #ifndef MFEM_THREAD_SAFE
8277  const int p1 = p + 1;
8278 
8279  shape_x.SetSize(p1);
8280  shape_y.SetSize(p1);
8281  shape_z.SetSize(p1);
8282  dshape_x.SetSize(p1);
8283  dshape_y.SetSize(p1);
8284  dshape_z.SetSize(p1);
8285 #endif
8286 
8287  int o = 0;
8288  for (int k = 0; k <= p; k++)
8289  for (int j = 0; j <= p; j++)
8290  for (int i = 0; i <= p; i++)
8291  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
8292  double(k)/p);
8293 }
8294 
8296  Vector &shape) const
8297 {
8298  const int p = order;
8299 
8300 #ifdef MFEM_THREAD_SAFE
8301  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8302 #endif
8303 
8304  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
8305  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
8306  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
8307 
8308  for (int o = 0, k = 0; k <= p; k++)
8309  for (int j = 0; j <= p; j++)
8310  for (int i = 0; i <= p; i++)
8311  {
8312  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
8313  }
8314 }
8315 
8317  DenseMatrix &dshape) const
8318 {
8319  const int p = order;
8320 
8321 #ifdef MFEM_THREAD_SAFE
8322  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8323  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8324 #endif
8325 
8326  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
8327  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
8328  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
8329 
8330  for (int o = 0, k = 0; k <= p; k++)
8331  for (int j = 0; j <= p; j++)
8332  for (int i = 0; i <= p; i++)
8333  {
8334  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
8335  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
8336  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8337  }
8338 }
8339 
8340 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8341 {
8342  dofs = 0.0;
8343  dofs[vertex] = 1.0;
8344 }
8345 
8346 
8347 H1_TriangleElement::H1_TriangleElement(const int p, const int btype)
8348  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8349  FunctionSpace::Pk)
8350 {
8351  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
8352 
8353 #ifndef MFEM_THREAD_SAFE
8354  shape_x.SetSize(p + 1);
8355  shape_y.SetSize(p + 1);
8356  shape_l.SetSize(p + 1);
8357  dshape_x.SetSize(p + 1);
8358  dshape_y.SetSize(p + 1);
8359  dshape_l.SetSize(p + 1);
8360  ddshape_x.SetSize(p + 1);
8361  ddshape_y.SetSize(p + 1);
8362  ddshape_l.SetSize(p + 1);
8363  u.SetSize(dof);
8364  du.SetSize(dof, dim);
8365  ddu.SetSize(dof, (dim * (dim + 1)) / 2 );
8366 #else
8367  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8368 #endif
8369 
8370  // vertices
8371  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
8372  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
8373  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
8374 
8375  // edges
8376  int o = 3;
8377  for (int i = 1; i < p; i++)
8378  {
8379  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
8380  }
8381  for (int i = 1; i < p; i++)
8382  {
8383  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
8384  }
8385  for (int i = 1; i < p; i++)
8386  {
8387  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
8388  }
8389 
8390  // interior
8391  for (int j = 1; j < p; j++)
8392  for (int i = 1; i + j < p; i++)
8393  {
8394  const double w = cp[i] + cp[j] + cp[p-i-j];
8395  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
8396  }
8397 
8398  DenseMatrix T(dof);
8399  for (int k = 0; k < dof; k++)
8400  {
8401  IntegrationPoint &ip = Nodes.IntPoint(k);
8402  poly1d.CalcBasis(p, ip.x, shape_x);
8403  poly1d.CalcBasis(p, ip.y, shape_y);
8404  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8405 
8406  o = 0;
8407  for (int j = 0; j <= p; j++)
8408  for (int i = 0; i + j <= p; i++)
8409  {
8410  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8411  }
8412  }
8413 
8414  Ti.Factor(T);
8415  // mfem::out << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
8416 }
8417 
8419  Vector &shape) const
8420 {
8421  const int p = order;
8422 
8423 #ifdef MFEM_THREAD_SAFE
8424  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(dof);
8425 #endif
8426 
8427  poly1d.CalcBasis(p, ip.x, shape_x);
8428  poly1d.CalcBasis(p, ip.y, shape_y);
8429  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8430 
8431  for (int o = 0, j = 0; j <= p; j++)
8432  for (int i = 0; i + j <= p; i++)
8433  {
8434  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
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_l(p + 1);
8447  Vector dshape_x(p + 1), dshape_y(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, 1. - ip.x - ip.y, shape_l, dshape_l);
8454 
8455  for (int o = 0, j = 0; j <= p; j++)
8456  for (int i = 0; i + j <= p; i++)
8457  {
8458  int k = p - i - j;
8459  du(o,0) = ((dshape_x(i)* shape_l(k)) -
8460  ( shape_x(i)*dshape_l(k)))*shape_y(j);
8461  du(o,1) = ((dshape_y(j)* shape_l(k)) -
8462  ( shape_y(j)*dshape_l(k)))*shape_x(i);
8463  o++;
8464  }
8465 
8466  Ti.Mult(du, dshape);
8467 }
8468 
8470  DenseMatrix &ddshape) const
8471 {
8472  const int p = order;
8473 #ifdef MFEM_THREAD_SAFE
8474  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8475  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8476  Vector ddshape_x(p + 1), ddshape_y(p + 1), ddshape_l(p + 1);
8477  DenseMatrix ddu(dof, dim);
8478 #endif
8479 
8480  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x, ddshape_x);
8481  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y, ddshape_y);
8482  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l, ddshape_l);
8483 
8484  for (int o = 0, j = 0; j <= p; j++)
8485  for (int i = 0; i + j <= p; i++)
8486  {
8487  int k = p - i - j;
8488  // u_xx, u_xy, u_yy
8489  ddu(o,0) = ((ddshape_x(i) * shape_l(k)) - 2. * (dshape_x(i) * dshape_l(k)) +
8490  (shape_x(i) * ddshape_l(k))) * shape_y(j);
8491  ddu(o,1) = (((shape_x(i) * ddshape_l(k)) - dshape_x(i) * dshape_l(k)) * shape_y(
8492  j)) + (((dshape_x(i) * shape_l(k)) - (shape_x(i) * dshape_l(k))) * dshape_y(j));
8493  ddu(o,2) = ((ddshape_y(j) * shape_l(k)) - 2. * (dshape_y(j) * dshape_l(k)) +
8494  (shape_y(j) * ddshape_l(k))) * shape_x(i);
8495  o++;
8496  }
8497 
8498  Ti.Mult(ddu, ddshape);
8499 }
8500 
8501 
8503  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
8504  p, FunctionSpace::Pk)
8505 {
8506  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
8507 
8508 #ifndef MFEM_THREAD_SAFE
8509  shape_x.SetSize(p + 1);
8510  shape_y.SetSize(p + 1);
8511  shape_z.SetSize(p + 1);
8512  shape_l.SetSize(p + 1);
8513  dshape_x.SetSize(p + 1);
8514  dshape_y.SetSize(p + 1);
8515  dshape_z.SetSize(p + 1);
8516  dshape_l.SetSize(p + 1);
8517  ddshape_x.SetSize(p + 1);
8518  ddshape_y.SetSize(p + 1);
8519  ddshape_z.SetSize(p + 1);
8520  ddshape_l.SetSize(p + 1);
8521  u.SetSize(dof);
8522  du.SetSize(dof, dim);
8523  ddu.SetSize(dof, (dim * (dim + 1)) / 2);
8524 #else
8525  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8526 #endif
8527 
8528  // vertices
8529  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
8530  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
8531  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
8532  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
8533 
8534  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
8535  int o = 4;
8536  for (int i = 1; i < p; i++) // (0,1)
8537  {
8538  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
8539  }
8540  for (int i = 1; i < p; i++) // (0,2)
8541  {
8542  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
8543  }
8544  for (int i = 1; i < p; i++) // (0,3)
8545  {
8546  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
8547  }
8548  for (int i = 1; i < p; i++) // (1,2)
8549  {
8550  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
8551  }
8552  for (int i = 1; i < p; i++) // (1,3)
8553  {
8554  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
8555  }
8556  for (int i = 1; i < p; i++) // (2,3)
8557  {
8558  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
8559  }
8560 
8561  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
8562  for (int j = 1; j < p; j++)
8563  for (int i = 1; i + j < p; i++) // (1,2,3)
8564  {
8565  double w = cp[i] + cp[j] + cp[p-i-j];
8566  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
8567  }
8568  for (int j = 1; j < p; j++)
8569  for (int i = 1; i + j < p; i++) // (0,3,2)
8570  {
8571  double w = cp[i] + cp[j] + cp[p-i-j];
8572  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
8573  }
8574  for (int j = 1; j < p; j++)
8575  for (int i = 1; i + j < p; i++) // (0,1,3)
8576  {
8577  double w = cp[i] + cp[j] + cp[p-i-j];
8578  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
8579  }
8580  for (int j = 1; j < p; j++)
8581  for (int i = 1; i + j < p; i++) // (0,2,1)
8582  {
8583  double w = cp[i] + cp[j] + cp[p-i-j];
8584  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
8585  }
8586 
8587  // interior
8588  for (int k = 1; k < p; k++)
8589  for (int j = 1; j + k < p; j++)
8590  for (int i = 1; i + j + k < p; i++)
8591  {
8592  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
8593  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
8594  }
8595 
8596  DenseMatrix T(dof);
8597  for (int m = 0; m < dof; m++)
8598  {
8599  IntegrationPoint &ip = Nodes.IntPoint(m);
8600  poly1d.CalcBasis(p, ip.x, shape_x);
8601  poly1d.CalcBasis(p, ip.y, shape_y);
8602  poly1d.CalcBasis(p, ip.z, shape_z);
8603  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8604 
8605  o = 0;
8606  for (int k = 0; k <= p; k++)
8607  for (int j = 0; j + k <= p; j++)
8608  for (int i = 0; i + j + k <= p; i++)
8609  {
8610  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8611  }
8612  }
8613 
8614  Ti.Factor(T);
8615  // mfem::out << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8616 }
8617 
8619  Vector &shape) const
8620 {
8621  const int p = order;
8622 
8623 #ifdef MFEM_THREAD_SAFE
8624  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8625  Vector u(dof);
8626 #endif
8627 
8628  poly1d.CalcBasis(p, ip.x, shape_x);
8629  poly1d.CalcBasis(p, ip.y, shape_y);
8630  poly1d.CalcBasis(p, ip.z, shape_z);
8631  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8632 
8633  for (int o = 0, k = 0; k <= p; k++)
8634  for (int j = 0; j + k <= p; j++)
8635  for (int i = 0; i + j + k <= p; i++)
8636  {
8637  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8638  }
8639 
8640  Ti.Mult(u, shape);
8641 }
8642 
8644  DenseMatrix &dshape) const
8645 {
8646  const int p = order;
8647 
8648 #ifdef MFEM_THREAD_SAFE
8649  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8650  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8651  DenseMatrix du(dof, dim);
8652 #endif
8653 
8654  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8655  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8656  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
8657  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
8658 
8659  for (int o = 0, k = 0; k <= p; k++)
8660  for (int j = 0; j + k <= p; j++)
8661  for (int i = 0; i + j + k <= p; i++)
8662  {
8663  int l = p - i - j - k;
8664  du(o,0) = ((dshape_x(i)* shape_l(l)) -
8665  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
8666  du(o,1) = ((dshape_y(j)* shape_l(l)) -
8667  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
8668  du(o,2) = ((dshape_z(k)* shape_l(l)) -
8669  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
8670  o++;
8671  }
8672 
8673  Ti.Mult(du, dshape);
8674 }
8675 
8677  DenseMatrix &ddshape) const
8678 {
8679  const int p = order;
8680 
8681 #ifdef MFEM_THREAD_SAFE
8682  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8683  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8684  Vector ddshape_x(p + 1), ddshape_y(p + 1), ddshape_z(p + 1), ddshape_l(p + 1);
8685  DenseMatrix ddu(dof, ((dim + 1) * dim) / 2);
8686 #endif
8687 
8688  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x, ddshape_x);
8689  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y, ddshape_y);
8690  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z, ddshape_z);
8691  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l, ddshape_l);
8692 
8693  for (int o = 0, k = 0; k <= p; k++)
8694  for (int j = 0; j + k <= p; j++)
8695  for (int i = 0; i + j + k <= p; i++)
8696  {
8697  // u_xx, u_xy, u_xz, u_yy, u_yz, u_zz
8698  int l = p - i - j - k;
8699  ddu(o,0) = ((ddshape_x(i) * shape_l(l)) - 2. * (dshape_x(i) * dshape_l(l)) +
8700  (shape_x(i) * ddshape_l(l))) * shape_y(j) * shape_z(k);
8701  ddu(o,1) = ((dshape_y(j) * ((dshape_x(i) * shape_l(l)) -
8702  (shape_x(i) * dshape_l(l)))) +
8703  (shape_y(j) * ((ddshape_l(l) * shape_x(i)) -
8704  (dshape_x(i) * dshape_l(l)))))* shape_z(k);
8705  ddu(o,2) = ((dshape_z(k) * ((dshape_x(i) * shape_l(l)) -
8706  (shape_x(i) * dshape_l(l)))) +
8707  (shape_z(k) * ((ddshape_l(l) * shape_x(i)) -
8708  (dshape_x(i) * dshape_l(l)))))* shape_y(j);
8709  ddu(o,3) = ((ddshape_y(j) * shape_l(l)) - 2. * (dshape_y(j) * dshape_l(l)) +
8710  (shape_y(j) * ddshape_l(l))) * shape_x(i) * shape_z(k);
8711  ddu(o,4) = ((dshape_z(k) * ((dshape_y(j) * shape_l(l)) -
8712  (shape_y(j)*dshape_l(l))) ) +
8713  (shape_z(k)* ((ddshape_l(l)*shape_y(j)) -
8714  (dshape_y(j) * dshape_l(l)) ) ) )* shape_x(i);
8715  ddu(o,5) = ((ddshape_z(k) * shape_l(l)) - 2. * (dshape_z(k) * dshape_l(l)) +
8716  (shape_z(k) * ddshape_l(l))) * shape_y(j) * shape_x(i);
8717  o++;
8718  }
8719  Ti.Mult(ddu, ddshape);
8720 }
8721 
8723  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8724  FunctionSpace::Pk)
8725 {
8726 #ifndef MFEM_THREAD_SAFE
8727  m_shape.SetSize(dof);
8728  dshape_1d.SetSize(p + 1);
8729  m_dshape.SetSize(dof, dim);
8730 #endif
8731  dof_map.SetSize(dof);
8732 
8733  struct Index
8734  {
8735  int p2p3;
8736  Index(int p) { p2p3 = 2*p + 3; }
8737  int operator()(int i, int j) { return ((p2p3-j)*j)/2+i; }
8738  };
8739  Index idx(p);
8740 
8741  // vertices
8742  dof_map[idx(0,0)] = 0;
8743  Nodes.IntPoint(0).Set2(0., 0.);
8744  dof_map[idx(p,0)] = 1;
8745  Nodes.IntPoint(1).Set2(1., 0.);
8746  dof_map[idx(0,p)] = 2;
8747  Nodes.IntPoint(2).Set2(0., 1.);
8748 
8749  // edges
8750  int o = 3;
8751  for (int i = 1; i < p; i++)
8752  {
8753  dof_map[idx(i,0)] = o;
8754  Nodes.IntPoint(o++).Set2(double(i)/p, 0.);
8755  }
8756  for (int i = 1; i < p; i++)
8757  {
8758  dof_map[idx(p-i,i)] = o;
8759  Nodes.IntPoint(o++).Set2(double(p-i)/p, double(i)/p);
8760  }
8761  for (int i = 1; i < p; i++)
8762  {
8763  dof_map[idx(0,p-i)] = o;
8764  Nodes.IntPoint(o++).Set2(0., double(p-i)/p);
8765  }
8766 
8767  // interior
8768  for (int j = 1; j < p; j++)
8769  for (int i = 1; i + j < p; i++)
8770  {
8771  dof_map[idx(i,j)] = o;
8772  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8773  }
8774 }
8775 
8776 // static method
8778  const int p, const double l1, const double l2, double *shape)
8779 {
8780  const double l3 = 1. - l1 - l2;
8781 
8782  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
8783  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
8784  // Another expression is given by the terms of the expansion:
8785  // (l1 + l2 + l3)^p =
8786  // \sum_{j=0}^p \binom{p}{j} l2^j
8787  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
8788  const int *bp = Poly_1D::Binom(p);
8789  double z = 1.;
8790  for (int o = 0, j = 0; j <= p; j++)
8791  {
8792  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape[o]);
8793  double s = bp[j]*z;
8794  for (int i = 0; i <= p - j; i++)
8795  {
8796  shape[o++] *= s;
8797  }
8798  z *= l2;
8799  }
8800 }
8801 
8802 // static method
8804  const int p, const double l1, const double l2,
8805  double *dshape_1d, double *dshape)
8806 {
8807  const int dof = ((p + 1)*(p + 2))/2;
8808  const double l3 = 1. - l1 - l2;
8809 
8810  const int *bp = Poly_1D::Binom(p);
8811  double z = 1.;
8812  for (int o = 0, j = 0; j <= p; j++)
8813  {
8814  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
8815  double s = bp[j]*z;
8816  for (int i = 0; i <= p - j; i++)
8817  {
8818  dshape[o++] = s*dshape_1d[i];
8819  }
8820  z *= l2;
8821  }
8822  z = 1.;
8823  for (int i = 0; i <= p; i++)
8824  {
8825  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
8826  double s = bp[i]*z;
8827  for (int o = i, j = 0; j <= p - i; j++)
8828  {
8829  dshape[dof + o] = s*dshape_1d[j];
8830  o += p + 1 - j;
8831  }
8832  z *= l1;
8833  }
8834 }
8835 
8837  Vector &shape) const
8838 {
8839 #ifdef MFEM_THREAD_SAFE
8840  Vector m_shape(dof);
8841 #endif
8842  CalcShape(order, ip.x, ip.y, m_shape.GetData());
8843  for (int i = 0; i < dof; i++)
8844  {
8845  shape(dof_map[i]) = m_shape(i);
8846  }
8847 }
8848 
8850  DenseMatrix &dshape) const
8851 {
8852 #ifdef MFEM_THREAD_SAFE
8853  Vector dshape_1d(order + 1);
8855 #endif
8856  CalcDShape(order, ip.x, ip.y, dshape_1d.GetData(), m_dshape.Data());
8857  for (int d = 0; d < 2; d++)
8858  {
8859  for (int i = 0; i < dof; i++)
8860  {
8861  dshape(dof_map[i],d) = m_dshape(i,d);
8862  }
8863  }
8864 }
8865 
8866 
8868  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
8869  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
8870 {
8871 #ifndef MFEM_THREAD_SAFE
8872  m_shape.SetSize(dof);
8873  dshape_1d.SetSize(p + 1);
8874  m_dshape.SetSize(dof, dim);
8875 #endif
8876  dof_map.SetSize(dof);
8877 
8878  struct Index
8879  {
8880  int p, dof;
8881  int tri(int k) { return (k*(k + 1))/2; }
8882  int tet(int k) { return (k*(k + 1)*(k + 2))/6; }
8883  Index(int p_) { p = p_; dof = tet(p + 1); }
8884  int operator()(int i, int j, int k)
8885  { return dof - tet(p - k) - tri(p + 1 - k - j) + i; }
8886  };
8887  Index idx(p);
8888 
8889  // vertices
8890  dof_map[idx(0,0,0)] = 0;
8891  Nodes.IntPoint(0).Set3(0., 0., 0.);
8892  dof_map[idx(p,0,0)] = 1;
8893  Nodes.IntPoint(1).Set3(1., 0., 0.);
8894  dof_map[idx(0,p,0)] = 2;
8895  Nodes.IntPoint(2).Set3(0., 1., 0.);
8896  dof_map[idx(0,0,p)] = 3;
8897  Nodes.IntPoint(3).Set3(0., 0., 1.);
8898 
8899  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
8900  int o = 4;
8901  for (int i = 1; i < p; i++) // (0,1)
8902  {
8903  dof_map[idx(i,0,0)] = o;
8904  Nodes.IntPoint(o++).Set3(double(i)/p, 0., 0.);
8905  }
8906  for (int i = 1; i < p; i++) // (0,2)
8907  {
8908  dof_map[idx(0,i,0)] = o;
8909  Nodes.IntPoint(o++).Set3(0., double(i)/p, 0.);
8910  }
8911  for (int i = 1; i < p; i++) // (0,3)
8912  {
8913  dof_map[idx(0,0,i)] = o;
8914  Nodes.IntPoint(o++).Set3(0., 0., double(i)/p);
8915  }
8916  for (int i = 1; i < p; i++) // (1,2)
8917  {
8918  dof_map[idx(p-i,i,0)] = o;
8919  Nodes.IntPoint(o++).Set3(double(p-i)/p, double(i)/p, 0.);
8920  }
8921  for (int i = 1; i < p; i++) // (1,3)
8922  {
8923  dof_map[idx(p-i,0,i)] = o;
8924  Nodes.IntPoint(o++).Set3(double(p-i)/p, 0., double(i)/p);
8925  }
8926  for (int i = 1; i < p; i++) // (2,3)
8927  {
8928  dof_map[idx(0,p-i,i)] = o;
8929  Nodes.IntPoint(o++).Set3(0., double(p-i)/p, double(i)/p);
8930  }
8931 
8932  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
8933  for (int j = 1; j < p; j++)
8934  for (int i = 1; i + j < p; i++) // (1,2,3)
8935  {
8936  dof_map[idx(p-i-j,i,j)] = o;
8937  Nodes.IntPoint(o++).Set3(double(p-i-j)/p, double(i)/p, double(j)/p);
8938  }
8939  for (int j = 1; j < p; j++)
8940  for (int i = 1; i + j < p; i++) // (0,3,2)
8941  {
8942  dof_map[idx(0,j,i)] = o;
8943  Nodes.IntPoint(o++).Set3(0., double(j)/p, double(i)/p);
8944  }
8945  for (int j = 1; j < p; j++)
8946  for (int i = 1; i + j < p; i++) // (0,1,3)
8947  {
8948  dof_map[idx(i,0,j)] = o;
8949  Nodes.IntPoint(o++).Set3(double(i)/p, 0., double(j)/p);
8950  }
8951  for (int j = 1; j < p; j++)
8952  for (int i = 1; i + j < p; i++) // (0,2,1)
8953  {
8954  dof_map[idx(j,i,0)] = o;
8955  Nodes.IntPoint(o++).Set3(double(j)/p, double(i)/p, 0.);
8956  }
8957 
8958  // interior
8959  for (int k = 1; k < p; k++)
8960  for (int j = 1; j + k < p; j++)
8961  for (int i = 1; i + j + k < p; i++)
8962  {
8963  dof_map[idx(i,j,k)] = o;
8964  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8965  }
8966 }
8967 
8968 // static method
8970  const int p, const double l1, const double l2, const double l3,
8971  double *shape)
8972 {
8973  const double l4 = 1. - l1 - l2 - l3;
8974 
8975  // The basis functions are the terms in the expansion:
8976  // (l1 + l2 + l3 + l4)^p =
8977  // \sum_{k=0}^p \binom{p}{k} l3^k
8978  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8979  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8980  const int *bp = Poly_1D::Binom(p);
8981  double l3k = 1.;
8982  for (int o = 0, k = 0; k <= p; k++)
8983  {
8984  const int *bpk = Poly_1D::Binom(p - k);
8985  const double ek = bp[k]*l3k;
8986  double l2j = 1.;
8987  for (int j = 0; j <= p - k; j++)
8988  {
8989  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape[o]);
8990  double ekj = ek*bpk[j]*l2j;
8991  for (int i = 0; i <= p - k - j; i++)
8992  {
8993  shape[o++] *= ekj;
8994  }
8995  l2j *= l2;
8996  }
8997  l3k *= l3;
8998  }
8999 }
9000 
9001 // static method
9003  const int p, const double l1, const double l2, const double l3,
9004  double *dshape_1d, double *dshape)
9005 {
9006  const int dof = ((p + 1)*(p + 2)*(p + 3))/6;
9007  const double l4 = 1. - l1 - l2 - l3;
9008 
9009  // For the x derivatives, differentiate the terms of the expression:
9010  // \sum_{k=0}^p \binom{p}{k} l3^k
9011  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
9012  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
9013  const int *bp = Poly_1D::Binom(p);
9014  double l3k = 1.;
9015  for (int o = 0, k = 0; k <= p; k++)
9016  {
9017  const int *bpk = Poly_1D::Binom(p - k);
9018  const double ek = bp[k]*l3k;
9019  double l2j = 1.;
9020  for (int j = 0; j <= p - k; j++)
9021  {
9022  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
9023  double ekj = ek*bpk[j]*l2j;
9024  for (int i = 0; i <= p - k - j; i++)
9025  {
9026  dshape[o++] = dshape_1d[i]*ekj;
9027  }
9028  l2j *= l2;
9029  }
9030  l3k *= l3;
9031  }
9032  // For the y derivatives, differentiate the terms of the expression:
9033  // \sum_{k=0}^p \binom{p}{k} l3^k
9034  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
9035  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
9036  l3k = 1.;
9037  for (int ok = 0, k = 0; k <= p; k++)
9038  {
9039  const int *bpk = Poly_1D::Binom(p - k);
9040  const double ek = bp[k]*l3k;
9041  double l1i = 1.;
9042  for (int i = 0; i <= p - k; i++)
9043  {
9044  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
9045  double eki = ek*bpk[i]*l1i;
9046  int o = ok + i;
9047  for (int j = 0; j <= p - k - i; j++)
9048  {
9049  dshape[dof + o] = dshape_1d[j]*eki;
9050  o += p - k - j + 1;
9051  }
9052  l1i *= l1;
9053  }
9054  l3k *= l3;
9055  ok += ((p - k + 2)*(p - k + 1))/2;
9056  }
9057  // For the z derivatives, differentiate the terms of the expression:
9058  // \sum_{j=0}^p \binom{p}{j} l2^j
9059  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
9060  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
9061  double l2j = 1.;
9062  for (int j = 0; j <= p; j++)
9063  {
9064  const int *bpj = Poly_1D::Binom(p - j);
9065  const double ej = bp[j]*l2j;
9066  double l1i = 1.;
9067  for (int i = 0; i <= p - j; i++)
9068  {
9069  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
9070  double eji = ej*bpj[i]*l1i;
9071  int m = ((p + 2)*(p + 1))/2;
9072  int n = ((p - j + 2)*(p - j + 1))/2;
9073  for (int o = i, k = 0; k <= p - j - i; k++)
9074  {
9075  // m = ((p - k + 2)*(p - k + 1))/2;
9076  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
9077  o += m;
9078  dshape[2*dof + o - n] = dshape_1d[k]*eji;
9079  m -= p - k + 1;
9080  n -= p - k - j + 1;
9081  }
9082  l1i *= l1;
9083  }
9084  l2j *= l2;
9085  }
9086 }
9087 
9089  Vector &shape) const
9090 {
9091 #ifdef MFEM_THREAD_SAFE
9092  Vector m_shape(dof);
9093 #endif
9094  CalcShape(order, ip.x, ip.y, ip.z, m_shape.GetData());
9095  for (int i = 0; i < dof; i++)
9096  {
9097  shape(dof_map[i]) = m_shape(i);
9098  }
9099 }
9100 
9102  DenseMatrix &dshape) const
9103 {
9104 #ifdef MFEM_THREAD_SAFE
9105  Vector dshape_1d(order + 1);
9107 #endif
9108  CalcDShape(order, ip.x, ip.y, ip.z, dshape_1d.GetData(), m_dshape.Data());
9109  for (int d = 0; d < 3; d++)
9110  {
9111  for (int i = 0; i < dof; i++)
9112  {
9113  dshape(dof_map[i],d) = m_dshape(i,d);
9114  }
9115  }
9116 }
9117 
9118 
9120  const int btype)
9121  : NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
9122  p, FunctionSpace::Qk),
9123  TriangleFE(p, btype),
9124  SegmentFE(p, btype)
9125 {
9126 #ifndef MFEM_THREAD_SAFE
9127  t_shape.SetSize(TriangleFE.GetDof());
9128  s_shape.SetSize(SegmentFE.GetDof());
9129  t_dshape.SetSize(TriangleFE.GetDof(), 2);
9130  s_dshape.SetSize(SegmentFE.GetDof(), 1);
9131 #endif
9132 
9133  t_dof.SetSize(dof);
9134  s_dof.SetSize(dof);
9135 
9136  // Nodal DoFs
9137  t_dof[0] = 0; s_dof[0] = 0;
9138  t_dof[1] = 1; s_dof[1] = 0;
9139  t_dof[2] = 2; s_dof[2] = 0;
9140  t_dof[3] = 0; s_dof[3] = 1;
9141  t_dof[4] = 1; s_dof[4] = 1;
9142  t_dof[5] = 2; s_dof[5] = 1;
9143 
9144  // Edge DoFs
9145  int ne = p-1;
9146  for (int i=1; i<p; i++)
9147  {
9148  t_dof[5 + 0 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 0 * ne + i] = 0;
9149  t_dof[5 + 1 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 1 * ne + i] = 0;
9150  t_dof[5 + 2 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 2 * ne + i] = 0;
9151  t_dof[5 + 3 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 3 * ne + i] = 1;
9152  t_dof[5 + 4 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 4 * ne + i] = 1;
9153  t_dof[5 + 5 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 5 * ne + i] = 1;
9154  t_dof[5 + 6 * ne + i] = 0; s_dof[5 + 6 * ne + i] = i + 1;
9155  t_dof[5 + 7 * ne + i] = 1; s_dof[5 + 7 * ne + i] = i + 1;
9156  t_dof[5 + 8 * ne + i] = 2; s_dof[5 + 8 * ne + i] = i + 1;
9157  }
9158 
9159  // Triangular Face DoFs
9160  int k=0;
9161  int nt = (p-1)*(p-2)/2;
9162  for (int j=1; j<p; j++)
9163  {
9164  for (int i=1; i<p-j; i++)
9165  {
9166  int l = j - p + (((2 * p - 1) - i) * i) / 2;
9167  t_dof[6 + 9 * ne + k] = 3 * p + l; s_dof[6 + 9 * ne + k] = 0;
9168  t_dof[6 + 9 * ne + nt + k] = 3 * p + k; s_dof[6 + 9 * ne + nt + k] = 1;
9169  k++;
9170  }
9171  }
9172 
9173  // Quadrilateral Face DoFs
9174  k=0;
9175  int nq = (p-1)*(p-1);
9176  for (int j=1; j<p; j++)
9177  {
9178  for (int i=1; i<p; i++)
9179  {
9180  t_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 2 + 0 * ne + i;
9181  t_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 2 + 1 * ne + i;
9182  t_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 2 + 2 * ne + i;
9183 
9184  s_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 1 + j;
9185  s_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 1 + j;
9186  s_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 1 + j;
9187 
9188  k++;
9189  }
9190  }
9191 
9192  // Interior DoFs
9193  int m=0;
9194  for (int k=1; k<p; k++)
9195  {
9196  int l=0;
9197  for (int j=1; j<p; j++)
9198  {
9199  for (int i=1; i<j; i++)
9200  {
9201  t_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 3 * p + l;
9202  s_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 1 + k;
9203  l++; m++;
9204  }
9205  }
9206  }
9207 
9208  // Define Nodes
9209  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
9210  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
9211  for (int i=0; i<dof; i++)
9212  {
9213  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
9214  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
9215  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
9216  }
9217 }
9218 
9220  Vector &shape) const
9221 {
9222 #ifdef MFEM_THREAD_SAFE
9223  Vector t_shape(TriangleFE.GetDof());
9224  Vector s_shape(SegmentFE.GetDof());
9225 #endif
9226 
9227  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9228 
9229  TriangleFE.CalcShape(ip, t_shape);
9230  SegmentFE.CalcShape(ipz, s_shape);
9231 
9232  for (int i=0; i<dof; i++)
9233  {
9234  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
9235  }
9236 }
9237 
9239  DenseMatrix &dshape) const
9240 {
9241 #ifdef MFEM_THREAD_SAFE
9242  Vector t_shape(TriangleFE.GetDof());
9243  DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
9244  Vector s_shape(SegmentFE.GetDof());
9245  DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
9246 #endif
9247 
9248  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9249 
9250  TriangleFE.CalcShape(ip, t_shape);
9251  TriangleFE.CalcDShape(ip, t_dshape);
9252  SegmentFE.CalcShape(ipz, s_shape);
9253  SegmentFE.CalcDShape(ipz, s_dshape);
9254 
9255  for (int i=0; i<dof; i++)
9256  {
9257  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
9258  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
9259  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
9260  }
9261 }
9262 
9263 
9265  : PositiveFiniteElement(3, Geometry::PRISM,
9266  ((p + 1)*(p + 1)*(p + 2))/2, p, FunctionSpace::Qk),
9267  TriangleFE(p),
9268  SegmentFE(p)
9269 {
9270 #ifndef MFEM_THREAD_SAFE
9275 #endif
9276 
9277  t_dof.SetSize(dof);
9278  s_dof.SetSize(dof);
9279 
9280  // Nodal DoFs
9281  t_dof[0] = 0; s_dof[0] = 0;
9282  t_dof[1] = 1; s_dof[1] = 0;
9283  t_dof[2] = 2; s_dof[2] = 0;
9284  t_dof[3] = 0; s_dof[3] = 1;
9285  t_dof[4] = 1; s_dof[4] = 1;
9286  t_dof[5] = 2; s_dof[5] = 1;
9287 
9288  // Edge DoFs
9289  int ne = p-1;
9290  for (int i=1; i<p; i++)
9291  {
9292  t_dof[5 + 0 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 0 * ne + i] = 0;
9293  t_dof[5 + 1 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 1 * ne + i] = 0;
9294  t_dof[5 + 2 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 2 * ne + i] = 0;
9295  t_dof[5 + 3 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 3 * ne + i] = 1;
9296  t_dof[5 + 4 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 4 * ne + i] = 1;
9297  t_dof[5 + 5 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 5 * ne + i] = 1;
9298  t_dof[5 + 6 * ne + i] = 0; s_dof[5 + 6 * ne + i] = i + 1;
9299  t_dof[5 + 7 * ne + i] = 1; s_dof[5 + 7 * ne + i] = i + 1;
9300  t_dof[5 + 8 * ne + i] = 2; s_dof[5 + 8 * ne + i] = i + 1;
9301  }
9302 
9303  // Triangular Face DoFs
9304  int k=0;
9305  int nt = (p-1)*(p-2)/2;
9306  for (int j=1; j<p; j++)
9307  {
9308  for (int i=1; i<j; i++)
9309  {
9310  t_dof[6 + 9 * ne + k] = 3 * p + k; s_dof[6 + 9 * ne + k] = 0;
9311  t_dof[6 + 9 * ne + nt + k] = 3 * p + k; s_dof[6 + 9 * ne + nt + k] = 1;
9312  k++;
9313  }
9314  }
9315 
9316  // Quadrilateral Face DoFs
9317  k=0;
9318  int nq = (p-1)*(p-1);
9319  for (int j=1; j<p; j++)
9320  {
9321  for (int i=1; i<p; i++)
9322  {
9323  t_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 2 + 0 * ne + i;
9324  t_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 2 + 1 * ne + i;
9325  t_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 2 + 2 * ne + i;
9326 
9327  s_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 1 + j;
9328  s_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 1 + j;
9329  s_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 1 + j;
9330 
9331  k++;
9332  }
9333  }
9334 
9335  // Interior DoFs
9336  int m=0;
9337  for (int k=1; k<p; k++)
9338  {
9339  int l=0;
9340  for (int j=1; j<p; j++)
9341  {
9342  for (int i=1; i<j; i++)
9343  {
9344  t_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 3 * p + l;
9345  s_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 1 + k;
9346  l++; m++;
9347  }
9348  }
9349  }
9350 
9351  // Define Nodes
9352  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
9353  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
9354  for (int i=0; i<dof; i++)
9355  {
9356  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
9357  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
9358  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
9359  }
9360 }
9361 
9363  Vector &shape) const
9364 {
9365 #ifdef MFEM_THREAD_SAFE
9368 #endif
9369 
9370  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9371 
9373  SegmentFE.CalcShape(ipz, s_shape);
9374 
9375  for (int i=0; i<dof; i++)
9376  {
9377  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
9378  }
9379 }
9380 
9382  DenseMatrix &dshape) const
9383 {
9384 #ifdef MFEM_THREAD_SAFE
9389 #endif
9390 
9391  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9392 
9395  SegmentFE.CalcShape(ipz, s_shape);
9397 
9398  for (int i=0; i<dof; i++)
9399  {
9400  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
9401  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
9402  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
9403  }
9404 }
9405 
9406 
9407 L2_SegmentElement::L2_SegmentElement(const int p, const int btype)
9408  : NodalTensorFiniteElement(1, p, VerifyOpen(btype), L2_DOF_MAP)
9409 {
9410  const double *op = poly1d.OpenPoints(p, btype);
9411 
9412 #ifndef MFEM_THREAD_SAFE
9413  shape_x.SetSize(p + 1);
9414  dshape_x.SetDataAndSize(NULL, p + 1);
9415 #endif
9416 
9417  for (int i = 0; i <= p; i++)
9418  {
9419  Nodes.IntPoint(i).x = op[i];
9420  }
9421 }
9422 
9424  Vector &shape) const
9425 {
9426  basis1d.Eval(ip.x, shape);
9427 }
9428 
9430  DenseMatrix &dshape) const
9431 {
9432 #ifdef MFEM_THREAD_SAFE
9433  Vector shape_x(dof), dshape_x(dshape.Data(), dof);
9434 #else
9435  dshape_x.SetData(dshape.Data());
9436 #endif
9437  basis1d.Eval(ip.x, shape_x, dshape_x);
9438 }
9439 
9440 void L2_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
9441 {
9442  const int p = order;
9443  const double *op = poly1d.OpenPoints(p, b_type);
9444 
9445  switch (vertex)
9446  {
9447  case 0:
9448  for (int i = 0; i <= p; i++)
9449  {
9450  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9451  }
9452  break;
9453 
9454  case 1:
9455  for (int i = 0; i <= p; i++)
9456  {
9457  dofs(i) = poly1d.CalcDelta(p,op[i]);
9458  }
9459  break;
9460  }
9461 }
9462 
9463 
9465  : PositiveTensorFiniteElement(1, p, L2_DOF_MAP)
9466 {
9467 #ifndef MFEM_THREAD_SAFE
9468  shape_x.SetSize(p + 1);
9469  dshape_x.SetDataAndSize(NULL, p + 1);
9470 #endif
9471 
9472  if (p == 0)
9473  {
9474  Nodes.IntPoint(0).x = 0.5;
9475  }
9476  else
9477  {
9478  for (int i = 0; i <= p; i++)
9479  {
9480  Nodes.IntPoint(i).x = double(i)/p;
9481  }
9482  }
9483 }
9484 
9486  Vector &shape) const
9487 {
9488  Poly_1D::CalcBernstein(order, ip.x, shape);
9489 }
9490 
9492  DenseMatrix &dshape) const
9493 {
9494 #ifdef MFEM_THREAD_SAFE
9495  Vector shape_x(dof), dshape_x(dshape.Data(), dof);
9496 #else
9497  dshape_x.SetData(dshape.Data());
9498 #endif
9499  Poly_1D::CalcBernstein(order, ip.x, shape_x, dshape_x);
9500 }
9501 
9502 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
9503 {
9504  dofs = 0.0;
9505  dofs[vertex*order] = 1.0;
9506 }
9507 
9508 
9510  : NodalTensorFiniteElement(2, p, VerifyOpen(btype), L2_DOF_MAP)
9511 {
9512  const double *op = poly1d.OpenPoints(p, b_type);
9513 
9514 #ifndef MFEM_THREAD_SAFE
9515  shape_x.SetSize(p + 1);
9516  shape_y.SetSize(p + 1);
9517  dshape_x.SetSize(p + 1);
9518  dshape_y.SetSize(p + 1);
9519 #endif
9520 
9521  for (int o = 0, j = 0; j <= p; j++)
9522  for (int i = 0; i <= p; i++)
9523  {
9524  Nodes.IntPoint(o++).Set2(op[i], op[j]);
9525  }
9526 }
9527 
9529  Vector &shape) const
9530 {
9531  const int p = order;
9532 
9533 #ifdef MFEM_THREAD_SAFE
9534  Vector shape_x(p+1), shape_y(p+1);
9535 #endif
9536 
9537  basis1d.Eval(ip.x, shape_x);
9538  basis1d.Eval(ip.y, shape_y);
9539 
9540  for (int o = 0, j = 0; j <= p; j++)
9541  for (int i = 0; i <= p; i++)
9542  {
9543  shape(o++) = shape_x(i)*shape_y(j);
9544  }
9545 }
9546 
9548  DenseMatrix &dshape) const
9549 {
9550  const int p = order;
9551 
9552 #ifdef MFEM_THREAD_SAFE
9553  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
9554 #endif
9555 
9556  basis1d.Eval(ip.x, shape_x, dshape_x);
9557  basis1d.Eval(ip.y, shape_y, dshape_y);
9558 
9559  for (int o = 0, j = 0; j <= p; j++)
9560  for (int i = 0; i <= p; i++)
9561  {
9562  dshape(o,0) = dshape_x(i)* shape_y(j);
9563  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
9564  }
9565 }
9566 
9567 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
9568 {
9569  const int p = order;
9570  const double *op = poly1d.OpenPoints(p, b_type);
9571 
9572 #ifdef MFEM_THREAD_SAFE
9573  Vector shape_x(p+1), shape_y(p+1);
9574 #endif
9575 
9576  for (int i = 0; i <= p; i++)
9577  {
9578  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9579  shape_y(i) = poly1d.CalcDelta(p,op[i]);
9580  }
9581 
9582  switch (vertex)
9583  {
9584  case 0:
9585  for (int o = 0, j = 0; j <= p; j++)
9586  for (int i = 0; i <= p; i++)
9587  {
9588  dofs[o++] = shape_x(i)*shape_x(j);
9589  }
9590  break;
9591  case 1:
9592  for (int o = 0, j = 0; j <= p; j++)
9593  for (int i = 0; i <= p; i++)
9594  {
9595  dofs[o++] = shape_y(i)*shape_x(j);
9596  }
9597  break;
9598  case 2:
9599  for (int o = 0, j = 0; j <= p; j++)
9600  for (int i = 0; i <= p; i++)
9601  {
9602  dofs[o++] = shape_y(i)*shape_y(j);
9603  }
9604  break;
9605  case 3:
9606  for (int o = 0, j = 0; j <= p; j++)
9607  for (int i = 0; i <= p; i++)
9608  {
9609  dofs[o++] = shape_x(i)*shape_y(j);
9610  }
9611  break;
9612  }
9613 }
9614 
9615 
9617  : PositiveTensorFiniteElement(2, p, L2_DOF_MAP)
9618 {
9619 #ifndef MFEM_THREAD_SAFE
9620  shape_x.SetSize(p + 1);
9621  shape_y.SetSize(p + 1);
9622  dshape_x.SetSize(p + 1);
9623  dshape_y.SetSize(p + 1);
9624 #endif
9625 
9626  if (p == 0)
9627  {
9628  Nodes.IntPoint(0).Set2(0.5, 0.5);
9629  }
9630  else
9631  {
9632  for (int o = 0, j = 0; j <= p; j++)
9633  for (int i = 0; i <= p; i++)
9634  {
9635  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
9636  }
9637  }
9638 }
9639 
9641  Vector &shape) const
9642 {
9643  const int p = order;
9644 
9645 #ifdef MFEM_THREAD_SAFE
9646  Vector shape_x(p+1), shape_y(p+1);
9647 #endif
9648 
9649  Poly_1D::CalcBernstein(p, ip.x, shape_x);
9650  Poly_1D::CalcBernstein(p, ip.y, shape_y);
9651 
9652  for (int o = 0, j = 0; j <= p; j++)
9653  for (int i = 0; i <= p; i++)
9654  {
9655  shape(o++) = shape_x(i)*shape_y(j);
9656  }
9657 }
9658 
9660  DenseMatrix &dshape) const
9661 {
9662  const int p = order;
9663 
9664 #ifdef MFEM_THREAD_SAFE
9665  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
9666 #endif
9667 
9668  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
9669  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
9670 
9671  for (int o = 0, j = 0; j <= p; j++)
9672  for (int i = 0; i <= p; i++)
9673  {
9674  dshape(o,0) = dshape_x(i)* shape_y(j);
9675  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
9676  }
9677 }
9678 
9680 {
9681  const int p = order;
9682 
9683  dofs = 0.0;
9684  switch (vertex)
9685  {
9686  case 0: dofs[0] = 1.0; break;
9687  case 1: dofs[p] = 1.0; break;
9688  case 2: dofs[p*(p + 2)] = 1.0; break;
9689  case 3: dofs[p*(p + 1)] = 1.0; break;
9690  }
9691 }
9692 
9693 
9694 L2_HexahedronElement::L2_HexahedronElement(const int p, const int btype)
9695  : NodalTensorFiniteElement(3, p, VerifyOpen(btype), L2_DOF_MAP)
9696 {
9697  const double *op = poly1d.OpenPoints(p, btype);
9698 
9699 #ifndef MFEM_THREAD_SAFE
9700  shape_x.SetSize(p + 1);
9701  shape_y.SetSize(p + 1);
9702  shape_z.SetSize(p + 1);
9703  dshape_x.SetSize(p + 1);
9704  dshape_y.SetSize(p + 1);
9705  dshape_z.SetSize(p + 1);
9706 #endif
9707 
9708  for (int o = 0, k = 0; k <= p; k++)
9709  for (int j = 0; j <= p; j++)
9710  for (int i = 0; i <= p; i++)
9711  {
9712  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
9713  }
9714 }
9715 
9717  Vector &shape) const
9718 {
9719  const int p = order;
9720 
9721 #ifdef MFEM_THREAD_SAFE
9722  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9723 #endif
9724 
9725  basis1d.Eval(ip.x, shape_x);
9726  basis1d.Eval(ip.y, shape_y);
9727  basis1d.Eval(ip.z, shape_z);
9728 
9729  for (int o = 0, k = 0; k <= p; k++)
9730  for (int j = 0; j <= p; j++)
9731  for (int i = 0; i <= p; i++)
9732  {
9733  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
9734  }
9735 }
9736 
9738  DenseMatrix &dshape) const
9739 {
9740  const int p = order;
9741 
9742 #ifdef MFEM_THREAD_SAFE
9743  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9744  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
9745 #endif
9746 
9747  basis1d.Eval(ip.x, shape_x, dshape_x);
9748  basis1d.Eval(ip.y, shape_y, dshape_y);
9749  basis1d.Eval(ip.z, shape_z, dshape_z);
9750 
9751  for (int o = 0, k = 0; k <= p; k++)
9752  for (int j = 0; j <= p; j++)
9753  for (int i = 0; i <= p; i++)
9754  {
9755  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
9756  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
9757  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
9758  }
9759 }
9760 
9761 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9762 {
9763  const int p = order;
9764  const double *op = poly1d.OpenPoints(p, b_type);
9765 
9766 #ifdef MFEM_THREAD_SAFE
9767  Vector shape_x(p+1), shape_y(p+1);
9768 #endif
9769 
9770  for (int i = 0; i <= p; i++)
9771  {
9772  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9773  shape_y(i) = poly1d.CalcDelta(p,op[i]);
9774  }
9775 
9776  switch (vertex)
9777  {
9778  case 0:
9779  for (int o = 0, k = 0; k <= p; k++)
9780  for (int j = 0; j <= p; j++)
9781  for (int i = 0; i <= p; i++)
9782  {
9783  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
9784  }
9785  break;
9786  case 1:
9787  for (int o = 0, k = 0; k <= p; k++)
9788  for (int j = 0; j <= p; j++)
9789  for (int i = 0; i <= p; i++)
9790  {
9791  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
9792  }
9793  break;
9794  case 2:
9795  for (int o = 0, k = 0; k <= p; k++)
9796  for (int j = 0; j <= p; j++)
9797  for (int i = 0; i <= p; i++)
9798  {
9799  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
9800  }
9801  break;
9802  case 3:
9803  for (int o = 0, k = 0; k <= p; k++)
9804  for (int j = 0; j <= p; j++)
9805  for (int i = 0; i <= p; i++)
9806  {
9807  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
9808  }
9809  break;
9810  case 4:
9811  for (int o = 0, k = 0; k <= p; k++)
9812  for (int j = 0; j <= p; j++)
9813  for (int i = 0; i <= p; i++)
9814  {
9815  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
9816  }
9817  break;
9818  case 5:
9819  for (int o = 0, k = 0; k <= p; k++)
9820  for (int j = 0; j <= p; j++)
9821  for (int i = 0; i <= p; i++)
9822  {
9823  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
9824  }
9825  break;
9826  case 6:
9827  for (int o = 0, k = 0; k <= p; k++)
9828  for (int j = 0; j <= p; j++)
9829  for (int i = 0; i <= p; i++)
9830  {
9831  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
9832  }
9833  break;
9834  case 7:
9835  for (int o = 0, k = 0; k <= p; k++)
9836  for (int j = 0; j <= p; j++)
9837  for (int i = 0; i <= p; i++)
9838  {
9839  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
9840  }
9841  break;
9842  }
9843 }
9844 
9845 
9847  : PositiveTensorFiniteElement(3, p, L2_DOF_MAP)
9848 {
9849 #ifndef MFEM_THREAD_SAFE
9850  shape_x.SetSize(p + 1);
9851  shape_y.SetSize(p + 1);
9852  shape_z.SetSize(p + 1);
9853  dshape_x.SetSize(p + 1);
9854  dshape_y.SetSize(p + 1);
9855  dshape_z.SetSize(p + 1);
9856 #endif
9857 
9858  if (p == 0)
9859  {
9860  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
9861  }
9862  else
9863  {
9864  for (int o = 0, k = 0; k <= p; k++)
9865  for (int j = 0; j <= p; j++)
9866  for (int i = 0; i <= p; i++)
9867  {
9868  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
9869  }
9870  }
9871 }
9872 
9874  Vector &shape) const
9875 {
9876  const int p = order;
9877 
9878 #ifdef MFEM_THREAD_SAFE
9879  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9880 #endif
9881 
9882  Poly_1D::CalcBernstein(p, ip.x, shape_x);
9883  Poly_1D::CalcBernstein(p, ip.y, shape_y);
9884  Poly_1D::CalcBernstein(p, ip.z, shape_z);
9885 
9886  for (int o = 0, k = 0; k <= p; k++)
9887  for (int j = 0; j <= p; j++)
9888  for (int i = 0; i <= p; i++)
9889  {
9890  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
9891  }
9892 }
9893 
9895  DenseMatrix &dshape) const
9896 {
9897  const int p = order;
9898 
9899 #ifdef MFEM_THREAD_SAFE
9900  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9901  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
9902 #endif
9903 
9904  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
9905  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
9906  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
9907 
9908  for (int o = 0, k = 0; k <= p; k++)
9909  for (int j = 0; j <= p; j++)
9910  for (int i = 0; i <= p; i++)
9911  {
9912  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
9913  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
9914  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
9915  }
9916 }
9917 
9918 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9919 {
9920  const int p = order;
9921 
9922  dofs = 0.0;
9923  switch (vertex)
9924  {
9925  case 0: dofs[0] = 1.0; break;
9926  case 1: dofs[p] = 1.0; break;
9927  case 2: dofs[p*(p + 2)] = 1.0; break;
9928  case 3: dofs[p*(p + 1)] = 1.0; break;
9929  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
9930  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
9931  case 6: dofs[dof - 1] = 1.0; break;
9932  case 7: dofs[dof - p - 1] = 1.0; break;
9933  }
9934 }
9935 
9936 
9937 L2_TriangleElement::L2_TriangleElement(const int p, const int btype)
9938  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
9939  FunctionSpace::Pk)
9940 {
9941  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
9942 
9943 #ifndef MFEM_THREAD_SAFE
9944  shape_x.SetSize(p + 1);
9945  shape_y.SetSize(p + 1);
9946  shape_l.SetSize(p + 1);
9947  dshape_x.SetSize(p + 1);
9948  dshape_y.SetSize(p + 1);
9949  dshape_l.SetSize(p + 1);
9950  u.SetSize(dof);
9951  du.SetSize(dof, dim);
9952 #else
9953  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9954 #endif
9955 
9956  for (int o = 0, j = 0; j <= p; j++)
9957  for (int i = 0; i + j <= p; i++)
9958  {
9959  double w = op[i] + op[j] + op[p-i-j];
9960  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
9961  }
9962 
9963  DenseMatrix T(dof);
9964  for (int k = 0; k < dof; k++)
9965  {
9966  IntegrationPoint &ip = Nodes.IntPoint(k);
9967  poly1d.CalcBasis(p, ip.x, shape_x);
9968  poly1d.CalcBasis(p, ip.y, shape_y);
9969  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9970 
9971  for (int o = 0, j = 0; j <= p; j++)
9972  for (int i = 0; i + j <= p; i++)
9973  {
9974  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9975  }
9976  }
9977 
9978  Ti.Factor(T);
9979  // mfem::out << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
9980 }
9981 
9983  Vector &shape) const
9984 {
9985  const int p = order;
9986 
9987 #ifdef MFEM_THREAD_SAFE
9988  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(dof);
9989 #endif
9990 
9991  poly1d.CalcBasis(p, ip.x, shape_x);
9992  poly1d.CalcBasis(p, ip.y, shape_y);
9993  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9994 
9995  for (int o = 0, j = 0; j <= p; j++)
9996  for (int i = 0; i + j <= p; i++)
9997  {
9998  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9999  }
10000 
10001  Ti.Mult(u, shape);
10002 }
10003 
10005  DenseMatrix &dshape) const
10006 {
10007  const int p = order;
10008 
10009 #ifdef MFEM_THREAD_SAFE
10010  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10011  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
10012  DenseMatrix du(dof, dim);
10013 #endif
10014 
10015  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
10016  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
10017  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
10018 
10019  for (int o = 0, j = 0; j <= p; j++)
10020  for (int i = 0; i + j <= p; i++)
10021  {
10022  int k = p - i - j;
10023  du(o,0) = ((dshape_x(i)* shape_l(k)) -
10024  ( shape_x(i)*dshape_l(k)))*shape_y(j);
10025  du(o,1) = ((dshape_y(j)* shape_l(k)) -
10026  ( shape_y(j)*dshape_l(k)))*shape_x(i);
10027  o++;
10028  }
10029 
10030  Ti.Mult(du, dshape);
10031 }
10032 
10033 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
10034 {
10035  switch (vertex)
10036  {
10037  case 0:
10038  for (int i = 0; i < dof; i++)
10039  {
10040  const IntegrationPoint &ip = Nodes.IntPoint(i);
10041  dofs[i] = pow(1.0 - ip.x - ip.y, order);
10042  }
10043  break;
10044  case 1:
10045  for (int i = 0; i < dof; i++)
10046  {
10047  const IntegrationPoint &ip = Nodes.IntPoint(i);
10048  dofs[i] = pow(ip.x, order);
10049  }
10050  break;
10051  case 2:
10052  for (int i = 0; i < dof; i++)
10053  {
10054  const IntegrationPoint &ip = Nodes.IntPoint(i);
10055  dofs[i] = pow(ip.y, order);
10056  }
10057  break;
10058  }
10059 }
10060 
10061 
10063  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
10064  FunctionSpace::Pk)
10065 {
10066 #ifndef MFEM_THREAD_SAFE
10067  dshape_1d.SetSize(p + 1);
10068 #endif
10069 
10070  if (p == 0)
10071  {
10072  Nodes.IntPoint(0).Set2(1./3, 1./3);
10073  }
10074  else
10075  {
10076  for (int o = 0, j = 0; j <= p; j++)
10077  for (int i = 0; i + j <= p; i++)
10078  {
10079  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
10080  }
10081  }
10082 }
10083 
10085  Vector &shape) const
10086 {
10087  H1Pos_TriangleElement::CalcShape(order, ip.x, ip.y, shape.GetData());
10088 }
10089 
10091  DenseMatrix &dshape) const
10092 {
10093 #ifdef MFEM_THREAD_SAFE
10094  Vector dshape_1d(order + 1);
10095 #endif
10096 
10097  H1Pos_TriangleElement::CalcDShape(order, ip.x, ip.y, dshape_1d.GetData(),
10098  dshape.Data());
10099 }
10100 
10101 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
10102 {
10103  dofs = 0.0;
10104  switch (vertex)
10105  {
10106  case 0: dofs[0] = 1.0; break;
10107  case 1: dofs[order] = 1.0; break;
10108  case 2: dofs[dof-1] = 1.0; break;
10109  }
10110 }
10111 
10112 
10114  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
10115  p, FunctionSpace::Pk)
10116 {
10117  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
10118 
10119 #ifndef MFEM_THREAD_SAFE
10120  shape_x.SetSize(p + 1);
10121  shape_y.SetSize(p + 1);
10122  shape_z.SetSize(p + 1);
10123  shape_l.SetSize(p + 1);
10124  dshape_x.SetSize(p + 1);
10125  dshape_y.SetSize(p + 1);
10126  dshape_z.SetSize(p + 1);
10127  dshape_l.SetSize(p + 1);
10128  u.SetSize(dof);
10129  du.SetSize(dof, dim);
10130 #else
10131  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10132 #endif
10133 
10134  for (int o = 0, k = 0; k <= p; k++)
10135  for (int j = 0; j + k <= p; j++)
10136  for (int i = 0; i + j + k <= p; i++)
10137  {
10138  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
10139  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
10140  }
10141 
10142  DenseMatrix T(dof);
10143  for (int m = 0; m < dof; m++)
10144  {
10145  IntegrationPoint &ip = Nodes.IntPoint(m);
10146  poly1d.CalcBasis(p, ip.x, shape_x);
10147  poly1d.CalcBasis(p, ip.y, shape_y);
10148  poly1d.CalcBasis(p, ip.z, shape_z);
10149  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
10150 
10151  for (int o = 0, k = 0; k <= p; k++)
10152  for (int j = 0; j + k <= p; j++)
10153  for (int i = 0; i + j + k <= p; i++)
10154  {
10155  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
10156  }
10157  }
10158 
10159  Ti.Factor(T);
10160  // mfem::out << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
10161 }
10162 
10164  Vector &shape) const
10165 {
10166  const int p = order;
10167 
10168 #ifdef MFEM_THREAD_SAFE
10169  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10170  Vector u(dof);
10171 #endif
10172 
10173  poly1d.CalcBasis(p, ip.x, shape_x);
10174  poly1d.CalcBasis(p, ip.y, shape_y);
10175  poly1d.CalcBasis(p, ip.z, shape_z);
10176  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
10177 
10178  for (int o = 0, k = 0; k <= p; k++)
10179  for (int j = 0; j + k <= p; j++)
10180  for (int i = 0; i + j + k <= p; i++)
10181  {
10182  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
10183  }
10184 
10185  Ti.Mult(u, shape);
10186 }
10187 
10189  DenseMatrix &dshape) const
10190 {
10191  const int p = order;
10192 
10193 #ifdef MFEM_THREAD_SAFE
10194  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10195  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
10196  DenseMatrix du(dof, dim);
10197 #endif
10198 
10199  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
10200  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
10201  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
10202  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10203 
10204  for (int o = 0, k = 0; k <= p; k++)
10205  for (int j = 0; j + k <= p; j++)
10206  for (int i = 0; i + j + k <= p; i++)
10207  {
10208  int l = p - i - j - k;
10209  du(o,0) = ((dshape_x(i)* shape_l(l)) -
10210  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
10211  du(o,1) = ((dshape_y(j)* shape_l(l)) -
10212  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
10213  du(o,2) = ((dshape_z(k)* shape_l(l)) -
10214  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
10215  o++;
10216  }
10217 
10218  Ti.Mult(du, dshape);
10219 }
10220 
10221 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
10222 {
10223  switch (vertex)
10224  {
10225  case 0:
10226  for (int i = 0; i < dof; i++)
10227  {
10228  const IntegrationPoint &ip = Nodes.IntPoint(i);
10229  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, order);
10230  }
10231  break;
10232  case 1:
10233  for (int i = 0; i < dof; i++)
10234  {
10235  const IntegrationPoint &ip = Nodes.IntPoint(i);
10236  dofs[i] = pow(ip.x, order);
10237  }
10238  break;
10239  case 2:
10240  for (int i = 0; i < dof; i++)
10241  {
10242  const IntegrationPoint &ip = Nodes.IntPoint(i);
10243  dofs[i] = pow(ip.y, order);
10244  }
10245  break;
10246  case 3:
10247  for (int i = 0; i < dof; i++)
10248  {
10249  const IntegrationPoint &ip = Nodes.IntPoint(i);
10250  dofs[i] = pow(ip.z, order);
10251  }
10252  break;
10253  }
10254 }
10255 
10256 
10258  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
10259  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
10260 {
10261 #ifndef MFEM_THREAD_SAFE
10262  dshape_1d.SetSize(p + 1);
10263 #endif
10264 
10265  if (p == 0)
10266  {
10267  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
10268  }
10269  else
10270  {
10271  for (int o = 0, k = 0; k <= p; k++)
10272  for (int j = 0; j + k <= p; j++)
10273  for (int i = 0; i + j + k <= p; i++)
10274  {
10275  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
10276  }
10277  }
10278 }
10279 
10281  Vector &shape) const
10282 {
10284  shape.GetData());
10285 }
10286 
10288  DenseMatrix &dshape) const
10289 {
10290 #ifdef MFEM_THREAD_SAFE
10291  Vector dshape_1d(order + 1);
10292 #endif
10293 
10295  dshape_1d.GetData(), dshape.Data());
10296 }
10297 
10298 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
10299 {
10300  dofs = 0.0;
10301  switch (vertex)
10302  {
10303  case 0: dofs[0] = 1.0; break;
10304  case 1: dofs[order] = 1.0; break;
10305  case 2: dofs[(order*(order+3))/2] = 1.0; break;
10306  case 3: dofs[dof-1] = 1.0; break;
10307  }
10308 }
10309 
10310 
10311 L2_WedgeElement::L2_WedgeElement(const int p, const int btype)
10312  : NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
10313  p, FunctionSpace::Qk),
10314  TriangleFE(p, btype),
10315  SegmentFE(p, btype)
10316 {
10317 #ifndef MFEM_THREAD_SAFE
10318  t_shape.SetSize(TriangleFE.GetDof());
10319  s_shape.SetSize(SegmentFE.GetDof());
10320  t_dshape.SetSize(TriangleFE.GetDof(), 2);
10321  s_dshape.SetSize(SegmentFE.GetDof(), 1);
10322 #endif
10323 
10324  t_dof.SetSize(dof);
10325  s_dof.SetSize(dof);
10326 
10327  // Interior DoFs
10328  int m=0;
10329  for (int k=0; k<=p; k++)
10330  {
10331  int l=0;
10332  for (int j=0; j<=p; j++)
10333  {
10334  for (int i=0; i<=j; i++)
10335  {
10336  t_dof[m] = l;
10337  s_dof[m] = k;
10338  l++; m++;
10339  }
10340  }
10341  }
10342 
10343  // Define Nodes
10344  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
10345  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
10346  for (int i=0; i<dof; i++)
10347  {
10348  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
10349  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
10350  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
10351  }
10352 }
10353 
10355  Vector &shape) const
10356 {
10357 #ifdef MFEM_THREAD_SAFE
10358  Vector t_shape(TriangleFE.GetDof());
10359  Vector s_shape(SegmentFE.GetDof());
10360 #endif
10361 
10362  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10363 
10364  TriangleFE.CalcShape(ip, t_shape);
10365  SegmentFE.CalcShape(ipz, s_shape);
10366 
10367  for (int i=0; i<dof; i++)
10368  {
10369  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
10370  }
10371 }
10372 
10374  DenseMatrix &dshape) const
10375 {
10376 #ifdef MFEM_THREAD_SAFE
10377  Vector t_shape(TriangleFE.GetDof());
10378  DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
10379  Vector s_shape(SegmentFE.GetDof());
10380  DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
10381 #endif
10382 
10383  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10384 
10385  TriangleFE.CalcShape(ip, t_shape);
10386  TriangleFE.CalcDShape(ip, t_dshape);
10387  SegmentFE.CalcShape(ipz, s_shape);
10388  SegmentFE.CalcDShape(ipz, s_dshape);
10389 
10390  for (int i=0; i<dof; i++)
10391  {
10392  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
10393  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
10394  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
10395  }
10396 }
10397 
10398 
10400  : PositiveFiniteElement(3, Geometry::PRISM,
10401  ((p + 1)*(p + 1)*(p + 2))/2, p, FunctionSpace::Qk),
10402  TriangleFE(p),
10403  SegmentFE(p)
10404 {
10405 #ifndef MFEM_THREAD_SAFE
10410 #endif
10411 
10412  t_dof.SetSize(dof);
10413  s_dof.SetSize(dof);
10414 
10415  // Interior DoFs
10416  int m=0;
10417  for (int k=0; k<=p; k++)
10418  {
10419  int l=0;
10420  for (int j=0; j<=p; j++)
10421  {
10422  for (int i=0; i<=j; i++)
10423  {
10424  t_dof[m] = l;
10425  s_dof[m] = k;
10426  l++; m++;
10427  }
10428  }
10429  }
10430 
10431  // Define Nodes
10432  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
10433  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
10434  for (int i=0; i<dof; i++)
10435  {
10436  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
10437  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
10438  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
10439  }
10440 }
10441 
10443  Vector &shape) const
10444 {
10445 #ifdef MFEM_THREAD_SAFE
10448 #endif
10449 
10450  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10451 
10453  SegmentFE.CalcShape(ipz, s_shape);
10454 
10455  for (int i=0; i<dof; i++)
10456  {
10457  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
10458  }
10459 }
10460 
10462  DenseMatrix &dshape) const
10463 {
10464 #ifdef MFEM_THREAD_SAFE
10469 #endif
10470 
10471  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10472 
10475  SegmentFE.CalcShape(ipz, s_shape);
10477 
10478  for (int i=0; i<dof; i++)
10479  {
10480  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
10481  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
10482  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
10483  }
10484 }
10485 
10486 
10487 const double RT_QuadrilateralElement::nk[8] =
10488 { 0., -1., 1., 0., 0., 1., -1., 0. };
10489 
10491  const int cb_type,
10492  const int ob_type)
10493  : VectorTensorFiniteElement(2, 2*(p + 1)*(p + 2), p + 1, cb_type, ob_type,
10494  H_DIV, DofMapType::L2_DOF_MAP),
10495  dof2nk(dof)
10496 {
10497  dof_map.SetSize(dof);
10498 
10499  const double *cp = poly1d.ClosedPoints(p + 1, cb_type);
10500  const double *op = poly1d.OpenPoints(p, ob_type);
10501  const int dof2 = dof/2;
10502 
10503 #ifndef MFEM_THREAD_SAFE
10504  shape_cx.SetSize(p + 2);
10505  shape_ox.SetSize(p + 1);
10506  shape_cy.SetSize(p + 2);
10507  shape_oy.SetSize(p + 1);
10508  dshape_cx.SetSize(p + 2);
10509  dshape_cy.SetSize(p + 2);
10510 #endif
10511 
10512  // edges
10513  int o = 0;
10514  for (int i = 0; i <= p; i++) // (0,1)
10515  {
10516  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
10517  }
10518  for (int i = 0; i <= p; i++) // (1,2)
10519  {
10520  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
10521  }
10522  for (int i = 0; i <= p; i++) // (2,3)
10523  {
10524  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
10525  }
10526  for (int i = 0; i <= p; i++) // (3,0)
10527  {
10528  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
10529  }
10530 
10531  // interior
10532  for (int j = 0; j <= p; j++) // x-components
10533  for (int i = 1; i <= p; i++)
10534  {
10535  dof_map[0*dof2 + i + j*(p + 2)] = o++;
10536  }
10537  for (int j = 1; j <= p; j++) // y-components
10538  for (int i = 0; i <= p; i++)
10539  {
10540  dof_map[1*dof2 + i + j*(p + 1)] = o++;
10541  }
10542 
10543  // dof orientations
10544  // x-components
10545  for (int j = 0; j <= p; j++)
10546  for (int i = 0; i <= p/2; i++)
10547  {
10548  int idx = 0*dof2 + i + j*(p + 2);
10549  dof_map[idx] = -1 - dof_map[idx];
10550  }
10551  if (p%2 == 1)
10552  for (int j = p/2 + 1; j <= p; j++)
10553  {
10554  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
10555  dof_map[idx] = -1 - dof_map[idx];
10556  }
10557  // y-components
10558  for (int j = 0; j <= p/2; j++)
10559  for (int i = 0; i <= p; i++)
10560  {
10561  int idx = 1*dof2 + i + j*(p + 1);
10562  dof_map[idx] = -1 - dof_map[idx];
10563  }
10564  if (p%2 == 1)
10565  for (int i = 0; i <= p/2; i++)
10566  {
10567  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
10568  dof_map[idx] = -1 - dof_map[idx];
10569  }
10570 
10571  o = 0;
10572  for (int j = 0; j <= p; j++)
10573  for (int i = 0; i <= p + 1; i++)
10574  {
10575  int idx;
10576  if ((idx = dof_map[o++]) < 0)
10577  {
10578  idx = -1 - idx;
10579  dof2nk[idx] = 3;
10580  }
10581  else
10582  {
10583  dof2nk[idx] = 1;
10584  }
10585  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
10586  }
10587  for (int j = 0; j <= p + 1; j++)
10588  for (int i = 0; i <= p; i++)
10589  {
10590  int idx;
10591  if ((idx = dof_map[o++]) < 0)
10592  {
10593  idx = -1 - idx;
10594  dof2nk[idx] = 0;
10595  }
10596  else
10597  {
10598  dof2nk[idx] = 2;
10599  }
10600  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
10601  }
10602 }
10603 
10605  DenseMatrix &shape) const
10606 {
10607  const int pp1 = order;
10608 
10609 #ifdef MFEM_THREAD_SAFE
10610  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10611 #endif
10612 
10613  cbasis1d.Eval(ip.x, shape_cx);
10614  obasis1d.Eval(ip.x, shape_ox);
10615  cbasis1d.Eval(ip.y, shape_cy);
10616  obasis1d.Eval(ip.y, shape_oy);
10617 
10618  int o = 0;
10619  for (int j = 0; j < pp1; j++)
10620  for (int i = 0; i <= pp1; i++)
10621  {
10622  int idx, s;
10623  if ((idx = dof_map[o++]) < 0)
10624  {
10625  idx = -1 - idx, s = -1;
10626  }
10627  else
10628  {
10629  s = +1;
10630  }
10631  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
10632  shape(idx,1) = 0.;
10633  }
10634  for (int j = 0; j <= pp1; j++)
10635  for (int i = 0; i < pp1; i++)
10636  {
10637  int idx, s;
10638  if ((idx = dof_map[o++]) < 0)
10639  {
10640  idx = -1 - idx, s = -1;
10641  }
10642  else
10643  {
10644  s = +1;
10645  }
10646  shape(idx,0) = 0.;
10647  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
10648  }
10649 }
10650 
10652  Vector &divshape) const
10653 {
10654  const int pp1 = order;
10655 
10656 #ifdef MFEM_THREAD_SAFE
10657  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10658  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
10659 #endif
10660 
10661  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10662  obasis1d.Eval(ip.x, shape_ox);
10663  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10664  obasis1d.Eval(ip.y, shape_oy);
10665 
10666  int o = 0;
10667  for (int j = 0; j < pp1; j++)
10668  for (int i = 0; i <= pp1; i++)
10669  {
10670  int idx, s;
10671  if ((idx = dof_map[o++]) < 0)
10672  {
10673  idx = -1 - idx, s = -1;
10674  }
10675  else
10676  {
10677  s = +1;
10678  }
10679  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
10680  }
10681  for (int j = 0; j <= pp1; j++)
10682  for (int i = 0; i < pp1; i++)
10683  {
10684  int idx, s;
10685  if ((idx = dof_map[o++]) < 0)
10686  {
10687  idx = -1 - idx, s = -1;
10688  }
10689  else
10690  {
10691  s = +1;
10692  }
10693  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
10694  }
10695 }
10696 
10697 
10698 const double RT_HexahedronElement::nk[18] =
10699 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
10700 
10702  const int cb_type,
10703  const int ob_type)
10704  : VectorTensorFiniteElement(3, 3*(p + 1)*(p + 1)*(p + 2), p + 1, cb_type,
10705  ob_type, H_DIV, DofMapType::L2_DOF_MAP),
10706  dof2nk(dof)
10707 {
10708  dof_map.SetSize(dof);
10709 
10710  const double *cp = poly1d.ClosedPoints(p + 1, cb_type);
10711  const double *op = poly1d.OpenPoints(p, ob_type);
10712  const int dof3 = dof/3;
10713 
10714 #ifndef MFEM_THREAD_SAFE
10715  shape_cx.SetSize(p + 2);
10716  shape_ox.SetSize(p + 1);
10717  shape_cy.SetSize(p + 2);
10718  shape_oy.SetSize(p + 1);
10719  shape_cz.SetSize(p + 2);
10720  shape_oz.SetSize(p + 1);
10721  dshape_cx.SetSize(p + 2);
10722  dshape_cy.SetSize(p + 2);
10723  dshape_cz.SetSize(p + 2);
10724 #endif
10725 
10726  // faces
10727  int o = 0;
10728  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
10729  for (int i = 0; i <= p; i++)
10730  {
10731  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
10732  }
10733  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
10734  for (int i = 0; i <= p; i++)
10735  {
10736  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
10737  }
10738  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
10739  for (int i = 0; i <= p; i++)
10740  {
10741  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
10742  }
10743  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
10744  for (int i = 0; i <= p; i++)
10745  {
10746  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
10747  }
10748  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
10749  for (int i = 0; i <= p; i++)
10750  {
10751  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
10752  }
10753  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
10754  for (int i = 0; i <= p; i++)
10755  {
10756  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
10757  }
10758 
10759  // interior
10760  // x-components
10761  for (int k = 0; k <= p; k++)
10762  for (int j = 0; j <= p; j++)
10763  for (int i = 1; i <= p; i++)
10764  {
10765  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
10766  }
10767  // y-components
10768  for (int k = 0; k <= p; k++)
10769  for (int j = 1; j <= p; j++)
10770  for (int i = 0; i <= p; i++)
10771  {
10772  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
10773  }
10774  // z-components
10775  for (int k = 1; k <= p; k++)
10776  for (int j = 0; j <= p; j++)
10777  for (int i = 0; i <= p; i++)
10778  {
10779  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
10780  }
10781 
10782  // dof orientations
10783  // for odd p, do not change the orientations in the mid-planes
10784  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
10785  // respectively.
10786  // x-components
10787  for (int k = 0; k <= p; k++)
10788  for (int j = 0; j <= p; j++)
10789  for (int i = 0; i <= p/2; i++)
10790  {
10791  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
10792  dof_map[idx] = -1 - dof_map[idx];
10793  }
10794  // y-components
10795  for (int k = 0; k <= p; k++)
10796  for (int j = 0; j <= p/2; j++)
10797  for (int i = 0; i <= p; i++)
10798  {
10799  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
10800  dof_map[idx] = -1 - dof_map[idx];
10801  }
10802  // z-components
10803  for (int k = 0; k <= p/2; k++)
10804  for (int j = 0; j <= p; j++)
10805  for (int i = 0; i <= p; i++)
10806  {
10807  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
10808  dof_map[idx] = -1 - dof_map[idx];
10809  }
10810 
10811  o = 0;
10812  // x-components
10813  for (int k = 0; k <= p; k++)
10814  for (int j = 0; j <= p; j++)
10815  for (int i = 0; i <= p + 1; i++)
10816  {
10817  int idx;
10818  if ((idx = dof_map[o++]) < 0)
10819  {
10820  idx = -1 - idx;
10821  dof2nk[idx] = 4;
10822  }
10823  else
10824  {
10825  dof2nk[idx] = 2;
10826  }
10827  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
10828  }
10829  // y-components
10830  for (int k = 0; k <= p; k++)
10831  for (int j = 0; j <= p + 1; j++)
10832  for (int i = 0; i <= p; i++)
10833  {
10834  int idx;
10835  if ((idx = dof_map[o++]) < 0)
10836  {
10837  idx = -1 - idx;
10838  dof2nk[idx] = 1;
10839  }
10840  else
10841  {
10842  dof2nk[idx] = 3;
10843  }
10844  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
10845  }
10846  // z-components
10847  for (int k = 0; k <= p + 1; k++)
10848  for (int j = 0; j <= p; j++)
10849  for (int i = 0; i <= p; i++)
10850  {
10851  int idx;
10852  if ((idx = dof_map[o++]) < 0)
10853  {
10854  idx = -1 - idx;
10855  dof2nk[idx] = 0;
10856  }
10857  else
10858  {
10859  dof2nk[idx] = 5;
10860  }
10861  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
10862  }
10863 }
10864 
10866  DenseMatrix &shape) const
10867 {
10868  const int pp1 = order;
10869 
10870 #ifdef MFEM_THREAD_SAFE
10871  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10872  Vector shape_cz(pp1 + 1), shape_oz(pp1);
10873 #endif
10874 
10875  cbasis1d.Eval(ip.x, shape_cx);
10876  obasis1d.Eval(ip.x, shape_ox);
10877  cbasis1d.Eval(ip.y, shape_cy);
10878  obasis1d.Eval(ip.y, shape_oy);
10879  cbasis1d.Eval(ip.z, shape_cz);
10880  obasis1d.Eval(ip.z, shape_oz);
10881 
10882  int o = 0;
10883  // x-components
10884  for (int k = 0; k < pp1; k++)
10885  for (int j = 0; j < pp1; j++)
10886  for (int i = 0; i <= pp1; i++)
10887  {
10888  int idx, s;
10889  if ((idx = dof_map[o++]) < 0)
10890  {
10891  idx = -1 - idx, s = -1;
10892  }
10893  else
10894  {
10895  s = +1;
10896  }
10897  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
10898  shape(idx,1) = 0.;
10899  shape(idx,2) = 0.;
10900  }
10901  // y-components
10902  for (int k = 0; k < pp1; k++)
10903  for (int j = 0; j <= pp1; j++)
10904  for (int i = 0; i < pp1; i++)
10905  {
10906  int idx, s;
10907  if ((idx = dof_map[o++]) < 0)
10908  {
10909  idx = -1 - idx, s = -1;
10910  }
10911  else
10912  {
10913  s = +1;
10914  }
10915  shape(idx,0) = 0.;
10916  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
10917  shape(idx,2) = 0.;
10918  }
10919  // z-components
10920  for (int k = 0; k <= pp1; k++)
10921  for (int j = 0; j < pp1; j++)
10922  for (int i = 0; i < pp1; i++)
10923  {
10924  int idx, s;
10925  if ((idx = dof_map[o++]) < 0)
10926  {
10927  idx = -1 - idx, s = -1;
10928  }
10929  else
10930  {
10931  s = +1;
10932  }
10933  shape(idx,0) = 0.;
10934  shape(idx,1) = 0.;
10935  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
10936  }
10937 }
10938 
10940  Vector &divshape) const
10941 {
10942  const int pp1 = order;
10943 
10944 #ifdef MFEM_THREAD_SAFE
10945  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10946  Vector shape_cz(pp1 + 1), shape_oz(pp1);
10947  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
10948 #endif
10949 
10950  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10951  obasis1d.Eval(ip.x, shape_ox);
10952  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10953  obasis1d.Eval(ip.y, shape_oy);
10954  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
10955  obasis1d.Eval(ip.z, shape_oz);
10956 
10957  int o = 0;
10958  // x-components
10959  for (int k = 0; k < pp1; k++)
10960  for (int j = 0; j < pp1; j++)
10961  for (int i = 0; i <= pp1; i++)
10962  {
10963  int idx, s;
10964  if ((idx = dof_map[o++]) < 0)
10965  {
10966  idx = -1 - idx, s = -1;
10967  }
10968  else
10969  {
10970  s = +1;
10971  }
10972  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
10973  }
10974  // y-components
10975  for (int k = 0; k < pp1; k++)
10976  for (int j = 0; j <= pp1; j++)
10977  for (int i = 0; i < pp1; i++)
10978  {
10979  int idx, s;
10980  if ((idx = dof_map[o++]) < 0)
10981  {
10982  idx = -1 - idx, s = -1;
10983  }
10984  else
10985  {
10986  s = +1;
10987  }
10988  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
10989  }
10990  // z-components
10991  for (int k = 0; k <= pp1; k++)
10992  for (int j = 0; j < pp1; j++)
10993  for (int i = 0; i < pp1; i++)
10994  {
10995  int idx, s;
10996  if ((idx = dof_map[o++]) < 0)
10997  {
10998  idx = -1 - idx, s = -1;
10999  }
11000  else
11001  {
11002  s = +1;
11003  }
11004  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
11005  }
11006 }
11007 
11008 
11009 const double RT_TriangleElement::nk[6] =
11010 { 0., -1., 1., 1., -1., 0. };
11011 
11012 const double RT_TriangleElement::c = 1./3.;
11013 
11015  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
11016  H_DIV, FunctionSpace::Pk),
11017  dof2nk(dof)
11018 {
11019  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
11020  const double *bop = poly1d.OpenPoints(p);
11021 
11022 #ifndef MFEM_THREAD_SAFE
11023  shape_x.SetSize(p + 1);
11024  shape_y.SetSize(p + 1);
11025  shape_l.SetSize(p + 1);
11026  dshape_x.SetSize(p + 1);
11027  dshape_y.SetSize(p + 1);
11028  dshape_l.SetSize(p + 1);
11029  u.SetSize(dof, dim);
11030  divu.SetSize(dof);
11031 #else
11032  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
11033 #endif
11034 
11035  // edges
11036  int o = 0;
11037  for (int i = 0; i <= p; i++) // (0,1)
11038  {
11039  Nodes.IntPoint(o).Set2(bop[i], 0.);
11040  dof2nk[o++] = 0;
11041  }
11042  for (int i = 0; i <= p; i++) // (1,2)
11043  {
11044  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
11045  dof2nk[o++] = 1;
11046  }
11047  for (int i = 0; i <= p; i++) // (2,0)
11048  {
11049  Nodes.IntPoint(o).Set2(0., bop[p-i]);
11050  dof2nk[o++] = 2;
11051  }
11052 
11053  // interior
11054  for (int j = 0; j < p; j++)
11055  for (int i = 0; i + j < p; i++)
11056  {
11057  double w = iop[i] + iop[j] + iop[p-1-i-j];
11058  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
11059  dof2nk[o++] = 0;
11060  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
11061  dof2nk[o++] = 2;
11062  }
11063 
11064  DenseMatrix T(dof);
11065  for (int k = 0; k < dof; k++)
11066  {
11067  const IntegrationPoint &ip = Nodes.IntPoint(k);
11068  poly1d.CalcBasis(p, ip.x, shape_x);
11069  poly1d.CalcBasis(p, ip.y, shape_y);
11070  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
11071  const double *n_k = nk + 2*dof2nk[k];
11072 
11073  o = 0;
11074  for (int j = 0; j <= p; j++)
11075  for (int i = 0; i + j <= p; i++)
11076  {
11077  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
11078  T(o++, k) = s*n_k[0];
11079  T(o++, k) = s*n_k[1];
11080  }
11081  for (int i = 0; i <= p; i++)
11082  {
11083  double s = shape_x(i)*shape_y(p-i);
11084  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
11085  }
11086  }
11087 
11088  Ti.Factor(T);
11089  // mfem::out << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
11090 }
11091 
11093  DenseMatrix &shape) const
11094 {
11095  const int p = order - 1;
11096 
11097 #ifdef MFEM_THREAD_SAFE
11098  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
11099  DenseMatrix u(dof, dim);
11100 #endif
11101 
11102  poly1d.CalcBasis(p, ip.x, shape_x);
11103  poly1d.CalcBasis(p, ip.y, shape_y);
11104  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
11105 
11106  int o = 0;
11107  for (int j = 0; j <= p; j++)
11108  for (int i = 0; i + j <= p; i++)
11109  {
11110  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
11111  u(o,0) = s; u(o,1) = 0; o++;
11112  u(o,0) = 0; u(o,1) = s; o++;
11113  }
11114  for (int i = 0; i <= p; i++)
11115  {
11116  double s = shape_x(i)*shape_y(p-i);
11117  u(o,0) = (ip.x - c)*s;
11118  u(o,1) = (ip.y - c)*s;
11119  o++;
11120  }
11121 
11122  Ti.Mult(u, shape);
11123 }
11124 
11126  Vector &divshape) const
11127 {
11128  const int p = order - 1;
11129 
11130 #ifdef MFEM_THREAD_SAFE
11131  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
11132  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
11133  Vector divu(dof);
11134 #endif
11135 
11136  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
11137  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
11138  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
11139 
11140  int o = 0;
11141  for (int j = 0; j <= p; j++)
11142  for (int i = 0; i + j <= p; i++)
11143  {
11144  int k = p - i - j;
11145  divu(o++) = (dshape_x(i)*shape_l(k) -
11146  shape_x(i)*dshape_l(k))*shape_y(j);
11147  divu(o++) = (dshape_y(j)*shape_l(k) -
11148  shape_y(j)*dshape_l(k))*shape_x(i);
11149  }
11150  for (int i = 0; i <= p; i++)
11151  {
11152  int j = p - i;
11153  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
11154  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
11155  }
11156 
11157  Ti.Mult(divu, divshape);
11158 }
11159 
11160 
11161 const double RT_TetrahedronElement::nk[12] =
11162 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
11163 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
11164 
11165 const double RT_TetrahedronElement::c = 1./4.;
11166 
11168  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
11169  p + 1, H_DIV, FunctionSpace::Pk),
11170  dof2nk(dof)
11171 {
11172  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
11173  const double *bop = poly1d.OpenPoints(p);
11174 
11175 #ifndef MFEM_THREAD_SAFE
11176  shape_x.SetSize(p + 1);
11177  shape_y.SetSize(p + 1);
11178  shape_z.SetSize(p + 1);
11179  shape_l.SetSize(p + 1);
11180  dshape_x.SetSize(p + 1);
11181  dshape_y.SetSize(p + 1);
11182  dshape_z.SetSize(p + 1);
11183  dshape_l.SetSize(p + 1);
11184  u.SetSize(dof, dim);
11185  divu.SetSize(dof);
11186 #else
11187  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
11188 #endif
11189 
11190  int o = 0;
11191  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
11192  // the constructor of H1_TetrahedronElement)
11193  for (int j = 0; j <= p; j++)
11194  for (int i = 0; i + j <= p; i++) // (1,2,3)
11195  {
11196  double w = bop[i] + bop[j] + bop[p-i-j];
11197  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
11198  dof2nk[o++] = 0;
11199  }
11200  for (int j = 0; j <= p; j++)
11201  for (int i = 0; i + j <= p; i++) // (0,3,2)
11202  {
11203  double w = bop[i] + bop[j] + bop[p-i-j];
11204  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
11205  dof2nk[o++] = 1;
11206  }
11207  for (int j = 0; j <= p; j++)
11208  for (int i = 0; i + j <= p; i++) // (0,1,3)
11209  {
11210  double w = bop[i] + bop[j] + bop[p-i-j];
11211  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
11212  dof2nk[o++] = 2;
11213  }
11214  for (int j = 0; j <= p; j++)
11215  for (int i = 0; i + j <= p; i++) // (0,2,1)
11216  {
11217  double w = bop[i] + bop[j] + bop[p-i-j];
11218  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
11219  dof2nk[o++] = 3;
11220  }
11221 
11222  // interior
11223  for (int k = 0; k < p; k++)
11224  for (int j = 0; j + k < p; j++)
11225  for (int i = 0; i + j + k < p; i++)
11226  {
11227  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
11228  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11229  dof2nk[o++] = 1;
11230  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11231  dof2nk[o++] = 2;
11232  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11233  dof2nk[o++] = 3;
11234  }
11235 
11236  DenseMatrix T(dof);
11237  for (int m = 0; m < dof; m++)
11238  {
11239  const IntegrationPoint &ip = Nodes.IntPoint(m);
11240  poly1d.CalcBasis(p, ip.x, shape_x);
11241  poly1d.CalcBasis(p, ip.y, shape_y);
11242  poly1d.CalcBasis(p, ip.z, shape_z);
11243  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
11244  const double *nm = nk + 3*dof2nk[m];
11245 
11246  o = 0;
11247  for (int k = 0; k <= p; k++)
11248  for (int j = 0; j + k <= p; j++)
11249  for (int i = 0; i + j + k <= p; i++)
11250  {
11251  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
11252  T(o++, m) = s * nm[0];
11253  T(o++, m) = s * nm[1];
11254  T(o++, m) = s * nm[2];
11255  }
11256  for (int j = 0; j <= p; j++)
11257  for (int i = 0; i + j <= p; i++)
11258  {
11259  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
11260  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
11261  (ip.z - c)*nm[2]);
11262  }
11263  }
11264 
11265  Ti.Factor(T);
11266  // mfem::out << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
11267 }
11268 
11270  DenseMatrix &shape) const
11271 {
11272  const int p = order - 1;
11273 
11274 #ifdef MFEM_THREAD_SAFE
11275  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
11276  DenseMatrix u(dof, dim);
11277 #endif
11278 
11279  poly1d.CalcBasis(p, ip.x, shape_x);
11280  poly1d.CalcBasis(p, ip.y, shape_y);
11281  poly1d.CalcBasis(p, ip.z, shape_z);
11282  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
11283 
11284  int o = 0;
11285  for (int k = 0; k <= p; k++)
11286  for (int j = 0; j + k <= p; j++)
11287  for (int i = 0; i + j + k <= p; i++)
11288  {
11289  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
11290  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
11291  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
11292  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
11293  }
11294  for (int j = 0; j <= p; j++)
11295  for (int i = 0; i + j <= p; i++)
11296  {
11297  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
11298  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
11299  o++;
11300  }
11301 
11302  Ti.Mult(u, shape);
11303 }
11304 
11306  Vector &divshape) const
11307 {
11308  const int p = order - 1;
11309 
11310 #ifdef MFEM_THREAD_SAFE
11311  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
11312  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
11313  Vector divu(dof);
11314 #endif
11315 
11316  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
11317  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
11318  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
11319  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
11320 
11321  int o = 0;
11322  for (int k = 0; k <= p; k++)
11323  for (int j = 0; j + k <= p; j++)
11324  for (int i = 0; i + j + k <= p; i++)
11325  {
11326  int l = p - i - j - k;
11327  divu(o++) = (dshape_x(i)*shape_l(l) -
11328  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
11329  divu(o++) = (dshape_y(j)*shape_l(l) -
11330  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
11331  divu(o++) = (dshape_z(k)*shape_l(l) -
11332  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
11333  }
11334  for (int j = 0; j <= p; j++)
11335  for (int i = 0; i + j <= p; i++)
11336  {
11337  int k = p - i - j;
11338  divu(o++) =
11339  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
11340  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
11341  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
11342  }
11343 
11344  Ti.Mult(divu, divshape);
11345 }
11346 
11347 
11348 const double ND_HexahedronElement::tk[18] =
11349 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
11350 
11352  const int cb_type, const int ob_type)
11353  : VectorTensorFiniteElement(3, 3*p*(p + 1)*(p + 1), p, cb_type, ob_type,
11354  H_CURL, DofMapType::L2_DOF_MAP),
11355  dof2tk(dof)
11356 {
11357  dof_map.SetSize(dof);
11358 
11359  const double *cp = poly1d.ClosedPoints(p, cb_type);
11360  const double *op = poly1d.OpenPoints(p - 1, ob_type);
11361  const int dof3 = dof/3;
11362 
11363 #ifndef MFEM_THREAD_SAFE
11364  shape_cx.SetSize(p + 1);
11365  shape_ox.SetSize(p);
11366  shape_cy.SetSize(p + 1);
11367  shape_oy.SetSize(p);
11368  shape_cz.SetSize(p + 1);
11369  shape_oz.SetSize(p);
11370  dshape_cx.SetSize(p + 1);
11371  dshape_cy.SetSize(p + 1);
11372  dshape_cz.SetSize(p + 1);
11373 #endif
11374 
11375  // edges
11376  int o = 0;
11377  for (int i = 0; i < p; i++) // (0,1)
11378  {
11379  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
11380  }
11381  for (int i = 0; i < p; i++) // (1,2)
11382  {
11383  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
11384  }
11385  for (int i = 0; i < p; i++) // (3,2)
11386  {
11387  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
11388  }
11389  for (int i = 0; i < p; i++) // (0,3)
11390  {
11391  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
11392  }
11393  for (int i = 0; i < p; i++) // (4,5)
11394  {
11395  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
11396  }
11397  for (int i = 0; i < p; i++) // (5,6)
11398  {
11399  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
11400  }
11401  for (int i = 0; i < p; i++) // (7,6)
11402  {
11403  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
11404  }
11405  for (int i = 0; i < p; i++) // (4,7)
11406  {
11407  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
11408  }
11409  for (int i = 0; i < p; i++) // (0,4)
11410  {
11411  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
11412  }
11413  for (int i = 0; i < p; i++) // (1,5)
11414  {
11415  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
11416  }
11417  for (int i = 0; i < p; i++) // (2,6)
11418  {
11419  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
11420  }
11421  for (int i = 0; i < p; i++) // (3,7)
11422  {
11423  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
11424  }
11425 
11426  // faces
11427  // (3,2,1,0) -- bottom
11428  for (int j = 1; j < p; j++) // x - components
11429  for (int i = 0; i < p; i++)
11430  {
11431  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
11432  }
11433  for (int j = 0; j < p; j++) // y - components
11434  for (int i = 1; i < p; i++)
11435  {
11436  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
11437  }
11438  // (0,1,5,4) -- front
11439  for (int k = 1; k < p; k++) // x - components
11440  for (int i = 0; i < p; i++)
11441  {
11442  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
11443  }
11444  for (int k = 0; k < p; k++) // z - components
11445  for (int i = 1; i < p; i++ )
11446  {
11447  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
11448  }
11449  // (1,2,6,5) -- right
11450  for (int k = 1; k < p; k++) // y - components
11451  for (int j = 0; j < p; j++)
11452  {
11453  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
11454  }
11455  for (int k = 0; k < p; k++) // z - components
11456  for (int j = 1; j < p; j++)
11457  {
11458  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
11459  }
11460  // (2,3,7,6) -- back
11461  for (int k = 1; k < p; k++) // x - components
11462  for (int i = 0; i < p; i++)
11463  {
11464  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
11465  }
11466  for (int k = 0; k < p; k++) // z - components
11467  for (int i = 1; i < p; i++)
11468  {
11469  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
11470  }
11471  // (3,0,4,7) -- left
11472  for (int k = 1; k < p; k++) // y - components
11473  for (int j = 0; j < p; j++)
11474  {
11475  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
11476  }
11477  for (int k = 0; k < p; k++) // z - components
11478  for (int j = 1; j < p; j++)
11479  {
11480  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
11481  }
11482  // (4,5,6,7) -- top
11483  for (int j = 1; j < p; j++) // x - components
11484  for (int i = 0; i < p; i++)
11485  {
11486  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
11487  }
11488  for (int j = 0; j < p; j++) // y - components
11489  for (int i = 1; i < p; i++)
11490  {
11491  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
11492  }
11493 
11494  // interior
11495  // x-components
11496  for (int k = 1; k < p; k++)
11497  for (int j = 1; j < p; j++)
11498  for (int i = 0; i < p; i++)
11499  {
11500  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
11501  }
11502  // y-components
11503  for (int k = 1; k < p; k++)
11504  for (int j = 0; j < p; j++)
11505  for (int i = 1; i < p; i++)
11506  {
11507  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
11508  }
11509  // z-components
11510  for (int k = 0; k < p; k++)
11511  for (int j = 1; j < p; j++)
11512  for (int i = 1; i < p; i++)
11513  {
11514  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
11515  }
11516 
11517  // set dof2tk and Nodes
11518  o = 0;
11519  // x-components
11520  for (int k = 0; k <= p; k++)
11521  for (int j = 0; j <= p; j++)
11522  for (int i = 0; i < p; i++)
11523  {
11524  int idx;
11525  if ((idx = dof_map[o++]) < 0)
11526  {
11527  dof2tk[idx = -1 - idx] = 3;
11528  }
11529  else
11530  {
11531  dof2tk[idx] = 0;
11532  }
11533  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
11534  }
11535  // y-components
11536  for (int k = 0; k <= p; k++)
11537  for (int j = 0; j < p; j++)
11538  for (int i = 0; i <= p; i++)
11539  {
11540  int idx;
11541  if ((idx = dof_map[o++]) < 0)
11542  {
11543  dof2tk[idx = -1 - idx] = 4;
11544  }
11545  else
11546  {
11547  dof2tk[idx] = 1;
11548  }
11549  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
11550  }
11551  // z-components
11552  for (int k = 0; k < p; k++)
11553  for (int j = 0; j <= p; j++)
11554  for (int i = 0; i <= p; i++)
11555  {
11556  int idx;
11557  if ((idx = dof_map[o++]) < 0)
11558  {
11559  dof2tk[idx = -1 - idx] = 5;
11560  }
11561  else
11562  {
11563  dof2tk[idx] = 2;
11564  }
11565  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
11566  }
11567 }
11568 
11570  DenseMatrix &shape) const
11571 {
11572  const int p = order;
11573 
11574 #ifdef MFEM_THREAD_SAFE
11575  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11576  Vector shape_cz(p + 1), shape_oz(p);
11577 #endif
11578 
11579  cbasis1d.Eval(ip.x, shape_cx);
11580  obasis1d.Eval(ip.x, shape_ox);
11581  cbasis1d.Eval(ip.y, shape_cy);
11582  obasis1d.Eval(ip.y, shape_oy);
11583  cbasis1d.Eval(ip.z, shape_cz);
11584  obasis1d.Eval(ip.z, shape_oz);
11585 
11586  int o = 0;
11587  // x-components
11588  for (int k = 0; k <= p; k++)
11589  for (int j = 0; j <= p; j++)
11590  for (int i = 0; i < p; i++)
11591  {
11592  int idx, s;
11593  if ((idx = dof_map[o++]) < 0)
11594  {
11595  idx = -1 - idx, s = -1;
11596  }
11597  else
11598  {
11599  s = +1;
11600  }
11601  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
11602  shape(idx,1) = 0.;
11603  shape(idx,2) = 0.;
11604  }
11605  // y-components
11606  for (int k = 0; k <= p; k++)
11607  for (int j = 0; j < p; j++)
11608  for (int i = 0; i <= p; i++)
11609  {
11610  int idx, s;
11611  if ((idx = dof_map[o++]) < 0)
11612  {
11613  idx = -1 - idx, s = -1;
11614  }
11615  else
11616  {
11617  s = +1;
11618  }
11619  shape(idx,0) = 0.;
11620  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
11621  shape(idx,2) = 0.;
11622  }
11623  // z-components
11624  for (int k = 0; k < p; k++)
11625  for (int j = 0; j <= p; j++)
11626  for (int i = 0; i <= p; i++)
11627  {
11628  int idx, s;
11629  if ((idx = dof_map[o++]) < 0)
11630  {
11631  idx = -1 - idx, s = -1;
11632  }
11633  else
11634  {
11635  s = +1;
11636  }
11637  shape(idx,0) = 0.;
11638  shape(idx,1) = 0.;
11639  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
11640  }
11641 }
11642 
11644  DenseMatrix &curl_shape) const
11645 {
11646  const int p = order;
11647 
11648 #ifdef MFEM_THREAD_SAFE
11649  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11650  Vector shape_cz(p + 1), shape_oz(p);
11651  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
11652 #endif
11653 
11654  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11655  obasis1d.Eval(ip.x, shape_ox);
11656  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11657  obasis1d.Eval(ip.y, shape_oy);
11658  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
11659  obasis1d.Eval(ip.z, shape_oz);
11660 
11661  int o = 0;
11662  // x-components
11663  for (int k = 0; k <= p; k++)
11664  for (int j = 0; j <= p; j++)
11665  for (int i = 0; i < p; i++)
11666  {
11667  int idx, s;
11668  if ((idx = dof_map[o++]) < 0)
11669  {
11670  idx = -1 - idx, s = -1;
11671  }
11672  else
11673  {
11674  s = +1;
11675  }
11676  curl_shape(idx,0) = 0.;
11677  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
11678  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
11679  }
11680  // y-components
11681  for (int k = 0; k <= p; k++)
11682  for (int j = 0; j < p; j++)
11683  for (int i = 0; i <= p; i++)
11684  {
11685  int idx, s;
11686  if ((idx = dof_map[o++]) < 0)
11687  {
11688  idx = -1 - idx, s = -1;
11689  }
11690  else
11691  {
11692  s = +1;
11693  }
11694  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
11695  curl_shape(idx,1) = 0.;
11696  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
11697  }
11698  // z-components
11699  for (int k = 0; k < p; k++)
11700  for (int j = 0; j <= p; j++)
11701  for (int i = 0; i <= p; i++)
11702  {
11703  int idx, s;
11704  if ((idx = dof_map[o++]) < 0)
11705  {
11706  idx = -1 - idx, s = -1;
11707  }
11708  else
11709  {
11710  s = +1;
11711  }
11712  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
11713  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
11714  curl_shape(idx,2) = 0.;
11715  }
11716 }
11717 
11719  const IntegrationRule &ir,
11720  DofToQuad::Mode mode) const
11721 {
11722  MFEM_VERIFY(mode != DofToQuad::FULL, "invalid mode requested");
11723 
11724  return GetTensorDofToQuad(ir, mode, true);
11725 }
11726 
11728  const IntegrationRule &ir,
11729  DofToQuad::Mode mode) const
11730 {
11731  MFEM_VERIFY(mode != DofToQuad::FULL, "invalid mode requested");
11732 
11733  return GetTensorDofToQuad(ir, mode, false);
11734 }
11735 
11737  const IntegrationRule &ir,
11738  DofToQuad::Mode mode,
11739  const bool closed) const
11740 {
11741  MFEM_VERIFY(mode == DofToQuad::TENSOR, "invalid mode requested");
11742 
11743  for (int i = 0;
11744  i < (closed ? dof2quad_array.Size() : dof2quad_array_open.Size());
11745  i++)
11746  {
11747  const DofToQuad &d2q = closed ? *dof2quad_array[i] : *dof2quad_array_open[i];
11748  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
11749  }
11750 
11751  DofToQuad *d2q = new DofToQuad;
11752  const int ndof = closed ? order + 1 : order;
11753  const int nqpt = (int)floor(pow(ir.GetNPoints(), 1.0/dim) + 0.5);
11754  d2q->FE = this;
11755  d2q->IntRule = &ir;
11756  d2q->mode = mode;
11757  d2q->ndof = ndof;
11758  d2q->nqpt = nqpt;
11759  d2q->B.SetSize(nqpt*ndof);
11760  d2q->Bt.SetSize(ndof*nqpt);
11761  d2q->G.SetSize(nqpt*ndof);
11762  d2q->Gt.SetSize(ndof*nqpt);
11763  Vector val(ndof), grad(ndof);
11764  for (int i = 0; i < nqpt; i++)
11765  {
11766  // The first 'nqpt' points in 'ir' have the same x-coordinates as those
11767  // of the 1D rule.
11768 
11769  if (closed)
11770  {
11771  cbasis1d.Eval(ir.IntPoint(i).x, val, grad);
11772  }
11773  else
11774  {
11775  obasis1d.Eval(ir.IntPoint(i).x, val, grad);
11776  }
11777 
11778  for (int j = 0; j < ndof; j++)
11779  {
11780  d2q->B[i+nqpt*j] = d2q->Bt[j+ndof*i] = val(j);
11781  d2q->G[i+nqpt*j] = d2q->Gt[j+ndof*i] = grad(j);
11782  }
11783  }
11784 
11785  if (closed)
11786  {
11787  dof2quad_array.Append(d2q);
11788  }
11789  else
11790  {
11791  dof2quad_array_open.Append(d2q);
11792  }
11793 
11794  return *d2q;
11795 }
11796 
11798 {
11799  for (int i = 0; i < dof2quad_array_open.Size(); i++)
11800  {
11801  delete dof2quad_array_open[i];
11802  }
11803 }
11804 
11805 const double ND_QuadrilateralElement::tk[8] =
11806 { 1.,0., 0.,1., -1.,0., 0.,-1. };
11807 
11809  const int cb_type,
11810  const int ob_type)
11811  : VectorTensorFiniteElement(2, 2*p*(p + 1), p, cb_type, ob_type,
11812  H_CURL, DofMapType::L2_DOF_MAP),
11813  dof2tk(dof)
11814 {
11815  dof_map.SetSize(dof);
11816 
11817  const double *cp = poly1d.ClosedPoints(p, cb_type);
11818  const double *op = poly1d.OpenPoints(p - 1, ob_type);
11819  const int dof2 = dof/2;
11820 
11821 #ifndef MFEM_THREAD_SAFE
11822  shape_cx.SetSize(p + 1);
11823  shape_ox.SetSize(p);
11824  shape_cy.SetSize(p + 1);
11825  shape_oy.SetSize(p);
11826  dshape_cx.SetSize(p + 1);
11827  dshape_cy.SetSize(p + 1);
11828 #endif
11829 
11830  // edges
11831  int o = 0;
11832  for (int i = 0; i < p; i++) // (0,1)
11833  {
11834  dof_map[0*dof2 + i + 0*p] = o++;
11835  }
11836  for (int j = 0; j < p; j++) // (1,2)
11837  {
11838  dof_map[1*dof2 + p + j*(p + 1)] = o++;
11839  }
11840  for (int i = 0; i < p; i++) // (2,3)
11841  {
11842  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
11843  }
11844  for (int j = 0; j < p; j++) // (3,0)
11845  {
11846  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
11847  }
11848 
11849  // interior
11850  // x-components
11851  for (int j = 1; j < p; j++)
11852  for (int i = 0; i < p; i++)
11853  {
11854  dof_map[0*dof2 + i + j*p] = o++;
11855  }
11856  // y-components
11857  for (int j = 0; j < p; j++)
11858  for (int i = 1; i < p; i++)
11859  {
11860  dof_map[1*dof2 + i + j*(p + 1)] = o++;
11861  }
11862 
11863  // set dof2tk and Nodes
11864  o = 0;
11865  // x-components
11866  for (int j = 0; j <= p; j++)
11867  for (int i = 0; i < p; i++)
11868  {
11869  int idx;
11870  if ((idx = dof_map[o++]) < 0)
11871  {
11872  dof2tk[idx = -1 - idx] = 2;
11873  }
11874  else
11875  {
11876  dof2tk[idx] = 0;
11877  }
11878  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
11879  }
11880  // y-components
11881  for (int j = 0; j < p; j++)
11882  for (int i = 0; i <= p; i++)
11883  {
11884  int idx;
11885  if ((idx = dof_map[o++]) < 0)
11886  {
11887  dof2tk[idx = -1 - idx] = 3;
11888  }
11889  else
11890  {
11891  dof2tk[idx] = 1;
11892  }
11893  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
11894  }
11895 }
11896 
11898  DenseMatrix &shape) const
11899 {
11900  const int p = order;
11901 
11902 #ifdef MFEM_THREAD_SAFE
11903  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11904 #endif
11905 
11906  cbasis1d.Eval(ip.x, shape_cx);
11907  obasis1d.Eval(ip.x, shape_ox);
11908  cbasis1d.Eval(ip.y, shape_cy);
11909  obasis1d.Eval(ip.y, shape_oy);
11910 
11911  int o = 0;
11912  // x-components
11913  for (int j = 0; j <= p; j++)
11914  for (int i = 0; i < p; i++)
11915  {
11916  int idx, s;
11917  if ((idx = dof_map[o++]) < 0)
11918  {
11919  idx = -1 - idx, s = -1;
11920  }
11921  else
11922  {
11923  s = +1;
11924  }
11925  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
11926  shape(idx,1) = 0.;
11927  }
11928  // y-components
11929  for (int j = 0; j < p; j++)
11930  for (int i = 0; i <= p; i++)
11931  {
11932  int idx, s;
11933  if ((idx = dof_map[o++]) < 0)
11934  {
11935  idx = -1 - idx, s = -1;
11936  }
11937  else
11938  {
11939  s = +1;
11940  }
11941  shape(idx,0) = 0.;
11942  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
11943  }
11944 }
11945 
11947  DenseMatrix &curl_shape) const
11948 {
11949  const int p = order;
11950 
11951 #ifdef MFEM_THREAD_SAFE
11952  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11953  Vector dshape_cx(p + 1), dshape_cy(p + 1);
11954 #endif
11955 
11956  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11957  obasis1d.Eval(ip.x, shape_ox);
11958  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11959  obasis1d.Eval(ip.y, shape_oy);
11960 
11961  int o = 0;
11962  // x-components
11963  for (int j = 0; j <= p; j++)
11964  for (int i = 0; i < p; i++)
11965  {
11966  int idx, s;
11967  if ((idx = dof_map[o++]) < 0)
11968  {
11969  idx = -1 - idx, s = -1;
11970  }
11971  else
11972  {
11973  s = +1;
11974  }
11975  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
11976  }
11977  // y-components
11978  for (int j = 0; j < p; j++)
11979  for (int i = 0; i <= p; i++)
11980  {
11981  int idx, s;
11982  if ((idx = dof_map[o++]) < 0)
11983  {
11984  idx = -1 - idx, s = -1;
11985  }
11986  else
11987  {
11988  s = +1;
11989  }
11990  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
11991  }
11992 }
11993 
11994 
11995 const double ND_TetrahedronElement::tk[18] =
11996 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
11997 
11998 const double ND_TetrahedronElement::c = 1./4.;
11999 
12001  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
12002  H_CURL, FunctionSpace::Pk), dof2tk(dof)
12003 {
12004  const double *eop = poly1d.OpenPoints(p - 1);
12005  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
12006  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
12007 
12008  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
12009 
12010 #ifndef MFEM_THREAD_SAFE
12011  shape_x.SetSize(p);
12012  shape_y.SetSize(p);
12013  shape_z.SetSize(p);
12014  shape_l.SetSize(p);
12015  dshape_x.SetSize(p);
12016  dshape_y.SetSize(p);
12017  dshape_z.SetSize(p);
12018  dshape_l.SetSize(p);
12019  u.SetSize(dof, dim);
12020 #else
12021  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
12022 #endif
12023 
12024  int o = 0;
12025  // edges
12026  for (int i = 0; i < p; i++) // (0,1)
12027  {
12028  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
12029  dof2tk[o++] = 0;
12030  }
12031  for (int i = 0; i < p; i++) // (0,2)
12032  {
12033  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
12034  dof2tk[o++] = 1;
12035  }
12036  for (int i = 0; i < p; i++) // (0,3)
12037  {
12038  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
12039  dof2tk[o++] = 2;
12040  }
12041  for (int i = 0; i < p; i++) // (1,2)
12042  {
12043  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
12044  dof2tk[o++] = 3;
12045  }
12046  for (int i = 0; i < p; i++) // (1,3)
12047  {
12048  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
12049  dof2tk[o++] = 4;
12050  }
12051  for (int i = 0; i < p; i++) // (2,3)
12052  {
12053  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
12054  dof2tk[o++] = 5;
12055  }
12056 
12057  // faces
12058  for (int j = 0; j <= pm2; j++) // (1,2,3)
12059  for (int i = 0; i + j <= pm2; i++)
12060  {
12061  double w = fop[i] + fop[j] + fop[pm2-i-j];
12062  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
12063  dof2tk[o++] = 3;
12064  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
12065  dof2tk[o++] = 4;
12066  }
12067  for (int j = 0; j <= pm2; j++) // (0,3,2)
12068  for (int i = 0; i + j <= pm2; i++)
12069  {
12070  double w = fop[i] + fop[j] + fop[pm2-i-j];
12071  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
12072  dof2tk[o++] = 2;
12073  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
12074  dof2tk[o++] = 1;
12075  }
12076  for (int j = 0; j <= pm2; j++) // (0,1,3)
12077  for (int i = 0; i + j <= pm2; i++)
12078  {
12079  double w = fop[i] + fop[j] + fop[pm2-i-j];
12080  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
12081  dof2tk[o++] = 0;
12082  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
12083  dof2tk[o++] = 2;
12084  }
12085  for (int j = 0; j <= pm2; j++) // (0,2,1)
12086  for (int i = 0; i + j <= pm2; i++)
12087  {
12088  double w = fop[i] + fop[j] + fop[pm2-i-j];
12089  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
12090  dof2tk[o++] = 1;
12091  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
12092  dof2tk[o++] = 0;
12093  }
12094 
12095  // interior
12096  for (int k = 0; k <= pm3; k++)
12097  for (int j = 0; j + k <= pm3; j++)
12098  for (int i = 0; i + j + k <= pm3; i++)
12099  {
12100  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
12101  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
12102  dof2tk[o++] = 0;
12103  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
12104  dof2tk[o++] = 1;
12105  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
12106  dof2tk[o++] = 2;
12107  }
12108 
12109  DenseMatrix T(dof);
12110  for (int m = 0; m < dof; m++)
12111  {
12112  const IntegrationPoint &ip = Nodes.IntPoint(m);
12113  const double *tm = tk + 3*dof2tk[m];
12114  o = 0;
12115 
12116  poly1d.CalcBasis(pm1, ip.x, shape_x);
12117  poly1d.CalcBasis(pm1, ip.y, shape_y);
12118  poly1d.CalcBasis(pm1, ip.z, shape_z);
12119  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
12120 
12121  for (int k = 0; k <= pm1; k++)
12122  for (int j = 0; j + k <= pm1; j++)
12123  for (int i = 0; i + j + k <= pm1; i++)
12124  {
12125  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
12126  T(o++, m) = s * tm[0];
12127  T(o++, m) = s * tm[1];
12128  T(o++, m) = s * tm[2];
12129  }
12130  for (int k = 0; k <= pm1; k++)
12131  for (int j = 0; j + k <= pm1; j++)
12132  {
12133  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
12134  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
12135  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
12136  }
12137  for (int k = 0; k <= pm1; k++)
12138  {
12139  T(o++, m) =
12140  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
12141  }
12142  }
12143 
12144  Ti.Factor(T);
12145  // mfem::out << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
12146 }
12147 
12149  DenseMatrix &shape) const
12150 {
12151  const int pm1 = order - 1;
12152 
12153 #ifdef MFEM_THREAD_SAFE
12154  const int p = order;
12155  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
12156  DenseMatrix u(dof, dim);
12157 #endif
12158 
12159  poly1d.CalcBasis(pm1, ip.x, shape_x);
12160  poly1d.CalcBasis(pm1, ip.y, shape_y);
12161  poly1d.CalcBasis(pm1, ip.z, shape_z);
12162  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
12163 
12164  int n = 0;
12165  for (int k = 0; k <= pm1; k++)
12166  for (int j = 0; j + k <= pm1; j++)
12167  for (int i = 0; i + j + k <= pm1; i++)
12168  {
12169  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
12170  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
12171  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
12172  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
12173  }
12174  for (int k = 0; k <= pm1; k++)
12175  for (int j = 0; j + k <= pm1; j++)
12176  {
12177  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
12178  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
12179  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
12180  }
12181  for (int k = 0; k <= pm1; k++)
12182  {
12183  double s = shape_y(pm1-k)*shape_z(k);
12184  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
12185  }
12186 
12187  Ti.Mult(u, shape);
12188 }
12189 
12191  DenseMatrix &curl_shape) const
12192 {
12193  const int pm1 = order - 1;
12194 
12195 #ifdef MFEM_THREAD_SAFE
12196  const int p = order;
12197  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
12198  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
12199  DenseMatrix u(dof, dim);
12200 #endif
12201 
12202  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
12203  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
12204  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
12205  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
12206 
12207  int n = 0;
12208  for (int k = 0; k <= pm1; k++)
12209  for (int j = 0; j + k <= pm1; j++)
12210  for (int i = 0; i + j + k <= pm1; i++)
12211  {
12212  int l = pm1-i-j-k;
12213  const double dx = (dshape_x(i)*shape_l(l) -
12214  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
12215  const double dy = (dshape_y(j)*shape_l(l) -
12216  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
12217  const double dz = (dshape_z(k)*shape_l(l) -
12218  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
12219 
12220  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
12221  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
12222  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
12223  }
12224  for (int k = 0; k <= pm1; k++)
12225  for (int j = 0; j + k <= pm1; j++)
12226  {
12227  int i = pm1 - j - k;
12228  // s = shape_x(i)*shape_y(j)*shape_z(k);
12229  // curl of s*(ip.y - c, -(ip.x - c), 0):
12230  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
12231  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
12232  u(n,2) =
12233  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
12234  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
12235  n++;
12236  // curl of s*(ip.z - c, 0, -(ip.x - c)):
12237  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
12238  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
12239  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
12240  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
12241  n++;
12242  }
12243  for (int k = 0; k <= pm1; k++)
12244  {
12245  int j = pm1 - k;
12246  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
12247  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
12248  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
12249  u(n,1) = 0.;
12250  u(n,2) = 0.; n++;
12251  }
12252 
12253  Ti.Mult(u, curl_shape);
12254 }
12255 
12256 
12257 const double ND_TriangleElement::tk[8] =
12258 { 1.,0., -1.,1., 0.,-1., 0.,1. };
12259 
12260 const double ND_TriangleElement::c = 1./3.;
12261 
12263  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
12264  H_CURL, FunctionSpace::Pk),
12265  dof2tk(dof)
12266 {
12267  const double *eop = poly1d.OpenPoints(p - 1);
12268  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
12269 
12270  const int pm1 = p - 1, pm2 = p - 2;
12271 
12272 #ifndef MFEM_THREAD_SAFE
12273  shape_x.SetSize(p);
12274  shape_y.SetSize(p);
12275  shape_l.SetSize(p);
12276  dshape_x.SetSize(p);
12277  dshape_y.SetSize(p);
12278  dshape_l.SetSize(p);
12279  u.SetSize(dof, dim);
12280  curlu.SetSize(dof);
12281 #else
12282  Vector shape_x(p), shape_y(p), shape_l(p);
12283 #endif
12284 
12285  int n = 0;
12286  // edges
12287  for (int i = 0; i < p; i++) // (0,1)
12288  {
12289  Nodes.IntPoint(n).Set2(eop[i], 0.);
12290  dof2tk[n++] = 0;
12291  }
12292  for (int i = 0; i < p; i++) // (1,2)
12293  {
12294  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
12295  dof2tk[n++] = 1;
12296  }
12297  for (int i = 0; i < p; i++) // (2,0)
12298  {
12299  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
12300  dof2tk[n++] = 2;
12301  }
12302 
12303  // interior
12304  for (int j = 0; j <= pm2; j++)
12305  for (int i = 0; i + j <= pm2; i++)
12306  {
12307  double w = iop[i] + iop[j] + iop[pm2-i-j];
12308  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
12309  dof2tk[n++] = 0;
12310  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
12311  dof2tk[n++] = 3;
12312  }
12313 
12314  DenseMatrix T(dof);
12315  for (int m = 0; m < dof; m++)
12316  {
12317  const IntegrationPoint &ip = Nodes.IntPoint(m);
12318  const double *tm = tk + 2*dof2tk[m];
12319  n = 0;
12320 
12321  poly1d.CalcBasis(pm1, ip.x, shape_x);
12322  poly1d.CalcBasis(pm1, ip.y, shape_y);
12323  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
12324 
12325  for (int j = 0; j <= pm1; j++)
12326  for (int i = 0; i + j <= pm1; i++)
12327  {
12328  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
12329  T(n++, m) = s * tm[0];
12330  T(n++, m) = s * tm[1];
12331  }
12332  for (int j = 0; j <= pm1; j++)
12333  {
12334  T(n++, m) =
12335  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
12336  }
12337  }
12338 
12339  Ti.Factor(T);
12340  // mfem::out << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
12341 }
12342 
12344  DenseMatrix &shape) const
12345 {
12346  const int pm1 = order - 1;
12347 
12348 #ifdef MFEM_THREAD_SAFE
12349  const int p = order;
12350  Vector shape_x(p), shape_y(p), shape_l(p);
12351  DenseMatrix u(dof, dim);
12352 #endif
12353 
12354  poly1d.CalcBasis(pm1, ip.x, shape_x);
12355  poly1d.CalcBasis(pm1, ip.y, shape_y);
12356  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
12357 
12358  int n = 0;
12359  for (int j = 0; j <= pm1; j++)
12360  for (int i = 0; i + j <= pm1; i++)
12361  {
12362  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
12363  u(n,0) = s; u(n,1) = 0; n++;
12364  u(n,0) = 0; u(n,1) = s; n++;
12365  }
12366  for (int j = 0; j <= pm1; j++)
12367  {
12368  double s = shape_x(pm1-j)*shape_y(j);
12369  u(n,0) = s*(ip.y - c);
12370  u(n,1) = -s*(ip.x - c);
12371  n++;
12372  }
12373 
12374  Ti.Mult(u, shape);
12375 }
12376 
12378  DenseMatrix &curl_shape) const
12379 {
12380  const int pm1 = order - 1;
12381 
12382 #ifdef MFEM_THREAD_SAFE
12383  const int p = order;
12384  Vector shape_x(p), shape_y(p), shape_l(p);
12385  Vector dshape_x(p), dshape_y(p), dshape_l(p);
12386  Vector curlu(dof);
12387 #endif
12388 
12389  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
12390  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
12391  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
12392 
12393  int n = 0;
12394  for (int j = 0; j <= pm1; j++)
12395  for (int i = 0; i + j <= pm1; i++)
12396  {
12397  int l = pm1-i-j;
12398  const double dx = (dshape_x(i)*shape_l(l) -
12399  shape_x(i)*dshape_l(l)) * shape_y(j);
12400  const double dy = (dshape_y(j)*shape_l(l) -
12401  shape_y(j)*dshape_l(l)) * shape_x(i);
12402 
12403  curlu(n++) = -dy;
12404  curlu(n++) = dx;
12405  }
12406 
12407  for (int j = 0; j <= pm1; j++)
12408  {
12409  int i = pm1 - j;
12410  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
12411  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
12412  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
12413  }
12414 
12415  Vector curl2d(curl_shape.Data(),dof);
12416  Ti.Mult(curlu, curl2d);
12417 }
12418 
12419 
12420 const double ND_SegmentElement::tk[1] = { 1. };
12421 
12422 ND_SegmentElement::ND_SegmentElement(const int p, const int ob_type)
12423  : VectorFiniteElement(1, Geometry::SEGMENT, p, p - 1,
12424  H_CURL, FunctionSpace::Pk),
12425  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(ob_type))),
12426  dof2tk(dof)
12427 {
12428  const double *op = poly1d.OpenPoints(p - 1, ob_type);
12429 
12430  // set dof2tk and Nodes
12431  for (int i = 0; i < p; i++)
12432  {
12433  dof2tk[i] = 0;
12434  Nodes.IntPoint(i).x = op[i];
12435  }
12436 }
12437 
12439  DenseMatrix &shape) const
12440 {
12441  Vector vshape(shape.Data(), dof);
12442 
12443  obasis1d.Eval(ip.x, vshape);
12444 }
12445 
12447 {
12448  order = kv[0]->GetOrder();
12449  dof = order + 1;
12450 
12451  weights.SetSize(dof);
12452  shape_x.SetSize(dof);
12453 }
12454 
12456  Vector &shape) const
12457 {
12458  kv[0]->CalcShape(shape, ijk[0], ip.x);
12459 
12460  double sum = 0.0;
12461  for (int i = 0; i <= order; i++)
12462  {
12463  sum += (shape(i) *= weights(i));
12464  }
12465 
12466  shape /= sum;
12467 }
12468 
12470  DenseMatrix &dshape) const
12471 {
12472  Vector grad(dshape.Data(), dof);
12473 
12474  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
12475  kv[0]->CalcDShape(grad, ijk[0], ip.x);
12476 
12477  double sum = 0.0, dsum = 0.0;
12478  for (int i = 0; i <= order; i++)
12479  {
12480  sum += (shape_x(i) *= weights(i));
12481  dsum += ( grad(i) *= weights(i));
12482  }
12483 
12484  sum = 1.0/sum;
12485  add(sum, grad, -dsum*sum*sum, shape_x, grad);
12486 }
12487 
12489  DenseMatrix &hessian) const
12490 {
12491  Vector grad(dof);
12492  Vector hess(hessian.Data(), dof);
12493 
12494  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
12495  kv[0]->CalcDShape(grad, ijk[0], ip.x);
12496  kv[0]->CalcD2Shape(hess, ijk[0], ip.x);
12497 
12498  double sum = 0.0, dsum = 0.0, d2sum = 0.0;
12499  for (int i = 0; i <= order; i++)
12500  {
12501  sum += (shape_x(i) *= weights(i));
12502  dsum += ( grad(i) *= weights(i));
12503  d2sum += ( hess(i) *= weights(i));
12504  }
12505 
12506  sum = 1.0/sum;
12507  add(sum, hess, -2*dsum*sum*sum, grad, hess);
12508  add(1.0, hess, (-d2sum + 2*dsum*dsum*sum)*sum*sum, shape_x, hess);
12509 }
12510 
12511 
12513 {
12514  orders[0] = kv[0]->GetOrder();
12515  orders[1] = kv[1]->GetOrder();
12516  shape_x.SetSize(orders[0]+1);
12517  shape_y.SetSize(orders[1]+1);
12518  dshape_x.SetSize(orders[0]+1);
12519  dshape_y.SetSize(orders[1]+1);
12520  d2shape_x.SetSize(orders[0]+1);
12521  d2shape_y.SetSize(orders[1]+1);
12522 
12523  order = max(orders[0], orders[1]);
12524  dof = (orders[0] + 1)*(orders[1] + 1);
12525  u.SetSize(dof);
12526  du.SetSize(dof);
12527  weights.SetSize(dof);
12528 }
12529 
12531  Vector &shape) const
12532 {
12533  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
12534  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
12535 
12536  double sum = 0.0;
12537  for (int o = 0, j = 0; j <= orders[1]; j++)
12538  {
12539  const double sy = shape_y(j);
12540  for (int i = 0; i <= orders[0]; i++, o++)
12541  {
12542  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
12543  }
12544  }
12545 
12546  shape /= sum;
12547 }
12548 
12550  DenseMatrix &dshape) const
12551 {
12552  double sum, dsum[2];
12553 
12554  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
12555  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
12556 
12557  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
12558  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
12559 
12560  sum = dsum[0] = dsum[1] = 0.0;
12561  for (int o = 0, j = 0; j <= orders[1]; j++)
12562  {
12563  const double sy = shape_y(j), dsy = dshape_y(j);
12564  for (int i = 0; i <= orders[0]; i++, o++)
12565  {
12566  sum += ( u(o) = shape_x(i)*sy*weights(o) );
12567 
12568  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
12569  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
12570  }
12571  }
12572 
12573  sum = 1.0/sum;
12574  dsum[0] *= sum*sum;
12575  dsum[1] *= sum*sum;
12576 
12577  for (int o = 0; o < dof; o++)
12578  {
12579  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
12580  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
12581  }
12582 }
12583 
12585  DenseMatrix &hessian) const
12586 {
12587  double sum, dsum[2], d2sum[3];
12588 
12589  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
12590  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
12591 
12592  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
12593  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
12594 
12595  kv[0]->CalcD2Shape(d2shape_x, ijk[0], ip.x);
12596  kv[1]->CalcD2Shape(d2shape_y, ijk[1], ip.y);
12597 
12598  sum = dsum[0] = dsum[1] = 0.0;
12599  d2sum[0] = d2sum[1] = d2sum[2] = 0.0;
12600  for (int o = 0, j = 0; j <= orders[1]; j++)
12601  {
12602  const double sy = shape_y(j), dsy = dshape_y(j), d2sy = d2shape_y(j);
12603  for (int i = 0; i <= orders[0]; i++, o++)
12604  {
12605  const double sx = shape_x(i), dsx = dshape_x(i), d2sx = d2shape_x(i);
12606  sum += ( u(o) = sx*sy*weights(o) );
12607 
12608  dsum[0] += ( du(o,0) = dsx*sy*weights(o) );
12609  dsum[1] += ( du(o,1) = sx*dsy*weights(o) );
12610 
12611  d2sum[0] += ( hessian(o,0) = d2sx*sy*weights(o) );
12612  d2sum[1] += ( hessian(o,1) = dsx*dsy*weights(o) );
12613  d2sum[2] += ( hessian(o,2) = sx*d2sy*weights(o) );
12614  }
12615  }
12616 
12617  sum = 1.0/sum;
12618  dsum[0] *= sum;
12619  dsum[1] *= sum;
12620 
12621  d2sum[0] *= sum;
12622  d2sum[1] *= sum;
12623  d2sum[2] *= sum;
12624 
12625  for (int o = 0; o < dof; o++)
12626  {
12627  hessian(o,0) = hessian(o,0)*sum
12628  - 2*du(o,0)*sum*dsum[0]
12629  + u[o]*sum*(2*dsum[0]*dsum[0] - d2sum[0]);
12630 
12631  hessian(o,1) = hessian(o,1)*sum
12632  - du(o,0)*sum*dsum[1]
12633  - du(o,1)*sum*dsum[0]
12634  + u[o]*sum*(2*dsum[0]*dsum[1] - d2sum[1]);
12635 
12636  hessian(o,2) = hessian(o,2)*sum
12637  - 2*du(o,1)*sum*dsum[1]
12638  + u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[2]);
12639  }
12640 }
12641 
12642 
12644 {
12645  orders[0] = kv[0]->GetOrder();
12646  orders[1] = kv[1]->GetOrder();
12647  orders[2] = kv[2]->GetOrder();
12648  shape_x.SetSize(orders[0]+1);
12649  shape_y.SetSize(orders[1]+1);
12650  shape_z.SetSize(orders[2]+1);
12651 
12652  dshape_x.SetSize(orders[0]+1);
12653  dshape_y.SetSize(orders[1]+1);
12654  dshape_z.SetSize(orders[2]+1);
12655 
12656  d2shape_x.SetSize(orders[0]+1);
12657  d2shape_y.SetSize(orders[1]+1);
12658  d2shape_z.SetSize(orders[2]+1);
12659 
12660  order = max(max(orders[0], orders[1]), orders[2]);
12661  dof = (orders[0] + 1)*(orders[1] + 1)*(orders[2] + 1);
12662  u.SetSize(dof);
12663  du.SetSize(dof);
12664  weights.SetSize(dof);
12665 }
12666 
12668  Vector &shape) const
12669 {
12670  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
12671  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
12672  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
12673 
12674  double sum = 0.0;
12675  for (int o = 0, k = 0; k <= orders[2]; k++)
12676  {
12677  const double sz = shape_z(k);
12678  for (int j = 0; j <= orders[1]; j++)
12679  {
12680  const double sy_sz = shape_y(j)*sz;
12681  for (int i = 0; i <= orders[0]; i++, o++)
12682  {
12683  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
12684  }
12685  }
12686  }
12687 
12688  shape /= sum;
12689 }
12690 
12692  DenseMatrix &dshape) const
12693 {
12694  double sum, dsum[3];
12695 
12696  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
12697  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
12698  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
12699 
12700  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
12701  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
12702  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
12703 
12704  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
12705  for (int o = 0, k = 0; k <= orders[2]; k++)
12706  {
12707  const double sz = shape_z(k), dsz = dshape_z(k);
12708  for (int j = 0; j <= orders[1]; j++)
12709  {
12710  const double sy_sz = shape_y(j)* sz;
12711  const double dsy_sz = dshape_y(j)* sz;
12712  const double sy_dsz = shape_y(j)*dsz;
12713  for (int i = 0; i <= orders[0]; i++, o++)
12714  {
12715  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
12716 
12717  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
12718  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
12719  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
12720  }
12721  }
12722  }
12723 
12724  sum = 1.0/sum;
12725  dsum[0] *= sum*sum;
12726  dsum[1] *= sum*sum;
12727  dsum[2] *= sum*sum;
12728 
12729  for (int o = 0; o < dof; o++)
12730  {
12731  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
12732  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
12733  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
12734  }
12735 }
12736 
12738  DenseMatrix &hessian) const
12739 {
12740  double sum, dsum[3], d2sum[6];
12741 
12742  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
12743  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
12744  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
12745 
12746  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
12747  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
12748  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
12749 
12750  kv[0]->CalcD2Shape(d2shape_x, ijk[0], ip.x);
12751  kv[1]->CalcD2Shape(d2shape_y, ijk[1], ip.y);
12752  kv[2]->CalcD2Shape(d2shape_z, ijk[2], ip.z);
12753 
12754  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
12755  d2sum[0] = d2sum[1] = d2sum[2] = d2sum[3] = d2sum[4] = d2sum[5] = 0.0;
12756 
12757  for (int o = 0, k = 0; k <= orders[2]; k++)
12758  {
12759  const double sz = shape_z(k), dsz = dshape_z(k), d2sz = d2shape_z(k);
12760  for (int j = 0; j <= orders[1]; j++)
12761  {
12762  const double sy = shape_y(j), dsy = dshape_y(j), d2sy = d2shape_y(j);
12763  for (int i = 0; i <= orders[0]; i++, o++)
12764  {
12765  const double sx = shape_x(i), dsx = dshape_x(i), d2sx = d2shape_x(i);
12766  sum += ( u(o) = sx*sy*sz*weights(o) );
12767 
12768  dsum[0] += ( du(o,0) = dsx*sy*sz*weights(o) );
12769  dsum[1] += ( du(o,1) = sx*dsy*sz*weights(o) );
12770  dsum[2] += ( du(o,2) = sx*sy*dsz*weights(o) );
12771 
12772  d2sum[0] += ( hessian(o,0) = d2sx*sy*sz*weights(o) );
12773  d2sum[1] += ( hessian(o,1) = dsx*dsy*sz*weights(o) );
12774  d2sum[2] += ( hessian(o,2) = dsx*sy*dsz*weights(o) );
12775 
12776  d2sum[3] += ( hessian(o,3) = sx*dsy*dsz*weights(o) );
12777 
12778  d2sum[4] += ( hessian(o,4) = sx*sy*d2sz*weights(o) );
12779  d2sum[5] += ( hessian(o,5) = sx*d2sy*sz*weights(o) );
12780  }
12781  }
12782  }
12783 
12784  sum = 1.0/sum;
12785  dsum[0] *= sum;
12786  dsum[1] *= sum;
12787  dsum[2] *= sum;
12788 
12789  d2sum[0] *= sum;
12790  d2sum[1] *= sum;
12791  d2sum[2] *= sum;
12792 
12793  d2sum[3] *= sum;
12794  d2sum[4] *= sum;
12795  d2sum[5] *= sum;
12796 
12797  for (int o = 0; o < dof; o++)
12798  {
12799  hessian(o,0) = hessian(o,0)*sum
12800  - 2*du(o,0)*sum*dsum[0]
12801  + u[o]*sum*(2*dsum[0]*dsum[0] - d2sum[0]);
12802 
12803  hessian(o,1) = hessian(o,1)*sum
12804  - du(o,0)*sum*dsum[1]
12805  - du(o,1)*sum*dsum[0]
12806  + u[o]*sum*(2*dsum[0]*dsum[1] - d2sum[1]);
12807 
12808  hessian(o,2) = hessian(o,2)*sum
12809  - du(o,0)*sum*dsum[2]
12810  - du(o,2)*sum*dsum[0]
12811  + u[o]*sum*(2*dsum[0]*dsum[2] - d2sum[2]);
12812 
12813  hessian(o,3) = hessian(o,3)*sum
12814  - du(o,1)*sum*dsum[2]
12815  - du(o,2)*sum*dsum[1]
12816  + u[o]*sum*(2*dsum[1]*dsum[2] - d2sum[3]);
12817 
12818  hessian(o,4) = hessian(o,4)*sum
12819  - 2*du(o,2)*sum*dsum[2]
12820  + u[o]*sum*(2*dsum[2]*dsum[2] - d2sum[4]);
12821 
12822  hessian(o,5) = hessian(o,5)*sum
12823  - 2*du(o,1)*sum*dsum[1]
12824  + u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[5]);
12825 
12826  }
12827 }
12828 
12829 // Global object definitions
12830 
12831 // Object declared in mesh/triangle.hpp.
12832 // Defined here to ensure it is constructed before 'Geometries'.
12834 
12835 // Object declared in mesh/tetrahedron.hpp.
12836 // Defined here to ensure it is constructed before 'Geometries'.
12838 
12839 // Object declared in mesh/wedge.hpp.
12840 // Defined here to ensure it is constructed after 'poly1d' and before
12841 // 'Geometries'.
12842 // TODO: define as thread_local to prevent race conditions in GLVis, because
12843 // there is no "LinearWedgeFiniteElement" and WedgeFE is in turn used from two
12844 // different threads for different things in GLVis. We also don't want to turn
12845 // MFEM_THREAD_SAFE on globally. (See PR #731)
12847 
12848 // Object declared in geom.hpp.
12849 // Construct 'Geometries' after 'TriangleFE', 'TetrahedronFE', and 'WedgeFE'.
12851 
12852 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:245
Abstract class for all finite elements.
Definition: fe.hpp:235
RefinedLinear3DFiniteElement()
Construct the RefinedLinear3DFiniteElement.
Definition: fe.cpp:4977
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:12488
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1862
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:9528
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:2393
RT0TriangleFiniteElement()
Construct the RT0TriangleFiniteElement.
Definition: fe.cpp:3322
ND_SegmentElement(const int p, const int ob_type=BasisType::GaussLegendre)
Construct the ND_SegmentElement of order p and open BasisType ob_type.
Definition: fe.cpp:12422
int Size() const
Return the logical size of the array.
Definition: array.hpp:124
const DenseMatrix & AdjugateJacobian()
Return the adjugate of the Jacobian matrix of the transformation at the currently set IntegrationPoin...
Definition: eltrans.hpp:127
DenseMatrix curlshape_J
Definition: fe.hpp:793
void Get(double *p, const int dim) const
Definition: intrules.hpp:51
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:6776
RT2TriangleFiniteElement()
Construct the RT2TriangleFiniteElement.
Definition: fe.cpp:3927
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:309
GaussQuad2DFiniteElement()
Construct the GaussQuad2DFiniteElement.
Definition: fe.cpp:1780
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:8198
void trans(const Vector &u, Vector &x)
Definition: ex27.cpp:421
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:3614
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:4555
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:1610
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:2163
L2Pos_WedgeElement(const int p)
Construct the L2Pos_WedgeElement of order p.
Definition: fe.cpp:10399
CrouzeixRaviartQuadFiniteElement()
Construct the CrouzeixRaviartQuadFiniteElement.
Definition: fe.cpp:3284
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:9918
P2SegmentFiniteElement()
Construct the P2SegmentFiniteElement.
Definition: fe.cpp:4346
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:12549
Linear3DFiniteElement()
Construct the Linear3DFiniteElement.
Definition: fe.cpp:3012
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:46
virtual void CalcPhysLinLaplacian(ElementTransformation &Trans, Vector &Laplacian) const
Definition: fe.cpp:254
static double CalcDelta(const int p, const double x)
Evaluate a representation of a Delta function at point x.
Definition: fe.hpp:1957
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:3796
RT1TriangleFiniteElement()
Construct the RT1TriangleFiniteElement.
Definition: fe.cpp:3547
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:9679
void ProjectMatrixCoefficient_RT(const double *nk, const Array< int > &d2n, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Project the rows of the matrix coefficient in an RT space.
Definition: fe.cpp:951
int NumCols() const
Definition: array.hpp:355
void ProjectMatrixCoefficient_ND(const double *tk, const Array< int > &d2t, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Project the rows of the matrix coefficient in an ND space.
Definition: fe.cpp:1140
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:11269
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 the RefinedBiLinear2DFiniteElement.
Definition: fe.cpp:5209
const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
Definition: fe.cpp:11718
NodalTensorFiniteElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:7680
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:2407
void LocalInterpolation_RT(const VectorFiniteElement &cfe, const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1234
L2Pos_TriangleElement(const int p)
Construct the L2Pos_TriangleElement of order p.
Definition: fe.cpp:10062
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:915
H1Pos_SegmentElement(const int p)
Construct the H1Pos_SegmentElement of order p.
Definition: fe.cpp:8140
Basis(const int p, const double *nodes, EvalType etype=Barycentric)
Create a nodal or positive (Bernstein) basis.
Definition: fe.cpp:6881
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Definition: fe.hpp:157
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Compute the discrete divergence matrix from the given FiniteElement onto &#39;this&#39; FiniteElement. The ElementTransformation is included to support cases when the matrix depends on it.
Definition: fe.cpp:183
Base class for vector Coefficients that optionally depend on time and space.
void SetRow(int r, const double *row)
Definition: densemat.cpp:1792
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
Definition: densemat.cpp:358
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:299
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:5821
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
Definition: fe.cpp:130
Array< const KnotVector * > kv
Definition: fe.hpp:3192
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:3251
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
virtual function which evaluates the values of all shape functions at a given point ip and stores the...
Definition: fe.cpp:3029
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:10101
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:3568
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
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:3848
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:2203
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:8178
PositiveTensorFiniteElement(const int dims, const int p, const DofMapType dmtype)
Definition: fe.cpp:7689
void GivePolyPoints(const int np, double *pts, const int type)
Definition: intrules.cpp:641
Class for finite elements utilizing the always positive Bernstein basis.
Definition: fe.hpp:738
L2Pos_TetrahedronElement(const int p)
Construct the L2Pos_TetrahedronElement of order p.
Definition: fe.cpp:10257
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:9381
PointFiniteElement()
Construct the PointFiniteElement.
Definition: fe.cpp:1395
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Given a matrix coefficient and a transformation, compute an approximation (&quot;projection&quot;) in the local...
Definition: fe.cpp:660
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:8026
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:891
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:459
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:10651
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:5883
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:212
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:4338
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:1531
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
Definition: fe.cpp:621
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:2227
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Compute the Hessian of second order partial derivatives at ip.
Definition: fe.cpp:2585
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:2496
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:3333
FiniteElement(int D, Geometry::Type G, int Do, int O, int F=FunctionSpace::Pk)
Construct FiniteElement with given.
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:2983
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:71
H1Pos_SegmentElement SegmentFE
Definition: fe.hpp:2412
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1420
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:7785
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)
Construct the H1Pos_TetrahedronElement of order p.
Definition: fe.cpp:8867
int dim
Dimension of reference space.
Definition: fe.hpp:238
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
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:9547
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
Definition: densemat.cpp:299
void SetIntPoint(const IntegrationPoint *ip)
Set the integration point ip that weights and Jacobians will be evaluated at.
Definition: eltrans.hpp:85
LagrangeHexFiniteElement(int degree)
Construct the LagrangeHexFiniteElement with the provided degree.
Definition: fe.cpp:4607
TensorBasisElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:7479
L2_SegmentElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_SegmentElement of order p and BasisType btype.
Definition: fe.cpp:9407
BiQuadPos2DFiniteElement()
Construct the BiQuadPos2DFiniteElement.
Definition: fe.cpp:2180
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition: fe.hpp:319
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:3346
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:1988
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:4461
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:4769
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Definition: fe.hpp:169
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:4413
GaussBiQuad2DFiniteElement()
Construct the GaussBiQuad2DFiniteElement.
Definition: fe.cpp:2355
int Size() const
Returns the size of the vector.
Definition: vector.hpp:160
Array< double > Gt
Transpose of G.
Definition: fe.hpp:208
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Compute the discrete gradient matrix from the given FiniteElement onto &#39;this&#39; FiniteElement. The ElementTransformation is included to support cases when the matrix depends on it.
Definition: fe.cpp:723
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:12469
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
Definition: fe.hpp:165
static int GetQuadrature1D(int b_type)
Get the corresponding Quadrature1D constant, when that makes sense; otherwise return Quadrature1D::In...
Definition: fe.hpp:62
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:11125
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:10461
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:6049
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:1053
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:2998
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:12446
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:2656
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()
Return the inverse of the Jacobian matrix of the transformation at the currently set IntegrationPoint...
Definition: eltrans.hpp:132
RefinedTriLinear3DFiniteElement()
Construct the RefinedTriLinear3DFiniteElement.
Definition: fe.cpp:5356
DenseMatrix vshape
Definition: fe.hpp:248
P0QuadFiniteElement()
Construct the P0QuadFiniteElement.
Definition: fe.cpp:2991
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:4594
Quadratic3DFiniteElement()
Construct the Quadratic3DFiniteElement.
Definition: fe.cpp:3068
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
Definition: fe.hpp:341
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:9423
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:6399
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:6586
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:3237
Geometry::Type geom_type
Geometry::Type of the reference element.
Definition: fe.hpp:239
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:3445
const IntegrationPoint & GetIntPoint()
Get a const reference to the currently set integration point. This will return NULL if no integration...
Definition: eltrans.hpp:90
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:10221
Intermediate class for finite elements whose basis functions return vector values.
Definition: fe.hpp:778
static void CalcLegendre(const int p, const double x, double *u)
Definition: fe.cpp:7305
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
Get the matrix I that defines nodal interpolation between this element and the refined element fine_f...
Definition: fe.cpp:393
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:2708
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:10287
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:3276
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:3268
const IntegrationPoint & GetCenter(int GeomType)
Return the center of the given Geometry::Type, GeomType.
Definition: geom.hpp:70
RT1HexFiniteElement()
Construct the RT1HexFiniteElement.
Definition: fe.cpp:6277
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:9485
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:7839
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:1091
H1Pos_HexahedronElement(const int p)
Construct the H1Pos_HexahedronElement of order p.
Definition: fe.cpp:8273
RT0QuadFiniteElement()
Construct the RT0QuadFiniteElement.
Definition: fe.cpp:3432
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Compute the discrete gradient matrix from the given FiniteElement onto &#39;this&#39; FiniteElement. The ElementTransformation is included to support cases when the matrix depends on it.
Definition: fe.cpp:167
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:169
RT1QuadFiniteElement()
Construct the RT1QuadFiniteElement.
Definition: fe.cpp:3689
static void CalcShape(const int p, const double x, const double y, const double z, double *shape)
Definition: fe.cpp:8969
const DofToQuad & GetTensorDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode, const bool closed) const
Definition: fe.cpp:11736
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:10163
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:1492
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:8245
Linear2DFiniteElement()
Construct the Linear2DFiniteElement.
Definition: fe.cpp:1434
const double * ClosedPoints(const int p, const int btype=BasisType::GaussLobatto)
Get coordinates of a closed (GaussLegendre) set of points if degree p.
Definition: fe.hpp:1917
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:3125
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:6721
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:261
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5545
Cubic2DFiniteElement()
Construct the Cubic2DFiniteElement.
Definition: fe.cpp:2683
H1_HexahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_HexahedronElement of order p and BasisType btype.
Definition: fe.cpp:7953
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:12343
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:1401
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:2728
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)
Construct the L2Pos_HexahedronElement of order p.
Definition: fe.cpp:9846
ND_TriangleElement(const int p)
Construct the ND_TriangleElement of order p.
Definition: fe.cpp:12262
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:11305
static void CalcDShape(const int p, const double x, const double y, const double z, double *dshape_1d, double *dshape)
Definition: fe.cpp:9002
static void CalcBasis(const int p, const double x, double *u)
Evaluate the values of a hierarchical 1D basis at point x hierarchical = k-th basis function is degre...
Definition: fe.hpp:1933
virtual void ProjectFromNodes(Vector &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector of values at the finite element nodes and a transformation, compute its projection (ap...
Definition: fe.cpp:142
int GetHeight() const
Get the height of the matrix.
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
evaluate shape function - constant 1
Definition: fe.cpp:2977
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:2756
static void CalcBinomTerms(const int p, const double x, const double y, double *u)
Compute the p terms in the expansion of the binomial (x + y)^p and store them in the already allocate...
Definition: fe.cpp:7211
const double * GetPoints(const int p, const int btype)
Get the coordinates of the points of the given BasisType, btype.
Definition: fe.cpp:7404
H1Pos_TriangleElement(const int p)
Construct the H1Pos_TriangleElement of order p.
Definition: fe.cpp:8722
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:4050
Poly_1D::Basis & obasis1d
Definition: fe.hpp:2096
Cubic3DFiniteElement()
Construct the Cubic3DFiniteElement.
Definition: fe.cpp:2803
Linear1DFiniteElement()
Construct the Linear1DFiniteElement.
Definition: fe.cpp:1413
A 1D element with uniform nodes.
Definition: fe.hpp:1527
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4918
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:6709
RT0HexFiniteElement()
Construct the RT0HexFiniteElement.
Definition: fe.cpp:6123
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:2276
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Compute the discrete curl matrix from the given FiniteElement onto &#39;this&#39; FiniteElement. The ElementTransformation is included to support cases when the matrix depends on it.
Definition: fe.cpp:175
Class for standard nodal finite elements.
Definition: fe.hpp:683
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:312
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:1667
CrouzeixRaviartFiniteElement()
Construct the CrouzeixRaviartFiniteElement.
Definition: fe.cpp:3257
static void CalcShape(const int p, const double x, const double y, double *shape)
Definition: fe.cpp:8777
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:3299
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:7696
Array< int > s_dof
Definition: fe.hpp:2656
Class for finite elements with basis functions that return scalar values.
Definition: fe.hpp:615
void SetSize(int m, int n)
Definition: array.hpp:352
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:2896
Geometry Geometries
Definition: fe.cpp:12850
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:4356
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:891
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Definition: densemat.cpp:203
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:2163
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:9429
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1627
Poly_1D::Basis & cbasis1d
Definition: fe.hpp:2096
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1638
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1886
Bernstein polynomials.
Definition: fe.hpp:35
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:65
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:9238
RefinedLinear1DFiniteElement()
Construct the RefinedLinear1DFiniteElement.
Definition: fe.cpp:4807
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:8055
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:8266
ND_HexahedronElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Construct the ND_HexahedronElement of order p and closed and open BasisType cb_type and ob_type...
Definition: fe.cpp:11351
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:2380
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:10004
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:8418
Poly_1D::Basis & basis1d
Definition: fe.hpp:2007
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4834
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:3989
static void ChebyshevPoints(const int p, double *x)
Compute the points for the Chebyshev polynomials of order p and place them in the already allocated x...
Definition: fe.cpp:7179
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
Definition: densemat.cpp:2823
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:111
Cubic1DFiniteElement()
Construct the Cubic1DFiniteElement.
Definition: fe.cpp:2647
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:6846
H1Pos_WedgeElement(const int p)
Construct the H1Pos_WedgeElement of order p.
Definition: fe.cpp:9264
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:4579
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:6687
ND_TetrahedronElement(const int p)
Construct the ND_TetrahedronElement of order p.
Definition: fe.cpp:12000
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:10090
Array< int > t_dof
Definition: fe.hpp:2656
int deriv_range_type
Definition: fe.hpp:240
Nedelec1TetFiniteElement()
Construct the Nedelec1TetFiniteElement.
Definition: fe.cpp:5958
RT2QuadFiniteElement()
Construct the RT2QuadFiniteElement.
Definition: fe.cpp:4013
Mode mode
Describes the contents of the B, Bt, G, and Gt arrays, see Mode.
Definition: fe.hpp:161
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)
Construct the H1_QuadrilateralElement of order p and BasisType btype.
Definition: fe.cpp:7813
GaussLinear2DFiniteElement()
Construct the GaussLinear2DFiniteElement.
Definition: fe.cpp:1502
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:1407
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:2671
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:637
class FiniteElement * FE
The FiniteElement that created and owns this object.
Definition: fe.hpp:136
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:2070
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Definition: fe.hpp:382
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:5936
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1708
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:9761
static int VerifyOpen(int b_type)
Ensure that the BasisType of b_type is open (doesn&#39;t have Quadrature1D points on the boundary)...
Definition: fe.hpp:598
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:3103
L2Pos_QuadrilateralElement(const int p)
Construct the L2Pos_QuadrilateralElement of order p.
Definition: fe.cpp:9616
const int * ijk
Definition: fe.hpp:3193
P1TetNonConfFiniteElement()
Construct the P1TetNonConfFiniteElement.
Definition: fe.cpp:4522
double Weight()
Return the weight of the Jacobian matrix of the transformation at the currently set IntegrationPoint...
Definition: eltrans.hpp:123
P0SegmentFiniteElement(int Ord=0)
Construct the P0SegmentFiniteElement with dummy order Ord.
Definition: fe.cpp:3239
static void CalcDShape(const int p, const double x, const double y, double *dshape_1d, double *dshape)
Definition: fe.cpp:8803
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:10354
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:3591
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:12667
DenseMatrix curlshape
Definition: fe.hpp:793
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
Definition: densemat.cpp:2845
A 3D linear element on a tetrahedron with nodes at the vertices of the tetrahedron.
Definition: fe.hpp:1236
H1_SegmentElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_SegmentElement of order p and BasisType btype.
Definition: fe.cpp:7709
Nedelec1HexFiniteElement()
Construct the Nedelec1HexFiniteElement.
Definition: fe.cpp:5713
int orders[Geometry::MaxDim]
Anisotropic orders.
Definition: fe.hpp:245
void Set2(const double x1, const double x2)
Definition: intrules.hpp:80
virtual ~FiniteElement()
Deconstruct the FiniteElement.
Definition: fe.cpp:384
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:10865
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:5987
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:201
A 2D linear element on triangle with nodes at the vertices of the triangle.
Definition: fe.hpp:929
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:9982
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:10604
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:2535
L2_QuadrilateralElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_QuadrilateralElement of order p and BasisType btype.
Definition: fe.cpp:9509
void SetData(double *d)
Definition: vector.hpp:121
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:4248
Basis & GetBasis(const int p, const int btype)
Get a Poly_1D::Basis object of the given degree and BasisType, btype.
Definition: fe.cpp:7428
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1483
void GetColumn(int c, Vector &col) const
Definition: densemat.cpp:1289
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
virtual function which evaluates the values of all partial derivatives of all shape functions at a gi...
Definition: fe.cpp:3038
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:10939
const double * OpenPoints(const int p, const int btype=BasisType::GaussLegendre)
Get coordinates of an open (GaussLegendre) set of points if degree p.
Definition: fe.hpp:1912
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:8618
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:1732
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:9219
class H1_WedgeElement WedgeFE
L2_WedgeElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_WedgeElement of order p and BasisType btype.
Definition: fe.cpp:10311
void ScalarLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
Get matrix I &quot;Interpolation&quot; defined through local L2-projection in the space defined by the fine_fe...
Definition: fe.cpp:427
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:1810
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:1213
L2_TetrahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_TetrahedronElement of order p and BasisType btype.
Definition: fe.cpp:10113
int deriv_map_type
Definition: fe.hpp:240
RT0TetFiniteElement()
Construct the RT0TetFiniteElement.
Definition: fe.cpp:6666
static const int MaxDim
Definition: geom.hpp:42
Array< int > t_dof
Definition: fe.hpp:2409
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:10084
void Threshold(double eps)
Replace small entries, abs(a_ij) &lt;= eps, with zero.
Definition: densemat.cpp:1822
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:2199
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:12691
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:1824
DenseMatrix m_dshape
Definition: fe.hpp:2304
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:11946
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:9640
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:70
IntegrationRule Nodes
Definition: fe.hpp:246
Array< int > dof_map
Definition: fe.hpp:2006
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1694
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:9873
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:8158
Array< double > Bt
Transpose of B.
Definition: fe.hpp:186
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:8340
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:4300
P0HexFiniteElement()
Construct the P0HexFiniteElement.
Definition: fe.cpp:4586
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:12377
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:3460
P1SegmentFiniteElement()
Construct the P1SegmentFiniteElement.
Definition: fe.cpp:4322
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5232
void LocalInterpolation_ND(const VectorFiniteElement &cfe, const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1273
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:8676
H1Pos_TriangleElement TriangleFE
Definition: fe.hpp:2411
ND_QuadrilateralElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Construct the ND_QuadrilateralElement of order p and closed and open BasisType cb_type and ob_type...
Definition: fe.cpp:11808
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:3357
BiCubic2DFiniteElement()
Construct the BiCubic2DFiniteElement.
Definition: fe.cpp:2459
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:903
DenseMatrix Jinv
Definition: fe.hpp:792
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:9440
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:315
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:8643
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
P0TetFiniteElement()
Construct the P0TetFiniteElement.
Definition: fe.cpp:4565
Base class Coefficients that optionally depend on space and time. These are used by the BilinearFormI...
Definition: coefficient.hpp:39
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:1578
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:6017
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:10280
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:191
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition: array.hpp:654
DenseMatrix t_dshape
Definition: fe.hpp:2407
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1445
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5402
Base class for Matrix Coefficients that optionally depend on time and space.
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:5099
DenseMatrix t_dshape
Definition: fe.hpp:2654
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
Definition: densemat.cpp:2331
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:7162
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:4150
DenseMatrix s_dshape
Definition: fe.hpp:2407
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:1513
H1_TetrahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_TetrahedronElement of order p and BasisType btype.
Definition: fe.cpp:8502
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:12643
DenseMatrix s_dshape
Definition: fe.hpp:2654
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:7880
void Mult(const double *x, double *y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:3277
Structure representing the matrices/tensors needed to evaluate (in reference space) the values...
Definition: fe.hpp:131
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:10442
class Linear3DFiniteElement TetrahedronFE
Definition: fe.cpp:12837
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:10188
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:11569
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:3524
L2Pos_TriangleElement TriangleFE
Definition: fe.hpp:2658
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:128
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:1935
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3183
Linear2DFiniteElement TriangleFE
Definition: fe.cpp:12833
A 2D bi-linear element on a square with nodes at the vertices of the square.
Definition: fe.hpp:951
Array< double > B
Basis functions evaluated at quadrature points.
Definition: fe.hpp:180
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:2029
Quad1DFiniteElement()
Construct the Quad1DFiniteElement.
Definition: fe.cpp:1619
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:8295
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Get the dofs associated with the given face. *dofs is set to an internal array of the local dofc on t...
Definition: fe.cpp:100
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
Definition: fe.cpp:376
virtual int GetSpaceDim() const =0
Get the dimension of the target (physical) space.
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:1567
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1474
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)
Construct the H1Pos_QuadrilateralElement of order p.
Definition: fe.cpp:8205
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:10373
void LocalRestriction_ND(const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &R) const
Definition: fe.cpp:1353
H1_TriangleElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_TriangleElement of order p and BasisType btype.
Definition: fe.cpp:8347
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1427
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:10033
Mode
Type of data stored in the arrays B, Bt, G, and Gt.
Definition: fe.hpp:144
Full multidimensional representation which does not use tensor product structure. The ordering of the...
Definition: fe.hpp:149
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Given a matrix coefficient and a transformation, compute an approximation (&quot;projection&quot;) in the local...
Definition: fe.cpp:148
L2Pos_SegmentElement SegmentFE
Definition: fe.hpp:2659
const Poly_1D::Basis & GetBasis1D() const
Definition: fe.hpp:2023
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:8316
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:9491
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:3004
const DofToQuad & GetDofToQuadOpen(const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:11727
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:9894
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:914
int dof
Number of degrees of freedom.
Definition: fe.hpp:243
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:7981
Array< DofToQuad * > dof2quad_array
Container for all DofToQuad objects created by the FiniteElement.
Definition: fe.hpp:253
H1_WedgeElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_WedgeElement of order p and BasisType btype.
Definition: fe.cpp:9119
Array< int > s_dof
Definition: fe.hpp:2409
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:1602
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:3964
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:12148
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:3724
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:11897
static int VerifyClosed(int b_type)
Ensure that the BasisType of b_type is closed (has Quadrature1D points on the boundary).
Definition: fe.hpp:589
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Compute the discrete divergence matrix from the given FiniteElement onto &#39;this&#39; FiniteElement. The ElementTransformation is included to support cases when the matrix depends on it.
Definition: fe.cpp:752
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:3472
Implements CalcDivShape methods.
Definition: fe.hpp:294
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:923
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
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:9502
RefinedLinear2DFiniteElement()
Construct the RefinedLinear2DFiniteElement.
Definition: fe.cpp:4853
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:6641
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:557
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4815
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:4543
Array< double > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
Definition: fe.hpp:201
Array< int > dof_map
Definition: fe.hpp:2306
RT_TetrahedronElement(const int p)
Construct the RT_TetrahedronElement of order p.
Definition: fe.cpp:11167
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:6197
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:7766
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:4748
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:7747
double infinity()
Define a shortcut for std::numeric_limits&lt;double&gt;::infinity()
Definition: vector.hpp:45
BiQuad2DFiniteElement()
Construct the BiQuad2DFiniteElement.
Definition: fe.cpp:1839
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Get the dofs associated with the given face. *dofs is set to an internal array of the local dofc on t...
Definition: fe.cpp:3058
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:3761
P0TriangleFiniteElement()
Construct the P0TriangleFiniteElement.
Definition: fe.cpp:2970
static int VerifyNodal(int b_type)
Ensure that the BasisType of b_type nodal (satisfies the interpolation property). ...
Definition: fe.hpp:606
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:3245
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)
Construct the H1Ser_QuadrilateralElement of order p.
Definition: fe.cpp:1954
RT_TriangleElement(const int p)
Construct the RT_TriangleElement of order p.
Definition: fe.cpp:11014
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:7728
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:12438
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:11643
void Eval(const double x, Vector &u) const
Definition: fe.cpp:6939
L2Pos_SegmentElement(const int p)
Construct the L2Pos_SegmentElement of order p.
Definition: fe.cpp:9464
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:12737
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:5012
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:6252
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:2650
void InvertLinearTrans(ElementTransformation &trans, const IntegrationPoint &pt, Vector &x)
Definition: fe.cpp:576
Vector data type.
Definition: vector.hpp:51
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:6183
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:175
static void CalcBernstein(const int p, const double x, double *u)
Compute the values of the Bernstein basis functions of order p at coordinate x and store the results ...
Definition: fe.hpp:1982
virtual void Transform(const IntegrationPoint &, Vector &)=0
Transform integration point from reference coordinates to physical coordinates and store them in the ...
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:12512
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:8225
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:9737
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:1760
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:11092
Quad2DFiniteElement()
Construct the Quad2DFiniteElement.
Definition: fe.cpp:1677
int GetWidth() const
Get the width of the matrix.
void LocalRestriction_RT(const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &R) const
Definition: fe.cpp:1310
static bool CheckPoint(int GeomType, const IntegrationPoint &ip)
Check if the given point is inside the given reference element.
Definition: geom.cpp:345
Describes the function space on each element.
Definition: fe.hpp:213
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3199
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
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:6102
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:9659
GaussBiLinear2DFiniteElement()
Construct the FiniteElement.
Definition: fe.cpp:1543
const DenseMatrix & Hessian()
Return the Hessian matrix of the transformation at the currently set IntegrationPoint, using the method SetIntPoint().
Definition: eltrans.hpp:117
RT_HexahedronElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Construct the RT_HexahedronElement of order p and closed and open BasisType cb_type and ob_type...
Definition: fe.cpp:10701
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:12190
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:4600
Arbitrary order H1 elements in 3D on a wedge.
Definition: fe.hpp:2356
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
Definition: fe.cpp:2305
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1453
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:2868
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:8469
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:3310
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
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:7904
QuadPos1DFiniteElement()
Construct the QuadPos1DFiniteElement.
Definition: fe.cpp:1649
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:6153
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:4368
RT_QuadrilateralElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Construct the RT_QuadrilateralElement of order p and closed and open BasisType cb_type and ob_type...
Definition: fe.cpp:10490
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Return a DofToQuad structure corresponding to the given IntegrationRule using the given DofToQuad::Mo...
Definition: fe.cpp:467
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5283
P1OnQuadFiniteElement()
Construct the P1OnQuadFiniteElement.
Definition: fe.cpp:1591
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...
RotTriLinearHexFiniteElement()
Construct the RotTriLinearHexFiniteElement.
Definition: fe.cpp:6801
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:12530
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:1110
int GetRangeType() const
Returns the FiniteElement::RangeType of the element, one of {SCALAR, VECTOR}.
Definition: fe.hpp:332
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:1556
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:378
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:3666
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:9362
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:4573
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:8002
L2_HexahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_HexahedronElement of order p and BasisType btype.
Definition: fe.cpp:9694
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:592
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:7858
static void CalcDBinomTerms(const int p, const double x, const double y, double *d)
Compute the derivatives (w.r.t. x) of the terms in the expansion of the binomial (x + y)^p assuming t...
Definition: fe.cpp:7275
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:5766
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:12584
const IntegrationRule * IntRule
IntegrationRule that defines the quadrature points at which the basis functions of the FE are evaluat...
Definition: fe.hpp:141
TriLinear3DFiniteElement()
Construct the TriLinear3DFiniteElement.
Definition: fe.cpp:3147
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:154
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:1657
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:9716
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4870
const DofToQuad & GetTensorDofToQuad(const class TensorBasisElement &tb, const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:515
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:4329
L2_TriangleElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_TriangleElement of order p and BasisType btype.
Definition: fe.cpp:9937
int order
Order/degree of the shape functions.
Definition: fe.hpp:243
BiLinear2DFiniteElement()
Construct the BiLinear2DFiniteElement.
Definition: fe.cpp:1461
Poly_1D poly1d
Definition: fe.cpp:7476
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:6829
Lagrange1DFiniteElement(int degree)
Construct the Lagrange1DFiniteElement with the provided degree.
Definition: fe.cpp:4381
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Given a vector coefficient and a transformation, compute its projection (approximation) in the local ...
Definition: fe.cpp:3409
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:6522
No derivatives implemented.
Definition: fe.hpp:292
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:10298
Implements CalcCurlShape methods.
Definition: fe.hpp:295
virtual void ProjectDelta(int vertex, Vector &dofs) const
Project a delta function centered on the given vertex in the local finite dimensional space represent...
Definition: fe.cpp:9567
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:1523
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:8440
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:1026
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Given a coefficient and a transformation, compute its projection (approximation) in the local finite ...
Definition: fe.cpp:784