MFEM  v4.3.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-2021, 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_ABORT("method is not implemented for this class");
44 }
45 
48 {
49  MFEM_ABORT("method is not implemented for this class");
50 }
51 
53  const IntegrationPoint &ip, Vector &divshape) const
54 {
55  MFEM_ABORT("method is not implemented for this class");
56 }
57 
59  ElementTransformation &Trans, Vector &div_shape) const
60 {
61  CalcDivShape(Trans.GetIntPoint(), div_shape);
62  div_shape *= (1.0 / Trans.Weight());
63 }
64 
66  DenseMatrix &curl_shape) const
67 {
68  MFEM_ABORT("method is not implemented for this class");
69 }
70 
72  DenseMatrix &curl_shape) const
73 {
74  switch (dim)
75  {
76  case 3:
77  {
78 #ifdef MFEM_THREAD_SAFE
80 #endif
82  MultABt(vshape, Trans.Jacobian(), curl_shape);
83  curl_shape *= (1.0 / Trans.Weight());
84  break;
85  }
86  case 2:
87  // This is valid for both 2x2 and 3x2 Jacobians
88  CalcCurlShape(Trans.GetIntPoint(), curl_shape);
89  curl_shape *= (1.0 / Trans.Weight());
90  break;
91  default:
92  MFEM_ABORT("Invalid dimension, Dim = " << dim);
93  }
94 }
95 
96 void FiniteElement::GetFaceDofs(int face, int **dofs, int *ndofs) const
97 {
98  MFEM_ABORT("method is not overloaded");
99 }
100 
102  DenseMatrix &h) const
103 {
104  MFEM_ABORT("method is not overloaded");
105 }
106 
108  DenseMatrix &I) const
109 {
110  MFEM_ABORT("method is not overloaded");
111 }
112 
114  DenseMatrix &) const
115 {
116  MFEM_ABORT("method is not overloaded");
117 }
118 
121  DenseMatrix &I) const
122 {
123  MFEM_ABORT("method is not overloaded");
124 }
125 
127  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
128 {
129  MFEM_ABORT("method is not overloaded");
130 }
131 
134 {
135  MFEM_ABORT("method is not overloaded");
136 }
137 
139  Vector &dofs) const
140 {
141  mfem_error ("FiniteElement::ProjectFromNodes() (vector) is not overloaded!");
142 }
143 
145  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
146 {
147  MFEM_ABORT("method is not overloaded");
148 }
149 
150 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
151 {
152  MFEM_ABORT("method is not implemented for this element");
153 }
154 
157 {
158  MFEM_ABORT("method is not implemented for this element");
159 }
160 
163  DenseMatrix &grad) const
164 {
165  MFEM_ABORT("method is not implemented for this element");
166 }
167 
170  DenseMatrix &curl) const
171 {
172  MFEM_ABORT("method is not implemented for this element");
173 }
174 
177  DenseMatrix &div) const
178 {
179  MFEM_ABORT("method is not implemented for this element");
180 }
181 
183  Vector &shape) const
184 {
185  CalcShape(Trans.GetIntPoint(), shape);
186  if (map_type == INTEGRAL)
187  {
188  shape /= Trans.Weight();
189  }
190 }
191 
193  DenseMatrix &dshape) const
194 {
195  MFEM_ASSERT(map_type == VALUE, "");
196 #ifdef MFEM_THREAD_SAFE
198 #endif
199  CalcDShape(Trans.GetIntPoint(), vshape);
200  Mult(vshape, Trans.InverseJacobian(), dshape);
201 }
202 
204  Vector &Laplacian) const
205 {
206  MFEM_ASSERT(map_type == VALUE, "");
207 
208  // Simpler routine if mapping is affine
209  if (Trans.Hessian().FNorm2() < 1e-20)
210  {
211  CalcPhysLinLaplacian(Trans, Laplacian);
212  return;
213  }
214 
215  // Compute full Hessian first if non-affine
216  int size = (dim*(dim+1))/2;
217  DenseMatrix hess(dof, size);
218  CalcPhysHessian(Trans,hess);
219 
220  if (dim == 3)
221  {
222  for (int nd = 0; nd < dof; nd++)
223  {
224  Laplacian[nd] = hess(nd,0) + hess(nd,4) + hess(nd,5);
225  }
226  }
227  else if (dim == 2)
228  {
229  for (int nd = 0; nd < dof; nd++)
230  {
231  Laplacian[nd] = hess(nd,0) + hess(nd,2);
232  }
233  }
234  else
235  {
236  for (int nd = 0; nd < dof; nd++)
237  {
238  Laplacian[nd] = hess(nd,0);
239  }
240  }
241 }
242 
243 
244 // Assume a linear mapping
246  Vector &Laplacian) const
247 {
248  MFEM_ASSERT(map_type == VALUE, "");
249  int size = (dim*(dim+1))/2;
250  DenseMatrix hess(dof, size);
251  DenseMatrix Gij(dim,dim);
252  Vector scale(size);
253 
254  CalcHessian (Trans.GetIntPoint(), hess);
255  MultAAt(Trans.InverseJacobian(), Gij);
256 
257  if (dim == 3)
258  {
259  scale[0] = Gij(0,0);
260  scale[1] = 2*Gij(0,1);
261  scale[2] = 2*Gij(0,2);
262 
263  scale[3] = 2*Gij(1,2);
264  scale[4] = Gij(2,2);
265 
266  scale[5] = Gij(1,1);
267  }
268  else if (dim == 2)
269  {
270  scale[0] = Gij(0,0);
271  scale[1] = 2*Gij(0,1);
272  scale[2] = Gij(1,1);
273  }
274  else
275  {
276  scale[0] = Gij(0,0);
277  }
278 
279  for (int nd = 0; nd < dof; nd++)
280  {
281  Laplacian[nd] = 0.0;
282  for (int ii = 0; ii < size; ii++)
283  {
284  Laplacian[nd] += hess(nd,ii)*scale[ii];
285  }
286  }
287 
288 }
289 
291  DenseMatrix& Hessian) const
292 {
293  MFEM_ASSERT(map_type == VALUE, "");
294 
295  // Roll 2-Tensors in vectors and 4-Tensor in Matrix, exploiting symmetry
296  Array<int> map(dim*dim);
297  if (dim == 3)
298  {
299  map[0] = 0;
300  map[1] = 1;
301  map[2] = 2;
302 
303  map[3] = 1;
304  map[4] = 5;
305  map[5] = 3;
306 
307  map[6] = 2;
308  map[7] = 3;
309  map[8] = 4;
310  }
311  else if (dim == 2)
312  {
313  map[0] = 0;
314  map[1] = 1;
315 
316  map[2] = 1;
317  map[3] = 2;
318  }
319  else
320  {
321  map[0] = 0;
322  }
323 
324  // Hessian in ref coords
325  int size = (dim*(dim+1))/2;
326  DenseMatrix hess(dof, size);
327  CalcHessian(Trans.GetIntPoint(), hess);
328 
329  // Gradient in physical coords
330  if (Trans.Hessian().FNorm2() > 1e-10)
331  {
332  DenseMatrix grad(dof, dim);
333  CalcPhysDShape(Trans, grad);
334  DenseMatrix gmap(dof, size);
335  Mult(grad,Trans.Hessian(),gmap);
336  hess -= gmap;
337  }
338 
339  // LHM
340  DenseMatrix lhm(size,size);
341  DenseMatrix invJ = Trans.Jacobian();
342  lhm = 0.0;
343  for (int i = 0; i < dim; i++)
344  {
345  for (int j = 0; j < dim; j++)
346  {
347  for (int k = 0; k < dim; k++)
348  {
349  for (int l = 0; l < dim; l++)
350  {
351  lhm(map[i*dim+j],map[k*dim+l]) += invJ(i,k)*invJ(j,l);
352  }
353  }
354  }
355  }
356  // Correct multiplicity
357  Vector mult(size);
358  mult = 0.0;
359  for (int i = 0; i < dim*dim; i++) { mult[map[i]]++; }
360  lhm.InvRightScaling(mult);
361 
362  // Hessian in physical coords
363  lhm.Invert();
364  Mult( hess, lhm, Hessian);
365 }
366 
368  DofToQuad::Mode) const
369 {
370  MFEM_ABORT("method is not implemented for this element");
371  return *dof2quad_array[0]; // suppress a warning
372 }
373 
375 {
376  for (int i = 0; i < dof2quad_array.Size(); i++)
377  {
378  delete dof2quad_array[i];
379  }
380 }
381 
382 
385  const ScalarFiniteElement &fine_fe) const
386 {
387  double v[Geometry::MaxDim];
388  Vector vv (v, dim);
389  IntegrationPoint f_ip;
390 
391 #ifdef MFEM_THREAD_SAFE
392  Vector c_shape(dof);
393 #endif
394 
395  MFEM_ASSERT(map_type == fine_fe.GetMapType(), "");
396 
397  I.SetSize(fine_fe.dof, dof);
398  for (int i = 0; i < fine_fe.dof; i++)
399  {
400  Trans.Transform(fine_fe.Nodes.IntPoint(i), vv);
401  f_ip.Set(v, dim);
402  CalcShape(f_ip, c_shape);
403  for (int j = 0; j < dof; j++)
404  {
405  if (fabs(I(i,j) = c_shape(j)) < 1.0e-12)
406  {
407  I(i,j) = 0.0;
408  }
409  }
410  }
411  if (map_type == INTEGRAL)
412  {
413  // assuming Trans is linear; this should be ok for all refinement types
415  I *= Trans.Weight();
416  }
417 }
418 
421  const ScalarFiniteElement &fine_fe) const
422 {
423  // General "interpolation", defined by L2 projection
424 
425  double v[Geometry::MaxDim];
426  Vector vv (v, dim);
427  IntegrationPoint f_ip;
428 
429  const int fs = fine_fe.GetDof(), cs = this->GetDof();
430  I.SetSize(fs, cs);
431  Vector fine_shape(fs), coarse_shape(cs);
432  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
433  const int ir_order =
434  std::max(GetOrder(), fine_fe.GetOrder()) + fine_fe.GetOrder();
435  const IntegrationRule &ir = IntRules.Get(fine_fe.GetGeomType(), ir_order);
436 
437  for (int i = 0; i < ir.GetNPoints(); i++)
438  {
439  const IntegrationPoint &ip = ir.IntPoint(i);
440  fine_fe.CalcShape(ip, fine_shape);
441  Trans.Transform(ip, vv);
442  f_ip.Set(v, dim);
443  this->CalcShape(f_ip, coarse_shape);
444 
445  AddMult_a_VVt(ip.weight, fine_shape, fine_mass);
446  AddMult_a_VWt(ip.weight, fine_shape, coarse_shape, fine_coarse_mass);
447  }
448 
449  DenseMatrixInverse fine_mass_inv(fine_mass);
450  fine_mass_inv.Mult(fine_coarse_mass, I);
451 
452  if (map_type == INTEGRAL)
453  {
454  // assuming Trans is linear; this should be ok for all refinement types
456  I *= Trans.Weight();
457  }
458 }
459 
462  const ScalarFiniteElement &coarse_fe) const
463 {
464  // General "restriction", defined by L2 projection
465  double v[Geometry::MaxDim];
466  Vector vv (v, dim);
467  IntegrationPoint f_ip;
468 
469  const int cs = coarse_fe.GetDof(), fs = this->GetDof();
470  R.SetSize(cs, fs);
471  Vector fine_shape(fs), coarse_shape(cs);
472  DenseMatrix coarse_mass(cs), coarse_fine_mass(cs, fs); // initialized with 0
473  const int ir_order = GetOrder() + coarse_fe.GetOrder();
474  const IntegrationRule &ir = IntRules.Get(coarse_fe.GetGeomType(), ir_order);
475 
476  for (int i = 0; i < ir.GetNPoints(); i++)
477  {
478  const IntegrationPoint &ip = ir.IntPoint(i);
479  this->CalcShape(ip, fine_shape);
480  Trans.Transform(ip, vv);
481  f_ip.Set(v, dim);
482  coarse_fe.CalcShape(f_ip, coarse_shape);
483 
484  AddMult_a_VVt(ip.weight, coarse_shape, coarse_mass);
485  AddMult_a_VWt(ip.weight, coarse_shape, fine_shape, coarse_fine_mass);
486  }
487 
488  DenseMatrixInverse coarse_mass_inv(coarse_mass);
489  coarse_mass_inv.Mult(coarse_fine_mass, R);
490 
491  if (map_type == INTEGRAL)
492  {
493  // assuming Trans is linear; this should be ok for all refinement types
495  R *= 1.0 / Trans.Weight();
496  }
497 }
498 
500  DofToQuad::Mode mode) const
501 {
502  MFEM_VERIFY(mode == DofToQuad::FULL, "invalid mode requested");
503 
504  for (int i = 0; i < dof2quad_array.Size(); i++)
505  {
506  const DofToQuad &d2q = *dof2quad_array[i];
507  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
508  }
509 
510  DofToQuad *d2q = new DofToQuad;
511  const int nqpt = ir.GetNPoints();
512  d2q->FE = this;
513  d2q->IntRule = &ir;
514  d2q->mode = mode;
515  d2q->ndof = dof;
516  d2q->nqpt = nqpt;
517  d2q->B.SetSize(nqpt*dof);
518  d2q->Bt.SetSize(dof*nqpt);
519  d2q->G.SetSize(nqpt*dim*dof);
520  d2q->Gt.SetSize(dof*nqpt*dim);
521 #ifdef MFEM_THREAD_SAFE
522  Vector c_shape(dof);
523  DenseMatrix vshape(dof, dim);
524 #endif
525  for (int i = 0; i < nqpt; i++)
526  {
527  const IntegrationPoint &ip = ir.IntPoint(i);
528  CalcShape(ip, c_shape);
529  for (int j = 0; j < dof; j++)
530  {
531  d2q->B[i+nqpt*j] = d2q->Bt[j+dof*i] = c_shape(j);
532  }
533  CalcDShape(ip, vshape);
534  for (int d = 0; d < dim; d++)
535  {
536  for (int j = 0; j < dof; j++)
537  {
538  d2q->G[i+nqpt*(d+dim*j)] = d2q->Gt[j+dof*(i+nqpt*d)] = vshape(j,d);
539  }
540  }
541  }
542  dof2quad_array.Append(d2q);
543  return *d2q;
544 }
545 
546 // protected method
548  const TensorBasisElement &tb,
549  const IntegrationRule &ir, DofToQuad::Mode mode) const
550 {
551  MFEM_VERIFY(mode == DofToQuad::TENSOR, "invalid mode requested");
552 
553  for (int i = 0; i < dof2quad_array.Size(); i++)
554  {
555  const DofToQuad &d2q = *dof2quad_array[i];
556  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
557  }
558 
559  DofToQuad *d2q = new DofToQuad;
560  const Poly_1D::Basis &basis_1d = tb.GetBasis1D();
561  const int ndof = order + 1;
562  const int nqpt = (int)floor(pow(ir.GetNPoints(), 1.0/dim) + 0.5);
563  d2q->FE = this;
564  d2q->IntRule = &ir;
565  d2q->mode = mode;
566  d2q->ndof = ndof;
567  d2q->nqpt = nqpt;
568  d2q->B.SetSize(nqpt*ndof);
569  d2q->Bt.SetSize(ndof*nqpt);
570  d2q->G.SetSize(nqpt*ndof);
571  d2q->Gt.SetSize(ndof*nqpt);
572  Vector val(ndof), grad(ndof);
573  for (int i = 0; i < nqpt; i++)
574  {
575  // The first 'nqpt' points in 'ir' have the same x-coordinates as those
576  // of the 1D rule.
577  basis_1d.Eval(ir.IntPoint(i).x, val, grad);
578  for (int j = 0; j < ndof; j++)
579  {
580  d2q->B[i+nqpt*j] = d2q->Bt[j+ndof*i] = val(j);
581  d2q->G[i+nqpt*j] = d2q->Gt[j+ndof*i] = grad(j);
582  }
583  }
584  dof2quad_array.Append(d2q);
585  return *d2q;
586 }
587 
588 
591  DenseMatrix &curl) const
592 {
593  DenseMatrix curl_shape(fe.GetDof(), 1);
594 
595  curl.SetSize(dof, fe.GetDof());
596  for (int i = 0; i < dof; i++)
597  {
598  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
599 
600  double w = 1.0;
602  {
603  Trans.SetIntPoint(&Nodes.IntPoint(i));
604  w /= Trans.Weight();
605  }
606  for (int j = 0; j < fe.GetDof(); j++)
607  {
608  curl(i,j) = w * curl_shape(j,0);
609  }
610  }
611 }
612 
614  const IntegrationPoint &pt, Vector &x)
615 {
616  // invert a linear transform with one Newton step
617  IntegrationPoint p0;
618  p0.Set3(0, 0, 0);
619  trans.Transform(p0, x);
620 
621  double store[3];
622  Vector v(store, x.Size());
623  pt.Get(v, x.Size());
624  v -= x;
625 
626  trans.InverseJacobian().Mult(v, x);
627 }
628 
630  DenseMatrix &R) const
631 {
632  IntegrationPoint ipt;
633  Vector pt(&ipt.x, dim);
634 
635 #ifdef MFEM_THREAD_SAFE
636  Vector c_shape(dof);
637 #endif
638 
639  Trans.SetIntPoint(&Nodes[0]);
640 
641  for (int j = 0; j < dof; j++)
642  {
643  InvertLinearTrans(Trans, Nodes[j], pt);
644  if (Geometries.CheckPoint(geom_type, ipt)) // do we need an epsilon here?
645  {
646  CalcShape(ipt, c_shape);
647  R.SetRow(j, c_shape);
648  }
649  else
650  {
651  // Set the whole row to avoid valgrind warnings in R.Threshold().
652  R.SetRow(j, infinity());
653  }
654  }
655  R.Threshold(1e-12);
656 }
657 
659  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
660 {
661  for (int i = 0; i < dof; i++)
662  {
663  const IntegrationPoint &ip = Nodes.IntPoint(i);
664  // some coefficients expect that Trans.IntPoint is the same
665  // as the second argument of Eval
666  Trans.SetIntPoint(&ip);
667  dofs(i) = coeff.Eval (Trans, ip);
668  if (map_type == INTEGRAL)
669  {
670  dofs(i) *= Trans.Weight();
671  }
672  }
673 }
674 
677 {
678  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*dof, "");
679  Vector x(vc.GetVDim());
680 
681  for (int i = 0; i < dof; i++)
682  {
683  const IntegrationPoint &ip = Nodes.IntPoint(i);
684  Trans.SetIntPoint(&ip);
685  vc.Eval (x, Trans, ip);
686  if (map_type == INTEGRAL)
687  {
688  x *= Trans.Weight();
689  }
690  for (int j = 0; j < x.Size(); j++)
691  {
692  dofs(dof*j+i) = x(j);
693  }
694  }
695 }
696 
698  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
699 {
700  // (mc.height x mc.width) @ DOFs -> (dof x mc.width x mc.height) in dofs
701  MFEM_ASSERT(dofs.Size() == mc.GetHeight()*mc.GetWidth()*dof, "");
702  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
703 
704  for (int k = 0; k < dof; k++)
705  {
706  T.SetIntPoint(&Nodes.IntPoint(k));
707  mc.Eval(MQ, T, Nodes.IntPoint(k));
708  if (map_type == INTEGRAL) { MQ *= T.Weight(); }
709  for (int r = 0; r < MQ.Height(); r++)
710  {
711  for (int d = 0; d < MQ.Width(); d++)
712  {
713  dofs(k+dof*(d+MQ.Width()*r)) = MQ(r,d);
714  }
715  }
716  }
717 }
718 
721 {
722  if (fe.GetRangeType() == SCALAR)
723  {
724  Vector shape(fe.GetDof());
725 
726  I.SetSize(dof, fe.GetDof());
727  if (map_type == fe.GetMapType())
728  {
729  for (int k = 0; k < dof; k++)
730  {
731  fe.CalcShape(Nodes.IntPoint(k), shape);
732  for (int j = 0; j < shape.Size(); j++)
733  {
734  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
735  }
736  }
737  }
738  else
739  {
740  for (int k = 0; k < dof; k++)
741  {
742  Trans.SetIntPoint(&Nodes.IntPoint(k));
743  fe.CalcPhysShape(Trans, shape);
744  if (map_type == INTEGRAL)
745  {
746  shape *= Trans.Weight();
747  }
748  for (int j = 0; j < shape.Size(); j++)
749  {
750  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
751  }
752  }
753  }
754  }
755  else
756  {
757  DenseMatrix vshape(fe.GetDof(), Trans.GetSpaceDim());
758 
759  I.SetSize(vshape.Width()*dof, fe.GetDof());
760  for (int k = 0; k < dof; k++)
761  {
762  Trans.SetIntPoint(&Nodes.IntPoint(k));
763  fe.CalcVShape(Trans, vshape);
764  if (map_type == INTEGRAL)
765  {
766  vshape *= Trans.Weight();
767  }
768  for (int j = 0; j < vshape.Height(); j++)
769  for (int d = 0; d < vshape.Width(); d++)
770  {
771  I(k+d*dof,j) = vshape(j,d);
772  }
773  }
774  }
775 }
776 
779  DenseMatrix &grad) const
780 {
781  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
782  MFEM_ASSERT(Trans.GetSpaceDim() == dim, "")
783 
784  DenseMatrix dshape(fe.GetDof(), dim), grad_k(fe.GetDof(), dim), Jinv(dim);
785 
786  grad.SetSize(dim*dof, fe.GetDof());
787  for (int k = 0; k < dof; k++)
788  {
789  const IntegrationPoint &ip = Nodes.IntPoint(k);
790  fe.CalcDShape(ip, dshape);
791  Trans.SetIntPoint(&ip);
792  CalcInverse(Trans.Jacobian(), Jinv);
793  Mult(dshape, Jinv, grad_k);
794  if (map_type == INTEGRAL)
795  {
796  grad_k *= Trans.Weight();
797  }
798  for (int j = 0; j < grad_k.Height(); j++)
799  for (int d = 0; d < dim; d++)
800  {
801  grad(k+d*dof,j) = grad_k(j,d);
802  }
803  }
804 }
805 
808  DenseMatrix &div) const
809 {
810  double detJ;
811  Vector div_shape(fe.GetDof());
812 
813  div.SetSize(dof, fe.GetDof());
814  for (int k = 0; k < dof; k++)
815  {
816  const IntegrationPoint &ip = Nodes.IntPoint(k);
817  fe.CalcDivShape(ip, div_shape);
818  if (map_type == VALUE)
819  {
820  Trans.SetIntPoint(&ip);
821  detJ = Trans.Weight();
822  for (int j = 0; j < div_shape.Size(); j++)
823  {
824  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
825  }
826  }
827  else
828  {
829  for (int j = 0; j < div_shape.Size(); j++)
830  {
831  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
832  }
833  }
834  }
835 }
836 
837 
839  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
840 {
841  for (int i = 0; i < dof; i++)
842  {
843  const IntegrationPoint &ip = Nodes.IntPoint(i);
844  Trans.SetIntPoint(&ip);
845  dofs(i) = coeff.Eval(Trans, ip);
846  }
847 }
848 
851 {
852  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*dof, "");
853  Vector x(vc.GetVDim());
854 
855  for (int i = 0; i < dof; i++)
856  {
857  const IntegrationPoint &ip = Nodes.IntPoint(i);
858  Trans.SetIntPoint(&ip);
859  vc.Eval (x, Trans, ip);
860  for (int j = 0; j < x.Size(); j++)
861  {
862  dofs(dof*j+i) = x(j);
863  }
864  }
865 }
866 
869 {
870  const NodalFiniteElement *nfe =
871  dynamic_cast<const NodalFiniteElement *>(&fe);
872 
873  if (nfe && dof == nfe->GetDof())
874  {
875  nfe->Project(*this, Trans, I);
876  I.Invert();
877  }
878  else
879  {
880  // local L2 projection
881  DenseMatrix pos_mass, mixed_mass;
882  MassIntegrator mass_integ;
883 
884  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
885  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
886 
887  DenseMatrixInverse pos_mass_inv(pos_mass);
888  I.SetSize(dof, fe.GetDof());
889  pos_mass_inv.Mult(mixed_mass, I);
890  }
891 }
892 
893 
894 void VectorFiniteElement::CalcShape (
895  const IntegrationPoint &ip, Vector &shape ) const
896 {
897  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
898  " VectorFiniteElements!");
899 }
900 
901 void VectorFiniteElement::CalcDShape (
902  const IntegrationPoint &ip, DenseMatrix &dshape ) const
903 {
904  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
905  " VectorFiniteElements!");
906 }
907 
909 {
910  switch (map_type)
911  {
912  case H_DIV:
913  deriv_type = DIV;
916  break;
917  case H_CURL:
918  switch (dim)
919  {
920  case 3: // curl: 3D H_CURL -> 3D H_DIV
921  deriv_type = CURL;
924  break;
925  case 2:
926  // curl: 2D H_CURL -> INTEGRAL
927  deriv_type = CURL;
930  break;
931  case 1:
932  deriv_type = NONE;
935  break;
936  default:
937  MFEM_ABORT("Invalid dimension, Dim = " << dim);
938  }
939  break;
940  default:
941  MFEM_ABORT("Invalid MapType = " << map_type);
942  }
943 }
944 
946  ElementTransformation &Trans, DenseMatrix &shape) const
947 {
948  MFEM_ASSERT(map_type == H_DIV, "");
949 #ifdef MFEM_THREAD_SAFE
951 #endif
952  CalcVShape(Trans.GetIntPoint(), vshape);
953  MultABt(vshape, Trans.Jacobian(), shape);
954  shape *= (1.0 / Trans.Weight());
955 }
956 
958  ElementTransformation &Trans, DenseMatrix &shape) const
959 {
960  MFEM_ASSERT(map_type == H_CURL, "");
961 #ifdef MFEM_THREAD_SAFE
963 #endif
964  CalcVShape(Trans.GetIntPoint(), vshape);
965  Mult(vshape, Trans.InverseJacobian(), shape);
966 }
967 
969  const double *nk, const Array<int> &d2n,
971 {
972  double vk[Geometry::MaxDim];
973  const int sdim = Trans.GetSpaceDim();
974  MFEM_ASSERT(vc.GetVDim() == sdim, "");
975  Vector xk(vk, sdim);
976  const bool square_J = (dim == sdim);
977 
978  for (int k = 0; k < dof; k++)
979  {
980  Trans.SetIntPoint(&Nodes.IntPoint(k));
981  vc.Eval(xk, Trans, Nodes.IntPoint(k));
982  // dof_k = nk^t adj(J) xk
983  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*dim);
984  if (!square_J) { dofs(k) /= Trans.Weight(); }
985  }
986 }
987 
989  const double *nk, const Array<int> &d2n,
990  Vector &vc, ElementTransformation &Trans, Vector &dofs) const
991 {
992  const int sdim = Trans.GetSpaceDim();
993  const bool square_J = (dim == sdim);
994 
995  for (int k = 0; k < dof; k++)
996  {
997  Trans.SetIntPoint(&Nodes.IntPoint(k));
998  // dof_k = nk^t adj(J) xk
999  Vector vk(vc.GetData()+k*sdim, sdim);
1000  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*dim);
1001  if (!square_J) { dofs(k) /= Trans.Weight(); }
1002  }
1003 }
1004 
1006  const double *nk, const Array<int> &d2n,
1007  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
1008 {
1009  // project the rows of the matrix coefficient in an RT space
1010 
1011  const int sdim = T.GetSpaceDim();
1012  MFEM_ASSERT(mc.GetWidth() == sdim, "");
1013  const bool square_J = (dim == sdim);
1014  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
1015  Vector nk_phys(sdim), dofs_k(MQ.Height());
1016  MFEM_ASSERT(dofs.Size() == dof*MQ.Height(), "");
1017 
1018  for (int k = 0; k < dof; k++)
1019  {
1020  T.SetIntPoint(&Nodes.IntPoint(k));
1021  mc.Eval(MQ, T, Nodes.IntPoint(k));
1022  // nk_phys = adj(J)^t nk
1023  T.AdjugateJacobian().MultTranspose(nk + d2n[k]*dim, nk_phys);
1024  if (!square_J) { nk_phys /= T.Weight(); }
1025  MQ.Mult(nk_phys, dofs_k);
1026  for (int r = 0; r < MQ.Height(); r++)
1027  {
1028  dofs(k+dof*r) = dofs_k(r);
1029  }
1030  }
1031 }
1032 
1034  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
1036 {
1037  if (fe.GetRangeType() == SCALAR)
1038  {
1039  double vk[Geometry::MaxDim];
1040  Vector shape(fe.GetDof());
1041  int sdim = Trans.GetSpaceDim();
1042 
1043  I.SetSize(dof, sdim*fe.GetDof());
1044  for (int k = 0; k < dof; k++)
1045  {
1046  const IntegrationPoint &ip = Nodes.IntPoint(k);
1047 
1048  fe.CalcShape(ip, shape);
1049  Trans.SetIntPoint(&ip);
1050  // Transform RT face normals from reference to physical space
1051  // vk = adj(J)^T nk
1052  Trans.AdjugateJacobian().MultTranspose(nk + d2n[k]*dim, vk);
1053  if (fe.GetMapType() == INTEGRAL)
1054  {
1055  double w = 1.0/Trans.Weight();
1056  for (int d = 0; d < dim; d++)
1057  {
1058  vk[d] *= w;
1059  }
1060  }
1061 
1062  for (int j = 0; j < shape.Size(); j++)
1063  {
1064  double s = shape(j);
1065  if (fabs(s) < 1e-12)
1066  {
1067  s = 0.0;
1068  }
1069  // Project scalar basis function multiplied by each coordinate
1070  // direction onto the transformed face normals
1071  for (int d = 0; d < sdim; d++)
1072  {
1073  I(k,j+d*shape.Size()) = s*vk[d];
1074  }
1075  }
1076  }
1077  }
1078  else
1079  {
1080  int sdim = Trans.GetSpaceDim();
1081  double vk[Geometry::MaxDim];
1082  DenseMatrix vshape(fe.GetDof(), sdim);
1083  Vector vshapenk(fe.GetDof());
1084  const bool square_J = (dim == sdim);
1085 
1086  I.SetSize(dof, fe.GetDof());
1087  for (int k = 0; k < dof; k++)
1088  {
1089  const IntegrationPoint &ip = Nodes.IntPoint(k);
1090 
1091  Trans.SetIntPoint(&ip);
1092  // Transform RT face normals from reference to physical space
1093  // vk = adj(J)^T nk
1094  Trans.AdjugateJacobian().MultTranspose(nk + d2n[k]*dim, vk);
1095  // Compute fe basis functions in physical space
1096  fe.CalcVShape(Trans, vshape);
1097  // Project fe basis functions onto transformed face normals
1098  vshape.Mult(vk, vshapenk);
1099  if (!square_J) { vshapenk /= Trans.Weight(); }
1100  for (int j=0; j<vshapenk.Size(); j++)
1101  {
1102  I(k,j) = vshapenk(j);
1103  }
1104  }
1105  }
1106 }
1107 
1109  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
1110  ElementTransformation &Trans, DenseMatrix &grad) const
1111 {
1112  if (dim != 2)
1113  {
1114  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
1115  }
1116 
1117  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
1118  Vector grad_k(fe.GetDof());
1119  double tk[2];
1120 
1121  grad.SetSize(dof, fe.GetDof());
1122  for (int k = 0; k < dof; k++)
1123  {
1124  fe.CalcDShape(Nodes.IntPoint(k), dshape);
1125  tk[0] = nk[d2n[k]*dim+1];
1126  tk[1] = -nk[d2n[k]*dim];
1127  dshape.Mult(tk, grad_k);
1128  for (int j = 0; j < grad_k.Size(); j++)
1129  {
1130  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1131  }
1132  }
1133 }
1134 
1136  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1137  ElementTransformation &Trans, DenseMatrix &curl) const
1138 {
1139 #ifdef MFEM_THREAD_SAFE
1142  DenseMatrix J(dim, dim);
1143 #else
1144  curlshape.SetSize(fe.GetDof(), dim);
1145  curlshape_J.SetSize(fe.GetDof(), dim);
1146  J.SetSize(dim, dim);
1147 #endif
1148 
1149  Vector curl_k(fe.GetDof());
1150 
1151  curl.SetSize(dof, fe.GetDof());
1152  for (int k = 0; k < dof; k++)
1153  {
1154  const IntegrationPoint &ip = Nodes.IntPoint(k);
1155 
1156  // calculate J^t * J / |J|
1157  Trans.SetIntPoint(&ip);
1158  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
1159  J *= 1.0 / Trans.Weight();
1160 
1161  // transform curl of shapes (rows) by J^t * J / |J|
1162  fe.CalcCurlShape(ip, curlshape);
1163  Mult(curlshape, J, curlshape_J);
1164 
1165  curlshape_J.Mult(tk + d2t[k]*dim, curl_k);
1166  for (int j = 0; j < curl_k.Size(); j++)
1167  {
1168  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
1169  }
1170  }
1171 }
1172 
1174  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
1175  ElementTransformation &Trans, DenseMatrix &curl) const
1176 {
1177  DenseMatrix curl_shape(fe.GetDof(), dim);
1178  Vector curl_k(fe.GetDof());
1179 
1180  curl.SetSize(dof, fe.GetDof());
1181  for (int k = 0; k < dof; k++)
1182  {
1183  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
1184  curl_shape.Mult(nk + d2n[k]*dim, curl_k);
1185  for (int j = 0; j < curl_k.Size(); j++)
1186  {
1187  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
1188  }
1189  }
1190 }
1191 
1193  const double *tk, const Array<int> &d2t,
1195 {
1196  double vk[Geometry::MaxDim];
1197  Vector xk(vk, vc.GetVDim());
1198 
1199  for (int k = 0; k < dof; k++)
1200  {
1201  Trans.SetIntPoint(&Nodes.IntPoint(k));
1202 
1203  vc.Eval(xk, Trans, Nodes.IntPoint(k));
1204  // dof_k = xk^t J tk
1205  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*dim, vk);
1206  }
1207 }
1208 
1210  const double *tk, const Array<int> &d2t,
1211  Vector &vc, ElementTransformation &Trans, Vector &dofs) const
1212 {
1213  for (int k = 0; k < dof; k++)
1214  {
1215  Trans.SetIntPoint(&Nodes.IntPoint(k));
1216  Vector vk(vc.GetData()+k*dim, dim);
1217  // dof_k = xk^t J tk
1218  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*dim, vk);
1219  }
1220 }
1221 
1223  const double *tk, const Array<int> &d2t,
1224  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
1225 {
1226  // project the rows of the matrix coefficient in an ND space
1227 
1228  const int sdim = T.GetSpaceDim();
1229  MFEM_ASSERT(mc.GetWidth() == sdim, "");
1230  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
1231  Vector tk_phys(sdim), dofs_k(MQ.Height());
1232  MFEM_ASSERT(dofs.Size() == dof*MQ.Height(), "");
1233 
1234  for (int k = 0; k < dof; k++)
1235  {
1236  T.SetIntPoint(&Nodes.IntPoint(k));
1237  mc.Eval(MQ, T, Nodes.IntPoint(k));
1238  // tk_phys = J tk
1239  T.Jacobian().Mult(tk + d2t[k]*dim, tk_phys);
1240  MQ.Mult(tk_phys, dofs_k);
1241  for (int r = 0; r < MQ.Height(); r++)
1242  {
1243  dofs(k+dof*r) = dofs_k(r);
1244  }
1245  }
1246 }
1247 
1249  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1251 {
1252  if (fe.GetRangeType() == SCALAR)
1253  {
1254  int sdim = Trans.GetSpaceDim();
1255  double vk[Geometry::MaxDim];
1256  Vector shape(fe.GetDof());
1257 
1258  I.SetSize(dof, sdim*fe.GetDof());
1259  for (int k = 0; k < dof; k++)
1260  {
1261  const IntegrationPoint &ip = Nodes.IntPoint(k);
1262 
1263  fe.CalcShape(ip, shape);
1264  Trans.SetIntPoint(&ip);
1265  // Transform ND edge tengents from reference to physical space
1266  // vk = J tk
1267  Trans.Jacobian().Mult(tk + d2t[k]*dim, vk);
1268  if (fe.GetMapType() == INTEGRAL)
1269  {
1270  double w = 1.0/Trans.Weight();
1271  for (int d = 0; d < sdim; d++)
1272  {
1273  vk[d] *= w;
1274  }
1275  }
1276 
1277  for (int j = 0; j < shape.Size(); j++)
1278  {
1279  double s = shape(j);
1280  if (fabs(s) < 1e-12)
1281  {
1282  s = 0.0;
1283  }
1284  // Project scalar basis function multiplied by each coordinate
1285  // direction onto the transformed edge tangents
1286  for (int d = 0; d < sdim; d++)
1287  {
1288  I(k, j + d*shape.Size()) = s*vk[d];
1289  }
1290  }
1291  }
1292  }
1293  else
1294  {
1295  int sdim = Trans.GetSpaceDim();
1296  double vk[Geometry::MaxDim];
1297  DenseMatrix vshape(fe.GetDof(), sdim);
1298  Vector vshapetk(fe.GetDof());
1299 
1300  I.SetSize(dof, fe.GetDof());
1301  for (int k = 0; k < dof; k++)
1302  {
1303  const IntegrationPoint &ip = Nodes.IntPoint(k);
1304 
1305  Trans.SetIntPoint(&ip);
1306  // Transform ND edge tangents from reference to physical space
1307  // vk = J tk
1308  Trans.Jacobian().Mult(tk + d2t[k]*dim, vk);
1309  // Compute fe basis functions in physical space
1310  fe.CalcVShape(Trans, vshape);
1311  // Project fe basis functions onto transformed edge tangents
1312  vshape.Mult(vk, vshapetk);
1313  for (int j=0; j<vshapetk.Size(); j++)
1314  {
1315  I(k, j) = vshapetk(j);
1316  }
1317  }
1318  }
1319 }
1320 
1322  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1323  ElementTransformation &Trans, DenseMatrix &grad) const
1324 {
1325  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
1326 
1327  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
1328  Vector grad_k(fe.GetDof());
1329 
1330  grad.SetSize(dof, fe.GetDof());
1331  for (int k = 0; k < dof; k++)
1332  {
1333  fe.CalcDShape(Nodes.IntPoint(k), dshape);
1334  dshape.Mult(tk + d2t[k]*dim, grad_k);
1335  for (int j = 0; j < grad_k.Size(); j++)
1336  {
1337  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1338  }
1339  }
1340 }
1341 
1344  DenseMatrix &I) const
1345 {
1346  Vector v(dim);
1347  IntegrationPoint tr_ip;
1348 
1349  const int fs = dof, cs = cfe.GetDof();
1350  I.SetSize(fs, cs);
1351  DenseMatrix fine_shape(fs, dim), coarse_shape(cs, cfe.GetDim());
1352  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
1353  const int ir_order =
1354  std::max(GetOrder(), this->GetOrder()) + this->GetOrder();
1355  const IntegrationRule &ir = IntRules.Get(this->GetGeomType(), ir_order);
1356 
1358  const DenseMatrix &adjJ = Trans.AdjugateJacobian();
1359  for (int i = 0; i < ir.GetNPoints(); i++)
1360  {
1361  const IntegrationPoint &ip = ir.IntPoint(i);
1362  double w = ip.weight;
1363  this->CalcVShape(ip, fine_shape);
1364  Trans.Transform(ip, v);
1365  tr_ip.Set(v, dim);
1366  cfe.CalcVShape(tr_ip, coarse_shape);
1367 
1368  AddMult_a_AAt(w, fine_shape, fine_mass);
1369  for (int k=0; k<fs; ++k)
1370  {
1371  for (int j=0; j<cs; ++j)
1372  {
1373  double Mkj = 0.0;
1374  for (int d1=0; d1<dim; ++d1)
1375  {
1376  for (int d2=0; d2<dim; ++d2)
1377  {
1378  Mkj += w*fine_shape(k,d1)*adjJ(d2,d1)*coarse_shape(j,d2);
1379  }
1380  }
1381  fine_coarse_mass(k,j) += (fabs(Mkj) < 1e-12) ? 0.0 : Mkj;
1382  }
1383  }
1384  }
1385  DenseMatrixInverse fine_mass_inv(fine_mass);
1386  fine_mass_inv.Mult(fine_coarse_mass, I);
1387 }
1388 
1390  const VectorFiniteElement &cfe, const double *nk, const Array<int> &d2n,
1392 {
1393  MFEM_ASSERT(map_type == cfe.GetMapType(), "");
1394 
1395  if (!is_nodal) { return LocalL2Projection_RT(cfe, Trans, I); }
1396 
1397  double vk[Geometry::MaxDim];
1398  Vector xk(vk, dim);
1399  IntegrationPoint ip;
1400 #ifdef MFEM_THREAD_SAFE
1401  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
1402 #else
1403  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
1404 #endif
1405  I.SetSize(dof, vshape.Height());
1406 
1407  // assuming Trans is linear; this should be ok for all refinement types
1409  const DenseMatrix &adjJ = Trans.AdjugateJacobian();
1410  for (int k = 0; k < dof; k++)
1411  {
1412  Trans.Transform(Nodes.IntPoint(k), xk);
1413  ip.Set3(vk);
1414  cfe.CalcVShape(ip, vshape);
1415  // xk = |J| J^{-t} n_k
1416  adjJ.MultTranspose(nk + d2n[k]*dim, vk);
1417  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,dof
1418  for (int j = 0; j < vshape.Height(); j++)
1419  {
1420  double Ikj = 0.;
1421  for (int i = 0; i < dim; i++)
1422  {
1423  Ikj += vshape(j, i) * vk[i];
1424  }
1425  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1426  }
1427  }
1428 }
1429 
1431  const VectorFiniteElement &cfe,
1433 {
1434  Vector v(dim);
1435  IntegrationPoint tr_ip;
1436 
1437  const int fs = dof, cs = cfe.GetDof();
1438  I.SetSize(fs, cs);
1439  DenseMatrix fine_shape(fs, dim), coarse_shape(cs, cfe.GetDim());
1440  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
1441  const int ir_order =
1442  std::max(GetOrder(), this->GetOrder()) + this->GetOrder();
1443  const IntegrationRule &ir = IntRules.Get(this->GetGeomType(), ir_order);
1444 
1446  const DenseMatrix &J = Trans.Jacobian();
1447  for (int i = 0; i < ir.GetNPoints(); i++)
1448  {
1449  const IntegrationPoint &ip = ir.IntPoint(i);
1450  this->CalcVShape(ip, fine_shape);
1451  Trans.Transform(ip, v);
1452  tr_ip.Set(v, dim);
1453  cfe.CalcVShape(tr_ip, coarse_shape);
1454 
1455  AddMult_a_AAt(ip.weight, fine_shape, fine_mass);
1456  for (int k=0; k<fs; ++k)
1457  {
1458  for (int j=0; j<cs; ++j)
1459  {
1460  double Mkj = 0.0;
1461  for (int d1=0; d1<dim; ++d1)
1462  {
1463  for (int d2=0; d2<dim; ++d2)
1464  {
1465  Mkj += ip.weight*fine_shape(k,d1)*J(d1,d2)*coarse_shape(j,d2);
1466  }
1467  }
1468  fine_coarse_mass(k,j) += (fabs(Mkj) < 1e-12) ? 0.0 : Mkj;
1469  }
1470  }
1471  }
1472  DenseMatrixInverse fine_mass_inv(fine_mass);
1473  fine_mass_inv.Mult(fine_coarse_mass, I);
1474 }
1475 
1477  const VectorFiniteElement &cfe, const double *tk, const Array<int> &d2t,
1479 {
1480  if (!is_nodal) { return LocalL2Projection_ND(cfe, Trans, I); }
1481 
1482  double vk[Geometry::MaxDim];
1483  Vector xk(vk, dim);
1484  IntegrationPoint ip;
1485 #ifdef MFEM_THREAD_SAFE
1486  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
1487 #else
1488  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
1489 #endif
1490  I.SetSize(dof, vshape.Height());
1491 
1492  // assuming Trans is linear; this should be ok for all refinement types
1494  const DenseMatrix &J = Trans.Jacobian();
1495  for (int k = 0; k < dof; k++)
1496  {
1497  Trans.Transform(Nodes.IntPoint(k), xk);
1498  ip.Set3(vk);
1499  cfe.CalcVShape(ip, vshape);
1500  // xk = J t_k
1501  J.Mult(tk + d2t[k]*dim, vk);
1502  // I_k = vshape_k.J.t_k, k=1,...,Dof
1503  for (int j = 0; j < vshape.Height(); j++)
1504  {
1505  double Ikj = 0.;
1506  for (int i = 0; i < dim; i++)
1507  {
1508  Ikj += vshape(j, i) * vk[i];
1509  }
1510  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1511  }
1512  }
1513 }
1514 
1516  const double *nk, const Array<int> &d2n, ElementTransformation &Trans,
1517  DenseMatrix &R) const
1518 {
1519  double pt_data[Geometry::MaxDim];
1520  IntegrationPoint ip;
1521  Vector pt(pt_data, dim);
1522 
1523 #ifdef MFEM_THREAD_SAFE
1525 #endif
1526 
1528  const DenseMatrix &J = Trans.Jacobian();
1529  const double weight = Trans.Weight();
1530  for (int j = 0; j < dof; j++)
1531  {
1532  InvertLinearTrans(Trans, Nodes.IntPoint(j), pt);
1533  ip.Set(pt_data, dim);
1534  if (Geometries.CheckPoint(geom_type, ip)) // do we need an epsilon here?
1535  {
1536  CalcVShape(ip, vshape);
1537  J.MultTranspose(nk+dim*d2n[j], pt_data);
1538  pt /= weight;
1539  for (int k = 0; k < dof; k++)
1540  {
1541  double R_jk = 0.0;
1542  for (int d = 0; d < dim; d++)
1543  {
1544  R_jk += vshape(k,d)*pt_data[d];
1545  }
1546  R(j,k) = R_jk;
1547  }
1548  }
1549  else
1550  {
1551  // Set the whole row to avoid valgrind warnings in R.Threshold().
1552  R.SetRow(j, infinity());
1553  }
1554  }
1555  R.Threshold(1e-12);
1556 }
1557 
1559  const double *tk, const Array<int> &d2t, ElementTransformation &Trans,
1560  DenseMatrix &R) const
1561 {
1562  double pt_data[Geometry::MaxDim];
1563  IntegrationPoint ip;
1564  Vector pt(pt_data, dim);
1565 
1566 #ifdef MFEM_THREAD_SAFE
1568 #endif
1569 
1571  const DenseMatrix &Jinv = Trans.InverseJacobian();
1572  for (int j = 0; j < dof; j++)
1573  {
1574  InvertLinearTrans(Trans, Nodes.IntPoint(j), pt);
1575  ip.Set(pt_data, dim);
1576  if (Geometries.CheckPoint(geom_type, ip)) // do we need an epsilon here?
1577  {
1578  CalcVShape(ip, vshape);
1579  Jinv.Mult(tk+dim*d2t[j], pt_data);
1580  for (int k = 0; k < dof; k++)
1581  {
1582  double R_jk = 0.0;
1583  for (int d = 0; d < dim; d++)
1584  {
1585  R_jk += vshape(k,d)*pt_data[d];
1586  }
1587  R(j,k) = R_jk;
1588  }
1589  }
1590  else
1591  {
1592  // Set the whole row to avoid valgrind warnings in R.Threshold().
1593  R.SetRow(j, infinity());
1594  }
1595  }
1596  R.Threshold(1e-12);
1597 }
1598 
1599 
1601  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
1602 {
1603  lex_ordering.SetSize(1);
1604  lex_ordering[0] = 0;
1605  Nodes.IntPoint(0).x = 0.0;
1606 }
1607 
1609  Vector &shape) const
1610 {
1611  shape(0) = 1.;
1612 }
1613 
1615  DenseMatrix &dshape) const
1616 {
1617  // dshape is (1 x 0) - nothing to compute
1618 }
1619 
1621  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
1622 {
1623  Nodes.IntPoint(0).x = 0.0;
1624  Nodes.IntPoint(1).x = 1.0;
1625 }
1626 
1628  Vector &shape) const
1629 {
1630  shape(0) = 1. - ip.x;
1631  shape(1) = ip.x;
1632 }
1633 
1635  DenseMatrix &dshape) const
1636 {
1637  dshape(0,0) = -1.;
1638  dshape(1,0) = 1.;
1639 }
1640 
1642  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
1643 {
1644  Nodes.IntPoint(0).x = 0.0;
1645  Nodes.IntPoint(0).y = 0.0;
1646  Nodes.IntPoint(1).x = 1.0;
1647  Nodes.IntPoint(1).y = 0.0;
1648  Nodes.IntPoint(2).x = 0.0;
1649  Nodes.IntPoint(2).y = 1.0;
1650 }
1651 
1653  Vector &shape) const
1654 {
1655  shape(0) = 1. - ip.x - ip.y;
1656  shape(1) = ip.x;
1657  shape(2) = ip.y;
1658 }
1659 
1661  DenseMatrix &dshape) const
1662 {
1663  dshape(0,0) = -1.; dshape(0,1) = -1.;
1664  dshape(1,0) = 1.; dshape(1,1) = 0.;
1665  dshape(2,0) = 0.; dshape(2,1) = 1.;
1666 }
1667 
1669  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1670 {
1671  Nodes.IntPoint(0).x = 0.0;
1672  Nodes.IntPoint(0).y = 0.0;
1673  Nodes.IntPoint(1).x = 1.0;
1674  Nodes.IntPoint(1).y = 0.0;
1675  Nodes.IntPoint(2).x = 1.0;
1676  Nodes.IntPoint(2).y = 1.0;
1677  Nodes.IntPoint(3).x = 0.0;
1678  Nodes.IntPoint(3).y = 1.0;
1679 }
1680 
1682  Vector &shape) const
1683 {
1684  shape(0) = (1. - ip.x) * (1. - ip.y) ;
1685  shape(1) = ip.x * (1. - ip.y) ;
1686  shape(2) = ip.x * ip.y ;
1687  shape(3) = (1. - ip.x) * ip.y ;
1688 }
1689 
1691  DenseMatrix &dshape) const
1692 {
1693  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
1694  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
1695  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
1696  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
1697 }
1698 
1700  const IntegrationPoint &ip, DenseMatrix &h) const
1701 {
1702  h(0,0) = 0.; h(0,1) = 1.; h(0,2) = 0.;
1703  h(1,0) = 0.; h(1,1) = -1.; h(1,2) = 0.;
1704  h(2,0) = 0.; h(2,1) = 1.; h(2,2) = 0.;
1705  h(3,0) = 0.; h(3,1) = -1.; h(3,2) = 0.;
1706 }
1707 
1708 
1710  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
1711 {
1712  Nodes.IntPoint(0).x = 1./6.;
1713  Nodes.IntPoint(0).y = 1./6.;
1714  Nodes.IntPoint(1).x = 2./3.;
1715  Nodes.IntPoint(1).y = 1./6.;
1716  Nodes.IntPoint(2).x = 1./6.;
1717  Nodes.IntPoint(2).y = 2./3.;
1718 }
1719 
1721  Vector &shape) const
1722 {
1723  const double x = ip.x, y = ip.y;
1724 
1725  shape(0) = 5./3. - 2. * (x + y);
1726  shape(1) = 2. * (x - 1./6.);
1727  shape(2) = 2. * (y - 1./6.);
1728 }
1729 
1731  DenseMatrix &dshape) const
1732 {
1733  dshape(0,0) = -2.; dshape(0,1) = -2.;
1734  dshape(1,0) = 2.; dshape(1,1) = 0.;
1735  dshape(2,0) = 0.; dshape(2,1) = 2.;
1736 }
1737 
1739 {
1740  dofs(vertex) = 2./3.;
1741  dofs((vertex+1)%3) = 1./6.;
1742  dofs((vertex+2)%3) = 1./6.;
1743 }
1744 
1745 
1746 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
1747 const double GaussBiLinear2DFiniteElement::p[] =
1748 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
1749 
1751  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1752 {
1753  Nodes.IntPoint(0).x = p[0];
1754  Nodes.IntPoint(0).y = p[0];
1755  Nodes.IntPoint(1).x = p[1];
1756  Nodes.IntPoint(1).y = p[0];
1757  Nodes.IntPoint(2).x = p[1];
1758  Nodes.IntPoint(2).y = p[1];
1759  Nodes.IntPoint(3).x = p[0];
1760  Nodes.IntPoint(3).y = p[1];
1761 }
1762 
1764  Vector &shape) const
1765 {
1766  const double x = ip.x, y = ip.y;
1767 
1768  shape(0) = 3. * (p[1] - x) * (p[1] - y);
1769  shape(1) = 3. * (x - p[0]) * (p[1] - y);
1770  shape(2) = 3. * (x - p[0]) * (y - p[0]);
1771  shape(3) = 3. * (p[1] - x) * (y - p[0]);
1772 }
1773 
1775  DenseMatrix &dshape) const
1776 {
1777  const double x = ip.x, y = ip.y;
1778 
1779  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
1780  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
1781  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
1782  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
1783 }
1784 
1786 {
1787 #if 1
1788  dofs(vertex) = p[1]*p[1];
1789  dofs((vertex+1)%4) = p[0]*p[1];
1790  dofs((vertex+2)%4) = p[0]*p[0];
1791  dofs((vertex+3)%4) = p[0]*p[1];
1792 #else
1793  dofs = 1.0;
1794 #endif
1795 }
1796 
1797 
1799  : NodalFiniteElement(2, Geometry::SQUARE, 3, 1, FunctionSpace::Qk)
1800 {
1801  Nodes.IntPoint(0).x = 0.0;
1802  Nodes.IntPoint(0).y = 0.0;
1803  Nodes.IntPoint(1).x = 1.0;
1804  Nodes.IntPoint(1).y = 0.0;
1805  Nodes.IntPoint(2).x = 0.0;
1806  Nodes.IntPoint(2).y = 1.0;
1807 }
1808 
1810  Vector &shape) const
1811 {
1812  shape(0) = 1. - ip.x - ip.y;
1813  shape(1) = ip.x;
1814  shape(2) = ip.y;
1815 }
1816 
1818  DenseMatrix &dshape) const
1819 {
1820  dshape(0,0) = -1.; dshape(0,1) = -1.;
1821  dshape(1,0) = 1.; dshape(1,1) = 0.;
1822  dshape(2,0) = 0.; dshape(2,1) = 1.;
1823 }
1824 
1825 
1827  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
1828 {
1829  Nodes.IntPoint(0).x = 0.0;
1830  Nodes.IntPoint(1).x = 1.0;
1831  Nodes.IntPoint(2).x = 0.5;
1832 }
1833 
1835  Vector &shape) const
1836 {
1837  double x = ip.x;
1838  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
1839 
1840  shape(0) = l1 * (-l3);
1841  shape(1) = l2 * l3;
1842  shape(2) = 4. * l1 * l2;
1843 }
1844 
1846  DenseMatrix &dshape) const
1847 {
1848  double x = ip.x;
1849 
1850  dshape(0,0) = 4. * x - 3.;
1851  dshape(1,0) = 4. * x - 1.;
1852  dshape(2,0) = 4. - 8. * x;
1853 }
1854 
1855 
1857  : PositiveFiniteElement(1, Geometry::SEGMENT, 3, 2)
1858 {
1859  Nodes.IntPoint(0).x = 0.0;
1860  Nodes.IntPoint(1).x = 1.0;
1861  Nodes.IntPoint(2).x = 0.5;
1862 }
1863 
1865  Vector &shape) const
1866 {
1867  const double x = ip.x, x1 = 1. - x;
1868 
1869  shape(0) = x1 * x1;
1870  shape(1) = x * x;
1871  shape(2) = 2. * x * x1;
1872 }
1873 
1875  DenseMatrix &dshape) const
1876 {
1877  const double x = ip.x;
1878 
1879  dshape(0,0) = 2. * x - 2.;
1880  dshape(1,0) = 2. * x;
1881  dshape(2,0) = 2. - 4. * x;
1882 }
1883 
1885  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1886 {
1887  Nodes.IntPoint(0).x = 0.0;
1888  Nodes.IntPoint(0).y = 0.0;
1889  Nodes.IntPoint(1).x = 1.0;
1890  Nodes.IntPoint(1).y = 0.0;
1891  Nodes.IntPoint(2).x = 0.0;
1892  Nodes.IntPoint(2).y = 1.0;
1893  Nodes.IntPoint(3).x = 0.5;
1894  Nodes.IntPoint(3).y = 0.0;
1895  Nodes.IntPoint(4).x = 0.5;
1896  Nodes.IntPoint(4).y = 0.5;
1897  Nodes.IntPoint(5).x = 0.0;
1898  Nodes.IntPoint(5).y = 0.5;
1899 }
1900 
1902  Vector &shape) const
1903 {
1904  double x = ip.x, y = ip.y;
1905  double l1 = 1.-x-y, l2 = x, l3 = y;
1906 
1907  shape(0) = l1 * (2. * l1 - 1.);
1908  shape(1) = l2 * (2. * l2 - 1.);
1909  shape(2) = l3 * (2. * l3 - 1.);
1910  shape(3) = 4. * l1 * l2;
1911  shape(4) = 4. * l2 * l3;
1912  shape(5) = 4. * l3 * l1;
1913 }
1914 
1916  DenseMatrix &dshape) const
1917 {
1918  double x = ip.x, y = ip.y;
1919 
1920  dshape(0,0) =
1921  dshape(0,1) = 4. * (x + y) - 3.;
1922 
1923  dshape(1,0) = 4. * x - 1.;
1924  dshape(1,1) = 0.;
1925 
1926  dshape(2,0) = 0.;
1927  dshape(2,1) = 4. * y - 1.;
1928 
1929  dshape(3,0) = -4. * (2. * x + y - 1.);
1930  dshape(3,1) = -4. * x;
1931 
1932  dshape(4,0) = 4. * y;
1933  dshape(4,1) = 4. * x;
1934 
1935  dshape(5,0) = -4. * y;
1936  dshape(5,1) = -4. * (x + 2. * y - 1.);
1937 }
1938 
1940  DenseMatrix &h) const
1941 {
1942  h(0,0) = 4.;
1943  h(0,1) = 4.;
1944  h(0,2) = 4.;
1945 
1946  h(1,0) = 4.;
1947  h(1,1) = 0.;
1948  h(1,2) = 0.;
1949 
1950  h(2,0) = 0.;
1951  h(2,1) = 0.;
1952  h(2,2) = 4.;
1953 
1954  h(3,0) = -8.;
1955  h(3,1) = -4.;
1956  h(3,2) = 0.;
1957 
1958  h(4,0) = 0.;
1959  h(4,1) = 4.;
1960  h(4,2) = 0.;
1961 
1962  h(5,0) = 0.;
1963  h(5,1) = -4.;
1964  h(5,2) = -8.;
1965 }
1966 
1967 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1968 {
1969 #if 0
1970  dofs = 1.;
1971 #else
1972  dofs = 0.;
1973  dofs(vertex) = 1.;
1974  switch (vertex)
1975  {
1976  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1977  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1978  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1979  }
1980 #endif
1981 }
1982 
1983 
1984 const double GaussQuad2DFiniteElement::p[] =
1985 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1986 
1988  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1989 {
1990  Nodes.IntPoint(0).x = p[0];
1991  Nodes.IntPoint(0).y = p[0];
1992  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1993  Nodes.IntPoint(1).y = p[0];
1994  Nodes.IntPoint(2).x = p[0];
1995  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1996  Nodes.IntPoint(3).x = p[1];
1997  Nodes.IntPoint(3).y = p[1];
1998  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1999  Nodes.IntPoint(4).y = p[1];
2000  Nodes.IntPoint(5).x = p[1];
2001  Nodes.IntPoint(5).y = 1. - 2. * p[1];
2002 
2003  for (int i = 0; i < 6; i++)
2004  {
2005  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
2006  A(0,i) = 1.;
2007  A(1,i) = x;
2008  A(2,i) = y;
2009  A(3,i) = x * x;
2010  A(4,i) = x * y;
2011  A(5,i) = y * y;
2012  }
2013 
2014  A.Invert();
2015 }
2016 
2018  Vector &shape) const
2019 {
2020  const double x = ip.x, y = ip.y;
2021  pol(0) = 1.;
2022  pol(1) = x;
2023  pol(2) = y;
2024  pol(3) = x * x;
2025  pol(4) = x * y;
2026  pol(5) = y * y;
2027 
2028  A.Mult(pol, shape);
2029 }
2030 
2032  DenseMatrix &dshape) const
2033 {
2034  const double x = ip.x, y = ip.y;
2035  D(0,0) = 0.; D(0,1) = 0.;
2036  D(1,0) = 1.; D(1,1) = 0.;
2037  D(2,0) = 0.; D(2,1) = 1.;
2038  D(3,0) = 2. * x; D(3,1) = 0.;
2039  D(4,0) = y; D(4,1) = x;
2040  D(5,0) = 0.; D(5,1) = 2. * y;
2041 
2042  Mult(A, D, dshape);
2043 }
2044 
2045 
2047  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
2048 {
2049  Nodes.IntPoint(0).x = 0.0;
2050  Nodes.IntPoint(0).y = 0.0;
2051  Nodes.IntPoint(1).x = 1.0;
2052  Nodes.IntPoint(1).y = 0.0;
2053  Nodes.IntPoint(2).x = 1.0;
2054  Nodes.IntPoint(2).y = 1.0;
2055  Nodes.IntPoint(3).x = 0.0;
2056  Nodes.IntPoint(3).y = 1.0;
2057  Nodes.IntPoint(4).x = 0.5;
2058  Nodes.IntPoint(4).y = 0.0;
2059  Nodes.IntPoint(5).x = 1.0;
2060  Nodes.IntPoint(5).y = 0.5;
2061  Nodes.IntPoint(6).x = 0.5;
2062  Nodes.IntPoint(6).y = 1.0;
2063  Nodes.IntPoint(7).x = 0.0;
2064  Nodes.IntPoint(7).y = 0.5;
2065  Nodes.IntPoint(8).x = 0.5;
2066  Nodes.IntPoint(8).y = 0.5;
2067 }
2068 
2070  Vector &shape) const
2071 {
2072  double x = ip.x, y = ip.y;
2073  double l1x, l2x, l3x, l1y, l2y, l3y;
2074 
2075  l1x = (x - 1.) * (2. * x - 1);
2076  l2x = 4. * x * (1. - x);
2077  l3x = x * (2. * x - 1.);
2078  l1y = (y - 1.) * (2. * y - 1);
2079  l2y = 4. * y * (1. - y);
2080  l3y = y * (2. * y - 1.);
2081 
2082  shape(0) = l1x * l1y;
2083  shape(4) = l2x * l1y;
2084  shape(1) = l3x * l1y;
2085  shape(7) = l1x * l2y;
2086  shape(8) = l2x * l2y;
2087  shape(5) = l3x * l2y;
2088  shape(3) = l1x * l3y;
2089  shape(6) = l2x * l3y;
2090  shape(2) = l3x * l3y;
2091 }
2092 
2094  DenseMatrix &dshape) const
2095 {
2096  double x = ip.x, y = ip.y;
2097  double l1x, l2x, l3x, l1y, l2y, l3y;
2098  double d1x, d2x, d3x, d1y, d2y, d3y;
2099 
2100  l1x = (x - 1.) * (2. * x - 1);
2101  l2x = 4. * x * (1. - x);
2102  l3x = x * (2. * x - 1.);
2103  l1y = (y - 1.) * (2. * y - 1);
2104  l2y = 4. * y * (1. - y);
2105  l3y = y * (2. * y - 1.);
2106 
2107  d1x = 4. * x - 3.;
2108  d2x = 4. - 8. * x;
2109  d3x = 4. * x - 1.;
2110  d1y = 4. * y - 3.;
2111  d2y = 4. - 8. * y;
2112  d3y = 4. * y - 1.;
2113 
2114  dshape(0,0) = d1x * l1y;
2115  dshape(0,1) = l1x * d1y;
2116 
2117  dshape(4,0) = d2x * l1y;
2118  dshape(4,1) = l2x * d1y;
2119 
2120  dshape(1,0) = d3x * l1y;
2121  dshape(1,1) = l3x * d1y;
2122 
2123  dshape(7,0) = d1x * l2y;
2124  dshape(7,1) = l1x * d2y;
2125 
2126  dshape(8,0) = d2x * l2y;
2127  dshape(8,1) = l2x * d2y;
2128 
2129  dshape(5,0) = d3x * l2y;
2130  dshape(5,1) = l3x * d2y;
2131 
2132  dshape(3,0) = d1x * l3y;
2133  dshape(3,1) = l1x * d3y;
2134 
2135  dshape(6,0) = d2x * l3y;
2136  dshape(6,1) = l2x * d3y;
2137 
2138  dshape(2,0) = d3x * l3y;
2139  dshape(2,1) = l3x * d3y;
2140 }
2141 
2142 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
2143 {
2144 #if 0
2145  dofs = 1.;
2146 #else
2147  dofs = 0.;
2148  dofs(vertex) = 1.;
2149  switch (vertex)
2150  {
2151  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
2152  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
2153  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
2154  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
2155  }
2156  dofs(8) = 1./16.;
2157 #endif
2158 }
2159 
2160 
2162  : ScalarFiniteElement(2, Geometry::SQUARE, (p*p + 3*p +6) / 2, p,
2163  FunctionSpace::Qk)
2164 {
2165  // Store the dof_map of the associated TensorBasisElement, which will be used
2166  // to create the serendipity dof map. Its size is larger than the size of
2167  // the serendipity element.
2168  TensorBasisElement tbeTemp =
2170  TensorBasisElement::DofMapType::Sr_DOF_MAP);
2171  const Array<int> tp_dof_map = tbeTemp.GetDofMap();
2172 
2173  const double *cp = poly1d.ClosedPoints(p, BasisType::GaussLobatto);
2174 
2175  // Fixing the Nodes is exactly the same as the H1_QuadrilateralElement
2176  // constructor except we only use those values of the associated tensor
2177  // product dof_map that are <= the number of serendipity Dofs e.g. only DoFs
2178  // 0-7 out of the 9 tensor product dofs (at quadratic order)
2179  int o = 0;
2180 
2181  for (int j = 0; j <= p; j++)
2182  {
2183  for (int i = 0; i <= p; i++)
2184  {
2185  if (tp_dof_map[o] < Nodes.Size())
2186  {
2187  Nodes.IntPoint(tp_dof_map[o]).x = cp[i];
2188  Nodes.IntPoint(tp_dof_map[o]).y = cp[j];
2189  }
2190  o++;
2191  }
2192  }
2193 }
2194 
2196  Vector &shape) const
2197 {
2198  int p = (this)->GetOrder();
2199  double x = ip.x, y = ip.y;
2200 
2202  Vector nodalX(p+1);
2203  Vector nodalY(p+1);
2204 
2205  edgeNodalBasis.Eval(x, nodalX);
2206  edgeNodalBasis.Eval(y, nodalY);
2207 
2208  // First, fix edge-based shape functions. Use a nodal interpolant for edge
2209  // points, weighted by the linear function that vanishes on opposite edge.
2210  for (int i = 0; i < p-1; i++)
2211  {
2212  shape(4 + 0*(p-1) + i) = (nodalX(i+1))*(1.-y); // south edge 0->1
2213  shape(4 + 1*(p-1) + i) = (nodalY(i+1))*x; // east edge 1->2
2214  shape(4 + 3*(p-1) - i - 1) = (nodalX(i+1)) * y; // north edge 3->2
2215  shape(4 + 4*(p-1) - i - 1) = (nodalY(i+1)) * (1. - x); // west edge 0->3
2216  }
2217 
2219  Vector bilinearsAtIP(4);
2220  bilinear.CalcShape(ip, bilinearsAtIP);
2221 
2222  const double *edgePts(poly1d.ClosedPoints(p, BasisType::GaussLobatto));
2223 
2224  // Next, set the shape function associated with vertex V, evaluated at (x,y)
2225  // to be: bilinear function associated to V, evaluated at (x,y) - sum (shape
2226  // function at edge point P, weighted by bilinear function for V evaluated at
2227  // P) where the sum is taken only for points P on edges incident to V.
2228 
2229  double vtx0fix =0;
2230  double vtx1fix =0;
2231  double vtx2fix =0;
2232  double vtx3fix =0;
2233  for (int i = 0; i<p-1; i++)
2234  {
2235  vtx0fix += (1-edgePts[i+1])*(shape(4 + i) +
2236  shape(4 + 4*(p-1) - i - 1)); // bot+left edge
2237  vtx1fix += (1-edgePts[i+1])*(shape(4 + 1*(p-1) + i) +
2238  shape(4 + (p-2)-i)); // right+bot edge
2239  vtx2fix += (1-edgePts[i+1])*(shape(4 + 2*(p-1) + i) +
2240  shape(1 + 2*p-i)); // top+right edge
2241  vtx3fix += (1-edgePts[i+1])*(shape(4 + 3*(p-1) + i) +
2242  shape(3*p - i)); // left+top edge
2243  }
2244  shape(0) = bilinearsAtIP(0) - vtx0fix;
2245  shape(1) = bilinearsAtIP(1) - vtx1fix;
2246  shape(2) = bilinearsAtIP(2) - vtx2fix;
2247  shape(3) = bilinearsAtIP(3) - vtx3fix;
2248 
2249  // Interior basis functions appear starting at order p=4. These are non-nodal
2250  // bubble functions.
2251  if (p > 3)
2252  {
2253  double *legX = new double[p-1];
2254  double *legY = new double[p-1];
2255  Poly_1D *storeLegendre = new Poly_1D();
2256 
2257  storeLegendre->CalcLegendre(p-2, x, legX);
2258  storeLegendre->CalcLegendre(p-2, y, legY);
2259 
2260  int interior_total = 0;
2261  for (int j = 4; j < p + 1; j++)
2262  {
2263  for (int k = 0; k < j-3; k++)
2264  {
2265  shape(4 + 4*(p-1) + interior_total)
2266  = legX[k] * legY[j-4-k] * x * (1. - x) * y * (1. - y);
2267  interior_total++;
2268  }
2269  }
2270 
2271  delete[] legX;
2272  delete[] legY;
2273  delete storeLegendre;
2274  }
2275 }
2276 
2278  DenseMatrix &dshape) const
2279 {
2280  int p = (this)->GetOrder();
2281  double x = ip.x, y = ip.y;
2282 
2284  Vector nodalX(p+1);
2285  Vector DnodalX(p+1);
2286  Vector nodalY(p+1);
2287  Vector DnodalY(p+1);
2288 
2289  edgeNodalBasis.Eval(x, nodalX, DnodalX);
2290  edgeNodalBasis.Eval(y, nodalY, DnodalY);
2291 
2292  for (int i = 0; i < p-1; i++)
2293  {
2294  dshape(4 + 0*(p-1) + i,0) = DnodalX(i+1) * (1.-y);
2295  dshape(4 + 0*(p-1) + i,1) = -nodalX(i+1);
2296  dshape(4 + 1*(p-1) + i,0) = nodalY(i+1);
2297  dshape(4 + 1*(p-1) + i,1) = DnodalY(i+1)*x;
2298  dshape(4 + 3*(p-1) - i - 1,0) = DnodalX(i+1)*y;
2299  dshape(4 + 3*(p-1) - i - 1,1) = nodalX(i+1);
2300  dshape(4 + 4*(p-1) - i - 1,0) = -nodalY(i+1);
2301  dshape(4 + 4*(p-1) - i - 1,1) = DnodalY(i+1) * (1.-x);
2302  }
2303 
2305  DenseMatrix DbilinearsAtIP(4);
2306  bilinear.CalcDShape(ip, DbilinearsAtIP);
2307 
2308  const double *edgePts(poly1d.ClosedPoints(p, BasisType::GaussLobatto));
2309 
2310  dshape(0,0) = DbilinearsAtIP(0,0);
2311  dshape(0,1) = DbilinearsAtIP(0,1);
2312  dshape(1,0) = DbilinearsAtIP(1,0);
2313  dshape(1,1) = DbilinearsAtIP(1,1);
2314  dshape(2,0) = DbilinearsAtIP(2,0);
2315  dshape(2,1) = DbilinearsAtIP(2,1);
2316  dshape(3,0) = DbilinearsAtIP(3,0);
2317  dshape(3,1) = DbilinearsAtIP(3,1);
2318 
2319  for (int i = 0; i<p-1; i++)
2320  {
2321  dshape(0,0) -= (1-edgePts[i+1])*(dshape(4 + 0*(p-1) + i, 0) +
2322  dshape(4 + 4*(p-1) - i - 1,0));
2323  dshape(0,1) -= (1-edgePts[i+1])*(dshape(4 + 0*(p-1) + i, 1) +
2324  dshape(4 + 4*(p-1) - i - 1,1));
2325  dshape(1,0) -= (1-edgePts[i+1])*(dshape(4 + 1*(p-1) + i, 0) +
2326  dshape(4 + (p-2)-i, 0));
2327  dshape(1,1) -= (1-edgePts[i+1])*(dshape(4 + 1*(p-1) + i, 1) +
2328  dshape(4 + (p-2)-i, 1));
2329  dshape(2,0) -= (1-edgePts[i+1])*(dshape(4 + 2*(p-1) + i, 0) +
2330  dshape(1 + 2*p-i, 0));
2331  dshape(2,1) -= (1-edgePts[i+1])*(dshape(4 + 2*(p-1) + i, 1) +
2332  dshape(1 + 2*p-i, 1));
2333  dshape(3,0) -= (1-edgePts[i+1])*(dshape(4 + 3*(p-1) + i, 0) +
2334  dshape(3*p - i, 0));
2335  dshape(3,1) -= (1-edgePts[i+1])*(dshape(4 + 3*(p-1) + i, 1) +
2336  dshape(3*p - i, 1));
2337  }
2338 
2339  if (p > 3)
2340  {
2341  double *legX = new double[p-1];
2342  double *legY = new double[p-1];
2343  double *DlegX = new double[p-1];
2344  double *DlegY = new double[p-1];
2345  Poly_1D *storeLegendre = new Poly_1D();
2346 
2347  storeLegendre->CalcLegendre(p-2, x, legX, DlegX);
2348  storeLegendre->CalcLegendre(p-2, y, legY, DlegY);
2349 
2350  int interior_total = 0;
2351  for (int j = 4; j < p + 1; j++)
2352  {
2353  for (int k = 0; k < j-3; k++)
2354  {
2355  dshape(4 + 4*(p-1) + interior_total, 0) =
2356  legY[j-4-k]*y*(1-y) * (DlegX[k]*x*(1-x) + legX[k]*(1-2*x));
2357  dshape(4 + 4*(p-1) + interior_total, 1) =
2358  legX[k]*x*(1-x) * (DlegY[j-4-k]*y*(1-y) + legY[j-4-k]*(1-2*y));
2359  interior_total++;
2360  }
2361  }
2362  delete[] legX;
2363  delete[] legY;
2364  delete[] DlegX;
2365  delete[] DlegY;
2366  delete storeLegendre;
2367  }
2368 }
2369 
2371  &Trans,
2372  DenseMatrix &I) const
2373 {
2374  // For p<=4, the basis is nodal; for p>4, the quad-interior functions are
2375  // non-nodal.
2376  if (order <= 4)
2377  {
2378  NodalLocalInterpolation(Trans, I, *this);
2379  }
2380  else
2381  {
2382  ScalarLocalInterpolation(Trans, I, *this);
2383  }
2384 }
2385 
2386 
2388  : PositiveFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
2389 {
2390  Nodes.IntPoint(0).x = 0.0;
2391  Nodes.IntPoint(0).y = 0.0;
2392  Nodes.IntPoint(1).x = 1.0;
2393  Nodes.IntPoint(1).y = 0.0;
2394  Nodes.IntPoint(2).x = 1.0;
2395  Nodes.IntPoint(2).y = 1.0;
2396  Nodes.IntPoint(3).x = 0.0;
2397  Nodes.IntPoint(3).y = 1.0;
2398  Nodes.IntPoint(4).x = 0.5;
2399  Nodes.IntPoint(4).y = 0.0;
2400  Nodes.IntPoint(5).x = 1.0;
2401  Nodes.IntPoint(5).y = 0.5;
2402  Nodes.IntPoint(6).x = 0.5;
2403  Nodes.IntPoint(6).y = 1.0;
2404  Nodes.IntPoint(7).x = 0.0;
2405  Nodes.IntPoint(7).y = 0.5;
2406  Nodes.IntPoint(8).x = 0.5;
2407  Nodes.IntPoint(8).y = 0.5;
2408 }
2409 
2411  Vector &shape) const
2412 {
2413  double x = ip.x, y = ip.y;
2414  double l1x, l2x, l3x, l1y, l2y, l3y;
2415 
2416  l1x = (1. - x) * (1. - x);
2417  l2x = 2. * x * (1. - x);
2418  l3x = x * x;
2419  l1y = (1. - y) * (1. - y);
2420  l2y = 2. * y * (1. - y);
2421  l3y = y * y;
2422 
2423  shape(0) = l1x * l1y;
2424  shape(4) = l2x * l1y;
2425  shape(1) = l3x * l1y;
2426  shape(7) = l1x * l2y;
2427  shape(8) = l2x * l2y;
2428  shape(5) = l3x * l2y;
2429  shape(3) = l1x * l3y;
2430  shape(6) = l2x * l3y;
2431  shape(2) = l3x * l3y;
2432 }
2433 
2435  DenseMatrix &dshape) const
2436 {
2437  double x = ip.x, y = ip.y;
2438  double l1x, l2x, l3x, l1y, l2y, l3y;
2439  double d1x, d2x, d3x, d1y, d2y, d3y;
2440 
2441  l1x = (1. - x) * (1. - x);
2442  l2x = 2. * x * (1. - x);
2443  l3x = x * x;
2444  l1y = (1. - y) * (1. - y);
2445  l2y = 2. * y * (1. - y);
2446  l3y = y * y;
2447 
2448  d1x = 2. * x - 2.;
2449  d2x = 2. - 4. * x;
2450  d3x = 2. * x;
2451  d1y = 2. * y - 2.;
2452  d2y = 2. - 4. * y;
2453  d3y = 2. * y;
2454 
2455  dshape(0,0) = d1x * l1y;
2456  dshape(0,1) = l1x * d1y;
2457 
2458  dshape(4,0) = d2x * l1y;
2459  dshape(4,1) = l2x * d1y;
2460 
2461  dshape(1,0) = d3x * l1y;
2462  dshape(1,1) = l3x * d1y;
2463 
2464  dshape(7,0) = d1x * l2y;
2465  dshape(7,1) = l1x * d2y;
2466 
2467  dshape(8,0) = d2x * l2y;
2468  dshape(8,1) = l2x * d2y;
2469 
2470  dshape(5,0) = d3x * l2y;
2471  dshape(5,1) = l3x * d2y;
2472 
2473  dshape(3,0) = d1x * l3y;
2474  dshape(3,1) = l1x * d3y;
2475 
2476  dshape(6,0) = d2x * l3y;
2477  dshape(6,1) = l2x * d3y;
2478 
2479  dshape(2,0) = d3x * l3y;
2480  dshape(2,1) = l3x * d3y;
2481 }
2482 
2485 {
2486  double s[9];
2487  IntegrationPoint tr_ip;
2488  Vector xx(&tr_ip.x, 2), shape(s, 9);
2489 
2490  for (int i = 0; i < 9; i++)
2491  {
2492  Trans.Transform(Nodes.IntPoint(i), xx);
2493  CalcShape(tr_ip, shape);
2494  for (int j = 0; j < 9; j++)
2495  if (fabs(I(i,j) = s[j]) < 1.0e-12)
2496  {
2497  I(i,j) = 0.0;
2498  }
2499  }
2500  for (int i = 0; i < 9; i++)
2501  {
2502  double *d = &I(0,i);
2503  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2504  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2505  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2506  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2507  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2508  0.25 * (d[0] + d[1] + d[2] + d[3]);
2509  }
2510 }
2511 
2513  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
2514 {
2515  double *d = dofs;
2516 
2517  for (int i = 0; i < 9; i++)
2518  {
2519  const IntegrationPoint &ip = Nodes.IntPoint(i);
2520  Trans.SetIntPoint(&ip);
2521  d[i] = coeff.Eval(Trans, ip);
2522  }
2523  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2524  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2525  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2526  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2527  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2528  0.25 * (d[0] + d[1] + d[2] + d[3]);
2529 }
2530 
2533  Vector &dofs) const
2534 {
2535  double v[3];
2536  Vector x (v, vc.GetVDim());
2537 
2538  for (int i = 0; i < 9; i++)
2539  {
2540  const IntegrationPoint &ip = Nodes.IntPoint(i);
2541  Trans.SetIntPoint(&ip);
2542  vc.Eval (x, Trans, ip);
2543  for (int j = 0; j < x.Size(); j++)
2544  {
2545  dofs(9*j+i) = v[j];
2546  }
2547  }
2548  for (int j = 0; j < x.Size(); j++)
2549  {
2550  double *d = &dofs(9*j);
2551 
2552  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
2553  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
2554  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
2555  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
2556  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
2557  0.25 * (d[0] + d[1] + d[2] + d[3]);
2558  }
2559 }
2560 
2561 
2563  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
2564 {
2565  const double p1 = 0.5*(1.-sqrt(3./5.));
2566 
2567  Nodes.IntPoint(0).x = p1;
2568  Nodes.IntPoint(0).y = p1;
2569  Nodes.IntPoint(4).x = 0.5;
2570  Nodes.IntPoint(4).y = p1;
2571  Nodes.IntPoint(1).x = 1.-p1;
2572  Nodes.IntPoint(1).y = p1;
2573  Nodes.IntPoint(7).x = p1;
2574  Nodes.IntPoint(7).y = 0.5;
2575  Nodes.IntPoint(8).x = 0.5;
2576  Nodes.IntPoint(8).y = 0.5;
2577  Nodes.IntPoint(5).x = 1.-p1;
2578  Nodes.IntPoint(5).y = 0.5;
2579  Nodes.IntPoint(3).x = p1;
2580  Nodes.IntPoint(3).y = 1.-p1;
2581  Nodes.IntPoint(6).x = 0.5;
2582  Nodes.IntPoint(6).y = 1.-p1;
2583  Nodes.IntPoint(2).x = 1.-p1;
2584  Nodes.IntPoint(2).y = 1.-p1;
2585 }
2586 
2588  Vector &shape) const
2589 {
2590  const double a = sqrt(5./3.);
2591  const double p1 = 0.5*(1.-sqrt(3./5.));
2592 
2593  double x = a*(ip.x-p1), y = a*(ip.y-p1);
2594  double l1x, l2x, l3x, l1y, l2y, l3y;
2595 
2596  l1x = (x - 1.) * (2. * x - 1);
2597  l2x = 4. * x * (1. - x);
2598  l3x = x * (2. * x - 1.);
2599  l1y = (y - 1.) * (2. * y - 1);
2600  l2y = 4. * y * (1. - y);
2601  l3y = y * (2. * y - 1.);
2602 
2603  shape(0) = l1x * l1y;
2604  shape(4) = l2x * l1y;
2605  shape(1) = l3x * l1y;
2606  shape(7) = l1x * l2y;
2607  shape(8) = l2x * l2y;
2608  shape(5) = l3x * l2y;
2609  shape(3) = l1x * l3y;
2610  shape(6) = l2x * l3y;
2611  shape(2) = l3x * l3y;
2612 }
2613 
2615  DenseMatrix &dshape) const
2616 {
2617  const double a = sqrt(5./3.);
2618  const double p1 = 0.5*(1.-sqrt(3./5.));
2619 
2620  double x = a*(ip.x-p1), y = a*(ip.y-p1);
2621  double l1x, l2x, l3x, l1y, l2y, l3y;
2622  double d1x, d2x, d3x, d1y, d2y, d3y;
2623 
2624  l1x = (x - 1.) * (2. * x - 1);
2625  l2x = 4. * x * (1. - x);
2626  l3x = x * (2. * x - 1.);
2627  l1y = (y - 1.) * (2. * y - 1);
2628  l2y = 4. * y * (1. - y);
2629  l3y = y * (2. * y - 1.);
2630 
2631  d1x = a * (4. * x - 3.);
2632  d2x = a * (4. - 8. * x);
2633  d3x = a * (4. * x - 1.);
2634  d1y = a * (4. * y - 3.);
2635  d2y = a * (4. - 8. * y);
2636  d3y = a * (4. * y - 1.);
2637 
2638  dshape(0,0) = d1x * l1y;
2639  dshape(0,1) = l1x * d1y;
2640 
2641  dshape(4,0) = d2x * l1y;
2642  dshape(4,1) = l2x * d1y;
2643 
2644  dshape(1,0) = d3x * l1y;
2645  dshape(1,1) = l3x * d1y;
2646 
2647  dshape(7,0) = d1x * l2y;
2648  dshape(7,1) = l1x * d2y;
2649 
2650  dshape(8,0) = d2x * l2y;
2651  dshape(8,1) = l2x * d2y;
2652 
2653  dshape(5,0) = d3x * l2y;
2654  dshape(5,1) = l3x * d2y;
2655 
2656  dshape(3,0) = d1x * l3y;
2657  dshape(3,1) = l1x * d3y;
2658 
2659  dshape(6,0) = d2x * l3y;
2660  dshape(6,1) = l2x * d3y;
2661 
2662  dshape(2,0) = d3x * l3y;
2663  dshape(2,1) = l3x * d3y;
2664 }
2665 
2667  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
2668 {
2669  Nodes.IntPoint(0).x = 0.;
2670  Nodes.IntPoint(0).y = 0.;
2671  Nodes.IntPoint(1).x = 1.;
2672  Nodes.IntPoint(1).y = 0.;
2673  Nodes.IntPoint(2).x = 1.;
2674  Nodes.IntPoint(2).y = 1.;
2675  Nodes.IntPoint(3).x = 0.;
2676  Nodes.IntPoint(3).y = 1.;
2677  Nodes.IntPoint(4).x = 1./3.;
2678  Nodes.IntPoint(4).y = 0.;
2679  Nodes.IntPoint(5).x = 2./3.;
2680  Nodes.IntPoint(5).y = 0.;
2681  Nodes.IntPoint(6).x = 1.;
2682  Nodes.IntPoint(6).y = 1./3.;
2683  Nodes.IntPoint(7).x = 1.;
2684  Nodes.IntPoint(7).y = 2./3.;
2685  Nodes.IntPoint(8).x = 2./3.;
2686  Nodes.IntPoint(8).y = 1.;
2687  Nodes.IntPoint(9).x = 1./3.;
2688  Nodes.IntPoint(9).y = 1.;
2689  Nodes.IntPoint(10).x = 0.;
2690  Nodes.IntPoint(10).y = 2./3.;
2691  Nodes.IntPoint(11).x = 0.;
2692  Nodes.IntPoint(11).y = 1./3.;
2693  Nodes.IntPoint(12).x = 1./3.;
2694  Nodes.IntPoint(12).y = 1./3.;
2695  Nodes.IntPoint(13).x = 2./3.;
2696  Nodes.IntPoint(13).y = 1./3.;
2697  Nodes.IntPoint(14).x = 1./3.;
2698  Nodes.IntPoint(14).y = 2./3.;
2699  Nodes.IntPoint(15).x = 2./3.;
2700  Nodes.IntPoint(15).y = 2./3.;
2701 }
2702 
2704  const IntegrationPoint &ip, Vector &shape) const
2705 {
2706  double x = ip.x, y = ip.y;
2707 
2708  double w1x, w2x, w3x, w1y, w2y, w3y;
2709  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2710 
2711  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2712  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2713 
2714  l0x = (- 4.5) * w1x * w2x * w3x;
2715  l1x = ( 13.5) * x * w2x * w3x;
2716  l2x = (-13.5) * x * w1x * w3x;
2717  l3x = ( 4.5) * x * w1x * w2x;
2718 
2719  l0y = (- 4.5) * w1y * w2y * w3y;
2720  l1y = ( 13.5) * y * w2y * w3y;
2721  l2y = (-13.5) * y * w1y * w3y;
2722  l3y = ( 4.5) * y * w1y * w2y;
2723 
2724  shape(0) = l0x * l0y;
2725  shape(1) = l3x * l0y;
2726  shape(2) = l3x * l3y;
2727  shape(3) = l0x * l3y;
2728  shape(4) = l1x * l0y;
2729  shape(5) = l2x * l0y;
2730  shape(6) = l3x * l1y;
2731  shape(7) = l3x * l2y;
2732  shape(8) = l2x * l3y;
2733  shape(9) = l1x * l3y;
2734  shape(10) = l0x * l2y;
2735  shape(11) = l0x * l1y;
2736  shape(12) = l1x * l1y;
2737  shape(13) = l2x * l1y;
2738  shape(14) = l1x * l2y;
2739  shape(15) = l2x * l2y;
2740 }
2741 
2743  const IntegrationPoint &ip, DenseMatrix &dshape) const
2744 {
2745  double x = ip.x, y = ip.y;
2746 
2747  double w1x, w2x, w3x, w1y, w2y, w3y;
2748  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2749  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
2750 
2751  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2752  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2753 
2754  l0x = (- 4.5) * w1x * w2x * w3x;
2755  l1x = ( 13.5) * x * w2x * w3x;
2756  l2x = (-13.5) * x * w1x * w3x;
2757  l3x = ( 4.5) * x * w1x * w2x;
2758 
2759  l0y = (- 4.5) * w1y * w2y * w3y;
2760  l1y = ( 13.5) * y * w2y * w3y;
2761  l2y = (-13.5) * y * w1y * w3y;
2762  l3y = ( 4.5) * y * w1y * w2y;
2763 
2764  d0x = -5.5 + ( 18. - 13.5 * x) * x;
2765  d1x = 9. + (-45. + 40.5 * x) * x;
2766  d2x = -4.5 + ( 36. - 40.5 * x) * x;
2767  d3x = 1. + (- 9. + 13.5 * x) * x;
2768 
2769  d0y = -5.5 + ( 18. - 13.5 * y) * y;
2770  d1y = 9. + (-45. + 40.5 * y) * y;
2771  d2y = -4.5 + ( 36. - 40.5 * y) * y;
2772  d3y = 1. + (- 9. + 13.5 * y) * y;
2773 
2774  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
2775  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
2776  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
2777  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
2778  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
2779  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
2780  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
2781  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
2782  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
2783  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
2784  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
2785  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
2786  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
2787  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
2788  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
2789  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
2790 }
2791 
2793  const IntegrationPoint &ip, DenseMatrix &h) const
2794 {
2795  double x = ip.x, y = ip.y;
2796 
2797  double w1x, w2x, w3x, w1y, w2y, w3y;
2798  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2799  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
2800  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
2801 
2802  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2803  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2804 
2805  l0x = (- 4.5) * w1x * w2x * w3x;
2806  l1x = ( 13.5) * x * w2x * w3x;
2807  l2x = (-13.5) * x * w1x * w3x;
2808  l3x = ( 4.5) * x * w1x * w2x;
2809 
2810  l0y = (- 4.5) * w1y * w2y * w3y;
2811  l1y = ( 13.5) * y * w2y * w3y;
2812  l2y = (-13.5) * y * w1y * w3y;
2813  l3y = ( 4.5) * y * w1y * w2y;
2814 
2815  d0x = -5.5 + ( 18. - 13.5 * x) * x;
2816  d1x = 9. + (-45. + 40.5 * x) * x;
2817  d2x = -4.5 + ( 36. - 40.5 * x) * x;
2818  d3x = 1. + (- 9. + 13.5 * x) * x;
2819 
2820  d0y = -5.5 + ( 18. - 13.5 * y) * y;
2821  d1y = 9. + (-45. + 40.5 * y) * y;
2822  d2y = -4.5 + ( 36. - 40.5 * y) * y;
2823  d3y = 1. + (- 9. + 13.5 * y) * y;
2824 
2825  h0x = -27. * x + 18.;
2826  h1x = 81. * x - 45.;
2827  h2x = -81. * x + 36.;
2828  h3x = 27. * x - 9.;
2829 
2830  h0y = -27. * y + 18.;
2831  h1y = 81. * y - 45.;
2832  h2y = -81. * y + 36.;
2833  h3y = 27. * y - 9.;
2834 
2835  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
2836  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
2837  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
2838  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
2839  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
2840  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
2841  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
2842  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
2843  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
2844  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
2845  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
2846  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
2847  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
2848  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
2849  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
2850  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
2851 }
2852 
2853 
2855  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
2856 {
2857  Nodes.IntPoint(0).x = 0.0;
2858  Nodes.IntPoint(1).x = 1.0;
2859  Nodes.IntPoint(2).x = 0.33333333333333333333;
2860  Nodes.IntPoint(3).x = 0.66666666666666666667;
2861 }
2862 
2864  Vector &shape) const
2865 {
2866  double x = ip.x;
2867  double l1 = x,
2868  l2 = (1.0-x),
2869  l3 = (0.33333333333333333333-x),
2870  l4 = (0.66666666666666666667-x);
2871 
2872  shape(0) = 4.5 * l2 * l3 * l4;
2873  shape(1) = 4.5 * l1 * l3 * l4;
2874  shape(2) = 13.5 * l1 * l2 * l4;
2875  shape(3) = -13.5 * l1 * l2 * l3;
2876 }
2877 
2879  DenseMatrix &dshape) const
2880 {
2881  double x = ip.x;
2882 
2883  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
2884  dshape(1,0) = 1. - x * (9. - 13.5 * x);
2885  dshape(2,0) = 9. - x * (45. - 40.5 * x);
2886  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
2887 }
2888 
2889 
2891  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
2892 {
2893  Nodes.IntPoint(0).x = 0.0;
2894  Nodes.IntPoint(0).y = 0.0;
2895  Nodes.IntPoint(1).x = 1.0;
2896  Nodes.IntPoint(1).y = 0.0;
2897  Nodes.IntPoint(2).x = 0.0;
2898  Nodes.IntPoint(2).y = 1.0;
2899  Nodes.IntPoint(3).x = 0.33333333333333333333;
2900  Nodes.IntPoint(3).y = 0.0;
2901  Nodes.IntPoint(4).x = 0.66666666666666666667;
2902  Nodes.IntPoint(4).y = 0.0;
2903  Nodes.IntPoint(5).x = 0.66666666666666666667;
2904  Nodes.IntPoint(5).y = 0.33333333333333333333;
2905  Nodes.IntPoint(6).x = 0.33333333333333333333;
2906  Nodes.IntPoint(6).y = 0.66666666666666666667;
2907  Nodes.IntPoint(7).x = 0.0;
2908  Nodes.IntPoint(7).y = 0.66666666666666666667;
2909  Nodes.IntPoint(8).x = 0.0;
2910  Nodes.IntPoint(8).y = 0.33333333333333333333;
2911  Nodes.IntPoint(9).x = 0.33333333333333333333;
2912  Nodes.IntPoint(9).y = 0.33333333333333333333;
2913 }
2914 
2916  Vector &shape) const
2917 {
2918  double x = ip.x, y = ip.y;
2919  double l1 = (-1. + x + y),
2920  lx = (-1. + 3.*x),
2921  ly = (-1. + 3.*y);
2922 
2923  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
2924  shape(1) = 0.5*x*(lx - 1.)*lx;
2925  shape(2) = 0.5*y*(-1. + ly)*ly;
2926  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
2927  shape(4) = -4.5*x*lx*l1;
2928  shape(5) = 4.5*x*lx*y;
2929  shape(6) = 4.5*x*y*ly;
2930  shape(7) = -4.5*y*l1*ly;
2931  shape(8) = 4.5*y*l1*(1. + 3.*l1);
2932  shape(9) = -27.*x*y*l1;
2933 }
2934 
2936  DenseMatrix &dshape) const
2937 {
2938  double x = ip.x, y = ip.y;
2939 
2940  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2941  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
2942  dshape(2,0) = 0.;
2943  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
2944  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
2945  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
2946  dshape(6,0) = 4.5*y*(-1. + 3.*y);
2947  dshape(7,0) = 4.5*(1. - 3.*y)*y;
2948  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
2949  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
2950 
2951  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2952  dshape(1,1) = 0.;
2953  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
2954  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
2955  dshape(4,1) = 4.5*(1. - 3.*x)*x;
2956  dshape(5,1) = 4.5*x*(-1. + 3.*x);
2957  dshape(6,1) = 4.5*x*(-1. + 6.*y);
2958  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
2959  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
2960  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
2961 }
2962 
2964  DenseMatrix &h) const
2965 {
2966  double x = ip.x, y = ip.y;
2967 
2968  h(0,0) = 18.-27.*(x+y);
2969  h(0,1) = 18.-27.*(x+y);
2970  h(0,2) = 18.-27.*(x+y);
2971 
2972  h(1,0) = -9.+27.*x;
2973  h(1,1) = 0.;
2974  h(1,2) = 0.;
2975 
2976  h(2,0) = 0.;
2977  h(2,1) = 0.;
2978  h(2,2) = -9.+27.*y;
2979 
2980  h(3,0) = -45.+81.*x+54.*y;
2981  h(3,1) = -22.5+54.*x+27.*y;
2982  h(3,2) = 27.*x;
2983 
2984  h(4,0) = 36.-81.*x-27.*y;
2985  h(4,1) = 4.5-27.*x;
2986  h(4,2) = 0.;
2987 
2988  h(5,0) = 27.*y;
2989  h(5,1) = -4.5+27.*x;
2990  h(5,2) = 0.;
2991 
2992  h(6,0) = 0.;
2993  h(6,1) = -4.5+27.*y;
2994  h(6,2) = 27.*x;
2995 
2996  h(7,0) = 0.;
2997  h(7,1) = 4.5-27.*y;
2998  h(7,2) = 36.-27.*x-81.*y;
2999 
3000  h(8,0) = 27.*y;
3001  h(8,1) = -22.5+27.*x+54.*y;
3002  h(8,2) = -45.+54.*x+81.*y;
3003 
3004  h(9,0) = -54.*y;
3005  h(9,1) = 27.-54.*(x+y);
3006  h(9,2) = -54.*x;
3007 }
3008 
3009 
3011  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
3012 {
3013  Nodes.IntPoint(0).x = 0;
3014  Nodes.IntPoint(0).y = 0;
3015  Nodes.IntPoint(0).z = 0;
3016  Nodes.IntPoint(1).x = 1.;
3017  Nodes.IntPoint(1).y = 0;
3018  Nodes.IntPoint(1).z = 0;
3019  Nodes.IntPoint(2).x = 0;
3020  Nodes.IntPoint(2).y = 1.;
3021  Nodes.IntPoint(2).z = 0;
3022  Nodes.IntPoint(3).x = 0;
3023  Nodes.IntPoint(3).y = 0;
3024  Nodes.IntPoint(3).z = 1.;
3025  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
3026  Nodes.IntPoint(4).y = 0;
3027  Nodes.IntPoint(4).z = 0;
3028  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
3029  Nodes.IntPoint(5).y = 0;
3030  Nodes.IntPoint(5).z = 0;
3031  Nodes.IntPoint(6).x = 0;
3032  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
3033  Nodes.IntPoint(6).z = 0;
3034  Nodes.IntPoint(7).x = 0;
3035  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
3036  Nodes.IntPoint(7).z = 0;
3037  Nodes.IntPoint(8).x = 0;
3038  Nodes.IntPoint(8).y = 0;
3039  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
3040  Nodes.IntPoint(9).x = 0;
3041  Nodes.IntPoint(9).y = 0;
3042  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
3043  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
3044  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
3045  Nodes.IntPoint(10).z = 0;
3046  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
3047  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
3048  Nodes.IntPoint(11).z = 0;
3049  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
3050  Nodes.IntPoint(12).y = 0;
3051  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
3052  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
3053  Nodes.IntPoint(13).y = 0;
3054  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
3055  Nodes.IntPoint(14).x = 0;
3056  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
3057  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
3058  Nodes.IntPoint(15).x = 0;
3059  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
3060  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
3061  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
3062  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
3063  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
3064  Nodes.IntPoint(17).x = 0;
3065  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
3066  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
3067  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
3068  Nodes.IntPoint(18).y = 0;
3069  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
3070  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
3071  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
3072  Nodes.IntPoint(19).z = 0;
3073 }
3074 
3076  Vector &shape) const
3077 {
3078  double x = ip.x, y = ip.y, z = ip.z;
3079 
3080  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
3081  (-1 + 3*x + 3*y + 3*z))/2.;
3082  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
3083  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
3084  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
3085  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
3086  shape(19) = -27*x*y*(-1 + x + y + z);
3087  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
3088  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
3089  shape(11) = (9*x*y*(-1 + 3*y))/2.;
3090  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
3091  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
3092  shape(18) = -27*x*z*(-1 + x + y + z);
3093  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
3094  shape(17) = -27*y*z*(-1 + x + y + z);
3095  shape(16) = 27*x*y*z;
3096  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
3097  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
3098  shape(13) = (9*x*z*(-1 + 3*z))/2.;
3099  shape(15) = (9*y*z*(-1 + 3*z))/2.;
3100  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
3101 }
3102 
3104  DenseMatrix &dshape) const
3105 {
3106  double x = ip.x, y = ip.y, z = ip.z;
3107 
3108  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
3109  x*(-4 + 6*y + 6*z)))/2.;
3110  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
3111  x*(-4 + 6*y + 6*z)))/2.;
3112  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
3113  x*(-4 + 6*y + 6*z)))/2.;
3114  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
3115  2*x*(-5 + 6*y + 6*z)))/2.;
3116  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
3117  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
3118  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
3119  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
3120  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
3121  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
3122  dshape(1,1) = 0;
3123  dshape(1,2) = 0;
3124  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
3125  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
3126  x*(-5 + 12*y + 6*z)))/2.;
3127  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
3128  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
3129  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
3130  dshape(19,2) = -27*x*y;
3131  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
3132  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
3133  dshape(10,2) = 0;
3134  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
3135  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
3136  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
3137  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
3138  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
3139  dshape(11,2) = 0;
3140  dshape(2,0) = 0;
3141  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
3142  dshape(2,2) = 0;
3143  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
3144  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
3145  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
3146  x*(-5 + 6*y + 12*z)))/2.;
3147  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
3148  dshape(18,1) = -27*x*z;
3149  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
3150  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
3151  dshape(12,1) = 0;
3152  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
3153  dshape(17,0) = -27*y*z;
3154  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
3155  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
3156  dshape(16,0) = 27*y*z;
3157  dshape(16,1) = 27*x*z;
3158  dshape(16,2) = 27*x*y;
3159  dshape(14,0) = 0;
3160  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
3161  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
3162  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
3163  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
3164  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
3165  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
3166  dshape(13,1) = 0;
3167  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
3168  dshape(15,0) = 0;
3169  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
3170  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
3171  dshape(3,0) = 0;
3172  dshape(3,1) = 0;
3173  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
3174 }
3175 
3176 
3178  : NodalFiniteElement(2, Geometry::TRIANGLE, 1, 0)
3179 {
3180  Nodes.IntPoint(0).x = 0.333333333333333333;
3181  Nodes.IntPoint(0).y = 0.333333333333333333;
3182 }
3183 
3185  Vector &shape) const
3186 {
3187  shape(0) = 1.0;
3188 }
3189 
3191  DenseMatrix &dshape) const
3192 {
3193  dshape(0,0) = 0.0;
3194  dshape(0,1) = 0.0;
3195 }
3196 
3197 
3199  : NodalFiniteElement(2, Geometry::SQUARE, 1, 0, FunctionSpace::Qk)
3200 {
3201  Nodes.IntPoint(0).x = 0.5;
3202  Nodes.IntPoint(0).y = 0.5;
3203 }
3204 
3206  Vector &shape) const
3207 {
3208  shape(0) = 1.0;
3209 }
3210 
3212  DenseMatrix &dshape) const
3213 {
3214  dshape(0,0) = 0.0;
3215  dshape(0,1) = 0.0;
3216 }
3217 
3218 
3220  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
3221 {
3222  Nodes.IntPoint(0).x = 0.0;
3223  Nodes.IntPoint(0).y = 0.0;
3224  Nodes.IntPoint(0).z = 0.0;
3225  Nodes.IntPoint(1).x = 1.0;
3226  Nodes.IntPoint(1).y = 0.0;
3227  Nodes.IntPoint(1).z = 0.0;
3228  Nodes.IntPoint(2).x = 0.0;
3229  Nodes.IntPoint(2).y = 1.0;
3230  Nodes.IntPoint(2).z = 0.0;
3231  Nodes.IntPoint(3).x = 0.0;
3232  Nodes.IntPoint(3).y = 0.0;
3233  Nodes.IntPoint(3).z = 1.0;
3234 }
3235 
3237  Vector &shape) const
3238 {
3239  shape(0) = 1. - ip.x - ip.y - ip.z;
3240  shape(1) = ip.x;
3241  shape(2) = ip.y;
3242  shape(3) = ip.z;
3243 }
3244 
3246  DenseMatrix &dshape) const
3247 {
3248  if (dshape.Height() == 4)
3249  {
3250  double *A = &dshape(0,0);
3251  A[0] = -1.; A[4] = -1.; A[8] = -1.;
3252  A[1] = 1.; A[5] = 0.; A[9] = 0.;
3253  A[2] = 0.; A[6] = 1.; A[10] = 0.;
3254  A[3] = 0.; A[7] = 0.; A[11] = 1.;
3255  }
3256  else
3257  {
3258  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
3259  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
3260  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
3261  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
3262  }
3263 }
3264 
3265 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
3266 const
3267 {
3268  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
3269 
3270  *ndofs = 3;
3271  *dofs = face_dofs[face];
3272 }
3273 
3274 
3276  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
3277 {
3278  Nodes.IntPoint(0).x = 0.0;
3279  Nodes.IntPoint(0).y = 0.0;
3280  Nodes.IntPoint(0).z = 0.0;
3281  Nodes.IntPoint(1).x = 1.0;
3282  Nodes.IntPoint(1).y = 0.0;
3283  Nodes.IntPoint(1).z = 0.0;
3284  Nodes.IntPoint(2).x = 0.0;
3285  Nodes.IntPoint(2).y = 1.0;
3286  Nodes.IntPoint(2).z = 0.0;
3287  Nodes.IntPoint(3).x = 0.0;
3288  Nodes.IntPoint(3).y = 0.0;
3289  Nodes.IntPoint(3).z = 1.0;
3290  Nodes.IntPoint(4).x = 0.5;
3291  Nodes.IntPoint(4).y = 0.0;
3292  Nodes.IntPoint(4).z = 0.0;
3293  Nodes.IntPoint(5).x = 0.0;
3294  Nodes.IntPoint(5).y = 0.5;
3295  Nodes.IntPoint(5).z = 0.0;
3296  Nodes.IntPoint(6).x = 0.0;
3297  Nodes.IntPoint(6).y = 0.0;
3298  Nodes.IntPoint(6).z = 0.5;
3299  Nodes.IntPoint(7).x = 0.5;
3300  Nodes.IntPoint(7).y = 0.5;
3301  Nodes.IntPoint(7).z = 0.0;
3302  Nodes.IntPoint(8).x = 0.5;
3303  Nodes.IntPoint(8).y = 0.0;
3304  Nodes.IntPoint(8).z = 0.5;
3305  Nodes.IntPoint(9).x = 0.0;
3306  Nodes.IntPoint(9).y = 0.5;
3307  Nodes.IntPoint(9).z = 0.5;
3308 }
3309 
3311  Vector &shape) const
3312 {
3313  double L0, L1, L2, L3;
3314 
3315  L0 = 1. - ip.x - ip.y - ip.z;
3316  L1 = ip.x;
3317  L2 = ip.y;
3318  L3 = ip.z;
3319 
3320  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
3321  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
3322  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
3323  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
3324  shape(4) = 4.0 * L0 * L1;
3325  shape(5) = 4.0 * L0 * L2;
3326  shape(6) = 4.0 * L0 * L3;
3327  shape(7) = 4.0 * L1 * L2;
3328  shape(8) = 4.0 * L1 * L3;
3329  shape(9) = 4.0 * L2 * L3;
3330 }
3331 
3333  DenseMatrix &dshape) const
3334 {
3335  double x, y, z, L0;
3336 
3337  x = ip.x;
3338  y = ip.y;
3339  z = ip.z;
3340  L0 = 1.0 - x - y - z;
3341 
3342  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
3343  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
3344  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
3345  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
3346  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
3347  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
3348  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
3349  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
3350  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
3351  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
3352 }
3353 
3355  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
3356 {
3357  Nodes.IntPoint(0).x = 0.0;
3358  Nodes.IntPoint(0).y = 0.0;
3359  Nodes.IntPoint(0).z = 0.0;
3360 
3361  Nodes.IntPoint(1).x = 1.0;
3362  Nodes.IntPoint(1).y = 0.0;
3363  Nodes.IntPoint(1).z = 0.0;
3364 
3365  Nodes.IntPoint(2).x = 1.0;
3366  Nodes.IntPoint(2).y = 1.0;
3367  Nodes.IntPoint(2).z = 0.0;
3368 
3369  Nodes.IntPoint(3).x = 0.0;
3370  Nodes.IntPoint(3).y = 1.0;
3371  Nodes.IntPoint(3).z = 0.0;
3372 
3373  Nodes.IntPoint(4).x = 0.0;
3374  Nodes.IntPoint(4).y = 0.0;
3375  Nodes.IntPoint(4).z = 1.0;
3376 
3377  Nodes.IntPoint(5).x = 1.0;
3378  Nodes.IntPoint(5).y = 0.0;
3379  Nodes.IntPoint(5).z = 1.0;
3380 
3381  Nodes.IntPoint(6).x = 1.0;
3382  Nodes.IntPoint(6).y = 1.0;
3383  Nodes.IntPoint(6).z = 1.0;
3384 
3385  Nodes.IntPoint(7).x = 0.0;
3386  Nodes.IntPoint(7).y = 1.0;
3387  Nodes.IntPoint(7).z = 1.0;
3388 }
3389 
3391  Vector &shape) const
3392 {
3393  double x = ip.x, y = ip.y, z = ip.z;
3394  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
3395 
3396  shape(0) = ox * oy * oz;
3397  shape(1) = x * oy * oz;
3398  shape(2) = x * y * oz;
3399  shape(3) = ox * y * oz;
3400  shape(4) = ox * oy * z;
3401  shape(5) = x * oy * z;
3402  shape(6) = x * y * z;
3403  shape(7) = ox * y * z;
3404 }
3405 
3407  DenseMatrix &dshape) const
3408 {
3409  double x = ip.x, y = ip.y, z = ip.z;
3410  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
3411 
3412  dshape(0,0) = - oy * oz;
3413  dshape(0,1) = - ox * oz;
3414  dshape(0,2) = - ox * oy;
3415 
3416  dshape(1,0) = oy * oz;
3417  dshape(1,1) = - x * oz;
3418  dshape(1,2) = - x * oy;
3419 
3420  dshape(2,0) = y * oz;
3421  dshape(2,1) = x * oz;
3422  dshape(2,2) = - x * y;
3423 
3424  dshape(3,0) = - y * oz;
3425  dshape(3,1) = ox * oz;
3426  dshape(3,2) = - ox * y;
3427 
3428  dshape(4,0) = - oy * z;
3429  dshape(4,1) = - ox * z;
3430  dshape(4,2) = ox * oy;
3431 
3432  dshape(5,0) = oy * z;
3433  dshape(5,1) = - x * z;
3434  dshape(5,2) = x * oy;
3435 
3436  dshape(6,0) = y * z;
3437  dshape(6,1) = x * z;
3438  dshape(6,2) = x * y;
3439 
3440  dshape(7,0) = - y * z;
3441  dshape(7,1) = ox * z;
3442  dshape(7,2) = ox * y;
3443 }
3444 
3445 
3447  : NodalFiniteElement(1, Geometry::SEGMENT, 1, Ord) // default Ord = 0
3448 {
3449  Nodes.IntPoint(0).x = 0.5;
3450 }
3451 
3453  Vector &shape) const
3454 {
3455  shape(0) = 1.0;
3456 }
3457 
3459  DenseMatrix &dshape) const
3460 {
3461  dshape(0,0) = 0.0;
3462 }
3463 
3465  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
3466 {
3467  Nodes.IntPoint(0).x = 0.5;
3468  Nodes.IntPoint(0).y = 0.0;
3469  Nodes.IntPoint(1).x = 0.5;
3470  Nodes.IntPoint(1).y = 0.5;
3471  Nodes.IntPoint(2).x = 0.0;
3472  Nodes.IntPoint(2).y = 0.5;
3473 }
3474 
3476  Vector &shape) const
3477 {
3478  shape(0) = 1.0 - 2.0 * ip.y;
3479  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
3480  shape(2) = 1.0 - 2.0 * ip.x;
3481 }
3482 
3484  DenseMatrix &dshape) const
3485 {
3486  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
3487  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
3488  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
3489 }
3490 
3492 // the FunctionSpace should be rotated (45 degrees) Q_1
3493 // i.e. the span of { 1, x, y, x^2 - y^2 }
3494  : NodalFiniteElement(2, Geometry::SQUARE, 4, 2, FunctionSpace::Qk)
3495 {
3496  Nodes.IntPoint(0).x = 0.5;
3497  Nodes.IntPoint(0).y = 0.0;
3498  Nodes.IntPoint(1).x = 1.0;
3499  Nodes.IntPoint(1).y = 0.5;
3500  Nodes.IntPoint(2).x = 0.5;
3501  Nodes.IntPoint(2).y = 1.0;
3502  Nodes.IntPoint(3).x = 0.0;
3503  Nodes.IntPoint(3).y = 0.5;
3504 }
3505 
3507  Vector &shape) const
3508 {
3509  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
3510 
3511  shape(0) = l2 * l3;
3512  shape(1) = l1 * l3;
3513  shape(2) = l1 * l4;
3514  shape(3) = l2 * l4;
3515 }
3516 
3518  DenseMatrix &dshape) const
3519 {
3520  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
3521 
3522  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
3523  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
3524  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
3525  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
3526 }
3527 
3528 
3530  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
3531 {
3532  Nodes.IntPoint(0).x = 0.5;
3533  Nodes.IntPoint(0).y = 0.0;
3534  Nodes.IntPoint(1).x = 0.5;
3535  Nodes.IntPoint(1).y = 0.5;
3536  Nodes.IntPoint(2).x = 0.0;
3537  Nodes.IntPoint(2).y = 0.5;
3538 }
3539 
3541  DenseMatrix &shape) const
3542 {
3543  double x = ip.x, y = ip.y;
3544 
3545  shape(0,0) = x;
3546  shape(0,1) = y - 1.;
3547  shape(1,0) = x;
3548  shape(1,1) = y;
3549  shape(2,0) = x - 1.;
3550  shape(2,1) = y;
3551 }
3552 
3554  Vector &divshape) const
3555 {
3556  divshape(0) = 2.;
3557  divshape(1) = 2.;
3558  divshape(2) = 2.;
3559 }
3560 
3561 const double RT0TriangleFiniteElement::nk[3][2] =
3562 { {0, -1}, {1, 1}, {-1, 0} };
3563 
3566 {
3567  int k, j;
3568 #ifdef MFEM_THREAD_SAFE
3570  DenseMatrix Jinv(dim);
3571 #endif
3572 
3573 #ifdef MFEM_DEBUG
3574  for (k = 0; k < 3; k++)
3575  {
3577  for (j = 0; j < 3; j++)
3578  {
3579  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3580  if (j == k) { d -= 1.0; }
3581  if (fabs(d) > 1.0e-12)
3582  {
3583  mfem::err << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
3584  " k = " << k << ", j = " << j << ", d = " << d << endl;
3585  mfem_error();
3586  }
3587  }
3588  }
3589 #endif
3590 
3591  IntegrationPoint ip;
3592  ip.x = ip.y = 0.0;
3593  Trans.SetIntPoint (&ip);
3594  // Trans must be linear
3595  // set Jinv = |J| J^{-t} = adj(J)^t
3596  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3597  double vk[2];
3598  Vector xk (vk, 2);
3599 
3600  for (k = 0; k < 3; k++)
3601  {
3602  Trans.Transform (Nodes.IntPoint (k), xk);
3603  ip.x = vk[0]; ip.y = vk[1];
3604  CalcVShape (ip, vshape);
3605  // vk = |J| J^{-t} nk
3606  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3607  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3608  for (j = 0; j < 3; j++)
3609  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3610  {
3611  I(k,j) = 0.0;
3612  }
3613  }
3614 }
3615 
3618  Vector &dofs) const
3619 {
3620  double vk[2];
3621  Vector xk (vk, 2);
3622 #ifdef MFEM_THREAD_SAFE
3623  DenseMatrix Jinv(dim);
3624 #endif
3625 
3626  for (int k = 0; k < 3; k++)
3627  {
3628  Trans.SetIntPoint (&Nodes.IntPoint (k));
3629  // set Jinv = |J| J^{-t} = adj(J)^t
3630  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3631 
3632  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3633  // xk^t |J| J^{-t} nk
3634  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3635  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3636  }
3637 }
3638 
3640  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
3641 {
3642  Nodes.IntPoint(0).x = 0.5;
3643  Nodes.IntPoint(0).y = 0.0;
3644  Nodes.IntPoint(1).x = 1.0;
3645  Nodes.IntPoint(1).y = 0.5;
3646  Nodes.IntPoint(2).x = 0.5;
3647  Nodes.IntPoint(2).y = 1.0;
3648  Nodes.IntPoint(3).x = 0.0;
3649  Nodes.IntPoint(3).y = 0.5;
3650 }
3651 
3653  DenseMatrix &shape) const
3654 {
3655  double x = ip.x, y = ip.y;
3656 
3657  shape(0,0) = 0;
3658  shape(0,1) = y - 1.;
3659  shape(1,0) = x;
3660  shape(1,1) = 0;
3661  shape(2,0) = 0;
3662  shape(2,1) = y;
3663  shape(3,0) = x - 1.;
3664  shape(3,1) = 0;
3665 }
3666 
3668  Vector &divshape) const
3669 {
3670  divshape(0) = 1.;
3671  divshape(1) = 1.;
3672  divshape(2) = 1.;
3673  divshape(3) = 1.;
3674 }
3675 
3676 const double RT0QuadFiniteElement::nk[4][2] =
3677 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
3678 
3681 {
3682  int k, j;
3683 #ifdef MFEM_THREAD_SAFE
3685  DenseMatrix Jinv(dim);
3686 #endif
3687 
3688 #ifdef MFEM_DEBUG
3689  for (k = 0; k < 4; k++)
3690  {
3692  for (j = 0; j < 4; j++)
3693  {
3694  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3695  if (j == k) { d -= 1.0; }
3696  if (fabs(d) > 1.0e-12)
3697  {
3698  mfem::err << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
3699  " k = " << k << ", j = " << j << ", d = " << d << endl;
3700  mfem_error();
3701  }
3702  }
3703  }
3704 #endif
3705 
3706  IntegrationPoint ip;
3707  ip.x = ip.y = 0.0;
3708  Trans.SetIntPoint (&ip);
3709  // Trans must be linear (more to have embedding?)
3710  // set Jinv = |J| J^{-t} = adj(J)^t
3711  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3712  double vk[2];
3713  Vector xk (vk, 2);
3714 
3715  for (k = 0; k < 4; k++)
3716  {
3717  Trans.Transform (Nodes.IntPoint (k), xk);
3718  ip.x = vk[0]; ip.y = vk[1];
3719  CalcVShape (ip, vshape);
3720  // vk = |J| J^{-t} nk
3721  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3722  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3723  for (j = 0; j < 4; j++)
3724  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3725  {
3726  I(k,j) = 0.0;
3727  }
3728  }
3729 }
3730 
3733  Vector &dofs) const
3734 {
3735  double vk[2];
3736  Vector xk (vk, 2);
3737 #ifdef MFEM_THREAD_SAFE
3738  DenseMatrix Jinv(dim);
3739 #endif
3740 
3741  for (int k = 0; k < 4; k++)
3742  {
3743  Trans.SetIntPoint (&Nodes.IntPoint (k));
3744  // set Jinv = |J| J^{-t} = adj(J)^t
3745  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3746 
3747  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3748  // xk^t |J| J^{-t} nk
3749  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3750  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3751  }
3752 }
3753 
3755  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
3756 {
3757  Nodes.IntPoint(0).x = 0.33333333333333333333;
3758  Nodes.IntPoint(0).y = 0.0;
3759  Nodes.IntPoint(1).x = 0.66666666666666666667;
3760  Nodes.IntPoint(1).y = 0.0;
3761  Nodes.IntPoint(2).x = 0.66666666666666666667;
3762  Nodes.IntPoint(2).y = 0.33333333333333333333;
3763  Nodes.IntPoint(3).x = 0.33333333333333333333;
3764  Nodes.IntPoint(3).y = 0.66666666666666666667;
3765  Nodes.IntPoint(4).x = 0.0;
3766  Nodes.IntPoint(4).y = 0.66666666666666666667;
3767  Nodes.IntPoint(5).x = 0.0;
3768  Nodes.IntPoint(5).y = 0.33333333333333333333;
3769  Nodes.IntPoint(6).x = 0.33333333333333333333;
3770  Nodes.IntPoint(6).y = 0.33333333333333333333;
3771  Nodes.IntPoint(7).x = 0.33333333333333333333;
3772  Nodes.IntPoint(7).y = 0.33333333333333333333;
3773 }
3774 
3776  DenseMatrix &shape) const
3777 {
3778  double x = ip.x, y = ip.y;
3779 
3780  shape(0,0) = -2 * x * (-1 + x + 2 * y);
3781  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
3782  shape(1,0) = 2 * x * (x - y);
3783  shape(1,1) = 2 * (x - y) * (-1 + y);
3784  shape(2,0) = 2 * x * (-1 + 2 * x + y);
3785  shape(2,1) = 2 * y * (-1 + 2 * x + y);
3786  shape(3,0) = 2 * x * (-1 + x + 2 * y);
3787  shape(3,1) = 2 * y * (-1 + x + 2 * y);
3788  shape(4,0) = -2 * (-1 + x) * (x - y);
3789  shape(4,1) = 2 * y * (-x + y);
3790  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
3791  shape(5,1) = -2 * y * (-1 + 2 * x + y);
3792  shape(6,0) = -3 * x * (-2 + 2 * x + y);
3793  shape(6,1) = -3 * y * (-1 + 2 * x + y);
3794  shape(7,0) = -3 * x * (-1 + x + 2 * y);
3795  shape(7,1) = -3 * y * (-2 + x + 2 * y);
3796 }
3797 
3799  Vector &divshape) const
3800 {
3801  double x = ip.x, y = ip.y;
3802 
3803  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
3804  divshape(1) = 2 + 6 * x - 6 * y;
3805  divshape(2) = -4 + 12 * x + 6 * y;
3806  divshape(3) = -4 + 6 * x + 12 * y;
3807  divshape(4) = 2 - 6 * x + 6 * y;
3808  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
3809  divshape(6) = -9 * (-1 + 2 * x + y);
3810  divshape(7) = -9 * (-1 + x + 2 * y);
3811 }
3812 
3813 const double RT1TriangleFiniteElement::nk[8][2] =
3814 {
3815  { 0,-1}, { 0,-1},
3816  { 1, 1}, { 1, 1},
3817  {-1, 0}, {-1, 0},
3818  { 1, 0}, { 0, 1}
3819 };
3820 
3823 {
3824  int k, j;
3825 #ifdef MFEM_THREAD_SAFE
3827  DenseMatrix Jinv(dim);
3828 #endif
3829 
3830 #ifdef MFEM_DEBUG
3831  for (k = 0; k < 8; k++)
3832  {
3834  for (j = 0; j < 8; j++)
3835  {
3836  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3837  if (j == k) { d -= 1.0; }
3838  if (fabs(d) > 1.0e-12)
3839  {
3840  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3841  " k = " << k << ", j = " << j << ", d = " << d << endl;
3842  mfem_error();
3843  }
3844  }
3845  }
3846 #endif
3847 
3848  IntegrationPoint ip;
3849  ip.x = ip.y = 0.0;
3850  Trans.SetIntPoint (&ip);
3851  // Trans must be linear (more to have embedding?)
3852  // set Jinv = |J| J^{-t} = adj(J)^t
3853  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3854  double vk[2];
3855  Vector xk (vk, 2);
3856 
3857  for (k = 0; k < 8; k++)
3858  {
3859  Trans.Transform (Nodes.IntPoint (k), xk);
3860  ip.x = vk[0]; ip.y = vk[1];
3861  CalcVShape (ip, vshape);
3862  // vk = |J| J^{-t} nk
3863  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3864  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3865  for (j = 0; j < 8; j++)
3866  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3867  {
3868  I(k,j) = 0.0;
3869  }
3870  }
3871 }
3872 
3875 {
3876  double vk[2];
3877  Vector xk (vk, 2);
3878 #ifdef MFEM_THREAD_SAFE
3879  DenseMatrix Jinv(dim);
3880 #endif
3881 
3882  for (int k = 0; k < 8; k++)
3883  {
3884  Trans.SetIntPoint (&Nodes.IntPoint (k));
3885  // set Jinv = |J| J^{-t} = adj(J)^t
3886  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3887 
3888  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3889  // xk^t |J| J^{-t} nk
3890  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3891  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3892  dofs(k) *= 0.5;
3893  }
3894 }
3895 
3897  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
3898 {
3899  // y = 0
3900  Nodes.IntPoint(0).x = 1./3.;
3901  Nodes.IntPoint(0).y = 0.0;
3902  Nodes.IntPoint(1).x = 2./3.;
3903  Nodes.IntPoint(1).y = 0.0;
3904  // x = 1
3905  Nodes.IntPoint(2).x = 1.0;
3906  Nodes.IntPoint(2).y = 1./3.;
3907  Nodes.IntPoint(3).x = 1.0;
3908  Nodes.IntPoint(3).y = 2./3.;
3909  // y = 1
3910  Nodes.IntPoint(4).x = 2./3.;
3911  Nodes.IntPoint(4).y = 1.0;
3912  Nodes.IntPoint(5).x = 1./3.;
3913  Nodes.IntPoint(5).y = 1.0;
3914  // x = 0
3915  Nodes.IntPoint(6).x = 0.0;
3916  Nodes.IntPoint(6).y = 2./3.;
3917  Nodes.IntPoint(7).x = 0.0;
3918  Nodes.IntPoint(7).y = 1./3.;
3919  // x = 0.5 (interior)
3920  Nodes.IntPoint(8).x = 0.5;
3921  Nodes.IntPoint(8).y = 1./3.;
3922  Nodes.IntPoint(9).x = 0.5;
3923  Nodes.IntPoint(9).y = 2./3.;
3924  // y = 0.5 (interior)
3925  Nodes.IntPoint(10).x = 1./3.;
3926  Nodes.IntPoint(10).y = 0.5;
3927  Nodes.IntPoint(11).x = 2./3.;
3928  Nodes.IntPoint(11).y = 0.5;
3929 }
3930 
3932  DenseMatrix &shape) const
3933 {
3934  double x = ip.x, y = ip.y;
3935 
3936  // y = 0
3937  shape(0,0) = 0;
3938  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
3939  shape(1,0) = 0;
3940  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
3941  // x = 1
3942  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
3943  shape(2,1) = 0;
3944  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
3945  shape(3,1) = 0;
3946  // y = 1
3947  shape(4,0) = 0;
3948  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
3949  shape(5,0) = 0;
3950  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
3951  // x = 0
3952  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
3953  shape(6,1) = 0;
3954  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
3955  shape(7,1) = 0;
3956  // x = 0.5 (interior)
3957  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
3958  shape(8,1) = 0;
3959  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
3960  shape(9,1) = 0;
3961  // y = 0.5 (interior)
3962  shape(10,0) = 0;
3963  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
3964  shape(11,0) = 0;
3965  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
3966 }
3967 
3969  Vector &divshape) const
3970 {
3971  double x = ip.x, y = ip.y;
3972 
3973  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
3974  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
3975  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
3976  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
3977  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
3978  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
3979  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
3980  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
3981  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
3982  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
3983  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
3984  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
3985 }
3986 
3987 const double RT1QuadFiniteElement::nk[12][2] =
3988 {
3989  // y = 0
3990  {0,-1}, {0,-1},
3991  // X = 1
3992  {1, 0}, {1, 0},
3993  // y = 1
3994  {0, 1}, {0, 1},
3995  // x = 0
3996  {-1,0}, {-1,0},
3997  // x = 0.5 (interior)
3998  {1, 0}, {1, 0},
3999  // y = 0.5 (interior)
4000  {0, 1}, {0, 1}
4001 };
4002 
4005 {
4006  int k, j;
4007 #ifdef MFEM_THREAD_SAFE
4009  DenseMatrix Jinv(dim);
4010 #endif
4011 
4012 #ifdef MFEM_DEBUG
4013  for (k = 0; k < 12; k++)
4014  {
4016  for (j = 0; j < 12; j++)
4017  {
4018  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
4019  if (j == k) { d -= 1.0; }
4020  if (fabs(d) > 1.0e-12)
4021  {
4022  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
4023  " k = " << k << ", j = " << j << ", d = " << d << endl;
4024  mfem_error();
4025  }
4026  }
4027  }
4028 #endif
4029 
4030  IntegrationPoint ip;
4031  ip.x = ip.y = 0.0;
4032  Trans.SetIntPoint (&ip);
4033  // Trans must be linear (more to have embedding?)
4034  // set Jinv = |J| J^{-t} = adj(J)^t
4035  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
4036  double vk[2];
4037  Vector xk (vk, 2);
4038 
4039  for (k = 0; k < 12; k++)
4040  {
4041  Trans.Transform (Nodes.IntPoint (k), xk);
4042  ip.x = vk[0]; ip.y = vk[1];
4043  CalcVShape (ip, vshape);
4044  // vk = |J| J^{-t} nk
4045  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
4046  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
4047  for (j = 0; j < 12; j++)
4048  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
4049  {
4050  I(k,j) = 0.0;
4051  }
4052  }
4053 }
4054 
4057 {
4058  double vk[2];
4059  Vector xk (vk, 2);
4060 #ifdef MFEM_THREAD_SAFE
4061  DenseMatrix Jinv(dim);
4062 #endif
4063 
4064  for (int k = 0; k < 12; k++)
4065  {
4066  Trans.SetIntPoint (&Nodes.IntPoint (k));
4067  // set Jinv = |J| J^{-t} = adj(J)^t
4068  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
4069 
4070  vc.Eval (xk, Trans, Nodes.IntPoint (k));
4071  // xk^t |J| J^{-t} nk
4072  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
4073  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
4074  }
4075 }
4076 
4077 const double RT2TriangleFiniteElement::M[15][15] =
4078 {
4079  {
4080  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
4081  0, 24.442740046346700787, -16.647580015448900262, -12.,
4082  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
4083  12., 30.590320061795601049, 15.295160030897800524
4084  },
4085  {
4086  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
4087  -15., 10.5
4088  },
4089  {
4090  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
4091  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
4092  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
4093  12., -6.5903200617956010489, -3.2951600308978005244
4094  },
4095  {
4096  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
4097  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
4098  0, -3.2951600308978005244
4099  },
4100  {
4101  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
4102  36., 10.5
4103  },
4104  {
4105  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
4106  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
4107  0, 15.295160030897800524
4108  },
4109  {
4110  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
4111  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
4112  -0.76209992275549868892, 4.1189500386222506555, -12.,
4113  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
4114  12.
4115  },
4116  {
4117  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
4118  -15., -15.
4119  },
4120  {
4121  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
4122  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
4123  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
4124  30.590320061795601049, 12.
4125  },
4126  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
4127  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
4128  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
4129  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
4130  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
4131  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
4132 };
4133 
4135  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
4136 {
4137  const double p = 0.11270166537925831148;
4138 
4139  Nodes.IntPoint(0).x = p;
4140  Nodes.IntPoint(0).y = 0.0;
4141  Nodes.IntPoint(1).x = 0.5;
4142  Nodes.IntPoint(1).y = 0.0;
4143  Nodes.IntPoint(2).x = 1.-p;
4144  Nodes.IntPoint(2).y = 0.0;
4145  Nodes.IntPoint(3).x = 1.-p;
4146  Nodes.IntPoint(3).y = p;
4147  Nodes.IntPoint(4).x = 0.5;
4148  Nodes.IntPoint(4).y = 0.5;
4149  Nodes.IntPoint(5).x = p;
4150  Nodes.IntPoint(5).y = 1.-p;
4151  Nodes.IntPoint(6).x = 0.0;
4152  Nodes.IntPoint(6).y = 1.-p;
4153  Nodes.IntPoint(7).x = 0.0;
4154  Nodes.IntPoint(7).y = 0.5;
4155  Nodes.IntPoint(8).x = 0.0;
4156  Nodes.IntPoint(8).y = p;
4157  Nodes.IntPoint(9).x = 0.25;
4158  Nodes.IntPoint(9).y = 0.25;
4159  Nodes.IntPoint(10).x = 0.25;
4160  Nodes.IntPoint(10).y = 0.25;
4161  Nodes.IntPoint(11).x = 0.5;
4162  Nodes.IntPoint(11).y = 0.25;
4163  Nodes.IntPoint(12).x = 0.5;
4164  Nodes.IntPoint(12).y = 0.25;
4165  Nodes.IntPoint(13).x = 0.25;
4166  Nodes.IntPoint(13).y = 0.5;
4167  Nodes.IntPoint(14).x = 0.25;
4168  Nodes.IntPoint(14).y = 0.5;
4169 }
4170 
4172  DenseMatrix &shape) const
4173 {
4174  double x = ip.x, y = ip.y;
4175 
4176  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
4177  x*x*y, x*y*y
4178  };
4179  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
4180  x*x*y, x*y*y, y*y*y
4181  };
4182 
4183  for (int i = 0; i < 15; i++)
4184  {
4185  double cx = 0.0, cy = 0.0;
4186  for (int j = 0; j < 15; j++)
4187  {
4188  cx += M[i][j] * Bx[j];
4189  cy += M[i][j] * By[j];
4190  }
4191  shape(i,0) = cx;
4192  shape(i,1) = cy;
4193  }
4194 }
4195 
4197  Vector &divshape) const
4198 {
4199  double x = ip.x, y = ip.y;
4200 
4201  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
4202  4.*x*x, 4.*x*y, 4.*y*y
4203  };
4204 
4205  for (int i = 0; i < 15; i++)
4206  {
4207  double div = 0.0;
4208  for (int j = 0; j < 15; j++)
4209  {
4210  div += M[i][j] * DivB[j];
4211  }
4212  divshape(i) = div;
4213  }
4214 }
4215 
4216 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
4217 
4218 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
4219 
4221  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
4222 {
4223  // y = 0 (pt[0])
4224  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
4225  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
4226  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
4227  // x = 1 (pt[3])
4228  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
4229  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
4230  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
4231  // y = 1 (pt[3])
4232  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
4233  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
4234  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
4235  // x = 0 (pt[0])
4236  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
4237  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
4238  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
4239  // x = pt[1] (interior)
4240  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
4241  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
4242  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
4243  // x = pt[2] (interior)
4244  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
4245  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
4246  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
4247  // y = pt[1] (interior)
4248  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
4249  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
4250  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
4251  // y = pt[2] (interior)
4252  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
4253  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
4254  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
4255 }
4256 
4258  DenseMatrix &shape) const
4259 {
4260  double x = ip.x, y = ip.y;
4261 
4262  double ax0 = pt[0] - x;
4263  double ax1 = pt[1] - x;
4264  double ax2 = pt[2] - x;
4265  double ax3 = pt[3] - x;
4266 
4267  double by0 = dpt[0] - y;
4268  double by1 = dpt[1] - y;
4269  double by2 = dpt[2] - y;
4270 
4271  double ay0 = pt[0] - y;
4272  double ay1 = pt[1] - y;
4273  double ay2 = pt[2] - y;
4274  double ay3 = pt[3] - y;
4275 
4276  double bx0 = dpt[0] - x;
4277  double bx1 = dpt[1] - x;
4278  double bx2 = dpt[2] - x;
4279 
4280  double A01 = pt[0] - pt[1];
4281  double A02 = pt[0] - pt[2];
4282  double A12 = pt[1] - pt[2];
4283  double A03 = pt[0] - pt[3];
4284  double A13 = pt[1] - pt[3];
4285  double A23 = pt[2] - pt[3];
4286 
4287  double B01 = dpt[0] - dpt[1];
4288  double B02 = dpt[0] - dpt[2];
4289  double B12 = dpt[1] - dpt[2];
4290 
4291  double tx0 = (bx1*bx2)/(B01*B02);
4292  double tx1 = -(bx0*bx2)/(B01*B12);
4293  double tx2 = (bx0*bx1)/(B02*B12);
4294 
4295  double ty0 = (by1*by2)/(B01*B02);
4296  double ty1 = -(by0*by2)/(B01*B12);
4297  double ty2 = (by0*by1)/(B02*B12);
4298 
4299  // y = 0 (p[0])
4300  shape(0, 0) = 0;
4301  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
4302  shape(1, 0) = 0;
4303  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
4304  shape(2, 0) = 0;
4305  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
4306  // x = 1 (p[3])
4307  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
4308  shape(3, 1) = 0;
4309  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
4310  shape(4, 1) = 0;
4311  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
4312  shape(5, 1) = 0;
4313  // y = 1 (p[3])
4314  shape(6, 0) = 0;
4315  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
4316  shape(7, 0) = 0;
4317  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
4318  shape(8, 0) = 0;
4319  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
4320  // x = 0 (p[0])
4321  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
4322  shape(9, 1) = 0;
4323  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
4324  shape(10, 1) = 0;
4325  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
4326  shape(11, 1) = 0;
4327  // x = p[1] (interior)
4328  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
4329  shape(12, 1) = 0;
4330  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
4331  shape(13, 1) = 0;
4332  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
4333  shape(14, 1) = 0;
4334  // x = p[2] (interior)
4335  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
4336  shape(15, 1) = 0;
4337  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
4338  shape(16, 1) = 0;
4339  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
4340  shape(17, 1) = 0;
4341  // y = p[1] (interior)
4342  shape(18, 0) = 0;
4343  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
4344  shape(19, 0) = 0;
4345  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
4346  shape(20, 0) = 0;
4347  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
4348  // y = p[2] (interior)
4349  shape(21, 0) = 0;
4350  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
4351  shape(22, 0) = 0;
4352  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
4353  shape(23, 0) = 0;
4354  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
4355 }
4356 
4358  Vector &divshape) const
4359 {
4360  double x = ip.x, y = ip.y;
4361 
4362  double a01 = pt[0]*pt[1];
4363  double a02 = pt[0]*pt[2];
4364  double a12 = pt[1]*pt[2];
4365  double a03 = pt[0]*pt[3];
4366  double a13 = pt[1]*pt[3];
4367  double a23 = pt[2]*pt[3];
4368 
4369  double bx0 = dpt[0] - x;
4370  double bx1 = dpt[1] - x;
4371  double bx2 = dpt[2] - x;
4372 
4373  double by0 = dpt[0] - y;
4374  double by1 = dpt[1] - y;
4375  double by2 = dpt[2] - y;
4376 
4377  double A01 = pt[0] - pt[1];
4378  double A02 = pt[0] - pt[2];
4379  double A12 = pt[1] - pt[2];
4380  double A03 = pt[0] - pt[3];
4381  double A13 = pt[1] - pt[3];
4382  double A23 = pt[2] - pt[3];
4383 
4384  double A012 = pt[0] + pt[1] + pt[2];
4385  double A013 = pt[0] + pt[1] + pt[3];
4386  double A023 = pt[0] + pt[2] + pt[3];
4387  double A123 = pt[1] + pt[2] + pt[3];
4388 
4389  double B01 = dpt[0] - dpt[1];
4390  double B02 = dpt[0] - dpt[2];
4391  double B12 = dpt[1] - dpt[2];
4392 
4393  double tx0 = (bx1*bx2)/(B01*B02);
4394  double tx1 = -(bx0*bx2)/(B01*B12);
4395  double tx2 = (bx0*bx1)/(B02*B12);
4396 
4397  double ty0 = (by1*by2)/(B01*B02);
4398  double ty1 = -(by0*by2)/(B01*B12);
4399  double ty2 = (by0*by1)/(B02*B12);
4400 
4401  // y = 0 (p[0])
4402  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
4403  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
4404  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
4405  // x = 1 (p[3])
4406  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
4407  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
4408  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
4409  // y = 1 (p[3])
4410  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
4411  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
4412  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
4413  // x = 0 (p[0])
4414  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
4415  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
4416  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
4417  // x = p[1] (interior)
4418  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
4419  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
4420  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
4421  // x = p[2] (interior)
4422  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
4423  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
4424  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
4425  // y = p[1] (interior)
4426  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
4427  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
4428  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
4429  // y = p[2] (interior)
4430  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
4431  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
4432  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
4433 }
4434 
4435 const double RT2QuadFiniteElement::nk[24][2] =
4436 {
4437  // y = 0
4438  {0,-1}, {0,-1}, {0,-1},
4439  // x = 1
4440  {1, 0}, {1, 0}, {1, 0},
4441  // y = 1
4442  {0, 1}, {0, 1}, {0, 1},
4443  // x = 0
4444  {-1,0}, {-1,0}, {-1,0},
4445  // x = p[1] (interior)
4446  {1, 0}, {1, 0}, {1, 0},
4447  // x = p[2] (interior)
4448  {1, 0}, {1, 0}, {1, 0},
4449  // y = p[1] (interior)
4450  {0, 1}, {0, 1}, {0, 1},
4451  // y = p[1] (interior)
4452  {0, 1}, {0, 1}, {0, 1}
4453 };
4454 
4457 {
4458  int k, j;
4459 #ifdef MFEM_THREAD_SAFE
4461  DenseMatrix Jinv(dim);
4462 #endif
4463 
4464 #ifdef MFEM_DEBUG
4465  for (k = 0; k < 24; k++)
4466  {
4468  for (j = 0; j < 24; j++)
4469  {
4470  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
4471  if (j == k) { d -= 1.0; }
4472  if (fabs(d) > 1.0e-12)
4473  {
4474  mfem::err << "RT2QuadFiniteElement::GetLocalInterpolation (...)\n"
4475  " k = " << k << ", j = " << j << ", d = " << d << endl;
4476  mfem_error();
4477  }
4478  }
4479  }
4480 #endif
4481 
4482  IntegrationPoint ip;
4483  ip.x = ip.y = 0.0;
4484  Trans.SetIntPoint (&ip);
4485  // Trans must be linear (more to have embedding?)
4486  // set Jinv = |J| J^{-t} = adj(J)^t
4487  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
4488  double vk[2];
4489  Vector xk (vk, 2);
4490 
4491  for (k = 0; k < 24; k++)
4492  {
4493  Trans.Transform (Nodes.IntPoint (k), xk);
4494  ip.x = vk[0]; ip.y = vk[1];
4495  CalcVShape (ip, vshape);
4496  // vk = |J| J^{-t} nk
4497  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
4498  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
4499  for (j = 0; j < 24; j++)
4500  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
4501  {
4502  I(k,j) = 0.0;
4503  }
4504  }
4505 }
4506 
4509 {
4510  double vk[2];
4511  Vector xk (vk, 2);
4512 #ifdef MFEM_THREAD_SAFE
4513  DenseMatrix Jinv(dim);
4514 #endif
4515 
4516  for (int k = 0; k < 24; k++)
4517  {
4518  Trans.SetIntPoint (&Nodes.IntPoint (k));
4519  // set Jinv = |J| J^{-t} = adj(J)^t
4520  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
4521 
4522  vc.Eval (xk, Trans, Nodes.IntPoint (k));
4523  // xk^t |J| J^{-t} nk
4524  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
4525  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
4526  }
4527 }
4528 
4530  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
4531 {
4532  Nodes.IntPoint(0).x = 0.33333333333333333333;
4533  Nodes.IntPoint(1).x = 0.66666666666666666667;
4534 }
4535 
4537  Vector &shape) const
4538 {
4539  double x = ip.x;
4540 
4541  shape(0) = 2. - 3. * x;
4542  shape(1) = 3. * x - 1.;
4543 }
4544 
4546  DenseMatrix &dshape) const
4547 {
4548  dshape(0,0) = -3.;
4549  dshape(1,0) = 3.;
4550 }
4551 
4552 
4554  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
4555 {
4556  const double p = 0.11270166537925831148;
4557 
4558  Nodes.IntPoint(0).x = p;
4559  Nodes.IntPoint(1).x = 0.5;
4560  Nodes.IntPoint(2).x = 1.-p;
4561 }
4562 
4564  Vector &shape) const
4565 {
4566  const double p = 0.11270166537925831148;
4567  const double w = 1./((1-2*p)*(1-2*p));
4568  double x = ip.x;
4569 
4570  shape(0) = (2*x-1)*(x-1+p)*w;
4571  shape(1) = 4*(x-1+p)*(p-x)*w;
4572  shape(2) = (2*x-1)*(x-p)*w;
4573 }
4574 
4576  DenseMatrix &dshape) const
4577 {
4578  const double p = 0.11270166537925831148;
4579  const double w = 1./((1-2*p)*(1-2*p));
4580  double x = ip.x;
4581 
4582  dshape(0,0) = (-3+4*x+2*p)*w;
4583  dshape(1,0) = (4-8*x)*w;
4584  dshape(2,0) = (-1+4*x-2*p)*w;
4585 }
4586 
4587 
4589  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
4590 {
4591  int i, m = degree;
4592 
4593  Nodes.IntPoint(0).x = 0.0;
4594  Nodes.IntPoint(1).x = 1.0;
4595  for (i = 1; i < m; i++)
4596  {
4597  Nodes.IntPoint(i+1).x = double(i) / m;
4598  }
4599 
4600  rwk.SetSize(degree+1);
4601 #ifndef MFEM_THREAD_SAFE
4602  rxxk.SetSize(degree+1);
4603 #endif
4604 
4605  rwk(0) = 1.0;
4606  for (i = 1; i <= m; i++)
4607  {
4608  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
4609  }
4610  for (i = 0; i < m/2+1; i++)
4611  {
4612  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
4613  }
4614  for (i = m-1; i >= 0; i -= 2)
4615  {
4616  rwk(i) = -rwk(i);
4617  }
4618 }
4619 
4621  Vector &shape) const
4622 {
4623  double w, wk, x = ip.x;
4624  int i, k, m = GetOrder();
4625 
4626 #ifdef MFEM_THREAD_SAFE
4627  Vector rxxk(m+1);
4628 #endif
4629 
4630  k = (int) floor ( m * x + 0.5 );
4631  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
4632 
4633  wk = 1.0;
4634  for (i = 0; i <= m; i++)
4635  if (i != k)
4636  {
4637  wk *= ( rxxk(i) = x - (double)(i) / m );
4638  }
4639  w = wk * ( rxxk(k) = x - (double)(k) / m );
4640 
4641  if (k != 0)
4642  {
4643  shape(0) = w * rwk(0) / rxxk(0);
4644  }
4645  else
4646  {
4647  shape(0) = wk * rwk(0);
4648  }
4649  if (k != m)
4650  {
4651  shape(1) = w * rwk(m) / rxxk(m);
4652  }
4653  else
4654  {
4655  shape(1) = wk * rwk(k);
4656  }
4657  for (i = 1; i < m; i++)
4658  if (i != k)
4659  {
4660  shape(i+1) = w * rwk(i) / rxxk(i);
4661  }
4662  else
4663  {
4664  shape(k+1) = wk * rwk(k);
4665  }
4666 }
4667 
4669  DenseMatrix &dshape) const
4670 {
4671  double s, srx, w, wk, x = ip.x;
4672  int i, k, m = GetOrder();
4673 
4674 #ifdef MFEM_THREAD_SAFE
4675  Vector rxxk(m+1);
4676 #endif
4677 
4678  k = (int) floor ( m * x + 0.5 );
4679  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
4680 
4681  wk = 1.0;
4682  for (i = 0; i <= m; i++)
4683  if (i != k)
4684  {
4685  wk *= ( rxxk(i) = x - (double)(i) / m );
4686  }
4687  w = wk * ( rxxk(k) = x - (double)(k) / m );
4688 
4689  for (i = 0; i <= m; i++)
4690  {
4691  rxxk(i) = 1.0 / rxxk(i);
4692  }
4693  srx = 0.0;
4694  for (i = 0; i <= m; i++)
4695  if (i != k)
4696  {
4697  srx += rxxk(i);
4698  }
4699  s = w * srx + wk;
4700 
4701  if (k != 0)
4702  {
4703  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
4704  }
4705  else
4706  {
4707  dshape(0,0) = wk * srx * rwk(0);
4708  }
4709  if (k != m)
4710  {
4711  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
4712  }
4713  else
4714  {
4715  dshape(1,0) = wk * srx * rwk(k);
4716  }
4717  for (i = 1; i < m; i++)
4718  if (i != k)
4719  {
4720  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
4721  }
4722  else
4723  {
4724  dshape(k+1,0) = wk * srx * rwk(k);
4725  }
4726 }
4727 
4728 
4730  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
4731 {
4732  Nodes.IntPoint(0).x = 0.33333333333333333333;
4733  Nodes.IntPoint(0).y = 0.33333333333333333333;
4734  Nodes.IntPoint(0).z = 0.33333333333333333333;
4735 
4736  Nodes.IntPoint(1).x = 0.0;
4737  Nodes.IntPoint(1).y = 0.33333333333333333333;
4738  Nodes.IntPoint(1).z = 0.33333333333333333333;
4739 
4740  Nodes.IntPoint(2).x = 0.33333333333333333333;
4741  Nodes.IntPoint(2).y = 0.0;
4742  Nodes.IntPoint(2).z = 0.33333333333333333333;
4743 
4744  Nodes.IntPoint(3).x = 0.33333333333333333333;
4745  Nodes.IntPoint(3).y = 0.33333333333333333333;
4746  Nodes.IntPoint(3).z = 0.0;
4747 
4748 }
4749 
4751  Vector &shape) const
4752 {
4753  double L0, L1, L2, L3;
4754 
4755  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
4756  shape(0) = 1.0 - 3.0 * L0;
4757  shape(1) = 1.0 - 3.0 * L1;
4758  shape(2) = 1.0 - 3.0 * L2;
4759  shape(3) = 1.0 - 3.0 * L3;
4760 }
4761 
4763  DenseMatrix &dshape) const
4764 {
4765  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
4766  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
4767  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
4768  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
4769 }
4770 
4771 
4773  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 1, 0)
4774 {
4775  Nodes.IntPoint(0).x = 0.25;
4776  Nodes.IntPoint(0).y = 0.25;
4777  Nodes.IntPoint(0).z = 0.25;
4778 }
4779 
4781  Vector &shape) const
4782 {
4783  shape(0) = 1.0;
4784 }
4785 
4787  DenseMatrix &dshape) const
4788 {
4789  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
4790 }
4791 
4792 
4794  : NodalFiniteElement(3, Geometry::CUBE, 1, 0, FunctionSpace::Qk)
4795 {
4796  Nodes.IntPoint(0).x = 0.5;
4797  Nodes.IntPoint(0).y = 0.5;
4798  Nodes.IntPoint(0).z = 0.5;
4799 }
4800 
4802  Vector &shape) const
4803 {
4804  shape(0) = 1.0;
4805 }
4806 
4808  DenseMatrix &dshape) const
4809 {
4810  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
4811 }
4812 
4813 
4815  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
4816  degree, FunctionSpace::Qk)
4817 {
4818  if (degree == 2)
4819  {
4820  I = new int[dof];
4821  J = new int[dof];
4822  K = new int[dof];
4823  // nodes
4824  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
4825  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
4826  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
4827  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
4828  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
4829  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
4830  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
4831  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
4832  // edges
4833  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
4834  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
4835  I[10] = 2; J[10] = 1; K[10] = 0;
4836  I[11] = 0; J[11] = 2; K[11] = 0;
4837  I[12] = 2; J[12] = 0; K[12] = 1;
4838  I[13] = 1; J[13] = 2; K[13] = 1;
4839  I[14] = 2; J[14] = 1; K[14] = 1;
4840  I[15] = 0; J[15] = 2; K[15] = 1;
4841  I[16] = 0; J[16] = 0; K[16] = 2;
4842  I[17] = 1; J[17] = 0; K[17] = 2;
4843  I[18] = 1; J[18] = 1; K[18] = 2;
4844  I[19] = 0; J[19] = 1; K[19] = 2;
4845  // faces
4846  I[20] = 2; J[20] = 2; K[20] = 0;
4847  I[21] = 2; J[21] = 0; K[21] = 2;
4848  I[22] = 1; J[22] = 2; K[22] = 2;
4849  I[23] = 2; J[23] = 1; K[23] = 2;
4850  I[24] = 0; J[24] = 2; K[24] = 2;
4851  I[25] = 2; J[25] = 2; K[25] = 1;
4852  // element
4853  I[26] = 2; J[26] = 2; K[26] = 2;
4854  }
4855  else if (degree == 3)
4856  {
4857  I = new int[dof];
4858  J = new int[dof];
4859  K = new int[dof];
4860  // nodes
4861  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
4862  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
4863  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
4864  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
4865  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
4866  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
4867  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
4868  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
4869  // edges
4870  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
4871  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
4872  I[10] = 1; J[10] = 2; K[10] = 0;
4873  I[11] = 1; J[11] = 3; K[11] = 0;
4874  I[12] = 2; J[12] = 1; K[12] = 0;
4875  I[13] = 3; J[13] = 1; K[13] = 0;
4876  I[14] = 0; J[14] = 2; K[14] = 0;
4877  I[15] = 0; J[15] = 3; K[15] = 0;
4878  I[16] = 2; J[16] = 0; K[16] = 1;
4879  I[17] = 3; J[17] = 0; K[17] = 1;
4880  I[18] = 1; J[18] = 2; K[18] = 1;
4881  I[19] = 1; J[19] = 3; K[19] = 1;
4882  I[20] = 2; J[20] = 1; K[20] = 1;
4883  I[21] = 3; J[21] = 1; K[21] = 1;
4884  I[22] = 0; J[22] = 2; K[22] = 1;
4885  I[23] = 0; J[23] = 3; K[23] = 1;
4886  I[24] = 0; J[24] = 0; K[24] = 2;
4887  I[25] = 0; J[25] = 0; K[25] = 3;
4888  I[26] = 1; J[26] = 0; K[26] = 2;
4889  I[27] = 1; J[27] = 0; K[27] = 3;
4890  I[28] = 1; J[28] = 1; K[28] = 2;
4891  I[29] = 1; J[29] = 1; K[29] = 3;
4892  I[30] = 0; J[30] = 1; K[30] = 2;
4893  I[31] = 0; J[31] = 1; K[31] = 3;
4894  // faces
4895  I[32] = 2; J[32] = 3; K[32] = 0;
4896  I[33] = 3; J[33] = 3; K[33] = 0;
4897  I[34] = 2; J[34] = 2; K[34] = 0;
4898  I[35] = 3; J[35] = 2; K[35] = 0;
4899  I[36] = 2; J[36] = 0; K[36] = 2;
4900  I[37] = 3; J[37] = 0; K[37] = 2;
4901  I[38] = 2; J[38] = 0; K[38] = 3;
4902  I[39] = 3; J[39] = 0; K[39] = 3;
4903  I[40] = 1; J[40] = 2; K[40] = 2;
4904  I[41] = 1; J[41] = 3; K[41] = 2;
4905  I[42] = 1; J[42] = 2; K[42] = 3;
4906  I[43] = 1; J[43] = 3; K[43] = 3;
4907  I[44] = 3; J[44] = 1; K[44] = 2;
4908  I[45] = 2; J[45] = 1; K[45] = 2;
4909  I[46] = 3; J[46] = 1; K[46] = 3;
4910  I[47] = 2; J[47] = 1; K[47] = 3;
4911  I[48] = 0; J[48] = 3; K[48] = 2;
4912  I[49] = 0; J[49] = 2; K[49] = 2;
4913  I[50] = 0; J[50] = 3; K[50] = 3;
4914  I[51] = 0; J[51] = 2; K[51] = 3;
4915  I[52] = 2; J[52] = 2; K[52] = 1;
4916  I[53] = 3; J[53] = 2; K[53] = 1;
4917  I[54] = 2; J[54] = 3; K[54] = 1;
4918  I[55] = 3; J[55] = 3; K[55] = 1;
4919  // element
4920  I[56] = 2; J[56] = 2; K[56] = 2;
4921  I[57] = 3; J[57] = 2; K[57] = 2;
4922  I[58] = 3; J[58] = 3; K[58] = 2;
4923  I[59] = 2; J[59] = 3; K[59] = 2;
4924  I[60] = 2; J[60] = 2; K[60] = 3;
4925  I[61] = 3; J[61] = 2; K[61] = 3;
4926  I[62] = 3; J[62] = 3; K[62] = 3;
4927  I[63] = 2; J[63] = 3; K[63] = 3;
4928  }
4929  else
4930  {
4931  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
4932  }
4933 
4934  fe1d = new Lagrange1DFiniteElement(degree);
4935  dof1d = fe1d -> GetDof();
4936 
4937 #ifndef MFEM_THREAD_SAFE
4938  shape1dx.SetSize(dof1d);
4939  shape1dy.SetSize(dof1d);
4940  shape1dz.SetSize(dof1d);
4941 
4942  dshape1dx.SetSize(dof1d,1);
4943  dshape1dy.SetSize(dof1d,1);
4944  dshape1dz.SetSize(dof1d,1);
4945 #endif
4946 
4947  for (int n = 0; n < dof; n++)
4948  {
4949  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
4950  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
4951  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
4952  }
4953 }
4954 
4956  Vector &shape) const
4957 {
4958  IntegrationPoint ipy, ipz;
4959  ipy.x = ip.y;
4960  ipz.x = ip.z;
4961 
4962 #ifdef MFEM_THREAD_SAFE
4963  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4964 #endif
4965 
4966  fe1d -> CalcShape(ip, shape1dx);
4967  fe1d -> CalcShape(ipy, shape1dy);
4968  fe1d -> CalcShape(ipz, shape1dz);
4969 
4970  for (int n = 0; n < dof; n++)
4971  {
4972  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
4973  }
4974 }
4975 
4977  DenseMatrix &dshape) const
4978 {
4979  IntegrationPoint ipy, ipz;
4980  ipy.x = ip.y;
4981  ipz.x = ip.z;
4982 
4983 #ifdef MFEM_THREAD_SAFE
4984  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4985  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
4986 #endif
4987 
4988  fe1d -> CalcShape(ip, shape1dx);
4989  fe1d -> CalcShape(ipy, shape1dy);
4990  fe1d -> CalcShape(ipz, shape1dz);
4991 
4992  fe1d -> CalcDShape(ip, dshape1dx);
4993  fe1d -> CalcDShape(ipy, dshape1dy);
4994  fe1d -> CalcDShape(ipz, dshape1dz);
4995 
4996  for (int n = 0; n < dof; n++)
4997  {
4998  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
4999  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
5000  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
5001  }
5002 }
5003 
5005 {
5006  delete fe1d;
5007 
5008  delete [] I;
5009  delete [] J;
5010  delete [] K;
5011 }
5012 
5013 
5015  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
5016 {
5017  Nodes.IntPoint(0).x = 0.0;
5018  Nodes.IntPoint(1).x = 1.0;
5019  Nodes.IntPoint(2).x = 0.5;
5020 }
5021 
5023  Vector &shape) const
5024 {
5025  double x = ip.x;
5026 
5027  if (x <= 0.5)
5028  {
5029  shape(0) = 1.0 - 2.0 * x;
5030  shape(1) = 0.0;
5031  shape(2) = 2.0 * x;
5032  }
5033  else
5034  {
5035  shape(0) = 0.0;
5036  shape(1) = 2.0 * x - 1.0;
5037  shape(2) = 2.0 - 2.0 * x;
5038  }
5039 }
5040 
5042  DenseMatrix &dshape) const
5043 {
5044  double x = ip.x;
5045 
5046  if (x <= 0.5)
5047  {
5048  dshape(0,0) = - 2.0;
5049  dshape(1,0) = 0.0;
5050  dshape(2,0) = 2.0;
5051  }
5052  else
5053  {
5054  dshape(0,0) = 0.0;
5055  dshape(1,0) = 2.0;
5056  dshape(2,0) = - 2.0;
5057  }
5058 }
5059 
5061  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
5062 {
5063  Nodes.IntPoint(0).x = 0.0;
5064  Nodes.IntPoint(0).y = 0.0;
5065  Nodes.IntPoint(1).x = 1.0;
5066  Nodes.IntPoint(1).y = 0.0;
5067  Nodes.IntPoint(2).x = 0.0;
5068  Nodes.IntPoint(2).y = 1.0;
5069  Nodes.IntPoint(3).x = 0.5;
5070  Nodes.IntPoint(3).y = 0.0;
5071  Nodes.IntPoint(4).x = 0.5;
5072  Nodes.IntPoint(4).y = 0.5;
5073  Nodes.IntPoint(5).x = 0.0;
5074  Nodes.IntPoint(5).y = 0.5;
5075 }
5076 
5078  Vector &shape) const
5079 {
5080  int i;
5081 
5082  double L0, L1, L2;
5083  L0 = 2.0 * ( 1. - ip.x - ip.y );
5084  L1 = 2.0 * ( ip.x );
5085  L2 = 2.0 * ( ip.y );
5086 
5087  // The reference triangle is split in 4 triangles as follows:
5088  //
5089  // T0 - 0,3,5
5090  // T1 - 1,3,4
5091  // T2 - 2,4,5
5092  // T3 - 3,4,5
5093 
5094  for (i = 0; i < 6; i++)
5095  {
5096  shape(i) = 0.0;
5097  }
5098 
5099  if (L0 >= 1.0) // T0
5100  {
5101  shape(0) = L0 - 1.0;
5102  shape(3) = L1;
5103  shape(5) = L2;
5104  }
5105  else if (L1 >= 1.0) // T1
5106  {
5107  shape(3) = L0;
5108  shape(1) = L1 - 1.0;
5109  shape(4) = L2;
5110  }
5111  else if (L2 >= 1.0) // T2
5112  {
5113  shape(5) = L0;
5114  shape(4) = L1;
5115  shape(2) = L2 - 1.0;
5116  }
5117  else // T3
5118  {
5119  shape(3) = 1.0 - L2;
5120  shape(4) = 1.0 - L0;
5121  shape(5) = 1.0 - L1;
5122  }
5123 }
5124 
5126  DenseMatrix &dshape) const
5127 {
5128  int i,j;
5129 
5130  double L0, L1, L2;
5131  L0 = 2.0 * ( 1. - ip.x - ip.y );
5132  L1 = 2.0 * ( ip.x );
5133  L2 = 2.0 * ( ip.y );
5134 
5135  double DL0[2], DL1[2], DL2[2];
5136  DL0[0] = -2.0; DL0[1] = -2.0;
5137  DL1[0] = 2.0; DL1[1] = 0.0;
5138  DL2[0] = 0.0; DL2[1] = 2.0;
5139 
5140  for (i = 0; i < 6; i++)
5141  for (j = 0; j < 2; j++)
5142  {
5143  dshape(i,j) = 0.0;
5144  }
5145 
5146  if (L0 >= 1.0) // T0
5147  {
5148  for (j = 0; j < 2; j++)
5149  {
5150  dshape(0,j) = DL0[j];
5151  dshape(3,j) = DL1[j];
5152  dshape(5,j) = DL2[j];
5153  }
5154  }
5155  else if (L1 >= 1.0) // T1
5156  {
5157  for (j = 0; j < 2; j++)
5158  {
5159  dshape(3,j) = DL0[j];
5160  dshape(1,j) = DL1[j];
5161  dshape(4,j) = DL2[j];
5162  }
5163  }
5164  else if (L2 >= 1.0) // T2
5165  {
5166  for (j = 0; j < 2; j++)
5167  {
5168  dshape(5,j) = DL0[j];
5169  dshape(4,j) = DL1[j];
5170  dshape(2,j) = DL2[j];
5171  }
5172  }
5173  else // T3
5174  {
5175  for (j = 0; j < 2; j++)
5176  {
5177  dshape(3,j) = - DL2[j];
5178  dshape(4,j) = - DL0[j];
5179  dshape(5,j) = - DL1[j];
5180  }
5181  }
5182 }
5183 
5185  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
5186 {
5187  Nodes.IntPoint(0).x = 0.0;
5188  Nodes.IntPoint(0).y = 0.0;
5189  Nodes.IntPoint(0).z = 0.0;
5190  Nodes.IntPoint(1).x = 1.0;
5191  Nodes.IntPoint(1).y = 0.0;
5192  Nodes.IntPoint(1).z = 0.0;
5193  Nodes.IntPoint(2).x = 0.0;
5194  Nodes.IntPoint(2).y = 1.0;
5195  Nodes.IntPoint(2).z = 0.0;
5196  Nodes.IntPoint(3).x = 0.0;
5197  Nodes.IntPoint(3).y = 0.0;
5198  Nodes.IntPoint(3).z = 1.0;
5199  Nodes.IntPoint(4).x = 0.5;
5200  Nodes.IntPoint(4).y = 0.0;
5201  Nodes.IntPoint(4).z = 0.0;
5202  Nodes.IntPoint(5).x = 0.0;
5203  Nodes.IntPoint(5).y = 0.5;
5204  Nodes.IntPoint(5).z = 0.0;
5205  Nodes.IntPoint(6).x = 0.0;
5206  Nodes.IntPoint(6).y = 0.0;
5207  Nodes.IntPoint(6).z = 0.5;
5208  Nodes.IntPoint(7).x = 0.5;
5209  Nodes.IntPoint(7).y = 0.5;
5210  Nodes.IntPoint(7).z = 0.0;
5211  Nodes.IntPoint(8).x = 0.5;
5212  Nodes.IntPoint(8).y = 0.0;
5213  Nodes.IntPoint(8).z = 0.5;
5214  Nodes.IntPoint(9).x = 0.0;
5215  Nodes.IntPoint(9).y = 0.5;
5216  Nodes.IntPoint(9).z = 0.5;
5217 }
5218 
5220  Vector &shape) const
5221 {
5222  int i;
5223 
5224  double L0, L1, L2, L3, L4, L5;
5225  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
5226  L1 = 2.0 * ( ip.x );
5227  L2 = 2.0 * ( ip.y );
5228  L3 = 2.0 * ( ip.z );
5229  L4 = 2.0 * ( ip.x + ip.y );
5230  L5 = 2.0 * ( ip.y + ip.z );
5231 
5232  // The reference tetrahedron is split in 8 tetrahedra as follows:
5233  //
5234  // T0 - 0,4,5,6
5235  // T1 - 1,4,7,8
5236  // T2 - 2,5,7,9
5237  // T3 - 3,6,8,9
5238  // T4 - 4,5,6,8
5239  // T5 - 4,5,7,8
5240  // T6 - 5,6,8,9
5241  // T7 - 5,7,8,9
5242 
5243  for (i = 0; i < 10; i++)
5244  {
5245  shape(i) = 0.0;
5246  }
5247 
5248  if (L0 >= 1.0) // T0
5249  {
5250  shape(0) = L0 - 1.0;
5251  shape(4) = L1;
5252  shape(5) = L2;
5253  shape(6) = L3;
5254  }
5255  else if (L1 >= 1.0) // T1
5256  {
5257  shape(4) = L0;
5258  shape(1) = L1 - 1.0;
5259  shape(7) = L2;
5260  shape(8) = L3;
5261  }
5262  else if (L2 >= 1.0) // T2
5263  {
5264  shape(5) = L0;
5265  shape(7) = L1;
5266  shape(2) = L2 - 1.0;
5267  shape(9) = L3;
5268  }
5269  else if (L3 >= 1.0) // T3
5270  {
5271  shape(6) = L0;
5272  shape(8) = L1;
5273  shape(9) = L2;
5274  shape(3) = L3 - 1.0;
5275  }
5276  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
5277  {
5278  shape(4) = 1.0 - L5;
5279  shape(5) = L2;
5280  shape(6) = 1.0 - L4;
5281  shape(8) = 1.0 - L0;
5282  }
5283  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
5284  {
5285  shape(4) = 1.0 - L5;
5286  shape(5) = 1.0 - L1;
5287  shape(7) = L4 - 1.0;
5288  shape(8) = L3;
5289  }
5290  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
5291  {
5292  shape(5) = 1.0 - L3;
5293  shape(6) = 1.0 - L4;
5294  shape(8) = L1;
5295  shape(9) = L5 - 1.0;
5296  }
5297  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
5298  {
5299  shape(5) = L0;
5300  shape(7) = L4 - 1.0;
5301  shape(8) = 1.0 - L2;
5302  shape(9) = L5 - 1.0;
5303  }
5304 }
5305 
5307  DenseMatrix &dshape) const
5308 {
5309  int i,j;
5310 
5311  double L0, L1, L2, L3, L4, L5;
5312  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
5313  L1 = 2.0 * ( ip.x );
5314  L2 = 2.0 * ( ip.y );
5315  L3 = 2.0 * ( ip.z );
5316  L4 = 2.0 * ( ip.x + ip.y );
5317  L5 = 2.0 * ( ip.y + ip.z );
5318 
5319  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
5320  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
5321  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
5322  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
5323  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
5324  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
5325  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
5326 
5327  for (i = 0; i < 10; i++)
5328  for (j = 0; j < 3; j++)
5329  {
5330  dshape(i,j) = 0.0;
5331  }
5332 
5333  if (L0 >= 1.0) // T0
5334  {
5335  for (j = 0; j < 3; j++)
5336  {
5337  dshape(0,j) = DL0[j];
5338  dshape(4,j) = DL1[j];
5339  dshape(5,j) = DL2[j];
5340  dshape(6,j) = DL3[j];
5341  }
5342  }
5343  else if (L1 >= 1.0) // T1
5344  {
5345  for (j = 0; j < 3; j++)
5346  {
5347  dshape(4,j) = DL0[j];
5348  dshape(1,j) = DL1[j];
5349  dshape(7,j) = DL2[j];
5350  dshape(8,j) = DL3[j];
5351  }
5352  }
5353  else if (L2 >= 1.0) // T2
5354  {
5355  for (j = 0; j < 3; j++)
5356  {
5357  dshape(5,j) = DL0[j];
5358  dshape(7,j) = DL1[j];
5359  dshape(2,j) = DL2[j];
5360  dshape(9,j) = DL3[j];
5361  }
5362  }
5363  else if (L3 >= 1.0) // T3
5364  {
5365  for (j = 0; j < 3; j++)
5366  {
5367  dshape(6,j) = DL0[j];
5368  dshape(8,j) = DL1[j];
5369  dshape(9,j) = DL2[j];
5370  dshape(3,j) = DL3[j];
5371  }
5372  }
5373  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
5374  {
5375  for (j = 0; j < 3; j++)
5376  {
5377  dshape(4,j) = - DL5[j];
5378  dshape(5,j) = DL2[j];
5379  dshape(6,j) = - DL4[j];
5380  dshape(8,j) = - DL0[j];
5381  }
5382  }
5383  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
5384  {
5385  for (j = 0; j < 3; j++)
5386  {
5387  dshape(4,j) = - DL5[j];
5388  dshape(5,j) = - DL1[j];
5389  dshape(7,j) = DL4[j];
5390  dshape(8,j) = DL3[j];
5391  }
5392  }
5393  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
5394  {
5395  for (j = 0; j < 3; j++)
5396  {
5397  dshape(5,j) = - DL3[j];
5398  dshape(6,j) = - DL4[j];
5399  dshape(8,j) = DL1[j];
5400  dshape(9,j) = DL5[j];
5401  }
5402  }
5403  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
5404  {
5405  for (j = 0; j < 3; j++)
5406  {
5407  dshape(5,j) = DL0[j];
5408  dshape(7,j) = DL4[j];
5409  dshape(8,j) = - DL2[j];
5410  dshape(9,j) = DL5[j];
5411  }
5412  }
5413 }
5414 
5415 
5417  : NodalFiniteElement(2, Geometry::SQUARE, 9, 1, FunctionSpace::rQk)
5418 {
5419  Nodes.IntPoint(0).x = 0.0;
5420  Nodes.IntPoint(0).y = 0.0;
5421  Nodes.IntPoint(1).x = 1.0;
5422  Nodes.IntPoint(1).y = 0.0;
5423  Nodes.IntPoint(2).x = 1.0;
5424  Nodes.IntPoint(2).y = 1.0;
5425  Nodes.IntPoint(3).x = 0.0;
5426  Nodes.IntPoint(3).y = 1.0;
5427  Nodes.IntPoint(4).x = 0.5;
5428  Nodes.IntPoint(4).y = 0.0;
5429  Nodes.IntPoint(5).x = 1.0;
5430  Nodes.IntPoint(5).y = 0.5;
5431  Nodes.IntPoint(6).x = 0.5;
5432  Nodes.IntPoint(6).y = 1.0;
5433  Nodes.IntPoint(7).x = 0.0;
5434  Nodes.IntPoint(7).y = 0.5;
5435  Nodes.IntPoint(8).x = 0.5;
5436  Nodes.IntPoint(8).y = 0.5;
5437 }
5438 
5440  Vector &shape) const
5441 {
5442  int i;
5443  double x = ip.x, y = ip.y;
5444  double Lx, Ly;
5445  Lx = 2.0 * ( 1. - x );
5446  Ly = 2.0 * ( 1. - y );
5447 
5448  // The reference square is split in 4 squares as follows:
5449  //
5450  // T0 - 0,4,7,8
5451  // T1 - 1,4,5,8
5452  // T2 - 2,5,6,8
5453  // T3 - 3,6,7,8
5454 
5455  for (i = 0; i < 9; i++)
5456  {
5457  shape(i) = 0.0;
5458  }
5459 
5460  if ((x <= 0.5) && (y <= 0.5)) // T0
5461  {
5462  shape(0) = (Lx - 1.0) * (Ly - 1.0);
5463  shape(4) = (2.0 - Lx) * (Ly - 1.0);
5464  shape(8) = (2.0 - Lx) * (2.0 - Ly);
5465  shape(7) = (Lx - 1.0) * (2.0 - Ly);
5466  }
5467  else if ((x >= 0.5) && (y <= 0.5)) // T1
5468  {
5469  shape(4) = Lx * (Ly - 1.0);
5470  shape(1) = (1.0 - Lx) * (Ly - 1.0);
5471  shape(5) = (1.0 - Lx) * (2.0 - Ly);
5472  shape(8) = Lx * (2.0 - Ly);
5473  }
5474  else if ((x >= 0.5) && (y >= 0.5)) // T2
5475  {
5476  shape(8) = Lx * Ly ;
5477  shape(5) = (1.0 - Lx) * Ly ;
5478  shape(2) = (1.0 - Lx) * (1.0 - Ly);
5479  shape(6) = Lx * (1.0 - Ly);
5480  }
5481  else if ((x <= 0.5) && (y >= 0.5)) // T3
5482  {
5483  shape(7) = (Lx - 1.0) * Ly ;
5484  shape(8) = (2.0 - Lx) * Ly ;
5485  shape(6) = (2.0 - Lx) * (1.0 - Ly);
5486  shape(3) = (Lx - 1.0) * (1.0 - Ly);
5487  }
5488 }
5489 
5491  DenseMatrix &dshape) const
5492 {
5493  int i,j;
5494  double x = ip.x, y = ip.y;
5495  double Lx, Ly;
5496  Lx = 2.0 * ( 1. - x );
5497  Ly = 2.0 * ( 1. - y );
5498 
5499  for (i = 0; i < 9; i++)
5500  for (j = 0; j < 2; j++)
5501  {
5502  dshape(i,j) = 0.0;
5503  }
5504 
5505  if ((x <= 0.5) && (y <= 0.5)) // T0
5506  {
5507  dshape(0,0) = 2.0 * (1.0 - Ly);
5508  dshape(0,1) = 2.0 * (1.0 - Lx);
5509 
5510  dshape(4,0) = 2.0 * (Ly - 1.0);
5511  dshape(4,1) = -2.0 * (2.0 - Lx);
5512 
5513  dshape(8,0) = 2.0 * (2.0 - Ly);
5514  dshape(8,1) = 2.0 * (2.0 - Lx);
5515 
5516  dshape(7,0) = -2.0 * (2.0 - Ly);
5517  dshape(7,0) = 2.0 * (Lx - 1.0);
5518  }
5519  else if ((x >= 0.5) && (y <= 0.5)) // T1
5520  {
5521  dshape(4,0) = -2.0 * (Ly - 1.0);
5522  dshape(4,1) = -2.0 * Lx;
5523 
5524  dshape(1,0) = 2.0 * (Ly - 1.0);
5525  dshape(1,1) = -2.0 * (1.0 - Lx);
5526 
5527  dshape(5,0) = 2.0 * (2.0 - Ly);
5528  dshape(5,1) = 2.0 * (1.0 - Lx);
5529 
5530  dshape(8,0) = -2.0 * (2.0 - Ly);
5531  dshape(8,1) = 2.0 * Lx;
5532  }
5533  else if ((x >= 0.5) && (y >= 0.5)) // T2
5534  {
5535  dshape(8,0) = -2.0 * Ly;
5536  dshape(8,1) = -2.0 * Lx;
5537 
5538  dshape(5,0) = 2.0 * Ly;
5539  dshape(5,1) = -2.0 * (1.0 - Lx);
5540 
5541  dshape(2,0) = 2.0 * (1.0 - Ly);
5542  dshape(2,1) = 2.0 * (1.0 - Lx);
5543 
5544  dshape(6,0) = -2.0 * (1.0 - Ly);
5545  dshape(6,1) = 2.0 * Lx;
5546  }
5547  else if ((x <= 0.5) && (y >= 0.5)) // T3
5548  {
5549  dshape(7,0) = -2.0 * Ly;
5550  dshape(7,1) = -2.0 * (Lx - 1.0);
5551 
5552  dshape(8,0) = 2.0 * Ly ;
5553  dshape(8,1) = -2.0 * (2.0 - Lx);
5554 
5555  dshape(6,0) = 2.0 * (1.0 - Ly);
5556  dshape(6,1) = 2.0 * (2.0 - Lx);
5557 
5558  dshape(3,0) = -2.0 * (1.0 - Ly);
5559  dshape(3,1) = 2.0 * (Lx - 1.0);
5560  }
5561 }
5562 
5564  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
5565 {
5566  double I[27];
5567  double J[27];
5568  double K[27];
5569  // nodes
5570  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
5571  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
5572  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
5573  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
5574  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
5575  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
5576  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
5577  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
5578  // edges
5579  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
5580  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
5581  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
5582  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
5583  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
5584  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
5585  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
5586  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
5587  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
5588  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
5589  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
5590  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
5591  // faces
5592  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
5593  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
5594  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
5595  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
5596  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
5597  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
5598  // element
5599  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
5600 
5601  for (int n = 0; n < 27; n++)
5602  {
5603  Nodes.IntPoint(n).x = I[n];
5604  Nodes.IntPoint(n).y = J[n];
5605  Nodes.IntPoint(n).z = K[n];
5606  }
5607 }
5608 
5610  Vector &shape) const
5611 {
5612  int i, N[8];
5613  double Lx, Ly, Lz;
5614  double x = ip.x, y = ip.y, z = ip.z;
5615 
5616  for (i = 0; i < 27; i++)
5617  {
5618  shape(i) = 0.0;
5619  }
5620 
5621  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
5622  {
5623  Lx = 1.0 - 2.0 * x;
5624  Ly = 1.0 - 2.0 * y;
5625  Lz = 1.0 - 2.0 * z;
5626 
5627  N[0] = 0;
5628  N[1] = 8;
5629  N[2] = 20;
5630  N[3] = 11;
5631  N[4] = 16;
5632  N[5] = 21;
5633  N[6] = 26;
5634  N[7] = 24;
5635  }
5636  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
5637  {
5638  Lx = 2.0 - 2.0 * x;
5639  Ly = 1.0 - 2.0 * y;
5640  Lz = 1.0 - 2.0 * z;
5641 
5642  N[0] = 8;
5643  N[1] = 1;
5644  N[2] = 9;
5645  N[3] = 20;
5646  N[4] = 21;
5647  N[5] = 17;
5648  N[6] = 22;
5649  N[7] = 26;
5650  }
5651  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
5652  {
5653  Lx = 2.0 - 2.0 * x;
5654  Ly = 2.0 - 2.0 * y;
5655  Lz = 1.0 - 2.0 * z;
5656 
5657  N[0] = 20;
5658  N[1] = 9;
5659  N[2] = 2;
5660  N[3] = 10;
5661  N[4] = 26;
5662  N[5] = 22;
5663  N[6] = 18;
5664  N[7] = 23;
5665  }
5666  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
5667  {
5668  Lx = 1.0 - 2.0 * x;
5669  Ly = 2.0 - 2.0 * y;
5670  Lz = 1.0 - 2.0 * z;
5671 
5672  N[0] = 11;
5673  N[1] = 20;
5674  N[2] = 10;
5675  N[3] = 3;
5676  N[4] = 24;
5677  N[5] = 26;
5678  N[6] = 23;
5679  N[7] = 19;
5680  }
5681  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
5682  {
5683  Lx = 1.0 - 2.0 * x;
5684  Ly = 1.0 - 2.0 * y;
5685  Lz = 2.0 - 2.0 * z;
5686 
5687  N[0] = 16;
5688  N[1] = 21;
5689  N[2] = 26;
5690  N[3] = 24;
5691  N[4] = 4;
5692  N[5] = 12;
5693  N[6] = 25;
5694  N[7] = 15;
5695  }
5696  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
5697  {
5698  Lx = 2.0 - 2.0 * x;
5699  Ly = 1.0 - 2.0 * y;
5700  Lz = 2.0 - 2.0 * z;
5701 
5702  N[0] = 21;
5703  N[1] = 17;
5704  N[2] = 22;
5705  N[3] = 26;
5706  N[4] = 12;
5707  N[5] = 5;
5708  N[6] = 13;
5709  N[7] = 25;
5710  }
5711  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
5712  {
5713  Lx = 2.0 - 2.0 * x;
5714  Ly = 2.0 - 2.0 * y;
5715  Lz = 2.0 - 2.0 * z;
5716 
5717  N[0] = 26;
5718  N[1] = 22;
5719  N[2] = 18;
5720  N[3] = 23;
5721  N[4] = 25;
5722  N[5] = 13;
5723  N[6] = 6;
5724  N[7] = 14;
5725  }
5726  else // T7
5727  {
5728  Lx = 1.0 - 2.0 * x;
5729  Ly = 2.0 - 2.0 * y;
5730  Lz = 2.0 - 2.0 * z;
5731 
5732  N[0] = 24;
5733  N[1] = 26;
5734  N[2] = 23;
5735  N[3] = 19;
5736  N[4] = 15;
5737  N[5] = 25;
5738  N[6] = 14;
5739  N[7] = 7;
5740  }
5741 
5742  shape(N[0]) = Lx * Ly * Lz;
5743  shape(N[1]) = (1 - Lx) * Ly * Lz;
5744  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
5745  shape(N[3]) = Lx * (1 - Ly) * Lz;
5746  shape(N[4]) = Lx * Ly * (1 - Lz);
5747  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
5748  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
5749  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
5750 }
5751 
5753  DenseMatrix &dshape) const
5754 {
5755  int i, j, N[8];
5756  double Lx, Ly, Lz;
5757  double x = ip.x, y = ip.y, z = ip.z;
5758 
5759  for (i = 0; i < 27; i++)
5760  for (j = 0; j < 3; j++)
5761  {
5762  dshape(i,j) = 0.0;
5763  }
5764 
5765  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
5766  {
5767  Lx = 1.0 - 2.0 * x;
5768  Ly = 1.0 - 2.0 * y;
5769  Lz = 1.0 - 2.0 * z;
5770 
5771  N[0] = 0;
5772  N[1] = 8;
5773  N[2] = 20;
5774  N[3] = 11;
5775  N[4] = 16;
5776  N[5] = 21;
5777  N[6] = 26;
5778  N[7] = 24;
5779  }
5780  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
5781  {
5782  Lx = 2.0 - 2.0 * x;
5783  Ly = 1.0 - 2.0 * y;
5784  Lz = 1.0 - 2.0 * z;
5785 
5786  N[0] = 8;
5787  N[1] = 1;
5788  N[2] = 9;
5789  N[3] = 20;
5790  N[4] = 21;
5791  N[5] = 17;
5792  N[6] = 22;
5793  N[7] = 26;
5794  }
5795  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
5796  {
5797  Lx = 2.0 - 2.0 * x;
5798  Ly = 2.0 - 2.0 * y;
5799  Lz = 1.0 - 2.0 * z;
5800 
5801  N[0] = 20;
5802  N[1] = 9;
5803  N[2] = 2;
5804  N[3] = 10;
5805  N[4] = 26;
5806  N[5] = 22;
5807  N[6] = 18;
5808  N[7] = 23;
5809  }
5810  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
5811  {
5812  Lx = 1.0 - 2.0 * x;
5813  Ly = 2.0 - 2.0 * y;
5814  Lz = 1.0 - 2.0 * z;
5815 
5816  N[0] = 11;
5817  N[1] = 20;
5818  N[2] = 10;
5819  N[3] = 3;
5820  N[4] = 24;
5821  N[5] = 26;
5822  N[6] = 23;
5823  N[7] = 19;
5824  }
5825  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
5826  {
5827  Lx = 1.0 - 2.0 * x;
5828  Ly = 1.0 - 2.0 * y;
5829  Lz = 2.0 - 2.0 * z;
5830 
5831  N[0] = 16;
5832  N[1] = 21;
5833  N[2] = 26;
5834  N[3] = 24;
5835  N[4] = 4;
5836  N[5] = 12;
5837  N[6] = 25;
5838  N[7] = 15;
5839  }
5840  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
5841  {
5842  Lx = 2.0 - 2.0 * x;
5843  Ly = 1.0 - 2.0 * y;
5844  Lz = 2.0 - 2.0 * z;
5845 
5846  N[0] = 21;
5847  N[1] = 17;
5848  N[2] = 22;
5849  N[3] = 26;
5850  N[4] = 12;
5851  N[5] = 5;
5852  N[6] = 13;
5853  N[7] = 25;
5854  }
5855  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
5856  {
5857  Lx = 2.0 - 2.0 * x;
5858  Ly = 2.0 - 2.0 * y;
5859  Lz = 2.0 - 2.0 * z;
5860 
5861  N[0] = 26;
5862  N[1] = 22;
5863  N[2] = 18;
5864  N[3] = 23;
5865  N[4] = 25;
5866  N[5] = 13;
5867  N[6] = 6;
5868  N[7] = 14;
5869  }
5870  else // T7
5871  {
5872  Lx = 1.0 - 2.0 * x;
5873  Ly = 2.0 - 2.0 * y;
5874  Lz = 2.0 - 2.0 * z;
5875 
5876  N[0] = 24;
5877  N[1] = 26;
5878  N[2] = 23;
5879  N[3] = 19;
5880  N[4] = 15;
5881  N[5] = 25;
5882  N[6] = 14;
5883  N[7] = 7;
5884  }
5885 
5886  dshape(N[0],0) = -2.0 * Ly * Lz ;
5887  dshape(N[0],1) = -2.0 * Lx * Lz ;
5888  dshape(N[0],2) = -2.0 * Lx * Ly ;
5889 
5890  dshape(N[1],0) = 2.0 * Ly * Lz ;
5891  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
5892  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
5893 
5894  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
5895  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
5896  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
5897 
5898  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
5899  dshape(N[3],1) = 2.0 * Lx * Lz ;
5900  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
5901 
5902  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
5903  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
5904  dshape(N[4],2) = 2.0 * Lx * Ly ;
5905 
5906  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
5907  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
5908  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
5909 
5910  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
5911  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
5912  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
5913 
5914  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
5915  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
5916  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
5917 }
5918 
5919 
5921  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
5922 {
5923  // not real nodes ...
5924  Nodes.IntPoint(0).x = 0.5;
5925  Nodes.IntPoint(0).y = 0.0;
5926  Nodes.IntPoint(0).z = 0.0;
5927 
5928  Nodes.IntPoint(1).x = 1.0;
5929  Nodes.IntPoint(1).y = 0.5;
5930  Nodes.IntPoint(1).z = 0.0;
5931 
5932  Nodes.IntPoint(2).x = 0.5;
5933  Nodes.IntPoint(2).y = 1.0;
5934  Nodes.IntPoint(2).z = 0.0;
5935 
5936  Nodes.IntPoint(3).x = 0.0;
5937  Nodes.IntPoint(3).y = 0.5;
5938  Nodes.IntPoint(3).z = 0.0;
5939 
5940  Nodes.IntPoint(4).x = 0.5;
5941  Nodes.IntPoint(4).y = 0.0;
5942  Nodes.IntPoint(4).z = 1.0;
5943 
5944  Nodes.IntPoint(5).x = 1.0;
5945  Nodes.IntPoint(5).y = 0.5;
5946  Nodes.IntPoint(5).z = 1.0;
5947 
5948  Nodes.IntPoint(6).x = 0.5;
5949  Nodes.IntPoint(6).y = 1.0;
5950  Nodes.IntPoint(6).z = 1.0;
5951 
5952  Nodes.IntPoint(7).x = 0.0;
5953  Nodes.IntPoint(7).y = 0.5;
5954  Nodes.IntPoint(7).z = 1.0;
5955 
5956  Nodes.IntPoint(8).x = 0.0;
5957  Nodes.IntPoint(8).y = 0.0;
5958  Nodes.IntPoint(8).z = 0.5;
5959 
5960  Nodes.IntPoint(9).x = 1.0;
5961  Nodes.IntPoint(9).y = 0.0;
5962  Nodes.IntPoint(9).z = 0.5;
5963 
5964  Nodes.IntPoint(10).x= 1.0;
5965  Nodes.IntPoint(10).y= 1.0;
5966  Nodes.IntPoint(10).z= 0.5;
5967 
5968  Nodes.IntPoint(11).x= 0.0;
5969  Nodes.IntPoint(11).y= 1.0;
5970  Nodes.IntPoint(11).z= 0.5;
5971 }
5972 
5974  DenseMatrix &shape) const
5975 {
5976  double x = ip.x, y = ip.y, z = ip.z;
5977 
5978  shape(0,0) = (1. - y) * (1. - z);
5979  shape(0,1) = 0.;
5980  shape(0,2) = 0.;
5981 
5982  shape(2,0) = y * (1. - z);
5983  shape(2,1) = 0.;
5984  shape(2,2) = 0.;
5985 
5986  shape(4,0) = z * (1. - y);
5987  shape(4,1) = 0.;
5988  shape(4,2) = 0.;
5989 
5990  shape(6,0) = y * z;
5991  shape(6,1) = 0.;
5992  shape(6,2) = 0.;
5993 
5994  shape(1,0) = 0.;
5995  shape(1,1) = x * (1. - z);
5996  shape(1,2) = 0.;
5997 
5998  shape(3,0) = 0.;
5999  shape(3,1) = (1. - x) * (1. - z);
6000  shape(3,2) = 0.;
6001 
6002  shape(5,0) = 0.;
6003  shape(5,1) = x * z;
6004  shape(5,2) = 0.;
6005 
6006  shape(7,0) = 0.;
6007  shape(7,1) = (1. - x) * z;
6008  shape(7,2) = 0.;
6009 
6010  shape(8,0) = 0.;
6011  shape(8,1) = 0.;
6012  shape(8,2) = (1. - x) * (1. - y);
6013 
6014  shape(9,0) = 0.;
6015  shape(9,1) = 0.;
6016  shape(9,2) = x * (1. - y);
6017 
6018  shape(10,0) = 0.;
6019  shape(10,1) = 0.;
6020  shape(10,2) = x * y;
6021 
6022  shape(11,0) = 0.;
6023  shape(11,1) = 0.;
6024  shape(11,2) = y * (1. - x);
6025 
6026 }
6027 
6029  DenseMatrix &curl_shape)
6030 const
6031 {
6032  double x = ip.x, y = ip.y, z = ip.z;
6033 
6034  curl_shape(0,0) = 0.;
6035  curl_shape(0,1) = y - 1.;
6036  curl_shape(0,2) = 1. - z;
6037 
6038  curl_shape(2,0) = 0.;
6039  curl_shape(2,1) = -y;
6040  curl_shape(2,2) = z - 1.;
6041 
6042  curl_shape(4,0) = 0;
6043  curl_shape(4,1) = 1. - y;
6044  curl_shape(4,2) = z;
6045 
6046  curl_shape(6,0) = 0.;
6047  curl_shape(6,1) = y;
6048  curl_shape(6,2) = -z;
6049 
6050  curl_shape(1,0) = x;
6051  curl_shape(1,1) = 0.;
6052  curl_shape(1,2) = 1. - z;
6053 
6054  curl_shape(3,0) = 1. - x;
6055  curl_shape(3,1) = 0.;
6056  curl_shape(3,2) = z - 1.;
6057 
6058  curl_shape(5,0) = -x;
6059  curl_shape(5,1) = 0.;
6060  curl_shape(5,2) = z;
6061 
6062  curl_shape(7,0) = x - 1.;
6063  curl_shape(7,1) = 0.;
6064  curl_shape(7,2) = -z;
6065 
6066  curl_shape(8,0) = x - 1.;
6067  curl_shape(8,1) = 1. - y;
6068  curl_shape(8,2) = 0.;
6069 
6070  curl_shape(9,0) = -x;
6071  curl_shape(9,1) = y - 1.;
6072  curl_shape(9,2) = 0;
6073 
6074  curl_shape(10,0) = x;
6075  curl_shape(10,1) = -y;
6076  curl_shape(10,2) = 0.;
6077 
6078  curl_shape(11,0) = 1. - x;
6079  curl_shape(11,1) = y;
6080  curl_shape(11,2) = 0.;
6081 }
6082 
6083 const double Nedelec1HexFiniteElement::tk[12][3] =
6084 {
6085  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
6086  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
6087  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
6088 };
6089 
6092 {
6093  int k, j;
6094 #ifdef MFEM_THREAD_SAFE
6096 #endif
6097 
6098 #ifdef MFEM_DEBUG
6099  for (k = 0; k < 12; k++)
6100  {
6102  for (j = 0; j < 12; j++)
6103  {
6104  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
6105  vshape(j,2)*tk[k][2] );
6106  if (j == k) { d -= 1.0; }
6107  if (fabs(d) > 1.0e-12)
6108  {
6109  mfem::err << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
6110  " k = " << k << ", j = " << j << ", d = " << d << endl;
6111  mfem_error();
6112  }
6113  }
6114  }
6115 #endif
6116 
6117  IntegrationPoint ip;
6118  ip.x = ip.y = ip.z = 0.0;
6119  Trans.SetIntPoint (&ip);
6120  // Trans must be linear (more to have embedding?)
6121  const DenseMatrix &J = Trans.Jacobian();
6122  double vk[3];
6123  Vector xk (vk, 3);
6124 
6125  for (k = 0; k < 12; k++)
6126  {
6127  Trans.Transform (Nodes.IntPoint (k), xk);
6128  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6129  CalcVShape (ip, vshape);
6130  // vk = J tk
6131  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
6132  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
6133  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
6134  for (j = 0; j < 12; j++)
6135  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6136  vshape(j,2)*vk[2])) < 1.0e-12)
6137  {
6138  I(k,j) = 0.0;
6139  }
6140  }
6141 }
6142 
6145  Vector &dofs) const
6146 {
6147  double vk[3];
6148  Vector xk (vk, 3);
6149 
6150  for (int k = 0; k < 12; k++)
6151  {
6152  Trans.SetIntPoint (&Nodes.IntPoint (k));
6153  const DenseMatrix &J = Trans.Jacobian();
6154 
6155  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6156  // xk^t J tk
6157  dofs(k) =
6158  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
6159  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
6160  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
6161  }
6162 }
6163 
6164 
6166  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
6167 {
6168  // not real nodes ...
6169  Nodes.IntPoint(0).x = 0.5;
6170  Nodes.IntPoint(0).y = 0.0;
6171  Nodes.IntPoint(0).z = 0.0;
6172 
6173  Nodes.IntPoint(1).x = 0.0;
6174  Nodes.IntPoint(1).y = 0.5;
6175  Nodes.IntPoint(1).z = 0.0;
6176 
6177  Nodes.IntPoint(2).x = 0.0;
6178  Nodes.IntPoint(2).y = 0.0;
6179  Nodes.IntPoint(2).z = 0.5;
6180 
6181  Nodes.IntPoint(3).x = 0.5;
6182  Nodes.IntPoint(3).y = 0.5;
6183  Nodes.IntPoint(3).z = 0.0;
6184 
6185  Nodes.IntPoint(4).x = 0.5;
6186  Nodes.IntPoint(4).y = 0.0;
6187  Nodes.IntPoint(4).z = 0.5;
6188 
6189  Nodes.IntPoint(5).x = 0.0;
6190  Nodes.IntPoint(5).y = 0.5;
6191  Nodes.IntPoint(5).z = 0.5;
6192 }
6193 
6195  DenseMatrix &shape) const
6196 {
6197  double x = ip.x, y = ip.y, z = ip.z;
6198 
6199  shape(0,0) = 1. - y - z;
6200  shape(0,1) = x;
6201  shape(0,2) = x;
6202 
6203  shape(1,0) = y;
6204  shape(1,1) = 1. - x - z;
6205  shape(1,2) = y;
6206 
6207  shape(2,0) = z;
6208  shape(2,1) = z;
6209  shape(2,2) = 1. - x - y;
6210 
6211  shape(3,0) = -y;
6212  shape(3,1) = x;
6213  shape(3,2) = 0.;
6214 
6215  shape(4,0) = -z;
6216  shape(4,1) = 0.;
6217  shape(4,2) = x;
6218 
6219  shape(5,0) = 0.;
6220  shape(5,1) = -z;
6221  shape(5,2) = y;
6222 }
6223 
6225  DenseMatrix &curl_shape)
6226 const
6227 {
6228  curl_shape(0,0) = 0.;
6229  curl_shape(0,1) = -2.;
6230  curl_shape(0,2) = 2.;
6231 
6232  curl_shape(1,0) = 2.;
6233  curl_shape(1,1) = 0.;
6234  curl_shape(1,2) = -2.;
6235 
6236  curl_shape(2,0) = -2.;
6237  curl_shape(2,1) = 2.;
6238  curl_shape(2,2) = 0.;
6239 
6240  curl_shape(3,0) = 0.;
6241  curl_shape(3,1) = 0.;
6242  curl_shape(3,2) = 2.;
6243 
6244  curl_shape(4,0) = 0.;
6245  curl_shape(4,1) = -2.;
6246  curl_shape(4,2) = 0.;
6247 
6248  curl_shape(5,0) = 2.;
6249  curl_shape(5,1) = 0.;
6250  curl_shape(5,2) = 0.;
6251 }
6252 
6253 const double Nedelec1TetFiniteElement::tk[6][3] =
6254 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
6255 
6258 {
6259  int k, j;
6260 #ifdef MFEM_THREAD_SAFE
6262 #endif
6263 
6264 #ifdef MFEM_DEBUG
6265  for (k = 0; k < 6; k++)
6266  {
6268  for (j = 0; j < 6; j++)
6269  {
6270  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
6271  vshape(j,2)*tk[k][2] );
6272  if (j == k) { d -= 1.0; }
6273  if (fabs(d) > 1.0e-12)
6274  {
6275  mfem::err << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
6276  " k = " << k << ", j = " << j << ", d = " << d << endl;
6277  mfem_error();
6278  }
6279  }
6280  }
6281 #endif
6282 
6283  IntegrationPoint ip;
6284  ip.x = ip.y = ip.z = 0.0;
6285  Trans.SetIntPoint (&ip);
6286  // Trans must be linear
6287  const DenseMatrix &J = Trans.Jacobian();
6288  double vk[3];
6289  Vector xk (vk, 3);
6290 
6291  for (k = 0; k < 6; k++)
6292  {
6293  Trans.Transform (Nodes.IntPoint (k), xk);
6294  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6295  CalcVShape (ip, vshape);
6296  // vk = J tk
6297  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
6298  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
6299  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
6300  for (j = 0; j < 6; j++)
6301  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6302  vshape(j,2)*vk[2])) < 1.0e-12)
6303  {
6304  I(k,j) = 0.0;
6305  }
6306  }
6307 }
6308 
6311  Vector &dofs) const
6312 {
6313  double vk[3];
6314  Vector xk (vk, 3);
6315 
6316  for (int k = 0; k < 6; k++)
6317  {
6318  Trans.SetIntPoint (&Nodes.IntPoint (k));
6319  const DenseMatrix &J = Trans.Jacobian();
6320 
6321  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6322  // xk^t J tk
6323  dofs(k) =
6324  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
6325  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
6326  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
6327  }
6328 }
6329 
6331  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
6332 {
6333  // not real nodes ...
6334  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
6335  Nodes.IntPoint(0).x = 0.5;
6336  Nodes.IntPoint(0).y = 0.5;
6337  Nodes.IntPoint(0).z = 0.0;
6338 
6339  Nodes.IntPoint(1).x = 0.5;
6340  Nodes.IntPoint(1).y = 0.0;
6341  Nodes.IntPoint(1).z = 0.5;
6342 
6343  Nodes.IntPoint(2).x = 1.0;
6344  Nodes.IntPoint(2).y = 0.5;
6345  Nodes.IntPoint(2).z = 0.5;
6346 
6347  Nodes.IntPoint(3).x = 0.5;
6348  Nodes.IntPoint(3).y = 1.0;
6349  Nodes.IntPoint(3).z = 0.5;
6350 
6351  Nodes.IntPoint(4).x = 0.0;
6352  Nodes.IntPoint(4).y = 0.5;
6353  Nodes.IntPoint(4).z = 0.5;
6354 
6355  Nodes.IntPoint(5).x = 0.5;
6356  Nodes.IntPoint(5).y = 0.5;
6357  Nodes.IntPoint(5).z = 1.0;
6358 }
6359 
6361  DenseMatrix &shape) const
6362 {
6363  double x = ip.x, y = ip.y, z = ip.z;
6364  // z = 0
6365  shape(0,0) = 0.;
6366  shape(0,1) = 0.;
6367  shape(0,2) = z - 1.;
6368  // y = 0
6369  shape(1,0) = 0.;
6370  shape(1,1) = y - 1.;
6371  shape(1,2) = 0.;
6372  // x = 1
6373  shape(2,0) = x;
6374  shape(2,1) = 0.;
6375  shape(2,2) = 0.;
6376  // y = 1
6377  shape(3,0) = 0.;
6378  shape(3,1) = y;
6379  shape(3,2) = 0.;
6380  // x = 0
6381  shape(4,0) = x - 1.;
6382  shape(4,1) = 0.;
6383  shape(4,2) = 0.;
6384  // z = 1
6385  shape(5,0) = 0.;
6386  shape(5,1) = 0.;
6387  shape(5,2) = z;
6388 }
6389 
6391  Vector &divshape) const
6392 {
6393  divshape(0) = 1.;
6394  divshape(1) = 1.;
6395  divshape(2) = 1.;
6396  divshape(3) = 1.;
6397  divshape(4) = 1.;
6398  divshape(5) = 1.;
6399 }
6400 
6401 const double RT0HexFiniteElement::nk[6][3] =
6402 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
6403 
6406 {
6407  int k, j;
6408 #ifdef MFEM_THREAD_SAFE
6410  DenseMatrix Jinv(dim);
6411 #endif
6412 
6413 #ifdef MFEM_DEBUG
6414  for (k = 0; k < 6; k++)
6415  {
6417  for (j = 0; j < 6; j++)
6418  {
6419  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6420  vshape(j,2)*nk[k][2] );
6421  if (j == k) { d -= 1.0; }
6422  if (fabs(d) > 1.0e-12)
6423  {
6424  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
6425  " k = " << k << ", j = " << j << ", d = " << d << endl;
6426  mfem_error();
6427  }
6428  }
6429  }
6430 #endif
6431 
6432  IntegrationPoint ip;
6433  ip.x = ip.y = ip.z = 0.0;
6434  Trans.SetIntPoint (&ip);
6435  // Trans must be linear
6436  // set Jinv = |J| J^{-t} = adj(J)^t
6437  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6438  double vk[3];
6439  Vector xk (vk, 3);
6440 
6441  for (k = 0; k < 6; k++)
6442  {
6443  Trans.Transform (Nodes.IntPoint (k), xk);
6444  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6445  CalcVShape (ip, vshape);
6446  // vk = |J| J^{-t} nk
6447  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6448  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6449  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6450  for (j = 0; j < 6; j++)
6451  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6452  vshape(j,2)*vk[2])) < 1.0e-12)
6453  {
6454  I(k,j) = 0.0;
6455  }
6456  }
6457 }
6458 
6461  Vector &dofs) const
6462 {
6463  double vk[3];
6464  Vector xk (vk, 3);
6465 #ifdef MFEM_THREAD_SAFE
6466  DenseMatrix Jinv(dim);
6467 #endif
6468 
6469  for (int k = 0; k < 6; k++)
6470  {
6471  Trans.SetIntPoint (&Nodes.IntPoint (k));
6472  // set Jinv = |J| J^{-t} = adj(J)^t
6473  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6474 
6475  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6476  // xk^t |J| J^{-t} nk
6477  dofs(k) =
6478  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6479  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6480  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6481  }
6482 }
6483 
6485  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
6486 {
6487  // z = 0
6488  Nodes.IntPoint(2).x = 1./3.;
6489  Nodes.IntPoint(2).y = 1./3.;
6490  Nodes.IntPoint(2).z = 0.0;
6491  Nodes.IntPoint(3).x = 2./3.;
6492  Nodes.IntPoint(3).y = 1./3.;
6493  Nodes.IntPoint(3).z = 0.0;
6494  Nodes.IntPoint(0).x = 1./3.;
6495  Nodes.IntPoint(0).y = 2./3.;
6496  Nodes.IntPoint(0).z = 0.0;
6497  Nodes.IntPoint(1).x = 2./3.;
6498  Nodes.IntPoint(1).y = 2./3.;
6499  Nodes.IntPoint(1).z = 0.0;
6500  // y = 0
6501  Nodes.IntPoint(4).x = 1./3.;
6502  Nodes.IntPoint(4).y = 0.0;
6503  Nodes.IntPoint(4).z = 1./3.;
6504  Nodes.IntPoint(5).x = 2./3.;
6505  Nodes.IntPoint(5).y = 0.0;
6506  Nodes.IntPoint(5).z = 1./3.;
6507  Nodes.IntPoint(6).x = 1./3.;
6508  Nodes.IntPoint(6).y = 0.0;
6509  Nodes.IntPoint(6).z = 2./3.;
6510  Nodes.IntPoint(7).x = 2./3.;
6511  Nodes.IntPoint(7).y = 0.0;
6512  Nodes.IntPoint(7).z = 2./3.;
6513  // x = 1
6514  Nodes.IntPoint(8).x = 1.0;
6515  Nodes.IntPoint(8).y = 1./3.;
6516  Nodes.IntPoint(8).z = 1./3.;
6517  Nodes.IntPoint(9).x = 1.0;
6518  Nodes.IntPoint(9).y = 2./3.;
6519  Nodes.IntPoint(9).z = 1./3.;
6520  Nodes.IntPoint(10).x = 1.0;
6521  Nodes.IntPoint(10).y = 1./3.;
6522  Nodes.IntPoint(10).z = 2./3.;
6523  Nodes.IntPoint(11).x = 1.0;
6524  Nodes.IntPoint(11).y = 2./3.;
6525  Nodes.IntPoint(11).z = 2./3.;
6526  // y = 1
6527  Nodes.IntPoint(13).x = 1./3.;
6528  Nodes.IntPoint(13).y = 1.0;
6529  Nodes.IntPoint(13).z = 1./3.;
6530  Nodes.IntPoint(12).x = 2./3.;
6531  Nodes.IntPoint(12).y = 1.0;
6532  Nodes.IntPoint(12).z = 1./3.;
6533  Nodes.IntPoint(15).x = 1./3.;
6534  Nodes.IntPoint(15).y = 1.0;
6535  Nodes.IntPoint(15).z = 2./3.;
6536  Nodes.IntPoint(14).x = 2./3.;
6537  Nodes.IntPoint(14).y = 1.0;
6538  Nodes.IntPoint(14).z = 2./3.;
6539  // x = 0
6540  Nodes.IntPoint(17).x = 0.0;
6541  Nodes.IntPoint(17).y = 1./3.;
6542  Nodes.IntPoint(17).z = 1./3.;
6543  Nodes.IntPoint(16).x = 0.0;
6544  Nodes.IntPoint(16).y = 2./3.;
6545  Nodes.IntPoint(16).z = 1./3.;
6546  Nodes.IntPoint(19).x = 0.0;
6547  Nodes.IntPoint(19).y = 1./3.;
6548  Nodes.IntPoint(19).z = 2./3.;
6549  Nodes.IntPoint(18).x = 0.0;
6550  Nodes.IntPoint(18).y = 2./3.;
6551  Nodes.IntPoint(18).z = 2./3.;
6552  // z = 1
6553  Nodes.IntPoint(20).x = 1./3.;
6554  Nodes.IntPoint(20).y = 1./3.;
6555  Nodes.IntPoint(20).z = 1.0;
6556  Nodes.IntPoint(21).x = 2./3.;
6557  Nodes.IntPoint(21).y = 1./3.;
6558  Nodes.IntPoint(21).z = 1.0;
6559  Nodes.IntPoint(22).x = 1./3.;
6560  Nodes.IntPoint(22).y = 2./3.;
6561  Nodes.IntPoint(22).z = 1.0;
6562  Nodes.IntPoint(23).x = 2./3.;
6563  Nodes.IntPoint(23).y = 2./3.;
6564  Nodes.IntPoint(23).z = 1.0;
6565  // x = 0.5 (interior)
6566  Nodes.IntPoint(24).x = 0.5;
6567  Nodes.IntPoint(24).y = 1./3.;
6568  Nodes.IntPoint(24).z = 1./3.;
6569  Nodes.IntPoint(25).x = 0.5;
6570  Nodes.IntPoint(25).y = 1./3.;
6571  Nodes.IntPoint(25).z = 2./3.;
6572  Nodes.IntPoint(26).x = 0.5;
6573  Nodes.IntPoint(26).y = 2./3.;
6574  Nodes.IntPoint(26).z = 1./3.;
6575  Nodes.IntPoint(27).x = 0.5;
6576  Nodes.IntPoint(27).y = 2./3.;
6577  Nodes.IntPoint(27).z = 2./3.;
6578  // y = 0.5 (interior)
6579  Nodes.IntPoint(28).x = 1./3.;
6580  Nodes.IntPoint(28).y = 0.5;
6581  Nodes.IntPoint(28).z = 1./3.;
6582  Nodes.IntPoint(29).x = 1./3.;
6583  Nodes.IntPoint(29).y = 0.5;
6584  Nodes.IntPoint(29).z = 2./3.;
6585  Nodes.IntPoint(30).x = 2./3.;
6586  Nodes.IntPoint(30).y = 0.5;
6587  Nodes.IntPoint(30).z = 1./3.;
6588  Nodes.IntPoint(31).x = 2./3.;
6589  Nodes.IntPoint(31).y = 0.5;
6590  Nodes.IntPoint(31).z = 2./3.;
6591  // z = 0.5 (interior)
6592  Nodes.IntPoint(32).x = 1./3.;
6593  Nodes.IntPoint(32).y = 1./3.;
6594  Nodes.IntPoint(32).z = 0.5;
6595  Nodes.IntPoint(33).x = 1./3.;
6596  Nodes.IntPoint(33).y = 2./3.;
6597  Nodes.IntPoint(33).z = 0.5;
6598  Nodes.IntPoint(34).x = 2./3.;
6599  Nodes.IntPoint(34).y = 1./3.;
6600  Nodes.IntPoint(34).z = 0.5;
6601  Nodes.IntPoint(35).x = 2./3.;
6602  Nodes.IntPoint(35).y = 2./3.;
6603  Nodes.IntPoint(35).z = 0.5;
6604 }
6605 
6607  DenseMatrix &shape) const
6608 {
6609  double x = ip.x, y = ip.y, z = ip.z;
6610  // z = 0
6611  shape(2,0) = 0.;
6612  shape(2,1) = 0.;
6613  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6614  shape(3,0) = 0.;
6615  shape(3,1) = 0.;
6616  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6617  shape(0,0) = 0.;
6618  shape(0,1) = 0.;
6619  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6620  shape(1,0) = 0.;
6621  shape(1,1) = 0.;
6622  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6623  // y = 0
6624  shape(4,0) = 0.;
6625  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6626  shape(4,2) = 0.;
6627  shape(5,0) = 0.;
6628  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6629  shape(5,2) = 0.;
6630  shape(6,0) = 0.;
6631  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6632  shape(6,2) = 0.;
6633  shape(7,0) = 0.;
6634  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6635  shape(7,2) = 0.;
6636  // x = 1
6637  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6638  shape(8,1) = 0.;
6639  shape(8,2) = 0.;
6640  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6641  shape(9,1) = 0.;
6642  shape(9,2) = 0.;
6643  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6644  shape(10,1) = 0.;
6645  shape(10,2) = 0.;
6646  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6647  shape(11,1) = 0.;
6648  shape(11,2) = 0.;
6649  // y = 1
6650  shape(13,0) = 0.;
6651  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6652  shape(13,2) = 0.;
6653  shape(12,0) = 0.;
6654  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6655  shape(12,2) = 0.;
6656  shape(15,0) = 0.;
6657  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6658  shape(15,2) = 0.;
6659  shape(14,0) = 0.;
6660  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6661  shape(14,2) = 0.;
6662  // x = 0
6663  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6664  shape(17,1) = 0.;
6665  shape(17,2) = 0.;
6666  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6667  shape(16,1) = 0.;
6668  shape(16,2) = 0.;
6669  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6670  shape(19,1) = 0.;
6671  shape(19,2) = 0.;
6672  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6673  shape(18,1) = 0.;
6674  shape(18,2) = 0.;
6675  // z = 1
6676  shape(20,0) = 0.;
6677  shape(20,1) = 0.;
6678  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6679  shape(21,0) = 0.;
6680  shape(21,1) = 0.;
6681  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6682  shape(22,0) = 0.;
6683  shape(22,1) = 0.;
6684  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6685  shape(23,0) = 0.;
6686  shape(23,1) = 0.;
6687  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6688  // x = 0.5 (interior)
6689  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6690  shape(24,1) = 0.;
6691  shape(24,2) = 0.;
6692  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6693  shape(25,1) = 0.;
6694  shape(25,2) = 0.;
6695  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6696  shape(26,1) = 0.;
6697  shape(26,2) = 0.;
6698  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6699  shape(27,1) = 0.;
6700  shape(27,2) = 0.;
6701  // y = 0.5 (interior)
6702  shape(28,0) = 0.;
6703  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6704  shape(28,2) = 0.;
6705  shape(29,0) = 0.;
6706  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6707  shape(29,2) = 0.;
6708  shape(30,0) = 0.;
6709  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6710  shape(30,2) = 0.;
6711  shape(31,0) = 0.;
6712  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6713  shape(31,2) = 0.;
6714  // z = 0.5 (interior)
6715  shape(32,0) = 0.;
6716  shape(32,1) = 0.;
6717  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6718  shape(33,0) = 0.;
6719  shape(33,1) = 0.;
6720  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6721  shape(34,0) = 0.;
6722  shape(34,1) = 0.;
6723  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6724  shape(35,0) = 0.;
6725  shape(35,1) = 0.;
6726  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6727 }
6728 
6730  Vector &divshape) const
6731 {
6732  double x = ip.x, y = ip.y, z = ip.z;
6733  // z = 0
6734  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6735  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6736  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6737  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6738  // y = 0
6739  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6740  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6741  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6742  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6743  // x = 1
6744  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6745  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6746  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6747  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6748  // y = 1
6749  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6750  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6751  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6752  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6753  // x = 0
6754  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6755  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6756  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6757  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6758  // z = 1
6759  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6760  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6761  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6762  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6763  // x = 0.5 (interior)
6764  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6765  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6766  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6767  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6768  // y = 0.5 (interior)
6769  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6770  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6771  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6772  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6773  // z = 0.5 (interior)
6774  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6775  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6776  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6777  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6778 }
6779 
6780 const double RT1HexFiniteElement::nk[36][3] =
6781 {
6782  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
6783  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
6784  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
6785  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
6786  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
6787  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
6788  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
6789  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
6790  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
6791 };
6792 
6795 {
6796  int k, j;
6797 #ifdef MFEM_THREAD_SAFE
6799  DenseMatrix Jinv(dim);
6800 #endif
6801 
6802 #ifdef MFEM_DEBUG
6803  for (k = 0; k < 36; k++)
6804  {
6806  for (j = 0; j < 36; j++)
6807  {
6808  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6809  vshape(j,2)*nk[k][2] );
6810  if (j == k) { d -= 1.0; }
6811  if (fabs(d) > 1.0e-12)
6812  {
6813  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
6814  " k = " << k << ", j = " << j << ", d = " << d << endl;
6815  mfem_error();
6816  }
6817  }
6818  }
6819 #endif
6820 
6821  IntegrationPoint ip;
6822  ip.x = ip.y = ip.z = 0.0;
6823  Trans.SetIntPoint (&ip);
6824  // Trans must be linear
6825  // set Jinv = |J| J^{-t} = adj(J)^t
6826  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6827  double vk[3];
6828  Vector xk (vk, 3);
6829 
6830  for (k = 0; k < 36; k++)
6831  {
6832  Trans.Transform (Nodes.IntPoint (k), xk);
6833  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6834  CalcVShape (ip, vshape);
6835  // vk = |J| J^{-t} nk
6836  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6837  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6838  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6839  for (j = 0; j < 36; j++)
6840  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6841  vshape(j,2)*vk[2])) < 1.0e-12)
6842  {
6843  I(k,j) = 0.0;
6844  }
6845  }
6846 }
6847 
6850  Vector &dofs) const
6851 {
6852  double vk[3];
6853  Vector xk (vk, 3);
6854 #ifdef MFEM_THREAD_SAFE
6855  DenseMatrix Jinv(dim);
6856 #endif
6857 
6858  for (int k = 0; k < 36; k++)
6859  {
6860  Trans.SetIntPoint (&Nodes.IntPoint (k));
6861  // set Jinv = |J| J^{-t} = adj(J)^t
6862  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6863 
6864  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6865  // xk^t |J| J^{-t} nk
6866  dofs(k) =
6867  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6868  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6869  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6870  }
6871 }
6872 
6874  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
6875 {
6876  // not real nodes ...
6877  Nodes.IntPoint(0).x = 0.33333333333333333333;
6878  Nodes.IntPoint(0).y = 0.33333333333333333333;
6879  Nodes.IntPoint(0).z = 0.33333333333333333333;
6880 
6881  Nodes.IntPoint(1).x = 0.0;
6882  Nodes.IntPoint(1).y = 0.33333333333333333333;
6883  Nodes.IntPoint(1).z = 0.33333333333333333333;
6884 
6885  Nodes.IntPoint(2).x = 0.33333333333333333333;
6886  Nodes.IntPoint(2).y = 0.0;
6887  Nodes.IntPoint(2).z = 0.33333333333333333333;
6888 
6889  Nodes.IntPoint(3).x = 0.33333333333333333333;
6890  Nodes.IntPoint(3).y = 0.33333333333333333333;
6891  Nodes.IntPoint(3).z = 0.0;
6892 }
6893 
6895  DenseMatrix &shape) const
6896 {
6897  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
6898 
6899  shape(0,0) = x2;
6900  shape(0,1) = y2;
6901  shape(0,2) = z2;
6902 
6903  shape(1,0) = x2 - 2.0;
6904  shape(1,1) = y2;
6905  shape(1,2) = z2;
6906 
6907  shape(2,0) = x2;
6908  shape(2,1) = y2 - 2.0;
6909  shape(2,2) = z2;
6910 
6911  shape(3,0) = x2;
6912  shape(3,1) = y2;
6913  shape(3,2) = z2 - 2.0;
6914 }
6915 
6917  Vector &divshape) const
6918 {
6919  divshape(0) = 6.0;
6920  divshape(1) = 6.0;
6921  divshape(2) = 6.0;
6922  divshape(3) = 6.0;
6923 }
6924 
6925 const double RT0TetFiniteElement::nk[4][3] =
6926 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
6927 
6930 {
6931  int k, j;
6932 #ifdef MFEM_THREAD_SAFE
6934  DenseMatrix Jinv(dim);
6935 #endif
6936 
6937 #ifdef MFEM_DEBUG
6938  for (k = 0; k < 4; k++)
6939  {
6941  for (j = 0; j < 4; j++)
6942  {
6943  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6944  vshape(j,2)*nk[k][2] );
6945  if (j == k) { d -= 1.0; }
6946  if (fabs(d) > 1.0e-12)
6947  {
6948  mfem::err << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
6949  " k = " << k << ", j = " << j << ", d = " << d << endl;
6950  mfem_error();
6951  }
6952  }
6953  }
6954 #endif
6955 
6956  IntegrationPoint ip;
6957  ip.x = ip.y = ip.z = 0.0;
6958  Trans.SetIntPoint (&ip);
6959  // Trans must be linear
6960  // set Jinv = |J| J^{-t} = adj(J)^t
6961  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6962  double vk[3];
6963  Vector xk (vk, 3);
6964 
6965  for (k = 0; k < 4; k++)
6966  {
6967  Trans.Transform (Nodes.IntPoint (k), xk);
6968  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6969  CalcVShape (ip, vshape);
6970  // vk = |J| J^{-t} nk
6971  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6972  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6973  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6974  for (j = 0; j < 4; j++)
6975  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6976  vshape(j,2)*vk[2])) < 1.0e-12)
6977  {
6978  I(k,j) = 0.0;
6979  }
6980  }
6981 }
6982 
6985  Vector &dofs) const
6986 {
6987  double vk[3];
6988  Vector xk (vk, 3);
6989 #ifdef MFEM_THREAD_SAFE
6990  DenseMatrix Jinv(dim);
6991 #endif
6992 
6993  for (int k = 0; k < 4; k++)
6994  {
6995  Trans.SetIntPoint (&Nodes.IntPoint (k));
6996  // set Jinv = |J| J^{-t} = adj(J)^t
6997  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6998 
6999  vc.Eval (xk, Trans, Nodes.IntPoint (k));
7000  // xk^t |J| J^{-t} nk
7001  dofs(k) =
7002  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
7003  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
7004  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
7005  }
7006 }
7007 
7009  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
7010 {
7011  Nodes.IntPoint(0).x = 0.5;
7012  Nodes.IntPoint(0).y = 0.5;
7013  Nodes.IntPoint(0).z = 0.0;
7014 
7015  Nodes.IntPoint(1).x = 0.5;
7016  Nodes.IntPoint(1).y = 0.0;
7017  Nodes.IntPoint(1).z = 0.5;
7018 
7019  Nodes.IntPoint(2).x = 1.0;
7020  Nodes.IntPoint(2).y = 0.5;
7021  Nodes.IntPoint(2).z = 0.5;
7022 
7023  Nodes.IntPoint(3).x = 0.5;
7024  Nodes.IntPoint(3).y = 1.0;
7025  Nodes.IntPoint(3).z = 0.5;
7026 
7027  Nodes.IntPoint(4).x = 0.0;
7028  Nodes.IntPoint(4).y = 0.5;
7029  Nodes.IntPoint(4).z = 0.5;
7030 
7031  Nodes.IntPoint(5).x = 0.5;
7032  Nodes.IntPoint(5).y = 0.5;
7033  Nodes.IntPoint(5).z = 1.0;
7034 }
7035 
7037  Vector &shape) const
7038 {
7039  double x = 2. * ip.x - 1.;
7040  double y = 2. * ip.y - 1.;
7041  double z = 2. * ip.z - 1.;
7042  double f5 = x * x - y * y;
7043  double f6 = y * y - z * z;
7044 
7045  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
7046  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
7047  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
7048  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
7049  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
7050  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
7051 }
7052 
7054  DenseMatrix &dshape) const
7055 {
7056  const double a = 2./3.;
7057 
7058  double xt = a * (1. - 2. * ip.x);
7059  double yt = a * (1. - 2. * ip.y);
7060  double zt = a * (1. - 2. * ip.z);
7061 
7062  dshape(0,0) = xt;
7063  dshape(0,1) = yt;
7064  dshape(0,2) = -1. - 2. * zt;
7065 
7066  dshape(1,0) = xt;
7067  dshape(1,1) = -1. - 2. * yt;
7068  dshape(1,2) = zt;
7069 
7070  dshape(2,0) = 1. - 2. * xt;
7071  dshape(2,1) = yt;
7072  dshape(2,2) = zt;
7073 
7074  dshape(3,0) = xt;
7075  dshape(3,1) = 1. - 2. * yt;
7076  dshape(3,2) = zt;
7077 
7078  dshape(4,0) = -1. - 2. * xt;
7079  dshape(4,1) = yt;
7080  dshape(4,2) = zt;
7081 
7082  dshape(5,0) = xt;
7083  dshape(5,1) = yt;
7084  dshape(5,2) = 1. - 2. * zt;
7085 }
7086 
7087 
7088 Poly_1D::Basis::Basis(const int p, const double *nodes, EvalType etype)
7089  : etype(etype), auxiliary_basis(NULL)
7090 {
7091  switch (etype)
7092  {
7093  case ChangeOfBasis:
7094  {
7095  x.SetSize(p + 1);
7096  w.SetSize(p + 1);
7097  DenseMatrix A(p + 1);
7098  for (int i = 0; i <= p; i++)
7099  {
7100  CalcBasis(p, nodes[i], A.GetColumn(i));
7101  }
7102  Ai.Factor(A);
7103  // mfem::out << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
7104  break;
7105  }
7106  case Barycentric:
7107  {
7108  x.SetSize(p + 1);
7109  w.SetSize(p + 1);
7110  x = nodes;
7111  w = 1.0;
7112  for (int i = 0; i <= p; i++)
7113  {
7114  for (int j = 0; j < i; j++)
7115  {
7116  double xij = x(i) - x(j);
7117  w(i) *= xij;
7118  w(j) *= -xij;
7119  }
7120  }
7121  for (int i = 0; i <= p; i++)
7122  {
7123  w(i) = 1.0/w(i);
7124  }
7125 
7126 #ifdef MFEM_DEBUG
7127  // Make sure the nodes are increasing
7128  for (int i = 0; i < p; i++)
7129  {
7130  if (x(i) >= x(i+1))
7131  {
7132  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
7133  }
7134  }
7135 #endif
7136  break;
7137  }
7138  case Positive:
7139  x.SetDataAndSize(NULL, p + 1); // use x to store (p + 1)
7140  break;
7141  case Integrated:
7142  auxiliary_basis = new Basis(
7144  u_aux.SetSize(p+2);
7145  d_aux.SetSize(p+2);
7146  d2_aux.SetSize(p+2);
7147  break;
7148  default: break;
7149  }
7150 }
7151 
7152 void Poly_1D::Basis::Eval(const double y, Vector &u) const
7153 {
7154  switch (etype)
7155  {
7156  case ChangeOfBasis:
7157  {
7158  CalcBasis(Ai.Width() - 1, y, x);
7159  Ai.Mult(x, u);
7160  break;
7161  }
7162  case Barycentric:
7163  {
7164  int i, k, p = x.Size() - 1;
7165  double l, lk;
7166 
7167  if (p == 0)
7168  {
7169  u(0) = 1.0;
7170  return;
7171  }
7172 
7173  lk = 1.0;
7174  for (k = 0; k < p; k++)
7175  {
7176  if (y >= (x(k) + x(k+1))/2)
7177  {
7178  lk *= y - x(k);
7179  }
7180  else
7181  {
7182  for (i = k+1; i <= p; i++)
7183  {
7184  lk *= y - x(i);
7185  }
7186  break;
7187  }
7188  }
7189  l = lk * (y - x(k));
7190 
7191  for (i = 0; i < k; i++)
7192  {
7193  u(i) = l * w(i) / (y - x(i));
7194  }
7195  u(k) = lk * w(k);
7196  for (i++; i <= p; i++)
7197  {
7198  u(i) = l * w(i) / (y - x(i));
7199  }
7200  break;
7201  }
7202  case Positive:
7203  CalcBernstein(x.Size() - 1, y, u);
7204  break;
7205  case Integrated:
7206  auxiliary_basis->Eval(y, u_aux, d_aux);
7207  EvalIntegrated(d_aux, u);
7208  break;
7209  default: break;
7210  }
7211 }
7212 
7213 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
7214 {
7215  switch (etype)
7216  {
7217  case ChangeOfBasis:
7218  {
7219  CalcBasis(Ai.Width() - 1, y, x, w);
7220  Ai.Mult(x, u);
7221  Ai.Mult(w, d);
7222  break;
7223  }
7224  case Barycentric:
7225  {
7226  int i, k, p = x.Size() - 1;
7227  double l, lp, lk, sk, si;
7228 
7229  if (p == 0)
7230  {
7231  u(0) = 1.0;
7232  d(0) = 0.0;
7233  return;
7234  }
7235 
7236  lk = 1.0;
7237  for (k = 0; k < p; k++)
7238  {
7239  if (y >= (x(k) + x(k+1))/2)
7240  {
7241  lk *= y - x(k);
7242  }
7243  else
7244  {
7245  for (i = k+1; i <= p; i++)
7246  {
7247  lk *= y - x(i);
7248  }
7249  break;
7250  }
7251  }
7252  l = lk * (y - x(k));
7253 
7254  sk = 0.0;
7255  for (i = 0; i < k; i++)
7256  {
7257  si = 1.0/(y - x(i));
7258  sk += si;
7259  u(i) = l * si * w(i);
7260  }
7261  u(k) = lk * w(k);
7262  for (i++; i <= p; i++)
7263  {
7264  si = 1.0/(y - x(i));
7265  sk += si;
7266  u(i) = l * si * w(i);
7267  }
7268  lp = l * sk + lk;
7269 
7270  for (i = 0; i < k; i++)
7271  {
7272  d(i) = (lp * w(i) - u(i))/(y - x(i));
7273  }
7274  d(k) = sk * u(k);
7275  for (i++; i <= p; i++)
7276  {
7277  d(i) = (lp * w(i) - u(i))/(y - x(i));
7278  }
7279  break;
7280  }
7281  case Positive:
7282  CalcBernstein(x.Size() - 1, y, u, d);
7283  break;
7284  case Integrated:
7285  auxiliary_basis->Eval(y, u_aux, d_aux, d2_aux);
7286  EvalIntegrated(d_aux,u);
7287  EvalIntegrated(d2_aux,d);
7288  break;
7289  default: break;
7290  }
7291 }
7292 
7293 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d,
7294  Vector &d2) const
7295 {
7296  MFEM_VERIFY(etype == Barycentric,
7297  "Basis::Eval with second order derivatives not implemented for"
7298  " etype = " << etype);
7299  switch (etype)
7300  {
7301  case ChangeOfBasis:
7302  {
7303  CalcBasis(Ai.Width() - 1, y, x, w);
7304  Ai.Mult(x, u);
7305  Ai.Mult(w, d);
7306  // set d2 (not implemented yet)
7307  break;
7308  }
7309  case Barycentric:
7310  {
7311  int i, k, p = x.Size() - 1;
7312  double l, lp, lp2, lk, sk, si, sk2;
7313 
7314  if (p == 0)
7315  {
7316  u(0) = 1.0;
7317  d(0) = 0.0;
7318  d2(0) = 0.0;
7319  return;
7320  }
7321 
7322  lk = 1.0;
7323  for (k = 0; k < p; k++)
7324  {
7325  if (y >= (x(k) + x(k+1))/2)
7326  {
7327  lk *= y - x(k);
7328  }
7329  else
7330  {
7331  for (i = k+1; i <= p; i++)
7332  {
7333  lk *= y - x(i);
7334  }
7335  break;
7336  }
7337  }
7338  l = lk * (y - x(k));
7339 
7340  sk = 0.0;
7341  sk2 = 0.0;
7342  for (i = 0; i < k; i++)
7343  {
7344  si = 1.0/(y - x(i));
7345  sk += si;
7346  sk2 -= si * si;
7347  u(i) = l * si * w(i);
7348  }
7349  u(k) = lk * w(k);
7350  for (i++; i <= p; i++)
7351  {
7352  si = 1.0/(y - x(i));
7353  sk += si;
7354  sk2 -= si * si;
7355  u(i) = l * si * w(i);
7356  }
7357  lp = l * sk + lk;
7358  lp2 = lp * sk + l * sk2 + sk * lk;
7359 
7360  for (i = 0; i < k; i++)
7361  {
7362  d(i) = (lp * w(i) - u(i))/(y - x(i));
7363  d2(i) = (lp2 * w(i) - 2 * d(i))/(y - x(i));
7364  }
7365  d(k) = sk * u(k);
7366  d2(k) = sk2 * u(k) + sk * d(k);
7367  for (i++; i <= p; i++)
7368  {
7369  d(i) = (lp * w(i) - u(i))/(y - x(i));
7370  d2(i) = (lp2 * w(i) - 2 * d(i))/(y - x(i));
7371  }
7372  break;
7373  }
7374  case Positive:
7375  CalcBernstein(x.Size() - 1, y, u, d);
7376  break;
7377  case Integrated:
7378  MFEM_ABORT("Integrated basis must be evaluated with EvalIntegrated");
7379  break;
7380  default: break;
7381  }
7382 }
7383 
7384 void Poly_1D::Basis::EvalIntegrated(const Vector &d_aux, Vector &u) const
7385 {
7386  MFEM_VERIFY(etype == Integrated,
7387  "EvalIntegrated is only valid for Integrated basis type");
7388  int p = d_aux.Size() - 1;
7389  u[0] = -d_aux[0];
7390  for (int j=1; j<p; ++j)
7391  {
7392  u[j] = u[j-1] - d_aux[j];
7393  }
7394 }
7395 
7397 {
7398  delete auxiliary_basis;
7399 }
7400 
7401 const int *Poly_1D::Binom(const int p)
7402 {
7403  if (binom.NumCols() <= p)
7404  {
7405  binom.SetSize(p + 1, p + 1);
7406  for (int i = 0; i <= p; i++)
7407  {
7408  binom(i,0) = binom(i,i) = 1;
7409  for (int j = 1; j < i; j++)
7410  {
7411  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
7412  }
7413  }
7414  }
7415  return binom[p];
7416 }
7417 
7418 void Poly_1D::ChebyshevPoints(const int p, double *x)
7419 {
7420  for (int i = 0; i <= p; i++)
7421  {
7422  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
7423  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
7424  x[i] = s*s;
7425  }
7426 }
7427 
7428 void Poly_1D::CalcMono(const int p, const double x, double *u)
7429 {
7430  double xn;
7431  u[0] = xn = 1.;
7432  for (int n = 1; n <= p; n++)
7433  {
7434  u[n] = (xn *= x);
7435  }
7436 }
7437 
7438 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
7439 {
7440  double xn;
7441  u[0] = xn = 1.;
7442  d[0] = 0.;
7443  for (int n = 1; n <= p; n++)
7444  {
7445  d[n] = n * xn;
7446  u[n] = (xn *= x);
7447  }
7448 }
7449 
7450 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
7451  double *u)
7452 {
7453  if (p == 0)
7454  {
7455  u[0] = 1.;
7456  }
7457  else
7458  {
7459  int i;
7460  const int *b = Binom(p);
7461  double z = x;
7462 
7463  for (i = 1; i < p; i++)
7464  {
7465  u[i] = b[i]*z;
7466  z *= x;
7467  }
7468  u[p] = z;
7469  z = y;
7470  for (i--; i > 0; i--)
7471  {
7472  u[i] *= z;
7473  z *= y;
7474  }
7475  u[0] = z;
7476  }
7477 }
7478 
7479 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
7480  double *u, double *d)
7481 {
7482  if (p == 0)
7483  {
7484  u[0] = 1.;
7485  d[0] = 0.;
7486  }
7487  else
7488  {
7489  int i;
7490  const int *b = Binom(p);
7491  const double xpy = x + y, ptx = p*x;
7492  double z = 1.;
7493 
7494  for (i = 1; i < p; i++)
7495  {
7496  d[i] = b[i]*z*(i*xpy - ptx);
7497  z *= x;
7498  u[i] = b[i]*z;
7499  }
7500  d[p] = p*z;
7501  u[p] = z*x;
7502  z = 1.;
7503  for (i--; i > 0; i--)
7504  {
7505  d[i] *= z;
7506  z *= y;
7507  u[i] *= z;
7508  }
7509  d[0] = -p*z;
7510  u[0] = z*y;
7511  }
7512 }
7513 
7514 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
7515  double *d)
7516 {
7517  if (p == 0)
7518  {
7519  d[0] = 0.;
7520  }
7521  else
7522  {
7523  int i;
7524  const int *b = Binom(p);
7525  const double xpy = x + y, ptx = p*x;
7526  double z = 1.;
7527 
7528  for (i = 1; i < p; i++)
7529  {
7530  d[i] = b[i]*z*(i*xpy - ptx);
7531  z *= x;
7532  }
7533  d[p] = p*z;
7534  z = 1.;
7535  for (i--; i > 0; i--)
7536  {
7537  d[i] *= z;
7538  z *= y;
7539  }
7540  d[0] = -p*z;
7541  }
7542 }
7543 
7544 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
7545 {
7546  // use the recursive definition for [-1,1]:
7547  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
7548  double z;
7549  u[0] = 1.;
7550  if (p == 0) { return; }
7551  u[1] = z = 2.*x - 1.;
7552  for (int n = 1; n < p; n++)
7553  {
7554  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
7555  }
7556 }
7557 
7558 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
7559 {
7560  // use the recursive definition for [-1,1]:
7561  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
7562  // for the derivative use, z in [-1,1]:
7563  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
7564  double z;
7565  u[0] = 1.;
7566  d[0] = 0.;
7567  if (p == 0) { return; }
7568  u[1] = z = 2.*x - 1.;
7569  d[1] = 2.;
7570  for (int n = 1; n < p; n++)
7571  {
7572  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
7573  d[n+1] = (4*n + 2)*u[n] + d[n-1];
7574  }
7575 }
7576 
7577 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
7578 {
7579  // recursive definition, z in [-1,1]
7580  // T_0(z) = 1, T_1(z) = z
7581  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7582  double z;
7583  u[0] = 1.;
7584  if (p == 0) { return; }
7585  u[1] = z = 2.*x - 1.;
7586  for (int n = 1; n < p; n++)
7587  {
7588  u[n+1] = 2*z*u[n] - u[n-1];
7589  }
7590 }
7591 
7592 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
7593 {
7594  // recursive definition, z in [-1,1]
7595  // T_0(z) = 1, T_1(z) = z
7596  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7597  // T'_n(z) = n*U_{n-1}(z)
7598  // U_0(z) = 1 U_1(z) = 2*z
7599  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
7600  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
7601  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
7602  double z;
7603  u[0] = 1.;
7604  d[0] = 0.;
7605  if (p == 0) { return; }
7606  u[1] = z = 2.*x - 1.;
7607  d[1] = 2.;
7608  for (int n = 1; n < p; n++)
7609  {
7610  u[n+1] = 2*z*u[n] - u[n-1];
7611  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
7612  }
7613 }
7614 
7615 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d,
7616  double *dd)
7617 {
7618  // recursive definition, z in [-1,1]
7619  // T_0(z) = 1, T_1(z) = z
7620  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
7621  // T'_n(z) = n*U_{n-1}(z)
7622  // U_0(z) = 1 U_1(z) = 2*z
7623  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
7624  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
7625  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
7626  // T''_{n+1}(z) = (n + 1)*(2*(n + 1)*T'_n(z) + z*T''_n(z)) / n
7627  double z;
7628  u[0] = 1.;
7629  d[0] = 0.;
7630  dd[0]= 0.;
7631  if (p == 0) { return; }
7632  u[1] = z = 2.*x - 1.;
7633  d[1] = 2.;
7634  dd[1] = 0;
7635  for (int n = 1; n < p; n++)
7636  {
7637  u[n+1] = 2*z*u[n] - u[n-1];
7638  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
7639  dd[n+1] = (n + 1)*(2.*(n + 1)*d[n] + z*dd[n])/n;
7640  }
7641 }
7642 
7643 const double *Poly_1D::GetPoints(const int p, const int btype)
7644 {
7645  BasisType::Check(btype);
7646  const int qtype = BasisType::GetQuadrature1D(btype);
7647 
7648  if (qtype == Quadrature1D::Invalid) { return NULL; }
7649 
7650  if (points_container.find(btype) == points_container.end())
7651  {
7652  points_container[btype] = new Array<double*>(h_mt);
7653  }
7654  Array<double*> &pts = *points_container[btype];
7655  if (pts.Size() <= p)
7656  {
7657  pts.SetSize(p + 1, NULL);
7658  }
7659  if (pts[p] == NULL)
7660  {
7661  pts[p] = new double[p + 1];
7662  quad_func.GivePolyPoints(p+1, pts[p], qtype);
7663  }
7664  return pts[p];
7665 }
7666 
7667 Poly_1D::Basis &Poly_1D::GetBasis(const int p, const int btype)
7668 {
7669  BasisType::Check(btype);
7670 
7671  if ( bases_container.find(btype) == bases_container.end() )
7672  {
7673  // we haven't been asked for basis or points of this type yet
7674  bases_container[btype] = new Array<Basis*>(h_mt);
7675  }
7676  Array<Basis*> &bases = *bases_container[btype];
7677  if (bases.Size() <= p)
7678  {
7679  bases.SetSize(p + 1, NULL);
7680  }
7681  if (bases[p] == NULL)
7682  {
7683  EvalType etype;
7684  if (btype == BasisType::Positive) { etype = Positive; }
7685  else if (btype == BasisType::IntegratedGLL) { etype = Integrated; }
7686  else { etype = Barycentric; }
7687  bases[p] = new Basis(p, GetPoints(p, btype), etype);
7688  }
7689  return *bases[p];
7690 }
7691 
7693 {
7694  for (PointsMap::iterator it = points_container.begin();
7695  it != points_container.end() ; ++it)
7696  {
7697  Array<double*>& pts = *it->second;
7698  for ( int i = 0 ; i < pts.Size() ; ++i )
7699  {
7700  delete [] pts[i];
7701  }
7702  delete it->second;
7703  }
7704 
7705  for (BasisMap::iterator it = bases_container.begin();
7706  it != bases_container.end() ; ++it)
7707  {
7708  Array<Basis*>& bases = *it->second;
7709  for ( int i = 0 ; i < bases.Size() ; ++i )
7710  {
7711  delete bases[i];
7712  }
7713  delete it->second;
7714  }
7715 }
7716 
7717 Array2D<int> Poly_1D::binom;
7719 
7720 
7721 TensorBasisElement::TensorBasisElement(const int dims, const int p,
7722  const int btype, const DofMapType dmtype)
7723  : b_type(btype),
7724  basis1d(poly1d.GetBasis(p, b_type))
7725 {
7726  if (dmtype == H1_DOF_MAP || dmtype == Sr_DOF_MAP)
7727  {
7728  switch (dims)
7729  {
7730  case 1:
7731  {
7732  dof_map.SetSize(p + 1);
7733  dof_map[0] = 0;
7734  dof_map[p] = 1;
7735  for (int i = 1; i < p; i++)
7736  {
7737  dof_map[i] = i+1;
7738  }
7739  break;
7740  }
7741  case 2:
7742  {
7743  const int p1 = p + 1;
7744  dof_map.SetSize(p1*p1);
7745 
7746  // vertices
7747  dof_map[0 + 0*p1] = 0;
7748  dof_map[p + 0*p1] = 1;
7749  dof_map[p + p*p1] = 2;
7750  dof_map[0 + p*p1] = 3;
7751 
7752  // edges
7753  int o = 4;
7754  for (int i = 1; i < p; i++)
7755  {
7756  dof_map[i + 0*p1] = o++;
7757  }
7758  for (int i = 1; i < p; i++)
7759  {
7760  dof_map[p + i*p1] = o++;
7761  }
7762  for (int i = 1; i < p; i++)
7763  {
7764  dof_map[(p-i) + p*p1] = o++;
7765  }
7766  for (int i = 1; i < p; i++)
7767  {
7768  dof_map[0 + (p-i)*p1] = o++;
7769  }
7770 
7771  // interior
7772  for (int j = 1; j < p; j++)
7773  {
7774  for (int i = 1; i < p; i++)
7775  {
7776  dof_map[i + j*p1] = o++;
7777  }
7778  }
7779  break;
7780  }
7781  case 3:
7782  {
7783  const int p1 = p + 1;
7784  dof_map.SetSize(p1*p1*p1);
7785 
7786  // vertices
7787  dof_map[0 + (0 + 0*p1)*p1] = 0;
7788  dof_map[p + (0 + 0*p1)*p1] = 1;
7789  dof_map[p + (p + 0*p1)*p1] = 2;
7790  dof_map[0 + (p + 0*p1)*p1] = 3;
7791  dof_map[0 + (0 + p*p1)*p1] = 4;
7792  dof_map[p + (0 + p*p1)*p1] = 5;
7793  dof_map[p + (p + p*p1)*p1] = 6;
7794  dof_map[0 + (p + p*p1)*p1] = 7;
7795 
7796  // edges (see Hexahedron::edges in mesh/hexahedron.cpp).
7797  // edges (see Constants<Geometry::CUBE>::Edges in fem/geom.cpp).
7798  int o = 8;
7799  for (int i = 1; i < p; i++)
7800  {
7801  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
7802  }
7803  for (int i = 1; i < p; i++)
7804  {
7805  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
7806  }
7807  for (int i = 1; i < p; i++)
7808  {
7809  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
7810  }
7811  for (int i = 1; i < p; i++)
7812  {
7813  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
7814  }
7815  for (int i = 1; i < p; i++)
7816  {
7817  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
7818  }
7819  for (int i = 1; i < p; i++)
7820  {
7821  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
7822  }
7823  for (int i = 1; i < p; i++)
7824  {
7825  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
7826  }
7827  for (int i = 1; i < p; i++)
7828  {
7829  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
7830  }
7831  for (int i = 1; i < p; i++)
7832  {
7833  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
7834  }
7835  for (int i = 1; i < p; i++)
7836  {
7837  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
7838  }
7839  for (int i = 1; i < p; i++)
7840  {
7841  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
7842  }
7843  for (int i = 1; i < p; i++)
7844  {
7845  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
7846  }
7847 
7848  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7849  for (int j = 1; j < p; j++)
7850  {
7851  for (int i = 1; i < p; i++)
7852  {
7853  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
7854  }
7855  }
7856  for (int j = 1; j < p; j++)
7857  {
7858  for (int i = 1; i < p; i++)
7859  {
7860  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
7861  }
7862  }
7863  for (int j = 1; j < p; j++)
7864  {
7865  for (int i = 1; i < p; i++)
7866  {
7867  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
7868  }
7869  }
7870  for (int j = 1; j < p; j++)
7871  {
7872  for (int i = 1; i < p; i++)
7873  {
7874  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
7875  }
7876  }
7877  for (int j = 1; j < p; j++)
7878  {
7879  for (int i = 1; i < p; i++)
7880  {
7881  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
7882  }
7883  }
7884  for (int j = 1; j < p; j++)
7885  {
7886  for (int i = 1; i < p; i++)
7887  {
7888  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
7889  }
7890  }
7891 
7892  // interior
7893  for (int k = 1; k < p; k++)
7894  {
7895  for (int j = 1; j < p; j++)
7896  {
7897  for (int i = 1; i < p; i++)
7898  {
7899  dof_map[i + (j + k*p1)*p1] = o++;
7900  }
7901  }
7902  }
7903  break;
7904  }
7905  default:
7906  MFEM_ABORT("invalid dimension: " << dims);
7907  break;
7908  }
7909  }
7910  else if (dmtype == L2_DOF_MAP)
7911  {
7912  // leave dof_map empty, indicating that the dofs are ordered
7913  // lexicographically, i.e. the dof_map is identity
7914  }
7915  else
7916  {
7917  MFEM_ABORT("invalid DofMapType: " << dmtype);
7918  }
7919 }
7920 
7921 
7923  const int p,
7924  const int btype,
7925  const DofMapType dmtype)
7926  : NodalFiniteElement(dims, GetTensorProductGeometry(dims), Pow(p + 1, dims),
7927  p, dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
7928  TensorBasisElement(dims, p, btype, dmtype)
7929 {
7931 }
7932 
7933 
7935  const int dims, const int p, const DofMapType dmtype)
7936  : PositiveFiniteElement(dims, GetTensorProductGeometry(dims),
7937  Pow(p + 1, dims), p,
7938  dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
7939  TensorBasisElement(dims, p, BasisType::Positive, dmtype) { }
7940 
7942  const int d,
7943  const int p,
7944  const int cbtype,
7945  const int obtype,
7946  const int M,
7947  const DofMapType dmtype)
7948  : VectorFiniteElement(dims, GetTensorProductGeometry(dims), d,
7949  p, M, FunctionSpace::Qk),
7950  TensorBasisElement(dims, p, VerifyNodal(cbtype), dmtype),
7951  cbasis1d(poly1d.GetBasis(p, VerifyClosed(cbtype))),
7952  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(obtype)))
7953 {
7954  MFEM_VERIFY(dims > 1, "Constructor for VectorTensorFiniteElement with both "
7955  "open and closed bases is not valid for 1D elements.");
7956 }
7957 
7959  const int d,
7960  const int p,
7961  const int obtype,
7962  const int M,
7963  const DofMapType dmtype)
7964  : VectorFiniteElement(dims, GetTensorProductGeometry(dims), d,
7965  p, M, FunctionSpace::Pk),
7966  TensorBasisElement(dims, p, obtype, dmtype),
7967  cbasis1d(poly1d.GetBasis(p, VerifyOpen(obtype))),
7968  obasis1d(poly1d.GetBasis(p, VerifyOpen(obtype)))
7969 {
7970  MFEM_VERIFY(dims == 1, "Constructor for VectorTensorFiniteElement without "
7971  "closed basis is only valid for 1D elements.");
7972 }
7973 
7974 H1_SegmentElement::H1_SegmentElement(const int p, const int btype)
7975  : NodalTensorFiniteElement(1, p, VerifyClosed(btype), H1_DOF_MAP)
7976 {
7977  const double *cp = poly1d.ClosedPoints(p, b_type);
7978 
7979 #ifndef MFEM_THREAD_SAFE
7980  shape_x.SetSize(p+1);
7981  dshape_x.SetSize(p+1);
7982  d2shape_x.SetSize(p+1);
7983 #endif
7984 
7985  Nodes.IntPoint(0).x = cp[0];
7986  Nodes.IntPoint(1).x = cp[p];
7987  for (int i = 1; i < p; i++)
7988  {
7989  Nodes.IntPoint(i+1).x = cp[i];
7990  }
7991 }
7992 
7994  Vector &shape) const
7995 {
7996  const int p = order;
7997 
7998 #ifdef MFEM_THREAD_SAFE
7999  Vector shape_x(p+1);
8000 #endif
8001 
8002  basis1d.Eval(ip.x, shape_x);
8003 
8004  shape(0) = shape_x(0);
8005  shape(1) = shape_x(p);
8006  for (int i = 1; i < p; i++)
8007  {
8008  shape(i+1) = shape_x(i);
8009  }
8010 }
8011 
8013  DenseMatrix &dshape) const
8014 {
8015  const int p = order;
8016 
8017 #ifdef MFEM_THREAD_SAFE
8018  Vector shape_x(p+1), dshape_x(p+1);
8019 #endif
8020 
8021  basis1d.Eval(ip.x, shape_x, dshape_x);
8022 
8023  dshape(0,0) = dshape_x(0);
8024  dshape(1,0) = dshape_x(p);
8025  for (int i = 1; i < p; i++)
8026  {
8027  dshape(i+1,0) = dshape_x(i);
8028  }
8029 }
8030 
8032  DenseMatrix &Hessian) const
8033 {
8034  const int p = order;
8035 
8036 #ifdef MFEM_THREAD_SAFE
8037  Vector shape_x(p+1), dshape_x(p+1), d2shape_x(p+1);
8038 #endif
8039 
8040  basis1d.Eval(ip.x, shape_x, dshape_x, d2shape_x);
8041 
8042  Hessian(0,0) = d2shape_x(0);
8043  Hessian(1,0) = d2shape_x(p);
8044  for (int i = 1; i < p; i++)
8045  {
8046  Hessian(i+1,0) = d2shape_x(i);
8047  }
8048 }
8049 
8050 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8051 {
8052  const int p = order;
8053  const double *cp = poly1d.ClosedPoints(p, b_type);
8054 
8055  switch (vertex)
8056  {
8057  case 0:
8058  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
8059  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
8060  for (int i = 1; i < p; i++)
8061  {
8062  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
8063  }
8064  break;
8065 
8066  case 1:
8067  dofs(0) = poly1d.CalcDelta(p, cp[0]);
8068  dofs(1) = poly1d.CalcDelta(p, cp[p]);
8069  for (int i = 1; i < p; i++)
8070  {
8071  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
8072  }
8073  break;
8074  }
8075 }
8076 
8077 
8079  : NodalTensorFiniteElement(2, p, VerifyClosed(btype), H1_DOF_MAP)
8080 {
8081  const double *cp = poly1d.ClosedPoints(p, b_type);
8082 
8083 #ifndef MFEM_THREAD_SAFE
8084  const int p1 = p + 1;
8085 
8086  shape_x.SetSize(p1);
8087  shape_y.SetSize(p1);
8088  dshape_x.SetSize(p1);
8089  dshape_y.SetSize(p1);
8090  d2shape_x.SetSize(p1);
8091  d2shape_y.SetSize(p1);
8092 #endif
8093 
8094  int o = 0;
8095  for (int j = 0; j <= p; j++)
8096  {
8097  for (int i = 0; i <= p; i++)
8098  {
8099  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
8100  }
8101  }
8102 }
8103 
8105  Vector &shape) const
8106 {
8107  const int p = order;
8108 
8109 #ifdef MFEM_THREAD_SAFE
8110  Vector shape_x(p+1), shape_y(p+1);
8111 #endif
8112 
8113  basis1d.Eval(ip.x, shape_x);
8114  basis1d.Eval(ip.y, shape_y);
8115 
8116  for (int o = 0, j = 0; j <= p; j++)
8117  for (int i = 0; i <= p; i++)
8118  {
8119  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
8120  }
8121 }
8122 
8124  DenseMatrix &dshape) const
8125 {
8126  const int p = order;
8127 
8128 #ifdef MFEM_THREAD_SAFE
8129  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8130 #endif
8131 
8132  basis1d.Eval(ip.x, shape_x, dshape_x);
8133  basis1d.Eval(ip.y, shape_y, dshape_y);
8134 
8135  for (int o = 0, j = 0; j <= p; j++)
8136  {
8137  for (int i = 0; i <= p; i++)
8138  {
8139  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
8140  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
8141  }
8142  }
8143 }
8144 
8146  DenseMatrix &Hessian) const
8147 {
8148  const int p = order;
8149 
8150 #ifdef MFEM_THREAD_SAFE
8151  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1),
8152  d2shape_x(p+1), d2shape_y(p+1);
8153 #endif
8154 
8155  basis1d.Eval(ip.x, shape_x, dshape_x, d2shape_x);
8156  basis1d.Eval(ip.y, shape_y, dshape_y, d2shape_y);
8157 
8158  for (int o = 0, j = 0; j <= p; j++)
8159  {
8160  for (int i = 0; i <= p; i++)
8161  {
8162  Hessian(dof_map[o],0) = d2shape_x(i)* shape_y(j);
8163  Hessian(dof_map[o],1) = dshape_x(i)* dshape_y(j);
8164  Hessian(dof_map[o],2) = shape_x(i)*d2shape_y(j); o++;
8165  }
8166  }
8167 }
8168 
8169 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
8170 {
8171  const int p = order;
8172  const double *cp = poly1d.ClosedPoints(p, b_type);
8173 
8174 #ifdef MFEM_THREAD_SAFE
8175  Vector shape_x(p+1), shape_y(p+1);
8176 #endif
8177 
8178  for (int i = 0; i <= p; i++)
8179  {
8180  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
8181  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
8182  }
8183 
8184  switch (vertex)
8185  {
8186  case 0:
8187  for (int o = 0, j = 0; j <= p; j++)
8188  for (int i = 0; i <= p; i++)
8189  {
8190  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
8191  }
8192  break;
8193  case 1:
8194  for (int o = 0, j = 0; j <= p; j++)
8195  for (int i = 0; i <= p; i++)
8196  {
8197  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
8198  }
8199  break;
8200  case 2:
8201  for (int o = 0, j = 0; j <= p; j++)
8202  for (int i = 0; i <= p; i++)
8203  {
8204  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
8205  }
8206  break;
8207  case 3:
8208  for (int o = 0, j = 0; j <= p; j++)
8209  for (int i = 0; i <= p; i++)
8210  {
8211  dofs(dof_map[o++]) = shape_x(i)*shape_y(j);
8212  }
8213  break;
8214  }
8215 }
8216 
8217 
8218 H1_HexahedronElement::H1_HexahedronElement(const int p, const int btype)
8219  : NodalTensorFiniteElement(3, p, VerifyClosed(btype), H1_DOF_MAP)
8220 {
8221  const double *cp = poly1d.ClosedPoints(p, b_type);
8222 
8223 #ifndef MFEM_THREAD_SAFE
8224  const int p1 = p + 1;
8225 
8226  shape_x.SetSize(p1);
8227  shape_y.SetSize(p1);
8228  shape_z.SetSize(p1);
8229  dshape_x.SetSize(p1);
8230  dshape_y.SetSize(p1);
8231  dshape_z.SetSize(p1);
8232  d2shape_x.SetSize(p1);
8233  d2shape_y.SetSize(p1);
8234  d2shape_z.SetSize(p1);
8235 #endif
8236 
8237  int o = 0;
8238  for (int k = 0; k <= p; k++)
8239  for (int j = 0; j <= p; j++)
8240  for (int i = 0; i <= p; i++)
8241  {
8242  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
8243  }
8244 }
8245 
8247  Vector &shape) const
8248 {
8249  const int p = order;
8250 
8251 #ifdef MFEM_THREAD_SAFE
8252  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8253 #endif
8254 
8255  basis1d.Eval(ip.x, shape_x);
8256  basis1d.Eval(ip.y, shape_y);
8257  basis1d.Eval(ip.z, shape_z);
8258 
8259  for (int o = 0, k = 0; k <= p; k++)
8260  for (int j = 0; j <= p; j++)
8261  for (int i = 0; i <= p; i++)
8262  {
8263  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
8264  }
8265 }
8266 
8268  DenseMatrix &dshape) const
8269 {
8270  const int p = order;
8271 
8272 #ifdef MFEM_THREAD_SAFE
8273  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8274  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8275 #endif
8276 
8277  basis1d.Eval(ip.x, shape_x, dshape_x);
8278  basis1d.Eval(ip.y, shape_y, dshape_y);
8279  basis1d.Eval(ip.z, shape_z, dshape_z);
8280 
8281  for (int o = 0, k = 0; k <= p; k++)
8282  for (int j = 0; j <= p; j++)
8283  for (int i = 0; i <= p; i++)
8284  {
8285  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
8286  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
8287  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8288  }
8289 }
8290 
8292  DenseMatrix &Hessian) const
8293 {
8294  const int p = order;
8295 
8296 #ifdef MFEM_THREAD_SAFE
8297  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8298  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8299  Vector d2shape_x(p+1), d2shape_y(p+1), d2shape_z(p+1);
8300 #endif
8301 
8302  basis1d.Eval(ip.x, shape_x, dshape_x, d2shape_x);
8303  basis1d.Eval(ip.y, shape_y, dshape_y, d2shape_y);
8304  basis1d.Eval(ip.z, shape_z, dshape_z, d2shape_z);
8305 
8306  for (int o = 0, k = 0; k <= p; k++)
8307  for (int j = 0; j <= p; j++)
8308  for (int i = 0; i <= p; i++)
8309  {
8310  Hessian(dof_map[o],0) = d2shape_x(i)* shape_y(j)* shape_z(k);
8311  Hessian(dof_map[o],1) = dshape_x(i)* dshape_y(j)* shape_z(k);
8312  Hessian(dof_map[o],2) = dshape_x(i)* shape_y(j)* dshape_z(k);
8313  Hessian(dof_map[o],3) = shape_x(i)*d2shape_y(j)* shape_z(k);
8314  Hessian(dof_map[o],4) = shape_x(i)* dshape_y(j)* dshape_z(k);
8315  Hessian(dof_map[o],5) = shape_x(i)* shape_y(j)*d2shape_z(k);
8316  o++;
8317  }
8318 }
8319 
8320 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8321 {
8322  const int p = order;
8323  const double *cp = poly1d.ClosedPoints(p,b_type);
8324 
8325 #ifdef MFEM_THREAD_SAFE
8326  Vector shape_x(p+1), shape_y(p+1);
8327 #endif
8328 
8329  for (int i = 0; i <= p; i++)
8330  {
8331  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
8332  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
8333  }
8334 
8335  switch (vertex)
8336  {
8337  case 0:
8338  for (int o = 0, k = 0; k <= p; k++)
8339  for (int j = 0; j <= p; j++)
8340  for (int i = 0; i <= p; i++)
8341  {
8342  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
8343  }
8344  break;
8345  case 1:
8346  for (int o = 0, k = 0; k <= p; k++)
8347  for (int j = 0; j <= p; j++)
8348  for (int i = 0; i <= p; i++)
8349  {
8350  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
8351  }
8352  break;
8353  case 2:
8354  for (int o = 0, k = 0; k <= p; k++)
8355  for (int j = 0; j <= p; j++)
8356  for (int i = 0; i <= p; i++)
8357  {
8358  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
8359  }
8360  break;
8361  case 3:
8362  for (int o = 0, k = 0; k <= p; k++)
8363  for (int j = 0; j <= p; j++)
8364  for (int i = 0; i <= p; i++)
8365  {
8366  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
8367  }
8368  break;
8369  case 4:
8370  for (int o = 0, k = 0; k <= p; k++)
8371  for (int j = 0; j <= p; j++)
8372  for (int i = 0; i <= p; i++)
8373  {
8374  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
8375  }
8376  break;
8377  case 5:
8378  for (int o = 0, k = 0; k <= p; k++)
8379  for (int j = 0; j <= p; j++)
8380  for (int i = 0; i <= p; i++)
8381  {
8382  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
8383  }
8384  break;
8385  case 6:
8386  for (int o = 0, k = 0; k <= p; k++)
8387  for (int j = 0; j <= p; j++)
8388  for (int i = 0; i <= p; i++)
8389  {
8390  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
8391  }
8392  break;
8393  case 7:
8394  for (int o = 0, k = 0; k <= p; k++)
8395  for (int j = 0; j <= p; j++)
8396  for (int i = 0; i <= p; i++)
8397  {
8398  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
8399  }
8400  break;
8401  }
8402 }
8403 
8404 
8406  : PositiveTensorFiniteElement(1, p, H1_DOF_MAP)
8407 {
8408 #ifndef MFEM_THREAD_SAFE
8409  // thread private versions; see class header.
8410  shape_x.SetSize(p+1);
8411  dshape_x.SetSize(p+1);
8412 #endif
8413 
8414  // Endpoints need to be first in the list, so reorder them.
8415  Nodes.IntPoint(0).x = 0.0;
8416  Nodes.IntPoint(1).x = 1.0;
8417  for (int i = 1; i < p; i++)
8418  {
8419  Nodes.IntPoint(i+1).x = double(i)/p;
8420  }
8421 }
8422 
8424  Vector &shape) const
8425 {
8426  const int p = order;
8427 
8428 #ifdef MFEM_THREAD_SAFE
8429  Vector shape_x(p+1);
8430 #endif
8431 
8432  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
8433 
8434  // Endpoints need to be first in the list, so reorder them.
8435  shape(0) = shape_x(0);
8436  shape(1) = shape_x(p);
8437  for (int i = 1; i < p; i++)
8438  {
8439  shape(i+1) = shape_x(i);
8440  }
8441 }
8442 
8444  DenseMatrix &dshape) const
8445 {
8446  const int p = order;
8447 
8448 #ifdef MFEM_THREAD_SAFE
8449  Vector shape_x(p+1), dshape_x(p+1);
8450 #endif
8451 
8452  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
8453 
8454  // Endpoints need to be first in the list, so reorder them.
8455  dshape(0,0) = dshape_x(0);
8456  dshape(1,0) = dshape_x(p);
8457  for (int i = 1; i < p; i++)
8458  {
8459  dshape(i+1,0) = dshape_x(i);
8460  }
8461 }
8462 
8463 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8464 {
8465  dofs = 0.0;
8466  dofs[vertex] = 1.0;
8467 }
8468 
8469 
8471  : PositiveTensorFiniteElement(2, p, H1_DOF_MAP)
8472 {
8473 #ifndef MFEM_THREAD_SAFE
8474  const int p1 = p + 1;
8475 
8476  shape_x.SetSize(p1);
8477  shape_y.SetSize(p1);
8478  dshape_x.SetSize(p1);
8479  dshape_y.SetSize(p1);
8480 #endif
8481 
8482  int o = 0;
8483  for (int j = 0; j <= p; j++)
8484  for (int i = 0; i <= p; i++)
8485  {
8486  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
8487  }
8488 }
8489 
8491  Vector &shape) const
8492 {
8493  const int p = order;
8494 
8495 #ifdef MFEM_THREAD_SAFE
8496  Vector shape_x(p+1), shape_y(p+1);
8497 #endif
8498 
8499  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
8500  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
8501 
8502  // Reorder so that vertices are at the beginning of the list
8503  for (int o = 0, j = 0; j <= p; j++)
8504  for (int i = 0; i <= p; i++)
8505  {
8506  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
8507  }
8508 }
8509 
8511  DenseMatrix &dshape) const
8512 {
8513  const int p = order;
8514 
8515 #ifdef MFEM_THREAD_SAFE
8516  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8517 #endif
8518 
8519  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
8520  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
8521 
8522  // Reorder so that vertices are at the beginning of the list
8523  for (int o = 0, j = 0; j <= p; j++)
8524  for (int i = 0; i <= p; i++)
8525  {
8526  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
8527  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
8528  }
8529 }
8530 
8532 {
8533  dofs = 0.0;
8534  dofs[vertex] = 1.0;
8535 }
8536 
8537 
8539  : PositiveTensorFiniteElement(3, p, H1_DOF_MAP)
8540 {
8541 #ifndef MFEM_THREAD_SAFE
8542  const int p1 = p + 1;
8543 
8544  shape_x.SetSize(p1);
8545  shape_y.SetSize(p1);
8546  shape_z.SetSize(p1);
8547  dshape_x.SetSize(p1);
8548  dshape_y.SetSize(p1);
8549  dshape_z.SetSize(p1);
8550 #endif
8551 
8552  int o = 0;
8553  for (int k = 0; k <= p; k++)
8554  for (int j = 0; j <= p; j++)
8555  for (int i = 0; i <= p; i++)
8556  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
8557  double(k)/p);
8558 }
8559 
8561  Vector &shape) const
8562 {
8563  const int p = order;
8564 
8565 #ifdef MFEM_THREAD_SAFE
8566  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8567 #endif
8568 
8569  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
8570  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
8571  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
8572 
8573  for (int o = 0, k = 0; k <= p; k++)
8574  for (int j = 0; j <= p; j++)
8575  for (int i = 0; i <= p; i++)
8576  {
8577  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
8578  }
8579 }
8580 
8582  DenseMatrix &dshape) const
8583 {
8584  const int p = order;
8585 
8586 #ifdef MFEM_THREAD_SAFE
8587  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8588  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8589 #endif
8590 
8591  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
8592  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
8593  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
8594 
8595  for (int o = 0, k = 0; k <= p; k++)
8596  for (int j = 0; j <= p; j++)
8597  for (int i = 0; i <= p; i++)
8598  {
8599  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
8600  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
8601  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8602  }
8603 }
8604 
8605 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8606 {
8607  dofs = 0.0;
8608  dofs[vertex] = 1.0;
8609 }
8610 
8611 
8612 H1_TriangleElement::H1_TriangleElement(const int p, const int btype)
8613  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8614  FunctionSpace::Pk)
8615 {
8616  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
8617 
8618 #ifndef MFEM_THREAD_SAFE
8619  shape_x.SetSize(p + 1);
8620  shape_y.SetSize(p + 1);
8621  shape_l.SetSize(p + 1);
8622  dshape_x.SetSize(p + 1);
8623  dshape_y.SetSize(p + 1);
8624  dshape_l.SetSize(p + 1);
8625  ddshape_x.SetSize(p + 1);
8626  ddshape_y.SetSize(p + 1);
8627  ddshape_l.SetSize(p + 1);
8628  u.SetSize(dof);
8629  du.SetSize(dof, dim);
8630  ddu.SetSize(dof, (dim * (dim + 1)) / 2 );
8631 #else
8632  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8633 #endif
8634 
8635  int p2p3 = 2*p + 3;
8636  auto idx = [p2p3](int i, int j) { return ((p2p3-j)*j)/2+i; };
8638 
8639  // vertices
8640  lex_ordering[idx(0,0)] = 0;
8641  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
8642  lex_ordering[idx(p,0)] = 1;
8643  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
8644  lex_ordering[idx(0,p)] = 2;
8645  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
8646 
8647  // edges
8648  int o = 3;
8649  for (int i = 1; i < p; i++)
8650  {
8651  lex_ordering[idx(i,0)] = o;
8652  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
8653  }
8654  for (int i = 1; i < p; i++)
8655  {
8656  lex_ordering[idx(p-i,i)] = o;
8657  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
8658  }
8659  for (int i = 1; i < p; i++)
8660  {
8661  lex_ordering[idx(0,p-i)] = o;
8662  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
8663  }
8664 
8665  // interior
8666  for (int j = 1; j < p; j++)
8667  for (int i = 1; i + j < p; i++)
8668  {
8669  const double w = cp[i] + cp[j] + cp[p-i-j];
8670  lex_ordering[idx(i,j)] = o;
8671  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
8672  }
8673 
8674  DenseMatrix T(dof);
8675  for (int k = 0; k < dof; k++)
8676  {
8677  IntegrationPoint &ip = Nodes.IntPoint(k);
8678  poly1d.CalcBasis(p, ip.x, shape_x);
8679  poly1d.CalcBasis(p, ip.y, shape_y);
8680  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8681 
8682  o = 0;
8683  for (int j = 0; j <= p; j++)
8684  for (int i = 0; i + j <= p; i++)
8685  {
8686  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8687  }
8688  }
8689 
8690  Ti.Factor(T);
8691  // mfem::out << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
8692 }
8693 
8695  Vector &shape) const
8696 {
8697  const int p = order;
8698 
8699 #ifdef MFEM_THREAD_SAFE
8700  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(dof);
8701 #endif
8702 
8703  poly1d.CalcBasis(p, ip.x, shape_x);
8704  poly1d.CalcBasis(p, ip.y, shape_y);
8705  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8706 
8707  for (int o = 0, j = 0; j <= p; j++)
8708  for (int i = 0; i + j <= p; i++)
8709  {
8710  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8711  }
8712 
8713  Ti.Mult(u, shape);
8714 }
8715 
8717  DenseMatrix &dshape) const
8718 {
8719  const int p = order;
8720 
8721 #ifdef MFEM_THREAD_SAFE
8722  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8723  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8724  DenseMatrix du(dof, dim);
8725 #endif
8726 
8727  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8728  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8729  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
8730 
8731  for (int o = 0, j = 0; j <= p; j++)
8732  for (int i = 0; i + j <= p; i++)
8733  {
8734  int k = p - i - j;
8735  du(o,0) = ((dshape_x(i)* shape_l(k)) -
8736  ( shape_x(i)*dshape_l(k)))*shape_y(j);
8737  du(o,1) = ((dshape_y(j)* shape_l(k)) -
8738  ( shape_y(j)*dshape_l(k)))*shape_x(i);
8739  o++;
8740  }
8741 
8742  Ti.Mult(du, dshape);
8743 }
8744 
8746  DenseMatrix &ddshape) const
8747 {
8748  const int p = order;
8749 #ifdef MFEM_THREAD_SAFE
8750  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8751  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8752  Vector ddshape_x(p + 1), ddshape_y(p + 1), ddshape_l(p + 1);
8753  DenseMatrix ddu(dof, dim);
8754 #endif
8755 
8756  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x, ddshape_x);
8757  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y, ddshape_y);
8758  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l, ddshape_l);
8759 
8760  for (int o = 0, j = 0; j <= p; j++)
8761  for (int i = 0; i + j <= p; i++)
8762  {
8763  int k = p - i - j;
8764  // u_xx, u_xy, u_yy
8765  ddu(o,0) = ((ddshape_x(i) * shape_l(k)) - 2. * (dshape_x(i) * dshape_l(k)) +
8766  (shape_x(i) * ddshape_l(k))) * shape_y(j);
8767  ddu(o,1) = (((shape_x(i) * ddshape_l(k)) - dshape_x(i) * dshape_l(k)) * shape_y(
8768  j)) + (((dshape_x(i) * shape_l(k)) - (shape_x(i) * dshape_l(k))) * dshape_y(j));
8769  ddu(o,2) = ((ddshape_y(j) * shape_l(k)) - 2. * (dshape_y(j) * dshape_l(k)) +
8770  (shape_y(j) * ddshape_l(k))) * shape_x(i);
8771  o++;
8772  }
8773 
8774  Ti.Mult(ddu, ddshape);
8775 }
8776 
8777 
8779  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
8780  p, FunctionSpace::Pk)
8781 {
8782  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
8783 
8784 #ifndef MFEM_THREAD_SAFE
8785  shape_x.SetSize(p + 1);
8786  shape_y.SetSize(p + 1);
8787  shape_z.SetSize(p + 1);
8788  shape_l.SetSize(p + 1);
8789  dshape_x.SetSize(p + 1);
8790  dshape_y.SetSize(p + 1);
8791  dshape_z.SetSize(p + 1);
8792  dshape_l.SetSize(p + 1);
8793  ddshape_x.SetSize(p + 1);
8794  ddshape_y.SetSize(p + 1);
8795  ddshape_z.SetSize(p + 1);
8796  ddshape_l.SetSize(p + 1);
8797  u.SetSize(dof);
8798  du.SetSize(dof, dim);
8799  ddu.SetSize(dof, (dim * (dim + 1)) / 2);
8800 #else
8801  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8802 #endif
8803 
8804  auto tri = [](int k) { return (k*(k + 1))/2; };
8805  auto tet = [](int k) { return (k*(k + 1)*(k + 2))/6; };
8806  int ndof = tet(p+1);
8807  auto idx = [tri, tet, p, ndof](int i, int j, int k)
8808  {
8809  return ndof - tet(p - k) - tri(p + 1 - k - j) + i;
8810  };
8811 
8813 
8814  // vertices
8815  lex_ordering[idx(0,0,0)] = 0;
8816  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
8817  lex_ordering[idx(p,0,0)] = 1;
8818  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
8819  lex_ordering[idx(0,p,0)] = 2;
8820  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
8821  lex_ordering[idx(0,0,p)] = 3;
8822  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
8823 
8824  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
8825  int o = 4;
8826  for (int i = 1; i < p; i++) // (0,1)
8827  {
8828  lex_ordering[idx(i,0,0)] = o;
8829  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
8830  }
8831  for (int i = 1; i < p; i++) // (0,2)
8832  {
8833  lex_ordering[idx(0,i,0)] = o;
8834  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
8835  }
8836  for (int i = 1; i < p; i++) // (0,3)
8837  {
8838  lex_ordering[idx(0,0,i)] = o;
8839  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
8840  }
8841  for (int i = 1; i < p; i++) // (1,2)
8842  {
8843  lex_ordering[idx(p-i,i,0)] = o;
8844  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
8845  }
8846  for (int i = 1; i < p; i++) // (1,3)
8847  {
8848  lex_ordering[idx(p-i,0,i)] = o;
8849  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
8850  }
8851  for (int i = 1; i < p; i++) // (2,3)
8852  {
8853  lex_ordering[idx(0,p-i,i)] = o;
8854  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
8855  }
8856 
8857  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
8858  for (int j = 1; j < p; j++)
8859  for (int i = 1; i + j < p; i++) // (1,2,3)
8860  {
8861  lex_ordering[idx(p-i-j,i,j)] = o;
8862  double w = cp[i] + cp[j] + cp[p-i-j];
8863  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
8864  }
8865  for (int j = 1; j < p; j++)
8866  for (int i = 1; i + j < p; i++) // (0,3,2)
8867  {
8868  lex_ordering[idx(0,j,i)] = o;
8869  double w = cp[i] + cp[j] + cp[p-i-j];
8870  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
8871  }
8872  for (int j = 1; j < p; j++)
8873  for (int i = 1; i + j < p; i++) // (0,1,3)
8874  {
8875  lex_ordering[idx(i,0,j)] = o;
8876  double w = cp[i] + cp[j] + cp[p-i-j];
8877  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
8878  }
8879  for (int j = 1; j < p; j++)
8880  for (int i = 1; i + j < p; i++) // (0,2,1)
8881  {
8882  lex_ordering[idx(j,i,0)] = o;
8883  double w = cp[i] + cp[j] + cp[p-i-j];
8884  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
8885  }
8886 
8887  // interior
8888  for (int k = 1; k < p; k++)
8889  for (int j = 1; j + k < p; j++)
8890  for (int i = 1; i + j + k < p; i++)
8891  {
8892  lex_ordering[idx(i,j,k)] = o;
8893  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
8894  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
8895  }
8896 
8897  DenseMatrix T(dof);
8898  for (int m = 0; m < dof; m++)
8899  {
8900  IntegrationPoint &ip = Nodes.IntPoint(m);
8901  poly1d.CalcBasis(p, ip.x, shape_x);
8902  poly1d.CalcBasis(p, ip.y, shape_y);
8903  poly1d.CalcBasis(p, ip.z, shape_z);
8904  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8905 
8906  o = 0;
8907  for (int k = 0; k <= p; k++)
8908  for (int j = 0; j + k <= p; j++)
8909  for (int i = 0; i + j + k <= p; i++)
8910  {
8911  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8912  }
8913  }
8914 
8915  Ti.Factor(T);
8916  // mfem::out << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8917 }
8918 
8920  Vector &shape) const
8921 {
8922  const int p = order;
8923 
8924 #ifdef MFEM_THREAD_SAFE
8925  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8926  Vector u(dof);
8927 #endif
8928 
8929  poly1d.CalcBasis(p, ip.x, shape_x);
8930  poly1d.CalcBasis(p, ip.y, shape_y);
8931  poly1d.CalcBasis(p, ip.z, shape_z);
8932  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8933 
8934  for (int o = 0, k = 0; k <= p; k++)
8935  for (int j = 0; j + k <= p; j++)
8936  for (int i = 0; i + j + k <= p; i++)
8937  {
8938  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8939  }
8940 
8941  Ti.Mult(u, shape);
8942 }
8943 
8945  DenseMatrix &dshape) const
8946 {
8947  const int p = order;
8948 
8949 #ifdef MFEM_THREAD_SAFE
8950  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8951  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8952  DenseMatrix du(dof, dim);
8953 #endif
8954 
8955  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8956  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8957  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
8958  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
8959 
8960  for (int o = 0, k = 0; k <= p; k++)
8961  for (int j = 0; j + k <= p; j++)
8962  for (int i = 0; i + j + k <= p; i++)
8963  {
8964  int l = p - i - j - k;
8965  du(o,0) = ((dshape_x(i)* shape_l(l)) -
8966  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
8967  du(o,1) = ((dshape_y(j)* shape_l(l)) -
8968  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
8969  du(o,2) = ((dshape_z(k)* shape_l(l)) -
8970  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
8971  o++;
8972  }
8973 
8974  Ti.Mult(du, dshape);
8975 }
8976 
8978  DenseMatrix &ddshape) const
8979 {
8980  const int p = order;
8981 
8982 #ifdef MFEM_THREAD_SAFE
8983  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8984  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8985  Vector ddshape_x(p + 1), ddshape_y(p + 1), ddshape_z(p + 1), ddshape_l(p + 1);
8986  DenseMatrix ddu(dof, ((dim + 1) * dim) / 2);
8987 #endif
8988 
8989  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x, ddshape_x);
8990  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y, ddshape_y);
8991  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z, ddshape_z);
8992  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l, ddshape_l);
8993 
8994  for (int o = 0, k = 0; k <= p; k++)
8995  for (int j = 0; j + k <= p; j++)
8996  for (int i = 0; i + j + k <= p; i++)
8997  {
8998  // u_xx, u_xy, u_xz, u_yy, u_yz, u_zz
8999  int l = p - i - j - k;
9000  ddu(o,0) = ((ddshape_x(i) * shape_l(l)) - 2. * (dshape_x(i) * dshape_l(l)) +
9001  (shape_x(i) * ddshape_l(l))) * shape_y(j) * shape_z(k);
9002  ddu(o,1) = ((dshape_y(j) * ((dshape_x(i) * shape_l(l)) -
9003  (shape_x(i) * dshape_l(l)))) +
9004  (shape_y(j) * ((ddshape_l(l) * shape_x(i)) -
9005  (dshape_x(i) * dshape_l(l)))))* shape_z(k);
9006  ddu(o,2) = ((dshape_z(k) * ((dshape_x(i) * shape_l(l)) -
9007  (shape_x(i) * dshape_l(l)))) +
9008  (shape_z(k) * ((ddshape_l(l) * shape_x(i)) -
9009  (dshape_x(i) * dshape_l(l)))))* shape_y(j);
9010  ddu(o,3) = ((ddshape_y(j) * shape_l(l)) - 2. * (dshape_y(j) * dshape_l(l)) +
9011  (shape_y(j) * ddshape_l(l))) * shape_x(i) * shape_z(k);
9012  ddu(o,4) = ((dshape_z(k) * ((dshape_y(j) * shape_l(l)) -
9013  (shape_y(j)*dshape_l(l))) ) +
9014  (shape_z(k)* ((ddshape_l(l)*shape_y(j)) -
9015  (dshape_y(j) * dshape_l(l)) ) ) )* shape_x(i);
9016  ddu(o,5) = ((ddshape_z(k) * shape_l(l)) - 2. * (dshape_z(k) * dshape_l(l)) +
9017  (shape_z(k) * ddshape_l(l))) * shape_y(j) * shape_x(i);
9018  o++;
9019  }
9020  Ti.Mult(ddu, ddshape);
9021 }
9022 
9024  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
9025  FunctionSpace::Pk)
9026 {
9027 #ifndef MFEM_THREAD_SAFE
9028  m_shape.SetSize(dof);
9029  dshape_1d.SetSize(p + 1);
9030  m_dshape.SetSize(dof, dim);
9031 #endif
9032  dof_map.SetSize(dof);
9033 
9034  struct Index
9035  {
9036  int p2p3;
9037  Index(int p) { p2p3 = 2*p + 3; }
9038  int operator()(int i, int j) { return ((p2p3-j)*j)/2+i; }
9039  };
9040  Index idx(p);
9041 
9042  // vertices
9043  dof_map[idx(0,0)] = 0;
9044  Nodes.IntPoint(0).Set2(0., 0.);
9045  dof_map[idx(p,0)] = 1;
9046  Nodes.IntPoint(1).Set2(1., 0.);
9047  dof_map[idx(0,p)] = 2;
9048  Nodes.IntPoint(2).Set2(0., 1.);
9049 
9050  // edges
9051  int o = 3;
9052  for (int i = 1; i < p; i++)
9053  {
9054  dof_map[idx(i,0)] = o;
9055  Nodes.IntPoint(o++).Set2(double(i)/p, 0.);
9056  }
9057  for (int i = 1; i < p; i++)
9058  {
9059  dof_map[idx(p-i,i)] = o;
9060  Nodes.IntPoint(o++).Set2(double(p-i)/p, double(i)/p);
9061  }
9062  for (int i = 1; i < p; i++)
9063  {
9064  dof_map[idx(0,p-i)] = o;
9065  Nodes.IntPoint(o++).Set2(0., double(p-i)/p);
9066  }
9067 
9068  // interior
9069  for (int j = 1; j < p; j++)
9070  for (int i = 1; i + j < p; i++)
9071  {
9072  dof_map[idx(i,j)] = o;
9073  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
9074  }
9075 }
9076 
9077 // static method
9079  const int p, const double l1, const double l2, double *shape)
9080 {
9081  const double l3 = 1. - l1 - l2;
9082 
9083  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
9084  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
9085  // Another expression is given by the terms of the expansion:
9086  // (l1 + l2 + l3)^p =
9087  // \sum_{j=0}^p \binom{p}{j} l2^j
9088  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
9089  const int *bp = Poly_1D::Binom(p);
9090  double z = 1.;
9091  for (int o = 0, j = 0; j <= p; j++)
9092  {
9093  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape[o]);
9094  double s = bp[j]*z;
9095  for (int i = 0; i <= p - j; i++)
9096  {
9097  shape[o++] *= s;
9098  }
9099  z *= l2;
9100  }
9101 }
9102 
9103 // static method
9105  const int p, const double l1, const double l2,
9106  double *dshape_1d, double *dshape)
9107 {
9108  const int dof = ((p + 1)*(p + 2))/2;
9109  const double l3 = 1. - l1 - l2;
9110 
9111  const int *bp = Poly_1D::Binom(p);
9112  double z = 1.;
9113  for (int o = 0, j = 0; j <= p; j++)
9114  {
9115  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
9116  double s = bp[j]*z;
9117  for (int i = 0; i <= p - j; i++)
9118  {
9119  dshape[o++] = s*dshape_1d[i];
9120  }
9121  z *= l2;
9122  }
9123  z = 1.;
9124  for (int i = 0; i <= p; i++)
9125  {
9126  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
9127  double s = bp[i]*z;
9128  for (int o = i, j = 0; j <= p - i; j++)
9129  {
9130  dshape[dof + o] = s*dshape_1d[j];
9131  o += p + 1 - j;
9132  }
9133  z *= l1;
9134  }
9135 }
9136 
9138  Vector &shape) const
9139 {
9140 #ifdef MFEM_THREAD_SAFE
9141  Vector m_shape(dof);
9142 #endif
9143  CalcShape(order, ip.x, ip.y, m_shape.GetData());
9144  for (int i = 0; i < dof; i++)
9145  {
9146  shape(dof_map[i]) = m_shape(i);
9147  }
9148 }
9149 
9151  DenseMatrix &dshape) const
9152 {
9153 #ifdef MFEM_THREAD_SAFE
9154  Vector dshape_1d(order + 1);
9156 #endif
9157  CalcDShape(order, ip.x, ip.y, dshape_1d.GetData(), m_dshape.Data());
9158  for (int d = 0; d < 2; d++)
9159  {
9160  for (int i = 0; i < dof; i++)
9161  {
9162  dshape(dof_map[i],d) = m_dshape(i,d);
9163  }
9164  }
9165 }
9166 
9167 
9169  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
9170  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
9171 {
9172 #ifndef MFEM_THREAD_SAFE
9173  m_shape.SetSize(dof);
9174  dshape_1d.SetSize(p + 1);
9175  m_dshape.SetSize(dof, dim);
9176 #endif
9177  dof_map.SetSize(dof);
9178 
9179  struct Index
9180  {
9181  int p, dof;
9182  int tri(int k) { return (k*(k + 1))/2; }
9183  int tet(int k) { return (k*(k + 1)*(k + 2))/6; }
9184  Index(int p_) { p = p_; dof = tet(p + 1); }
9185  int operator()(int i, int j, int k)
9186  { return dof - tet(p - k) - tri(p + 1 - k - j) + i; }
9187  };
9188  Index idx(p);
9189 
9190  // vertices
9191  dof_map[idx(0,0,0)] = 0;
9192  Nodes.IntPoint(0).Set3(0., 0., 0.);
9193  dof_map[idx(p,0,0)] = 1;
9194  Nodes.IntPoint(1).Set3(1., 0., 0.);
9195  dof_map[idx(0,p,0)] = 2;
9196  Nodes.IntPoint(2).Set3(0., 1., 0.);
9197  dof_map[idx(0,0,p)] = 3;
9198  Nodes.IntPoint(3).Set3(0., 0., 1.);
9199 
9200  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
9201  int o = 4;
9202  for (int i = 1; i < p; i++) // (0,1)
9203  {
9204  dof_map[idx(i,0,0)] = o;
9205  Nodes.IntPoint(o++).Set3(double(i)/p, 0., 0.);
9206  }
9207  for (int i = 1; i < p; i++) // (0,2)
9208  {
9209  dof_map[idx(0,i,0)] = o;
9210  Nodes.IntPoint(o++).Set3(0., double(i)/p, 0.);
9211  }
9212  for (int i = 1; i < p; i++) // (0,3)
9213  {
9214  dof_map[idx(0,0,i)] = o;
9215  Nodes.IntPoint(o++).Set3(0., 0., double(i)/p);
9216  }
9217  for (int i = 1; i < p; i++) // (1,2)
9218  {
9219  dof_map[idx(p-i,i,0)] = o;
9220  Nodes.IntPoint(o++).Set3(double(p-i)/p, double(i)/p, 0.);
9221  }
9222  for (int i = 1; i < p; i++) // (1,3)
9223  {
9224  dof_map[idx(p-i,0,i)] = o;
9225  Nodes.IntPoint(o++).Set3(double(p-i)/p, 0., double(i)/p);
9226  }
9227  for (int i = 1; i < p; i++) // (2,3)
9228  {
9229  dof_map[idx(0,p-i,i)] = o;
9230  Nodes.IntPoint(o++).Set3(0., double(p-i)/p, double(i)/p);
9231  }
9232 
9233  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
9234  for (int j = 1; j < p; j++)
9235  for (int i = 1; i + j < p; i++) // (1,2,3)
9236  {
9237  dof_map[idx(p-i-j,i,j)] = o;
9238  Nodes.IntPoint(o++).Set3(double(p-i-j)/p, double(i)/p, double(j)/p);
9239  }
9240  for (int j = 1; j < p; j++)
9241  for (int i = 1; i + j < p; i++) // (0,3,2)
9242  {
9243  dof_map[idx(0,j,i)] = o;
9244  Nodes.IntPoint(o++).Set3(0., double(j)/p, double(i)/p);
9245  }
9246  for (int j = 1; j < p; j++)
9247  for (int i = 1; i + j < p; i++) // (0,1,3)
9248  {
9249  dof_map[idx(i,0,j)] = o;
9250  Nodes.IntPoint(o++).Set3(double(i)/p, 0., double(j)/p);
9251  }
9252  for (int j = 1; j < p; j++)
9253  for (int i = 1; i + j < p; i++) // (0,2,1)
9254  {
9255  dof_map[idx(j,i,0)] = o;
9256  Nodes.IntPoint(o++).Set3(double(j)/p, double(i)/p, 0.);
9257  }
9258 
9259  // interior
9260  for (int k = 1; k < p; k++)
9261  for (int j = 1; j + k < p; j++)
9262  for (int i = 1; i + j + k < p; i++)
9263  {
9264  dof_map[idx(i,j,k)] = o;
9265  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
9266  }
9267 }
9268 
9269 // static method
9271  const int p, const double l1, const double l2, const double l3,
9272  double *shape)
9273 {
9274  const double l4 = 1. - l1 - l2 - l3;
9275 
9276  // The basis functions are the terms in the expansion:
9277  // (l1 + l2 + l3 + l4)^p =
9278  // \sum_{k=0}^p \binom{p}{k} l3^k
9279  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
9280  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
9281  const int *bp = Poly_1D::Binom(p);
9282  double l3k = 1.;
9283  for (int o = 0, k = 0; k <= p; k++)
9284  {
9285  const int *bpk = Poly_1D::Binom(p - k);
9286  const double ek = bp[k]*l3k;
9287  double l2j = 1.;
9288  for (int j = 0; j <= p - k; j++)
9289  {
9290  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape[o]);
9291  double ekj = ek*bpk[j]*l2j;
9292  for (int i = 0; i <= p - k - j; i++)
9293  {
9294  shape[o++] *= ekj;
9295  }
9296  l2j *= l2;
9297  }
9298  l3k *= l3;
9299  }
9300 }
9301 
9302 // static method
9304  const int p, const double l1, const double l2, const double l3,
9305  double *dshape_1d, double *dshape)
9306 {
9307  const int dof = ((p + 1)*(p + 2)*(p + 3))/6;
9308  const double l4 = 1. - l1 - l2 - l3;
9309 
9310  // For the x derivatives, differentiate the terms of the expression:
9311  // \sum_{k=0}^p \binom{p}{k} l3^k
9312  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
9313  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
9314  const int *bp = Poly_1D::Binom(p);
9315  double l3k = 1.;
9316  for (int o = 0, k = 0; k <= p; k++)
9317  {
9318  const int *bpk = Poly_1D::Binom(p - k);
9319  const double ek = bp[k]*l3k;
9320  double l2j = 1.;
9321  for (int j = 0; j <= p - k; j++)
9322  {
9323  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
9324  double ekj = ek*bpk[j]*l2j;
9325  for (int i = 0; i <= p - k - j; i++)
9326  {
9327  dshape[o++] = dshape_1d[i]*ekj;
9328  }
9329  l2j *= l2;
9330  }
9331  l3k *= l3;
9332  }
9333  // For the y derivatives, differentiate the terms of the expression:
9334  // \sum_{k=0}^p \binom{p}{k} l3^k
9335  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
9336  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
9337  l3k = 1.;
9338  for (int ok = 0, k = 0; k <= p; k++)
9339  {
9340  const int *bpk = Poly_1D::Binom(p - k);
9341  const double ek = bp[k]*l3k;
9342  double l1i = 1.;
9343  for (int i = 0; i <= p - k; i++)
9344  {
9345  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
9346  double eki = ek*bpk[i]*l1i;
9347  int o = ok + i;
9348  for (int j = 0; j <= p - k - i; j++)
9349  {
9350  dshape[dof + o] = dshape_1d[j]*eki;
9351  o += p - k - j + 1;
9352  }
9353  l1i *= l1;
9354  }
9355  l3k *= l3;
9356  ok += ((p - k + 2)*(p - k + 1))/2;
9357  }
9358  // For the z derivatives, differentiate the terms of the expression:
9359  // \sum_{j=0}^p \binom{p}{j} l2^j
9360  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
9361  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
9362  double l2j = 1.;
9363  for (int j = 0; j <= p; j++)
9364  {
9365  const int *bpj = Poly_1D::Binom(p - j);
9366  const double ej = bp[j]*l2j;
9367  double l1i = 1.;
9368  for (int i = 0; i <= p - j; i++)
9369  {
9370  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
9371  double eji = ej*bpj[i]*l1i;
9372  int m = ((p + 2)*(p + 1))/2;
9373  int n = ((p - j + 2)*(p - j + 1))/2;
9374  for (int o = i, k = 0; k <= p - j - i; k++)
9375  {
9376  // m = ((p - k + 2)*(p - k + 1))/2;
9377  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
9378  o += m;
9379  dshape[2*dof + o - n] = dshape_1d[k]*eji;
9380  m -= p - k + 1;
9381  n -= p - k - j + 1;
9382  }
9383  l1i *= l1;
9384  }
9385  l2j *= l2;
9386  }
9387 }
9388 
9390  Vector &shape) const
9391 {
9392 #ifdef MFEM_THREAD_SAFE
9393  Vector m_shape(dof);
9394 #endif
9395  CalcShape(order, ip.x, ip.y, ip.z, m_shape.GetData());
9396  for (int i = 0; i < dof; i++)
9397  {
9398  shape(dof_map[i]) = m_shape(i);
9399  }
9400 }
9401 
9403  DenseMatrix &dshape) const
9404 {
9405 #ifdef MFEM_THREAD_SAFE
9406  Vector dshape_1d(order + 1);
9408 #endif
9409  CalcDShape(order, ip.x, ip.y, ip.z, dshape_1d.GetData(), m_dshape.Data());
9410  for (int d = 0; d < 3; d++)
9411  {
9412  for (int i = 0; i < dof; i++)
9413  {
9414  dshape(dof_map[i],d) = m_dshape(i,d);
9415  }
9416  }
9417 }
9418 
9419 
9421  const int btype)
9422  : NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
9423  p, FunctionSpace::Qk),
9424  TriangleFE(p, btype),
9425  SegmentFE(p, btype)
9426 {
9427 #ifndef MFEM_THREAD_SAFE
9428  t_shape.SetSize(TriangleFE.GetDof());
9429  s_shape.SetSize(SegmentFE.GetDof());
9430  t_dshape.SetSize(TriangleFE.GetDof(), 2);
9431  s_dshape.SetSize(SegmentFE.GetDof(), 1);
9432 #endif
9433 
9434  t_dof.SetSize(dof);
9435  s_dof.SetSize(dof);
9436 
9437  int p2p3 = 2*p + 3, ntri = ((p + 1)*(p + 2))/2;
9438  auto idx = [p2p3,ntri](int i, int j, int k)
9439  {
9440  return k*ntri + ((p2p3-j)*j)/2+i;
9441  };
9442 
9444  int o = 0;
9445 
9446  // Nodal DoFs
9447  lex_ordering[idx(0,0,0)] = o++;
9448  lex_ordering[idx(p,0,0)] = o++;
9449  lex_ordering[idx(0,p,0)] = o++;
9450  lex_ordering[idx(0,0,p)] = o++;
9451  lex_ordering[idx(p,0,p)] = o++;
9452  lex_ordering[idx(0,p,p)] = o++;
9453  t_dof[0] = 0; s_dof[0] = 0;
9454  t_dof[1] = 1; s_dof[1] = 0;
9455  t_dof[2] = 2; s_dof[2] = 0;
9456  t_dof[3] = 0; s_dof[3] = 1;
9457  t_dof[4] = 1; s_dof[4] = 1;
9458  t_dof[5] = 2; s_dof[5] = 1;
9459 
9460  // Edge DoFs
9461  int k = 0;
9462  int ne = p-1;
9463  for (int i=1; i<p; i++)
9464  {
9465  lex_ordering[idx(i,0,0)] = o + 0*ne + k;
9466  lex_ordering[idx(p-i,i,0)] = o + 1*ne + k;
9467  lex_ordering[idx(0,p-i,0)] = o + 2*ne + k;
9468  lex_ordering[idx(i,0,p)] = o + 3*ne + k;
9469  lex_ordering[idx(p-i,i,p)] = o + 4*ne + k;
9470  lex_ordering[idx(0,p-i,p)] = o + 5*ne + k;
9471  lex_ordering[idx(0,0,i)] = o + 6*ne + k;
9472  lex_ordering[idx(p,0,i)] = o + 7*ne + k;
9473  lex_ordering[idx(0,p,i)] = o + 8*ne + k;
9474  t_dof[5 + 0 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 0 * ne + i] = 0;
9475  t_dof[5 + 1 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 1 * ne + i] = 0;
9476  t_dof[5 + 2 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 2 * ne + i] = 0;
9477  t_dof[5 + 3 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 3 * ne + i] = 1;
9478  t_dof[5 + 4 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 4 * ne + i] = 1;
9479  t_dof[5 + 5 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 5 * ne + i] = 1;
9480  t_dof[5 + 6 * ne + i] = 0; s_dof[5 + 6 * ne + i] = i + 1;
9481  t_dof[5 + 7 * ne + i] = 1; s_dof[5 + 7 * ne + i] = i + 1;
9482  t_dof[5 + 8 * ne + i] = 2; s_dof[5 + 8 * ne + i] = i + 1;
9483  ++k;
9484  }
9485  o += 9*ne;
9486 
9487  // Triangular Face DoFs
9488  k=0;
9489  int nt = (p-1)*(p-2)/2;
9490  for (int j=1; j<p; j++)
9491  {
9492  for (int i=1; i<p-j; i++)
9493  {
9494  int l = j - p + (((2 * p - 1) - i) * i) / 2;
9495  lex_ordering[idx(i,j,0)] = o+l;
9496  lex_ordering[idx(i,j,p)] = o+nt+k;
9497  t_dof[6 + 9 * ne + k] = 3 * p + l; s_dof[6 + 9 * ne + k] = 0;
9498  t_dof[6 + 9 * ne + nt + k] = 3 * p + k; s_dof[6 + 9 * ne + nt + k] = 1;
9499  k++;
9500  }
9501  }
9502  o += 2*nt;
9503 
9504  // Quadrilateral Face DoFs
9505  k=0;
9506  int nq = (p-1)*(p-1);
9507  for (int j=1; j<p; j++)
9508  {
9509  for (int i=1; i<p; i++)
9510  {
9511  lex_ordering[idx(i,0,j)] = o+k;
9512  lex_ordering[idx(p-i,i,j)] = o+nq+k;
9513  lex_ordering[idx(0,p-i,j)] = o+2*nq+k;
9514 
9515  t_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 2 + 0 * ne + i;
9516  t_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 2 + 1 * ne + i;
9517  t_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 2 + 2 * ne + i;
9518 
9519  s_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 1 + j;
9520  s_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 1 + j;
9521  s_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 1 + j;
9522 
9523  k++;
9524  }
9525  }
9526  o += 3*nq;
9527 
9528  // Interior DoFs
9529  int m=0;
9530  for (int k=1; k<p; k++)
9531  {
9532  int l=0;
9533  for (int j=1; j<p; j++)
9534  {
9535  for (int i=1; i+j<p; i++)
9536  {
9537  lex_ordering[idx(i,j,k)] = o++;
9538  t_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 3 * p + l;
9539  s_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 1 + k;
9540  l++; m++;
9541  }
9542  }
9543  }
9544 
9545  // Define Nodes
9546  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
9547  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
9548  for (int i=0; i<dof; i++)
9549  {
9550  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
9551  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
9552  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
9553  }
9554 }
9555 
9557  Vector &shape) const
9558 {
9559 #ifdef MFEM_THREAD_SAFE
9560  Vector t_shape(TriangleFE.GetDof());
9561  Vector s_shape(SegmentFE.GetDof());
9562 #endif
9563 
9564  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9565 
9566  TriangleFE.CalcShape(ip, t_shape);
9567  SegmentFE.CalcShape(ipz, s_shape);
9568 
9569  for (int i=0; i<dof; i++)
9570  {
9571  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
9572  }
9573 }
9574 
9576  DenseMatrix &dshape) const
9577 {
9578 #ifdef MFEM_THREAD_SAFE
9579  Vector t_shape(TriangleFE.GetDof());
9580  DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
9581  Vector s_shape(SegmentFE.GetDof());
9582  DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
9583 #endif
9584 
9585  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9586 
9587  TriangleFE.CalcShape(ip, t_shape);
9588  TriangleFE.CalcDShape(ip, t_dshape);
9589  SegmentFE.CalcShape(ipz, s_shape);
9590  SegmentFE.CalcDShape(ipz, s_dshape);
9591 
9592  for (int i=0; i<dof; i++)
9593  {
9594  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
9595  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
9596  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
9597  }
9598 }
9599 
9600 
9602  : PositiveFiniteElement(3, Geometry::PRISM,
9603  ((p + 1)*(p + 1)*(p + 2))/2, p, FunctionSpace::Qk),
9604  TriangleFE(p),
9605  SegmentFE(p)
9606 {
9607 #ifndef MFEM_THREAD_SAFE
9612 #endif
9613 
9614  t_dof.SetSize(dof);
9615  s_dof.SetSize(dof);
9616 
9617  // Nodal DoFs
9618  t_dof[0] = 0; s_dof[0] = 0;
9619  t_dof[1] = 1; s_dof[1] = 0;
9620  t_dof[2] = 2; s_dof[2] = 0;
9621  t_dof[3] = 0; s_dof[3] = 1;
9622  t_dof[4] = 1; s_dof[4] = 1;
9623  t_dof[5] = 2; s_dof[5] = 1;
9624 
9625  // Edge DoFs
9626  int ne = p-1;
9627  for (int i=1; i<p; i++)
9628  {
9629  t_dof[5 + 0 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 0 * ne + i] = 0;
9630  t_dof[5 + 1 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 1 * ne + i] = 0;
9631  t_dof[5 + 2 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 2 * ne + i] = 0;
9632  t_dof[5 + 3 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 3 * ne + i] = 1;
9633  t_dof[5 + 4 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 4 * ne + i] = 1;
9634  t_dof[5 + 5 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 5 * ne + i] = 1;
9635  t_dof[5 + 6 * ne + i] = 0; s_dof[5 + 6 * ne + i] = i + 1;
9636  t_dof[5 + 7 * ne + i] = 1; s_dof[5 + 7 * ne + i] = i + 1;
9637  t_dof[5 + 8 * ne + i] = 2; s_dof[5 + 8 * ne + i] = i + 1;
9638  }
9639 
9640  // Triangular Face DoFs
9641  int k=0;
9642  int nt = (p-1)*(p-2)/2;
9643  for (int j=1; j<p; j++)
9644  {
9645  for (int i=1; i<j; i++)
9646  {
9647  t_dof[6 + 9 * ne + k] = 3 * p + k; s_dof[6 + 9 * ne + k] = 0;
9648  t_dof[6 + 9 * ne + nt + k] = 3 * p + k; s_dof[6 + 9 * ne + nt + k] = 1;
9649  k++;
9650  }
9651  }
9652 
9653  // Quadrilateral Face DoFs
9654  k=0;
9655  int nq = (p-1)*(p-1);
9656  for (int j=1; j<p; j++)
9657  {
9658  for (int i=1; i<p; i++)
9659  {
9660  t_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 2 + 0 * ne + i;
9661  t_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 2 + 1 * ne + i;
9662  t_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 2 + 2 * ne + i;
9663 
9664  s_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 1 + j;
9665  s_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 1 + j;
9666  s_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 1 + j;
9667 
9668  k++;
9669  }
9670  }
9671 
9672  // Interior DoFs
9673  int m=0;
9674  for (int k=1; k<p; k++)
9675  {
9676  int l=0;
9677  for (int j=1; j<p; j++)
9678  {
9679  for (int i=1; i<j; i++)
9680  {
9681  t_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 3 * p + l;
9682  s_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 1 + k;
9683  l++; m++;
9684  }
9685  }
9686  }
9687 
9688  // Define Nodes
9689  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
9690  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
9691  for (int i=0; i<dof; i++)
9692  {
9693  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
9694  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
9695  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
9696  }
9697 }
9698 
9700  Vector &shape) const
9701 {
9702 #ifdef MFEM_THREAD_SAFE
9705 #endif
9706 
9707  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9708 
9710  SegmentFE.CalcShape(ipz, s_shape);
9711 
9712  for (int i=0; i<dof; i++)
9713  {
9714  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
9715  }
9716 }
9717 
9719  DenseMatrix &dshape) const
9720 {
9721 #ifdef MFEM_THREAD_SAFE
9726 #endif
9727 
9728  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9729 
9732  SegmentFE.CalcShape(ipz, s_shape);
9734 
9735  for (int i=0; i<dof; i++)
9736  {
9737  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
9738  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
9739  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
9740  }
9741 }
9742 
9743 
9744 L2_SegmentElement::L2_SegmentElement(const int p, const int btype)
9745  : NodalTensorFiniteElement(1, p, VerifyOpen(btype), L2_DOF_MAP)
9746 {
9747  const double *op = poly1d.OpenPoints(p, btype);
9748 
9749 #ifndef MFEM_THREAD_SAFE
9750  shape_x.SetSize(p + 1);
9751  dshape_x.SetDataAndSize(NULL, p + 1);
9752 #endif
9753 
9754  for (int i = 0; i <= p; i++)
9755  {
9756  Nodes.IntPoint(i).x = op[i];
9757  }
9758 }
9759 
9761  Vector &shape) const
9762 {
9763  basis1d.Eval(ip.x, shape);
9764 }
9765 
9767  DenseMatrix &dshape) const
9768 {
9769 #ifdef MFEM_THREAD_SAFE
9770  Vector shape_x(dof), dshape_x(dshape.Data(), dof);
9771 #else
9772  dshape_x.SetData(dshape.Data());
9773 #endif
9774  basis1d.Eval(ip.x, shape_x, dshape_x);
9775 }
9776 
9777 void L2_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
9778 {
9779  const int p = order;
9780  const double *op = poly1d.OpenPoints(p, b_type);
9781 
9782  switch (vertex)
9783  {
9784  case 0:
9785  for (int i = 0; i <= p; i++)
9786  {
9787  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9788  }
9789  break;
9790 
9791  case 1:
9792  for (int i = 0; i <= p; i++)
9793  {
9794  dofs(i) = poly1d.CalcDelta(p,op[i]);
9795  }
9796  break;
9797  }
9798 }
9799 
9800 
9802  : PositiveTensorFiniteElement(1, p, L2_DOF_MAP)
9803 {
9804 #ifndef MFEM_THREAD_SAFE
9805  shape_x.SetSize(p + 1);
9806  dshape_x.SetDataAndSize(NULL, p + 1);
9807 #endif
9808 
9809  if (p == 0)
9810  {
9811  Nodes.IntPoint(0).x = 0.5;
9812  }
9813  else
9814  {
9815  for (int i = 0; i <= p; i++)
9816  {
9817  Nodes.IntPoint(i).x = double(i)/p;
9818  }
9819  }
9820 }
9821 
9823  Vector &shape) const
9824 {
9825  Poly_1D::CalcBernstein(order, ip.x, shape);
9826 }
9827 
9829  DenseMatrix &dshape) const
9830 {
9831 #ifdef MFEM_THREAD_SAFE
9832  Vector shape_x(dof), dshape_x(dshape.Data(), dof);
9833 #else
9834  dshape_x.SetData(dshape.Data());
9835 #endif
9836  Poly_1D::CalcBernstein(order, ip.x, shape_x, dshape_x);
9837 }
9838 
9839 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
9840 {
9841  dofs = 0.0;
9842  dofs[vertex*order] = 1.0;
9843 }
9844 
9845 
9847  : NodalTensorFiniteElement(2, p, VerifyOpen(btype), L2_DOF_MAP)
9848 {
9849  const double *op = poly1d.OpenPoints(p, b_type);
9850 
9851 #ifndef MFEM_THREAD_SAFE
9852  shape_x.SetSize(p + 1);
9853  shape_y.SetSize(p + 1);
9854  dshape_x.SetSize(p + 1);
9855  dshape_y.SetSize(p + 1);
9856 #endif
9857 
9858  for (int o = 0, j = 0; j <= p; j++)
9859  for (int i = 0; i <= p; i++)
9860  {
9861  Nodes.IntPoint(o++).Set2(op[i], op[j]);
9862  }
9863 }
9864 
9866  Vector &shape) const
9867 {
9868  const int p = order;
9869 
9870 #ifdef MFEM_THREAD_SAFE
9871  Vector shape_x(p+1), shape_y(p+1);
9872 #endif
9873 
9874  basis1d.Eval(ip.x, shape_x);
9875  basis1d.Eval(ip.y, shape_y);
9876 
9877  for (int o = 0, j = 0; j <= p; j++)
9878  for (int i = 0; i <= p; i++)
9879  {
9880  shape(o++) = shape_x(i)*shape_y(j);
9881  }
9882 }
9883 
9885  DenseMatrix &dshape) const
9886 {
9887  const int p = order;
9888 
9889 #ifdef MFEM_THREAD_SAFE
9890  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
9891 #endif
9892 
9893  basis1d.Eval(ip.x, shape_x, dshape_x);
9894  basis1d.Eval(ip.y, shape_y, dshape_y);
9895 
9896  for (int o = 0, j = 0; j <= p; j++)
9897  for (int i = 0; i <= p; i++)
9898  {
9899  dshape(o,0) = dshape_x(i)* shape_y(j);
9900  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
9901  }
9902 }
9903 
9904 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
9905 {
9906  const int p = order;
9907  const double *op = poly1d.OpenPoints(p, b_type);
9908 
9909 #ifdef MFEM_THREAD_SAFE
9910  Vector shape_x(p+1), shape_y(p+1);
9911 #endif
9912 
9913  for (int i = 0; i <= p; i++)
9914  {
9915  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9916  shape_y(i) = poly1d.CalcDelta(p,op[i]);
9917  }
9918 
9919  switch (vertex)
9920  {
9921  case 0:
9922  for (int o = 0, j = 0; j <= p; j++)
9923  for (int i = 0; i <= p; i++)
9924  {
9925  dofs[o++] = shape_x(i)*shape_x(j);
9926  }
9927  break;
9928  case 1:
9929  for (int o = 0, j = 0; j <= p; j++)
9930  for (int i = 0; i <= p; i++)
9931  {
9932  dofs[o++] = shape_y(i)*shape_x(j);
9933  }
9934  break;
9935  case 2:
9936  for (int o = 0, j = 0; j <= p; j++)
9937  for (int i = 0; i <= p; i++)
9938  {
9939  dofs[o++] = shape_y(i)*shape_y(j);
9940  }
9941  break;
9942  case 3:
9943  for (int o = 0, j = 0; j <= p; j++)
9944  for (int i = 0; i <= p; i++)
9945  {
9946  dofs[o++] = shape_x(i)*shape_y(j);
9947  }
9948  break;
9949  }
9950 }
9951 
9952 
9954  : PositiveTensorFiniteElement(2, p, L2_DOF_MAP)
9955 {
9956 #ifndef MFEM_THREAD_SAFE
9957  shape_x.SetSize(p + 1);
9958  shape_y.SetSize(p + 1);
9959  dshape_x.SetSize(p + 1);
9960  dshape_y.SetSize(p + 1);
9961 #endif
9962 
9963  if (p == 0)
9964  {
9965  Nodes.IntPoint(0).Set2(0.5, 0.5);
9966  }
9967  else
9968  {
9969  for (int o = 0, j = 0; j <= p; j++)
9970  for (int i = 0; i <= p; i++)
9971  {
9972  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
9973  }
9974  }
9975 }
9976 
9978  Vector &shape) const
9979 {
9980  const int p = order;
9981 
9982 #ifdef MFEM_THREAD_SAFE
9983  Vector shape_x(p+1), shape_y(p+1);
9984 #endif
9985 
9986  Poly_1D::CalcBernstein(p, ip.x, shape_x);
9987  Poly_1D::CalcBernstein(p, ip.y, shape_y);
9988 
9989  for (int o = 0, j = 0; j <= p; j++)
9990  for (int i = 0; i <= p; i++)
9991  {
9992  shape(o++) = shape_x(i)*shape_y(j);
9993  }
9994 }
9995 
9997  DenseMatrix &dshape) const
9998 {
9999  const int p = order;
10000 
10001 #ifdef MFEM_THREAD_SAFE
10002  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
10003 #endif
10004 
10005  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
10006  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
10007 
10008  for (int o = 0, j = 0; j <= p; j++)
10009  for (int i = 0; i <= p; i++)
10010  {
10011  dshape(o,0) = dshape_x(i)* shape_y(j);
10012  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
10013  }
10014 }
10015 
10017 {
10018  const int p = order;
10019 
10020  dofs = 0.0;
10021  switch (vertex)
10022  {
10023  case 0: dofs[0] = 1.0; break;
10024  case 1: dofs[p] = 1.0; break;
10025  case 2: dofs[p*(p + 2)] = 1.0; break;
10026  case 3: dofs[p*(p + 1)] = 1.0; break;
10027  }
10028 }
10029 
10030 
10031 L2_HexahedronElement::L2_HexahedronElement(const int p, const int btype)
10032  : NodalTensorFiniteElement(3, p, VerifyOpen(btype), L2_DOF_MAP)
10033 {
10034  const double *op = poly1d.OpenPoints(p, btype);
10035 
10036 #ifndef MFEM_THREAD_SAFE
10037  shape_x.SetSize(p + 1);
10038  shape_y.SetSize(p + 1);
10039  shape_z.SetSize(p + 1);
10040  dshape_x.SetSize(p + 1);
10041  dshape_y.SetSize(p + 1);
10042  dshape_z.SetSize(p + 1);
10043 #endif
10044 
10045  for (int o = 0, k = 0; k <= p; k++)
10046  for (int j = 0; j <= p; j++)
10047  for (int i = 0; i <= p; i++)
10048  {
10049  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
10050  }
10051 }
10052 
10054  Vector &shape) const
10055 {
10056  const int p = order;
10057 
10058 #ifdef MFEM_THREAD_SAFE
10059  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
10060 #endif
10061 
10062  basis1d.Eval(ip.x, shape_x);
10063  basis1d.Eval(ip.y, shape_y);
10064  basis1d.Eval(ip.z, shape_z);
10065 
10066  for (int o = 0, k = 0; k <= p; k++)
10067  for (int j = 0; j <= p; j++)
10068  for (int i = 0; i <= p; i++)
10069  {
10070  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
10071  }
10072 }
10073 
10075  DenseMatrix &dshape) const
10076 {
10077  const int p = order;
10078 
10079 #ifdef MFEM_THREAD_SAFE
10080  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
10081  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
10082 #endif
10083 
10084  basis1d.Eval(ip.x, shape_x, dshape_x);
10085  basis1d.Eval(ip.y, shape_y, dshape_y);
10086  basis1d.Eval(ip.z, shape_z, dshape_z);
10087 
10088  for (int o = 0, k = 0; k <= p; k++)
10089  for (int j = 0; j <= p; j++)
10090  for (int i = 0; i <= p; i++)
10091  {
10092  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
10093  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
10094  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
10095  }
10096 }
10097 
10098 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
10099 {
10100  const int p = order;
10101  const double *op = poly1d.OpenPoints(p, b_type);
10102 
10103 #ifdef MFEM_THREAD_SAFE
10104  Vector shape_x(p+1), shape_y(p+1);
10105 #endif
10106 
10107  for (int i = 0; i <= p; i++)
10108  {
10109  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
10110  shape_y(i) = poly1d.CalcDelta(p,op[i]);
10111  }
10112 
10113  switch (vertex)
10114  {
10115  case 0:
10116  for (int o = 0, k = 0; k <= p; k++)
10117  for (int j = 0; j <= p; j++)
10118  for (int i = 0; i <= p; i++)
10119  {
10120  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
10121  }
10122  break;
10123  case 1:
10124  for (int o = 0, k = 0; k <= p; k++)
10125  for (int j = 0; j <= p; j++)
10126  for (int i = 0; i <= p; i++)
10127  {
10128  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
10129  }
10130  break;
10131  case 2:
10132  for (int o = 0, k = 0; k <= p; k++)
10133  for (int j = 0; j <= p; j++)
10134  for (int i = 0; i <= p; i++)
10135  {
10136  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
10137  }
10138  break;
10139  case 3:
10140  for (int o = 0, k = 0; k <= p; k++)
10141  for (int j = 0; j <= p; j++)
10142  for (int i = 0; i <= p; i++)
10143  {
10144  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
10145  }
10146  break;
10147  case 4:
10148  for (int o = 0, k = 0; k <= p; k++)
10149  for (int j = 0; j <= p; j++)
10150  for (int i = 0; i <= p; i++)
10151  {
10152  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
10153  }
10154  break;
10155  case 5:
10156  for (int o = 0, k = 0; k <= p; k++)
10157  for (int j = 0; j <= p; j++)
10158  for (int i = 0; i <= p; i++)
10159  {
10160  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
10161  }
10162  break;
10163  case 6:
10164  for (int o = 0, k = 0; k <= p; k++)
10165  for (int j = 0; j <= p; j++)
10166  for (int i = 0; i <= p; i++)
10167  {
10168  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
10169  }
10170  break;
10171  case 7:
10172  for (int o = 0, k = 0; k <= p; k++)
10173  for (int j = 0; j <= p; j++)
10174  for (int i = 0; i <= p; i++)
10175  {
10176  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
10177  }
10178  break;
10179  }
10180 }
10181 
10182 
10184  : PositiveTensorFiniteElement(3, p, L2_DOF_MAP)
10185 {
10186 #ifndef MFEM_THREAD_SAFE
10187  shape_x.SetSize(p + 1);
10188  shape_y.SetSize(p + 1);
10189  shape_z.SetSize(p + 1);
10190  dshape_x.SetSize(p + 1);
10191  dshape_y.SetSize(p + 1);
10192  dshape_z.SetSize(p + 1);
10193 #endif
10194 
10195  if (p == 0)
10196  {
10197  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
10198  }
10199  else
10200  {
10201  for (int o = 0, k = 0; k <= p; k++)
10202  for (int j = 0; j <= p; j++)
10203  for (int i = 0; i <= p; i++)
10204  {
10205  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
10206  }
10207  }
10208 }
10209 
10211  Vector &shape) const
10212 {
10213  const int p = order;
10214 
10215 #ifdef MFEM_THREAD_SAFE
10216  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
10217 #endif
10218 
10219  Poly_1D::CalcBernstein(p, ip.x, shape_x);
10220  Poly_1D::CalcBernstein(p, ip.y, shape_y);
10221  Poly_1D::CalcBernstein(p, ip.z, shape_z);
10222 
10223  for (int o = 0, k = 0; k <= p; k++)
10224  for (int j = 0; j <= p; j++)
10225  for (int i = 0; i <= p; i++)
10226  {
10227  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
10228  }
10229 }
10230 
10232  DenseMatrix &dshape) const
10233 {
10234  const int p = order;
10235 
10236 #ifdef MFEM_THREAD_SAFE
10237  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
10238  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
10239 #endif
10240 
10241  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
10242  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
10243  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
10244 
10245  for (int o = 0, k = 0; k <= p; k++)
10246  for (int j = 0; j <= p; j++)
10247  for (int i = 0; i <= p; i++)
10248  {
10249  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
10250  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
10251  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
10252  }
10253 }
10254 
10255 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
10256 {
10257  const int p = order;
10258 
10259  dofs = 0.0;
10260  switch (vertex)
10261  {
10262  case 0: dofs[0] = 1.0; break;
10263  case 1: dofs[p] = 1.0; break;
10264  case 2: dofs[p*(p + 2)] = 1.0; break;
10265  case 3: dofs[p*(p + 1)] = 1.0; break;
10266  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
10267  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
10268  case 6: dofs[dof - 1] = 1.0; break;
10269  case 7: dofs[dof - p - 1] = 1.0; break;
10270  }
10271 }
10272 
10273 
10274 L2_TriangleElement::L2_TriangleElement(const int p, const int btype)
10275  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
10276  FunctionSpace::Pk)
10277 {
10278  const double *op = poly1d.OpenPoints(p, VerifyOpen(btype));
10279 
10280 #ifndef MFEM_THREAD_SAFE
10281  shape_x.SetSize(p + 1);
10282  shape_y.SetSize(p + 1);
10283  shape_l.SetSize(p + 1);
10284  dshape_x.SetSize(p + 1);
10285  dshape_y.SetSize(p + 1);
10286  dshape_l.SetSize(p + 1);
10287  u.SetSize(dof);
10288  du.SetSize(dof, dim);
10289 #else
10290  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10291 #endif
10292 
10293  for (int o = 0, j = 0; j <= p; j++)
10294  for (int i = 0; i + j <= p; i++)
10295  {
10296  double w = op[i] + op[j] + op[p-i-j];
10297  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
10298  }
10299 
10300  DenseMatrix T(dof);
10301  for (int k = 0; k < dof; k++)
10302  {
10303  IntegrationPoint &ip = Nodes.IntPoint(k);
10304  poly1d.CalcBasis(p, ip.x, shape_x);
10305  poly1d.CalcBasis(p, ip.y, shape_y);
10306  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
10307 
10308  for (int o = 0, j = 0; j <= p; j++)
10309  for (int i = 0; i + j <= p; i++)
10310  {
10311  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
10312  }
10313  }
10314 
10315  Ti.Factor(T);
10316  // mfem::out << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
10317 }
10318 
10320  Vector &shape) const
10321 {
10322  const int p = order;
10323 
10324 #ifdef MFEM_THREAD_SAFE
10325  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(dof);
10326 #endif
10327 
10328  poly1d.CalcBasis(p, ip.x, shape_x);
10329  poly1d.CalcBasis(p, ip.y, shape_y);
10330  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
10331 
10332  for (int o = 0, j = 0; j <= p; j++)
10333  for (int i = 0; i + j <= p; i++)
10334  {
10335  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
10336  }
10337 
10338  Ti.Mult(u, shape);
10339 }
10340 
10342  DenseMatrix &dshape) const
10343 {
10344  const int p = order;
10345 
10346 #ifdef MFEM_THREAD_SAFE
10347  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10348  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
10349  DenseMatrix du(dof, dim);
10350 #endif
10351 
10352  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
10353  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
10354  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
10355 
10356  for (int o = 0, j = 0; j <= p; j++)
10357  for (int i = 0; i + j <= p; i++)
10358  {
10359  int k = p - i - j;
10360  du(o,0) = ((dshape_x(i)* shape_l(k)) -
10361  ( shape_x(i)*dshape_l(k)))*shape_y(j);
10362  du(o,1) = ((dshape_y(j)* shape_l(k)) -
10363  ( shape_y(j)*dshape_l(k)))*shape_x(i);
10364  o++;
10365  }
10366 
10367  Ti.Mult(du, dshape);
10368 }
10369 
10370 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
10371 {
10372  switch (vertex)
10373  {
10374  case 0:
10375  for (int i = 0; i < dof; i++)
10376  {
10377  const IntegrationPoint &ip = Nodes.IntPoint(i);
10378  dofs[i] = pow(1.0 - ip.x - ip.y, order);
10379  }
10380  break;
10381  case 1:
10382  for (int i = 0; i < dof; i++)
10383  {
10384  const IntegrationPoint &ip = Nodes.IntPoint(i);
10385  dofs[i] = pow(ip.x, order);
10386  }
10387  break;
10388  case 2:
10389  for (int i = 0; i < dof; i++)
10390  {
10391  const IntegrationPoint &ip = Nodes.IntPoint(i);
10392  dofs[i] = pow(ip.y, order);
10393  }
10394  break;
10395  }
10396 }
10397 
10398 
10400  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
10401  FunctionSpace::Pk)
10402 {
10403 #ifndef MFEM_THREAD_SAFE
10404  dshape_1d.SetSize(p + 1);
10405 #endif
10406 
10407  if (p == 0)
10408  {
10409  Nodes.IntPoint(0).Set2(1./3, 1./3);
10410  }
10411  else
10412  {
10413  for (int o = 0, j = 0; j <= p; j++)
10414  for (int i = 0; i + j <= p; i++)
10415  {
10416  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
10417  }
10418  }
10419 }
10420 
10422  Vector &shape) const
10423 {
10424  H1Pos_TriangleElement::CalcShape(order, ip.x, ip.y, shape.GetData());
10425 }
10426 
10428  DenseMatrix &dshape) const
10429 {
10430 #ifdef MFEM_THREAD_SAFE
10431  Vector dshape_1d(order + 1);
10432 #endif
10433 
10434  H1Pos_TriangleElement::CalcDShape(order, ip.x, ip.y, dshape_1d.GetData(),
10435  dshape.Data());
10436 }
10437 
10438 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
10439 {
10440  dofs = 0.0;
10441  switch (vertex)
10442  {
10443  case 0: dofs[0] = 1.0; break;
10444  case 1: dofs[order] = 1.0; break;
10445  case 2: dofs[dof-1] = 1.0; break;
10446  }
10447 }
10448 
10449 
10451  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
10452  p, FunctionSpace::Pk)
10453 {
10454  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
10455 
10456 #ifndef MFEM_THREAD_SAFE
10457  shape_x.SetSize(p + 1);
10458  shape_y.SetSize(p + 1);
10459  shape_z.SetSize(p + 1);
10460  shape_l.SetSize(p + 1);
10461  dshape_x.SetSize(p + 1);
10462  dshape_y.SetSize(p + 1);
10463  dshape_z.SetSize(p + 1);
10464  dshape_l.SetSize(p + 1);
10465  u.SetSize(dof);
10466  du.SetSize(dof, dim);
10467 #else
10468  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10469 #endif
10470 
10471  for (int o = 0, k = 0; k <= p; k++)
10472  for (int j = 0; j + k <= p; j++)
10473  for (int i = 0; i + j + k <= p; i++)
10474  {
10475  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
10476  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
10477  }
10478 
10479  DenseMatrix T(dof);
10480  for (int m = 0; m < dof; m++)
10481  {
10482  IntegrationPoint &ip = Nodes.IntPoint(m);
10483  poly1d.CalcBasis(p, ip.x, shape_x);
10484  poly1d.CalcBasis(p, ip.y, shape_y);
10485  poly1d.CalcBasis(p, ip.z, shape_z);
10486  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
10487 
10488  for (int o = 0, k = 0; k <= p; k++)
10489  for (int j = 0; j + k <= p; j++)
10490  for (int i = 0; i + j + k <= p; i++)
10491  {
10492  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
10493  }
10494  }
10495 
10496  Ti.Factor(T);
10497  // mfem::out << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
10498 }
10499 
10501  Vector &shape) const
10502 {
10503  const int p = order;
10504 
10505 #ifdef MFEM_THREAD_SAFE
10506  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10507  Vector u(dof);
10508 #endif
10509 
10510  poly1d.CalcBasis(p, ip.x, shape_x);
10511  poly1d.CalcBasis(p, ip.y, shape_y);
10512  poly1d.CalcBasis(p, ip.z, shape_z);
10513  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
10514 
10515  for (int o = 0, k = 0; k <= p; k++)
10516  for (int j = 0; j + k <= p; j++)
10517  for (int i = 0; i + j + k <= p; i++)
10518  {
10519  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
10520  }
10521 
10522  Ti.Mult(u, shape);
10523 }
10524 
10526  DenseMatrix &dshape) const
10527 {
10528  const int p = order;
10529 
10530 #ifdef MFEM_THREAD_SAFE
10531  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10532  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
10533  DenseMatrix du(dof, dim);
10534 #endif
10535 
10536  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
10537  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
10538  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
10539  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10540 
10541  for (int o = 0, k = 0; k <= p; k++)
10542  for (int j = 0; j + k <= p; j++)
10543  for (int i = 0; i + j + k <= p; i++)
10544  {
10545  int l = p - i - j - k;
10546  du(o,0) = ((dshape_x(i)* shape_l(l)) -
10547  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
10548  du(o,1) = ((dshape_y(j)* shape_l(l)) -
10549  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
10550  du(o,2) = ((dshape_z(k)* shape_l(l)) -
10551  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
10552  o++;
10553  }
10554 
10555  Ti.Mult(du, dshape);
10556 }
10557 
10558 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
10559 {
10560  switch (vertex)
10561  {
10562  case 0:
10563  for (int i = 0; i < dof; i++)
10564  {
10565  const IntegrationPoint &ip = Nodes.IntPoint(i);
10566  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, order);
10567  }
10568  break;
10569  case 1:
10570  for (int i = 0; i < dof; i++)
10571  {
10572  const IntegrationPoint &ip = Nodes.IntPoint(i);
10573  dofs[i] = pow(ip.x, order);
10574  }
10575  break;
10576  case 2:
10577  for (int i = 0; i < dof; i++)
10578  {
10579  const IntegrationPoint &ip = Nodes.IntPoint(i);
10580  dofs[i] = pow(ip.y, order);
10581  }
10582  break;
10583  case 3:
10584  for (int i = 0; i < dof; i++)
10585  {
10586  const IntegrationPoint &ip = Nodes.IntPoint(i);
10587  dofs[i] = pow(ip.z, order);
10588  }
10589  break;
10590  }
10591 }
10592 
10593 
10595  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
10596  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
10597 {
10598 #ifndef MFEM_THREAD_SAFE
10599  dshape_1d.SetSize(p + 1);
10600 #endif
10601 
10602  if (p == 0)
10603  {
10604  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
10605  }
10606  else
10607  {
10608  for (int o = 0, k = 0; k <= p; k++)
10609  for (int j = 0; j + k <= p; j++)
10610  for (int i = 0; i + j + k <= p; i++)
10611  {
10612  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
10613  }
10614  }
10615 }
10616 
10618  Vector &shape) const
10619 {
10621  shape.GetData());
10622 }
10623 
10625  DenseMatrix &dshape) const
10626 {
10627 #ifdef MFEM_THREAD_SAFE
10628  Vector dshape_1d(order + 1);
10629 #endif
10630 
10632  dshape_1d.GetData(), dshape.Data());
10633 }
10634 
10635 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
10636 {
10637  dofs = 0.0;
10638  switch (vertex)
10639  {
10640  case 0: dofs[0] = 1.0; break;
10641  case 1: dofs[order] = 1.0; break;
10642  case 2: dofs[(order*(order+3))/2] = 1.0; break;
10643  case 3: dofs[dof-1] = 1.0; break;
10644  }
10645 }
10646 
10647 
10648 L2_WedgeElement::L2_WedgeElement(const int p, const int btype)
10649  : NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
10650  p, FunctionSpace::Qk),
10651  TriangleFE(p, btype),
10652  SegmentFE(p, btype)
10653 {
10654 #ifndef MFEM_THREAD_SAFE
10655  t_shape.SetSize(TriangleFE.GetDof());
10656  s_shape.SetSize(SegmentFE.GetDof());
10657  t_dshape.SetSize(TriangleFE.GetDof(), 2);
10658  s_dshape.SetSize(SegmentFE.GetDof(), 1);
10659 #endif
10660 
10661  t_dof.SetSize(dof);
10662  s_dof.SetSize(dof);
10663 
10664  // Interior DoFs
10665  int m=0;
10666  for (int k=0; k<=p; k++)
10667  {
10668  int l=0;
10669  for (int j=0; j<=p; j++)
10670  {
10671  for (int i=0; i<=j; i++)
10672  {
10673  t_dof[m] = l;
10674  s_dof[m] = k;
10675  l++; m++;
10676  }
10677  }
10678  }
10679 
10680  // Define Nodes
10681  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
10682  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
10683  for (int i=0; i<dof; i++)
10684  {
10685  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
10686  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
10687  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
10688  }
10689 }
10690 
10692  Vector &shape) const
10693 {
10694 #ifdef MFEM_THREAD_SAFE
10695  Vector t_shape(TriangleFE.GetDof());
10696  Vector s_shape(SegmentFE.GetDof());
10697 #endif
10698 
10699  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10700 
10701  TriangleFE.CalcShape(ip, t_shape);
10702  SegmentFE.CalcShape(ipz, s_shape);
10703 
10704  for (int i=0; i<dof; i++)
10705  {
10706  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
10707  }
10708 }
10709 
10711  DenseMatrix &dshape) const
10712 {
10713 #ifdef MFEM_THREAD_SAFE
10714  Vector t_shape(TriangleFE.GetDof());
10715  DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
10716  Vector s_shape(SegmentFE.GetDof());
10717  DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
10718 #endif
10719 
10720  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10721 
10722  TriangleFE.CalcShape(ip, t_shape);
10723  TriangleFE.CalcDShape(ip, t_dshape);
10724  SegmentFE.CalcShape(ipz, s_shape);
10725  SegmentFE.CalcDShape(ipz, s_dshape);
10726 
10727  for (int i=0; i<dof; i++)
10728  {
10729  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
10730  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
10731  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
10732  }
10733 }
10734 
10735 
10737  : PositiveFiniteElement(3, Geometry::PRISM,
10738  ((p + 1)*(p + 1)*(p + 2))/2, p, FunctionSpace::Qk),
10739  TriangleFE(p),
10740  SegmentFE(p)
10741 {
10742 #ifndef MFEM_THREAD_SAFE
10747 #endif
10748 
10749  t_dof.SetSize(dof);
10750  s_dof.SetSize(dof);
10751 
10752  // Interior DoFs
10753  int m=0;
10754  for (int k=0; k<=p; k++)
10755  {
10756  int l=0;
10757  for (int j=0; j<=p; j++)
10758  {
10759  for (int i=0; i<=j; i++)
10760  {
10761  t_dof[m] = l;
10762  s_dof[m] = k;
10763  l++; m++;
10764  }
10765  }
10766  }
10767 
10768  // Define Nodes
10769  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
10770  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
10771  for (int i=0; i<dof; i++)
10772  {
10773  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
10774  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
10775  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
10776  }
10777 }
10778 
10780  Vector &shape) const
10781 {
10782 #ifdef MFEM_THREAD_SAFE
10785 #endif
10786 
10787  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10788 
10790  SegmentFE.CalcShape(ipz, s_shape);
10791 
10792  for (int i=0; i<dof; i++)
10793  {
10794  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
10795  }
10796 }
10797 
10799  DenseMatrix &dshape) const
10800 {
10801 #ifdef MFEM_THREAD_SAFE
10806 #endif
10807 
10808  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
10809 
10812  SegmentFE.CalcShape(ipz, s_shape);
10814 
10815  for (int i=0; i<dof; i++)
10816  {
10817  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
10818  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
10819  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
10820  }
10821 }
10822 
10823 
10824 const double RT_QuadrilateralElement::nk[8] =
10825 { 0., -1., 1., 0., 0., 1., -1., 0. };
10826 
10828  const int cb_type,
10829  const int ob_type)
10830  : VectorTensorFiniteElement(2, 2*(p + 1)*(p + 2), p + 1, cb_type, ob_type,
10831  H_DIV, DofMapType::L2_DOF_MAP),
10832  dof2nk(dof),
10833  cp(poly1d.ClosedPoints(p + 1, cb_type))
10834 {
10835  if (obasis1d.IsIntegratedType()) { is_nodal = false; }
10836 
10837  dof_map.SetSize(dof);
10838 
10839  const double *op = poly1d.OpenPoints(p, ob_type);
10840  const int dof2 = dof/2;
10841 
10842 #ifndef MFEM_THREAD_SAFE
10843  shape_cx.SetSize(p + 2);
10844  shape_ox.SetSize(p + 1);
10845  shape_cy.SetSize(p + 2);
10846  shape_oy.SetSize(p + 1);
10847  dshape_cx.SetSize(p + 2);
10848  dshape_cy.SetSize(p + 2);
10849 #endif
10850 
10851  // edges
10852  int o = 0;
10853  for (int i = 0; i <= p; i++) // (0,1)
10854  {
10855  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
10856  }
10857  for (int i = 0; i <= p; i++) // (1,2)
10858  {
10859  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
10860  }
10861  for (int i = 0; i <= p; i++) // (2,3)
10862  {
10863  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
10864  }
10865  for (int i = 0; i <= p; i++) // (3,0)
10866  {
10867  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
10868  }
10869 
10870  // interior
10871  for (int j = 0; j <= p; j++) // x-components
10872  for (int i = 1; i <= p; i++)
10873  {
10874  dof_map[0*dof2 + i + j*(p + 2)] = o++;
10875  }
10876  for (int j = 1; j <= p; j++) // y-components
10877  for (int i = 0; i <= p; i++)
10878  {
10879  dof_map[1*dof2 + i + j*(p + 1)] = o++;
10880  }
10881 
10882  // dof orientations
10883  // x-components
10884  for (int j = 0; j <= p; j++)
10885  for (int i = 0; i <= p/2; i++)
10886  {
10887  int idx = 0*dof2 + i + j*(p + 2);
10888  dof_map[idx] = -1 - dof_map[idx];
10889  }
10890  if (p%2 == 1)
10891  for (int j = p/2 + 1; j <= p; j++)
10892  {
10893  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
10894  dof_map[idx] = -1 - dof_map[idx];
10895  }
10896  // y-components
10897  for (int j = 0; j <= p/2; j++)
10898  for (int i = 0; i <= p; i++)
10899  {
10900  int idx = 1*dof2 + i + j*(p + 1);
10901  dof_map[idx] = -1 - dof_map[idx];
10902  }
10903  if (p%2 == 1)
10904  for (int i = 0; i <= p/2; i++)
10905  {
10906  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
10907  dof_map[idx] = -1 - dof_map[idx];
10908  }
10909 
10910  o = 0;
10911  for (int j = 0; j <= p; j++)
10912  for (int i = 0; i <= p + 1; i++)
10913  {
10914  int idx;
10915  if ((idx = dof_map[o++]) < 0)
10916  {
10917  idx = -1 - idx;
10918  dof2nk[idx] = 3;
10919  }
10920  else
10921  {
10922  dof2nk[idx] = 1;
10923  }
10924  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
10925  }
10926  for (int j = 0; j <= p + 1; j++)
10927  for (int i = 0; i <= p; i++)
10928  {
10929  int idx;
10930  if ((idx = dof_map[o++]) < 0)
10931  {
10932  idx = -1 - idx;
10933  dof2nk[idx] = 0;
10934  }
10935  else
10936  {
10937  dof2nk[idx] = 2;
10938  }
10939  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
10940  }
10941 }
10942 
10944  DenseMatrix &shape) const
10945 {
10946  const int pp1 = order;
10947 
10948 #ifdef MFEM_THREAD_SAFE
10949  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10950 #endif
10951 
10952  if (obasis1d.IsIntegratedType())
10953  {
10954  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10955  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10956  obasis1d.EvalIntegrated(dshape_cx, shape_ox);
10957  obasis1d.EvalIntegrated(dshape_cy, shape_oy);
10958  }
10959  else
10960  {
10961  cbasis1d.Eval(ip.x, shape_cx);
10962  cbasis1d.Eval(ip.y, shape_cy);
10963  obasis1d.Eval(ip.x, shape_ox);
10964  obasis1d.Eval(ip.y, shape_oy);
10965  }
10966 
10967  int o = 0;
10968  for (int j = 0; j < pp1; j++)
10969  for (int i = 0; i <= pp1; i++)
10970  {
10971  int idx, s;
10972  if ((idx = dof_map[o++]) < 0)
10973  {
10974  idx = -1 - idx, s = -1;
10975  }
10976  else
10977  {
10978  s = +1;
10979  }
10980  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
10981  shape(idx,1) = 0.;
10982  }
10983  for (int j = 0; j <= pp1; j++)
10984  for (int i = 0; i < pp1; i++)
10985  {
10986  int idx, s;
10987  if ((idx = dof_map[o++]) < 0)
10988  {
10989  idx = -1 - idx, s = -1;
10990  }
10991  else
10992  {
10993  s = +1;
10994  }
10995  shape(idx,0) = 0.;
10996  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
10997  }
10998 }
10999 
11001  Vector &divshape) const
11002 {
11003  const int pp1 = order;
11004 
11005 #ifdef MFEM_THREAD_SAFE
11006  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
11007  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
11008 #endif
11009 
11010  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11011  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11012  if (obasis1d.IsIntegratedType())
11013  {
11014  obasis1d.EvalIntegrated(dshape_cx, shape_ox);
11015  obasis1d.EvalIntegrated(dshape_cy, shape_oy);
11016  }
11017  else
11018  {
11019  obasis1d.Eval(ip.x, shape_ox);
11020  obasis1d.Eval(ip.y, shape_oy);
11021  }
11022 
11023  int o = 0;
11024  for (int j = 0; j < pp1; j++)
11025  for (int i = 0; i <= pp1; i++)
11026  {
11027  int idx, s;
11028  if ((idx = dof_map[o++]) < 0)
11029  {
11030  idx = -1 - idx, s = -1;
11031  }
11032  else
11033  {
11034  s = +1;
11035  }
11036  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
11037  }
11038  for (int j = 0; j <= pp1; j++)
11039  for (int i = 0; i < pp1; i++)
11040  {
11041  int idx, s;
11042  if ((idx = dof_map[o++]) < 0)
11043  {
11044  idx = -1 - idx, s = -1;
11045  }
11046  else
11047  {
11048  s = +1;
11049  }
11050  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
11051  }
11052 }
11053 
11056  Vector &dofs) const
11057 {
11058  MFEM_ASSERT(obasis1d.IsIntegratedType(), "Not integrated type");
11059  double vk[Geometry::MaxDim];
11060  Vector xk(vk, vc.GetVDim());
11061 
11063  const int nqpt = ir.GetNPoints();
11064 
11065  IntegrationPoint ip2d;
11066 
11067  int o = 0;
11068  for (int c = 0; c < 2; c++)
11069  {
11070  int im = (c == 0) ? order + 1 : order;
11071  int jm = (c == 1) ? order + 1 : order;
11072  for (int j = 0; j < jm; j++)
11073  for (int i = 0; i < im; i++)
11074  {
11075  int idx = dof_map[o++];
11076  if (idx < 0) { idx = -1 - idx; }
11077  int ic = (c == 0) ? j : i;
11078  const double h = cp[ic+1] - cp[ic];
11079  double val = 0.0;
11080  for (int k = 0; k < nqpt; k++)
11081  {
11082  const IntegrationPoint &ip1d = ir.IntPoint(k);
11083  if (c == 0) { ip2d.Set2(cp[i], cp[j] + (h*ip1d.x)); }
11084  else { ip2d.Set2(cp[i] + (h*ip1d.x), cp[j]); }
11085  Trans.SetIntPoint(&ip2d);
11086  vc.Eval(xk, Trans, ip2d);
11087  // nk^t adj(J) xk
11088  const double ipval = Trans.AdjugateJacobian().InnerProduct(vk,
11089  nk + dof2nk[idx]*dim);
11090  val += ip1d.weight*ipval;
11091  }
11092  dofs(idx) = val*h;
11093  }
11094  }
11095 }
11096 
11097 
11098 const double RT_HexahedronElement::nk[18] =
11099 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
11100 
11102  const int cb_type,
11103  const int ob_type)
11104  : VectorTensorFiniteElement(3, 3*(p + 1)*(p + 1)*(p + 2), p + 1, cb_type,
11105  ob_type, H_DIV, DofMapType::L2_DOF_MAP),
11106  dof2nk(dof),
11107  cp(poly1d.ClosedPoints(p + 1, cb_type))
11108 {
11109  if (obasis1d.IsIntegratedType()) { is_nodal = false; }
11110 
11111  dof_map.SetSize(dof);
11112 
11113  const double *op = poly1d.OpenPoints(p, ob_type);
11114  const int dof3 = dof/3;
11115 
11116 #ifndef MFEM_THREAD_SAFE
11117  shape_cx.SetSize(p + 2);
11118  shape_ox.SetSize(p + 1);
11119  shape_cy.SetSize(p + 2);
11120  shape_oy.SetSize(p + 1);
11121  shape_cz.SetSize(p + 2);
11122  shape_oz.SetSize(p + 1);
11123  dshape_cx.SetSize(p + 2);
11124  dshape_cy.SetSize(p + 2);
11125  dshape_cz.SetSize(p + 2);
11126 #endif
11127 
11128  // faces
11129  int o = 0;
11130  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
11131  for (int i = 0; i <= p; i++)
11132  {
11133  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
11134  }
11135  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
11136  for (int i = 0; i <= p; i++)
11137  {
11138  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
11139  }
11140  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
11141  for (int i = 0; i <= p; i++)
11142  {
11143  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
11144  }
11145  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
11146  for (int i = 0; i <= p; i++)
11147  {
11148  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
11149  }
11150  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
11151  for (int i = 0; i <= p; i++)
11152  {
11153  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
11154  }
11155  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
11156  for (int i = 0; i <= p; i++)
11157  {
11158  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
11159  }
11160 
11161  // interior
11162  // x-components
11163  for (int k = 0; k <= p; k++)
11164  for (int j = 0; j <= p; j++)
11165  for (int i = 1; i <= p; i++)
11166  {
11167  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
11168  }
11169  // y-components
11170  for (int k = 0; k <= p; k++)
11171  for (int j = 1; j <= p; j++)
11172  for (int i = 0; i <= p; i++)
11173  {
11174  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
11175  }
11176  // z-components
11177  for (int k = 1; k <= p; k++)
11178  for (int j = 0; j <= p; j++)
11179  for (int i = 0; i <= p; i++)
11180  {
11181  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
11182  }
11183 
11184  // dof orientations
11185  // for odd p, do not change the orientations in the mid-planes
11186  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
11187  // respectively.
11188  // x-components
11189  for (int k = 0; k <= p; k++)
11190  for (int j = 0; j <= p; j++)
11191  for (int i = 0; i <= p/2; i++)
11192  {
11193  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
11194  dof_map[idx] = -1 - dof_map[idx];
11195  }
11196  // y-components
11197  for (int k = 0; k <= p; k++)
11198  for (int j = 0; j <= p/2; j++)
11199  for (int i = 0; i <= p; i++)
11200  {
11201  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
11202  dof_map[idx] = -1 - dof_map[idx];
11203  }
11204  // z-components
11205  for (int k = 0; k <= p/2; k++)
11206  for (int j = 0; j <= p; j++)
11207  for (int i = 0; i <= p; i++)
11208  {
11209  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
11210  dof_map[idx] = -1 - dof_map[idx];
11211  }
11212 
11213  o = 0;
11214  // x-components
11215  for (int k = 0; k <= p; k++)
11216  for (int j = 0; j <= p; j++)
11217  for (int i = 0; i <= p + 1; i++)
11218  {
11219  int idx;
11220  if ((idx = dof_map[o++]) < 0)
11221  {
11222  idx = -1 - idx;
11223  dof2nk[idx] = 4;
11224  }
11225  else
11226  {
11227  dof2nk[idx] = 2;
11228  }
11229  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
11230  }
11231  // y-components
11232  for (int k = 0; k <= p; k++)
11233  for (int j = 0; j <= p + 1; j++)
11234  for (int i = 0; i <= p; i++)
11235  {
11236  int idx;
11237  if ((idx = dof_map[o++]) < 0)
11238  {
11239  idx = -1 - idx;
11240  dof2nk[idx] = 1;
11241  }
11242  else
11243  {
11244  dof2nk[idx] = 3;
11245  }
11246  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
11247  }
11248  // z-components
11249  for (int k = 0; k <= p + 1; k++)
11250  for (int j = 0; j <= p; j++)
11251  for (int i = 0; i <= p; i++)
11252  {
11253  int idx;
11254  if ((idx = dof_map[o++]) < 0)
11255  {
11256  idx = -1 - idx;
11257  dof2nk[idx] = 0;
11258  }
11259  else
11260  {
11261  dof2nk[idx] = 5;
11262  }
11263  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
11264  }
11265 }
11266 
11268  DenseMatrix &shape) const
11269 {
11270  const int pp1 = order;
11271 
11272 #ifdef MFEM_THREAD_SAFE
11273  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
11274  Vector shape_cz(pp1 + 1), shape_oz(pp1);
11275 #endif
11276 
11277  if (obasis1d.IsIntegratedType())
11278  {
11279  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11280  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11281  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
11282  obasis1d.EvalIntegrated(dshape_cx, shape_ox);
11283  obasis1d.EvalIntegrated(dshape_cy, shape_oy);
11284  obasis1d.EvalIntegrated(dshape_cz, shape_oz);
11285  }
11286  else
11287  {
11288  cbasis1d.Eval(ip.x, shape_cx);
11289  cbasis1d.Eval(ip.y, shape_cy);
11290  cbasis1d.Eval(ip.z, shape_cz);
11291  obasis1d.Eval(ip.x, shape_ox);
11292  obasis1d.Eval(ip.y, shape_oy);
11293  obasis1d.Eval(ip.z, shape_oz);
11294  }
11295 
11296  int o = 0;
11297  // x-components
11298  for (int k = 0; k < pp1; k++)
11299  for (int j = 0; j < pp1; j++)
11300  for (int i = 0; i <= pp1; i++)
11301  {
11302  int idx, s;
11303  if ((idx = dof_map[o++]) < 0)
11304  {
11305  idx = -1 - idx, s = -1;
11306  }
11307  else
11308  {
11309  s = +1;
11310  }
11311  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
11312  shape(idx,1) = 0.;
11313  shape(idx,2) = 0.;
11314  }
11315  // y-components
11316  for (int k = 0; k < pp1; k++)
11317  for (int j = 0; j <= pp1; j++)
11318  for (int i = 0; i < pp1; i++)
11319  {
11320  int idx, s;
11321  if ((idx = dof_map[o++]) < 0)
11322  {
11323  idx = -1 - idx, s = -1;
11324  }
11325  else
11326  {
11327  s = +1;
11328  }
11329  shape(idx,0) = 0.;
11330  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
11331  shape(idx,2) = 0.;
11332  }
11333  // z-components
11334  for (int k = 0; k <= pp1; k++)
11335  for (int j = 0; j < pp1; j++)
11336  for (int i = 0; i < pp1; i++)
11337  {
11338  int idx, s;
11339  if ((idx = dof_map[o++]) < 0)
11340  {
11341  idx = -1 - idx, s = -1;
11342  }
11343  else
11344  {
11345  s = +1;
11346  }
11347  shape(idx,0) = 0.;
11348  shape(idx,1) = 0.;
11349  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
11350  }
11351 }
11352 
11354  Vector &divshape) const
11355 {
11356  const int pp1 = order;
11357 
11358 #ifdef MFEM_THREAD_SAFE
11359  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
11360  Vector shape_cz(pp1 + 1), shape_oz(pp1);
11361  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
11362 #endif
11363 
11364  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11365  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11366  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
11367  if (obasis1d.IsIntegratedType())
11368  {
11369  obasis1d.EvalIntegrated(dshape_cx, shape_ox);
11370  obasis1d.EvalIntegrated(dshape_cy, shape_oy);
11371  obasis1d.EvalIntegrated(dshape_cz, shape_oz);
11372  }
11373  else
11374  {
11375  obasis1d.Eval(ip.x, shape_ox);
11376  obasis1d.Eval(ip.y, shape_oy);
11377  obasis1d.Eval(ip.z, shape_oz);
11378  }
11379 
11380  int o = 0;
11381  // x-components
11382  for (int k = 0; k < pp1; k++)
11383  for (int j = 0; j < pp1; j++)
11384  for (int i = 0; i <= pp1; i++)
11385  {
11386  int idx, s;
11387  if ((idx = dof_map[o++]) < 0)
11388  {
11389  idx = -1 - idx, s = -1;
11390  }
11391  else
11392  {
11393  s = +1;
11394  }
11395  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
11396  }
11397  // y-components
11398  for (int k = 0; k < pp1; k++)
11399  for (int j = 0; j <= pp1; j++)
11400  for (int i = 0; i < pp1; i++)
11401  {
11402  int idx, s;
11403  if ((idx = dof_map[o++]) < 0)
11404  {
11405  idx = -1 - idx, s = -1;
11406  }
11407  else
11408  {
11409  s = +1;
11410  }
11411  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
11412  }
11413  // z-components
11414  for (int k = 0; k <= pp1; k++)
11415  for (int j = 0; j < pp1; j++)
11416  for (int i = 0; i < pp1; i++)
11417  {
11418  int idx, s;
11419  if ((idx = dof_map[o++]) < 0)
11420  {
11421  idx = -1 - idx, s = -1;
11422  }
11423  else
11424  {
11425  s = +1;
11426  }
11427  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
11428  }
11429 }
11430 
11433  Vector &dofs) const
11434 {
11435  MFEM_ASSERT(obasis1d.IsIntegratedType(), "Not integrated type");
11436  double vq[Geometry::MaxDim];
11437  Vector xq(vq, vc.GetVDim());
11438 
11440  const int nqpt = ir2d.GetNPoints();
11441 
11442  IntegrationPoint ip3d;
11443 
11444  int o = 0;
11445  for (int c = 0; c < 3; c++)
11446  {
11447  int im = (c == 0) ? order + 1 : order;
11448  int jm = (c == 1) ? order + 1 : order;
11449  int km = (c == 2) ? order + 1 : order;
11450  for (int k = 0; k < km; k++)
11451  for (int j = 0; j < jm; j++)
11452  for (int i = 0; i < im; i++)
11453  {
11454  int idx = dof_map[o++];
11455  if (idx < 0) { idx = -1 - idx; }
11456  int ic1, ic2;
11457  if (c == 0) { ic1 = j; ic2 = k; }
11458  else if (c == 1) { ic1 = i; ic2 = k; }
11459  else { ic1 = i; ic2 = j; }
11460  const double h1 = cp[ic1+1] - cp[ic1];
11461  const double h2 = cp[ic2+1] - cp[ic2];
11462  double val = 0.0;
11463  for (int q = 0; q < nqpt; q++)
11464  {
11465  const IntegrationPoint &ip2d = ir2d.IntPoint(q);
11466  if (c == 0) { ip3d.Set3(cp[i], cp[j] + h1*ip2d.x, cp[k] + h2*ip2d.y); }
11467  else if (c == 1) { ip3d.Set3(cp[i] + h1*ip2d.x, cp[j], cp[k] + h2*ip2d.y); }
11468  else { ip3d.Set3(cp[i] + h1*ip2d.x, cp[j] + h2*ip2d.y, cp[k]); }
11469  Trans.SetIntPoint(&ip3d);
11470  vc.Eval(xq, Trans, ip3d);
11471  // nk^t adj(J) xq
11472  const double ipval
11473  = Trans.AdjugateJacobian().InnerProduct(vq, nk + dof2nk[idx]*dim);
11474  val += ip2d.weight*ipval;
11475  }
11476  dofs(idx) = val*h1*h2;
11477  }
11478  }
11479 }
11480 
11481 
11482 const double RT_TriangleElement::nk[6] =
11483 { 0., -1., 1., 1., -1., 0. };
11484 
11485 const double RT_TriangleElement::c = 1./3.;
11486 
11488  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
11489  H_DIV, FunctionSpace::Pk),
11490  dof2nk(dof)
11491 {
11492  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
11493  const double *bop = poly1d.OpenPoints(p);
11494 
11495 #ifndef MFEM_THREAD_SAFE
11496  shape_x.SetSize(p + 1);
11497  shape_y.SetSize(p + 1);
11498  shape_l.SetSize(p + 1);
11499  dshape_x.SetSize(p + 1);
11500  dshape_y.SetSize(p + 1);
11501  dshape_l.SetSize(p + 1);
11502  u.SetSize(dof, dim);
11503  divu.SetSize(dof);
11504 #else
11505  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
11506 #endif
11507 
11508  // edges
11509  int o = 0;
11510  for (int i = 0; i <= p; i++) // (0,1)
11511  {
11512  Nodes.IntPoint(o).Set2(bop[i], 0.);
11513  dof2nk[o++] = 0;
11514  }
11515  for (int i = 0; i <= p; i++) // (1,2)
11516  {
11517  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
11518  dof2nk[o++] = 1;
11519  }
11520  for (int i = 0; i <= p; i++) // (2,0)
11521  {
11522  Nodes.IntPoint(o).Set2(0., bop[p-i]);
11523  dof2nk[o++] = 2;
11524  }
11525 
11526  // interior
11527  for (int j = 0; j < p; j++)
11528  for (int i = 0; i + j < p; i++)
11529  {
11530  double w = iop[i] + iop[j] + iop[p-1-i-j];
11531  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
11532  dof2nk[o++] = 0;
11533  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
11534  dof2nk[o++] = 2;
11535  }
11536 
11537  DenseMatrix T(dof);
11538  for (int k = 0; k < dof; k++)
11539  {
11540  const IntegrationPoint &ip = Nodes.IntPoint(k);
11541  poly1d.CalcBasis(p, ip.x, shape_x);
11542  poly1d.CalcBasis(p, ip.y, shape_y);
11543  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
11544  const double *n_k = nk + 2*dof2nk[k];
11545 
11546  o = 0;
11547  for (int j = 0; j <= p; j++)
11548  for (int i = 0; i + j <= p; i++)
11549  {
11550  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
11551  T(o++, k) = s*n_k[0];
11552  T(o++, k) = s*n_k[1];
11553  }
11554  for (int i = 0; i <= p; i++)
11555  {
11556  double s = shape_x(i)*shape_y(p-i);
11557  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
11558  }
11559  }
11560 
11561  Ti.Factor(T);
11562  // mfem::out << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
11563 }
11564 
11566  DenseMatrix &shape) const
11567 {
11568  const int p = order - 1;
11569 
11570 #ifdef MFEM_THREAD_SAFE
11571  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
11572  DenseMatrix u(dof, dim);
11573 #endif
11574 
11575  poly1d.CalcBasis(p, ip.x, shape_x);
11576  poly1d.CalcBasis(p, ip.y, shape_y);
11577  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
11578 
11579  int o = 0;
11580  for (int j = 0; j <= p; j++)
11581  for (int i = 0; i + j <= p; i++)
11582  {
11583  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
11584  u(o,0) = s; u(o,1) = 0; o++;
11585  u(o,0) = 0; u(o,1) = s; o++;
11586  }
11587  for (int i = 0; i <= p; i++)
11588  {
11589  double s = shape_x(i)*shape_y(p-i);
11590  u(o,0) = (ip.x - c)*s;
11591  u(o,1) = (ip.y - c)*s;
11592  o++;
11593  }
11594 
11595  Ti.Mult(u, shape);
11596 }
11597 
11599  Vector &divshape) const
11600 {
11601  const int p = order - 1;
11602 
11603 #ifdef MFEM_THREAD_SAFE
11604  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
11605  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
11606  Vector divu(dof);
11607 #endif
11608 
11609  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
11610  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
11611  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
11612 
11613  int o = 0;
11614  for (int j = 0; j <= p; j++)
11615  for (int i = 0; i + j <= p; i++)
11616  {
11617  int k = p - i - j;
11618  divu(o++) = (dshape_x(i)*shape_l(k) -
11619  shape_x(i)*dshape_l(k))*shape_y(j);
11620  divu(o++) = (dshape_y(j)*shape_l(k) -
11621  shape_y(j)*dshape_l(k))*shape_x(i);
11622  }
11623  for (int i = 0; i <= p; i++)
11624  {
11625  int j = p - i;
11626  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
11627  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
11628  }
11629 
11630  Ti.Mult(divu, divshape);
11631 }
11632 
11633 
11634 const double RT_TetrahedronElement::nk[12] =
11635 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
11636 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
11637 
11638 const double RT_TetrahedronElement::c = 1./4.;
11639 
11641  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
11642  p + 1, H_DIV, FunctionSpace::Pk),
11643  dof2nk(dof)
11644 {
11645  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
11646  const double *bop = poly1d.OpenPoints(p);
11647 
11648 #ifndef MFEM_THREAD_SAFE
11649  shape_x.SetSize(p + 1);
11650  shape_y.SetSize(p + 1);
11651  shape_z.SetSize(p + 1);
11652  shape_l.SetSize(p + 1);
11653  dshape_x.SetSize(p + 1);
11654  dshape_y.SetSize(p + 1);
11655  dshape_z.SetSize(p + 1);
11656  dshape_l.SetSize(p + 1);
11657  u.SetSize(dof, dim);
11658  divu.SetSize(dof);
11659 #else
11660  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
11661 #endif
11662 
11663  int o = 0;
11664  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
11665  // the constructor of H1_TetrahedronElement)
11666  for (int j = 0; j <= p; j++)
11667  for (int i = 0; i + j <= p; i++) // (1,2,3)
11668  {
11669  double w = bop[i] + bop[j] + bop[p-i-j];
11670  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
11671  dof2nk[o++] = 0;
11672  }
11673  for (int j = 0; j <= p; j++)
11674  for (int i = 0; i + j <= p; i++) // (0,3,2)
11675  {
11676  double w = bop[i] + bop[j] + bop[p-i-j];
11677  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
11678  dof2nk[o++] = 1;
11679  }
11680  for (int j = 0; j <= p; j++)
11681  for (int i = 0; i + j <= p; i++) // (0,1,3)
11682  {
11683  double w = bop[i] + bop[j] + bop[p-i-j];
11684  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
11685  dof2nk[o++] = 2;
11686  }
11687  for (int j = 0; j <= p; j++)
11688  for (int i = 0; i + j <= p; i++) // (0,2,1)
11689  {
11690  double w = bop[i] + bop[j] + bop[p-i-j];
11691  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
11692  dof2nk[o++] = 3;
11693  }
11694 
11695  // interior
11696  for (int k = 0; k < p; k++)
11697  for (int j = 0; j + k < p; j++)
11698  for (int i = 0; i + j + k < p; i++)
11699  {
11700  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
11701  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11702  dof2nk[o++] = 1;
11703  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11704  dof2nk[o++] = 2;
11705  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11706  dof2nk[o++] = 3;
11707  }
11708 
11709  DenseMatrix T(dof);
11710  for (int m = 0; m < dof; m++)
11711  {
11712  const IntegrationPoint &ip = Nodes.IntPoint(m);
11713  poly1d.CalcBasis(p, ip.x, shape_x);
11714  poly1d.CalcBasis(p, ip.y, shape_y);
11715  poly1d.CalcBasis(p, ip.z, shape_z);
11716  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
11717  const double *nm = nk + 3*dof2nk[m];
11718 
11719  o = 0;
11720  for (int k = 0; k <= p; k++)
11721  for (int j = 0; j + k <= p; j++)
11722  for (int i = 0; i + j + k <= p; i++)
11723  {
11724  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
11725  T(o++, m) = s * nm[0];
11726  T(o++, m) = s * nm[1];
11727  T(o++, m) = s * nm[2];
11728  }
11729  for (int j = 0; j <= p; j++)
11730  for (int i = 0; i + j <= p; i++)
11731  {
11732  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
11733  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
11734  (ip.z - c)*nm[2]);
11735  }
11736  }
11737 
11738  Ti.Factor(T);
11739  // mfem::out << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
11740 }
11741 
11743  DenseMatrix &shape) const
11744 {
11745  const int p = order - 1;
11746 
11747 #ifdef MFEM_THREAD_SAFE
11748  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
11749  DenseMatrix u(dof, dim);
11750 #endif
11751 
11752  poly1d.CalcBasis(p, ip.x, shape_x);
11753  poly1d.CalcBasis(p, ip.y, shape_y);
11754  poly1d.CalcBasis(p, ip.z, shape_z);
11755  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
11756 
11757  int o = 0;
11758  for (int k = 0; k <= p; k++)
11759  for (int j = 0; j + k <= p; j++)
11760  for (int i = 0; i + j + k <= p; i++)
11761  {
11762  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
11763  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
11764  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
11765  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
11766  }
11767  for (int j = 0; j <= p; j++)
11768  for (int i = 0; i + j <= p; i++)
11769  {
11770  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
11771  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
11772  o++;
11773  }
11774 
11775  Ti.Mult(u, shape);
11776 }
11777 
11779  Vector &divshape) const
11780 {
11781  const int p = order - 1;
11782 
11783 #ifdef MFEM_THREAD_SAFE
11784  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
11785  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
11786  Vector divu(dof);
11787 #endif
11788 
11789  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
11790  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
11791  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
11792  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
11793 
11794  int o = 0;
11795  for (int k = 0; k <= p; k++)
11796  for (int j = 0; j + k <= p; j++)
11797  for (int i = 0; i + j + k <= p; i++)
11798  {
11799  int l = p - i - j - k;
11800  divu(o++) = (dshape_x(i)*shape_l(l) -
11801  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
11802  divu(o++) = (dshape_y(j)*shape_l(l) -
11803  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
11804  divu(o++) = (dshape_z(k)*shape_l(l) -
11805  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
11806  }
11807  for (int j = 0; j <= p; j++)
11808  for (int i = 0; i + j <= p; i++)
11809  {
11810  int k = p - i - j;
11811  divu(o++) =
11812  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
11813  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
11814  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
11815  }
11816 
11817  Ti.Mult(divu, divshape);
11818 }
11819 
11820 
11821 const double ND_HexahedronElement::tk[18] =
11822 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
11823 
11825  const int cb_type, const int ob_type)
11826  : VectorTensorFiniteElement(3, 3*p*(p + 1)*(p + 1), p, cb_type, ob_type,
11827  H_CURL, DofMapType::L2_DOF_MAP),
11828  dof2tk(dof), cp(poly1d.ClosedPoints(p, cb_type))
11829 {
11830  if (obasis1d.IsIntegratedType()) { is_nodal = false; }
11831 
11832  dof_map.SetSize(dof);
11833 
11834  const double *op = poly1d.OpenPoints(p - 1, ob_type);
11835  const int dof3 = dof/3;
11836 
11837 #ifndef MFEM_THREAD_SAFE
11838  shape_cx.SetSize(p + 1);
11839  shape_ox.SetSize(p);
11840  shape_cy.SetSize(p + 1);
11841  shape_oy.SetSize(p);
11842  shape_cz.SetSize(p + 1);
11843  shape_oz.SetSize(p);
11844  dshape_cx.SetSize(p + 1);
11845  dshape_cy.SetSize(p + 1);
11846  dshape_cz.SetSize(p + 1);
11847 #endif
11848 
11849  // edges
11850  int o = 0;
11851  for (int i = 0; i < p; i++) // (0,1)
11852  {
11853  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
11854  }
11855  for (int i = 0; i < p; i++) // (1,2)
11856  {
11857  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
11858  }
11859  for (int i = 0; i < p; i++) // (3,2)
11860  {
11861  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
11862  }
11863  for (int i = 0; i < p; i++) // (0,3)
11864  {
11865  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
11866  }
11867  for (int i = 0; i < p; i++) // (4,5)
11868  {
11869  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
11870  }
11871  for (int i = 0; i < p; i++) // (5,6)
11872  {
11873  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
11874  }
11875  for (int i = 0; i < p; i++) // (7,6)
11876  {
11877  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
11878  }
11879  for (int i = 0; i < p; i++) // (4,7)
11880  {
11881  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
11882  }
11883  for (int i = 0; i < p; i++) // (0,4)
11884  {
11885  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
11886  }
11887  for (int i = 0; i < p; i++) // (1,5)
11888  {
11889  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
11890  }
11891  for (int i = 0; i < p; i++) // (2,6)
11892  {
11893  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
11894  }
11895  for (int i = 0; i < p; i++) // (3,7)
11896  {
11897  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
11898  }
11899 
11900  // faces
11901  // (3,2,1,0) -- bottom
11902  for (int j = 1; j < p; j++) // x - components
11903  for (int i = 0; i < p; i++)
11904  {
11905  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
11906  }
11907  for (int j = 0; j < p; j++) // y - components
11908  for (int i = 1; i < p; i++)
11909  {
11910  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
11911  }
11912  // (0,1,5,4) -- front
11913  for (int k = 1; k < p; k++) // x - components
11914  for (int i = 0; i < p; i++)
11915  {
11916  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
11917  }
11918  for (int k = 0; k < p; k++) // z - components
11919  for (int i = 1; i < p; i++ )
11920  {
11921  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
11922  }
11923  // (1,2,6,5) -- right
11924  for (int k = 1; k < p; k++) // y - components
11925  for (int j = 0; j < p; j++)
11926  {
11927  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
11928  }
11929  for (int k = 0; k < p; k++) // z - components
11930  for (int j = 1; j < p; j++)
11931  {
11932  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
11933  }
11934  // (2,3,7,6) -- back
11935  for (int k = 1; k < p; k++) // x - components
11936  for (int i = 0; i < p; i++)
11937  {
11938  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
11939  }
11940  for (int k = 0; k < p; k++) // z - components
11941  for (int i = 1; i < p; i++)
11942  {
11943  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
11944  }
11945  // (3,0,4,7) -- left
11946  for (int k = 1; k < p; k++) // y - components
11947  for (int j = 0; j < p; j++)
11948  {
11949  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
11950  }
11951  for (int k = 0; k < p; k++) // z - components
11952  for (int j = 1; j < p; j++)
11953  {
11954  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
11955  }
11956  // (4,5,6,7) -- top
11957  for (int j = 1; j < p; j++) // x - components
11958  for (int i = 0; i < p; i++)
11959  {
11960  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
11961  }
11962  for (int j = 0; j < p; j++) // y - components
11963  for (int i = 1; i < p; i++)
11964  {
11965  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
11966  }
11967 
11968  // interior
11969  // x-components
11970  for (int k = 1; k < p; k++)
11971  for (int j = 1; j < p; j++)
11972  for (int i = 0; i < p; i++)
11973  {
11974  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
11975  }
11976  // y-components
11977  for (int k = 1; k < p; k++)
11978  for (int j = 0; j < p; j++)
11979  for (int i = 1; i < p; i++)
11980  {
11981  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
11982  }
11983  // z-components
11984  for (int k = 0; k < p; k++)
11985  for (int j = 1; j < p; j++)
11986  for (int i = 1; i < p; i++)
11987  {
11988  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
11989  }
11990 
11991  // set dof2tk and Nodes
11992  o = 0;
11993  // x-components
11994  for (int k = 0; k <= p; k++)
11995  for (int j = 0; j <= p; j++)
11996  for (int i = 0; i < p; i++)
11997  {
11998  int idx;
11999  if ((idx = dof_map[o++]) < 0)
12000  {
12001  dof2tk[idx = -1 - idx] = 3;
12002  }
12003  else
12004  {
12005  dof2tk[idx] = 0;
12006  }
12007  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
12008  }
12009  // y-components
12010  for (int k = 0; k <= p; k++)
12011  for (int j = 0; j < p; j++)
12012  for (int i = 0; i <= p; i++)
12013  {
12014  int idx;
12015  if ((idx = dof_map[o++]) < 0)
12016  {
12017  dof2tk[idx = -1 - idx] = 4;
12018  }
12019  else
12020  {
12021  dof2tk[idx] = 1;
12022  }
12023  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
12024  }
12025  // z-components
12026  for (int k = 0; k < p; k++)
12027  for (int j = 0; j <= p; j++)
12028  for (int i = 0; i <= p; i++)
12029  {
12030  int idx;
12031  if ((idx = dof_map[o++]) < 0)
12032  {
12033  dof2tk[idx = -1 - idx] = 5;
12034  }
12035  else
12036  {
12037  dof2tk[idx] = 2;
12038  }
12039  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
12040  }
12041 }
12042 
12045  Vector &dofs) const
12046 {
12047  MFEM_ASSERT(obasis1d.IsIntegratedType(), "Not integrated type");
12048  double vk[Geometry::MaxDim];
12049  Vector xk(vk, vc.GetVDim());
12050 
12052  const int nqpt = ir.GetNPoints();
12053 
12054  IntegrationPoint ip3d;
12055 
12056  int o = 0;
12057  for (int c = 0; c < 3; ++c) // loop over x, y, z components
12058  {
12059  const int im = c == 0 ? order - 1 : order;
12060  const int jm = c == 1 ? order - 1 : order;
12061  const int km = c == 2 ? order - 1 : order;
12062 
12063  for (int k = 0; k <= km; k++)
12064  for (int j = 0; j <= jm; j++)
12065  for (int i = 0; i <= im; i++)
12066  {
12067  int idx;
12068  if ((idx = dof_map[o++]) < 0)
12069  {
12070  idx = -1 - idx;
12071  }
12072 
12073  const int id1 = c == 0 ? i : (c == 1 ? j : k);
12074  const double h = cp[id1+1] - cp[id1];
12075 
12076  double val = 0.0;
12077 
12078  for (int q = 0; q < nqpt; q++)
12079  {
12080  const IntegrationPoint &ip1d = ir.IntPoint(q);
12081 
12082  if (c == 0)
12083  {
12084  ip3d.Set3(cp[i] + (h*ip1d.x), cp[j], cp[k]);
12085  }
12086  else if (c == 1)
12087  {
12088  ip3d.Set3(cp[i], cp[j] + (h*ip1d.x), cp[k]);
12089  }
12090  else
12091  {
12092  ip3d.Set3(cp[i], cp[j], cp[k] + (h*ip1d.x));
12093  }
12094 
12095  Trans.SetIntPoint(&ip3d);
12096  vc.Eval(xk, Trans, ip3d);
12097 
12098  // xk^t J tk
12099  const double ipval = Trans.Jacobian().InnerProduct(tk + dof2tk[idx]*dim, vk);
12100  val += ip1d.weight * ipval;
12101  }
12102 
12103  dofs(idx) = val*h;
12104  }
12105  }
12106 }
12107 
12109  DenseMatrix &shape) const
12110 {
12111  const int p = order;
12112 
12113 #ifdef MFEM_THREAD_SAFE
12114  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
12115  Vector shape_cz(p + 1), shape_oz(p);
12116 #endif
12117 
12118  if (obasis1d.IsIntegratedType())
12119  {
12120  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
12121  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
12122  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
12123  obasis1d.EvalIntegrated(dshape_cx, shape_ox);
12124  obasis1d.EvalIntegrated(dshape_cy, shape_oy);
12125  obasis1d.EvalIntegrated(dshape_cz, shape_oz);
12126  }
12127  else
12128  {
12129  cbasis1d.Eval(ip.x, shape_cx);
12130  cbasis1d.Eval(ip.y, shape_cy);
12131  cbasis1d.Eval(ip.z, shape_cz);
12132  obasis1d.Eval(ip.x, shape_ox);
12133  obasis1d.Eval(ip.y, shape_oy);
12134  obasis1d.Eval(ip.z, shape_oz);
12135  }
12136 
12137  int o = 0;
12138  // x-components
12139  for (int k = 0; k <= p; k++)
12140  for (int j = 0; j <= p; j++)
12141  for (int i = 0; i < p; i++)
12142  {
12143  int idx, s;
12144  if ((idx = dof_map[o++]) < 0)
12145  {
12146  idx = -1 - idx, s = -1;
12147  }
12148  else
12149  {
12150  s = +1;
12151  }
12152  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
12153  shape(idx,1) = 0.;
12154  shape(idx,2) = 0.;
12155  }
12156  // y-components
12157  for (int k = 0; k <= p; k++)
12158  for (int j = 0; j < p; j++)
12159  for (int i = 0; i <= p; i++)
12160  {
12161  int idx, s;
12162  if ((idx = dof_map[o++]) < 0)
12163  {
12164  idx = -1 - idx, s = -1;
12165  }
12166  else
12167  {
12168  s = +1;
12169  }
12170  shape(idx,0) = 0.;
12171  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
12172  shape(idx,2) = 0.;
12173  }
12174  // z-components
12175  for (int k = 0; k < p; k++)
12176  for (int j = 0; j <= p; j++)
12177  for (int i = 0; i <= p; i++)
12178  {
12179  int idx, s;
12180  if ((idx = dof_map[o++]) < 0)
12181  {
12182  idx = -1 - idx, s = -1;
12183  }
12184  else
12185  {
12186  s = +1;
12187  }
12188  shape(idx,0) = 0.;
12189  shape(idx,1) = 0.;
12190  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
12191  }
12192 }
12193 
12195  DenseMatrix &curl_shape) const
12196 {
12197  const int p = order;
12198 
12199 #ifdef MFEM_THREAD_SAFE
12200  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
12201  Vector shape_cz(p + 1), shape_oz(p);
12202  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
12203 #endif
12204 
12205  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
12206  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
12207  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
12208  if (obasis1d.IsIntegratedType())
12209  {
12210  obasis1d.EvalIntegrated(dshape_cx, shape_ox);
12211  obasis1d.EvalIntegrated(dshape_cy, shape_oy);
12212  obasis1d.EvalIntegrated(dshape_cz, shape_oz);
12213  }
12214  else
12215  {
12216  obasis1d.Eval(ip.x, shape_ox);
12217  obasis1d.Eval(ip.y, shape_oy);
12218  obasis1d.Eval(ip.z, shape_oz);
12219  }
12220 
12221  int o = 0;
12222  // x-components
12223  for (int k = 0; k <= p; k++)
12224  for (int j = 0; j <= p; j++)
12225  for (int i = 0; i < p; i++)
12226  {
12227  int idx, s;
12228  if ((idx = dof_map[o++]) < 0)
12229  {
12230  idx = -1 - idx, s = -1;
12231  }
12232  else
12233  {
12234  s = +1;
12235  }
12236  curl_shape(idx,0) = 0.;
12237  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
12238  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
12239  }
12240  // y-components
12241  for (int k = 0; k <= p; k++)
12242  for (int j = 0; j < p; j++)
12243  for (int i = 0; i <= p; i++)
12244  {
12245  int idx, s;
12246  if ((idx = dof_map[o++]) < 0)
12247  {
12248  idx = -1 - idx, s = -1;
12249  }
12250  else
12251  {
12252  s = +1;
12253  }
12254  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
12255  curl_shape(idx,1) = 0.;
12256  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
12257  }
12258  // z-components
12259  for (int k = 0; k < p; k++)
12260  for (int j = 0; j <= p; j++)
12261  for (int i = 0; i <= p; i++)
12262  {
12263  int idx, s;
12264  if ((idx = dof_map[o++]) < 0)
12265  {
12266  idx = -1 - idx, s = -1;
12267  }
12268  else
12269  {
12270  s = +1;
12271  }
12272  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
12273  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
12274  curl_shape(idx,2) = 0.;
12275  }
12276 }
12277 
12279  const IntegrationRule &ir,
12280  DofToQuad::Mode mode) const
12281 {
12282  MFEM_VERIFY(mode != DofToQuad::FULL, "invalid mode requested");
12283 
12284  return GetTensorDofToQuad(ir, mode, true);
12285 }
12286 
12288  const IntegrationRule &ir,
12289  DofToQuad::Mode mode) const
12290 {
12291  MFEM_VERIFY(mode != DofToQuad::FULL, "invalid mode requested");
12292 
12293  return GetTensorDofToQuad(ir, mode, false);
12294 }
12295 
12297  const IntegrationRule &ir,
12298  DofToQuad::Mode mode,
12299  const bool closed) const
12300 {
12301  MFEM_VERIFY(mode == DofToQuad::TENSOR, "invalid mode requested");
12302 
12303  for (int i = 0;
12304  i < (closed ? dof2quad_array.Size() : dof2quad_array_open.Size());
12305  i++)
12306  {
12307  const DofToQuad &d2q = closed ? *dof2quad_array[i] : *dof2quad_array_open[i];
12308  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
12309  }
12310 
12311  DofToQuad *d2q = new DofToQuad;
12312  const int ndof = closed ? order + 1 : order;
12313  const int nqpt = (int)floor(pow(ir.GetNPoints(), 1.0/dim) + 0.5);
12314  d2q->FE = this;
12315  d2q->IntRule = &ir;
12316  d2q->mode = mode;
12317  d2q->ndof = ndof;
12318  d2q->nqpt = nqpt;
12319  d2q->B.SetSize(nqpt*ndof);
12320  d2q->Bt.SetSize(ndof*nqpt);
12321  d2q->G.SetSize(nqpt*ndof);
12322  d2q->Gt.SetSize(ndof*nqpt);
12323  Vector val(ndof), grad(ndof);
12324  for (int i = 0; i < nqpt; i++)
12325  {
12326  // The first 'nqpt' points in 'ir' have the same x-coordinates as those
12327  // of the 1D rule.
12328 
12329  if (closed)
12330  {
12331  cbasis1d.Eval(ir.IntPoint(i).x, val, grad);
12332  }
12333  else
12334  {
12335  obasis1d.Eval(ir.IntPoint(i).x, val, grad);
12336  }
12337 
12338  for (int j = 0; j < ndof; j++)
12339  {
12340  d2q->B[i+nqpt*j] = d2q->Bt[j+ndof*i] = val(j);
12341  d2q->G[i+nqpt*j] = d2q->Gt[j+ndof*i] = grad(j);
12342  }
12343  }
12344 
12345  if (closed)
12346  {
12347  dof2quad_array.Append(d2q);
12348  }
12349  else
12350  {
12351  dof2quad_array_open.Append(d2q);
12352  }
12353 
12354  return *d2q;
12355 }
12356 
12358 {
12359  for (int i = 0; i < dof2quad_array_open.Size(); i++)
12360  {
12361  delete dof2quad_array_open[i];
12362  }
12363 }
12364 
12365 const double ND_QuadrilateralElement::tk[8] =
12366 { 1.,0., 0.,1., -1.,0., 0.,-1. };
12367 
12369  const int cb_type,
12370  const int ob_type)
12371  : VectorTensorFiniteElement(2, 2*p*(p + 1), p, cb_type, ob_type,
12372  H_CURL, DofMapType::L2_DOF_MAP),
12373  dof2tk(dof),
12374  cp(poly1d.ClosedPoints(p, cb_type))
12375 {
12376  if (obasis1d.IsIntegratedType()) { is_nodal = false; }
12377 
12378  dof_map.SetSize(dof);
12379 
12380  const double *op = poly1d.OpenPoints(p - 1, ob_type);
12381  const int dof2 = dof/2;
12382 
12383 #ifndef MFEM_THREAD_SAFE
12384  shape_cx.SetSize(p + 1);
12385  shape_ox.SetSize(p);
12386  shape_cy.SetSize(p + 1);
12387  shape_oy.SetSize(p);
12388  dshape_cx.SetSize(p + 1);
12389  dshape_cy.SetSize(p + 1);
12390 #endif
12391 
12392  // edges
12393  int o = 0;
12394  for (int i = 0; i < p; i++) // (0,1)
12395  {
12396  dof_map[0*dof2 + i + 0*p] = o++;
12397  }
12398  for (int j = 0; j < p; j++) // (1,2)
12399  {
12400  dof_map[1*dof2 + p + j*(p + 1)] = o++;
12401  }
12402  for (int i = 0; i < p; i++) // (2,3)
12403  {
12404  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
12405  }
12406  for (int j = 0; j < p; j++) // (3,0)
12407  {
12408  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
12409  }
12410 
12411  // interior
12412  // x-components
12413  for (int j = 1; j < p; j++)
12414  for (int i = 0; i < p; i++)
12415  {
12416  dof_map[0*dof2 + i + j*p] = o++;
12417  }
12418  // y-components
12419  for (int j = 0; j < p; j++)
12420  for (int i = 1; i < p; i++)
12421  {
12422  dof_map[1*dof2 + i + j*(p + 1)] = o++;
12423  }
12424 
12425  // set dof2tk and Nodes
12426  o = 0;
12427  // x-components
12428  for (int j = 0; j <= p; j++)
12429  for (int i = 0; i < p; i++)
12430  {
12431  int idx;
12432  if ((idx = dof_map[o++]) < 0)
12433  {
12434  dof2tk[idx = -1 - idx] = 2;
12435  }
12436  else
12437  {
12438  dof2tk[idx] = 0;
12439  }
12440  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
12441  }
12442  // y-components
12443  for (int j = 0; j < p; j++)
12444  for (int i = 0; i <= p; i++)
12445  {
12446  int idx;
12447  if ((idx = dof_map[o++]) < 0)
12448  {
12449  dof2tk[idx = -1 - idx] = 3;
12450  }
12451  else
12452  {
12453  dof2tk[idx] = 1;
12454  }
12455  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
12456  }
12457 }
12458 
12461  Vector &dofs) const
12462 {
12463  MFEM_ASSERT(obasis1d.IsIntegratedType(), "Not integrated type");
12464  double vk[Geometry::MaxDim];
12465  Vector xk(vk, vc.GetVDim());
12466 
12468  const int nqpt = ir.GetNPoints();
12469 
12470  IntegrationPoint ip2d;
12471 
12472  int o = 0;
12473  // x-components
12474  for (int j = 0; j <= order; j++)
12475  for (int i = 0; i < order; i++)
12476  {
12477  int idx;
12478  if ((idx = dof_map[o++]) < 0)
12479  {
12480  idx = -1 - idx;
12481  }
12482 
12483  const double h = cp[i+1] - cp[i];
12484 
12485  double val = 0.0;
12486 
12487  for (int k = 0; k < nqpt; k++)
12488  {
12489  const IntegrationPoint &ip1d = ir.IntPoint(k);
12490 
12491  ip2d.Set2(cp[i] + (h*ip1d.x), cp[j]);
12492 
12493  Trans.SetIntPoint(&ip2d);
12494  vc.Eval(xk, Trans, ip2d);
12495 
12496  // xk^t J tk
12497  const double ipval = Trans.Jacobian().InnerProduct(tk + dof2tk[idx]*dim, vk);
12498  val += ip1d.weight * ipval;
12499  }
12500 
12501  dofs(idx) = val*h;
12502  }
12503  // y-components
12504  for (int j = 0; j < order; j++)
12505  for (int i = 0; i <= order; i++)
12506  {
12507  int idx;
12508  if ((idx = dof_map[o++]) < 0)
12509  {
12510  idx = -1 - idx;
12511  }
12512 
12513  const double h = cp[j+1] - cp[j];
12514 
12515  double val = 0.0;
12516 
12517  for (int k = 0; k < nqpt; k++)
12518  {
12519  const IntegrationPoint &ip1d = ir.IntPoint(k);
12520 
12521  ip2d.Set2(cp[i], cp[j] + (h*ip1d.x));
12522 
12523  Trans.SetIntPoint(&ip2d);
12524  vc.Eval(xk, Trans, ip2d);
12525 
12526  // xk^t J tk
12527  const double ipval = Trans.Jacobian().InnerProduct(tk + dof2tk[idx]*dim, vk);
12528  val += ip1d.weight * ipval;
12529  }
12530 
12531  dofs(idx) = val*h;
12532  }
12533 }
12534 
12536  DenseMatrix &shape) const
12537 {
12538  const int p = order;
12539 
12540 #ifdef MFEM_THREAD_SAFE
12541  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
12542 #endif
12543 
12544  if (obasis1d.IsIntegratedType())
12545  {
12546  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
12547  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
12548  obasis1d.EvalIntegrated(dshape_cx, shape_ox);
12549  obasis1d.EvalIntegrated(dshape_cy, shape_oy);
12550  }
12551  else
12552  {
12553  cbasis1d.Eval(ip.x, shape_cx);
12554  cbasis1d.Eval(ip.y, shape_cy);
12555  obasis1d.Eval(ip.x, shape_ox);
12556  obasis1d.Eval(ip.y, shape_oy);
12557  }
12558 
12559  int o = 0;
12560  // x-components
12561  for (int j = 0; j <= p; j++)
12562  for (int i = 0; i < p; i++)
12563  {
12564  int idx, s;
12565  if ((idx = dof_map[o++]) < 0)
12566  {
12567  idx = -1 - idx, s = -1;
12568  }
12569  else
12570  {
12571  s = +1;
12572  }
12573  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
12574  shape(idx,1) = 0.;
12575  }
12576  // y-components
12577  for (int j = 0; j < p; j++)
12578  for (int i = 0; i <= p; i++)
12579  {
12580  int idx, s;
12581  if ((idx = dof_map[o++]) < 0)
12582  {
12583  idx = -1 - idx, s = -1;
12584  }
12585  else
12586  {
12587  s = +1;
12588  }
12589  shape(idx,0) = 0.;
12590  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
12591  }
12592 }
12593 
12595  DenseMatrix &curl_shape) const
12596 {
12597  const int p = order;
12598 
12599 #ifdef MFEM_THREAD_SAFE
12600  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
12601  Vector dshape_cx(p + 1), dshape_cy(p + 1);
12602 #endif
12603 
12604  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
12605  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
12606  if (obasis1d.IsIntegratedType())
12607  {
12608  obasis1d.EvalIntegrated(dshape_cx, shape_ox);
12609  obasis1d.EvalIntegrated(dshape_cy, shape_oy);
12610  }
12611  else
12612  {
12613  obasis1d.Eval(ip.x, shape_ox);
12614  obasis1d.Eval(ip.y, shape_oy);
12615  }
12616 
12617  int o = 0;
12618  // x-components
12619  for (int j = 0; j <= p; j++)
12620  for (int i = 0; i < p; i++)
12621  {
12622  int idx, s;
12623  if ((idx = dof_map[o++]) < 0)
12624  {
12625  idx = -1 - idx, s = -1;
12626  }
12627  else
12628  {
12629  s = +1;
12630  }
12631  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
12632  }
12633  // y-components
12634  for (int j = 0; j < p; j++)
12635  for (int i = 0; i <= p; i++)
12636  {
12637  int idx, s;
12638  if ((idx = dof_map[o++]) < 0)
12639  {
12640  idx = -1 - idx, s = -1;
12641  }
12642  else
12643  {
12644  s = +1;
12645  }
12646  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
12647  }
12648 }
12649 
12650 
12651 const double ND_TetrahedronElement::tk[18] =
12652 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
12653 
12654 const double ND_TetrahedronElement::c = 1./4.;
12655 
12657  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
12658  H_CURL, FunctionSpace::Pk), dof2tk(dof)
12659 {
12660  const double *eop = poly1d.OpenPoints(p - 1);
12661  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
12662  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
12663 
12664  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
12665 
12666 #ifndef MFEM_THREAD_SAFE
12667  shape_x.SetSize(p);
12668  shape_y.SetSize(p);
12669  shape_z.SetSize(p);
12670  shape_l.SetSize(p);
12671  dshape_x.SetSize(p);
12672  dshape_y.SetSize(p);
12673  dshape_z.SetSize(p);
12674  dshape_l.SetSize(p);
12675  u.SetSize(dof, dim);
12676 #else
12677  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
12678 #endif
12679 
12680  int o = 0;
12681  // edges
12682  for (int i = 0; i < p; i++) // (0,1)
12683  {
12684  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
12685  dof2tk[o++] = 0;
12686  }
12687  for (int i = 0; i < p; i++) // (0,2)
12688  {
12689  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
12690  dof2tk[o++] = 1;
12691  }
12692  for (int i = 0; i < p; i++) // (0,3)
12693  {
12694  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
12695  dof2tk[o++] = 2;
12696  }
12697  for (int i = 0; i < p; i++) // (1,2)
12698  {
12699  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
12700  dof2tk[o++] = 3;
12701  }
12702  for (int i = 0; i < p; i++) // (1,3)
12703  {
12704  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
12705  dof2tk[o++] = 4;
12706  }
12707  for (int i = 0; i < p; i++) // (2,3)
12708  {
12709  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
12710  dof2tk[o++] = 5;
12711  }
12712 
12713  // faces
12714  for (int j = 0; j <= pm2; j++) // (1,2,3)
12715  for (int i = 0; i + j <= pm2; i++)
12716  {
12717  double w = fop[i] + fop[j] + fop[pm2-i-j];
12718  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
12719  dof2tk[o++] = 3;
12720  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
12721  dof2tk[o++] = 4;
12722  }
12723  for (int j = 0; j <= pm2; j++) // (0,3,2)
12724  for (int i = 0; i + j <= pm2; i++)
12725  {
12726  double w = fop[i] + fop[j] + fop[pm2-i-j];
12727  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
12728  dof2tk[o++] = 2;
12729  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
12730  dof2tk[o++] = 1;
12731  }
12732  for (int j = 0; j <= pm2; j++) // (0,1,3)
12733  for (int i = 0; i + j <= pm2; i++)
12734  {
12735  double w = fop[i] + fop[j] + fop[pm2-i-j];
12736  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
12737  dof2tk[o++] = 0;
12738  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
12739  dof2tk[o++] = 2;
12740  }
12741  for (int j = 0; j <= pm2; j++) // (0,2,1)
12742  for (int i = 0; i + j <= pm2; i++)
12743  {
12744  double w = fop[i] + fop[j] + fop[pm2-i-j];
12745  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
12746  dof2tk[o++] = 1;
12747  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
12748  dof2tk[o++] = 0;
12749  }
12750 
12751  // interior
12752  for (int k = 0; k <= pm3; k++)
12753  for (int j = 0; j + k <= pm3; j++)
12754  for (int i = 0; i + j + k <= pm3; i++)
12755  {
12756  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
12757  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
12758  dof2tk[o++] = 0;
12759  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
12760  dof2tk[o++] = 1;
12761  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
12762  dof2tk[o++] = 2;
12763  }
12764 
12765  DenseMatrix T(dof);
12766  for (int m = 0; m < dof; m++)
12767  {
12768  const IntegrationPoint &ip = Nodes.IntPoint(m);
12769  const double *tm = tk + 3*dof2tk[m];
12770  o = 0;
12771 
12772  poly1d.CalcBasis(pm1, ip.x, shape_x);
12773  poly1d.CalcBasis(pm1, ip.y, shape_y);
12774  poly1d.CalcBasis(pm1, ip.z, shape_z);
12775  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
12776 
12777  for (int k = 0; k <= pm1; k++)
12778  for (int j = 0; j + k <= pm1; j++)
12779  for (int i = 0; i + j + k <= pm1; i++)
12780  {
12781  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
12782  T(o++, m) = s * tm[0];
12783  T(o++, m) = s * tm[1];
12784  T(o++, m) = s * tm[2];
12785  }
12786  for (int k = 0; k <= pm1; k++)
12787  for (int j = 0; j + k <= pm1; j++)
12788  {
12789  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
12790  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
12791  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
12792  }
12793  for (int k = 0; k <= pm1; k++)
12794  {
12795  T(o++, m) =
12796  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
12797  }
12798  }
12799 
12800  Ti.Factor(T);
12801  // mfem::out << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
12802 }
12803 
12805  DenseMatrix &shape) const
12806 {
12807  const int pm1 = order - 1;
12808 
12809 #ifdef MFEM_THREAD_SAFE
12810  const int p = order;
12811  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
12812  DenseMatrix u(dof, dim);
12813 #endif
12814 
12815  poly1d.CalcBasis(pm1, ip.x, shape_x);
12816  poly1d.CalcBasis(pm1, ip.y, shape_y);
12817  poly1d.CalcBasis(pm1, ip.z, shape_z);
12818  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
12819 
12820  int n = 0;
12821  for (int k = 0; k <= pm1; k++)
12822  for (int j = 0; j + k <= pm1; j++)
12823  for (int i = 0; i + j + k <= pm1; i++)
12824  {
12825  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
12826  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
12827  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
12828  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
12829  }
12830  for (int k = 0; k <= pm1; k++)
12831  for (int j = 0; j + k <= pm1; j++)
12832  {
12833  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
12834  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
12835  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
12836  }
12837  for (int k = 0; k <= pm1; k++)
12838  {
12839  double s = shape_y(pm1-k)*shape_z(k);
12840  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
12841  }
12842 
12843  Ti.Mult(u, shape);
12844 }
12845 
12847  DenseMatrix &curl_shape) const
12848 {
12849  const int pm1 = order - 1;
12850 
12851 #ifdef MFEM_THREAD_SAFE
12852  const int p = order;
12853  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
12854  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
12855  DenseMatrix u(dof, dim);
12856 #endif
12857 
12858  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
12859  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
12860  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
12861  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
12862 
12863  int n = 0;
12864  for (int k = 0; k <= pm1; k++)
12865  for (int j = 0; j + k <= pm1; j++)
12866  for (int i = 0; i + j + k <= pm1; i++)
12867  {
12868  int l = pm1-i-j-k;
12869  const double dx = (dshape_x(i)*shape_l(l) -
12870  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
12871  const double dy = (dshape_y(j)*shape_l(l) -
12872  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
12873  const double dz = (dshape_z(k)*shape_l(l) -
12874  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
12875 
12876  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
12877  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
12878  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
12879  }
12880  for (int k = 0; k <= pm1; k++)
12881  for (int j = 0; j + k <= pm1; j++)
12882  {
12883  int i = pm1 - j - k;
12884  // s = shape_x(i)*shape_y(j)*shape_z(k);
12885  // curl of s*(ip.y - c, -(ip.x - c), 0):
12886  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
12887  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
12888  u(n,2) =
12889  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
12890  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
12891  n++;
12892  // curl of s*(ip.z - c, 0, -(ip.x - c)):
12893  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
12894  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
12895  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
12896  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
12897  n++;
12898  }
12899  for (int k = 0; k <= pm1; k++)
12900  {
12901  int j = pm1 - k;
12902  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
12903  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
12904  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
12905  u(n,1) = 0.;
12906  u(n,2) = 0.; n++;
12907  }
12908 
12909  Ti.Mult(u, curl_shape);
12910 }
12911 
12912 
12913 const double ND_TriangleElement::tk[8] =
12914 { 1.,0., -1.,1., 0.,-1., 0.,1. };
12915 
12916 const double ND_TriangleElement::c = 1./3.;
12917 
12919  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
12920  H_CURL, FunctionSpace::Pk),
12921  dof2tk(dof)
12922 {
12923  const double *eop = poly1d.OpenPoints(p - 1);
12924  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
12925 
12926  const int pm1 = p - 1, pm2 = p - 2;
12927 
12928 #ifndef MFEM_THREAD_SAFE
12929  shape_x.SetSize(p);
12930  shape_y.SetSize(p);
12931  shape_l.SetSize(p);
12932  dshape_x.SetSize(p);
12933  dshape_y.SetSize(p);
12934  dshape_l.SetSize(p);
12935  u.SetSize(dof, dim);
12936  curlu.SetSize(dof);
12937 #else
12938  Vector shape_x(p), shape_y(p), shape_l(p);
12939 #endif
12940 
12941  int n = 0;
12942  // edges
12943  for (int i = 0; i < p; i++) // (0,1)
12944  {
12945  Nodes.IntPoint(n).Set2(eop[i], 0.);
12946  dof2tk[n++] = 0;
12947  }
12948  for (int i = 0; i < p; i++) // (1,2)
12949  {
12950  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
12951  dof2tk[n++] = 1;
12952  }
12953  for (int i = 0; i < p; i++) // (2,0)
12954  {
12955  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
12956  dof2tk[n++] = 2;
12957  }
12958 
12959  // interior
12960  for (int j = 0; j <= pm2; j++)
12961  for (int i = 0; i + j <= pm2; i++)
12962  {
12963  double w = iop[i] + iop[j] + iop[pm2-i-j];
12964  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
12965  dof2tk[n++] = 0;
12966  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
12967  dof2tk[n++] = 3;
12968  }
12969 
12970  DenseMatrix T(dof);
12971  for (int m = 0; m < dof; m++)
12972  {
12973  const IntegrationPoint &ip = Nodes.IntPoint(m);
12974  const double *tm = tk + 2*dof2tk[m];
12975  n = 0;
12976 
12977  poly1d.CalcBasis(pm1, ip.x, shape_x);
12978  poly1d.CalcBasis(pm1, ip.y, shape_y);
12979  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
12980 
12981  for (int j = 0; j <= pm1; j++)
12982  for (int i = 0; i + j <= pm1; i++)
12983  {
12984  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
12985  T(n++, m) = s * tm[0];
12986  T(n++, m) = s * tm[1];
12987  }
12988  for (int j = 0; j <= pm1; j++)
12989  {
12990  T(n++, m) =
12991  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
12992  }
12993  }
12994 
12995  Ti.Factor(T);
12996  // mfem::out << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
12997 }
12998 
13000  DenseMatrix &shape) const
13001 {
13002  const int pm1 = order - 1;
13003 
13004 #ifdef MFEM_THREAD_SAFE
13005  const int p = order;
13006  Vector shape_x(p), shape_y(p), shape_l(p);
13007  DenseMatrix u(dof, dim);
13008 #endif
13009 
13010  poly1d.CalcBasis(pm1, ip.x, shape_x);
13011  poly1d.CalcBasis(pm1, ip.y, shape_y);
13012  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
13013 
13014  int n = 0;
13015  for (int j = 0; j <= pm1; j++)
13016  for (int i = 0; i + j <= pm1; i++)
13017  {
13018  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
13019  u(n,0) = s; u(n,1) = 0; n++;
13020  u(n,0) = 0; u(n,1) = s; n++;
13021  }
13022  for (int j = 0; j <= pm1; j++)
13023  {
13024  double s = shape_x(pm1-j)*shape_y(j);
13025  u(n,0) = s*(ip.y - c);
13026  u(n,1) = -s*(ip.x - c);
13027  n++;
13028  }
13029 
13030  Ti.Mult(u, shape);
13031 }
13032 
13034  DenseMatrix &curl_shape) const
13035 {
13036  const int pm1 = order - 1;
13037 
13038 #ifdef MFEM_THREAD_SAFE
13039  const int p = order;
13040  Vector shape_x(p), shape_y(p), shape_l(p);
13041  Vector dshape_x(p), dshape_y(p), dshape_l(p);
13042  Vector curlu(dof);
13043 #endif
13044 
13045  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
13046  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
13047  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
13048 
13049  int n = 0;
13050  for (int j = 0; j <= pm1; j++)
13051  for (int i = 0; i + j <= pm1; i++)
13052  {
13053  int l = pm1-i-j;
13054  const double dx = (dshape_x(i)*shape_l(l) -
13055  shape_x(i)*dshape_l(l)) * shape_y(j);
13056  const double dy = (dshape_y(j)*shape_l(l) -
13057  shape_y(j)*dshape_l(l)) * shape_x(i);
13058 
13059  curlu(n++) = -dy;
13060  curlu(n++) = dx;
13061  }
13062 
13063  for (int j = 0; j <= pm1; j++)
13064  {
13065  int i = pm1 - j;
13066  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
13067  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
13068  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
13069  }
13070 
13071  Vector curl2d(curl_shape.Data(),dof);
13072  Ti.Mult(curlu, curl2d);
13073 }
13074 
13075 
13076 const double ND_SegmentElement::tk[1] = { 1. };
13077 
13078 ND_SegmentElement::ND_SegmentElement(const int p, const int ob_type)
13079  : VectorTensorFiniteElement(1, p, p - 1, ob_type, H_CURL,
13080  DofMapType::L2_DOF_MAP),
13081  dof2tk(dof)
13082 {
13083  if (obasis1d.IsIntegratedType()) { is_nodal = false; }
13084 
13085  const double *op = poly1d.OpenPoints(p - 1, ob_type);
13086 
13087  // set dof2tk and Nodes
13088  for (int i = 0; i < p; i++)
13089  {
13090  dof2tk[i] = 0;
13091  Nodes.IntPoint(i).x = op[i];
13092  }
13093 }
13094 
13096  DenseMatrix &shape) const
13097 {
13098  Vector vshape(shape.Data(), dof);
13099 
13100  obasis1d.Eval(ip.x, vshape);
13101 }
13102 
13104 {
13105  order = kv[0]->GetOrder();
13106  dof = order + 1;
13107 
13108  weights.SetSize(dof);
13109  shape_x.SetSize(dof);
13110 }
13111 
13113  Vector &shape) const
13114 {
13115  kv[0]->CalcShape(shape, ijk[0], ip.x);
13116 
13117  double sum = 0.0;
13118  for (int i = 0; i <= order; i++)
13119  {
13120  sum += (shape(i) *= weights(i));
13121  }
13122 
13123  shape /= sum;
13124 }
13125 
13127  DenseMatrix &dshape) const
13128 {
13129  Vector grad(dshape.Data(), dof);
13130 
13131  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
13132  kv[0]->CalcDShape(grad, ijk[0], ip.x);
13133 
13134  double sum = 0.0, dsum = 0.0;
13135  for (int i = 0; i <= order; i++)
13136  {
13137  sum += (shape_x(i) *= weights(i));
13138  dsum += ( grad(i) *= weights(i));
13139  }
13140 
13141  sum = 1.0/sum;
13142  add(sum, grad, -dsum*sum*sum, shape_x, grad);
13143 }
13144 
13146  DenseMatrix &hessian) const
13147 {
13148  Vector grad(dof);
13149  Vector hess(hessian.Data(), dof);
13150 
13151  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
13152  kv[0]->CalcDShape(grad, ijk[0], ip.x);
13153  kv[0]->CalcD2Shape(hess, ijk[0], ip.x);
13154 
13155  double sum = 0.0, dsum = 0.0, d2sum = 0.0;
13156  for (int i = 0; i <= order; i++)
13157  {
13158  sum += (shape_x(i) *= weights(i));
13159  dsum += ( grad(i) *= weights(i));
13160  d2sum += ( hess(i) *= weights(i));
13161  }
13162 
13163  sum = 1.0/sum;
13164  add(sum, hess, -2*dsum*sum*sum, grad, hess);
13165  add(1.0, hess, (-d2sum + 2*dsum*dsum*sum)*sum*sum, shape_x, hess);
13166 }
13167 
13168 
13170 {
13171  orders[0] = kv[0]->GetOrder();
13172  orders[1] = kv[1]->GetOrder();
13173  shape_x.SetSize(orders[0]+1);
13174  shape_y.SetSize(orders[1]+1);
13175  dshape_x.SetSize(orders[0]+1);
13176  dshape_y.SetSize(orders[1]+1);
13177  d2shape_x.SetSize(orders[0]+1);
13178  d2shape_y.SetSize(orders[1]+1);
13179 
13180  order = max(orders[0], orders[1]);
13181  dof = (orders[0] + 1)*(orders[1] + 1);
13182  u.SetSize(dof);
13183  du.SetSize(dof);
13184  weights.SetSize(dof);
13185 }
13186 
13188  Vector &shape) const
13189 {
13190  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
13191  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
13192 
13193  double sum = 0.0;
13194  for (int o = 0, j = 0; j <= orders[1]; j++)
13195  {
13196  const double sy = shape_y(j);
13197  for (int i = 0; i <= orders[0]; i++, o++)
13198  {
13199  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
13200  }
13201  }
13202 
13203  shape /= sum;
13204 }
13205 
13207  DenseMatrix &dshape) const
13208 {
13209  double sum, dsum[2];
13210 
13211  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
13212  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
13213 
13214  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
13215  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
13216 
13217  sum = dsum[0] = dsum[1] = 0.0;
13218  for (int o = 0, j = 0; j <= orders[1]; j++)
13219  {
13220  const double sy = shape_y(j), dsy = dshape_y(j);
13221  for (int i = 0; i <= orders[0]; i++, o++)
13222  {
13223  sum += ( u(o) = shape_x(i)*sy*weights(o) );
13224 
13225  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
13226  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
13227  }
13228  }
13229 
13230  sum = 1.0/sum;
13231  dsum[0] *= sum*sum;
13232  dsum[1] *= sum*sum;
13233 
13234  for (int o = 0; o < dof; o++)
13235  {
13236  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
13237  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
13238  }
13239 }
13240 
13242  DenseMatrix &hessian) const
13243 {
13244  double sum, dsum[2], d2sum[3];
13245 
13246  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
13247  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
13248 
13249  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
13250  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
13251 
13252  kv[0]->CalcD2Shape(d2shape_x, ijk[0], ip.x);
13253  kv[1]->CalcD2Shape(d2shape_y, ijk[1], ip.y);
13254 
13255  sum = dsum[0] = dsum[1] = 0.0;
13256  d2sum[0] = d2sum[1] = d2sum[2] = 0.0;
13257  for (int o = 0, j = 0; j <= orders[1]; j++)
13258  {
13259  const double sy = shape_y(j), dsy = dshape_y(j), d2sy = d2shape_y(j);
13260  for (int i = 0; i <= orders[0]; i++, o++)
13261  {
13262  const double sx = shape_x(i), dsx = dshape_x(i), d2sx = d2shape_x(i);
13263  sum += ( u(o) = sx*sy*weights(o) );
13264 
13265  dsum[0] += ( du(o,0) = dsx*sy*weights(o) );
13266  dsum[1] += ( du(o,1) = sx*dsy*weights(o) );
13267 
13268  d2sum[0] += ( hessian(o,0) = d2sx*sy*weights(o) );
13269  d2sum[1] += ( hessian(o,1) = dsx*dsy*weights(o) );
13270  d2sum[2] += ( hessian(o,2) = sx*d2sy*weights(o) );
13271  }
13272  }
13273 
13274  sum = 1.0/sum;
13275  dsum[0] *= sum;
13276  dsum[1] *= sum;
13277 
13278  d2sum[0] *= sum;
13279  d2sum[1] *= sum;
13280  d2sum[2] *= sum;
13281 
13282  for (int o = 0; o < dof; o++)
13283  {
13284  hessian(o,0) = hessian(o,0)*sum
13285  - 2*du(o,0)*sum*dsum[0]
13286  + u[o]*sum*(2*dsum[0]*dsum[0] - d2sum[0]);
13287 
13288  hessian(o,1) = hessian(o,1)*sum
13289  - du(o,0)*sum*dsum[1]
13290  - du(o,1)*sum*dsum[0]
13291  + u[o]*sum*(2*dsum[0]*dsum[1] - d2sum[1]);
13292 
13293  hessian(o,2) = hessian(o,2)*sum
13294  - 2*du(o,1)*sum*dsum[1]
13295  + u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[2]);
13296  }
13297 }
13298 
13299 
13301 {
13302  orders[0] = kv[0]->GetOrder();
13303  orders[1] = kv[1]->GetOrder();
13304  orders[2] = kv[2]->GetOrder();
13305  shape_x.SetSize(orders[0]+1);
13306  shape_y.SetSize(orders[1]+1);
13307  shape_z.SetSize(orders[2]+1);
13308 
13309  dshape_x.SetSize(orders[0]+1);
13310  dshape_y.SetSize(orders[1]+1);
13311  dshape_z.SetSize(orders[2]+1);
13312 
13313  d2shape_x.SetSize(orders[0]+1);
13314  d2shape_y.SetSize(orders[1]+1);
13315  d2shape_z.SetSize(orders[2]+1);
13316 
13317  order = max(max(orders[0], orders[1]), orders[2]);
13318  dof = (orders[0] + 1)*(orders[1] + 1)*(orders[2] + 1);
13319  u.SetSize(dof);
13320  du.SetSize(dof);
13321  weights.SetSize(dof);
13322 }
13323 
13325  Vector &shape) const
13326 {
13327  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
13328  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
13329  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
13330 
13331  double sum = 0.0;
13332  for (int o = 0, k = 0; k <= orders[2]; k++)
13333  {
13334  const double sz = shape_z(k);
13335  for (int j = 0; j <= orders[1]; j++)
13336  {
13337  const double sy_sz = shape_y(j)*sz;
13338  for (int i = 0; i <= orders[0]; i++, o++)
13339  {
13340  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
13341  }
13342  }
13343  }
13344 
13345  shape /= sum;
13346 }
13347 
13349  DenseMatrix &dshape) const
13350 {
13351  double sum, dsum[3];
13352 
13353  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
13354  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
13355  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
13356 
13357  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
13358  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
13359  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
13360 
13361  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
13362  for (int o = 0, k = 0; k <= orders[2]; k++)
13363  {
13364  const double sz = shape_z(k), dsz = dshape_z(k);
13365  for (int j = 0; j <= orders[1]; j++)
13366  {
13367  const double sy_sz = shape_y(j)* sz;
13368  const double dsy_sz = dshape_y(j)* sz;
13369  const double sy_dsz = shape_y(j)*dsz;
13370  for (int i = 0; i <= orders[0]; i++, o++)
13371  {
13372  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
13373 
13374  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
13375  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
13376  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
13377  }
13378  }
13379  }
13380 
13381  sum = 1.0/sum;
13382  dsum[0] *= sum*sum;
13383  dsum[1] *= sum*sum;
13384  dsum[2] *= sum*sum;
13385 
13386  for (int o = 0; o < dof; o++)
13387  {
13388  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
13389  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
13390  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
13391  }
13392 }
13393 
13395  DenseMatrix &hessian) const
13396 {
13397  double sum, dsum[3], d2sum[6];
13398 
13399  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
13400  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
13401  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
13402 
13403  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
13404  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
13405  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
13406 
13407  kv[0]->CalcD2Shape(d2shape_x, ijk[0], ip.x);
13408  kv[1]->CalcD2Shape(d2shape_y, ijk[1], ip.y);
13409  kv[2]->CalcD2Shape(d2shape_z, ijk[2], ip.z);
13410 
13411  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
13412  d2sum[0] = d2sum[1] = d2sum[2] = d2sum[3] = d2sum[4] = d2sum[5] = 0.0;
13413 
13414  for (int o = 0, k = 0; k <= orders[2]; k++)
13415  {
13416  const double sz = shape_z(k), dsz = dshape_z(k), d2sz = d2shape_z(k);
13417  for (int j = 0; j <= orders[1]; j++)
13418  {
13419  const double sy = shape_y(j), dsy = dshape_y(j), d2sy = d2shape_y(j);
13420  for (int i = 0; i <= orders[0]; i++, o++)
13421  {
13422  const double sx = shape_x(i), dsx = dshape_x(i), d2sx = d2shape_x(i);
13423  sum += ( u(o) = sx*sy*sz*weights(o) );
13424 
13425  dsum[0] += ( du(o,0) = dsx*sy*sz*weights(o) );
13426  dsum[1] += ( du(o,1) = sx*dsy*sz*weights(o) );
13427  dsum[2] += ( du(o,2) = sx*sy*dsz*weights(o) );
13428 
13429  d2sum[0] += ( hessian(o,0) = d2sx*sy*sz*weights(o) );
13430  d2sum[1] += ( hessian(o,1) = dsx*dsy*sz*weights(o) );
13431  d2sum[2] += ( hessian(o,2) = dsx*sy*dsz*weights(o) );
13432 
13433  d2sum[3] += ( hessian(o,3) = sx*dsy*dsz*weights(o) );
13434 
13435  d2sum[4] += ( hessian(o,4) = sx*sy*d2sz*weights(o) );
13436  d2sum[5] += ( hessian(o,5) = sx*d2sy*sz*weights(o) );
13437  }
13438  }
13439  }
13440 
13441  sum = 1.0/sum;
13442  dsum[0] *= sum;
13443  dsum[1] *= sum;
13444  dsum[2] *= sum;
13445 
13446  d2sum[0] *= sum;
13447  d2sum[1] *= sum;
13448  d2sum[2] *= sum;
13449 
13450  d2sum[3] *= sum;
13451  d2sum[4] *= sum;
13452  d2sum[5] *= sum;
13453 
13454  for (int o = 0; o < dof; o++)
13455  {
13456  hessian(o,0) = hessian(o,0)*sum
13457  - 2*du(o,0)*sum*dsum[0]
13458  + u[o]*sum*(2*dsum[0]*dsum[0] - d2sum[0]);
13459 
13460  hessian(o,1) = hessian(o,1)*sum
13461  - du(o,0)*sum*dsum[1]
13462  - du(o,1)*sum*dsum[0]
13463  + u[o]*sum*(2*dsum[0]*dsum[1] - d2sum[1]);
13464 
13465  hessian(o,2) = hessian(o,2)*sum
13466  - du(o,0)*sum*dsum[2]
13467  - du(o,2)*sum*dsum[0]
13468  + u[o]*sum*(2*dsum[0]*dsum[2] - d2sum[2]);
13469 
13470  hessian(o,3) = hessian(o,3)*sum
13471  - du(o,1)*sum*dsum[2]
13472  - du(o,2)*sum*dsum[1]
13473  + u[o]*sum*(2*dsum[1]*dsum[2] - d2sum[3]);
13474 
13475  hessian(o,4) = hessian(o,4)*sum
13476  - 2*du(o,2)*sum*dsum[2]
13477  + u[o]*sum*(2*dsum[2]*dsum[2] - d2sum[4]);
13478 
13479  hessian(o,5) = hessian(o,5)*sum
13480  - 2*du(o,1)*sum*dsum[1]
13481  + u[o]*sum*(2*dsum[1]*dsum[1] - d2sum[5]);
13482 
13483  }
13484 }
13485 
13486 // Global object definitions
13487 
13488 // Object declared in mesh/triangle.hpp.
13489 // Defined here to ensure it is constructed before 'Geometries'.
13491 
13492 // Object declared in mesh/tetrahedron.hpp.
13493 // Defined here to ensure it is constructed before 'Geometries'.
13495 
13496 // Object declared in mesh/wedge.hpp.
13497 // Defined here to ensure it is constructed after 'poly1d' and before
13498 // 'Geometries'.
13499 // TODO: define as thread_local to prevent race conditions in GLVis, because
13500 // there is no "LinearWedgeFiniteElement" and WedgeFE is in turn used from two
13501 // different threads for different things in GLVis. We also don't want to turn
13502 // MFEM_THREAD_SAFE on globally. (See PR #731)
13504 
13505 // Object declared in geom.hpp.
13506 // Construct 'Geometries' after 'TriangleFE', 'TetrahedronFE', and 'WedgeFE'.
13508 
13509 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:247
Abstract class for all finite elements.
Definition: fe.hpp:243
RefinedLinear3DFiniteElement()
Construct the RefinedLinear3DFiniteElement.
Definition: fe.cpp:5184
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:13145
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2069
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:9865
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
Definition: densemat.cpp:2391
RT0TriangleFiniteElement()
Construct the RT0TriangleFiniteElement.
Definition: fe.cpp:3529
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:13078
int Size() const
Return the logical size of the array.
Definition: array.hpp:134
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:845
void Get(double *p, const int dim) const
Definition: intrules.hpp:51
void ProjectIntegrated(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:12459
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:6983
RT2TriangleFiniteElement()
Construct the RT2TriangleFiniteElement.
Definition: fe.cpp:4134
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:317
GaussQuad2DFiniteElement()
Construct the GaussQuad2DFiniteElement.
Definition: fe.cpp:1987
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:8463
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:3821
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:4762
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:1817
Array< int > lex_ordering
Definition: fe.hpp:709
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:2370
L2Pos_WedgeElement(const int p)
Construct the L2Pos_WedgeElement of order p.
Definition: fe.cpp:10736
CrouzeixRaviartQuadFiniteElement()
Construct the CrouzeixRaviartQuadFiniteElement.
Definition: fe.cpp:3491
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:10255
P2SegmentFiniteElement()
Construct the P2SegmentFiniteElement.
Definition: fe.cpp:4553
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:13206
Linear3DFiniteElement()
Construct the Linear3DFiniteElement.
Definition: fe.cpp:3219
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:47
virtual void CalcPhysLinLaplacian(ElementTransformation &Trans, Vector &Laplacian) const
Definition: fe.cpp:245
static double CalcDelta(const int p, const double x)
Evaluate a representation of a Delta function at point x.
Definition: fe.hpp:2082
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:4003
RT1TriangleFiniteElement()
Construct the RT1TriangleFiniteElement.
Definition: fe.cpp:3754
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:10016
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:1005
int NumCols() const
Definition: array.hpp:369
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:1222
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:11742
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:5416
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:12278
NodalTensorFiniteElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:7922
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:2614
void LocalInterpolation_RT(const VectorFiniteElement &cfe, const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1389
L2Pos_TriangleElement(const int p)
Construct the L2Pos_TriangleElement of order p.
Definition: fe.cpp:10399
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:920
H1Pos_SegmentElement(const int p)
Construct the H1Pos_SegmentElement of order p.
Definition: fe.cpp:8405
Basis(const int p, const double *nodes, EvalType etype=Barycentric)
Create a nodal or positive (Bernstein) basis.
Definition: fe.cpp:7088
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Definition: fe.hpp:165
bool IsIntegratedType() const
Definition: fe.hpp:1994
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:175
Base class for vector Coefficients that optionally depend on time and space.
void SetRow(int r, const double *row)
Definition: densemat.cpp:1788
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:290
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:6028
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:126
Array< const KnotVector * > kv
Definition: fe.hpp:3369
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:3458
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:58
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:3236
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:10438
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:3775
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:4055
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:2410
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:8443
PositiveTensorFiniteElement(const int dims, const int p, const DofMapType dmtype)
Definition: fe.cpp:7934
static void GivePolyPoints(const int np, double *pts, const int type)
Definition: intrules.cpp:646
Class for finite elements utilizing the always positive Bernstein basis.
Definition: fe.hpp:785
L2Pos_TetrahedronElement(const int p)
Construct the L2Pos_TetrahedronElement of order p.
Definition: fe.cpp:10594
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:9718
PointFiniteElement()
Construct the PointFiniteElement.
Definition: fe.cpp:1600
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:697
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:8291
Integrated GLL indicator functions.
Definition: fe.hpp:41
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:945
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:513
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:11000
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:6090
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:203
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:4545
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:1738
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:658
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:2434
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Compute the Hessian of second order partial derivatives at ip.
Definition: fe.cpp:2792
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:2703
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:3540
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:3190
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:72
H1Pos_SegmentElement SegmentFE
Definition: fe.hpp:2556
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1627
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:8050
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:9168
int dim
Dimension of reference space.
Definition: fe.hpp:246
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:13112
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:9884
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:4814
TensorBasisElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:7721
L2_SegmentElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_SegmentElement of order p and BasisType btype.
Definition: fe.cpp:9744
BiQuadPos2DFiniteElement()
Construct the BiQuadPos2DFiniteElement.
Definition: fe.cpp:2387
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition: fe.hpp:327
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:3553
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:2195
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:4668
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:4976
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Definition: fe.hpp:177
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:4620
GaussBiQuad2DFiniteElement()
Construct the GaussBiQuad2DFiniteElement.
Definition: fe.cpp:2562
int Size() const
Returns the size of the vector.
Definition: vector.hpp:190
Array< double > Gt
Transpose of G.
Definition: fe.hpp:216
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:777
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:13126
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
Definition: fe.hpp:173
static int GetQuadrature1D(int b_type)
Get the corresponding Quadrature1D constant, when that makes sense; otherwise return Quadrature1D::In...
Definition: fe.hpp:63
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:11598
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:10798
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:6256
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:1135
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:3205
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:13103
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:2863
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:107
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:5563
DenseMatrix vshape
Definition: fe.hpp:256
P0QuadFiniteElement()
Construct the P0QuadFiniteElement.
Definition: fe.cpp:3198
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:4801
Quadratic3DFiniteElement()
Construct the Quadratic3DFiniteElement.
Definition: fe.cpp:3275
int GetMapType() const
Returns the FiniteElement::MapType of the element describing how reference functions are mapped to ph...
Definition: fe.hpp:349
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:9760
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:6606
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:6793
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:3235
Geometry::Type geom_type
Geometry::Type of the reference element.
Definition: fe.hpp:247
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:3652
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:10558
Intermediate class for finite elements whose basis functions return vector values.
Definition: fe.hpp:829
static void CalcLegendre(const int p, const double x, double *u)
Definition: fe.cpp:7544
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:383
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:2915
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:10624
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:3483
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:3475
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:6484
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:9822
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:8104
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:1173
H1Pos_HexahedronElement(const int p)
Construct the H1Pos_HexahedronElement of order p.
Definition: fe.cpp:8538
RT0QuadFiniteElement()
Construct the RT0QuadFiniteElement.
Definition: fe.cpp:3639
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:161
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:199
RT1QuadFiniteElement()
Construct the RT1QuadFiniteElement.
Definition: fe.cpp:3896
static void CalcShape(const int p, const double x, const double y, const double z, double *shape)
Definition: fe.cpp:9270
const DofToQuad & GetTensorDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode, const bool closed) const
Definition: fe.cpp:12296
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:10500
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:1699
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:8510
Linear2DFiniteElement()
Construct the Linear2DFiniteElement.
Definition: fe.cpp:1641
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:2042
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:3332
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:6928
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:291
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5752
Cubic2DFiniteElement()
Construct the Cubic2DFiniteElement.
Definition: fe.cpp:2890
void ProjectIntegrated(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:11431
H1_HexahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_HexahedronElement of order p and BasisType btype.
Definition: fe.cpp:8218
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:12999
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:1608
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:2935
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:71
L2Pos_HexahedronElement(const int p)
Construct the L2Pos_HexahedronElement of order p.
Definition: fe.cpp:10183
ND_TriangleElement(const int p)
Construct the ND_TriangleElement of order p.
Definition: fe.cpp:12918
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:11778
static void CalcDShape(const int p, const double x, const double y, const double z, double *dshape_1d, double *dshape)
Definition: fe.cpp:9303
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:2058
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:138
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:3184
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:2963
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:7450
const double * GetPoints(const int p, const int btype)
Get the coordinates of the points of the given BasisType, btype.
Definition: fe.cpp:7643
H1Pos_TriangleElement(const int p)
Construct the H1Pos_TriangleElement of order p.
Definition: fe.cpp:9023
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:4257
Poly_1D::Basis & obasis1d
Definition: fe.hpp:2235
Cubic3DFiniteElement()
Construct the Cubic3DFiniteElement.
Definition: fe.cpp:3010
Linear1DFiniteElement()
Construct the Linear1DFiniteElement.
Definition: fe.cpp:1620
A 1D element with uniform nodes.
Definition: fe.hpp:1641
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5125
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:6916
RT0HexFiniteElement()
Construct the RT0HexFiniteElement.
Definition: fe.cpp:6330
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:2483
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:168
Class for standard nodal finite elements.
Definition: fe.hpp:706
void ScalarLocalRestriction(ElementTransformation &Trans, DenseMatrix &R, const ScalarFiniteElement &coarse_fe) const
Get restriction matrix R defined through local L2-projection in the space defined by the coarse_fe...
Definition: fe.cpp:460
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:320
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:1874
CrouzeixRaviartFiniteElement()
Construct the CrouzeixRaviartFiniteElement.
Definition: fe.cpp:3464
static void CalcShape(const int p, const double x, const double y, double *shape)
Definition: fe.cpp:9078
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:3506
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:7941
Array< int > s_dof
Definition: fe.hpp:2800
Class for finite elements with basis functions that return scalar values.
Definition: fe.hpp:629
void SetSize(int m, int n)
Definition: array.hpp:366
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:3103
Geometry Geometries
Definition: fe.cpp:13507
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:250
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:4563
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
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:2161
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:9766
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1834
Poly_1D::Basis & cbasis1d
Definition: fe.hpp:2235
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1845
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2093
Bernstein polynomials.
Definition: fe.hpp:35
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:66
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:9575
RefinedLinear1DFiniteElement()
Construct the RefinedLinear1DFiniteElement.
Definition: fe.cpp:5014
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:8320
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:8531
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:11824
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:2587
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:10341
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:8694
Poly_1D::Basis & basis1d
Definition: fe.hpp:2132
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5041
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:4196
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:7418
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
Definition: densemat.cpp:2821
double b
Definition: lissajous.cpp:42
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint, using the method SetIntPoint().
Definition: eltrans.hpp:111
Cubic1DFiniteElement()
Construct the Cubic1DFiniteElement.
Definition: fe.cpp:2854
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:7053
H1Pos_WedgeElement(const int p)
Construct the H1Pos_WedgeElement of order p.
Definition: fe.cpp:9601
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:4786
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:6894
ND_TetrahedronElement(const int p)
Construct the ND_TetrahedronElement of order p.
Definition: fe.cpp:12656
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:10427
Array< int > t_dof
Definition: fe.hpp:2800
int deriv_range_type
Definition: fe.hpp:248
Nedelec1TetFiniteElement()
Construct the Nedelec1TetFiniteElement.
Definition: fe.cpp:6165
RT2QuadFiniteElement()
Construct the RT2QuadFiniteElement.
Definition: fe.cpp:4220
Mode mode
Describes the contents of the B, Bt, G, and Gt arrays, see Mode.
Definition: fe.hpp:169
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:8078
GaussLinear2DFiniteElement()
Construct the GaussLinear2DFiniteElement.
Definition: fe.cpp:1709
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:1614
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:2878
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:633
class FiniteElement * FE
The FiniteElement that created and owns this object.
Definition: fe.hpp:144
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:2277
const IntegrationRule & GetNodes() const
Get a const reference to the nodes of the element.
Definition: fe.hpp:390
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:6143
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1915
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:10098
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:612
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:3310
L2Pos_QuadrilateralElement(const int p)
Construct the L2Pos_QuadrilateralElement of order p.
Definition: fe.cpp:9953
const int * ijk
Definition: fe.hpp:3370
P1TetNonConfFiniteElement()
Construct the P1TetNonConfFiniteElement.
Definition: fe.cpp:4729
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:3446
static void CalcDShape(const int p, const double x, const double y, double *dshape_1d, double *dshape)
Definition: fe.cpp:9104
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:10691
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:3798
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:13324
DenseMatrix curlshape
Definition: fe.hpp:845
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
Definition: densemat.cpp:2843
void EvalIntegrated(const Vector &d, Vector &i) const
Definition: fe.cpp:7384
A 3D linear element on a tetrahedron with nodes at the vertices of the tetrahedron.
Definition: fe.hpp:1350
H1_SegmentElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_SegmentElement of order p and BasisType btype.
Definition: fe.cpp:7974
Nedelec1HexFiniteElement()
Construct the Nedelec1HexFiniteElement.
Definition: fe.cpp:5920
int orders[Geometry::MaxDim]
Anisotropic orders.
Definition: fe.hpp:253
void Set2(const double x1, const double x2)
Definition: intrules.hpp:80
virtual ~FiniteElement()
Deconstruct the FiniteElement.
Definition: fe.cpp:374
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:11267
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:6194
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:192
A 2D linear element on triangle with nodes at the vertices of the triangle.
Definition: fe.hpp:1043
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:10319
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:10943
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:2742
L2_QuadrilateralElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_QuadrilateralElement of order p and BasisType btype.
Definition: fe.cpp:9846
void SetData(double *d)
Definition: vector.hpp:140
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:4455
Basis & GetBasis(const int p, const int btype)
Get a Poly_1D::Basis object of the given degree and BasisType, btype.
Definition: fe.cpp:7667
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1690
void GetColumn(int c, Vector &col) const
Definition: densemat.cpp:1285
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:3245
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:11353
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:2037
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:8919
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:1939
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:9556
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:10648
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:419
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:2017
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:1321
L2_TetrahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_TetrahedronElement of order p and BasisType btype.
Definition: fe.cpp:10450
int deriv_map_type
Definition: fe.hpp:248
RT0TetFiniteElement()
Construct the RT0TetFiniteElement.
Definition: fe.cpp:6873
static const int MaxDim
Definition: geom.hpp:42
Array< int > t_dof
Definition: fe.hpp:2553
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:10421
void Threshold(double eps)
Replace small entries, abs(a_ij) &lt;= eps, with zero.
Definition: densemat.cpp:1818
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:2197
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:13348
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:2031
DenseMatrix m_dshape
Definition: fe.hpp:2448
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:12594
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:9977
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:70
IntegrationRule Nodes
Definition: fe.hpp:254
Array< int > dof_map
Definition: fe.hpp:2131
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1901
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:10210
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:8423
Array< double > Bt
Transpose of B.
Definition: fe.hpp:194
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:8605
void ProjectIntegrated(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:11054
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:4507
P0HexFiniteElement()
Construct the P0HexFiniteElement.
Definition: fe.cpp:4793
double * Data() const
Returns the matrix data array.
Definition: densemat.hpp:111
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:13033
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:3667
P1SegmentFiniteElement()
Construct the P1SegmentFiniteElement.
Definition: fe.cpp:4529
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5439
void LocalInterpolation_ND(const VectorFiniteElement &cfe, const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1476
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:8977
H1Pos_TriangleElement TriangleFE
Definition: fe.hpp:2555
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:12368
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:3564
BiCubic2DFiniteElement()
Construct the BiCubic2DFiniteElement.
Definition: fe.cpp:2666
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:957
DenseMatrix Jinv
Definition: fe.hpp:844
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:9777
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:323
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:8944
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:4772
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:1785
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:6224
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:101
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:10617
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:182
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition: array.hpp:674
DenseMatrix t_dshape
Definition: fe.hpp:2551
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1652
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5609
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:5306
DenseMatrix t_dshape
Definition: fe.hpp:2798
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
Definition: densemat.cpp:2329
static const int * Binom(const int p)
Get a pointer to an array containing the binomial coefficients &quot;p choose k&quot; for k=0,...,p for the given p.
Definition: fe.cpp:7401
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:4357
DenseMatrix s_dshape
Definition: fe.hpp:2551
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:52
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:1720
H1_TetrahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_TetrahedronElement of order p and BasisType btype.
Definition: fe.cpp:8778
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:13300
DenseMatrix s_dshape
Definition: fe.hpp:2798
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:8145
void Mult(const double *x, double *y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:3275
Structure representing the matrices/tensors needed to evaluate (in reference space) the values...
Definition: fe.hpp:139
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:10779
class Linear3DFiniteElement TetrahedronFE
Definition: fe.cpp:13494
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:10525
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:12108
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:3731
L2Pos_TriangleElement TriangleFE
Definition: fe.hpp:2802
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:147
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:2142
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3390
Linear2DFiniteElement TriangleFE
Definition: fe.cpp:13490
A 2D bi-linear element on a square with nodes at the vertices of the square.
Definition: fe.hpp:1065
Array< double > B
Basis functions evaluated at quadrature points.
Definition: fe.hpp:188
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:2154
Quad1DFiniteElement()
Construct the Quad1DFiniteElement.
Definition: fe.cpp:1826
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:8560
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:96
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:367
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:1774
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1681
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:65
H1Pos_QuadrilateralElement(const int p)
Construct the H1Pos_QuadrilateralElement of order p.
Definition: fe.cpp:8470
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:10710
void LocalRestriction_ND(const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &R) const
Definition: fe.cpp:1558
H1_TriangleElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_TriangleElement of order p and BasisType btype.
Definition: fe.cpp:8612
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1634
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:10370
Mode
Type of data stored in the arrays B, Bt, G, and Gt.
Definition: fe.hpp:152
Full multidimensional representation which does not use tensor product structure. The ordering of the...
Definition: fe.hpp:157
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:144
L2Pos_SegmentElement SegmentFE
Definition: fe.hpp:2803
const Poly_1D::Basis & GetBasis1D() const
Definition: fe.hpp:2148
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:8581
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:9828
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:3211
const DofToQuad & GetDofToQuadOpen(const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:12287
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:10231
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Project a vector coefficient onto the RT basis functions.
Definition: fe.cpp:968
int dof
Number of degrees of freedom.
Definition: fe.hpp:251
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:8246
Array< DofToQuad * > dof2quad_array
Container for all DofToQuad objects created by the FiniteElement.
Definition: fe.hpp:261
H1_WedgeElement(const int p, const int btype=BasisType::GaussLobatto)
Construct the H1_WedgeElement of order p and BasisType btype.
Definition: fe.cpp:9420
Array< int > s_dof
Definition: fe.hpp:2553
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:1809
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:4171
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:12804
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:3931
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:12535
static int VerifyClosed(int b_type)
Ensure that the BasisType of b_type is closed (has Quadrature1D points on the boundary).
Definition: fe.hpp:603
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:806
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:3679
Implements CalcDivShape methods.
Definition: fe.hpp:302
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
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:113
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:9839
RefinedLinear2DFiniteElement()
Construct the RefinedLinear2DFiniteElement.
Definition: fe.cpp:5060
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:6848
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:589
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5022
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:4750
Array< double > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
Definition: fe.hpp:209
Array< int > dof_map
Definition: fe.hpp:2450
RT_TetrahedronElement(const int p)
Construct the RT_TetrahedronElement of order p.
Definition: fe.cpp:11640
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:6404
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:8031
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:4955
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:8012
double infinity()
Define a shortcut for std::numeric_limits&lt;double&gt;::infinity()
Definition: vector.hpp:46
BiQuad2DFiniteElement()
Construct the BiQuad2DFiniteElement.
Definition: fe.cpp:2046
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:3265
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:3968
P0TriangleFiniteElement()
Construct the P0TriangleFiniteElement.
Definition: fe.cpp:3177
static int VerifyNodal(int b_type)
Ensure that the BasisType of b_type nodal (satisfies the interpolation property). ...
Definition: fe.hpp:620
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:3452
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:2161
RT_TriangleElement(const int p)
Construct the RT_TriangleElement of order p.
Definition: fe.cpp:11487
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:7993
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:13095
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:12194
void Eval(const double x, Vector &u) const
Definition: fe.cpp:7152
void LocalL2Projection_ND(const VectorFiniteElement &cfe, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1430
L2Pos_SegmentElement(const int p)
Construct the L2Pos_SegmentElement of order p.
Definition: fe.cpp:9801
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:13394
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:5219
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:6459
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
Definition: densemat.cpp:2648
void InvertLinearTrans(ElementTransformation &trans, const IntegrationPoint &pt, Vector &x)
Definition: fe.cpp:613
Vector data type.
Definition: vector.hpp:60
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:6390
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:2107
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:13169
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:8490
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:10074
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:1967
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:11565
Quad2DFiniteElement()
Construct the Quad2DFiniteElement.
Definition: fe.cpp:1884
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:1515
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:221
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3406
void pts(int iphi, int t, double x[])
RefCoord s[3]
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:119
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:6309
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:9996
GaussBiLinear2DFiniteElement()
Construct the FiniteElement.
Definition: fe.cpp:1750
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:11101
double u(const Vector &xvec)
Definition: lor_mms.hpp:24
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:12846
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:4807
Arbitrary order H1 elements in 3D on a wedge.
Definition: fe.hpp:2500
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:2512
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1660
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:3075
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:8745
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:3517
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:105
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:8169
QuadPos1DFiniteElement()
Construct the QuadPos1DFiniteElement.
Definition: fe.cpp:1856
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:6360
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:4575
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:10827
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:499
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5490
P1OnQuadFiniteElement()
Construct the P1OnQuadFiniteElement.
Definition: fe.cpp:1798
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:7008
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:13187
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Project a vector coefficient onto the ND basis functions.
Definition: fe.cpp:1192
int GetRangeType() const
Returns the FiniteElement::RangeType of the element, one of {SCALAR, VECTOR}.
Definition: fe.hpp:340
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:1763
double FNorm2() const
Compute the square of the Frobenius norm of the matrix.
Definition: densemat.hpp:242
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:377
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:3873
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:9699
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:4780
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:8267
L2_HexahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_HexahedronElement of order p and BasisType btype.
Definition: fe.cpp:10031
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:629
void ProjectIntegrated(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:12043
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:8123
void AddMult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt += a * A * A^t.
Definition: densemat.cpp:2705
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:7514
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:5973
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:13241
const IntegrationRule * IntRule
IntegrationRule that defines the quadrature points at which the basis functions of the FE are evaluat...
Definition: fe.hpp:149
TriLinear3DFiniteElement()
Construct the TriLinear3DFiniteElement.
Definition: fe.cpp:3354
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:150
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:1864
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:10053
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5077
const DofToQuad & GetTensorDofToQuad(const class TensorBasisElement &tb, const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:547
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:4536
L2_TriangleElement(const int p, const int btype=BasisType::GaussLegendre)
Construct the L2_TriangleElement of order p and BasisType btype.
Definition: fe.cpp:10274
int order
Order/degree of the shape functions.
Definition: fe.hpp:251
BiLinear2DFiniteElement()
Construct the BiLinear2DFiniteElement.
Definition: fe.cpp:1668
Poly_1D poly1d
Definition: fe.cpp:7718
void LocalL2Projection_RT(const VectorFiniteElement &cfe, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1342
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:7036
Lagrange1DFiniteElement(int degree)
Construct the Lagrange1DFiniteElement with the provided degree.
Definition: fe.cpp:4588
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:3616
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:6729
No derivatives implemented.
Definition: fe.hpp:300
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:10635
Implements CalcCurlShape methods.
Definition: fe.hpp:303
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:9904
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:1730
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:8716
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:1108
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:838