MFEM  v4.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, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Finite Element classes
13 
14 #include "fe.hpp"
15 #include "fe_coll.hpp"
16 #include "../mesh/nurbs.hpp"
17 #include "bilininteg.hpp"
18 #include <cmath>
19 
20 namespace mfem
21 {
22 
23 using namespace std;
24 
25 FiniteElement::FiniteElement(int D, Geometry::Type G, int Do, int O, int F)
26  : Nodes(Do)
27 {
28  Dim = D ; GeomType = G ; Dof = Do ; Order = O ; FuncSpace = F;
29  RangeType = SCALAR;
30  MapType = VALUE;
31  DerivType = NONE;
34  for (int i = 0; i < Geometry::MaxDim; i++) { Orders[i] = -1; }
35 #ifndef MFEM_THREAD_SAFE
37 #endif
38 }
39 
41  const IntegrationPoint &ip, DenseMatrix &shape) const
42 {
43  mfem_error ("FiniteElement::CalcVShape (ip, ...)\n"
44  " is not implemented for this class!");
45 }
46 
49 {
50  mfem_error ("FiniteElement::CalcVShape (trans, ...)\n"
51  " is not implemented for this class!");
52 }
53 
55  const IntegrationPoint &ip, Vector &divshape) const
56 {
57  mfem_error ("FiniteElement::CalcDivShape (ip, ...)\n"
58  " is not implemented for this class!");
59 }
60 
62  ElementTransformation &Trans, Vector &div_shape) const
63 {
64  CalcDivShape(Trans.GetIntPoint(), div_shape);
65  div_shape *= (1.0 / Trans.Weight());
66 }
67 
69  DenseMatrix &curl_shape) const
70 {
71  mfem_error ("FiniteElement::CalcCurlShape (ip, ...)\n"
72  " is not implemented for this class!");
73 }
74 
76  DenseMatrix &curl_shape) const
77 {
78  switch (Dim)
79  {
80  case 3:
81  {
82 #ifdef MFEM_THREAD_SAFE
84 #endif
86  MultABt(vshape, Trans.Jacobian(), curl_shape);
87  curl_shape *= (1.0 / Trans.Weight());
88  break;
89  }
90  case 2:
91  // This is valid for both 2x2 and 3x2 Jacobians
92  CalcCurlShape(Trans.GetIntPoint(), curl_shape);
93  curl_shape *= (1.0 / Trans.Weight());
94  break;
95  default:
96  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
97  }
98 }
99 
100 void FiniteElement::GetFaceDofs(int face, int **dofs, int *ndofs) const
101 {
102  mfem_error ("FiniteElement::GetFaceDofs (...)");
103 }
104 
106  DenseMatrix &h) const
107 {
108  mfem_error ("FiniteElement::CalcHessian (...) is not overloaded !");
109 }
110 
112  DenseMatrix &I) const
113 {
114  mfem_error ("GetLocalInterpolation (...) is not overloaded !");
115 }
116 
118  DenseMatrix &) const
119 {
120  mfem_error("FiniteElement::GetLocalRestriction() is not overloaded !");
121 }
122 
125  DenseMatrix &I) const
126 {
127  MFEM_ABORT("method is not overloaded !");
128 }
129 
131  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
132 {
133  mfem_error ("FiniteElement::Project (...) is not overloaded !");
134 }
135 
138 {
139  mfem_error ("FiniteElement::Project (...) (vector) is not overloaded !");
140 }
141 
143  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
144 {
145  mfem_error("FiniteElement::ProjectMatrixCoefficient() is not overloaded !");
146 }
147 
148 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
149 {
150  mfem_error("FiniteElement::ProjectDelta(...) is not implemented for "
151  "this element!");
152 }
153 
156 {
157  mfem_error("FiniteElement::Project(...) (fe version) is not implemented "
158  "for this element!");
159 }
160 
163  DenseMatrix &grad) const
164 {
165  mfem_error("FiniteElement::ProjectGrad(...) is not implemented for "
166  "this element!");
167 }
168 
171  DenseMatrix &curl) const
172 {
173  mfem_error("FiniteElement::ProjectCurl(...) is not implemented for "
174  "this element!");
175 }
176 
179  DenseMatrix &div) const
180 {
181  mfem_error("FiniteElement::ProjectDiv(...) is not implemented for "
182  "this element!");
183 }
184 
186  Vector &shape) const
187 {
188  CalcShape(Trans.GetIntPoint(), shape);
189  if (MapType == INTEGRAL)
190  {
191  shape /= Trans.Weight();
192  }
193 }
194 
196  DenseMatrix &dshape) const
197 {
198  MFEM_ASSERT(MapType == VALUE, "");
199 #ifdef MFEM_THREAD_SAFE
201 #endif
202  CalcDShape(Trans.GetIntPoint(), vshape);
203  Mult(vshape, Trans.InverseJacobian(), dshape);
204 }
205 
207  DofToQuad::Mode) const
208 {
209  mfem_error("FiniteElement::GetDofToQuad(...) is not implemented for "
210  "this element!");
211  return *dof2quad_array[0]; // suppress a warning
212 }
213 
215 {
216  for (int i = 0; i < dof2quad_array.Size(); i++)
217  {
218  delete dof2quad_array[i];
219  }
220 }
221 
222 
225  const ScalarFiniteElement &fine_fe) const
226 {
227  double v[Geometry::MaxDim];
228  Vector vv (v, Dim);
229  IntegrationPoint f_ip;
230 
231 #ifdef MFEM_THREAD_SAFE
232  Vector c_shape(Dof);
233 #endif
234 
235  MFEM_ASSERT(MapType == fine_fe.GetMapType(), "");
236 
237  I.SetSize(fine_fe.Dof, Dof);
238  for (int i = 0; i < fine_fe.Dof; i++)
239  {
240  Trans.Transform(fine_fe.Nodes.IntPoint(i), vv);
241  f_ip.Set(v, Dim);
242  CalcShape(f_ip, c_shape);
243  for (int j = 0; j < Dof; j++)
244  if (fabs(I(i,j) = c_shape(j)) < 1.0e-12)
245  {
246  I(i,j) = 0.0;
247  }
248  }
249  if (MapType == INTEGRAL)
250  {
251  // assuming Trans is linear; this should be ok for all refinement types
253  I *= Trans.Weight();
254  }
255 }
256 
259  const ScalarFiniteElement &fine_fe) const
260 {
261  // General "interpolation", defined by L2 projection
262 
263  double v[Geometry::MaxDim];
264  Vector vv (v, Dim);
265  IntegrationPoint f_ip;
266 
267  const int fs = fine_fe.GetDof(), cs = this->GetDof();
268  I.SetSize(fs, cs);
269  Vector fine_shape(fs), coarse_shape(cs);
270  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
271  const int ir_order = GetOrder() + fine_fe.GetOrder();
272  const IntegrationRule &ir = IntRules.Get(fine_fe.GetGeomType(), ir_order);
273 
274  for (int i = 0; i < ir.GetNPoints(); i++)
275  {
276  const IntegrationPoint &ip = ir.IntPoint(i);
277  fine_fe.CalcShape(ip, fine_shape);
278  Trans.Transform(ip, vv);
279  f_ip.Set(v, Dim);
280  this->CalcShape(f_ip, coarse_shape);
281 
282  AddMult_a_VVt(ip.weight, fine_shape, fine_mass);
283  AddMult_a_VWt(ip.weight, fine_shape, coarse_shape, fine_coarse_mass);
284  }
285 
286  DenseMatrixInverse fine_mass_inv(fine_mass);
287  fine_mass_inv.Mult(fine_coarse_mass, I);
288 
289  if (MapType == INTEGRAL)
290  {
291  // assuming Trans is linear; this should be ok for all refinement types
293  I *= Trans.Weight();
294  }
295 }
296 
298  DofToQuad::Mode mode) const
299 {
300  MFEM_VERIFY(mode == DofToQuad::FULL, "invalid mode requested");
301 
302  for (int i = 0; i < dof2quad_array.Size(); i++)
303  {
304  const DofToQuad &d2q = *dof2quad_array[i];
305  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
306  }
307 
308  DofToQuad *d2q = new DofToQuad;
309  const int nqpt = ir.GetNPoints();
310  d2q->FE = this;
311  d2q->IntRule = &ir;
312  d2q->mode = mode;
313  d2q->ndof = Dof;
314  d2q->nqpt = nqpt;
315  d2q->B.SetSize(nqpt*Dof);
316  d2q->Bt.SetSize(Dof*nqpt);
317  d2q->G.SetSize(nqpt*Dim*Dof);
318  d2q->Gt.SetSize(Dof*nqpt*Dim);
319 #ifdef MFEM_THREAD_SAFE
320  Vector c_shape(Dof);
321  DenseMatrix vshape(Dof, Dim);
322 #endif
323  for (int i = 0; i < nqpt; i++)
324  {
325  const IntegrationPoint &ip = ir.IntPoint(i);
326  CalcShape(ip, c_shape);
327  for (int j = 0; j < Dof; j++)
328  {
329  d2q->B[i+nqpt*j] = d2q->Bt[j+Dof*i] = c_shape(j);
330  }
331  CalcDShape(ip, vshape);
332  for (int d = 0; d < Dim; d++)
333  {
334  for (int j = 0; j < Dof; j++)
335  {
336  d2q->G[i+nqpt*(d+Dim*j)] = d2q->Gt[j+Dof*(i+nqpt*d)] = vshape(j,d);
337  }
338  }
339  }
340  dof2quad_array.Append(d2q);
341  return *d2q;
342 }
343 
344 // protected method
346  const TensorBasisElement &tb,
347  const IntegrationRule &ir, DofToQuad::Mode mode) const
348 {
349  MFEM_VERIFY(mode == DofToQuad::TENSOR, "invalid mode requested");
350 
351  for (int i = 0; i < dof2quad_array.Size(); i++)
352  {
353  const DofToQuad &d2q = *dof2quad_array[i];
354  if (d2q.IntRule == &ir && d2q.mode == mode) { return d2q; }
355  }
356 
357  DofToQuad *d2q = new DofToQuad;
358  const Poly_1D::Basis &basis_1d = tb.GetBasis1D();
359  const int ndof = Order + 1;
360  const int nqpt = (int)floor(pow(ir.GetNPoints(), 1.0/Dim) + 0.5);
361  d2q->FE = this;
362  d2q->IntRule = &ir;
363  d2q->mode = mode;
364  d2q->ndof = ndof;
365  d2q->nqpt = nqpt;
366  d2q->B.SetSize(nqpt*ndof);
367  d2q->Bt.SetSize(ndof*nqpt);
368  d2q->G.SetSize(nqpt*ndof);
369  d2q->Gt.SetSize(ndof*nqpt);
370  Vector val(ndof), grad(ndof);
371  for (int i = 0; i < nqpt; i++)
372  {
373  // The first 'nqpt' points in 'ir' have the same x-coordinates as those
374  // of the 1D rule.
375  basis_1d.Eval(ir.IntPoint(i).x, val, grad);
376  for (int j = 0; j < ndof; j++)
377  {
378  d2q->B[i+nqpt*j] = d2q->Bt[j+ndof*i] = val(j);
379  d2q->G[i+nqpt*j] = d2q->Gt[j+ndof*i] = grad(j);
380  }
381  }
382  dof2quad_array.Append(d2q);
383  return *d2q;
384 }
385 
386 
389  DenseMatrix &curl) const
390 {
391  MFEM_ASSERT(GetMapType() == FiniteElement::INTEGRAL, "");
392 
393  DenseMatrix curl_shape(fe.GetDof(), 1);
394 
395  curl.SetSize(Dof, fe.GetDof());
396  for (int i = 0; i < Dof; i++)
397  {
398  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
399  for (int j = 0; j < fe.GetDof(); j++)
400  {
401  curl(i,j) = curl_shape(j,0);
402  }
403  }
404 }
405 
407  const IntegrationPoint &pt, Vector &x)
408 {
409  // invert a linear transform with one Newton step
410  IntegrationPoint p0;
411  p0.Set3(0, 0, 0);
412  trans.Transform(p0, x);
413 
414  double store[3];
415  Vector v(store, x.Size());
416  pt.Get(v, x.Size());
417  v -= x;
418 
419  trans.InverseJacobian().Mult(v, x);
420 }
421 
423  DenseMatrix &R) const
424 {
425  IntegrationPoint ipt;
426  Vector pt(&ipt.x, Dim);
427 
428 #ifdef MFEM_THREAD_SAFE
429  Vector c_shape(Dof);
430 #endif
431 
432  Trans.SetIntPoint(&Nodes[0]);
433 
434  for (int j = 0; j < Dof; j++)
435  {
436  InvertLinearTrans(Trans, Nodes[j], pt);
437  if (Geometries.CheckPoint(GeomType, ipt)) // do we need an epsilon here?
438  {
439  CalcShape(ipt, c_shape);
440  R.SetRow(j, c_shape);
441  }
442  else
443  {
444  // Set the whole row to avoid valgrind warnings in R.Threshold().
445  R.SetRow(j, infinity());
446  }
447  }
448  R.Threshold(1e-12);
449 }
450 
452  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
453 {
454  for (int i = 0; i < Dof; i++)
455  {
456  const IntegrationPoint &ip = Nodes.IntPoint(i);
457  // some coefficients expect that Trans.IntPoint is the same
458  // as the second argument of Eval
459  Trans.SetIntPoint(&ip);
460  dofs(i) = coeff.Eval (Trans, ip);
461  if (MapType == INTEGRAL)
462  {
463  dofs(i) *= Trans.Weight();
464  }
465  }
466 }
467 
470 {
471  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*Dof, "");
472  Vector x(vc.GetVDim());
473 
474  for (int i = 0; i < Dof; i++)
475  {
476  const IntegrationPoint &ip = Nodes.IntPoint(i);
477  Trans.SetIntPoint(&ip);
478  vc.Eval (x, Trans, ip);
479  if (MapType == INTEGRAL)
480  {
481  x *= Trans.Weight();
482  }
483  for (int j = 0; j < x.Size(); j++)
484  {
485  dofs(Dof*j+i) = x(j);
486  }
487  }
488 }
489 
491  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
492 {
493  // (mc.height x mc.width) @ DOFs -> (Dof x mc.width x mc.height) in dofs
494  MFEM_ASSERT(dofs.Size() == mc.GetHeight()*mc.GetWidth()*Dof, "");
495  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
496 
497  for (int k = 0; k < Dof; k++)
498  {
499  T.SetIntPoint(&Nodes.IntPoint(k));
500  mc.Eval(MQ, T, Nodes.IntPoint(k));
501  if (MapType == INTEGRAL) { MQ *= T.Weight(); }
502  for (int r = 0; r < MQ.Height(); r++)
503  {
504  for (int d = 0; d < MQ.Width(); d++)
505  {
506  dofs(k+Dof*(d+MQ.Width()*r)) = MQ(r,d);
507  }
508  }
509  }
510 }
511 
514 {
515  if (fe.GetRangeType() == SCALAR)
516  {
517  MFEM_ASSERT(MapType == fe.GetMapType(), "");
518 
519  Vector shape(fe.GetDof());
520 
521  I.SetSize(Dof, fe.GetDof());
522  for (int k = 0; k < Dof; k++)
523  {
524  fe.CalcShape(Nodes.IntPoint(k), shape);
525  for (int j = 0; j < shape.Size(); j++)
526  {
527  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
528  }
529  }
530  }
531  else
532  {
533  DenseMatrix vshape(fe.GetDof(), Trans.GetSpaceDim());
534 
535  I.SetSize(vshape.Width()*Dof, fe.GetDof());
536  for (int k = 0; k < Dof; k++)
537  {
538  Trans.SetIntPoint(&Nodes.IntPoint(k));
539  fe.CalcVShape(Trans, vshape);
540  if (MapType == INTEGRAL)
541  {
542  vshape *= Trans.Weight();
543  }
544  for (int j = 0; j < vshape.Height(); j++)
545  for (int d = 0; d < vshape.Width(); d++)
546  {
547  I(k+d*Dof,j) = vshape(j,d);
548  }
549  }
550  }
551 }
552 
555  DenseMatrix &grad) const
556 {
557  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
558  MFEM_ASSERT(Trans.GetSpaceDim() == Dim, "")
559 
560  DenseMatrix dshape(fe.GetDof(), Dim), grad_k(fe.GetDof(), Dim), Jinv(Dim);
561 
562  grad.SetSize(Dim*Dof, fe.GetDof());
563  for (int k = 0; k < Dof; k++)
564  {
565  const IntegrationPoint &ip = Nodes.IntPoint(k);
566  fe.CalcDShape(ip, dshape);
567  Trans.SetIntPoint(&ip);
568  CalcInverse(Trans.Jacobian(), Jinv);
569  Mult(dshape, Jinv, grad_k);
570  if (MapType == INTEGRAL)
571  {
572  grad_k *= Trans.Weight();
573  }
574  for (int j = 0; j < grad_k.Height(); j++)
575  for (int d = 0; d < Dim; d++)
576  {
577  grad(k+d*Dof,j) = grad_k(j,d);
578  }
579  }
580 }
581 
584  DenseMatrix &div) const
585 {
586  double detJ;
587  Vector div_shape(fe.GetDof());
588 
589  div.SetSize(Dof, fe.GetDof());
590  for (int k = 0; k < Dof; k++)
591  {
592  const IntegrationPoint &ip = Nodes.IntPoint(k);
593  fe.CalcDivShape(ip, div_shape);
594  if (MapType == VALUE)
595  {
596  Trans.SetIntPoint(&ip);
597  detJ = Trans.Weight();
598  for (int j = 0; j < div_shape.Size(); j++)
599  {
600  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
601  }
602  }
603  else
604  {
605  for (int j = 0; j < div_shape.Size(); j++)
606  {
607  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
608  }
609  }
610  }
611 }
612 
613 
615  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
616 {
617  for (int i = 0; i < Dof; i++)
618  {
619  const IntegrationPoint &ip = Nodes.IntPoint(i);
620  Trans.SetIntPoint(&ip);
621  dofs(i) = coeff.Eval(Trans, ip);
622  }
623 }
624 
627 {
628  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*Dof, "");
629  Vector x(vc.GetVDim());
630 
631  for (int i = 0; i < Dof; i++)
632  {
633  const IntegrationPoint &ip = Nodes.IntPoint(i);
634  Trans.SetIntPoint(&ip);
635  vc.Eval (x, Trans, ip);
636  for (int j = 0; j < x.Size(); j++)
637  {
638  dofs(Dof*j+i) = x(j);
639  }
640  }
641 }
642 
645 {
646  const NodalFiniteElement *nfe =
647  dynamic_cast<const NodalFiniteElement *>(&fe);
648 
649  if (nfe && Dof == nfe->GetDof())
650  {
651  nfe->Project(*this, Trans, I);
652  I.Invert();
653  }
654  else
655  {
656  // local L2 projection
657  DenseMatrix pos_mass, mixed_mass;
658  MassIntegrator mass_integ;
659 
660  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
661  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
662 
663  DenseMatrixInverse pos_mass_inv(pos_mass);
664  I.SetSize(Dof, fe.GetDof());
665  pos_mass_inv.Mult(mixed_mass, I);
666  }
667 }
668 
669 
670 void VectorFiniteElement::CalcShape (
671  const IntegrationPoint &ip, Vector &shape ) const
672 {
673  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
674  " VectorFiniteElements!");
675 }
676 
677 void VectorFiniteElement::CalcDShape (
678  const IntegrationPoint &ip, DenseMatrix &dshape ) const
679 {
680  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
681  " VectorFiniteElements!");
682 }
683 
685 {
686  switch (MapType)
687  {
688  case H_DIV:
689  DerivType = DIV;
692  break;
693  case H_CURL:
694  switch (Dim)
695  {
696  case 3: // curl: 3D H_CURL -> 3D H_DIV
697  DerivType = CURL;
700  break;
701  case 2:
702  // curl: 2D H_CURL -> INTEGRAL
703  DerivType = CURL;
706  break;
707  case 1:
708  DerivType = NONE;
711  break;
712  default:
713  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
714  }
715  break;
716  default:
717  MFEM_ABORT("Invalid MapType = " << MapType);
718  }
719 }
720 
722  ElementTransformation &Trans, DenseMatrix &shape) const
723 {
724  MFEM_ASSERT(MapType == H_DIV, "");
725 #ifdef MFEM_THREAD_SAFE
727 #endif
728  CalcVShape(Trans.GetIntPoint(), vshape);
729  MultABt(vshape, Trans.Jacobian(), shape);
730  shape *= (1.0 / Trans.Weight());
731 }
732 
734  ElementTransformation &Trans, DenseMatrix &shape) const
735 {
736  MFEM_ASSERT(MapType == H_CURL, "");
737 #ifdef MFEM_THREAD_SAFE
739 #endif
740  CalcVShape(Trans.GetIntPoint(), vshape);
741  Mult(vshape, Trans.InverseJacobian(), shape);
742 }
743 
745  const double *nk, const Array<int> &d2n,
747 {
748  double vk[Geometry::MaxDim];
749  const int sdim = Trans.GetSpaceDim();
750  MFEM_ASSERT(vc.GetVDim() == sdim, "");
751  Vector xk(vk, sdim);
752  const bool square_J = (Dim == sdim);
753 
754  for (int k = 0; k < Dof; k++)
755  {
756  Trans.SetIntPoint(&Nodes.IntPoint(k));
757  vc.Eval(xk, Trans, Nodes.IntPoint(k));
758  // dof_k = nk^t adj(J) xk
759  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*Dim);
760  if (!square_J) { dofs(k) /= Trans.Weight(); }
761  }
762 }
763 
765  const double *nk, const Array<int> &d2n,
766  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
767 {
768  // project the rows of the matrix coefficient in an RT space
769 
770  const int sdim = T.GetSpaceDim();
771  MFEM_ASSERT(mc.GetWidth() == sdim, "");
772  const bool square_J = (Dim == sdim);
773  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
774  Vector nk_phys(sdim), dofs_k(MQ.Height());
775  MFEM_ASSERT(dofs.Size() == Dof*MQ.Height(), "");
776 
777  for (int k = 0; k < Dof; k++)
778  {
779  T.SetIntPoint(&Nodes.IntPoint(k));
780  mc.Eval(MQ, T, Nodes.IntPoint(k));
781  // nk_phys = adj(J)^t nk
782  T.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, nk_phys);
783  if (!square_J) { nk_phys /= T.Weight(); }
784  MQ.Mult(nk_phys, dofs_k);
785  for (int r = 0; r < MQ.Height(); r++)
786  {
787  dofs(k+Dof*r) = dofs_k(r);
788  }
789  }
790 }
791 
793  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
795 {
796  if (fe.GetRangeType() == SCALAR)
797  {
798  double vk[Geometry::MaxDim];
799  Vector shape(fe.GetDof());
800  int sdim = Trans.GetSpaceDim();
801 
802  I.SetSize(Dof, sdim*fe.GetDof());
803  for (int k = 0; k < Dof; k++)
804  {
805  const IntegrationPoint &ip = Nodes.IntPoint(k);
806 
807  fe.CalcShape(ip, shape);
808  Trans.SetIntPoint(&ip);
809  Trans.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, vk);
810  if (fe.GetMapType() == INTEGRAL)
811  {
812  double w = 1.0/Trans.Weight();
813  for (int d = 0; d < Dim; d++)
814  {
815  vk[d] *= w;
816  }
817  }
818 
819  for (int j = 0; j < shape.Size(); j++)
820  {
821  double s = shape(j);
822  if (fabs(s) < 1e-12)
823  {
824  s = 0.0;
825  }
826  for (int d = 0; d < sdim; d++)
827  {
828  I(k,j+d*shape.Size()) = s*vk[d];
829  }
830  }
831  }
832  }
833  else
834  {
835  mfem_error("VectorFiniteElement::Project_RT (fe version)");
836  }
837 }
838 
840  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
842 {
843  if (Dim != 2)
844  {
845  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
846  }
847 
848  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
849  Vector grad_k(fe.GetDof());
850  double tk[2];
851 
852  grad.SetSize(Dof, fe.GetDof());
853  for (int k = 0; k < Dof; k++)
854  {
855  fe.CalcDShape(Nodes.IntPoint(k), dshape);
856  tk[0] = nk[d2n[k]*Dim+1];
857  tk[1] = -nk[d2n[k]*Dim];
858  dshape.Mult(tk, grad_k);
859  for (int j = 0; j < grad_k.Size(); j++)
860  {
861  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
862  }
863  }
864 }
865 
867  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
869 {
870 #ifdef MFEM_THREAD_SAFE
873  DenseMatrix J(Dim, Dim);
874 #else
875  curlshape.SetSize(fe.GetDof(), Dim);
876  curlshape_J.SetSize(fe.GetDof(), Dim);
877  J.SetSize(Dim, Dim);
878 #endif
879 
880  Vector curl_k(fe.GetDof());
881 
882  curl.SetSize(Dof, fe.GetDof());
883  for (int k = 0; k < Dof; k++)
884  {
885  const IntegrationPoint &ip = Nodes.IntPoint(k);
886 
887  // calculate J^t * J / |J|
888  Trans.SetIntPoint(&ip);
889  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
890  J *= 1.0 / Trans.Weight();
891 
892  // transform curl of shapes (rows) by J^t * J / |J|
893  fe.CalcCurlShape(ip, curlshape);
895 
896  curlshape_J.Mult(tk + d2t[k]*Dim, curl_k);
897  for (int j = 0; j < curl_k.Size(); j++)
898  {
899  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
900  }
901  }
902 }
903 
905  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
907 {
908  DenseMatrix curl_shape(fe.GetDof(), Dim);
909  Vector curl_k(fe.GetDof());
910 
911  curl.SetSize(Dof, fe.GetDof());
912  for (int k = 0; k < Dof; k++)
913  {
914  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
915  curl_shape.Mult(nk + d2n[k]*Dim, curl_k);
916  for (int j = 0; j < curl_k.Size(); j++)
917  {
918  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
919  }
920  }
921 }
922 
924  const double *tk, const Array<int> &d2t,
926 {
927  double vk[Geometry::MaxDim];
928  Vector xk(vk, vc.GetVDim());
929 
930  for (int k = 0; k < Dof; k++)
931  {
932  Trans.SetIntPoint(&Nodes.IntPoint(k));
933 
934  vc.Eval(xk, Trans, Nodes.IntPoint(k));
935  // dof_k = xk^t J tk
936  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*Dim, vk);
937  }
938 }
939 
941  const double *tk, const Array<int> &d2t,
942  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
943 {
944  // project the rows of the matrix coefficient in an ND space
945 
946  const int sdim = T.GetSpaceDim();
947  MFEM_ASSERT(mc.GetWidth() == sdim, "");
948  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
949  Vector tk_phys(sdim), dofs_k(MQ.Height());
950  MFEM_ASSERT(dofs.Size() == Dof*MQ.Height(), "");
951 
952  for (int k = 0; k < Dof; k++)
953  {
954  T.SetIntPoint(&Nodes.IntPoint(k));
955  mc.Eval(MQ, T, Nodes.IntPoint(k));
956  // tk_phys = J tk
957  T.Jacobian().Mult(tk + d2t[k]*Dim, tk_phys);
958  MQ.Mult(tk_phys, dofs_k);
959  for (int r = 0; r < MQ.Height(); r++)
960  {
961  dofs(k+Dof*r) = dofs_k(r);
962  }
963  }
964 }
965 
967  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
969 {
970  if (fe.GetRangeType() == SCALAR)
971  {
972  int sdim = Trans.GetSpaceDim();
973  double vk[Geometry::MaxDim];
974  Vector shape(fe.GetDof());
975 
976  I.SetSize(Dof, sdim*fe.GetDof());
977  for (int k = 0; k < Dof; k++)
978  {
979  const IntegrationPoint &ip = Nodes.IntPoint(k);
980 
981  fe.CalcShape(ip, shape);
982  Trans.SetIntPoint(&ip);
983  Trans.Jacobian().Mult(tk + d2t[k]*Dim, vk);
984  if (fe.GetMapType() == INTEGRAL)
985  {
986  double w = 1.0/Trans.Weight();
987  for (int d = 0; d < sdim; d++)
988  {
989  vk[d] *= w;
990  }
991  }
992 
993  for (int j = 0; j < shape.Size(); j++)
994  {
995  double s = shape(j);
996  if (fabs(s) < 1e-12)
997  {
998  s = 0.0;
999  }
1000  for (int d = 0; d < sdim; d++)
1001  {
1002  I(k, j + d*shape.Size()) = s*vk[d];
1003  }
1004  }
1005  }
1006  }
1007  else
1008  {
1009  mfem_error("VectorFiniteElement::Project_ND (fe version)");
1010  }
1011 }
1012 
1014  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
1015  ElementTransformation &Trans, DenseMatrix &grad) const
1016 {
1017  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
1018 
1019  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
1020  Vector grad_k(fe.GetDof());
1021 
1022  grad.SetSize(Dof, fe.GetDof());
1023  for (int k = 0; k < Dof; k++)
1024  {
1025  fe.CalcDShape(Nodes.IntPoint(k), dshape);
1026  dshape.Mult(tk + d2t[k]*Dim, grad_k);
1027  for (int j = 0; j < grad_k.Size(); j++)
1028  {
1029  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
1030  }
1031  }
1032 }
1033 
1035  const VectorFiniteElement &cfe, const double *nk, const Array<int> &d2n,
1037 {
1038  MFEM_ASSERT(MapType == cfe.GetMapType(), "");
1039 
1040  double vk[Geometry::MaxDim];
1041  Vector xk(vk, Dim);
1042  IntegrationPoint ip;
1043 #ifdef MFEM_THREAD_SAFE
1044  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
1045 #else
1046  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
1047 #endif
1048  I.SetSize(Dof, vshape.Height());
1049 
1050  // assuming Trans is linear; this should be ok for all refinement types
1052  const DenseMatrix &adjJ = Trans.AdjugateJacobian();
1053  for (int k = 0; k < Dof; k++)
1054  {
1055  Trans.Transform(Nodes.IntPoint(k), xk);
1056  ip.Set3(vk);
1057  cfe.CalcVShape(ip, vshape);
1058  // xk = |J| J^{-t} n_k
1059  adjJ.MultTranspose(nk + d2n[k]*Dim, vk);
1060  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,Dof
1061  for (int j = 0; j < vshape.Height(); j++)
1062  {
1063  double Ikj = 0.;
1064  for (int i = 0; i < Dim; i++)
1065  {
1066  Ikj += vshape(j, i) * vk[i];
1067  }
1068  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1069  }
1070  }
1071 }
1072 
1074  const VectorFiniteElement &cfe, const double *tk, const Array<int> &d2t,
1076 {
1077  double vk[Geometry::MaxDim];
1078  Vector xk(vk, Dim);
1079  IntegrationPoint ip;
1080 #ifdef MFEM_THREAD_SAFE
1081  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
1082 #else
1083  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
1084 #endif
1085  I.SetSize(Dof, vshape.Height());
1086 
1087  // assuming Trans is linear; this should be ok for all refinement types
1089  const DenseMatrix &J = Trans.Jacobian();
1090  for (int k = 0; k < Dof; k++)
1091  {
1092  Trans.Transform(Nodes.IntPoint(k), xk);
1093  ip.Set3(vk);
1094  cfe.CalcVShape(ip, vshape);
1095  // xk = J t_k
1096  J.Mult(tk + d2t[k]*Dim, vk);
1097  // I_k = vshape_k.J.t_k, k=1,...,Dof
1098  for (int j = 0; j < vshape.Height(); j++)
1099  {
1100  double Ikj = 0.;
1101  for (int i = 0; i < Dim; i++)
1102  {
1103  Ikj += vshape(j, i) * vk[i];
1104  }
1105  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
1106  }
1107  }
1108 }
1109 
1111  const double *nk, const Array<int> &d2n, ElementTransformation &Trans,
1112  DenseMatrix &R) const
1113 {
1114  double pt_data[Geometry::MaxDim];
1115  IntegrationPoint ip;
1116  Vector pt(pt_data, Dim);
1117 
1118 #ifdef MFEM_THREAD_SAFE
1120 #endif
1121 
1123  const DenseMatrix &J = Trans.Jacobian();
1124  const double weight = Trans.Weight();
1125  for (int j = 0; j < Dof; j++)
1126  {
1127  InvertLinearTrans(Trans, Nodes.IntPoint(j), pt);
1128  ip.Set(pt_data, Dim);
1129  if (Geometries.CheckPoint(GeomType, ip)) // do we need an epsilon here?
1130  {
1131  CalcVShape(ip, vshape);
1132  J.MultTranspose(nk+Dim*d2n[j], pt_data);
1133  pt /= weight;
1134  for (int k = 0; k < Dof; k++)
1135  {
1136  double R_jk = 0.0;
1137  for (int d = 0; d < Dim; d++)
1138  {
1139  R_jk += vshape(k,d)*pt_data[d];
1140  }
1141  R(j,k) = R_jk;
1142  }
1143  }
1144  else
1145  {
1146  // Set the whole row to avoid valgrind warnings in R.Threshold().
1147  R.SetRow(j, infinity());
1148  }
1149  }
1150  R.Threshold(1e-12);
1151 }
1152 
1154  const double *tk, const Array<int> &d2t, ElementTransformation &Trans,
1155  DenseMatrix &R) const
1156 {
1157  double pt_data[Geometry::MaxDim];
1158  IntegrationPoint ip;
1159  Vector pt(pt_data, Dim);
1160 
1161 #ifdef MFEM_THREAD_SAFE
1163 #endif
1164 
1166  const DenseMatrix &Jinv = Trans.InverseJacobian();
1167  for (int j = 0; j < Dof; j++)
1168  {
1169  InvertLinearTrans(Trans, Nodes.IntPoint(j), pt);
1170  ip.Set(pt_data, Dim);
1171  if (Geometries.CheckPoint(GeomType, ip)) // do we need an epsilon here?
1172  {
1173  CalcVShape(ip, vshape);
1174  Jinv.Mult(tk+Dim*d2t[j], pt_data);
1175  for (int k = 0; k < Dof; k++)
1176  {
1177  double R_jk = 0.0;
1178  for (int d = 0; d < Dim; d++)
1179  {
1180  R_jk += vshape(k,d)*pt_data[d];
1181  }
1182  R(j,k) = R_jk;
1183  }
1184  }
1185  else
1186  {
1187  // Set the whole row to avoid valgrind warnings in R.Threshold().
1188  R.SetRow(j, infinity());
1189  }
1190  }
1191  R.Threshold(1e-12);
1192 }
1193 
1194 
1196  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
1197 {
1198  Nodes.IntPoint(0).x = 0.0;
1199 }
1200 
1202  Vector &shape) const
1203 {
1204  shape(0) = 1.;
1205 }
1206 
1208  DenseMatrix &dshape) const
1209 {
1210  // dshape is (1 x 0) - nothing to compute
1211 }
1212 
1214  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
1215 {
1216  Nodes.IntPoint(0).x = 0.0;
1217  Nodes.IntPoint(1).x = 1.0;
1218 }
1219 
1221  Vector &shape) const
1222 {
1223  shape(0) = 1. - ip.x;
1224  shape(1) = ip.x;
1225 }
1226 
1228  DenseMatrix &dshape) const
1229 {
1230  dshape(0,0) = -1.;
1231  dshape(1,0) = 1.;
1232 }
1233 
1235  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
1236 {
1237  Nodes.IntPoint(0).x = 0.0;
1238  Nodes.IntPoint(0).y = 0.0;
1239  Nodes.IntPoint(1).x = 1.0;
1240  Nodes.IntPoint(1).y = 0.0;
1241  Nodes.IntPoint(2).x = 0.0;
1242  Nodes.IntPoint(2).y = 1.0;
1243 }
1244 
1246  Vector &shape) const
1247 {
1248  shape(0) = 1. - ip.x - ip.y;
1249  shape(1) = ip.x;
1250  shape(2) = ip.y;
1251 }
1252 
1254  DenseMatrix &dshape) const
1255 {
1256  dshape(0,0) = -1.; dshape(0,1) = -1.;
1257  dshape(1,0) = 1.; dshape(1,1) = 0.;
1258  dshape(2,0) = 0.; dshape(2,1) = 1.;
1259 }
1260 
1262  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1263 {
1264  Nodes.IntPoint(0).x = 0.0;
1265  Nodes.IntPoint(0).y = 0.0;
1266  Nodes.IntPoint(1).x = 1.0;
1267  Nodes.IntPoint(1).y = 0.0;
1268  Nodes.IntPoint(2).x = 1.0;
1269  Nodes.IntPoint(2).y = 1.0;
1270  Nodes.IntPoint(3).x = 0.0;
1271  Nodes.IntPoint(3).y = 1.0;
1272 }
1273 
1275  Vector &shape) const
1276 {
1277  shape(0) = (1. - ip.x) * (1. - ip.y) ;
1278  shape(1) = ip.x * (1. - ip.y) ;
1279  shape(2) = ip.x * ip.y ;
1280  shape(3) = (1. - ip.x) * ip.y ;
1281 }
1282 
1284  DenseMatrix &dshape) const
1285 {
1286  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
1287  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
1288  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
1289  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
1290 }
1291 
1293  const IntegrationPoint &ip, DenseMatrix &h) const
1294 {
1295  h(0,0) = 0.; h(0,1) = 1.; h(0,2) = 0.;
1296  h(1,0) = 0.; h(1,1) = -1.; h(1,2) = 0.;
1297  h(2,0) = 0.; h(2,1) = 1.; h(2,2) = 0.;
1298  h(3,0) = 0.; h(3,1) = -1.; h(3,2) = 0.;
1299 }
1300 
1301 
1303  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
1304 {
1305  Nodes.IntPoint(0).x = 1./6.;
1306  Nodes.IntPoint(0).y = 1./6.;
1307  Nodes.IntPoint(1).x = 2./3.;
1308  Nodes.IntPoint(1).y = 1./6.;
1309  Nodes.IntPoint(2).x = 1./6.;
1310  Nodes.IntPoint(2).y = 2./3.;
1311 }
1312 
1314  Vector &shape) const
1315 {
1316  const double x = ip.x, y = ip.y;
1317 
1318  shape(0) = 5./3. - 2. * (x + y);
1319  shape(1) = 2. * (x - 1./6.);
1320  shape(2) = 2. * (y - 1./6.);
1321 }
1322 
1324  DenseMatrix &dshape) const
1325 {
1326  dshape(0,0) = -2.; dshape(0,1) = -2.;
1327  dshape(1,0) = 2.; dshape(1,1) = 0.;
1328  dshape(2,0) = 0.; dshape(2,1) = 2.;
1329 }
1330 
1332 {
1333  dofs(vertex) = 2./3.;
1334  dofs((vertex+1)%3) = 1./6.;
1335  dofs((vertex+2)%3) = 1./6.;
1336 }
1337 
1338 
1339 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
1340 const double GaussBiLinear2DFiniteElement::p[] =
1341 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
1342 
1344  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1345 {
1346  Nodes.IntPoint(0).x = p[0];
1347  Nodes.IntPoint(0).y = p[0];
1348  Nodes.IntPoint(1).x = p[1];
1349  Nodes.IntPoint(1).y = p[0];
1350  Nodes.IntPoint(2).x = p[1];
1351  Nodes.IntPoint(2).y = p[1];
1352  Nodes.IntPoint(3).x = p[0];
1353  Nodes.IntPoint(3).y = p[1];
1354 }
1355 
1357  Vector &shape) const
1358 {
1359  const double x = ip.x, y = ip.y;
1360 
1361  shape(0) = 3. * (p[1] - x) * (p[1] - y);
1362  shape(1) = 3. * (x - p[0]) * (p[1] - y);
1363  shape(2) = 3. * (x - p[0]) * (y - p[0]);
1364  shape(3) = 3. * (p[1] - x) * (y - p[0]);
1365 }
1366 
1368  DenseMatrix &dshape) const
1369 {
1370  const double x = ip.x, y = ip.y;
1371 
1372  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
1373  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
1374  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
1375  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
1376 }
1377 
1379 {
1380 #if 1
1381  dofs(vertex) = p[1]*p[1];
1382  dofs((vertex+1)%4) = p[0]*p[1];
1383  dofs((vertex+2)%4) = p[0]*p[0];
1384  dofs((vertex+3)%4) = p[0]*p[1];
1385 #else
1386  dofs = 1.0;
1387 #endif
1388 }
1389 
1390 
1392  : NodalFiniteElement(2, Geometry::SQUARE, 3, 1, FunctionSpace::Qk)
1393 {
1394  Nodes.IntPoint(0).x = 0.0;
1395  Nodes.IntPoint(0).y = 0.0;
1396  Nodes.IntPoint(1).x = 1.0;
1397  Nodes.IntPoint(1).y = 0.0;
1398  Nodes.IntPoint(2).x = 0.0;
1399  Nodes.IntPoint(2).y = 1.0;
1400 }
1401 
1403  Vector &shape) const
1404 {
1405  shape(0) = 1. - ip.x - ip.y;
1406  shape(1) = ip.x;
1407  shape(2) = ip.y;
1408 }
1409 
1411  DenseMatrix &dshape) const
1412 {
1413  dshape(0,0) = -1.; dshape(0,1) = -1.;
1414  dshape(1,0) = 1.; dshape(1,1) = 0.;
1415  dshape(2,0) = 0.; dshape(2,1) = 1.;
1416 }
1417 
1418 
1420  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
1421 {
1422  Nodes.IntPoint(0).x = 0.0;
1423  Nodes.IntPoint(1).x = 1.0;
1424  Nodes.IntPoint(2).x = 0.5;
1425 }
1426 
1428  Vector &shape) const
1429 {
1430  double x = ip.x;
1431  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
1432 
1433  shape(0) = l1 * (-l3);
1434  shape(1) = l2 * l3;
1435  shape(2) = 4. * l1 * l2;
1436 }
1437 
1439  DenseMatrix &dshape) const
1440 {
1441  double x = ip.x;
1442 
1443  dshape(0,0) = 4. * x - 3.;
1444  dshape(1,0) = 4. * x - 1.;
1445  dshape(2,0) = 4. - 8. * x;
1446 }
1447 
1448 
1450  : PositiveFiniteElement(1, Geometry::SEGMENT, 3, 2)
1451 {
1452  Nodes.IntPoint(0).x = 0.0;
1453  Nodes.IntPoint(1).x = 1.0;
1454  Nodes.IntPoint(2).x = 0.5;
1455 }
1456 
1458  Vector &shape) const
1459 {
1460  const double x = ip.x, x1 = 1. - x;
1461 
1462  shape(0) = x1 * x1;
1463  shape(1) = x * x;
1464  shape(2) = 2. * x * x1;
1465 }
1466 
1468  DenseMatrix &dshape) const
1469 {
1470  const double x = ip.x;
1471 
1472  dshape(0,0) = 2. * x - 2.;
1473  dshape(1,0) = 2. * x;
1474  dshape(2,0) = 2. - 4. * x;
1475 }
1476 
1478  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1479 {
1480  Nodes.IntPoint(0).x = 0.0;
1481  Nodes.IntPoint(0).y = 0.0;
1482  Nodes.IntPoint(1).x = 1.0;
1483  Nodes.IntPoint(1).y = 0.0;
1484  Nodes.IntPoint(2).x = 0.0;
1485  Nodes.IntPoint(2).y = 1.0;
1486  Nodes.IntPoint(3).x = 0.5;
1487  Nodes.IntPoint(3).y = 0.0;
1488  Nodes.IntPoint(4).x = 0.5;
1489  Nodes.IntPoint(4).y = 0.5;
1490  Nodes.IntPoint(5).x = 0.0;
1491  Nodes.IntPoint(5).y = 0.5;
1492 }
1493 
1495  Vector &shape) const
1496 {
1497  double x = ip.x, y = ip.y;
1498  double l1 = 1.-x-y, l2 = x, l3 = y;
1499 
1500  shape(0) = l1 * (2. * l1 - 1.);
1501  shape(1) = l2 * (2. * l2 - 1.);
1502  shape(2) = l3 * (2. * l3 - 1.);
1503  shape(3) = 4. * l1 * l2;
1504  shape(4) = 4. * l2 * l3;
1505  shape(5) = 4. * l3 * l1;
1506 }
1507 
1509  DenseMatrix &dshape) const
1510 {
1511  double x = ip.x, y = ip.y;
1512 
1513  dshape(0,0) =
1514  dshape(0,1) = 4. * (x + y) - 3.;
1515 
1516  dshape(1,0) = 4. * x - 1.;
1517  dshape(1,1) = 0.;
1518 
1519  dshape(2,0) = 0.;
1520  dshape(2,1) = 4. * y - 1.;
1521 
1522  dshape(3,0) = -4. * (2. * x + y - 1.);
1523  dshape(3,1) = -4. * x;
1524 
1525  dshape(4,0) = 4. * y;
1526  dshape(4,1) = 4. * x;
1527 
1528  dshape(5,0) = -4. * y;
1529  dshape(5,1) = -4. * (x + 2. * y - 1.);
1530 }
1531 
1533  DenseMatrix &h) const
1534 {
1535  h(0,0) = 4.;
1536  h(0,1) = 4.;
1537  h(0,2) = 4.;
1538 
1539  h(1,0) = 4.;
1540  h(1,1) = 0.;
1541  h(1,2) = 0.;
1542 
1543  h(2,0) = 0.;
1544  h(2,1) = 0.;
1545  h(2,2) = 4.;
1546 
1547  h(3,0) = -8.;
1548  h(3,1) = -4.;
1549  h(3,2) = 0.;
1550 
1551  h(4,0) = 0.;
1552  h(4,1) = 4.;
1553  h(4,2) = 0.;
1554 
1555  h(5,0) = 0.;
1556  h(5,1) = -4.;
1557  h(5,2) = -8.;
1558 }
1559 
1560 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1561 {
1562 #if 0
1563  dofs = 1.;
1564 #else
1565  dofs = 0.;
1566  dofs(vertex) = 1.;
1567  switch (vertex)
1568  {
1569  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1570  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1571  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1572  }
1573 #endif
1574 }
1575 
1576 
1577 const double GaussQuad2DFiniteElement::p[] =
1578 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1579 
1581  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1582 {
1583  Nodes.IntPoint(0).x = p[0];
1584  Nodes.IntPoint(0).y = p[0];
1585  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1586  Nodes.IntPoint(1).y = p[0];
1587  Nodes.IntPoint(2).x = p[0];
1588  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1589  Nodes.IntPoint(3).x = p[1];
1590  Nodes.IntPoint(3).y = p[1];
1591  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1592  Nodes.IntPoint(4).y = p[1];
1593  Nodes.IntPoint(5).x = p[1];
1594  Nodes.IntPoint(5).y = 1. - 2. * p[1];
1595 
1596  for (int i = 0; i < 6; i++)
1597  {
1598  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
1599  A(0,i) = 1.;
1600  A(1,i) = x;
1601  A(2,i) = y;
1602  A(3,i) = x * x;
1603  A(4,i) = x * y;
1604  A(5,i) = y * y;
1605  }
1606 
1607  A.Invert();
1608 }
1609 
1611  Vector &shape) const
1612 {
1613  const double x = ip.x, y = ip.y;
1614  pol(0) = 1.;
1615  pol(1) = x;
1616  pol(2) = y;
1617  pol(3) = x * x;
1618  pol(4) = x * y;
1619  pol(5) = y * y;
1620 
1621  A.Mult(pol, shape);
1622 }
1623 
1625  DenseMatrix &dshape) const
1626 {
1627  const double x = ip.x, y = ip.y;
1628  D(0,0) = 0.; D(0,1) = 0.;
1629  D(1,0) = 1.; D(1,1) = 0.;
1630  D(2,0) = 0.; D(2,1) = 1.;
1631  D(3,0) = 2. * x; D(3,1) = 0.;
1632  D(4,0) = y; D(4,1) = x;
1633  D(5,0) = 0.; D(5,1) = 2. * y;
1634 
1635  Mult(A, D, dshape);
1636 }
1637 
1638 
1640  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1641 {
1642  Nodes.IntPoint(0).x = 0.0;
1643  Nodes.IntPoint(0).y = 0.0;
1644  Nodes.IntPoint(1).x = 1.0;
1645  Nodes.IntPoint(1).y = 0.0;
1646  Nodes.IntPoint(2).x = 1.0;
1647  Nodes.IntPoint(2).y = 1.0;
1648  Nodes.IntPoint(3).x = 0.0;
1649  Nodes.IntPoint(3).y = 1.0;
1650  Nodes.IntPoint(4).x = 0.5;
1651  Nodes.IntPoint(4).y = 0.0;
1652  Nodes.IntPoint(5).x = 1.0;
1653  Nodes.IntPoint(5).y = 0.5;
1654  Nodes.IntPoint(6).x = 0.5;
1655  Nodes.IntPoint(6).y = 1.0;
1656  Nodes.IntPoint(7).x = 0.0;
1657  Nodes.IntPoint(7).y = 0.5;
1658  Nodes.IntPoint(8).x = 0.5;
1659  Nodes.IntPoint(8).y = 0.5;
1660 }
1661 
1663  Vector &shape) const
1664 {
1665  double x = ip.x, y = ip.y;
1666  double l1x, l2x, l3x, l1y, l2y, l3y;
1667 
1668  l1x = (x - 1.) * (2. * x - 1);
1669  l2x = 4. * x * (1. - x);
1670  l3x = x * (2. * x - 1.);
1671  l1y = (y - 1.) * (2. * y - 1);
1672  l2y = 4. * y * (1. - y);
1673  l3y = y * (2. * y - 1.);
1674 
1675  shape(0) = l1x * l1y;
1676  shape(4) = l2x * l1y;
1677  shape(1) = l3x * l1y;
1678  shape(7) = l1x * l2y;
1679  shape(8) = l2x * l2y;
1680  shape(5) = l3x * l2y;
1681  shape(3) = l1x * l3y;
1682  shape(6) = l2x * l3y;
1683  shape(2) = l3x * l3y;
1684 }
1685 
1687  DenseMatrix &dshape) const
1688 {
1689  double x = ip.x, y = ip.y;
1690  double l1x, l2x, l3x, l1y, l2y, l3y;
1691  double d1x, d2x, d3x, d1y, d2y, d3y;
1692 
1693  l1x = (x - 1.) * (2. * x - 1);
1694  l2x = 4. * x * (1. - x);
1695  l3x = x * (2. * x - 1.);
1696  l1y = (y - 1.) * (2. * y - 1);
1697  l2y = 4. * y * (1. - y);
1698  l3y = y * (2. * y - 1.);
1699 
1700  d1x = 4. * x - 3.;
1701  d2x = 4. - 8. * x;
1702  d3x = 4. * x - 1.;
1703  d1y = 4. * y - 3.;
1704  d2y = 4. - 8. * y;
1705  d3y = 4. * y - 1.;
1706 
1707  dshape(0,0) = d1x * l1y;
1708  dshape(0,1) = l1x * d1y;
1709 
1710  dshape(4,0) = d2x * l1y;
1711  dshape(4,1) = l2x * d1y;
1712 
1713  dshape(1,0) = d3x * l1y;
1714  dshape(1,1) = l3x * d1y;
1715 
1716  dshape(7,0) = d1x * l2y;
1717  dshape(7,1) = l1x * d2y;
1718 
1719  dshape(8,0) = d2x * l2y;
1720  dshape(8,1) = l2x * d2y;
1721 
1722  dshape(5,0) = d3x * l2y;
1723  dshape(5,1) = l3x * d2y;
1724 
1725  dshape(3,0) = d1x * l3y;
1726  dshape(3,1) = l1x * d3y;
1727 
1728  dshape(6,0) = d2x * l3y;
1729  dshape(6,1) = l2x * d3y;
1730 
1731  dshape(2,0) = d3x * l3y;
1732  dshape(2,1) = l3x * d3y;
1733 }
1734 
1735 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1736 {
1737 #if 0
1738  dofs = 1.;
1739 #else
1740  dofs = 0.;
1741  dofs(vertex) = 1.;
1742  switch (vertex)
1743  {
1744  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
1745  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
1746  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
1747  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
1748  }
1749  dofs(8) = 1./16.;
1750 #endif
1751 }
1752 
1754  : PositiveFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1755 {
1756  Nodes.IntPoint(0).x = 0.0;
1757  Nodes.IntPoint(0).y = 0.0;
1758  Nodes.IntPoint(1).x = 1.0;
1759  Nodes.IntPoint(1).y = 0.0;
1760  Nodes.IntPoint(2).x = 1.0;
1761  Nodes.IntPoint(2).y = 1.0;
1762  Nodes.IntPoint(3).x = 0.0;
1763  Nodes.IntPoint(3).y = 1.0;
1764  Nodes.IntPoint(4).x = 0.5;
1765  Nodes.IntPoint(4).y = 0.0;
1766  Nodes.IntPoint(5).x = 1.0;
1767  Nodes.IntPoint(5).y = 0.5;
1768  Nodes.IntPoint(6).x = 0.5;
1769  Nodes.IntPoint(6).y = 1.0;
1770  Nodes.IntPoint(7).x = 0.0;
1771  Nodes.IntPoint(7).y = 0.5;
1772  Nodes.IntPoint(8).x = 0.5;
1773  Nodes.IntPoint(8).y = 0.5;
1774 }
1775 
1777  Vector &shape) const
1778 {
1779  double x = ip.x, y = ip.y;
1780  double l1x, l2x, l3x, l1y, l2y, l3y;
1781 
1782  l1x = (1. - x) * (1. - x);
1783  l2x = 2. * x * (1. - x);
1784  l3x = x * x;
1785  l1y = (1. - y) * (1. - y);
1786  l2y = 2. * y * (1. - y);
1787  l3y = y * y;
1788 
1789  shape(0) = l1x * l1y;
1790  shape(4) = l2x * l1y;
1791  shape(1) = l3x * l1y;
1792  shape(7) = l1x * l2y;
1793  shape(8) = l2x * l2y;
1794  shape(5) = l3x * l2y;
1795  shape(3) = l1x * l3y;
1796  shape(6) = l2x * l3y;
1797  shape(2) = l3x * l3y;
1798 }
1799 
1801  DenseMatrix &dshape) const
1802 {
1803  double x = ip.x, y = ip.y;
1804  double l1x, l2x, l3x, l1y, l2y, l3y;
1805  double d1x, d2x, d3x, d1y, d2y, d3y;
1806 
1807  l1x = (1. - x) * (1. - x);
1808  l2x = 2. * x * (1. - x);
1809  l3x = x * x;
1810  l1y = (1. - y) * (1. - y);
1811  l2y = 2. * y * (1. - y);
1812  l3y = y * y;
1813 
1814  d1x = 2. * x - 2.;
1815  d2x = 2. - 4. * x;
1816  d3x = 2. * x;
1817  d1y = 2. * y - 2.;
1818  d2y = 2. - 4. * y;
1819  d3y = 2. * y;
1820 
1821  dshape(0,0) = d1x * l1y;
1822  dshape(0,1) = l1x * d1y;
1823 
1824  dshape(4,0) = d2x * l1y;
1825  dshape(4,1) = l2x * d1y;
1826 
1827  dshape(1,0) = d3x * l1y;
1828  dshape(1,1) = l3x * d1y;
1829 
1830  dshape(7,0) = d1x * l2y;
1831  dshape(7,1) = l1x * d2y;
1832 
1833  dshape(8,0) = d2x * l2y;
1834  dshape(8,1) = l2x * d2y;
1835 
1836  dshape(5,0) = d3x * l2y;
1837  dshape(5,1) = l3x * d2y;
1838 
1839  dshape(3,0) = d1x * l3y;
1840  dshape(3,1) = l1x * d3y;
1841 
1842  dshape(6,0) = d2x * l3y;
1843  dshape(6,1) = l2x * d3y;
1844 
1845  dshape(2,0) = d3x * l3y;
1846  dshape(2,1) = l3x * d3y;
1847 }
1848 
1851 {
1852  double s[9];
1853  IntegrationPoint tr_ip;
1854  Vector xx(&tr_ip.x, 2), shape(s, 9);
1855 
1856  for (int i = 0; i < 9; i++)
1857  {
1858  Trans.Transform(Nodes.IntPoint(i), xx);
1859  CalcShape(tr_ip, shape);
1860  for (int j = 0; j < 9; j++)
1861  if (fabs(I(i,j) = s[j]) < 1.0e-12)
1862  {
1863  I(i,j) = 0.0;
1864  }
1865  }
1866  for (int i = 0; i < 9; i++)
1867  {
1868  double *d = &I(0,i);
1869  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1870  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1871  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1872  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1873  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1874  0.25 * (d[0] + d[1] + d[2] + d[3]);
1875  }
1876 }
1877 
1879  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
1880 {
1881  double *d = dofs;
1882 
1883  for (int i = 0; i < 9; i++)
1884  {
1885  const IntegrationPoint &ip = Nodes.IntPoint(i);
1886  Trans.SetIntPoint(&ip);
1887  d[i] = coeff.Eval(Trans, ip);
1888  }
1889  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1890  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1891  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1892  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1893  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1894  0.25 * (d[0] + d[1] + d[2] + d[3]);
1895 }
1896 
1899  Vector &dofs) const
1900 {
1901  double v[3];
1902  Vector x (v, vc.GetVDim());
1903 
1904  for (int i = 0; i < 9; i++)
1905  {
1906  const IntegrationPoint &ip = Nodes.IntPoint(i);
1907  Trans.SetIntPoint(&ip);
1908  vc.Eval (x, Trans, ip);
1909  for (int j = 0; j < x.Size(); j++)
1910  {
1911  dofs(9*j+i) = v[j];
1912  }
1913  }
1914  for (int j = 0; j < x.Size(); j++)
1915  {
1916  double *d = &dofs(9*j);
1917 
1918  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1919  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1920  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1921  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1922  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1923  0.25 * (d[0] + d[1] + d[2] + d[3]);
1924  }
1925 }
1926 
1927 
1929  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1930 {
1931  const double p1 = 0.5*(1.-sqrt(3./5.));
1932 
1933  Nodes.IntPoint(0).x = p1;
1934  Nodes.IntPoint(0).y = p1;
1935  Nodes.IntPoint(4).x = 0.5;
1936  Nodes.IntPoint(4).y = p1;
1937  Nodes.IntPoint(1).x = 1.-p1;
1938  Nodes.IntPoint(1).y = p1;
1939  Nodes.IntPoint(7).x = p1;
1940  Nodes.IntPoint(7).y = 0.5;
1941  Nodes.IntPoint(8).x = 0.5;
1942  Nodes.IntPoint(8).y = 0.5;
1943  Nodes.IntPoint(5).x = 1.-p1;
1944  Nodes.IntPoint(5).y = 0.5;
1945  Nodes.IntPoint(3).x = p1;
1946  Nodes.IntPoint(3).y = 1.-p1;
1947  Nodes.IntPoint(6).x = 0.5;
1948  Nodes.IntPoint(6).y = 1.-p1;
1949  Nodes.IntPoint(2).x = 1.-p1;
1950  Nodes.IntPoint(2).y = 1.-p1;
1951 }
1952 
1954  Vector &shape) const
1955 {
1956  const double a = sqrt(5./3.);
1957  const double p1 = 0.5*(1.-sqrt(3./5.));
1958 
1959  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1960  double l1x, l2x, l3x, l1y, l2y, l3y;
1961 
1962  l1x = (x - 1.) * (2. * x - 1);
1963  l2x = 4. * x * (1. - x);
1964  l3x = x * (2. * x - 1.);
1965  l1y = (y - 1.) * (2. * y - 1);
1966  l2y = 4. * y * (1. - y);
1967  l3y = y * (2. * y - 1.);
1968 
1969  shape(0) = l1x * l1y;
1970  shape(4) = l2x * l1y;
1971  shape(1) = l3x * l1y;
1972  shape(7) = l1x * l2y;
1973  shape(8) = l2x * l2y;
1974  shape(5) = l3x * l2y;
1975  shape(3) = l1x * l3y;
1976  shape(6) = l2x * l3y;
1977  shape(2) = l3x * l3y;
1978 }
1979 
1981  DenseMatrix &dshape) const
1982 {
1983  const double a = sqrt(5./3.);
1984  const double p1 = 0.5*(1.-sqrt(3./5.));
1985 
1986  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1987  double l1x, l2x, l3x, l1y, l2y, l3y;
1988  double d1x, d2x, d3x, d1y, d2y, d3y;
1989 
1990  l1x = (x - 1.) * (2. * x - 1);
1991  l2x = 4. * x * (1. - x);
1992  l3x = x * (2. * x - 1.);
1993  l1y = (y - 1.) * (2. * y - 1);
1994  l2y = 4. * y * (1. - y);
1995  l3y = y * (2. * y - 1.);
1996 
1997  d1x = a * (4. * x - 3.);
1998  d2x = a * (4. - 8. * x);
1999  d3x = a * (4. * x - 1.);
2000  d1y = a * (4. * y - 3.);
2001  d2y = a * (4. - 8. * y);
2002  d3y = a * (4. * y - 1.);
2003 
2004  dshape(0,0) = d1x * l1y;
2005  dshape(0,1) = l1x * d1y;
2006 
2007  dshape(4,0) = d2x * l1y;
2008  dshape(4,1) = l2x * d1y;
2009 
2010  dshape(1,0) = d3x * l1y;
2011  dshape(1,1) = l3x * d1y;
2012 
2013  dshape(7,0) = d1x * l2y;
2014  dshape(7,1) = l1x * d2y;
2015 
2016  dshape(8,0) = d2x * l2y;
2017  dshape(8,1) = l2x * d2y;
2018 
2019  dshape(5,0) = d3x * l2y;
2020  dshape(5,1) = l3x * d2y;
2021 
2022  dshape(3,0) = d1x * l3y;
2023  dshape(3,1) = l1x * d3y;
2024 
2025  dshape(6,0) = d2x * l3y;
2026  dshape(6,1) = l2x * d3y;
2027 
2028  dshape(2,0) = d3x * l3y;
2029  dshape(2,1) = l3x * d3y;
2030 }
2031 
2033  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
2034 {
2035  Nodes.IntPoint(0).x = 0.;
2036  Nodes.IntPoint(0).y = 0.;
2037  Nodes.IntPoint(1).x = 1.;
2038  Nodes.IntPoint(1).y = 0.;
2039  Nodes.IntPoint(2).x = 1.;
2040  Nodes.IntPoint(2).y = 1.;
2041  Nodes.IntPoint(3).x = 0.;
2042  Nodes.IntPoint(3).y = 1.;
2043  Nodes.IntPoint(4).x = 1./3.;
2044  Nodes.IntPoint(4).y = 0.;
2045  Nodes.IntPoint(5).x = 2./3.;
2046  Nodes.IntPoint(5).y = 0.;
2047  Nodes.IntPoint(6).x = 1.;
2048  Nodes.IntPoint(6).y = 1./3.;
2049  Nodes.IntPoint(7).x = 1.;
2050  Nodes.IntPoint(7).y = 2./3.;
2051  Nodes.IntPoint(8).x = 2./3.;
2052  Nodes.IntPoint(8).y = 1.;
2053  Nodes.IntPoint(9).x = 1./3.;
2054  Nodes.IntPoint(9).y = 1.;
2055  Nodes.IntPoint(10).x = 0.;
2056  Nodes.IntPoint(10).y = 2./3.;
2057  Nodes.IntPoint(11).x = 0.;
2058  Nodes.IntPoint(11).y = 1./3.;
2059  Nodes.IntPoint(12).x = 1./3.;
2060  Nodes.IntPoint(12).y = 1./3.;
2061  Nodes.IntPoint(13).x = 2./3.;
2062  Nodes.IntPoint(13).y = 1./3.;
2063  Nodes.IntPoint(14).x = 1./3.;
2064  Nodes.IntPoint(14).y = 2./3.;
2065  Nodes.IntPoint(15).x = 2./3.;
2066  Nodes.IntPoint(15).y = 2./3.;
2067 }
2068 
2070  const IntegrationPoint &ip, Vector &shape) const
2071 {
2072  double x = ip.x, y = ip.y;
2073 
2074  double w1x, w2x, w3x, w1y, w2y, w3y;
2075  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2076 
2077  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2078  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2079 
2080  l0x = (- 4.5) * w1x * w2x * w3x;
2081  l1x = ( 13.5) * x * w2x * w3x;
2082  l2x = (-13.5) * x * w1x * w3x;
2083  l3x = ( 4.5) * x * w1x * w2x;
2084 
2085  l0y = (- 4.5) * w1y * w2y * w3y;
2086  l1y = ( 13.5) * y * w2y * w3y;
2087  l2y = (-13.5) * y * w1y * w3y;
2088  l3y = ( 4.5) * y * w1y * w2y;
2089 
2090  shape(0) = l0x * l0y;
2091  shape(1) = l3x * l0y;
2092  shape(2) = l3x * l3y;
2093  shape(3) = l0x * l3y;
2094  shape(4) = l1x * l0y;
2095  shape(5) = l2x * l0y;
2096  shape(6) = l3x * l1y;
2097  shape(7) = l3x * l2y;
2098  shape(8) = l2x * l3y;
2099  shape(9) = l1x * l3y;
2100  shape(10) = l0x * l2y;
2101  shape(11) = l0x * l1y;
2102  shape(12) = l1x * l1y;
2103  shape(13) = l2x * l1y;
2104  shape(14) = l1x * l2y;
2105  shape(15) = l2x * l2y;
2106 }
2107 
2109  const IntegrationPoint &ip, DenseMatrix &dshape) const
2110 {
2111  double x = ip.x, y = ip.y;
2112 
2113  double w1x, w2x, w3x, w1y, w2y, w3y;
2114  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2115  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
2116 
2117  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2118  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2119 
2120  l0x = (- 4.5) * w1x * w2x * w3x;
2121  l1x = ( 13.5) * x * w2x * w3x;
2122  l2x = (-13.5) * x * w1x * w3x;
2123  l3x = ( 4.5) * x * w1x * w2x;
2124 
2125  l0y = (- 4.5) * w1y * w2y * w3y;
2126  l1y = ( 13.5) * y * w2y * w3y;
2127  l2y = (-13.5) * y * w1y * w3y;
2128  l3y = ( 4.5) * y * w1y * w2y;
2129 
2130  d0x = -5.5 + ( 18. - 13.5 * x) * x;
2131  d1x = 9. + (-45. + 40.5 * x) * x;
2132  d2x = -4.5 + ( 36. - 40.5 * x) * x;
2133  d3x = 1. + (- 9. + 13.5 * x) * x;
2134 
2135  d0y = -5.5 + ( 18. - 13.5 * y) * y;
2136  d1y = 9. + (-45. + 40.5 * y) * y;
2137  d2y = -4.5 + ( 36. - 40.5 * y) * y;
2138  d3y = 1. + (- 9. + 13.5 * y) * y;
2139 
2140  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
2141  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
2142  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
2143  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
2144  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
2145  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
2146  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
2147  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
2148  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
2149  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
2150  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
2151  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
2152  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
2153  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
2154  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
2155  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
2156 }
2157 
2159  const IntegrationPoint &ip, DenseMatrix &h) const
2160 {
2161  double x = ip.x, y = ip.y;
2162 
2163  double w1x, w2x, w3x, w1y, w2y, w3y;
2164  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
2165  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
2166  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
2167 
2168  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
2169  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
2170 
2171  l0x = (- 4.5) * w1x * w2x * w3x;
2172  l1x = ( 13.5) * x * w2x * w3x;
2173  l2x = (-13.5) * x * w1x * w3x;
2174  l3x = ( 4.5) * x * w1x * w2x;
2175 
2176  l0y = (- 4.5) * w1y * w2y * w3y;
2177  l1y = ( 13.5) * y * w2y * w3y;
2178  l2y = (-13.5) * y * w1y * w3y;
2179  l3y = ( 4.5) * y * w1y * w2y;
2180 
2181  d0x = -5.5 + ( 18. - 13.5 * x) * x;
2182  d1x = 9. + (-45. + 40.5 * x) * x;
2183  d2x = -4.5 + ( 36. - 40.5 * x) * x;
2184  d3x = 1. + (- 9. + 13.5 * x) * x;
2185 
2186  d0y = -5.5 + ( 18. - 13.5 * y) * y;
2187  d1y = 9. + (-45. + 40.5 * y) * y;
2188  d2y = -4.5 + ( 36. - 40.5 * y) * y;
2189  d3y = 1. + (- 9. + 13.5 * y) * y;
2190 
2191  h0x = -27. * x + 18.;
2192  h1x = 81. * x - 45.;
2193  h2x = -81. * x + 36.;
2194  h3x = 27. * x - 9.;
2195 
2196  h0y = -27. * y + 18.;
2197  h1y = 81. * y - 45.;
2198  h2y = -81. * y + 36.;
2199  h3y = 27. * y - 9.;
2200 
2201  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
2202  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
2203  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
2204  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
2205  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
2206  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
2207  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
2208  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
2209  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
2210  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
2211  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
2212  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
2213  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
2214  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
2215  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
2216  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
2217 }
2218 
2219 
2221  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
2222 {
2223  Nodes.IntPoint(0).x = 0.0;
2224  Nodes.IntPoint(1).x = 1.0;
2225  Nodes.IntPoint(2).x = 0.33333333333333333333;
2226  Nodes.IntPoint(3).x = 0.66666666666666666667;
2227 }
2228 
2230  Vector &shape) const
2231 {
2232  double x = ip.x;
2233  double l1 = x,
2234  l2 = (1.0-x),
2235  l3 = (0.33333333333333333333-x),
2236  l4 = (0.66666666666666666667-x);
2237 
2238  shape(0) = 4.5 * l2 * l3 * l4;
2239  shape(1) = 4.5 * l1 * l3 * l4;
2240  shape(2) = 13.5 * l1 * l2 * l4;
2241  shape(3) = -13.5 * l1 * l2 * l3;
2242 }
2243 
2245  DenseMatrix &dshape) const
2246 {
2247  double x = ip.x;
2248 
2249  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
2250  dshape(1,0) = 1. - x * (9. - 13.5 * x);
2251  dshape(2,0) = 9. - x * (45. - 40.5 * x);
2252  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
2253 }
2254 
2255 
2257  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
2258 {
2259  Nodes.IntPoint(0).x = 0.0;
2260  Nodes.IntPoint(0).y = 0.0;
2261  Nodes.IntPoint(1).x = 1.0;
2262  Nodes.IntPoint(1).y = 0.0;
2263  Nodes.IntPoint(2).x = 0.0;
2264  Nodes.IntPoint(2).y = 1.0;
2265  Nodes.IntPoint(3).x = 0.33333333333333333333;
2266  Nodes.IntPoint(3).y = 0.0;
2267  Nodes.IntPoint(4).x = 0.66666666666666666667;
2268  Nodes.IntPoint(4).y = 0.0;
2269  Nodes.IntPoint(5).x = 0.66666666666666666667;
2270  Nodes.IntPoint(5).y = 0.33333333333333333333;
2271  Nodes.IntPoint(6).x = 0.33333333333333333333;
2272  Nodes.IntPoint(6).y = 0.66666666666666666667;
2273  Nodes.IntPoint(7).x = 0.0;
2274  Nodes.IntPoint(7).y = 0.66666666666666666667;
2275  Nodes.IntPoint(8).x = 0.0;
2276  Nodes.IntPoint(8).y = 0.33333333333333333333;
2277  Nodes.IntPoint(9).x = 0.33333333333333333333;
2278  Nodes.IntPoint(9).y = 0.33333333333333333333;
2279 }
2280 
2282  Vector &shape) const
2283 {
2284  double x = ip.x, y = ip.y;
2285  double l1 = (-1. + x + y),
2286  lx = (-1. + 3.*x),
2287  ly = (-1. + 3.*y);
2288 
2289  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
2290  shape(1) = 0.5*x*(lx - 1.)*lx;
2291  shape(2) = 0.5*y*(-1. + ly)*ly;
2292  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
2293  shape(4) = -4.5*x*lx*l1;
2294  shape(5) = 4.5*x*lx*y;
2295  shape(6) = 4.5*x*y*ly;
2296  shape(7) = -4.5*y*l1*ly;
2297  shape(8) = 4.5*y*l1*(1. + 3.*l1);
2298  shape(9) = -27.*x*y*l1;
2299 }
2300 
2302  DenseMatrix &dshape) const
2303 {
2304  double x = ip.x, y = ip.y;
2305 
2306  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2307  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
2308  dshape(2,0) = 0.;
2309  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
2310  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
2311  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
2312  dshape(6,0) = 4.5*y*(-1. + 3.*y);
2313  dshape(7,0) = 4.5*(1. - 3.*y)*y;
2314  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
2315  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
2316 
2317  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2318  dshape(1,1) = 0.;
2319  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
2320  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
2321  dshape(4,1) = 4.5*(1. - 3.*x)*x;
2322  dshape(5,1) = 4.5*x*(-1. + 3.*x);
2323  dshape(6,1) = 4.5*x*(-1. + 6.*y);
2324  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
2325  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
2326  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
2327 }
2328 
2330  DenseMatrix &h) const
2331 {
2332  double x = ip.x, y = ip.y;
2333 
2334  h(0,0) = 18.-27.*(x+y);
2335  h(0,1) = 18.-27.*(x+y);
2336  h(0,2) = 18.-27.*(x+y);
2337 
2338  h(1,0) = -9.+27.*x;
2339  h(1,1) = 0.;
2340  h(1,2) = 0.;
2341 
2342  h(2,0) = 0.;
2343  h(2,1) = 0.;
2344  h(2,2) = -9.+27.*y;
2345 
2346  h(3,0) = -45.+81.*x+54.*y;
2347  h(3,1) = -22.5+54.*x+27.*y;
2348  h(3,2) = 27.*x;
2349 
2350  h(4,0) = 36.-81.*x-27.*y;
2351  h(4,1) = 4.5-27.*x;
2352  h(4,2) = 0.;
2353 
2354  h(5,0) = 27.*y;
2355  h(5,1) = -4.5+27.*x;
2356  h(5,2) = 0.;
2357 
2358  h(6,0) = 0.;
2359  h(6,1) = -4.5+27.*y;
2360  h(6,2) = 27.*x;
2361 
2362  h(7,0) = 0.;
2363  h(7,1) = 4.5-27.*y;
2364  h(7,2) = 36.-27.*x-81.*y;
2365 
2366  h(8,0) = 27.*y;
2367  h(8,1) = -22.5+27.*x+54.*y;
2368  h(8,2) = -45.+54.*x+81.*y;
2369 
2370  h(9,0) = -54.*y;
2371  h(9,1) = 27.-54.*(x+y);
2372  h(9,2) = -54.*x;
2373 }
2374 
2375 
2377  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
2378 {
2379  Nodes.IntPoint(0).x = 0;
2380  Nodes.IntPoint(0).y = 0;
2381  Nodes.IntPoint(0).z = 0;
2382  Nodes.IntPoint(1).x = 1.;
2383  Nodes.IntPoint(1).y = 0;
2384  Nodes.IntPoint(1).z = 0;
2385  Nodes.IntPoint(2).x = 0;
2386  Nodes.IntPoint(2).y = 1.;
2387  Nodes.IntPoint(2).z = 0;
2388  Nodes.IntPoint(3).x = 0;
2389  Nodes.IntPoint(3).y = 0;
2390  Nodes.IntPoint(3).z = 1.;
2391  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
2392  Nodes.IntPoint(4).y = 0;
2393  Nodes.IntPoint(4).z = 0;
2394  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
2395  Nodes.IntPoint(5).y = 0;
2396  Nodes.IntPoint(5).z = 0;
2397  Nodes.IntPoint(6).x = 0;
2398  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
2399  Nodes.IntPoint(6).z = 0;
2400  Nodes.IntPoint(7).x = 0;
2401  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
2402  Nodes.IntPoint(7).z = 0;
2403  Nodes.IntPoint(8).x = 0;
2404  Nodes.IntPoint(8).y = 0;
2405  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
2406  Nodes.IntPoint(9).x = 0;
2407  Nodes.IntPoint(9).y = 0;
2408  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
2409  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
2410  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
2411  Nodes.IntPoint(10).z = 0;
2412  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
2413  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
2414  Nodes.IntPoint(11).z = 0;
2415  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
2416  Nodes.IntPoint(12).y = 0;
2417  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
2418  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
2419  Nodes.IntPoint(13).y = 0;
2420  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
2421  Nodes.IntPoint(14).x = 0;
2422  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
2423  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
2424  Nodes.IntPoint(15).x = 0;
2425  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
2426  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
2427  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
2428  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
2429  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
2430  Nodes.IntPoint(17).x = 0;
2431  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
2432  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
2433  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
2434  Nodes.IntPoint(18).y = 0;
2435  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
2436  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
2437  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
2438  Nodes.IntPoint(19).z = 0;
2439 }
2440 
2442  Vector &shape) const
2443 {
2444  double x = ip.x, y = ip.y, z = ip.z;
2445 
2446  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
2447  (-1 + 3*x + 3*y + 3*z))/2.;
2448  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2449  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
2450  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
2451  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2452  shape(19) = -27*x*y*(-1 + x + y + z);
2453  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
2454  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
2455  shape(11) = (9*x*y*(-1 + 3*y))/2.;
2456  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
2457  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2458  shape(18) = -27*x*z*(-1 + x + y + z);
2459  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
2460  shape(17) = -27*y*z*(-1 + x + y + z);
2461  shape(16) = 27*x*y*z;
2462  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
2463  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
2464  shape(13) = (9*x*z*(-1 + 3*z))/2.;
2465  shape(15) = (9*y*z*(-1 + 3*z))/2.;
2466  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
2467 }
2468 
2470  DenseMatrix &dshape) const
2471 {
2472  double x = ip.x, y = ip.y, z = ip.z;
2473 
2474  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2475  x*(-4 + 6*y + 6*z)))/2.;
2476  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2477  x*(-4 + 6*y + 6*z)))/2.;
2478  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2479  x*(-4 + 6*y + 6*z)))/2.;
2480  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
2481  2*x*(-5 + 6*y + 6*z)))/2.;
2482  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2483  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2484  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
2485  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
2486  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
2487  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
2488  dshape(1,1) = 0;
2489  dshape(1,2) = 0;
2490  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2491  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
2492  x*(-5 + 12*y + 6*z)))/2.;
2493  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2494  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
2495  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
2496  dshape(19,2) = -27*x*y;
2497  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
2498  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
2499  dshape(10,2) = 0;
2500  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
2501  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
2502  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
2503  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
2504  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
2505  dshape(11,2) = 0;
2506  dshape(2,0) = 0;
2507  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
2508  dshape(2,2) = 0;
2509  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2510  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2511  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
2512  x*(-5 + 6*y + 12*z)))/2.;
2513  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
2514  dshape(18,1) = -27*x*z;
2515  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
2516  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
2517  dshape(12,1) = 0;
2518  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
2519  dshape(17,0) = -27*y*z;
2520  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
2521  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
2522  dshape(16,0) = 27*y*z;
2523  dshape(16,1) = 27*x*z;
2524  dshape(16,2) = 27*x*y;
2525  dshape(14,0) = 0;
2526  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
2527  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
2528  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
2529  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
2530  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
2531  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
2532  dshape(13,1) = 0;
2533  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
2534  dshape(15,0) = 0;
2535  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
2536  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
2537  dshape(3,0) = 0;
2538  dshape(3,1) = 0;
2539  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
2540 }
2541 
2542 
2544  : NodalFiniteElement(2, Geometry::TRIANGLE, 1, 0)
2545 {
2546  Nodes.IntPoint(0).x = 0.333333333333333333;
2547  Nodes.IntPoint(0).y = 0.333333333333333333;
2548 }
2549 
2551  Vector &shape) const
2552 {
2553  shape(0) = 1.0;
2554 }
2555 
2557  DenseMatrix &dshape) const
2558 {
2559  dshape(0,0) = 0.0;
2560  dshape(0,1) = 0.0;
2561 }
2562 
2563 
2565  : NodalFiniteElement(2, Geometry::SQUARE, 1, 0, FunctionSpace::Qk)
2566 {
2567  Nodes.IntPoint(0).x = 0.5;
2568  Nodes.IntPoint(0).y = 0.5;
2569 }
2570 
2572  Vector &shape) const
2573 {
2574  shape(0) = 1.0;
2575 }
2576 
2578  DenseMatrix &dshape) const
2579 {
2580  dshape(0,0) = 0.0;
2581  dshape(0,1) = 0.0;
2582 }
2583 
2584 
2586  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
2587 {
2588  Nodes.IntPoint(0).x = 0.0;
2589  Nodes.IntPoint(0).y = 0.0;
2590  Nodes.IntPoint(0).z = 0.0;
2591  Nodes.IntPoint(1).x = 1.0;
2592  Nodes.IntPoint(1).y = 0.0;
2593  Nodes.IntPoint(1).z = 0.0;
2594  Nodes.IntPoint(2).x = 0.0;
2595  Nodes.IntPoint(2).y = 1.0;
2596  Nodes.IntPoint(2).z = 0.0;
2597  Nodes.IntPoint(3).x = 0.0;
2598  Nodes.IntPoint(3).y = 0.0;
2599  Nodes.IntPoint(3).z = 1.0;
2600 }
2601 
2603  Vector &shape) const
2604 {
2605  shape(0) = 1. - ip.x - ip.y - ip.z;
2606  shape(1) = ip.x;
2607  shape(2) = ip.y;
2608  shape(3) = ip.z;
2609 }
2610 
2612  DenseMatrix &dshape) const
2613 {
2614  if (dshape.Height() == 4)
2615  {
2616  double *A = &dshape(0,0);
2617  A[0] = -1.; A[4] = -1.; A[8] = -1.;
2618  A[1] = 1.; A[5] = 0.; A[9] = 0.;
2619  A[2] = 0.; A[6] = 1.; A[10] = 0.;
2620  A[3] = 0.; A[7] = 0.; A[11] = 1.;
2621  }
2622  else
2623  {
2624  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
2625  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
2626  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
2627  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
2628  }
2629 }
2630 
2631 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
2632 const
2633 {
2634  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
2635 
2636  *ndofs = 3;
2637  *dofs = face_dofs[face];
2638 }
2639 
2640 
2642  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
2643 {
2644  Nodes.IntPoint(0).x = 0.0;
2645  Nodes.IntPoint(0).y = 0.0;
2646  Nodes.IntPoint(0).z = 0.0;
2647  Nodes.IntPoint(1).x = 1.0;
2648  Nodes.IntPoint(1).y = 0.0;
2649  Nodes.IntPoint(1).z = 0.0;
2650  Nodes.IntPoint(2).x = 0.0;
2651  Nodes.IntPoint(2).y = 1.0;
2652  Nodes.IntPoint(2).z = 0.0;
2653  Nodes.IntPoint(3).x = 0.0;
2654  Nodes.IntPoint(3).y = 0.0;
2655  Nodes.IntPoint(3).z = 1.0;
2656  Nodes.IntPoint(4).x = 0.5;
2657  Nodes.IntPoint(4).y = 0.0;
2658  Nodes.IntPoint(4).z = 0.0;
2659  Nodes.IntPoint(5).x = 0.0;
2660  Nodes.IntPoint(5).y = 0.5;
2661  Nodes.IntPoint(5).z = 0.0;
2662  Nodes.IntPoint(6).x = 0.0;
2663  Nodes.IntPoint(6).y = 0.0;
2664  Nodes.IntPoint(6).z = 0.5;
2665  Nodes.IntPoint(7).x = 0.5;
2666  Nodes.IntPoint(7).y = 0.5;
2667  Nodes.IntPoint(7).z = 0.0;
2668  Nodes.IntPoint(8).x = 0.5;
2669  Nodes.IntPoint(8).y = 0.0;
2670  Nodes.IntPoint(8).z = 0.5;
2671  Nodes.IntPoint(9).x = 0.0;
2672  Nodes.IntPoint(9).y = 0.5;
2673  Nodes.IntPoint(9).z = 0.5;
2674 }
2675 
2677  Vector &shape) const
2678 {
2679  double L0, L1, L2, L3;
2680 
2681  L0 = 1. - ip.x - ip.y - ip.z;
2682  L1 = ip.x;
2683  L2 = ip.y;
2684  L3 = ip.z;
2685 
2686  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
2687  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
2688  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
2689  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
2690  shape(4) = 4.0 * L0 * L1;
2691  shape(5) = 4.0 * L0 * L2;
2692  shape(6) = 4.0 * L0 * L3;
2693  shape(7) = 4.0 * L1 * L2;
2694  shape(8) = 4.0 * L1 * L3;
2695  shape(9) = 4.0 * L2 * L3;
2696 }
2697 
2699  DenseMatrix &dshape) const
2700 {
2701  double x, y, z, L0;
2702 
2703  x = ip.x;
2704  y = ip.y;
2705  z = ip.z;
2706  L0 = 1.0 - x - y - z;
2707 
2708  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
2709  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
2710  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
2711  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
2712  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
2713  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
2714  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
2715  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
2716  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
2717  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
2718 }
2719 
2721  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
2722 {
2723  Nodes.IntPoint(0).x = 0.0;
2724  Nodes.IntPoint(0).y = 0.0;
2725  Nodes.IntPoint(0).z = 0.0;
2726 
2727  Nodes.IntPoint(1).x = 1.0;
2728  Nodes.IntPoint(1).y = 0.0;
2729  Nodes.IntPoint(1).z = 0.0;
2730 
2731  Nodes.IntPoint(2).x = 1.0;
2732  Nodes.IntPoint(2).y = 1.0;
2733  Nodes.IntPoint(2).z = 0.0;
2734 
2735  Nodes.IntPoint(3).x = 0.0;
2736  Nodes.IntPoint(3).y = 1.0;
2737  Nodes.IntPoint(3).z = 0.0;
2738 
2739  Nodes.IntPoint(4).x = 0.0;
2740  Nodes.IntPoint(4).y = 0.0;
2741  Nodes.IntPoint(4).z = 1.0;
2742 
2743  Nodes.IntPoint(5).x = 1.0;
2744  Nodes.IntPoint(5).y = 0.0;
2745  Nodes.IntPoint(5).z = 1.0;
2746 
2747  Nodes.IntPoint(6).x = 1.0;
2748  Nodes.IntPoint(6).y = 1.0;
2749  Nodes.IntPoint(6).z = 1.0;
2750 
2751  Nodes.IntPoint(7).x = 0.0;
2752  Nodes.IntPoint(7).y = 1.0;
2753  Nodes.IntPoint(7).z = 1.0;
2754 }
2755 
2757  Vector &shape) const
2758 {
2759  double x = ip.x, y = ip.y, z = ip.z;
2760  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2761 
2762  shape(0) = ox * oy * oz;
2763  shape(1) = x * oy * oz;
2764  shape(2) = x * y * oz;
2765  shape(3) = ox * y * oz;
2766  shape(4) = ox * oy * z;
2767  shape(5) = x * oy * z;
2768  shape(6) = x * y * z;
2769  shape(7) = ox * y * z;
2770 }
2771 
2773  DenseMatrix &dshape) const
2774 {
2775  double x = ip.x, y = ip.y, z = ip.z;
2776  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2777 
2778  dshape(0,0) = - oy * oz;
2779  dshape(0,1) = - ox * oz;
2780  dshape(0,2) = - ox * oy;
2781 
2782  dshape(1,0) = oy * oz;
2783  dshape(1,1) = - x * oz;
2784  dshape(1,2) = - x * oy;
2785 
2786  dshape(2,0) = y * oz;
2787  dshape(2,1) = x * oz;
2788  dshape(2,2) = - x * y;
2789 
2790  dshape(3,0) = - y * oz;
2791  dshape(3,1) = ox * oz;
2792  dshape(3,2) = - ox * y;
2793 
2794  dshape(4,0) = - oy * z;
2795  dshape(4,1) = - ox * z;
2796  dshape(4,2) = ox * oy;
2797 
2798  dshape(5,0) = oy * z;
2799  dshape(5,1) = - x * z;
2800  dshape(5,2) = x * oy;
2801 
2802  dshape(6,0) = y * z;
2803  dshape(6,1) = x * z;
2804  dshape(6,2) = x * y;
2805 
2806  dshape(7,0) = - y * z;
2807  dshape(7,1) = ox * z;
2808  dshape(7,2) = ox * y;
2809 }
2810 
2811 
2813  : NodalFiniteElement(1, Geometry::SEGMENT, 1, Ord) // defaul Ord = 0
2814 {
2815  Nodes.IntPoint(0).x = 0.5;
2816 }
2817 
2819  Vector &shape) const
2820 {
2821  shape(0) = 1.0;
2822 }
2823 
2825  DenseMatrix &dshape) const
2826 {
2827  dshape(0,0) = 0.0;
2828 }
2829 
2831  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
2832 {
2833  Nodes.IntPoint(0).x = 0.5;
2834  Nodes.IntPoint(0).y = 0.0;
2835  Nodes.IntPoint(1).x = 0.5;
2836  Nodes.IntPoint(1).y = 0.5;
2837  Nodes.IntPoint(2).x = 0.0;
2838  Nodes.IntPoint(2).y = 0.5;
2839 }
2840 
2842  Vector &shape) const
2843 {
2844  shape(0) = 1.0 - 2.0 * ip.y;
2845  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
2846  shape(2) = 1.0 - 2.0 * ip.x;
2847 }
2848 
2850  DenseMatrix &dshape) const
2851 {
2852  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
2853  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
2854  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
2855 }
2856 
2858 // the FunctionSpace should be rotated (45 degrees) Q_1
2859 // i.e. the span of { 1, x, y, x^2 - y^2 }
2860  : NodalFiniteElement(2, Geometry::SQUARE, 4, 2, FunctionSpace::Qk)
2861 {
2862  Nodes.IntPoint(0).x = 0.5;
2863  Nodes.IntPoint(0).y = 0.0;
2864  Nodes.IntPoint(1).x = 1.0;
2865  Nodes.IntPoint(1).y = 0.5;
2866  Nodes.IntPoint(2).x = 0.5;
2867  Nodes.IntPoint(2).y = 1.0;
2868  Nodes.IntPoint(3).x = 0.0;
2869  Nodes.IntPoint(3).y = 0.5;
2870 }
2871 
2873  Vector &shape) const
2874 {
2875  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
2876 
2877  shape(0) = l2 * l3;
2878  shape(1) = l1 * l3;
2879  shape(2) = l1 * l4;
2880  shape(3) = l2 * l4;
2881 }
2882 
2884  DenseMatrix &dshape) const
2885 {
2886  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
2887 
2888  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
2889  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
2890  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
2891  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
2892 }
2893 
2894 
2896  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
2897 {
2898  Nodes.IntPoint(0).x = 0.5;
2899  Nodes.IntPoint(0).y = 0.0;
2900  Nodes.IntPoint(1).x = 0.5;
2901  Nodes.IntPoint(1).y = 0.5;
2902  Nodes.IntPoint(2).x = 0.0;
2903  Nodes.IntPoint(2).y = 0.5;
2904 }
2905 
2907  DenseMatrix &shape) const
2908 {
2909  double x = ip.x, y = ip.y;
2910 
2911  shape(0,0) = x;
2912  shape(0,1) = y - 1.;
2913  shape(1,0) = x;
2914  shape(1,1) = y;
2915  shape(2,0) = x - 1.;
2916  shape(2,1) = y;
2917 }
2918 
2920  Vector &divshape) const
2921 {
2922  divshape(0) = 2.;
2923  divshape(1) = 2.;
2924  divshape(2) = 2.;
2925 }
2926 
2927 const double RT0TriangleFiniteElement::nk[3][2] =
2928 { {0, -1}, {1, 1}, {-1, 0} };
2929 
2932 {
2933  int k, j;
2934 #ifdef MFEM_THREAD_SAFE
2936  DenseMatrix Jinv(Dim);
2937 #endif
2938 
2939 #ifdef MFEM_DEBUG
2940  for (k = 0; k < 3; k++)
2941  {
2943  for (j = 0; j < 3; j++)
2944  {
2945  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2946  if (j == k) { d -= 1.0; }
2947  if (fabs(d) > 1.0e-12)
2948  {
2949  mfem::err << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
2950  " k = " << k << ", j = " << j << ", d = " << d << endl;
2951  mfem_error();
2952  }
2953  }
2954  }
2955 #endif
2956 
2957  IntegrationPoint ip;
2958  ip.x = ip.y = 0.0;
2959  Trans.SetIntPoint (&ip);
2960  // Trans must be linear
2961  // set Jinv = |J| J^{-t} = adj(J)^t
2962  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2963  double vk[2];
2964  Vector xk (vk, 2);
2965 
2966  for (k = 0; k < 3; k++)
2967  {
2968  Trans.Transform (Nodes.IntPoint (k), xk);
2969  ip.x = vk[0]; ip.y = vk[1];
2970  CalcVShape (ip, vshape);
2971  // vk = |J| J^{-t} nk
2972  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2973  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2974  for (j = 0; j < 3; j++)
2975  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2976  {
2977  I(k,j) = 0.0;
2978  }
2979  }
2980 }
2981 
2984  Vector &dofs) const
2985 {
2986  double vk[2];
2987  Vector xk (vk, 2);
2988 #ifdef MFEM_THREAD_SAFE
2989  DenseMatrix Jinv(Dim);
2990 #endif
2991 
2992  for (int k = 0; k < 3; k++)
2993  {
2994  Trans.SetIntPoint (&Nodes.IntPoint (k));
2995  // set Jinv = |J| J^{-t} = adj(J)^t
2996  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2997 
2998  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2999  // xk^t |J| J^{-t} nk
3000  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3001  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3002  }
3003 }
3004 
3006  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
3007 {
3008  Nodes.IntPoint(0).x = 0.5;
3009  Nodes.IntPoint(0).y = 0.0;
3010  Nodes.IntPoint(1).x = 1.0;
3011  Nodes.IntPoint(1).y = 0.5;
3012  Nodes.IntPoint(2).x = 0.5;
3013  Nodes.IntPoint(2).y = 1.0;
3014  Nodes.IntPoint(3).x = 0.0;
3015  Nodes.IntPoint(3).y = 0.5;
3016 }
3017 
3019  DenseMatrix &shape) const
3020 {
3021  double x = ip.x, y = ip.y;
3022 
3023  shape(0,0) = 0;
3024  shape(0,1) = y - 1.;
3025  shape(1,0) = x;
3026  shape(1,1) = 0;
3027  shape(2,0) = 0;
3028  shape(2,1) = y;
3029  shape(3,0) = x - 1.;
3030  shape(3,1) = 0;
3031 }
3032 
3034  Vector &divshape) const
3035 {
3036  divshape(0) = 1.;
3037  divshape(1) = 1.;
3038  divshape(2) = 1.;
3039  divshape(3) = 1.;
3040 }
3041 
3042 const double RT0QuadFiniteElement::nk[4][2] =
3043 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
3044 
3047 {
3048  int k, j;
3049 #ifdef MFEM_THREAD_SAFE
3051  DenseMatrix Jinv(Dim);
3052 #endif
3053 
3054 #ifdef MFEM_DEBUG
3055  for (k = 0; k < 4; k++)
3056  {
3058  for (j = 0; j < 4; j++)
3059  {
3060  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3061  if (j == k) { d -= 1.0; }
3062  if (fabs(d) > 1.0e-12)
3063  {
3064  mfem::err << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
3065  " k = " << k << ", j = " << j << ", d = " << d << endl;
3066  mfem_error();
3067  }
3068  }
3069  }
3070 #endif
3071 
3072  IntegrationPoint ip;
3073  ip.x = ip.y = 0.0;
3074  Trans.SetIntPoint (&ip);
3075  // Trans must be linear (more to have embedding?)
3076  // set Jinv = |J| J^{-t} = adj(J)^t
3077  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3078  double vk[2];
3079  Vector xk (vk, 2);
3080 
3081  for (k = 0; k < 4; k++)
3082  {
3083  Trans.Transform (Nodes.IntPoint (k), xk);
3084  ip.x = vk[0]; ip.y = vk[1];
3085  CalcVShape (ip, vshape);
3086  // vk = |J| J^{-t} nk
3087  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3088  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3089  for (j = 0; j < 4; j++)
3090  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3091  {
3092  I(k,j) = 0.0;
3093  }
3094  }
3095 }
3096 
3099  Vector &dofs) const
3100 {
3101  double vk[2];
3102  Vector xk (vk, 2);
3103 #ifdef MFEM_THREAD_SAFE
3104  DenseMatrix Jinv(Dim);
3105 #endif
3106 
3107  for (int k = 0; k < 4; k++)
3108  {
3109  Trans.SetIntPoint (&Nodes.IntPoint (k));
3110  // set Jinv = |J| J^{-t} = adj(J)^t
3111  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3112 
3113  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3114  // xk^t |J| J^{-t} nk
3115  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3116  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3117  }
3118 }
3119 
3121  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
3122 {
3123  Nodes.IntPoint(0).x = 0.33333333333333333333;
3124  Nodes.IntPoint(0).y = 0.0;
3125  Nodes.IntPoint(1).x = 0.66666666666666666667;
3126  Nodes.IntPoint(1).y = 0.0;
3127  Nodes.IntPoint(2).x = 0.66666666666666666667;
3128  Nodes.IntPoint(2).y = 0.33333333333333333333;
3129  Nodes.IntPoint(3).x = 0.33333333333333333333;
3130  Nodes.IntPoint(3).y = 0.66666666666666666667;
3131  Nodes.IntPoint(4).x = 0.0;
3132  Nodes.IntPoint(4).y = 0.66666666666666666667;
3133  Nodes.IntPoint(5).x = 0.0;
3134  Nodes.IntPoint(5).y = 0.33333333333333333333;
3135  Nodes.IntPoint(6).x = 0.33333333333333333333;
3136  Nodes.IntPoint(6).y = 0.33333333333333333333;
3137  Nodes.IntPoint(7).x = 0.33333333333333333333;
3138  Nodes.IntPoint(7).y = 0.33333333333333333333;
3139 }
3140 
3142  DenseMatrix &shape) const
3143 {
3144  double x = ip.x, y = ip.y;
3145 
3146  shape(0,0) = -2 * x * (-1 + x + 2 * y);
3147  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
3148  shape(1,0) = 2 * x * (x - y);
3149  shape(1,1) = 2 * (x - y) * (-1 + y);
3150  shape(2,0) = 2 * x * (-1 + 2 * x + y);
3151  shape(2,1) = 2 * y * (-1 + 2 * x + y);
3152  shape(3,0) = 2 * x * (-1 + x + 2 * y);
3153  shape(3,1) = 2 * y * (-1 + x + 2 * y);
3154  shape(4,0) = -2 * (-1 + x) * (x - y);
3155  shape(4,1) = 2 * y * (-x + y);
3156  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
3157  shape(5,1) = -2 * y * (-1 + 2 * x + y);
3158  shape(6,0) = -3 * x * (-2 + 2 * x + y);
3159  shape(6,1) = -3 * y * (-1 + 2 * x + y);
3160  shape(7,0) = -3 * x * (-1 + x + 2 * y);
3161  shape(7,1) = -3 * y * (-2 + x + 2 * y);
3162 }
3163 
3165  Vector &divshape) const
3166 {
3167  double x = ip.x, y = ip.y;
3168 
3169  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
3170  divshape(1) = 2 + 6 * x - 6 * y;
3171  divshape(2) = -4 + 12 * x + 6 * y;
3172  divshape(3) = -4 + 6 * x + 12 * y;
3173  divshape(4) = 2 - 6 * x + 6 * y;
3174  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
3175  divshape(6) = -9 * (-1 + 2 * x + y);
3176  divshape(7) = -9 * (-1 + x + 2 * y);
3177 }
3178 
3179 const double RT1TriangleFiniteElement::nk[8][2] =
3180 {
3181  { 0,-1}, { 0,-1},
3182  { 1, 1}, { 1, 1},
3183  {-1, 0}, {-1, 0},
3184  { 1, 0}, { 0, 1}
3185 };
3186 
3189 {
3190  int k, j;
3191 #ifdef MFEM_THREAD_SAFE
3193  DenseMatrix Jinv(Dim);
3194 #endif
3195 
3196 #ifdef MFEM_DEBUG
3197  for (k = 0; k < 8; k++)
3198  {
3200  for (j = 0; j < 8; j++)
3201  {
3202  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3203  if (j == k) { d -= 1.0; }
3204  if (fabs(d) > 1.0e-12)
3205  {
3206  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3207  " k = " << k << ", j = " << j << ", d = " << d << endl;
3208  mfem_error();
3209  }
3210  }
3211  }
3212 #endif
3213 
3214  IntegrationPoint ip;
3215  ip.x = ip.y = 0.0;
3216  Trans.SetIntPoint (&ip);
3217  // Trans must be linear (more to have embedding?)
3218  // set Jinv = |J| J^{-t} = adj(J)^t
3219  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3220  double vk[2];
3221  Vector xk (vk, 2);
3222 
3223  for (k = 0; k < 8; k++)
3224  {
3225  Trans.Transform (Nodes.IntPoint (k), xk);
3226  ip.x = vk[0]; ip.y = vk[1];
3227  CalcVShape (ip, vshape);
3228  // vk = |J| J^{-t} nk
3229  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3230  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3231  for (j = 0; j < 8; j++)
3232  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3233  {
3234  I(k,j) = 0.0;
3235  }
3236  }
3237 }
3238 
3241 {
3242  double vk[2];
3243  Vector xk (vk, 2);
3244 #ifdef MFEM_THREAD_SAFE
3245  DenseMatrix Jinv(Dim);
3246 #endif
3247 
3248  for (int k = 0; k < 8; k++)
3249  {
3250  Trans.SetIntPoint (&Nodes.IntPoint (k));
3251  // set Jinv = |J| J^{-t} = adj(J)^t
3252  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3253 
3254  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3255  // xk^t |J| J^{-t} nk
3256  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3257  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3258  dofs(k) *= 0.5;
3259  }
3260 }
3261 
3263  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
3264 {
3265  // y = 0
3266  Nodes.IntPoint(0).x = 1./3.;
3267  Nodes.IntPoint(0).y = 0.0;
3268  Nodes.IntPoint(1).x = 2./3.;
3269  Nodes.IntPoint(1).y = 0.0;
3270  // x = 1
3271  Nodes.IntPoint(2).x = 1.0;
3272  Nodes.IntPoint(2).y = 1./3.;
3273  Nodes.IntPoint(3).x = 1.0;
3274  Nodes.IntPoint(3).y = 2./3.;
3275  // y = 1
3276  Nodes.IntPoint(4).x = 2./3.;
3277  Nodes.IntPoint(4).y = 1.0;
3278  Nodes.IntPoint(5).x = 1./3.;
3279  Nodes.IntPoint(5).y = 1.0;
3280  // x = 0
3281  Nodes.IntPoint(6).x = 0.0;
3282  Nodes.IntPoint(6).y = 2./3.;
3283  Nodes.IntPoint(7).x = 0.0;
3284  Nodes.IntPoint(7).y = 1./3.;
3285  // x = 0.5 (interior)
3286  Nodes.IntPoint(8).x = 0.5;
3287  Nodes.IntPoint(8).y = 1./3.;
3288  Nodes.IntPoint(9).x = 0.5;
3289  Nodes.IntPoint(9).y = 2./3.;
3290  // y = 0.5 (interior)
3291  Nodes.IntPoint(10).x = 1./3.;
3292  Nodes.IntPoint(10).y = 0.5;
3293  Nodes.IntPoint(11).x = 2./3.;
3294  Nodes.IntPoint(11).y = 0.5;
3295 }
3296 
3298  DenseMatrix &shape) const
3299 {
3300  double x = ip.x, y = ip.y;
3301 
3302  // y = 0
3303  shape(0,0) = 0;
3304  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
3305  shape(1,0) = 0;
3306  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
3307  // x = 1
3308  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
3309  shape(2,1) = 0;
3310  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
3311  shape(3,1) = 0;
3312  // y = 1
3313  shape(4,0) = 0;
3314  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
3315  shape(5,0) = 0;
3316  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
3317  // x = 0
3318  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
3319  shape(6,1) = 0;
3320  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
3321  shape(7,1) = 0;
3322  // x = 0.5 (interior)
3323  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
3324  shape(8,1) = 0;
3325  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
3326  shape(9,1) = 0;
3327  // y = 0.5 (interior)
3328  shape(10,0) = 0;
3329  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
3330  shape(11,0) = 0;
3331  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
3332 }
3333 
3335  Vector &divshape) const
3336 {
3337  double x = ip.x, y = ip.y;
3338 
3339  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
3340  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
3341  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
3342  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
3343  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
3344  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
3345  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
3346  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
3347  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
3348  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
3349  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
3350  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
3351 }
3352 
3353 const double RT1QuadFiniteElement::nk[12][2] =
3354 {
3355  // y = 0
3356  {0,-1}, {0,-1},
3357  // X = 1
3358  {1, 0}, {1, 0},
3359  // y = 1
3360  {0, 1}, {0, 1},
3361  // x = 0
3362  {-1,0}, {-1,0},
3363  // x = 0.5 (interior)
3364  {1, 0}, {1, 0},
3365  // y = 0.5 (interior)
3366  {0, 1}, {0, 1}
3367 };
3368 
3371 {
3372  int k, j;
3373 #ifdef MFEM_THREAD_SAFE
3375  DenseMatrix Jinv(Dim);
3376 #endif
3377 
3378 #ifdef MFEM_DEBUG
3379  for (k = 0; k < 12; k++)
3380  {
3382  for (j = 0; j < 12; j++)
3383  {
3384  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3385  if (j == k) { d -= 1.0; }
3386  if (fabs(d) > 1.0e-12)
3387  {
3388  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3389  " k = " << k << ", j = " << j << ", d = " << d << endl;
3390  mfem_error();
3391  }
3392  }
3393  }
3394 #endif
3395 
3396  IntegrationPoint ip;
3397  ip.x = ip.y = 0.0;
3398  Trans.SetIntPoint (&ip);
3399  // Trans must be linear (more to have embedding?)
3400  // set Jinv = |J| J^{-t} = adj(J)^t
3401  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3402  double vk[2];
3403  Vector xk (vk, 2);
3404 
3405  for (k = 0; k < 12; k++)
3406  {
3407  Trans.Transform (Nodes.IntPoint (k), xk);
3408  ip.x = vk[0]; ip.y = vk[1];
3409  CalcVShape (ip, vshape);
3410  // vk = |J| J^{-t} nk
3411  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3412  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3413  for (j = 0; j < 12; j++)
3414  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3415  {
3416  I(k,j) = 0.0;
3417  }
3418  }
3419 }
3420 
3423 {
3424  double vk[2];
3425  Vector xk (vk, 2);
3426 #ifdef MFEM_THREAD_SAFE
3427  DenseMatrix Jinv(Dim);
3428 #endif
3429 
3430  for (int k = 0; k < 12; k++)
3431  {
3432  Trans.SetIntPoint (&Nodes.IntPoint (k));
3433  // set Jinv = |J| J^{-t} = adj(J)^t
3434  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3435 
3436  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3437  // xk^t |J| J^{-t} nk
3438  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3439  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3440  }
3441 }
3442 
3443 const double RT2TriangleFiniteElement::M[15][15] =
3444 {
3445  {
3446  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
3447  0, 24.442740046346700787, -16.647580015448900262, -12.,
3448  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
3449  12., 30.590320061795601049, 15.295160030897800524
3450  },
3451  {
3452  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
3453  -15., 10.5
3454  },
3455  {
3456  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
3457  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
3458  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
3459  12., -6.5903200617956010489, -3.2951600308978005244
3460  },
3461  {
3462  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
3463  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
3464  0, -3.2951600308978005244
3465  },
3466  {
3467  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
3468  36., 10.5
3469  },
3470  {
3471  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
3472  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
3473  0, 15.295160030897800524
3474  },
3475  {
3476  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
3477  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
3478  -0.76209992275549868892, 4.1189500386222506555, -12.,
3479  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
3480  12.
3481  },
3482  {
3483  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
3484  -15., -15.
3485  },
3486  {
3487  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
3488  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
3489  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
3490  30.590320061795601049, 12.
3491  },
3492  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
3493  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
3494  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
3495  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
3496  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
3497  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
3498 };
3499 
3501  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
3502 {
3503  const double p = 0.11270166537925831148;
3504 
3505  Nodes.IntPoint(0).x = p;
3506  Nodes.IntPoint(0).y = 0.0;
3507  Nodes.IntPoint(1).x = 0.5;
3508  Nodes.IntPoint(1).y = 0.0;
3509  Nodes.IntPoint(2).x = 1.-p;
3510  Nodes.IntPoint(2).y = 0.0;
3511  Nodes.IntPoint(3).x = 1.-p;
3512  Nodes.IntPoint(3).y = p;
3513  Nodes.IntPoint(4).x = 0.5;
3514  Nodes.IntPoint(4).y = 0.5;
3515  Nodes.IntPoint(5).x = p;
3516  Nodes.IntPoint(5).y = 1.-p;
3517  Nodes.IntPoint(6).x = 0.0;
3518  Nodes.IntPoint(6).y = 1.-p;
3519  Nodes.IntPoint(7).x = 0.0;
3520  Nodes.IntPoint(7).y = 0.5;
3521  Nodes.IntPoint(8).x = 0.0;
3522  Nodes.IntPoint(8).y = p;
3523  Nodes.IntPoint(9).x = 0.25;
3524  Nodes.IntPoint(9).y = 0.25;
3525  Nodes.IntPoint(10).x = 0.25;
3526  Nodes.IntPoint(10).y = 0.25;
3527  Nodes.IntPoint(11).x = 0.5;
3528  Nodes.IntPoint(11).y = 0.25;
3529  Nodes.IntPoint(12).x = 0.5;
3530  Nodes.IntPoint(12).y = 0.25;
3531  Nodes.IntPoint(13).x = 0.25;
3532  Nodes.IntPoint(13).y = 0.5;
3533  Nodes.IntPoint(14).x = 0.25;
3534  Nodes.IntPoint(14).y = 0.5;
3535 }
3536 
3538  DenseMatrix &shape) const
3539 {
3540  double x = ip.x, y = ip.y;
3541 
3542  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
3543  x*x*y, x*y*y
3544  };
3545  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
3546  x*x*y, x*y*y, y*y*y
3547  };
3548 
3549  for (int i = 0; i < 15; i++)
3550  {
3551  double cx = 0.0, cy = 0.0;
3552  for (int j = 0; j < 15; j++)
3553  {
3554  cx += M[i][j] * Bx[j];
3555  cy += M[i][j] * By[j];
3556  }
3557  shape(i,0) = cx;
3558  shape(i,1) = cy;
3559  }
3560 }
3561 
3563  Vector &divshape) const
3564 {
3565  double x = ip.x, y = ip.y;
3566 
3567  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
3568  4.*x*x, 4.*x*y, 4.*y*y
3569  };
3570 
3571  for (int i = 0; i < 15; i++)
3572  {
3573  double div = 0.0;
3574  for (int j = 0; j < 15; j++)
3575  {
3576  div += M[i][j] * DivB[j];
3577  }
3578  divshape(i) = div;
3579  }
3580 }
3581 
3582 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
3583 
3584 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
3585 
3587  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
3588 {
3589  // y = 0 (pt[0])
3590  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
3591  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
3592  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
3593  // x = 1 (pt[3])
3594  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
3595  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
3596  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
3597  // y = 1 (pt[3])
3598  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
3599  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
3600  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
3601  // x = 0 (pt[0])
3602  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
3603  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
3604  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
3605  // x = pt[1] (interior)
3606  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
3607  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
3608  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
3609  // x = pt[2] (interior)
3610  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
3611  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
3612  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
3613  // y = pt[1] (interior)
3614  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
3615  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
3616  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
3617  // y = pt[2] (interior)
3618  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
3619  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
3620  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
3621 }
3622 
3624  DenseMatrix &shape) const
3625 {
3626  double x = ip.x, y = ip.y;
3627 
3628  double ax0 = pt[0] - x;
3629  double ax1 = pt[1] - x;
3630  double ax2 = pt[2] - x;
3631  double ax3 = pt[3] - x;
3632 
3633  double by0 = dpt[0] - y;
3634  double by1 = dpt[1] - y;
3635  double by2 = dpt[2] - y;
3636 
3637  double ay0 = pt[0] - y;
3638  double ay1 = pt[1] - y;
3639  double ay2 = pt[2] - y;
3640  double ay3 = pt[3] - y;
3641 
3642  double bx0 = dpt[0] - x;
3643  double bx1 = dpt[1] - x;
3644  double bx2 = dpt[2] - x;
3645 
3646  double A01 = pt[0] - pt[1];
3647  double A02 = pt[0] - pt[2];
3648  double A12 = pt[1] - pt[2];
3649  double A03 = pt[0] - pt[3];
3650  double A13 = pt[1] - pt[3];
3651  double A23 = pt[2] - pt[3];
3652 
3653  double B01 = dpt[0] - dpt[1];
3654  double B02 = dpt[0] - dpt[2];
3655  double B12 = dpt[1] - dpt[2];
3656 
3657  double tx0 = (bx1*bx2)/(B01*B02);
3658  double tx1 = -(bx0*bx2)/(B01*B12);
3659  double tx2 = (bx0*bx1)/(B02*B12);
3660 
3661  double ty0 = (by1*by2)/(B01*B02);
3662  double ty1 = -(by0*by2)/(B01*B12);
3663  double ty2 = (by0*by1)/(B02*B12);
3664 
3665  // y = 0 (p[0])
3666  shape(0, 0) = 0;
3667  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
3668  shape(1, 0) = 0;
3669  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
3670  shape(2, 0) = 0;
3671  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
3672  // x = 1 (p[3])
3673  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
3674  shape(3, 1) = 0;
3675  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
3676  shape(4, 1) = 0;
3677  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
3678  shape(5, 1) = 0;
3679  // y = 1 (p[3])
3680  shape(6, 0) = 0;
3681  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
3682  shape(7, 0) = 0;
3683  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
3684  shape(8, 0) = 0;
3685  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
3686  // x = 0 (p[0])
3687  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
3688  shape(9, 1) = 0;
3689  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
3690  shape(10, 1) = 0;
3691  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
3692  shape(11, 1) = 0;
3693  // x = p[1] (interior)
3694  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
3695  shape(12, 1) = 0;
3696  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
3697  shape(13, 1) = 0;
3698  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
3699  shape(14, 1) = 0;
3700  // x = p[2] (interior)
3701  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
3702  shape(15, 1) = 0;
3703  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
3704  shape(16, 1) = 0;
3705  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
3706  shape(17, 1) = 0;
3707  // y = p[1] (interior)
3708  shape(18, 0) = 0;
3709  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
3710  shape(19, 0) = 0;
3711  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
3712  shape(20, 0) = 0;
3713  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
3714  // y = p[2] (interior)
3715  shape(21, 0) = 0;
3716  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
3717  shape(22, 0) = 0;
3718  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
3719  shape(23, 0) = 0;
3720  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
3721 }
3722 
3724  Vector &divshape) const
3725 {
3726  double x = ip.x, y = ip.y;
3727 
3728  double a01 = pt[0]*pt[1];
3729  double a02 = pt[0]*pt[2];
3730  double a12 = pt[1]*pt[2];
3731  double a03 = pt[0]*pt[3];
3732  double a13 = pt[1]*pt[3];
3733  double a23 = pt[2]*pt[3];
3734 
3735  double bx0 = dpt[0] - x;
3736  double bx1 = dpt[1] - x;
3737  double bx2 = dpt[2] - x;
3738 
3739  double by0 = dpt[0] - y;
3740  double by1 = dpt[1] - y;
3741  double by2 = dpt[2] - y;
3742 
3743  double A01 = pt[0] - pt[1];
3744  double A02 = pt[0] - pt[2];
3745  double A12 = pt[1] - pt[2];
3746  double A03 = pt[0] - pt[3];
3747  double A13 = pt[1] - pt[3];
3748  double A23 = pt[2] - pt[3];
3749 
3750  double A012 = pt[0] + pt[1] + pt[2];
3751  double A013 = pt[0] + pt[1] + pt[3];
3752  double A023 = pt[0] + pt[2] + pt[3];
3753  double A123 = pt[1] + pt[2] + pt[3];
3754 
3755  double B01 = dpt[0] - dpt[1];
3756  double B02 = dpt[0] - dpt[2];
3757  double B12 = dpt[1] - dpt[2];
3758 
3759  double tx0 = (bx1*bx2)/(B01*B02);
3760  double tx1 = -(bx0*bx2)/(B01*B12);
3761  double tx2 = (bx0*bx1)/(B02*B12);
3762 
3763  double ty0 = (by1*by2)/(B01*B02);
3764  double ty1 = -(by0*by2)/(B01*B12);
3765  double ty2 = (by0*by1)/(B02*B12);
3766 
3767  // y = 0 (p[0])
3768  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
3769  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
3770  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
3771  // x = 1 (p[3])
3772  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
3773  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
3774  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
3775  // y = 1 (p[3])
3776  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
3777  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
3778  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
3779  // x = 0 (p[0])
3780  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
3781  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
3782  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
3783  // x = p[1] (interior)
3784  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
3785  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
3786  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
3787  // x = p[2] (interior)
3788  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
3789  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
3790  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
3791  // y = p[1] (interior)
3792  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
3793  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
3794  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
3795  // y = p[2] (interior)
3796  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
3797  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
3798  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
3799 }
3800 
3801 const double RT2QuadFiniteElement::nk[24][2] =
3802 {
3803  // y = 0
3804  {0,-1}, {0,-1}, {0,-1},
3805  // x = 1
3806  {1, 0}, {1, 0}, {1, 0},
3807  // y = 1
3808  {0, 1}, {0, 1}, {0, 1},
3809  // x = 0
3810  {-1,0}, {-1,0}, {-1,0},
3811  // x = p[1] (interior)
3812  {1, 0}, {1, 0}, {1, 0},
3813  // x = p[2] (interior)
3814  {1, 0}, {1, 0}, {1, 0},
3815  // y = p[1] (interior)
3816  {0, 1}, {0, 1}, {0, 1},
3817  // y = p[1] (interior)
3818  {0, 1}, {0, 1}, {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 < 24; k++)
3832  {
3834  for (j = 0; j < 24; 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 << "RT2QuadFiniteElement::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 < 24; 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 < 24; 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 < 24; 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  }
3893 }
3894 
3896  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
3897 {
3898  Nodes.IntPoint(0).x = 0.33333333333333333333;
3899  Nodes.IntPoint(1).x = 0.66666666666666666667;
3900 }
3901 
3903  Vector &shape) const
3904 {
3905  double x = ip.x;
3906 
3907  shape(0) = 2. - 3. * x;
3908  shape(1) = 3. * x - 1.;
3909 }
3910 
3912  DenseMatrix &dshape) const
3913 {
3914  dshape(0,0) = -3.;
3915  dshape(1,0) = 3.;
3916 }
3917 
3918 
3920  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
3921 {
3922  const double p = 0.11270166537925831148;
3923 
3924  Nodes.IntPoint(0).x = p;
3925  Nodes.IntPoint(1).x = 0.5;
3926  Nodes.IntPoint(2).x = 1.-p;
3927 }
3928 
3930  Vector &shape) const
3931 {
3932  const double p = 0.11270166537925831148;
3933  const double w = 1./((1-2*p)*(1-2*p));
3934  double x = ip.x;
3935 
3936  shape(0) = (2*x-1)*(x-1+p)*w;
3937  shape(1) = 4*(x-1+p)*(p-x)*w;
3938  shape(2) = (2*x-1)*(x-p)*w;
3939 }
3940 
3942  DenseMatrix &dshape) const
3943 {
3944  const double p = 0.11270166537925831148;
3945  const double w = 1./((1-2*p)*(1-2*p));
3946  double x = ip.x;
3947 
3948  dshape(0,0) = (-3+4*x+2*p)*w;
3949  dshape(1,0) = (4-8*x)*w;
3950  dshape(2,0) = (-1+4*x-2*p)*w;
3951 }
3952 
3953 
3955  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
3956 {
3957  int i, m = degree;
3958 
3959  Nodes.IntPoint(0).x = 0.0;
3960  Nodes.IntPoint(1).x = 1.0;
3961  for (i = 1; i < m; i++)
3962  {
3963  Nodes.IntPoint(i+1).x = double(i) / m;
3964  }
3965 
3966  rwk.SetSize(degree+1);
3967 #ifndef MFEM_THREAD_SAFE
3968  rxxk.SetSize(degree+1);
3969 #endif
3970 
3971  rwk(0) = 1.0;
3972  for (i = 1; i <= m; i++)
3973  {
3974  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
3975  }
3976  for (i = 0; i < m/2+1; i++)
3977  {
3978  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
3979  }
3980  for (i = m-1; i >= 0; i -= 2)
3981  {
3982  rwk(i) = -rwk(i);
3983  }
3984 }
3985 
3987  Vector &shape) const
3988 {
3989  double w, wk, x = ip.x;
3990  int i, k, m = GetOrder();
3991 
3992 #ifdef MFEM_THREAD_SAFE
3993  Vector rxxk(m+1);
3994 #endif
3995 
3996  k = (int) floor ( m * x + 0.5 );
3997  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
3998 
3999  wk = 1.0;
4000  for (i = 0; i <= m; i++)
4001  if (i != k)
4002  {
4003  wk *= ( rxxk(i) = x - (double)(i) / m );
4004  }
4005  w = wk * ( rxxk(k) = x - (double)(k) / m );
4006 
4007  if (k != 0)
4008  {
4009  shape(0) = w * rwk(0) / rxxk(0);
4010  }
4011  else
4012  {
4013  shape(0) = wk * rwk(0);
4014  }
4015  if (k != m)
4016  {
4017  shape(1) = w * rwk(m) / rxxk(m);
4018  }
4019  else
4020  {
4021  shape(1) = wk * rwk(k);
4022  }
4023  for (i = 1; i < m; i++)
4024  if (i != k)
4025  {
4026  shape(i+1) = w * rwk(i) / rxxk(i);
4027  }
4028  else
4029  {
4030  shape(k+1) = wk * rwk(k);
4031  }
4032 }
4033 
4035  DenseMatrix &dshape) const
4036 {
4037  double s, srx, w, wk, x = ip.x;
4038  int i, k, m = GetOrder();
4039 
4040 #ifdef MFEM_THREAD_SAFE
4041  Vector rxxk(m+1);
4042 #endif
4043 
4044  k = (int) floor ( m * x + 0.5 );
4045  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
4046 
4047  wk = 1.0;
4048  for (i = 0; i <= m; i++)
4049  if (i != k)
4050  {
4051  wk *= ( rxxk(i) = x - (double)(i) / m );
4052  }
4053  w = wk * ( rxxk(k) = x - (double)(k) / m );
4054 
4055  for (i = 0; i <= m; i++)
4056  {
4057  rxxk(i) = 1.0 / rxxk(i);
4058  }
4059  srx = 0.0;
4060  for (i = 0; i <= m; i++)
4061  if (i != k)
4062  {
4063  srx += rxxk(i);
4064  }
4065  s = w * srx + wk;
4066 
4067  if (k != 0)
4068  {
4069  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
4070  }
4071  else
4072  {
4073  dshape(0,0) = wk * srx * rwk(0);
4074  }
4075  if (k != m)
4076  {
4077  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
4078  }
4079  else
4080  {
4081  dshape(1,0) = wk * srx * rwk(k);
4082  }
4083  for (i = 1; i < m; i++)
4084  if (i != k)
4085  {
4086  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
4087  }
4088  else
4089  {
4090  dshape(k+1,0) = wk * srx * rwk(k);
4091  }
4092 }
4093 
4094 
4096  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
4097 {
4098  Nodes.IntPoint(0).x = 0.33333333333333333333;
4099  Nodes.IntPoint(0).y = 0.33333333333333333333;
4100  Nodes.IntPoint(0).z = 0.33333333333333333333;
4101 
4102  Nodes.IntPoint(1).x = 0.0;
4103  Nodes.IntPoint(1).y = 0.33333333333333333333;
4104  Nodes.IntPoint(1).z = 0.33333333333333333333;
4105 
4106  Nodes.IntPoint(2).x = 0.33333333333333333333;
4107  Nodes.IntPoint(2).y = 0.0;
4108  Nodes.IntPoint(2).z = 0.33333333333333333333;
4109 
4110  Nodes.IntPoint(3).x = 0.33333333333333333333;
4111  Nodes.IntPoint(3).y = 0.33333333333333333333;
4112  Nodes.IntPoint(3).z = 0.0;
4113 
4114 }
4115 
4117  Vector &shape) const
4118 {
4119  double L0, L1, L2, L3;
4120 
4121  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
4122  shape(0) = 1.0 - 3.0 * L0;
4123  shape(1) = 1.0 - 3.0 * L1;
4124  shape(2) = 1.0 - 3.0 * L2;
4125  shape(3) = 1.0 - 3.0 * L3;
4126 }
4127 
4129  DenseMatrix &dshape) const
4130 {
4131  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
4132  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
4133  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
4134  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
4135 }
4136 
4137 
4139  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 1, 0)
4140 {
4141  Nodes.IntPoint(0).x = 0.25;
4142  Nodes.IntPoint(0).y = 0.25;
4143  Nodes.IntPoint(0).z = 0.25;
4144 }
4145 
4147  Vector &shape) const
4148 {
4149  shape(0) = 1.0;
4150 }
4151 
4153  DenseMatrix &dshape) const
4154 {
4155  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
4156 }
4157 
4158 
4160  : NodalFiniteElement(3, Geometry::CUBE, 1, 0, FunctionSpace::Qk)
4161 {
4162  Nodes.IntPoint(0).x = 0.5;
4163  Nodes.IntPoint(0).y = 0.5;
4164  Nodes.IntPoint(0).z = 0.5;
4165 }
4166 
4168  Vector &shape) const
4169 {
4170  shape(0) = 1.0;
4171 }
4172 
4174  DenseMatrix &dshape) const
4175 {
4176  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
4177 }
4178 
4179 
4181  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
4182  degree, FunctionSpace::Qk)
4183 {
4184  if (degree == 2)
4185  {
4186  I = new int[Dof];
4187  J = new int[Dof];
4188  K = new int[Dof];
4189  // nodes
4190  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
4191  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
4192  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
4193  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
4194  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
4195  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
4196  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
4197  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
4198  // edges
4199  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
4200  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
4201  I[10] = 2; J[10] = 1; K[10] = 0;
4202  I[11] = 0; J[11] = 2; K[11] = 0;
4203  I[12] = 2; J[12] = 0; K[12] = 1;
4204  I[13] = 1; J[13] = 2; K[13] = 1;
4205  I[14] = 2; J[14] = 1; K[14] = 1;
4206  I[15] = 0; J[15] = 2; K[15] = 1;
4207  I[16] = 0; J[16] = 0; K[16] = 2;
4208  I[17] = 1; J[17] = 0; K[17] = 2;
4209  I[18] = 1; J[18] = 1; K[18] = 2;
4210  I[19] = 0; J[19] = 1; K[19] = 2;
4211  // faces
4212  I[20] = 2; J[20] = 2; K[20] = 0;
4213  I[21] = 2; J[21] = 0; K[21] = 2;
4214  I[22] = 1; J[22] = 2; K[22] = 2;
4215  I[23] = 2; J[23] = 1; K[23] = 2;
4216  I[24] = 0; J[24] = 2; K[24] = 2;
4217  I[25] = 2; J[25] = 2; K[25] = 1;
4218  // element
4219  I[26] = 2; J[26] = 2; K[26] = 2;
4220  }
4221  else if (degree == 3)
4222  {
4223  I = new int[Dof];
4224  J = new int[Dof];
4225  K = new int[Dof];
4226  // nodes
4227  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
4228  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
4229  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
4230  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
4231  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
4232  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
4233  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
4234  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
4235  // edges
4236  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
4237  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
4238  I[10] = 1; J[10] = 2; K[10] = 0;
4239  I[11] = 1; J[11] = 3; K[11] = 0;
4240  I[12] = 2; J[12] = 1; K[12] = 0;
4241  I[13] = 3; J[13] = 1; K[13] = 0;
4242  I[14] = 0; J[14] = 2; K[14] = 0;
4243  I[15] = 0; J[15] = 3; K[15] = 0;
4244  I[16] = 2; J[16] = 0; K[16] = 1;
4245  I[17] = 3; J[17] = 0; K[17] = 1;
4246  I[18] = 1; J[18] = 2; K[18] = 1;
4247  I[19] = 1; J[19] = 3; K[19] = 1;
4248  I[20] = 2; J[20] = 1; K[20] = 1;
4249  I[21] = 3; J[21] = 1; K[21] = 1;
4250  I[22] = 0; J[22] = 2; K[22] = 1;
4251  I[23] = 0; J[23] = 3; K[23] = 1;
4252  I[24] = 0; J[24] = 0; K[24] = 2;
4253  I[25] = 0; J[25] = 0; K[25] = 3;
4254  I[26] = 1; J[26] = 0; K[26] = 2;
4255  I[27] = 1; J[27] = 0; K[27] = 3;
4256  I[28] = 1; J[28] = 1; K[28] = 2;
4257  I[29] = 1; J[29] = 1; K[29] = 3;
4258  I[30] = 0; J[30] = 1; K[30] = 2;
4259  I[31] = 0; J[31] = 1; K[31] = 3;
4260  // faces
4261  I[32] = 2; J[32] = 3; K[32] = 0;
4262  I[33] = 3; J[33] = 3; K[33] = 0;
4263  I[34] = 2; J[34] = 2; K[34] = 0;
4264  I[35] = 3; J[35] = 2; K[35] = 0;
4265  I[36] = 2; J[36] = 0; K[36] = 2;
4266  I[37] = 3; J[37] = 0; K[37] = 2;
4267  I[38] = 2; J[38] = 0; K[38] = 3;
4268  I[39] = 3; J[39] = 0; K[39] = 3;
4269  I[40] = 1; J[40] = 2; K[40] = 2;
4270  I[41] = 1; J[41] = 3; K[41] = 2;
4271  I[42] = 1; J[42] = 2; K[42] = 3;
4272  I[43] = 1; J[43] = 3; K[43] = 3;
4273  I[44] = 3; J[44] = 1; K[44] = 2;
4274  I[45] = 2; J[45] = 1; K[45] = 2;
4275  I[46] = 3; J[46] = 1; K[46] = 3;
4276  I[47] = 2; J[47] = 1; K[47] = 3;
4277  I[48] = 0; J[48] = 3; K[48] = 2;
4278  I[49] = 0; J[49] = 2; K[49] = 2;
4279  I[50] = 0; J[50] = 3; K[50] = 3;
4280  I[51] = 0; J[51] = 2; K[51] = 3;
4281  I[52] = 2; J[52] = 2; K[52] = 1;
4282  I[53] = 3; J[53] = 2; K[53] = 1;
4283  I[54] = 2; J[54] = 3; K[54] = 1;
4284  I[55] = 3; J[55] = 3; K[55] = 1;
4285  // element
4286  I[56] = 2; J[56] = 2; K[56] = 2;
4287  I[57] = 3; J[57] = 2; K[57] = 2;
4288  I[58] = 3; J[58] = 3; K[58] = 2;
4289  I[59] = 2; J[59] = 3; K[59] = 2;
4290  I[60] = 2; J[60] = 2; K[60] = 3;
4291  I[61] = 3; J[61] = 2; K[61] = 3;
4292  I[62] = 3; J[62] = 3; K[62] = 3;
4293  I[63] = 2; J[63] = 3; K[63] = 3;
4294  }
4295  else
4296  {
4297  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
4298  }
4299 
4300  fe1d = new Lagrange1DFiniteElement(degree);
4301  dof1d = fe1d -> GetDof();
4302 
4303 #ifndef MFEM_THREAD_SAFE
4304  shape1dx.SetSize(dof1d);
4305  shape1dy.SetSize(dof1d);
4306  shape1dz.SetSize(dof1d);
4307 
4308  dshape1dx.SetSize(dof1d,1);
4309  dshape1dy.SetSize(dof1d,1);
4310  dshape1dz.SetSize(dof1d,1);
4311 #endif
4312 
4313  for (int n = 0; n < Dof; n++)
4314  {
4315  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
4316  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
4317  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
4318  }
4319 }
4320 
4322  Vector &shape) const
4323 {
4324  IntegrationPoint ipy, ipz;
4325  ipy.x = ip.y;
4326  ipz.x = ip.z;
4327 
4328 #ifdef MFEM_THREAD_SAFE
4329  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4330 #endif
4331 
4332  fe1d -> CalcShape(ip, shape1dx);
4333  fe1d -> CalcShape(ipy, shape1dy);
4334  fe1d -> CalcShape(ipz, shape1dz);
4335 
4336  for (int n = 0; n < Dof; n++)
4337  {
4338  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
4339  }
4340 }
4341 
4343  DenseMatrix &dshape) const
4344 {
4345  IntegrationPoint ipy, ipz;
4346  ipy.x = ip.y;
4347  ipz.x = ip.z;
4348 
4349 #ifdef MFEM_THREAD_SAFE
4350  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4351  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
4352 #endif
4353 
4354  fe1d -> CalcShape(ip, shape1dx);
4355  fe1d -> CalcShape(ipy, shape1dy);
4356  fe1d -> CalcShape(ipz, shape1dz);
4357 
4358  fe1d -> CalcDShape(ip, dshape1dx);
4359  fe1d -> CalcDShape(ipy, dshape1dy);
4360  fe1d -> CalcDShape(ipz, dshape1dz);
4361 
4362  for (int n = 0; n < Dof; n++)
4363  {
4364  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
4365  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
4366  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
4367  }
4368 }
4369 
4371 {
4372  delete fe1d;
4373 
4374  delete [] I;
4375  delete [] J;
4376  delete [] K;
4377 }
4378 
4379 
4381  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
4382 {
4383  Nodes.IntPoint(0).x = 0.0;
4384  Nodes.IntPoint(1).x = 1.0;
4385  Nodes.IntPoint(2).x = 0.5;
4386 }
4387 
4389  Vector &shape) const
4390 {
4391  double x = ip.x;
4392 
4393  if (x <= 0.5)
4394  {
4395  shape(0) = 1.0 - 2.0 * x;
4396  shape(1) = 0.0;
4397  shape(2) = 2.0 * x;
4398  }
4399  else
4400  {
4401  shape(0) = 0.0;
4402  shape(1) = 2.0 * x - 1.0;
4403  shape(2) = 2.0 - 2.0 * x;
4404  }
4405 }
4406 
4408  DenseMatrix &dshape) const
4409 {
4410  double x = ip.x;
4411 
4412  if (x <= 0.5)
4413  {
4414  dshape(0,0) = - 2.0;
4415  dshape(1,0) = 0.0;
4416  dshape(2,0) = 2.0;
4417  }
4418  else
4419  {
4420  dshape(0,0) = 0.0;
4421  dshape(1,0) = 2.0;
4422  dshape(2,0) = - 2.0;
4423  }
4424 }
4425 
4427  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
4428 {
4429  Nodes.IntPoint(0).x = 0.0;
4430  Nodes.IntPoint(0).y = 0.0;
4431  Nodes.IntPoint(1).x = 1.0;
4432  Nodes.IntPoint(1).y = 0.0;
4433  Nodes.IntPoint(2).x = 0.0;
4434  Nodes.IntPoint(2).y = 1.0;
4435  Nodes.IntPoint(3).x = 0.5;
4436  Nodes.IntPoint(3).y = 0.0;
4437  Nodes.IntPoint(4).x = 0.5;
4438  Nodes.IntPoint(4).y = 0.5;
4439  Nodes.IntPoint(5).x = 0.0;
4440  Nodes.IntPoint(5).y = 0.5;
4441 }
4442 
4444  Vector &shape) const
4445 {
4446  int i;
4447 
4448  double L0, L1, L2;
4449  L0 = 2.0 * ( 1. - ip.x - ip.y );
4450  L1 = 2.0 * ( ip.x );
4451  L2 = 2.0 * ( ip.y );
4452 
4453  // The reference triangle is split in 4 triangles as follows:
4454  //
4455  // T0 - 0,3,5
4456  // T1 - 1,3,4
4457  // T2 - 2,4,5
4458  // T3 - 3,4,5
4459 
4460  for (i = 0; i < 6; i++)
4461  {
4462  shape(i) = 0.0;
4463  }
4464 
4465  if (L0 >= 1.0) // T0
4466  {
4467  shape(0) = L0 - 1.0;
4468  shape(3) = L1;
4469  shape(5) = L2;
4470  }
4471  else if (L1 >= 1.0) // T1
4472  {
4473  shape(3) = L0;
4474  shape(1) = L1 - 1.0;
4475  shape(4) = L2;
4476  }
4477  else if (L2 >= 1.0) // T2
4478  {
4479  shape(5) = L0;
4480  shape(4) = L1;
4481  shape(2) = L2 - 1.0;
4482  }
4483  else // T3
4484  {
4485  shape(3) = 1.0 - L2;
4486  shape(4) = 1.0 - L0;
4487  shape(5) = 1.0 - L1;
4488  }
4489 }
4490 
4492  DenseMatrix &dshape) const
4493 {
4494  int i,j;
4495 
4496  double L0, L1, L2;
4497  L0 = 2.0 * ( 1. - ip.x - ip.y );
4498  L1 = 2.0 * ( ip.x );
4499  L2 = 2.0 * ( ip.y );
4500 
4501  double DL0[2], DL1[2], DL2[2];
4502  DL0[0] = -2.0; DL0[1] = -2.0;
4503  DL1[0] = 2.0; DL1[1] = 0.0;
4504  DL2[0] = 0.0; DL2[1] = 2.0;
4505 
4506  for (i = 0; i < 6; i++)
4507  for (j = 0; j < 2; j++)
4508  {
4509  dshape(i,j) = 0.0;
4510  }
4511 
4512  if (L0 >= 1.0) // T0
4513  {
4514  for (j = 0; j < 2; j++)
4515  {
4516  dshape(0,j) = DL0[j];
4517  dshape(3,j) = DL1[j];
4518  dshape(5,j) = DL2[j];
4519  }
4520  }
4521  else if (L1 >= 1.0) // T1
4522  {
4523  for (j = 0; j < 2; j++)
4524  {
4525  dshape(3,j) = DL0[j];
4526  dshape(1,j) = DL1[j];
4527  dshape(4,j) = DL2[j];
4528  }
4529  }
4530  else if (L2 >= 1.0) // T2
4531  {
4532  for (j = 0; j < 2; j++)
4533  {
4534  dshape(5,j) = DL0[j];
4535  dshape(4,j) = DL1[j];
4536  dshape(2,j) = DL2[j];
4537  }
4538  }
4539  else // T3
4540  {
4541  for (j = 0; j < 2; j++)
4542  {
4543  dshape(3,j) = - DL2[j];
4544  dshape(4,j) = - DL0[j];
4545  dshape(5,j) = - DL1[j];
4546  }
4547  }
4548 }
4549 
4551  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
4552 {
4553  Nodes.IntPoint(0).x = 0.0;
4554  Nodes.IntPoint(0).y = 0.0;
4555  Nodes.IntPoint(0).z = 0.0;
4556  Nodes.IntPoint(1).x = 1.0;
4557  Nodes.IntPoint(1).y = 0.0;
4558  Nodes.IntPoint(1).z = 0.0;
4559  Nodes.IntPoint(2).x = 0.0;
4560  Nodes.IntPoint(2).y = 1.0;
4561  Nodes.IntPoint(2).z = 0.0;
4562  Nodes.IntPoint(3).x = 0.0;
4563  Nodes.IntPoint(3).y = 0.0;
4564  Nodes.IntPoint(3).z = 1.0;
4565  Nodes.IntPoint(4).x = 0.5;
4566  Nodes.IntPoint(4).y = 0.0;
4567  Nodes.IntPoint(4).z = 0.0;
4568  Nodes.IntPoint(5).x = 0.0;
4569  Nodes.IntPoint(5).y = 0.5;
4570  Nodes.IntPoint(5).z = 0.0;
4571  Nodes.IntPoint(6).x = 0.0;
4572  Nodes.IntPoint(6).y = 0.0;
4573  Nodes.IntPoint(6).z = 0.5;
4574  Nodes.IntPoint(7).x = 0.5;
4575  Nodes.IntPoint(7).y = 0.5;
4576  Nodes.IntPoint(7).z = 0.0;
4577  Nodes.IntPoint(8).x = 0.5;
4578  Nodes.IntPoint(8).y = 0.0;
4579  Nodes.IntPoint(8).z = 0.5;
4580  Nodes.IntPoint(9).x = 0.0;
4581  Nodes.IntPoint(9).y = 0.5;
4582  Nodes.IntPoint(9).z = 0.5;
4583 }
4584 
4586  Vector &shape) const
4587 {
4588  int i;
4589 
4590  double L0, L1, L2, L3, L4, L5;
4591  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4592  L1 = 2.0 * ( ip.x );
4593  L2 = 2.0 * ( ip.y );
4594  L3 = 2.0 * ( ip.z );
4595  L4 = 2.0 * ( ip.x + ip.y );
4596  L5 = 2.0 * ( ip.y + ip.z );
4597 
4598  // The reference tetrahedron is split in 8 tetrahedra as follows:
4599  //
4600  // T0 - 0,4,5,6
4601  // T1 - 1,4,7,8
4602  // T2 - 2,5,7,9
4603  // T3 - 3,6,8,9
4604  // T4 - 4,5,6,8
4605  // T5 - 4,5,7,8
4606  // T6 - 5,6,8,9
4607  // T7 - 5,7,8,9
4608 
4609  for (i = 0; i < 10; i++)
4610  {
4611  shape(i) = 0.0;
4612  }
4613 
4614  if (L0 >= 1.0) // T0
4615  {
4616  shape(0) = L0 - 1.0;
4617  shape(4) = L1;
4618  shape(5) = L2;
4619  shape(6) = L3;
4620  }
4621  else if (L1 >= 1.0) // T1
4622  {
4623  shape(4) = L0;
4624  shape(1) = L1 - 1.0;
4625  shape(7) = L2;
4626  shape(8) = L3;
4627  }
4628  else if (L2 >= 1.0) // T2
4629  {
4630  shape(5) = L0;
4631  shape(7) = L1;
4632  shape(2) = L2 - 1.0;
4633  shape(9) = L3;
4634  }
4635  else if (L3 >= 1.0) // T3
4636  {
4637  shape(6) = L0;
4638  shape(8) = L1;
4639  shape(9) = L2;
4640  shape(3) = L3 - 1.0;
4641  }
4642  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4643  {
4644  shape(4) = 1.0 - L5;
4645  shape(5) = L2;
4646  shape(6) = 1.0 - L4;
4647  shape(8) = 1.0 - L0;
4648  }
4649  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4650  {
4651  shape(4) = 1.0 - L5;
4652  shape(5) = 1.0 - L1;
4653  shape(7) = L4 - 1.0;
4654  shape(8) = L3;
4655  }
4656  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4657  {
4658  shape(5) = 1.0 - L3;
4659  shape(6) = 1.0 - L4;
4660  shape(8) = L1;
4661  shape(9) = L5 - 1.0;
4662  }
4663  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4664  {
4665  shape(5) = L0;
4666  shape(7) = L4 - 1.0;
4667  shape(8) = 1.0 - L2;
4668  shape(9) = L5 - 1.0;
4669  }
4670 }
4671 
4673  DenseMatrix &dshape) const
4674 {
4675  int i,j;
4676 
4677  double L0, L1, L2, L3, L4, L5;
4678  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4679  L1 = 2.0 * ( ip.x );
4680  L2 = 2.0 * ( ip.y );
4681  L3 = 2.0 * ( ip.z );
4682  L4 = 2.0 * ( ip.x + ip.y );
4683  L5 = 2.0 * ( ip.y + ip.z );
4684 
4685  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
4686  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
4687  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
4688  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
4689  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
4690  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
4691  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
4692 
4693  for (i = 0; i < 10; i++)
4694  for (j = 0; j < 3; j++)
4695  {
4696  dshape(i,j) = 0.0;
4697  }
4698 
4699  if (L0 >= 1.0) // T0
4700  {
4701  for (j = 0; j < 3; j++)
4702  {
4703  dshape(0,j) = DL0[j];
4704  dshape(4,j) = DL1[j];
4705  dshape(5,j) = DL2[j];
4706  dshape(6,j) = DL3[j];
4707  }
4708  }
4709  else if (L1 >= 1.0) // T1
4710  {
4711  for (j = 0; j < 3; j++)
4712  {
4713  dshape(4,j) = DL0[j];
4714  dshape(1,j) = DL1[j];
4715  dshape(7,j) = DL2[j];
4716  dshape(8,j) = DL3[j];
4717  }
4718  }
4719  else if (L2 >= 1.0) // T2
4720  {
4721  for (j = 0; j < 3; j++)
4722  {
4723  dshape(5,j) = DL0[j];
4724  dshape(7,j) = DL1[j];
4725  dshape(2,j) = DL2[j];
4726  dshape(9,j) = DL3[j];
4727  }
4728  }
4729  else if (L3 >= 1.0) // T3
4730  {
4731  for (j = 0; j < 3; j++)
4732  {
4733  dshape(6,j) = DL0[j];
4734  dshape(8,j) = DL1[j];
4735  dshape(9,j) = DL2[j];
4736  dshape(3,j) = DL3[j];
4737  }
4738  }
4739  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4740  {
4741  for (j = 0; j < 3; j++)
4742  {
4743  dshape(4,j) = - DL5[j];
4744  dshape(5,j) = DL2[j];
4745  dshape(6,j) = - DL4[j];
4746  dshape(8,j) = - DL0[j];
4747  }
4748  }
4749  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4750  {
4751  for (j = 0; j < 3; j++)
4752  {
4753  dshape(4,j) = - DL5[j];
4754  dshape(5,j) = - DL1[j];
4755  dshape(7,j) = DL4[j];
4756  dshape(8,j) = DL3[j];
4757  }
4758  }
4759  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4760  {
4761  for (j = 0; j < 3; j++)
4762  {
4763  dshape(5,j) = - DL3[j];
4764  dshape(6,j) = - DL4[j];
4765  dshape(8,j) = DL1[j];
4766  dshape(9,j) = DL5[j];
4767  }
4768  }
4769  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4770  {
4771  for (j = 0; j < 3; j++)
4772  {
4773  dshape(5,j) = DL0[j];
4774  dshape(7,j) = DL4[j];
4775  dshape(8,j) = - DL2[j];
4776  dshape(9,j) = DL5[j];
4777  }
4778  }
4779 }
4780 
4781 
4783  : NodalFiniteElement(2, Geometry::SQUARE, 9, 1, FunctionSpace::rQk)
4784 {
4785  Nodes.IntPoint(0).x = 0.0;
4786  Nodes.IntPoint(0).y = 0.0;
4787  Nodes.IntPoint(1).x = 1.0;
4788  Nodes.IntPoint(1).y = 0.0;
4789  Nodes.IntPoint(2).x = 1.0;
4790  Nodes.IntPoint(2).y = 1.0;
4791  Nodes.IntPoint(3).x = 0.0;
4792  Nodes.IntPoint(3).y = 1.0;
4793  Nodes.IntPoint(4).x = 0.5;
4794  Nodes.IntPoint(4).y = 0.0;
4795  Nodes.IntPoint(5).x = 1.0;
4796  Nodes.IntPoint(5).y = 0.5;
4797  Nodes.IntPoint(6).x = 0.5;
4798  Nodes.IntPoint(6).y = 1.0;
4799  Nodes.IntPoint(7).x = 0.0;
4800  Nodes.IntPoint(7).y = 0.5;
4801  Nodes.IntPoint(8).x = 0.5;
4802  Nodes.IntPoint(8).y = 0.5;
4803 }
4804 
4806  Vector &shape) const
4807 {
4808  int i;
4809  double x = ip.x, y = ip.y;
4810  double Lx, Ly;
4811  Lx = 2.0 * ( 1. - x );
4812  Ly = 2.0 * ( 1. - y );
4813 
4814  // The reference square is split in 4 squares as follows:
4815  //
4816  // T0 - 0,4,7,8
4817  // T1 - 1,4,5,8
4818  // T2 - 2,5,6,8
4819  // T3 - 3,6,7,8
4820 
4821  for (i = 0; i < 9; i++)
4822  {
4823  shape(i) = 0.0;
4824  }
4825 
4826  if ((x <= 0.5) && (y <= 0.5)) // T0
4827  {
4828  shape(0) = (Lx - 1.0) * (Ly - 1.0);
4829  shape(4) = (2.0 - Lx) * (Ly - 1.0);
4830  shape(8) = (2.0 - Lx) * (2.0 - Ly);
4831  shape(7) = (Lx - 1.0) * (2.0 - Ly);
4832  }
4833  else if ((x >= 0.5) && (y <= 0.5)) // T1
4834  {
4835  shape(4) = Lx * (Ly - 1.0);
4836  shape(1) = (1.0 - Lx) * (Ly - 1.0);
4837  shape(5) = (1.0 - Lx) * (2.0 - Ly);
4838  shape(8) = Lx * (2.0 - Ly);
4839  }
4840  else if ((x >= 0.5) && (y >= 0.5)) // T2
4841  {
4842  shape(8) = Lx * Ly ;
4843  shape(5) = (1.0 - Lx) * Ly ;
4844  shape(2) = (1.0 - Lx) * (1.0 - Ly);
4845  shape(6) = Lx * (1.0 - Ly);
4846  }
4847  else if ((x <= 0.5) && (y >= 0.5)) // T3
4848  {
4849  shape(7) = (Lx - 1.0) * Ly ;
4850  shape(8) = (2.0 - Lx) * Ly ;
4851  shape(6) = (2.0 - Lx) * (1.0 - Ly);
4852  shape(3) = (Lx - 1.0) * (1.0 - Ly);
4853  }
4854 }
4855 
4857  DenseMatrix &dshape) const
4858 {
4859  int i,j;
4860  double x = ip.x, y = ip.y;
4861  double Lx, Ly;
4862  Lx = 2.0 * ( 1. - x );
4863  Ly = 2.0 * ( 1. - y );
4864 
4865  for (i = 0; i < 9; i++)
4866  for (j = 0; j < 2; j++)
4867  {
4868  dshape(i,j) = 0.0;
4869  }
4870 
4871  if ((x <= 0.5) && (y <= 0.5)) // T0
4872  {
4873  dshape(0,0) = 2.0 * (1.0 - Ly);
4874  dshape(0,1) = 2.0 * (1.0 - Lx);
4875 
4876  dshape(4,0) = 2.0 * (Ly - 1.0);
4877  dshape(4,1) = -2.0 * (2.0 - Lx);
4878 
4879  dshape(8,0) = 2.0 * (2.0 - Ly);
4880  dshape(8,1) = 2.0 * (2.0 - Lx);
4881 
4882  dshape(7,0) = -2.0 * (2.0 - Ly);
4883  dshape(7,0) = 2.0 * (Lx - 1.0);
4884  }
4885  else if ((x >= 0.5) && (y <= 0.5)) // T1
4886  {
4887  dshape(4,0) = -2.0 * (Ly - 1.0);
4888  dshape(4,1) = -2.0 * Lx;
4889 
4890  dshape(1,0) = 2.0 * (Ly - 1.0);
4891  dshape(1,1) = -2.0 * (1.0 - Lx);
4892 
4893  dshape(5,0) = 2.0 * (2.0 - Ly);
4894  dshape(5,1) = 2.0 * (1.0 - Lx);
4895 
4896  dshape(8,0) = -2.0 * (2.0 - Ly);
4897  dshape(8,1) = 2.0 * Lx;
4898  }
4899  else if ((x >= 0.5) && (y >= 0.5)) // T2
4900  {
4901  dshape(8,0) = -2.0 * Ly;
4902  dshape(8,1) = -2.0 * Lx;
4903 
4904  dshape(5,0) = 2.0 * Ly;
4905  dshape(5,1) = -2.0 * (1.0 - Lx);
4906 
4907  dshape(2,0) = 2.0 * (1.0 - Ly);
4908  dshape(2,1) = 2.0 * (1.0 - Lx);
4909 
4910  dshape(6,0) = -2.0 * (1.0 - Ly);
4911  dshape(6,1) = 2.0 * Lx;
4912  }
4913  else if ((x <= 0.5) && (y >= 0.5)) // T3
4914  {
4915  dshape(7,0) = -2.0 * Ly;
4916  dshape(7,1) = -2.0 * (Lx - 1.0);
4917 
4918  dshape(8,0) = 2.0 * Ly ;
4919  dshape(8,1) = -2.0 * (2.0 - Lx);
4920 
4921  dshape(6,0) = 2.0 * (1.0 - Ly);
4922  dshape(6,1) = 2.0 * (2.0 - Lx);
4923 
4924  dshape(3,0) = -2.0 * (1.0 - Ly);
4925  dshape(3,1) = 2.0 * (Lx - 1.0);
4926  }
4927 }
4928 
4930  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
4931 {
4932  double I[27];
4933  double J[27];
4934  double K[27];
4935  // nodes
4936  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
4937  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
4938  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
4939  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
4940  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
4941  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
4942  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
4943  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
4944  // edges
4945  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
4946  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
4947  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
4948  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
4949  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
4950  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
4951  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
4952  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
4953  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
4954  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
4955  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
4956  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
4957  // faces
4958  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
4959  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
4960  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
4961  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
4962  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
4963  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
4964  // element
4965  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
4966 
4967  for (int n = 0; n < 27; n++)
4968  {
4969  Nodes.IntPoint(n).x = I[n];
4970  Nodes.IntPoint(n).y = J[n];
4971  Nodes.IntPoint(n).z = K[n];
4972  }
4973 }
4974 
4976  Vector &shape) const
4977 {
4978  int i, N[8];
4979  double Lx, Ly, Lz;
4980  double x = ip.x, y = ip.y, z = ip.z;
4981 
4982  for (i = 0; i < 27; i++)
4983  {
4984  shape(i) = 0.0;
4985  }
4986 
4987  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4988  {
4989  Lx = 1.0 - 2.0 * x;
4990  Ly = 1.0 - 2.0 * y;
4991  Lz = 1.0 - 2.0 * z;
4992 
4993  N[0] = 0;
4994  N[1] = 8;
4995  N[2] = 20;
4996  N[3] = 11;
4997  N[4] = 16;
4998  N[5] = 21;
4999  N[6] = 26;
5000  N[7] = 24;
5001  }
5002  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
5003  {
5004  Lx = 2.0 - 2.0 * x;
5005  Ly = 1.0 - 2.0 * y;
5006  Lz = 1.0 - 2.0 * z;
5007 
5008  N[0] = 8;
5009  N[1] = 1;
5010  N[2] = 9;
5011  N[3] = 20;
5012  N[4] = 21;
5013  N[5] = 17;
5014  N[6] = 22;
5015  N[7] = 26;
5016  }
5017  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
5018  {
5019  Lx = 2.0 - 2.0 * x;
5020  Ly = 2.0 - 2.0 * y;
5021  Lz = 1.0 - 2.0 * z;
5022 
5023  N[0] = 20;
5024  N[1] = 9;
5025  N[2] = 2;
5026  N[3] = 10;
5027  N[4] = 26;
5028  N[5] = 22;
5029  N[6] = 18;
5030  N[7] = 23;
5031  }
5032  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
5033  {
5034  Lx = 1.0 - 2.0 * x;
5035  Ly = 2.0 - 2.0 * y;
5036  Lz = 1.0 - 2.0 * z;
5037 
5038  N[0] = 11;
5039  N[1] = 20;
5040  N[2] = 10;
5041  N[3] = 3;
5042  N[4] = 24;
5043  N[5] = 26;
5044  N[6] = 23;
5045  N[7] = 19;
5046  }
5047  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
5048  {
5049  Lx = 1.0 - 2.0 * x;
5050  Ly = 1.0 - 2.0 * y;
5051  Lz = 2.0 - 2.0 * z;
5052 
5053  N[0] = 16;
5054  N[1] = 21;
5055  N[2] = 26;
5056  N[3] = 24;
5057  N[4] = 4;
5058  N[5] = 12;
5059  N[6] = 25;
5060  N[7] = 15;
5061  }
5062  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
5063  {
5064  Lx = 2.0 - 2.0 * x;
5065  Ly = 1.0 - 2.0 * y;
5066  Lz = 2.0 - 2.0 * z;
5067 
5068  N[0] = 21;
5069  N[1] = 17;
5070  N[2] = 22;
5071  N[3] = 26;
5072  N[4] = 12;
5073  N[5] = 5;
5074  N[6] = 13;
5075  N[7] = 25;
5076  }
5077  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
5078  {
5079  Lx = 2.0 - 2.0 * x;
5080  Ly = 2.0 - 2.0 * y;
5081  Lz = 2.0 - 2.0 * z;
5082 
5083  N[0] = 26;
5084  N[1] = 22;
5085  N[2] = 18;
5086  N[3] = 23;
5087  N[4] = 25;
5088  N[5] = 13;
5089  N[6] = 6;
5090  N[7] = 14;
5091  }
5092  else // T7
5093  {
5094  Lx = 1.0 - 2.0 * x;
5095  Ly = 2.0 - 2.0 * y;
5096  Lz = 2.0 - 2.0 * z;
5097 
5098  N[0] = 24;
5099  N[1] = 26;
5100  N[2] = 23;
5101  N[3] = 19;
5102  N[4] = 15;
5103  N[5] = 25;
5104  N[6] = 14;
5105  N[7] = 7;
5106  }
5107 
5108  shape(N[0]) = Lx * Ly * Lz;
5109  shape(N[1]) = (1 - Lx) * Ly * Lz;
5110  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
5111  shape(N[3]) = Lx * (1 - Ly) * Lz;
5112  shape(N[4]) = Lx * Ly * (1 - Lz);
5113  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
5114  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
5115  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
5116 }
5117 
5119  DenseMatrix &dshape) const
5120 {
5121  int i, j, N[8];
5122  double Lx, Ly, Lz;
5123  double x = ip.x, y = ip.y, z = ip.z;
5124 
5125  for (i = 0; i < 27; i++)
5126  for (j = 0; j < 3; j++)
5127  {
5128  dshape(i,j) = 0.0;
5129  }
5130 
5131  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
5132  {
5133  Lx = 1.0 - 2.0 * x;
5134  Ly = 1.0 - 2.0 * y;
5135  Lz = 1.0 - 2.0 * z;
5136 
5137  N[0] = 0;
5138  N[1] = 8;
5139  N[2] = 20;
5140  N[3] = 11;
5141  N[4] = 16;
5142  N[5] = 21;
5143  N[6] = 26;
5144  N[7] = 24;
5145  }
5146  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
5147  {
5148  Lx = 2.0 - 2.0 * x;
5149  Ly = 1.0 - 2.0 * y;
5150  Lz = 1.0 - 2.0 * z;
5151 
5152  N[0] = 8;
5153  N[1] = 1;
5154  N[2] = 9;
5155  N[3] = 20;
5156  N[4] = 21;
5157  N[5] = 17;
5158  N[6] = 22;
5159  N[7] = 26;
5160  }
5161  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
5162  {
5163  Lx = 2.0 - 2.0 * x;
5164  Ly = 2.0 - 2.0 * y;
5165  Lz = 1.0 - 2.0 * z;
5166 
5167  N[0] = 20;
5168  N[1] = 9;
5169  N[2] = 2;
5170  N[3] = 10;
5171  N[4] = 26;
5172  N[5] = 22;
5173  N[6] = 18;
5174  N[7] = 23;
5175  }
5176  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
5177  {
5178  Lx = 1.0 - 2.0 * x;
5179  Ly = 2.0 - 2.0 * y;
5180  Lz = 1.0 - 2.0 * z;
5181 
5182  N[0] = 11;
5183  N[1] = 20;
5184  N[2] = 10;
5185  N[3] = 3;
5186  N[4] = 24;
5187  N[5] = 26;
5188  N[6] = 23;
5189  N[7] = 19;
5190  }
5191  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
5192  {
5193  Lx = 1.0 - 2.0 * x;
5194  Ly = 1.0 - 2.0 * y;
5195  Lz = 2.0 - 2.0 * z;
5196 
5197  N[0] = 16;
5198  N[1] = 21;
5199  N[2] = 26;
5200  N[3] = 24;
5201  N[4] = 4;
5202  N[5] = 12;
5203  N[6] = 25;
5204  N[7] = 15;
5205  }
5206  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
5207  {
5208  Lx = 2.0 - 2.0 * x;
5209  Ly = 1.0 - 2.0 * y;
5210  Lz = 2.0 - 2.0 * z;
5211 
5212  N[0] = 21;
5213  N[1] = 17;
5214  N[2] = 22;
5215  N[3] = 26;
5216  N[4] = 12;
5217  N[5] = 5;
5218  N[6] = 13;
5219  N[7] = 25;
5220  }
5221  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
5222  {
5223  Lx = 2.0 - 2.0 * x;
5224  Ly = 2.0 - 2.0 * y;
5225  Lz = 2.0 - 2.0 * z;
5226 
5227  N[0] = 26;
5228  N[1] = 22;
5229  N[2] = 18;
5230  N[3] = 23;
5231  N[4] = 25;
5232  N[5] = 13;
5233  N[6] = 6;
5234  N[7] = 14;
5235  }
5236  else // T7
5237  {
5238  Lx = 1.0 - 2.0 * x;
5239  Ly = 2.0 - 2.0 * y;
5240  Lz = 2.0 - 2.0 * z;
5241 
5242  N[0] = 24;
5243  N[1] = 26;
5244  N[2] = 23;
5245  N[3] = 19;
5246  N[4] = 15;
5247  N[5] = 25;
5248  N[6] = 14;
5249  N[7] = 7;
5250  }
5251 
5252  dshape(N[0],0) = -2.0 * Ly * Lz ;
5253  dshape(N[0],1) = -2.0 * Lx * Lz ;
5254  dshape(N[0],2) = -2.0 * Lx * Ly ;
5255 
5256  dshape(N[1],0) = 2.0 * Ly * Lz ;
5257  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
5258  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
5259 
5260  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
5261  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
5262  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
5263 
5264  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
5265  dshape(N[3],1) = 2.0 * Lx * Lz ;
5266  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
5267 
5268  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
5269  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
5270  dshape(N[4],2) = 2.0 * Lx * Ly ;
5271 
5272  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
5273  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
5274  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
5275 
5276  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
5277  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
5278  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
5279 
5280  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
5281  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
5282  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
5283 }
5284 
5285 
5287  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
5288 {
5289  // not real nodes ...
5290  Nodes.IntPoint(0).x = 0.5;
5291  Nodes.IntPoint(0).y = 0.0;
5292  Nodes.IntPoint(0).z = 0.0;
5293 
5294  Nodes.IntPoint(1).x = 1.0;
5295  Nodes.IntPoint(1).y = 0.5;
5296  Nodes.IntPoint(1).z = 0.0;
5297 
5298  Nodes.IntPoint(2).x = 0.5;
5299  Nodes.IntPoint(2).y = 1.0;
5300  Nodes.IntPoint(2).z = 0.0;
5301 
5302  Nodes.IntPoint(3).x = 0.0;
5303  Nodes.IntPoint(3).y = 0.5;
5304  Nodes.IntPoint(3).z = 0.0;
5305 
5306  Nodes.IntPoint(4).x = 0.5;
5307  Nodes.IntPoint(4).y = 0.0;
5308  Nodes.IntPoint(4).z = 1.0;
5309 
5310  Nodes.IntPoint(5).x = 1.0;
5311  Nodes.IntPoint(5).y = 0.5;
5312  Nodes.IntPoint(5).z = 1.0;
5313 
5314  Nodes.IntPoint(6).x = 0.5;
5315  Nodes.IntPoint(6).y = 1.0;
5316  Nodes.IntPoint(6).z = 1.0;
5317 
5318  Nodes.IntPoint(7).x = 0.0;
5319  Nodes.IntPoint(7).y = 0.5;
5320  Nodes.IntPoint(7).z = 1.0;
5321 
5322  Nodes.IntPoint(8).x = 0.0;
5323  Nodes.IntPoint(8).y = 0.0;
5324  Nodes.IntPoint(8).z = 0.5;
5325 
5326  Nodes.IntPoint(9).x = 1.0;
5327  Nodes.IntPoint(9).y = 0.0;
5328  Nodes.IntPoint(9).z = 0.5;
5329 
5330  Nodes.IntPoint(10).x= 1.0;
5331  Nodes.IntPoint(10).y= 1.0;
5332  Nodes.IntPoint(10).z= 0.5;
5333 
5334  Nodes.IntPoint(11).x= 0.0;
5335  Nodes.IntPoint(11).y= 1.0;
5336  Nodes.IntPoint(11).z= 0.5;
5337 }
5338 
5340  DenseMatrix &shape) const
5341 {
5342  double x = ip.x, y = ip.y, z = ip.z;
5343 
5344  shape(0,0) = (1. - y) * (1. - z);
5345  shape(0,1) = 0.;
5346  shape(0,2) = 0.;
5347 
5348  shape(2,0) = y * (1. - z);
5349  shape(2,1) = 0.;
5350  shape(2,2) = 0.;
5351 
5352  shape(4,0) = z * (1. - y);
5353  shape(4,1) = 0.;
5354  shape(4,2) = 0.;
5355 
5356  shape(6,0) = y * z;
5357  shape(6,1) = 0.;
5358  shape(6,2) = 0.;
5359 
5360  shape(1,0) = 0.;
5361  shape(1,1) = x * (1. - z);
5362  shape(1,2) = 0.;
5363 
5364  shape(3,0) = 0.;
5365  shape(3,1) = (1. - x) * (1. - z);
5366  shape(3,2) = 0.;
5367 
5368  shape(5,0) = 0.;
5369  shape(5,1) = x * z;
5370  shape(5,2) = 0.;
5371 
5372  shape(7,0) = 0.;
5373  shape(7,1) = (1. - x) * z;
5374  shape(7,2) = 0.;
5375 
5376  shape(8,0) = 0.;
5377  shape(8,1) = 0.;
5378  shape(8,2) = (1. - x) * (1. - y);
5379 
5380  shape(9,0) = 0.;
5381  shape(9,1) = 0.;
5382  shape(9,2) = x * (1. - y);
5383 
5384  shape(10,0) = 0.;
5385  shape(10,1) = 0.;
5386  shape(10,2) = x * y;
5387 
5388  shape(11,0) = 0.;
5389  shape(11,1) = 0.;
5390  shape(11,2) = y * (1. - x);
5391 
5392 }
5393 
5395  DenseMatrix &curl_shape)
5396 const
5397 {
5398  double x = ip.x, y = ip.y, z = ip.z;
5399 
5400  curl_shape(0,0) = 0.;
5401  curl_shape(0,1) = y - 1.;
5402  curl_shape(0,2) = 1. - z;
5403 
5404  curl_shape(2,0) = 0.;
5405  curl_shape(2,1) = -y;
5406  curl_shape(2,2) = z - 1.;
5407 
5408  curl_shape(4,0) = 0;
5409  curl_shape(4,1) = 1. - y;
5410  curl_shape(4,2) = z;
5411 
5412  curl_shape(6,0) = 0.;
5413  curl_shape(6,1) = y;
5414  curl_shape(6,2) = -z;
5415 
5416  curl_shape(1,0) = x;
5417  curl_shape(1,1) = 0.;
5418  curl_shape(1,2) = 1. - z;
5419 
5420  curl_shape(3,0) = 1. - x;
5421  curl_shape(3,1) = 0.;
5422  curl_shape(3,2) = z - 1.;
5423 
5424  curl_shape(5,0) = -x;
5425  curl_shape(5,1) = 0.;
5426  curl_shape(5,2) = z;
5427 
5428  curl_shape(7,0) = x - 1.;
5429  curl_shape(7,1) = 0.;
5430  curl_shape(7,2) = -z;
5431 
5432  curl_shape(8,0) = x - 1.;
5433  curl_shape(8,1) = 1. - y;
5434  curl_shape(8,2) = 0.;
5435 
5436  curl_shape(9,0) = -x;
5437  curl_shape(9,1) = y - 1.;
5438  curl_shape(9,2) = 0;
5439 
5440  curl_shape(10,0) = x;
5441  curl_shape(10,1) = -y;
5442  curl_shape(10,2) = 0.;
5443 
5444  curl_shape(11,0) = 1. - x;
5445  curl_shape(11,1) = y;
5446  curl_shape(11,2) = 0.;
5447 }
5448 
5449 const double Nedelec1HexFiniteElement::tk[12][3] =
5450 {
5451  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5452  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5453  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
5454 };
5455 
5458 {
5459  int k, j;
5460 #ifdef MFEM_THREAD_SAFE
5462 #endif
5463 
5464 #ifdef MFEM_DEBUG
5465  for (k = 0; k < 12; k++)
5466  {
5468  for (j = 0; j < 12; j++)
5469  {
5470  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5471  vshape(j,2)*tk[k][2] );
5472  if (j == k) { d -= 1.0; }
5473  if (fabs(d) > 1.0e-12)
5474  {
5475  mfem::err << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
5476  " k = " << k << ", j = " << j << ", d = " << d << endl;
5477  mfem_error();
5478  }
5479  }
5480  }
5481 #endif
5482 
5483  IntegrationPoint ip;
5484  ip.x = ip.y = ip.z = 0.0;
5485  Trans.SetIntPoint (&ip);
5486  // Trans must be linear (more to have embedding?)
5487  const DenseMatrix &J = Trans.Jacobian();
5488  double vk[3];
5489  Vector xk (vk, 3);
5490 
5491  for (k = 0; k < 12; k++)
5492  {
5493  Trans.Transform (Nodes.IntPoint (k), xk);
5494  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5495  CalcVShape (ip, vshape);
5496  // vk = J tk
5497  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5498  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5499  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5500  for (j = 0; j < 12; j++)
5501  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5502  vshape(j,2)*vk[2])) < 1.0e-12)
5503  {
5504  I(k,j) = 0.0;
5505  }
5506  }
5507 }
5508 
5511  Vector &dofs) const
5512 {
5513  double vk[3];
5514  Vector xk (vk, 3);
5515 
5516  for (int k = 0; k < 12; k++)
5517  {
5518  Trans.SetIntPoint (&Nodes.IntPoint (k));
5519  const DenseMatrix &J = Trans.Jacobian();
5520 
5521  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5522  // xk^t J tk
5523  dofs(k) =
5524  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5525  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5526  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5527  }
5528 }
5529 
5530 
5532  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
5533 {
5534  // not real nodes ...
5535  Nodes.IntPoint(0).x = 0.5;
5536  Nodes.IntPoint(0).y = 0.0;
5537  Nodes.IntPoint(0).z = 0.0;
5538 
5539  Nodes.IntPoint(1).x = 0.0;
5540  Nodes.IntPoint(1).y = 0.5;
5541  Nodes.IntPoint(1).z = 0.0;
5542 
5543  Nodes.IntPoint(2).x = 0.0;
5544  Nodes.IntPoint(2).y = 0.0;
5545  Nodes.IntPoint(2).z = 0.5;
5546 
5547  Nodes.IntPoint(3).x = 0.5;
5548  Nodes.IntPoint(3).y = 0.5;
5549  Nodes.IntPoint(3).z = 0.0;
5550 
5551  Nodes.IntPoint(4).x = 0.5;
5552  Nodes.IntPoint(4).y = 0.0;
5553  Nodes.IntPoint(4).z = 0.5;
5554 
5555  Nodes.IntPoint(5).x = 0.0;
5556  Nodes.IntPoint(5).y = 0.5;
5557  Nodes.IntPoint(5).z = 0.5;
5558 }
5559 
5561  DenseMatrix &shape) const
5562 {
5563  double x = ip.x, y = ip.y, z = ip.z;
5564 
5565  shape(0,0) = 1. - y - z;
5566  shape(0,1) = x;
5567  shape(0,2) = x;
5568 
5569  shape(1,0) = y;
5570  shape(1,1) = 1. - x - z;
5571  shape(1,2) = y;
5572 
5573  shape(2,0) = z;
5574  shape(2,1) = z;
5575  shape(2,2) = 1. - x - y;
5576 
5577  shape(3,0) = -y;
5578  shape(3,1) = x;
5579  shape(3,2) = 0.;
5580 
5581  shape(4,0) = -z;
5582  shape(4,1) = 0.;
5583  shape(4,2) = x;
5584 
5585  shape(5,0) = 0.;
5586  shape(5,1) = -z;
5587  shape(5,2) = y;
5588 }
5589 
5591  DenseMatrix &curl_shape)
5592 const
5593 {
5594  curl_shape(0,0) = 0.;
5595  curl_shape(0,1) = -2.;
5596  curl_shape(0,2) = 2.;
5597 
5598  curl_shape(1,0) = 2.;
5599  curl_shape(1,1) = 0.;
5600  curl_shape(1,2) = -2.;
5601 
5602  curl_shape(2,0) = -2.;
5603  curl_shape(2,1) = 2.;
5604  curl_shape(2,2) = 0.;
5605 
5606  curl_shape(3,0) = 0.;
5607  curl_shape(3,1) = 0.;
5608  curl_shape(3,2) = 2.;
5609 
5610  curl_shape(4,0) = 0.;
5611  curl_shape(4,1) = -2.;
5612  curl_shape(4,2) = 0.;
5613 
5614  curl_shape(5,0) = 2.;
5615  curl_shape(5,1) = 0.;
5616  curl_shape(5,2) = 0.;
5617 }
5618 
5619 const double Nedelec1TetFiniteElement::tk[6][3] =
5620 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
5621 
5624 {
5625  int k, j;
5626 #ifdef MFEM_THREAD_SAFE
5628 #endif
5629 
5630 #ifdef MFEM_DEBUG
5631  for (k = 0; k < 6; k++)
5632  {
5634  for (j = 0; j < 6; j++)
5635  {
5636  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5637  vshape(j,2)*tk[k][2] );
5638  if (j == k) { d -= 1.0; }
5639  if (fabs(d) > 1.0e-12)
5640  {
5641  mfem::err << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
5642  " k = " << k << ", j = " << j << ", d = " << d << endl;
5643  mfem_error();
5644  }
5645  }
5646  }
5647 #endif
5648 
5649  IntegrationPoint ip;
5650  ip.x = ip.y = ip.z = 0.0;
5651  Trans.SetIntPoint (&ip);
5652  // Trans must be linear
5653  const DenseMatrix &J = Trans.Jacobian();
5654  double vk[3];
5655  Vector xk (vk, 3);
5656 
5657  for (k = 0; k < 6; k++)
5658  {
5659  Trans.Transform (Nodes.IntPoint (k), xk);
5660  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5661  CalcVShape (ip, vshape);
5662  // vk = J tk
5663  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5664  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5665  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5666  for (j = 0; j < 6; j++)
5667  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5668  vshape(j,2)*vk[2])) < 1.0e-12)
5669  {
5670  I(k,j) = 0.0;
5671  }
5672  }
5673 }
5674 
5677  Vector &dofs) const
5678 {
5679  double vk[3];
5680  Vector xk (vk, 3);
5681 
5682  for (int k = 0; k < 6; k++)
5683  {
5684  Trans.SetIntPoint (&Nodes.IntPoint (k));
5685  const DenseMatrix &J = Trans.Jacobian();
5686 
5687  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5688  // xk^t J tk
5689  dofs(k) =
5690  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5691  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5692  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5693  }
5694 }
5695 
5697  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
5698 {
5699  // not real nodes ...
5700  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
5701  Nodes.IntPoint(0).x = 0.5;
5702  Nodes.IntPoint(0).y = 0.5;
5703  Nodes.IntPoint(0).z = 0.0;
5704 
5705  Nodes.IntPoint(1).x = 0.5;
5706  Nodes.IntPoint(1).y = 0.0;
5707  Nodes.IntPoint(1).z = 0.5;
5708 
5709  Nodes.IntPoint(2).x = 1.0;
5710  Nodes.IntPoint(2).y = 0.5;
5711  Nodes.IntPoint(2).z = 0.5;
5712 
5713  Nodes.IntPoint(3).x = 0.5;
5714  Nodes.IntPoint(3).y = 1.0;
5715  Nodes.IntPoint(3).z = 0.5;
5716 
5717  Nodes.IntPoint(4).x = 0.0;
5718  Nodes.IntPoint(4).y = 0.5;
5719  Nodes.IntPoint(4).z = 0.5;
5720 
5721  Nodes.IntPoint(5).x = 0.5;
5722  Nodes.IntPoint(5).y = 0.5;
5723  Nodes.IntPoint(5).z = 1.0;
5724 }
5725 
5727  DenseMatrix &shape) const
5728 {
5729  double x = ip.x, y = ip.y, z = ip.z;
5730  // z = 0
5731  shape(0,0) = 0.;
5732  shape(0,1) = 0.;
5733  shape(0,2) = z - 1.;
5734  // y = 0
5735  shape(1,0) = 0.;
5736  shape(1,1) = y - 1.;
5737  shape(1,2) = 0.;
5738  // x = 1
5739  shape(2,0) = x;
5740  shape(2,1) = 0.;
5741  shape(2,2) = 0.;
5742  // y = 1
5743  shape(3,0) = 0.;
5744  shape(3,1) = y;
5745  shape(3,2) = 0.;
5746  // x = 0
5747  shape(4,0) = x - 1.;
5748  shape(4,1) = 0.;
5749  shape(4,2) = 0.;
5750  // z = 1
5751  shape(5,0) = 0.;
5752  shape(5,1) = 0.;
5753  shape(5,2) = z;
5754 }
5755 
5757  Vector &divshape) const
5758 {
5759  divshape(0) = 1.;
5760  divshape(1) = 1.;
5761  divshape(2) = 1.;
5762  divshape(3) = 1.;
5763  divshape(4) = 1.;
5764  divshape(5) = 1.;
5765 }
5766 
5767 const double RT0HexFiniteElement::nk[6][3] =
5768 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
5769 
5772 {
5773  int k, j;
5774 #ifdef MFEM_THREAD_SAFE
5776  DenseMatrix Jinv(Dim);
5777 #endif
5778 
5779 #ifdef MFEM_DEBUG
5780  for (k = 0; k < 6; k++)
5781  {
5783  for (j = 0; j < 6; j++)
5784  {
5785  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5786  vshape(j,2)*nk[k][2] );
5787  if (j == k) { d -= 1.0; }
5788  if (fabs(d) > 1.0e-12)
5789  {
5790  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5791  " k = " << k << ", j = " << j << ", d = " << d << endl;
5792  mfem_error();
5793  }
5794  }
5795  }
5796 #endif
5797 
5798  IntegrationPoint ip;
5799  ip.x = ip.y = ip.z = 0.0;
5800  Trans.SetIntPoint (&ip);
5801  // Trans must be linear
5802  // set Jinv = |J| J^{-t} = adj(J)^t
5803  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5804  double vk[3];
5805  Vector xk (vk, 3);
5806 
5807  for (k = 0; k < 6; k++)
5808  {
5809  Trans.Transform (Nodes.IntPoint (k), xk);
5810  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5811  CalcVShape (ip, vshape);
5812  // vk = |J| J^{-t} nk
5813  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5814  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5815  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5816  for (j = 0; j < 6; j++)
5817  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5818  vshape(j,2)*vk[2])) < 1.0e-12)
5819  {
5820  I(k,j) = 0.0;
5821  }
5822  }
5823 }
5824 
5827  Vector &dofs) const
5828 {
5829  double vk[3];
5830  Vector xk (vk, 3);
5831 #ifdef MFEM_THREAD_SAFE
5832  DenseMatrix Jinv(Dim);
5833 #endif
5834 
5835  for (int k = 0; k < 6; k++)
5836  {
5837  Trans.SetIntPoint (&Nodes.IntPoint (k));
5838  // set Jinv = |J| J^{-t} = adj(J)^t
5839  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5840 
5841  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5842  // xk^t |J| J^{-t} nk
5843  dofs(k) =
5844  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5845  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5846  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5847  }
5848 }
5849 
5851  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
5852 {
5853  // z = 0
5854  Nodes.IntPoint(2).x = 1./3.;
5855  Nodes.IntPoint(2).y = 1./3.;
5856  Nodes.IntPoint(2).z = 0.0;
5857  Nodes.IntPoint(3).x = 2./3.;
5858  Nodes.IntPoint(3).y = 1./3.;
5859  Nodes.IntPoint(3).z = 0.0;
5860  Nodes.IntPoint(0).x = 1./3.;
5861  Nodes.IntPoint(0).y = 2./3.;
5862  Nodes.IntPoint(0).z = 0.0;
5863  Nodes.IntPoint(1).x = 2./3.;
5864  Nodes.IntPoint(1).y = 2./3.;
5865  Nodes.IntPoint(1).z = 0.0;
5866  // y = 0
5867  Nodes.IntPoint(4).x = 1./3.;
5868  Nodes.IntPoint(4).y = 0.0;
5869  Nodes.IntPoint(4).z = 1./3.;
5870  Nodes.IntPoint(5).x = 2./3.;
5871  Nodes.IntPoint(5).y = 0.0;
5872  Nodes.IntPoint(5).z = 1./3.;
5873  Nodes.IntPoint(6).x = 1./3.;
5874  Nodes.IntPoint(6).y = 0.0;
5875  Nodes.IntPoint(6).z = 2./3.;
5876  Nodes.IntPoint(7).x = 2./3.;
5877  Nodes.IntPoint(7).y = 0.0;
5878  Nodes.IntPoint(7).z = 2./3.;
5879  // x = 1
5880  Nodes.IntPoint(8).x = 1.0;
5881  Nodes.IntPoint(8).y = 1./3.;
5882  Nodes.IntPoint(8).z = 1./3.;
5883  Nodes.IntPoint(9).x = 1.0;
5884  Nodes.IntPoint(9).y = 2./3.;
5885  Nodes.IntPoint(9).z = 1./3.;
5886  Nodes.IntPoint(10).x = 1.0;
5887  Nodes.IntPoint(10).y = 1./3.;
5888  Nodes.IntPoint(10).z = 2./3.;
5889  Nodes.IntPoint(11).x = 1.0;
5890  Nodes.IntPoint(11).y = 2./3.;
5891  Nodes.IntPoint(11).z = 2./3.;
5892  // y = 1
5893  Nodes.IntPoint(13).x = 1./3.;
5894  Nodes.IntPoint(13).y = 1.0;
5895  Nodes.IntPoint(13).z = 1./3.;
5896  Nodes.IntPoint(12).x = 2./3.;
5897  Nodes.IntPoint(12).y = 1.0;
5898  Nodes.IntPoint(12).z = 1./3.;
5899  Nodes.IntPoint(15).x = 1./3.;
5900  Nodes.IntPoint(15).y = 1.0;
5901  Nodes.IntPoint(15).z = 2./3.;
5902  Nodes.IntPoint(14).x = 2./3.;
5903  Nodes.IntPoint(14).y = 1.0;
5904  Nodes.IntPoint(14).z = 2./3.;
5905  // x = 0
5906  Nodes.IntPoint(17).x = 0.0;
5907  Nodes.IntPoint(17).y = 1./3.;
5908  Nodes.IntPoint(17).z = 1./3.;
5909  Nodes.IntPoint(16).x = 0.0;
5910  Nodes.IntPoint(16).y = 2./3.;
5911  Nodes.IntPoint(16).z = 1./3.;
5912  Nodes.IntPoint(19).x = 0.0;
5913  Nodes.IntPoint(19).y = 1./3.;
5914  Nodes.IntPoint(19).z = 2./3.;
5915  Nodes.IntPoint(18).x = 0.0;
5916  Nodes.IntPoint(18).y = 2./3.;
5917  Nodes.IntPoint(18).z = 2./3.;
5918  // z = 1
5919  Nodes.IntPoint(20).x = 1./3.;
5920  Nodes.IntPoint(20).y = 1./3.;
5921  Nodes.IntPoint(20).z = 1.0;
5922  Nodes.IntPoint(21).x = 2./3.;
5923  Nodes.IntPoint(21).y = 1./3.;
5924  Nodes.IntPoint(21).z = 1.0;
5925  Nodes.IntPoint(22).x = 1./3.;
5926  Nodes.IntPoint(22).y = 2./3.;
5927  Nodes.IntPoint(22).z = 1.0;
5928  Nodes.IntPoint(23).x = 2./3.;
5929  Nodes.IntPoint(23).y = 2./3.;
5930  Nodes.IntPoint(23).z = 1.0;
5931  // x = 0.5 (interior)
5932  Nodes.IntPoint(24).x = 0.5;
5933  Nodes.IntPoint(24).y = 1./3.;
5934  Nodes.IntPoint(24).z = 1./3.;
5935  Nodes.IntPoint(25).x = 0.5;
5936  Nodes.IntPoint(25).y = 1./3.;
5937  Nodes.IntPoint(25).z = 2./3.;
5938  Nodes.IntPoint(26).x = 0.5;
5939  Nodes.IntPoint(26).y = 2./3.;
5940  Nodes.IntPoint(26).z = 1./3.;
5941  Nodes.IntPoint(27).x = 0.5;
5942  Nodes.IntPoint(27).y = 2./3.;
5943  Nodes.IntPoint(27).z = 2./3.;
5944  // y = 0.5 (interior)
5945  Nodes.IntPoint(28).x = 1./3.;
5946  Nodes.IntPoint(28).y = 0.5;
5947  Nodes.IntPoint(28).z = 1./3.;
5948  Nodes.IntPoint(29).x = 1./3.;
5949  Nodes.IntPoint(29).y = 0.5;
5950  Nodes.IntPoint(29).z = 2./3.;
5951  Nodes.IntPoint(30).x = 2./3.;
5952  Nodes.IntPoint(30).y = 0.5;
5953  Nodes.IntPoint(30).z = 1./3.;
5954  Nodes.IntPoint(31).x = 2./3.;
5955  Nodes.IntPoint(31).y = 0.5;
5956  Nodes.IntPoint(31).z = 2./3.;
5957  // z = 0.5 (interior)
5958  Nodes.IntPoint(32).x = 1./3.;
5959  Nodes.IntPoint(32).y = 1./3.;
5960  Nodes.IntPoint(32).z = 0.5;
5961  Nodes.IntPoint(33).x = 1./3.;
5962  Nodes.IntPoint(33).y = 2./3.;
5963  Nodes.IntPoint(33).z = 0.5;
5964  Nodes.IntPoint(34).x = 2./3.;
5965  Nodes.IntPoint(34).y = 1./3.;
5966  Nodes.IntPoint(34).z = 0.5;
5967  Nodes.IntPoint(35).x = 2./3.;
5968  Nodes.IntPoint(35).y = 2./3.;
5969  Nodes.IntPoint(35).z = 0.5;
5970 }
5971 
5973  DenseMatrix &shape) const
5974 {
5975  double x = ip.x, y = ip.y, z = ip.z;
5976  // z = 0
5977  shape(2,0) = 0.;
5978  shape(2,1) = 0.;
5979  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5980  shape(3,0) = 0.;
5981  shape(3,1) = 0.;
5982  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5983  shape(0,0) = 0.;
5984  shape(0,1) = 0.;
5985  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5986  shape(1,0) = 0.;
5987  shape(1,1) = 0.;
5988  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5989  // y = 0
5990  shape(4,0) = 0.;
5991  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5992  shape(4,2) = 0.;
5993  shape(5,0) = 0.;
5994  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5995  shape(5,2) = 0.;
5996  shape(6,0) = 0.;
5997  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5998  shape(6,2) = 0.;
5999  shape(7,0) = 0.;
6000  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6001  shape(7,2) = 0.;
6002  // x = 1
6003  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6004  shape(8,1) = 0.;
6005  shape(8,2) = 0.;
6006  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6007  shape(9,1) = 0.;
6008  shape(9,2) = 0.;
6009  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6010  shape(10,1) = 0.;
6011  shape(10,2) = 0.;
6012  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6013  shape(11,1) = 0.;
6014  shape(11,2) = 0.;
6015  // y = 1
6016  shape(13,0) = 0.;
6017  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6018  shape(13,2) = 0.;
6019  shape(12,0) = 0.;
6020  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6021  shape(12,2) = 0.;
6022  shape(15,0) = 0.;
6023  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6024  shape(15,2) = 0.;
6025  shape(14,0) = 0.;
6026  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6027  shape(14,2) = 0.;
6028  // x = 0
6029  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6030  shape(17,1) = 0.;
6031  shape(17,2) = 0.;
6032  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6033  shape(16,1) = 0.;
6034  shape(16,2) = 0.;
6035  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6036  shape(19,1) = 0.;
6037  shape(19,2) = 0.;
6038  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6039  shape(18,1) = 0.;
6040  shape(18,2) = 0.;
6041  // z = 1
6042  shape(20,0) = 0.;
6043  shape(20,1) = 0.;
6044  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6045  shape(21,0) = 0.;
6046  shape(21,1) = 0.;
6047  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6048  shape(22,0) = 0.;
6049  shape(22,1) = 0.;
6050  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6051  shape(23,0) = 0.;
6052  shape(23,1) = 0.;
6053  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6054  // x = 0.5 (interior)
6055  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
6056  shape(24,1) = 0.;
6057  shape(24,2) = 0.;
6058  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
6059  shape(25,1) = 0.;
6060  shape(25,2) = 0.;
6061  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
6062  shape(26,1) = 0.;
6063  shape(26,2) = 0.;
6064  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
6065  shape(27,1) = 0.;
6066  shape(27,2) = 0.;
6067  // y = 0.5 (interior)
6068  shape(28,0) = 0.;
6069  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
6070  shape(28,2) = 0.;
6071  shape(29,0) = 0.;
6072  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
6073  shape(29,2) = 0.;
6074  shape(30,0) = 0.;
6075  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
6076  shape(30,2) = 0.;
6077  shape(31,0) = 0.;
6078  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
6079  shape(31,2) = 0.;
6080  // z = 0.5 (interior)
6081  shape(32,0) = 0.;
6082  shape(32,1) = 0.;
6083  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
6084  shape(33,0) = 0.;
6085  shape(33,1) = 0.;
6086  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
6087  shape(34,0) = 0.;
6088  shape(34,1) = 0.;
6089  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
6090  shape(35,0) = 0.;
6091  shape(35,1) = 0.;
6092  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
6093 }
6094 
6096  Vector &divshape) const
6097 {
6098  double x = ip.x, y = ip.y, z = ip.z;
6099  // z = 0
6100  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6101  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6102  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6103  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6104  // y = 0
6105  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6106  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6107  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6108  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6109  // x = 1
6110  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6111  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6112  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6113  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6114  // y = 1
6115  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6116  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6117  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6118  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6119  // x = 0
6120  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6121  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6122  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6123  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6124  // z = 1
6125  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6126  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6127  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6128  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6129  // x = 0.5 (interior)
6130  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
6131  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
6132  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
6133  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
6134  // y = 0.5 (interior)
6135  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
6136  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
6137  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
6138  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
6139  // z = 0.5 (interior)
6140  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
6141  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
6142  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
6143  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
6144 }
6145 
6146 const double RT1HexFiniteElement::nk[36][3] =
6147 {
6148  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
6149  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
6150  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
6151  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
6152  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
6153  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
6154  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
6155  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
6156  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
6157 };
6158 
6161 {
6162  int k, j;
6163 #ifdef MFEM_THREAD_SAFE
6165  DenseMatrix Jinv(Dim);
6166 #endif
6167 
6168 #ifdef MFEM_DEBUG
6169  for (k = 0; k < 36; k++)
6170  {
6172  for (j = 0; j < 36; j++)
6173  {
6174  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6175  vshape(j,2)*nk[k][2] );
6176  if (j == k) { d -= 1.0; }
6177  if (fabs(d) > 1.0e-12)
6178  {
6179  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
6180  " k = " << k << ", j = " << j << ", d = " << d << endl;
6181  mfem_error();
6182  }
6183  }
6184  }
6185 #endif
6186 
6187  IntegrationPoint ip;
6188  ip.x = ip.y = ip.z = 0.0;
6189  Trans.SetIntPoint (&ip);
6190  // Trans must be linear
6191  // set Jinv = |J| J^{-t} = adj(J)^t
6192  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6193  double vk[3];
6194  Vector xk (vk, 3);
6195 
6196  for (k = 0; k < 36; k++)
6197  {
6198  Trans.Transform (Nodes.IntPoint (k), xk);
6199  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6200  CalcVShape (ip, vshape);
6201  // vk = |J| J^{-t} nk
6202  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6203  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6204  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6205  for (j = 0; j < 36; j++)
6206  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6207  vshape(j,2)*vk[2])) < 1.0e-12)
6208  {
6209  I(k,j) = 0.0;
6210  }
6211  }
6212 }
6213 
6216  Vector &dofs) const
6217 {
6218  double vk[3];
6219  Vector xk (vk, 3);
6220 #ifdef MFEM_THREAD_SAFE
6221  DenseMatrix Jinv(Dim);
6222 #endif
6223 
6224  for (int k = 0; k < 36; k++)
6225  {
6226  Trans.SetIntPoint (&Nodes.IntPoint (k));
6227  // set Jinv = |J| J^{-t} = adj(J)^t
6228  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6229 
6230  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6231  // xk^t |J| J^{-t} nk
6232  dofs(k) =
6233  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6234  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6235  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6236  }
6237 }
6238 
6240  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
6241 {
6242  // not real nodes ...
6243  Nodes.IntPoint(0).x = 0.33333333333333333333;
6244  Nodes.IntPoint(0).y = 0.33333333333333333333;
6245  Nodes.IntPoint(0).z = 0.33333333333333333333;
6246 
6247  Nodes.IntPoint(1).x = 0.0;
6248  Nodes.IntPoint(1).y = 0.33333333333333333333;
6249  Nodes.IntPoint(1).z = 0.33333333333333333333;
6250 
6251  Nodes.IntPoint(2).x = 0.33333333333333333333;
6252  Nodes.IntPoint(2).y = 0.0;
6253  Nodes.IntPoint(2).z = 0.33333333333333333333;
6254 
6255  Nodes.IntPoint(3).x = 0.33333333333333333333;
6256  Nodes.IntPoint(3).y = 0.33333333333333333333;
6257  Nodes.IntPoint(3).z = 0.0;
6258 }
6259 
6261  DenseMatrix &shape) const
6262 {
6263  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
6264 
6265  shape(0,0) = x2;
6266  shape(0,1) = y2;
6267  shape(0,2) = z2;
6268 
6269  shape(1,0) = x2 - 2.0;
6270  shape(1,1) = y2;
6271  shape(1,2) = z2;
6272 
6273  shape(2,0) = x2;
6274  shape(2,1) = y2 - 2.0;
6275  shape(2,2) = z2;
6276 
6277  shape(3,0) = x2;
6278  shape(3,1) = y2;
6279  shape(3,2) = z2 - 2.0;
6280 }
6281 
6283  Vector &divshape) const
6284 {
6285  divshape(0) = 6.0;
6286  divshape(1) = 6.0;
6287  divshape(2) = 6.0;
6288  divshape(3) = 6.0;
6289 }
6290 
6291 const double RT0TetFiniteElement::nk[4][3] =
6292 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
6293 
6296 {
6297  int k, j;
6298 #ifdef MFEM_THREAD_SAFE
6300  DenseMatrix Jinv(Dim);
6301 #endif
6302 
6303 #ifdef MFEM_DEBUG
6304  for (k = 0; k < 4; k++)
6305  {
6307  for (j = 0; j < 4; j++)
6308  {
6309  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6310  vshape(j,2)*nk[k][2] );
6311  if (j == k) { d -= 1.0; }
6312  if (fabs(d) > 1.0e-12)
6313  {
6314  mfem::err << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
6315  " k = " << k << ", j = " << j << ", d = " << d << endl;
6316  mfem_error();
6317  }
6318  }
6319  }
6320 #endif
6321 
6322  IntegrationPoint ip;
6323  ip.x = ip.y = ip.z = 0.0;
6324  Trans.SetIntPoint (&ip);
6325  // Trans must be linear
6326  // set Jinv = |J| J^{-t} = adj(J)^t
6327  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6328  double vk[3];
6329  Vector xk (vk, 3);
6330 
6331  for (k = 0; k < 4; k++)
6332  {
6333  Trans.Transform (Nodes.IntPoint (k), xk);
6334  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6335  CalcVShape (ip, vshape);
6336  // vk = |J| J^{-t} nk
6337  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6338  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6339  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6340  for (j = 0; j < 4; j++)
6341  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6342  vshape(j,2)*vk[2])) < 1.0e-12)
6343  {
6344  I(k,j) = 0.0;
6345  }
6346  }
6347 }
6348 
6351  Vector &dofs) const
6352 {
6353  double vk[3];
6354  Vector xk (vk, 3);
6355 #ifdef MFEM_THREAD_SAFE
6356  DenseMatrix Jinv(Dim);
6357 #endif
6358 
6359  for (int k = 0; k < 4; k++)
6360  {
6361  Trans.SetIntPoint (&Nodes.IntPoint (k));
6362  // set Jinv = |J| J^{-t} = adj(J)^t
6363  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6364 
6365  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6366  // xk^t |J| J^{-t} nk
6367  dofs(k) =
6368  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6369  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6370  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6371  }
6372 }
6373 
6375  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
6376 {
6377  Nodes.IntPoint(0).x = 0.5;
6378  Nodes.IntPoint(0).y = 0.5;
6379  Nodes.IntPoint(0).z = 0.0;
6380 
6381  Nodes.IntPoint(1).x = 0.5;
6382  Nodes.IntPoint(1).y = 0.0;
6383  Nodes.IntPoint(1).z = 0.5;
6384 
6385  Nodes.IntPoint(2).x = 1.0;
6386  Nodes.IntPoint(2).y = 0.5;
6387  Nodes.IntPoint(2).z = 0.5;
6388 
6389  Nodes.IntPoint(3).x = 0.5;
6390  Nodes.IntPoint(3).y = 1.0;
6391  Nodes.IntPoint(3).z = 0.5;
6392 
6393  Nodes.IntPoint(4).x = 0.0;
6394  Nodes.IntPoint(4).y = 0.5;
6395  Nodes.IntPoint(4).z = 0.5;
6396 
6397  Nodes.IntPoint(5).x = 0.5;
6398  Nodes.IntPoint(5).y = 0.5;
6399  Nodes.IntPoint(5).z = 1.0;
6400 }
6401 
6403  Vector &shape) const
6404 {
6405  double x = 2. * ip.x - 1.;
6406  double y = 2. * ip.y - 1.;
6407  double z = 2. * ip.z - 1.;
6408  double f5 = x * x - y * y;
6409  double f6 = y * y - z * z;
6410 
6411  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
6412  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
6413  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
6414  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
6415  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
6416  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
6417 }
6418 
6420  DenseMatrix &dshape) const
6421 {
6422  const double a = 2./3.;
6423 
6424  double xt = a * (1. - 2. * ip.x);
6425  double yt = a * (1. - 2. * ip.y);
6426  double zt = a * (1. - 2. * ip.z);
6427 
6428  dshape(0,0) = xt;
6429  dshape(0,1) = yt;
6430  dshape(0,2) = -1. - 2. * zt;
6431 
6432  dshape(1,0) = xt;
6433  dshape(1,1) = -1. - 2. * yt;
6434  dshape(1,2) = zt;
6435 
6436  dshape(2,0) = 1. - 2. * xt;
6437  dshape(2,1) = yt;
6438  dshape(2,2) = zt;
6439 
6440  dshape(3,0) = xt;
6441  dshape(3,1) = 1. - 2. * yt;
6442  dshape(3,2) = zt;
6443 
6444  dshape(4,0) = -1. - 2. * xt;
6445  dshape(4,1) = yt;
6446  dshape(4,2) = zt;
6447 
6448  dshape(5,0) = xt;
6449  dshape(5,1) = yt;
6450  dshape(5,2) = 1. - 2. * zt;
6451 }
6452 
6453 
6454 Poly_1D::Basis::Basis(const int p, const double *nodes, EvalType etype)
6455  : etype(etype)
6456 {
6457  switch (etype)
6458  {
6459  case ChangeOfBasis:
6460  {
6461  x.SetSize(p + 1);
6462  w.SetSize(p + 1);
6463  DenseMatrix A(p + 1);
6464  for (int i = 0; i <= p; i++)
6465  {
6466  CalcBasis(p, nodes[i], A.GetColumn(i));
6467  }
6468  Ai.Factor(A);
6469  // mfem::out << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
6470  break;
6471  }
6472  case Barycentric:
6473  {
6474  x.SetSize(p + 1);
6475  w.SetSize(p + 1);
6476  x = nodes;
6477  w = 1.0;
6478  for (int i = 0; i <= p; i++)
6479  {
6480  for (int j = 0; j < i; j++)
6481  {
6482  double xij = x(i) - x(j);
6483  w(i) *= xij;
6484  w(j) *= -xij;
6485  }
6486  }
6487  for (int i = 0; i <= p; i++)
6488  {
6489  w(i) = 1.0/w(i);
6490  }
6491 
6492 #ifdef MFEM_DEBUG
6493  // Make sure the nodes are increasing
6494  for (int i = 0; i < p; i++)
6495  {
6496  if (x(i) >= x(i+1))
6497  {
6498  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
6499  }
6500  }
6501 #endif
6502  break;
6503  }
6504  case Positive:
6505  x.SetDataAndSize(NULL, p + 1); // use x to store (p + 1)
6506  break;
6507 
6508  default: break;
6509  }
6510 }
6511 
6512 void Poly_1D::Basis::Eval(const double y, Vector &u) const
6513 {
6514  switch (etype)
6515  {
6516  case ChangeOfBasis:
6517  {
6518  CalcBasis(Ai.Width() - 1, y, x);
6519  Ai.Mult(x, u);
6520  break;
6521  }
6522  case Barycentric:
6523  {
6524  int i, k, p = x.Size() - 1;
6525  double l, lk;
6526 
6527  if (p == 0)
6528  {
6529  u(0) = 1.0;
6530  return;
6531  }
6532 
6533  lk = 1.0;
6534  for (k = 0; k < p; k++)
6535  {
6536  if (y >= (x(k) + x(k+1))/2)
6537  {
6538  lk *= y - x(k);
6539  }
6540  else
6541  {
6542  for (i = k+1; i <= p; i++)
6543  {
6544  lk *= y - x(i);
6545  }
6546  break;
6547  }
6548  }
6549  l = lk * (y - x(k));
6550 
6551  for (i = 0; i < k; i++)
6552  {
6553  u(i) = l * w(i) / (y - x(i));
6554  }
6555  u(k) = lk * w(k);
6556  for (i++; i <= p; i++)
6557  {
6558  u(i) = l * w(i) / (y - x(i));
6559  }
6560  break;
6561  }
6562  case Positive:
6563  CalcBernstein(x.Size() - 1, y, u);
6564  break;
6565 
6566  default: break;
6567  }
6568 }
6569 
6570 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
6571 {
6572  switch (etype)
6573  {
6574  case ChangeOfBasis:
6575  {
6576  CalcBasis(Ai.Width() - 1, y, x, w);
6577  Ai.Mult(x, u);
6578  Ai.Mult(w, d);
6579  break;
6580  }
6581  case Barycentric:
6582  {
6583  int i, k, p = x.Size() - 1;
6584  double l, lp, lk, sk, si;
6585 
6586  if (p == 0)
6587  {
6588  u(0) = 1.0;
6589  d(0) = 0.0;
6590  return;
6591  }
6592 
6593  lk = 1.0;
6594  for (k = 0; k < p; k++)
6595  {
6596  if (y >= (x(k) + x(k+1))/2)
6597  {
6598  lk *= y - x(k);
6599  }
6600  else
6601  {
6602  for (i = k+1; i <= p; i++)
6603  {
6604  lk *= y - x(i);
6605  }
6606  break;
6607  }
6608  }
6609  l = lk * (y - x(k));
6610 
6611  sk = 0.0;
6612  for (i = 0; i < k; i++)
6613  {
6614  si = 1.0/(y - x(i));
6615  sk += si;
6616  u(i) = l * si * w(i);
6617  }
6618  u(k) = lk * w(k);
6619  for (i++; i <= p; i++)
6620  {
6621  si = 1.0/(y - x(i));
6622  sk += si;
6623  u(i) = l * si * w(i);
6624  }
6625  lp = l * sk + lk;
6626 
6627  for (i = 0; i < k; i++)
6628  {
6629  d(i) = (lp * w(i) - u(i))/(y - x(i));
6630  }
6631  d(k) = sk * u(k);
6632  for (i++; i <= p; i++)
6633  {
6634  d(i) = (lp * w(i) - u(i))/(y - x(i));
6635  }
6636  break;
6637  }
6638  case Positive:
6639  CalcBernstein(x.Size() - 1, y, u, d);
6640  break;
6641 
6642  default: break;
6643  }
6644 }
6645 
6646 const int *Poly_1D::Binom(const int p)
6647 {
6648  if (binom.NumCols() <= p)
6649  {
6650  binom.SetSize(p + 1, p + 1);
6651  for (int i = 0; i <= p; i++)
6652  {
6653  binom(i,0) = binom(i,i) = 1;
6654  for (int j = 1; j < i; j++)
6655  {
6656  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
6657  }
6658  }
6659  }
6660  return binom[p];
6661 }
6662 
6663 void Poly_1D::ChebyshevPoints(const int p, double *x)
6664 {
6665  for (int i = 0; i <= p; i++)
6666  {
6667  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
6668  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
6669  x[i] = s*s;
6670  }
6671 }
6672 
6673 void Poly_1D::CalcMono(const int p, const double x, double *u)
6674 {
6675  double xn;
6676  u[0] = xn = 1.;
6677  for (int n = 1; n <= p; n++)
6678  {
6679  u[n] = (xn *= x);
6680  }
6681 }
6682 
6683 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
6684 {
6685  double xn;
6686  u[0] = xn = 1.;
6687  d[0] = 0.;
6688  for (int n = 1; n <= p; n++)
6689  {
6690  d[n] = n * xn;
6691  u[n] = (xn *= x);
6692  }
6693 }
6694 
6695 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6696  double *u)
6697 {
6698  if (p == 0)
6699  {
6700  u[0] = 1.;
6701  }
6702  else
6703  {
6704  int i;
6705  const int *b = Binom(p);
6706  double z = x;
6707 
6708  for (i = 1; i < p; i++)
6709  {
6710  u[i] = b[i]*z;
6711  z *= x;
6712  }
6713  u[p] = z;
6714  z = y;
6715  for (i--; i > 0; i--)
6716  {
6717  u[i] *= z;
6718  z *= y;
6719  }
6720  u[0] = z;
6721  }
6722 }
6723 
6724 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6725  double *u, double *d)
6726 {
6727  if (p == 0)
6728  {
6729  u[0] = 1.;
6730  d[0] = 0.;
6731  }
6732  else
6733  {
6734  int i;
6735  const int *b = Binom(p);
6736  const double xpy = x + y, ptx = p*x;
6737  double z = 1.;
6738 
6739  for (i = 1; i < p; i++)
6740  {
6741  d[i] = b[i]*z*(i*xpy - ptx);
6742  z *= x;
6743  u[i] = b[i]*z;
6744  }
6745  d[p] = p*z;
6746  u[p] = z*x;
6747  z = 1.;
6748  for (i--; i > 0; i--)
6749  {
6750  d[i] *= z;
6751  z *= y;
6752  u[i] *= z;
6753  }
6754  d[0] = -p*z;
6755  u[0] = z*y;
6756  }
6757 }
6758 
6759 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
6760  double *d)
6761 {
6762  if (p == 0)
6763  {
6764  d[0] = 0.;
6765  }
6766  else
6767  {
6768  int i;
6769  const int *b = Binom(p);
6770  const double xpy = x + y, ptx = p*x;
6771  double z = 1.;
6772 
6773  for (i = 1; i < p; i++)
6774  {
6775  d[i] = b[i]*z*(i*xpy - ptx);
6776  z *= x;
6777  }
6778  d[p] = p*z;
6779  z = 1.;
6780  for (i--; i > 0; i--)
6781  {
6782  d[i] *= z;
6783  z *= y;
6784  }
6785  d[0] = -p*z;
6786  }
6787 }
6788 
6789 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
6790 {
6791  // use the recursive definition for [-1,1]:
6792  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6793  double z;
6794  u[0] = 1.;
6795  if (p == 0) { return; }
6796  u[1] = z = 2.*x - 1.;
6797  for (int n = 1; n < p; n++)
6798  {
6799  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6800  }
6801 }
6802 
6803 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
6804 {
6805  // use the recursive definition for [-1,1]:
6806  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6807  // for the derivative use, z in [-1,1]:
6808  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
6809  double z;
6810  u[0] = 1.;
6811  d[0] = 0.;
6812  if (p == 0) { return; }
6813  u[1] = z = 2.*x - 1.;
6814  d[1] = 2.;
6815  for (int n = 1; n < p; n++)
6816  {
6817  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6818  d[n+1] = (4*n + 2)*u[n] + d[n-1];
6819  }
6820 }
6821 
6822 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
6823 {
6824  // recursive definition, z in [-1,1]
6825  // T_0(z) = 1, T_1(z) = z
6826  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6827  double z;
6828  u[0] = 1.;
6829  if (p == 0) { return; }
6830  u[1] = z = 2.*x - 1.;
6831  for (int n = 1; n < p; n++)
6832  {
6833  u[n+1] = 2*z*u[n] - u[n-1];
6834  }
6835 }
6836 
6837 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
6838 {
6839  // recursive definition, z in [-1,1]
6840  // T_0(z) = 1, T_1(z) = z
6841  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6842  // T'_n(z) = n*U_{n-1}(z)
6843  // U_0(z) = 1 U_1(z) = 2*z
6844  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
6845  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
6846  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
6847  double z;
6848  u[0] = 1.;
6849  d[0] = 0.;
6850  if (p == 0) { return; }
6851  u[1] = z = 2.*x - 1.;
6852  d[1] = 2.;
6853  for (int n = 1; n < p; n++)
6854  {
6855  u[n+1] = 2*z*u[n] - u[n-1];
6856  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
6857  }
6858 }
6859 
6860 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d,
6861  double *dd)
6862 {
6863  // recursive definition, z in [-1,1]
6864  // T_0(z) = 1, T_1(z) = z
6865  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6866  // T'_n(z) = n*U_{n-1}(z)
6867  // U_0(z) = 1 U_1(z) = 2*z
6868  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
6869  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
6870  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
6871  // T''_{n+1}(z) = (n + 1)*(2*(n + 1)*T'_n(z) + z*T''_n(z)) / n
6872  double z;
6873  u[0] = 1.;
6874  d[0] = 0.;
6875  dd[0]= 0.;
6876  if (p == 0) { return; }
6877  u[1] = z = 2.*x - 1.;
6878  d[1] = 2.;
6879  dd[1] = 0;
6880  for (int n = 1; n < p; n++)
6881  {
6882  u[n+1] = 2*z*u[n] - u[n-1];
6883  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
6884  dd[n+1] = (n + 1)*(2.*(n + 1)*d[n] + z*dd[n])/n;
6885  }
6886 }
6887 
6888 const double *Poly_1D::GetPoints(const int p, const int btype)
6889 {
6890  BasisType::Check(btype);
6891  const int qtype = BasisType::GetQuadrature1D(btype);
6892 
6893  if (qtype == Quadrature1D::Invalid) { return NULL; }
6894 
6895  if (points_container.find(btype) == points_container.end())
6896  {
6897  points_container[btype] = new Array<double*>;
6898  }
6899  Array<double*> &pts = *points_container[btype];
6900  if (pts.Size() <= p)
6901  {
6902  pts.SetSize(p + 1, NULL);
6903  }
6904  if (pts[p] == NULL)
6905  {
6906  pts[p] = new double[p + 1];
6907  quad_func.GivePolyPoints(p+1, pts[p], qtype);
6908  }
6909  return pts[p];
6910 }
6911 
6912 Poly_1D::Basis &Poly_1D::GetBasis(const int p, const int btype)
6913 {
6914  BasisType::Check(btype);
6915 
6916  if ( bases_container.find(btype) == bases_container.end() )
6917  {
6918  // we haven't been asked for basis or points of this type yet
6919  bases_container[btype] = new Array<Basis*>;
6920  }
6921  Array<Basis*> &bases = *bases_container[btype];
6922  if (bases.Size() <= p)
6923  {
6924  bases.SetSize(p + 1, NULL);
6925  }
6926  if (bases[p] == NULL)
6927  {
6928  EvalType etype = (btype == BasisType::Positive) ? Positive : Barycentric;
6929  bases[p] = new Basis(p, GetPoints(p, btype), etype);
6930  }
6931  return *bases[p];
6932 }
6933 
6935 {
6936  for (PointsMap::iterator it = points_container.begin();
6937  it != points_container.end() ; ++it)
6938  {
6939  Array<double*>& pts = *it->second;
6940  for ( int i = 0 ; i < pts.Size() ; ++i )
6941  {
6942  delete [] pts[i];
6943  }
6944  delete it->second;
6945  }
6946 
6947  for (BasisMap::iterator it = bases_container.begin();
6948  it != bases_container.end() ; ++it)
6949  {
6950  Array<Basis*>& bases = *it->second;
6951  for ( int i = 0 ; i < bases.Size() ; ++i )
6952  {
6953  delete bases[i];
6954  }
6955  delete it->second;
6956  }
6957 }
6958 
6959 Array2D<int> Poly_1D::binom;
6961 
6962 
6963 TensorBasisElement::TensorBasisElement(const int dims, const int p,
6964  const int btype, const DofMapType dmtype)
6965  : b_type(btype),
6966  basis1d(poly1d.GetBasis(p, b_type))
6967 {
6968  if (dmtype == H1_DOF_MAP)
6969  {
6970  switch (dims)
6971  {
6972  case 1:
6973  {
6974  dof_map.SetSize(p + 1);
6975  dof_map[0] = 0;
6976  dof_map[p] = 1;
6977  for (int i = 1; i < p; i++)
6978  {
6979  dof_map[i] = i+1;
6980  }
6981  break;
6982  }
6983  case 2:
6984  {
6985  const int p1 = p + 1;
6986  dof_map.SetSize(p1*p1);
6987 
6988  // vertices
6989  dof_map[0 + 0*p1] = 0;
6990  dof_map[p + 0*p1] = 1;
6991  dof_map[p + p*p1] = 2;
6992  dof_map[0 + p*p1] = 3;
6993 
6994  // edges
6995  int o = 4;
6996  for (int i = 1; i < p; i++)
6997  {
6998  dof_map[i + 0*p1] = o++;
6999  }
7000  for (int i = 1; i < p; i++)
7001  {
7002  dof_map[p + i*p1] = o++;
7003  }
7004  for (int i = 1; i < p; i++)
7005  {
7006  dof_map[(p-i) + p*p1] = o++;
7007  }
7008  for (int i = 1; i < p; i++)
7009  {
7010  dof_map[0 + (p-i)*p1] = o++;
7011  }
7012 
7013  // interior
7014  for (int j = 1; j < p; j++)
7015  {
7016  for (int i = 1; i < p; i++)
7017  {
7018  dof_map[i + j*p1] = o++;
7019  }
7020  }
7021  break;
7022  }
7023  case 3:
7024  {
7025  const int p1 = p + 1;
7026  dof_map.SetSize(p1*p1*p1);
7027 
7028  // vertices
7029  dof_map[0 + (0 + 0*p1)*p1] = 0;
7030  dof_map[p + (0 + 0*p1)*p1] = 1;
7031  dof_map[p + (p + 0*p1)*p1] = 2;
7032  dof_map[0 + (p + 0*p1)*p1] = 3;
7033  dof_map[0 + (0 + p*p1)*p1] = 4;
7034  dof_map[p + (0 + p*p1)*p1] = 5;
7035  dof_map[p + (p + p*p1)*p1] = 6;
7036  dof_map[0 + (p + p*p1)*p1] = 7;
7037 
7038  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
7039  int o = 8;
7040  for (int i = 1; i < p; i++)
7041  {
7042  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
7043  }
7044  for (int i = 1; i < p; i++)
7045  {
7046  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
7047  }
7048  for (int i = 1; i < p; i++)
7049  {
7050  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
7051  }
7052  for (int i = 1; i < p; i++)
7053  {
7054  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
7055  }
7056  for (int i = 1; i < p; i++)
7057  {
7058  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
7059  }
7060  for (int i = 1; i < p; i++)
7061  {
7062  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
7063  }
7064  for (int i = 1; i < p; i++)
7065  {
7066  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
7067  }
7068  for (int i = 1; i < p; i++)
7069  {
7070  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
7071  }
7072  for (int i = 1; i < p; i++)
7073  {
7074  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
7075  }
7076  for (int i = 1; i < p; i++)
7077  {
7078  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
7079  }
7080  for (int i = 1; i < p; i++)
7081  {
7082  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
7083  }
7084  for (int i = 1; i < p; i++)
7085  {
7086  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
7087  }
7088 
7089  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7090  for (int j = 1; j < p; j++)
7091  {
7092  for (int i = 1; i < p; i++)
7093  {
7094  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
7095  }
7096  }
7097  for (int j = 1; j < p; j++)
7098  {
7099  for (int i = 1; i < p; i++)
7100  {
7101  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
7102  }
7103  }
7104  for (int j = 1; j < p; j++)
7105  {
7106  for (int i = 1; i < p; i++)
7107  {
7108  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
7109  }
7110  }
7111  for (int j = 1; j < p; j++)
7112  {
7113  for (int i = 1; i < p; i++)
7114  {
7115  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
7116  }
7117  }
7118  for (int j = 1; j < p; j++)
7119  {
7120  for (int i = 1; i < p; i++)
7121  {
7122  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
7123  }
7124  }
7125  for (int j = 1; j < p; j++)
7126  {
7127  for (int i = 1; i < p; i++)
7128  {
7129  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
7130  }
7131  }
7132 
7133  // interior
7134  for (int k = 1; k < p; k++)
7135  {
7136  for (int j = 1; j < p; j++)
7137  {
7138  for (int i = 1; i < p; i++)
7139  {
7140  dof_map[i + (j + k*p1)*p1] = o++;
7141  }
7142  }
7143  }
7144  break;
7145  }
7146  default:
7147  MFEM_ABORT("invalid dimension: " << dims);
7148  break;
7149  }
7150  }
7151  else if (dmtype == L2_DOF_MAP)
7152  {
7153  // leave dof_map empty, indicating that the dofs are ordered
7154  // lexicographically, i.e. the dof_map is identity
7155  }
7156  else
7157  {
7158  MFEM_ABORT("invalid DofMapType: " << dmtype);
7159  }
7160 }
7161 
7162 
7164  const int p,
7165  const int btype,
7166  const DofMapType dmtype)
7167  : NodalFiniteElement(dims, GetTensorProductGeometry(dims), Pow(p + 1, dims),
7168  p, dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
7169  TensorBasisElement(dims, p, VerifyNodal(btype), dmtype) { }
7170 
7171 
7173  const int dims, const int p, const DofMapType dmtype)
7174  : PositiveFiniteElement(dims, GetTensorProductGeometry(dims),
7175  Pow(p + 1, dims), p,
7176  dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
7177  TensorBasisElement(dims, p, BasisType::Positive, dmtype) { }
7178 
7179 
7180 H1_SegmentElement::H1_SegmentElement(const int p, const int btype)
7181  : NodalTensorFiniteElement(1, p, VerifyClosed(btype), H1_DOF_MAP)
7182 {
7183  const double *cp = poly1d.ClosedPoints(p, b_type);
7184 
7185 #ifndef MFEM_THREAD_SAFE
7186  shape_x.SetSize(p+1);
7187  dshape_x.SetSize(p+1);
7188 #endif
7189 
7190  Nodes.IntPoint(0).x = cp[0];
7191  Nodes.IntPoint(1).x = cp[p];
7192  for (int i = 1; i < p; i++)
7193  {
7194  Nodes.IntPoint(i+1).x = cp[i];
7195  }
7196 }
7197 
7199  Vector &shape) const
7200 {
7201  const int p = Order;
7202 
7203 #ifdef MFEM_THREAD_SAFE
7204  Vector shape_x(p+1);
7205 #endif
7206 
7207  basis1d.Eval(ip.x, shape_x);
7208 
7209  shape(0) = shape_x(0);
7210  shape(1) = shape_x(p);
7211  for (int i = 1; i < p; i++)
7212  {
7213  shape(i+1) = shape_x(i);
7214  }
7215 }
7216 
7218  DenseMatrix &dshape) const
7219 {
7220  const int p = Order;
7221 
7222 #ifdef MFEM_THREAD_SAFE
7223  Vector shape_x(p+1), dshape_x(p+1);
7224 #endif
7225 
7226  basis1d.Eval(ip.x, shape_x, dshape_x);
7227 
7228  dshape(0,0) = dshape_x(0);
7229  dshape(1,0) = dshape_x(p);
7230  for (int i = 1; i < p; i++)
7231  {
7232  dshape(i+1,0) = dshape_x(i);
7233  }
7234 }
7235 
7236 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7237 {
7238  const int p = Order;
7239  const double *cp = poly1d.ClosedPoints(p, b_type);
7240 
7241  switch (vertex)
7242  {
7243  case 0:
7244  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
7245  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
7246  for (int i = 1; i < p; i++)
7247  {
7248  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7249  }
7250  break;
7251 
7252  case 1:
7253  dofs(0) = poly1d.CalcDelta(p, cp[0]);
7254  dofs(1) = poly1d.CalcDelta(p, cp[p]);
7255  for (int i = 1; i < p; i++)
7256  {
7257  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
7258  }
7259  break;
7260  }
7261 }
7262 
7263 
7265  : NodalTensorFiniteElement(2, p, VerifyClosed(btype), H1_DOF_MAP)
7266 {
7267  const double *cp = poly1d.ClosedPoints(p, b_type);
7268 
7269 #ifndef MFEM_THREAD_SAFE
7270  const int p1 = p + 1;
7271 
7272  shape_x.SetSize(p1);
7273  shape_y.SetSize(p1);
7274  dshape_x.SetSize(p1);
7275  dshape_y.SetSize(p1);
7276 #endif
7277 
7278  int o = 0;
7279  for (int j = 0; j <= p; j++)
7280  {
7281  for (int i = 0; i <= p; i++)
7282  {
7283  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
7284  }
7285  }
7286 }
7287 
7289  Vector &shape) const
7290 {
7291  const int p = Order;
7292 
7293 #ifdef MFEM_THREAD_SAFE
7294  Vector shape_x(p+1), shape_y(p+1);
7295 #endif
7296 
7297  basis1d.Eval(ip.x, shape_x);
7298  basis1d.Eval(ip.y, shape_y);
7299 
7300  for (int o = 0, j = 0; j <= p; j++)
7301  for (int i = 0; i <= p; i++)
7302  {
7303  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7304  }
7305 }
7306 
7308  DenseMatrix &dshape) const
7309 {
7310  const int p = Order;
7311 
7312 #ifdef MFEM_THREAD_SAFE
7313  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7314 #endif
7315 
7316  basis1d.Eval(ip.x, shape_x, dshape_x);
7317  basis1d.Eval(ip.y, shape_y, dshape_y);
7318 
7319  for (int o = 0, j = 0; j <= p; j++)
7320  {
7321  for (int i = 0; i <= p; i++)
7322  {
7323  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7324  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7325  }
7326  }
7327 }
7328 
7329 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
7330 {
7331  const int p = Order;
7332  const double *cp = poly1d.ClosedPoints(p, b_type);
7333 
7334 #ifdef MFEM_THREAD_SAFE
7335  Vector shape_x(p+1), shape_y(p+1);
7336 #endif
7337 
7338  for (int i = 0; i <= p; i++)
7339  {
7340  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7341  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7342  }
7343 
7344  switch (vertex)
7345  {
7346  case 0:
7347  for (int o = 0, j = 0; j <= p; j++)
7348  for (int i = 0; i <= p; i++)
7349  {
7350  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
7351  }
7352  break;
7353  case 1:
7354  for (int o = 0, j = 0; j <= p; j++)
7355  for (int i = 0; i <= p; i++)
7356  {
7357  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
7358  }
7359  break;
7360  case 2:
7361  for (int o = 0, j = 0; j <= p; j++)
7362  for (int i = 0; i <= p; i++)
7363  {
7364  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
7365  }
7366  break;
7367  case 3:
7368  for (int o = 0, j = 0; j <= p; j++)
7369  for (int i = 0; i <= p; i++)
7370  {
7371  dofs(dof_map[o++]) = shape_x(i)*shape_y(j);
7372  }
7373  break;
7374  }
7375 }
7376 
7377 
7378 H1_HexahedronElement::H1_HexahedronElement(const int p, const int btype)
7379  : NodalTensorFiniteElement(3, p, VerifyClosed(btype), H1_DOF_MAP)
7380 {
7381  const double *cp = poly1d.ClosedPoints(p, b_type);
7382 
7383 #ifndef MFEM_THREAD_SAFE
7384  const int p1 = p + 1;
7385 
7386  shape_x.SetSize(p1);
7387  shape_y.SetSize(p1);
7388  shape_z.SetSize(p1);
7389  dshape_x.SetSize(p1);
7390  dshape_y.SetSize(p1);
7391  dshape_z.SetSize(p1);
7392 #endif
7393 
7394  int o = 0;
7395  for (int k = 0; k <= p; k++)
7396  for (int j = 0; j <= p; j++)
7397  for (int i = 0; i <= p; i++)
7398  {
7399  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
7400  }
7401 }
7402 
7404  Vector &shape) const
7405 {
7406  const int p = Order;
7407 
7408 #ifdef MFEM_THREAD_SAFE
7409  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7410 #endif
7411 
7412  basis1d.Eval(ip.x, shape_x);
7413  basis1d.Eval(ip.y, shape_y);
7414  basis1d.Eval(ip.z, shape_z);
7415 
7416  for (int o = 0, k = 0; k <= p; k++)
7417  for (int j = 0; j <= p; j++)
7418  for (int i = 0; i <= p; i++)
7419  {
7420  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7421  }
7422 }
7423 
7425  DenseMatrix &dshape) const
7426 {
7427  const int p = Order;
7428 
7429 #ifdef MFEM_THREAD_SAFE
7430  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7431  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7432 #endif
7433 
7434  basis1d.Eval(ip.x, shape_x, dshape_x);
7435  basis1d.Eval(ip.y, shape_y, dshape_y);
7436  basis1d.Eval(ip.z, shape_z, dshape_z);
7437 
7438  for (int o = 0, k = 0; k <= p; k++)
7439  for (int j = 0; j <= p; j++)
7440  for (int i = 0; i <= p; i++)
7441  {
7442  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7443  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7444  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7445  }
7446 }
7447 
7448 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7449 {
7450  const int p = Order;
7451  const double *cp = poly1d.ClosedPoints(p,b_type);
7452 
7453 #ifdef MFEM_THREAD_SAFE
7454  Vector shape_x(p+1), shape_y(p+1);
7455 #endif
7456 
7457  for (int i = 0; i <= p; i++)
7458  {
7459  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7460  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7461  }
7462 
7463  switch (vertex)
7464  {
7465  case 0:
7466  for (int o = 0, k = 0; k <= p; k++)
7467  for (int j = 0; j <= p; j++)
7468  for (int i = 0; i <= p; i++)
7469  {
7470  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
7471  }
7472  break;
7473  case 1:
7474  for (int o = 0, k = 0; k <= p; k++)
7475  for (int j = 0; j <= p; j++)
7476  for (int i = 0; i <= p; i++)
7477  {
7478  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
7479  }
7480  break;
7481  case 2:
7482  for (int o = 0, k = 0; k <= p; k++)
7483  for (int j = 0; j <= p; j++)
7484  for (int i = 0; i <= p; i++)
7485  {
7486  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
7487  }
7488  break;
7489  case 3:
7490  for (int o = 0, k = 0; k <= p; k++)
7491  for (int j = 0; j <= p; j++)
7492  for (int i = 0; i <= p; i++)
7493  {
7494  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
7495  }
7496  break;
7497  case 4:
7498  for (int o = 0, k = 0; k <= p; k++)
7499  for (int j = 0; j <= p; j++)
7500  for (int i = 0; i <= p; i++)
7501  {
7502  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
7503  }
7504  break;
7505  case 5:
7506  for (int o = 0, k = 0; k <= p; k++)
7507  for (int j = 0; j <= p; j++)
7508  for (int i = 0; i <= p; i++)
7509  {
7510  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
7511  }
7512  break;
7513  case 6:
7514  for (int o = 0, k = 0; k <= p; k++)
7515  for (int j = 0; j <= p; j++)
7516  for (int i = 0; i <= p; i++)
7517  {
7518  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
7519  }
7520  break;
7521  case 7:
7522  for (int o = 0, k = 0; k <= p; k++)
7523  for (int j = 0; j <= p; j++)
7524  for (int i = 0; i <= p; i++)
7525  {
7526  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
7527  }
7528  break;
7529  }
7530 }
7531 
7532 
7534  : PositiveTensorFiniteElement(1, p, H1_DOF_MAP)
7535 {
7536 #ifndef MFEM_THREAD_SAFE
7537  // thread private versions; see class header.
7538  shape_x.SetSize(p+1);
7539  dshape_x.SetSize(p+1);
7540 #endif
7541 
7542  // Endpoints need to be first in the list, so reorder them.
7543  Nodes.IntPoint(0).x = 0.0;
7544  Nodes.IntPoint(1).x = 1.0;
7545  for (int i = 1; i < p; i++)
7546  {
7547  Nodes.IntPoint(i+1).x = double(i)/p;
7548  }
7549 }
7550 
7552  Vector &shape) const
7553 {
7554  const int p = Order;
7555 
7556 #ifdef MFEM_THREAD_SAFE
7557  Vector shape_x(p+1);
7558 #endif
7559 
7560  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7561 
7562  // Endpoints need to be first in the list, so reorder them.
7563  shape(0) = shape_x(0);
7564  shape(1) = shape_x(p);
7565  for (int i = 1; i < p; i++)
7566  {
7567  shape(i+1) = shape_x(i);
7568  }
7569 }
7570 
7572  DenseMatrix &dshape) const
7573 {
7574  const int p = Order;
7575 
7576 #ifdef MFEM_THREAD_SAFE
7577  Vector shape_x(p+1), dshape_x(p+1);
7578 #endif
7579 
7580  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7581 
7582  // Endpoints need to be first in the list, so reorder them.
7583  dshape(0,0) = dshape_x(0);
7584  dshape(1,0) = dshape_x(p);
7585  for (int i = 1; i < p; i++)
7586  {
7587  dshape(i+1,0) = dshape_x(i);
7588  }
7589 }
7590 
7591 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7592 {
7593  dofs = 0.0;
7594  dofs[vertex] = 1.0;
7595 }
7596 
7597 
7599  : PositiveTensorFiniteElement(2, p, H1_DOF_MAP)
7600 {
7601 #ifndef MFEM_THREAD_SAFE
7602  const int p1 = p + 1;
7603 
7604  shape_x.SetSize(p1);
7605  shape_y.SetSize(p1);
7606  dshape_x.SetSize(p1);
7607  dshape_y.SetSize(p1);
7608 #endif
7609 
7610  int o = 0;
7611  for (int j = 0; j <= p; j++)
7612  for (int i = 0; i <= p; i++)
7613  {
7614  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
7615  }
7616 }
7617 
7619  Vector &shape) const
7620 {
7621  const int p = Order;
7622 
7623 #ifdef MFEM_THREAD_SAFE
7624  Vector shape_x(p+1), shape_y(p+1);
7625 #endif
7626 
7627  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7628  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7629 
7630  // Reorder so that vertices are at the beginning of the list
7631  for (int o = 0, j = 0; j <= p; j++)
7632  for (int i = 0; i <= p; i++)
7633  {
7634  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7635  }
7636 }
7637 
7639  DenseMatrix &dshape) const
7640 {
7641  const int p = Order;
7642 
7643 #ifdef MFEM_THREAD_SAFE
7644  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7645 #endif
7646 
7647  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7648  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7649 
7650  // Reorder so that vertices are at the beginning of the list
7651  for (int o = 0, j = 0; j <= p; j++)
7652  for (int i = 0; i <= p; i++)
7653  {
7654  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7655  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7656  }
7657 }
7658 
7660 {
7661  dofs = 0.0;
7662  dofs[vertex] = 1.0;
7663 }
7664 
7665 
7667  : PositiveTensorFiniteElement(3, p, H1_DOF_MAP)
7668 {
7669 #ifndef MFEM_THREAD_SAFE
7670  const int p1 = p + 1;
7671 
7672  shape_x.SetSize(p1);
7673  shape_y.SetSize(p1);
7674  shape_z.SetSize(p1);
7675  dshape_x.SetSize(p1);
7676  dshape_y.SetSize(p1);
7677  dshape_z.SetSize(p1);
7678 #endif
7679 
7680  int o = 0;
7681  for (int k = 0; k <= p; k++)
7682  for (int j = 0; j <= p; j++)
7683  for (int i = 0; i <= p; i++)
7684  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
7685  double(k)/p);
7686 }
7687 
7689  Vector &shape) const
7690 {
7691  const int p = Order;
7692 
7693 #ifdef MFEM_THREAD_SAFE
7694  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7695 #endif
7696 
7697  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7698  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7699  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
7700 
7701  for (int o = 0, k = 0; k <= p; k++)
7702  for (int j = 0; j <= p; j++)
7703  for (int i = 0; i <= p; i++)
7704  {
7705  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7706  }
7707 }
7708 
7710  DenseMatrix &dshape) const
7711 {
7712  const int p = Order;
7713 
7714 #ifdef MFEM_THREAD_SAFE
7715  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7716  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7717 #endif
7718 
7719  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7720  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7721  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
7722 
7723  for (int o = 0, k = 0; k <= p; k++)
7724  for (int j = 0; j <= p; j++)
7725  for (int i = 0; i <= p; i++)
7726  {
7727  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7728  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7729  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7730  }
7731 }
7732 
7733 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7734 {
7735  dofs = 0.0;
7736  dofs[vertex] = 1.0;
7737 }
7738 
7739 
7740 H1_TriangleElement::H1_TriangleElement(const int p, const int btype)
7741  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7742  FunctionSpace::Pk)
7743 {
7744  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
7745 
7746 #ifndef MFEM_THREAD_SAFE
7747  shape_x.SetSize(p + 1);
7748  shape_y.SetSize(p + 1);
7749  shape_l.SetSize(p + 1);
7750  dshape_x.SetSize(p + 1);
7751  dshape_y.SetSize(p + 1);
7752  dshape_l.SetSize(p + 1);
7753  ddshape_x.SetSize(p + 1);
7754  ddshape_y.SetSize(p + 1);
7755  ddshape_l.SetSize(p + 1);
7756  u.SetSize(Dof);
7757  du.SetSize(Dof, Dim);
7758  ddu.SetSize(Dof, (Dim * (Dim + 1)) / 2 );
7759 #else
7760  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7761 #endif
7762 
7763  // vertices
7764  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
7765  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
7766  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
7767 
7768  // edges
7769  int o = 3;
7770  for (int i = 1; i < p; i++)
7771  {
7772  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
7773  }
7774  for (int i = 1; i < p; i++)
7775  {
7776  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
7777  }
7778  for (int i = 1; i < p; i++)
7779  {
7780  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
7781  }
7782 
7783  // interior
7784  for (int j = 1; j < p; j++)
7785  for (int i = 1; i + j < p; i++)
7786  {
7787  const double w = cp[i] + cp[j] + cp[p-i-j];
7788  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
7789  }
7790 
7791  DenseMatrix T(Dof);
7792  for (int k = 0; k < Dof; k++)
7793  {
7794  IntegrationPoint &ip = Nodes.IntPoint(k);
7795  poly1d.CalcBasis(p, ip.x, shape_x);
7796  poly1d.CalcBasis(p, ip.y, shape_y);
7797  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7798 
7799  o = 0;
7800  for (int j = 0; j <= p; j++)
7801  for (int i = 0; i + j <= p; i++)
7802  {
7803  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7804  }
7805  }
7806 
7807  Ti.Factor(T);
7808  // mfem::out << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
7809 }
7810 
7812  Vector &shape) const
7813 {
7814  const int p = Order;
7815 
7816 #ifdef MFEM_THREAD_SAFE
7817  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
7818 #endif
7819 
7820  poly1d.CalcBasis(p, ip.x, shape_x);
7821  poly1d.CalcBasis(p, ip.y, shape_y);
7822  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7823 
7824  for (int o = 0, j = 0; j <= p; j++)
7825  for (int i = 0; i + j <= p; i++)
7826  {
7827  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7828  }
7829 
7830  Ti.Mult(u, shape);
7831 }
7832 
7834  DenseMatrix &dshape) const
7835 {
7836  const int p = Order;
7837 
7838 #ifdef MFEM_THREAD_SAFE
7839  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7840  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
7841  DenseMatrix du(Dof, Dim);
7842 #endif
7843 
7844  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7845  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7846  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
7847 
7848  for (int o = 0, j = 0; j <= p; j++)
7849  for (int i = 0; i + j <= p; i++)
7850  {
7851  int k = p - i - j;
7852  du(o,0) = ((dshape_x(i)* shape_l(k)) -
7853  ( shape_x(i)*dshape_l(k)))*shape_y(j);
7854  du(o,1) = ((dshape_y(j)* shape_l(k)) -
7855  ( shape_y(j)*dshape_l(k)))*shape_x(i);
7856  o++;
7857  }
7858 
7859  Ti.Mult(du, dshape);
7860 }
7861 
7863  DenseMatrix &ddshape) const
7864 {
7865  const int p = Order;
7866 #ifdef MFEM_THREAD_SAFE
7867  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7868  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
7869  Vector ddshape_x(p + 1), ddshape_y(p + 1), ddshape_l(p + 1);
7870  DenseMatrix ddu(Dof, Dim);
7871 #endif
7872 
7873  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x, ddshape_x);
7874  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y, ddshape_y);
7875  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l, ddshape_l);
7876 
7877  for (int o = 0, j = 0; j <= p; j++)
7878  for (int i = 0; i + j <= p; i++)
7879  {
7880  int k = p - i - j;
7881  // u_xx, u_xy, u_yy
7882  ddu(o,0) = ((ddshape_x(i) * shape_l(k)) - 2. * (dshape_x(i) * dshape_l(k)) +
7883  (shape_x(i) * ddshape_l(k))) * shape_y(j);
7884  ddu(o,1) = (((shape_x(i) * ddshape_l(k)) - dshape_x(i) * dshape_l(k)) * shape_y(
7885  j)) + (((dshape_x(i) * shape_l(k)) - (shape_x(i) * dshape_l(k))) * dshape_y(j));
7886  ddu(o,2) = ((ddshape_y(j) * shape_l(k)) - 2. * (dshape_y(j) * dshape_l(k)) +
7887  (shape_y(j) * ddshape_l(k))) * shape_x(i);
7888  o++;
7889  }
7890 
7891  Ti.Mult(ddu, ddshape);
7892 }
7893 
7894 
7896  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
7897  p, FunctionSpace::Pk)
7898 {
7899  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
7900 
7901 #ifndef MFEM_THREAD_SAFE
7902  shape_x.SetSize(p + 1);
7903  shape_y.SetSize(p + 1);
7904  shape_z.SetSize(p + 1);
7905  shape_l.SetSize(p + 1);
7906  dshape_x.SetSize(p + 1);
7907  dshape_y.SetSize(p + 1);
7908  dshape_z.SetSize(p + 1);
7909  dshape_l.SetSize(p + 1);
7910  ddshape_x.SetSize(p + 1);
7911  ddshape_y.SetSize(p + 1);
7912  ddshape_z.SetSize(p + 1);
7913  ddshape_l.SetSize(p + 1);
7914  u.SetSize(Dof);
7915  du.SetSize(Dof, Dim);
7916  ddu.SetSize(Dof, (Dim * (Dim + 1)) / 2);
7917 #else
7918  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7919 #endif
7920 
7921  // vertices
7922  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
7923  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
7924  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
7925  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
7926 
7927  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7928  int o = 4;
7929  for (int i = 1; i < p; i++) // (0,1)
7930  {
7931  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
7932  }
7933  for (int i = 1; i < p; i++) // (0,2)
7934  {
7935  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
7936  }
7937  for (int i = 1; i < p; i++) // (0,3)
7938  {
7939  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
7940  }
7941  for (int i = 1; i < p; i++) // (1,2)
7942  {
7943  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
7944  }
7945  for (int i = 1; i < p; i++) // (1,3)
7946  {
7947  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
7948  }
7949  for (int i = 1; i < p; i++) // (2,3)
7950  {
7951  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
7952  }
7953 
7954  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7955  for (int j = 1; j < p; j++)
7956  for (int i = 1; i + j < p; i++) // (1,2,3)
7957  {
7958  double w = cp[i] + cp[j] + cp[p-i-j];
7959  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
7960  }
7961  for (int j = 1; j < p; j++)
7962  for (int i = 1; i + j < p; i++) // (0,3,2)
7963  {
7964  double w = cp[i] + cp[j] + cp[p-i-j];
7965  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
7966  }
7967  for (int j = 1; j < p; j++)
7968  for (int i = 1; i + j < p; i++) // (0,1,3)
7969  {
7970  double w = cp[i] + cp[j] + cp[p-i-j];
7971  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
7972  }
7973  for (int j = 1; j < p; j++)
7974  for (int i = 1; i + j < p; i++) // (0,2,1)
7975  {
7976  double w = cp[i] + cp[j] + cp[p-i-j];
7977  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
7978  }
7979 
7980  // interior
7981  for (int k = 1; k < p; k++)
7982  for (int j = 1; j + k < p; j++)
7983  for (int i = 1; i + j + k < p; i++)
7984  {
7985  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
7986  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
7987  }
7988 
7989  DenseMatrix T(Dof);
7990  for (int m = 0; m < Dof; m++)
7991  {
7992  IntegrationPoint &ip = Nodes.IntPoint(m);
7993  poly1d.CalcBasis(p, ip.x, shape_x);
7994  poly1d.CalcBasis(p, ip.y, shape_y);
7995  poly1d.CalcBasis(p, ip.z, shape_z);
7996  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7997 
7998  o = 0;
7999  for (int k = 0; k <= p; k++)
8000  for (int j = 0; j + k <= p; j++)
8001  for (int i = 0; i + j + k <= p; i++)
8002  {
8003  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8004  }
8005  }
8006 
8007  Ti.Factor(T);
8008  // mfem::out << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8009 }
8010 
8012  Vector &shape) const
8013 {
8014  const int p = Order;
8015 
8016 #ifdef MFEM_THREAD_SAFE
8017  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8018  Vector u(Dof);
8019 #endif
8020 
8021  poly1d.CalcBasis(p, ip.x, shape_x);
8022  poly1d.CalcBasis(p, ip.y, shape_y);
8023  poly1d.CalcBasis(p, ip.z, shape_z);
8024  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8025 
8026  for (int o = 0, k = 0; k <= p; k++)
8027  for (int j = 0; j + k <= p; j++)
8028  for (int i = 0; i + j + k <= p; i++)
8029  {
8030  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8031  }
8032 
8033  Ti.Mult(u, shape);
8034 }
8035 
8037  DenseMatrix &dshape) const
8038 {
8039  const int p = Order;
8040 
8041 #ifdef MFEM_THREAD_SAFE
8042  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8043  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8044  DenseMatrix du(Dof, Dim);
8045 #endif
8046 
8047  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8048  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8049  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
8050  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
8051 
8052  for (int o = 0, k = 0; k <= p; k++)
8053  for (int j = 0; j + k <= p; j++)
8054  for (int i = 0; i + j + k <= p; i++)
8055  {
8056  int l = p - i - j - k;
8057  du(o,0) = ((dshape_x(i)* shape_l(l)) -
8058  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
8059  du(o,1) = ((dshape_y(j)* shape_l(l)) -
8060  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
8061  du(o,2) = ((dshape_z(k)* shape_l(l)) -
8062  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
8063  o++;
8064  }
8065 
8066  Ti.Mult(du, dshape);
8067 }
8068 
8070  DenseMatrix &ddshape) const
8071 {
8072  const int p = Order;
8073 
8074 #ifdef MFEM_THREAD_SAFE
8075  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8076  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8077  Vector ddshape_x(p + 1), ddshape_y(p + 1), ddshape_z(p + 1), ddshape_l(p + 1);
8078  DenseMatrix ddu(Dof, ((Dim + 1) * Dim) / 2);
8079 #endif
8080 
8081  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x, ddshape_x);
8082  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y, ddshape_y);
8083  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z, ddshape_z);
8084  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l, ddshape_l);
8085 
8086  for (int o = 0, k = 0; k <= p; k++)
8087  for (int j = 0; j + k <= p; j++)
8088  for (int i = 0; i + j + k <= p; i++)
8089  {
8090  // u_xx, u_xy, u_xz, u_yy, u_yz, u_zz
8091  int l = p - i - j - k;
8092  ddu(o,0) = ((ddshape_x(i) * shape_l(l)) - 2. * (dshape_x(i) * dshape_l(l)) +
8093  (shape_x(i) * ddshape_l(l))) * shape_y(j) * shape_z(k);
8094  ddu(o,1) = ((dshape_y(j) * ((dshape_x(i) * shape_l(l)) -
8095  (shape_x(i) * dshape_l(l)))) +
8096  (shape_y(j) * ((ddshape_l(l) * shape_x(i)) -
8097  (dshape_x(i) * dshape_l(l)))))* shape_z(k);
8098  ddu(o,2) = ((dshape_z(k) * ((dshape_x(i) * shape_l(l)) -
8099  (shape_x(i) * dshape_l(l)))) +
8100  (shape_z(k) * ((ddshape_l(l) * shape_x(i)) -
8101  (dshape_x(i) * dshape_l(l)))))* shape_y(j);
8102  ddu(o,3) = ((ddshape_y(j) * shape_l(l)) - 2. * (dshape_y(j) * dshape_l(l)) +
8103  (shape_y(j) * ddshape_l(l))) * shape_x(i) * shape_z(k);
8104  ddu(o,4) = ((dshape_z(k) * ((dshape_y(j) * shape_l(l)) -
8105  (shape_y(j)*dshape_l(l))) ) +
8106  (shape_z(k)* ((ddshape_l(l)*shape_y(j)) -
8107  (dshape_y(j) * dshape_l(l)) ) ) )* shape_x(i);
8108  ddu(o,5) = ((ddshape_z(k) * shape_l(l)) - 2. * (dshape_z(k) * dshape_l(l)) +
8109  (shape_z(k) * ddshape_l(l))) * shape_y(j) * shape_x(i);
8110  o++;
8111  }
8112  Ti.Mult(ddu, ddshape);
8113 }
8114 
8116  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8117  FunctionSpace::Pk)
8118 {
8119 #ifndef MFEM_THREAD_SAFE
8120  m_shape.SetSize(Dof);
8121  dshape_1d.SetSize(p + 1);
8122  m_dshape.SetSize(Dof, Dim);
8123 #endif
8124  dof_map.SetSize(Dof);
8125 
8126  struct Index
8127  {
8128  int p2p3;
8129  Index(int p) { p2p3 = 2*p + 3; }
8130  int operator()(int i, int j) { return ((p2p3-j)*j)/2+i; }
8131  };
8132  Index idx(p);
8133 
8134  // vertices
8135  dof_map[idx(0,0)] = 0;
8136  Nodes.IntPoint(0).Set2(0., 0.);
8137  dof_map[idx(p,0)] = 1;
8138  Nodes.IntPoint(1).Set2(1., 0.);
8139  dof_map[idx(0,p)] = 2;
8140  Nodes.IntPoint(2).Set2(0., 1.);
8141 
8142  // edges
8143  int o = 3;
8144  for (int i = 1; i < p; i++)
8145  {
8146  dof_map[idx(i,0)] = o;
8147  Nodes.IntPoint(o++).Set2(double(i)/p, 0.);
8148  }
8149  for (int i = 1; i < p; i++)
8150  {
8151  dof_map[idx(p-i,i)] = o;
8152  Nodes.IntPoint(o++).Set2(double(p-i)/p, double(i)/p);
8153  }
8154  for (int i = 1; i < p; i++)
8155  {
8156  dof_map[idx(0,p-i)] = o;
8157  Nodes.IntPoint(o++).Set2(0., double(p-i)/p);
8158  }
8159 
8160  // interior
8161  for (int j = 1; j < p; j++)
8162  for (int i = 1; i + j < p; i++)
8163  {
8164  dof_map[idx(i,j)] = o;
8165  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8166  }
8167 }
8168 
8169 // static method
8171  const int p, const double l1, const double l2, double *shape)
8172 {
8173  const double l3 = 1. - l1 - l2;
8174 
8175  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
8176  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
8177  // Another expression is given by the terms of the expansion:
8178  // (l1 + l2 + l3)^p =
8179  // \sum_{j=0}^p \binom{p}{j} l2^j
8180  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
8181  const int *bp = Poly_1D::Binom(p);
8182  double z = 1.;
8183  for (int o = 0, j = 0; j <= p; j++)
8184  {
8185  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape[o]);
8186  double s = bp[j]*z;
8187  for (int i = 0; i <= p - j; i++)
8188  {
8189  shape[o++] *= s;
8190  }
8191  z *= l2;
8192  }
8193 }
8194 
8195 // static method
8197  const int p, const double l1, const double l2,
8198  double *dshape_1d, double *dshape)
8199 {
8200  const int dof = ((p + 1)*(p + 2))/2;
8201  const double l3 = 1. - l1 - l2;
8202 
8203  const int *bp = Poly_1D::Binom(p);
8204  double z = 1.;
8205  for (int o = 0, j = 0; j <= p; j++)
8206  {
8207  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
8208  double s = bp[j]*z;
8209  for (int i = 0; i <= p - j; i++)
8210  {
8211  dshape[o++] = s*dshape_1d[i];
8212  }
8213  z *= l2;
8214  }
8215  z = 1.;
8216  for (int i = 0; i <= p; i++)
8217  {
8218  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
8219  double s = bp[i]*z;
8220  for (int o = i, j = 0; j <= p - i; j++)
8221  {
8222  dshape[dof + o] = s*dshape_1d[j];
8223  o += p + 1 - j;
8224  }
8225  z *= l1;
8226  }
8227 }
8228 
8230  Vector &shape) const
8231 {
8232 #ifdef MFEM_THREAD_SAFE
8233  Vector m_shape(Dof);
8234 #endif
8235  CalcShape(Order, ip.x, ip.y, m_shape.GetData());
8236  for (int i = 0; i < Dof; i++)
8237  {
8238  shape(dof_map[i]) = m_shape(i);
8239  }
8240 }
8241 
8243  DenseMatrix &dshape) const
8244 {
8245 #ifdef MFEM_THREAD_SAFE
8246  Vector dshape_1d(Order + 1);
8248 #endif
8249  CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(), m_dshape.Data());
8250  for (int d = 0; d < 2; d++)
8251  {
8252  for (int i = 0; i < Dof; i++)
8253  {
8254  dshape(dof_map[i],d) = m_dshape(i,d);
8255  }
8256  }
8257 }
8258 
8259 
8261  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
8262  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
8263 {
8264 #ifndef MFEM_THREAD_SAFE
8265  m_shape.SetSize(Dof);
8266  dshape_1d.SetSize(p + 1);
8267  m_dshape.SetSize(Dof, Dim);
8268 #endif
8269  dof_map.SetSize(Dof);
8270 
8271  struct Index
8272  {
8273  int p, dof;
8274  int tri(int k) { return (k*(k + 1))/2; }
8275  int tet(int k) { return (k*(k + 1)*(k + 2))/6; }
8276  Index(int p_) { p = p_; dof = tet(p + 1); }
8277  int operator()(int i, int j, int k)
8278  { return dof - tet(p - k) - tri(p + 1 - k - j) + i; }
8279  };
8280  Index idx(p);
8281 
8282  // vertices
8283  dof_map[idx(0,0,0)] = 0;
8284  Nodes.IntPoint(0).Set3(0., 0., 0.);
8285  dof_map[idx(p,0,0)] = 1;
8286  Nodes.IntPoint(1).Set3(1., 0., 0.);
8287  dof_map[idx(0,p,0)] = 2;
8288  Nodes.IntPoint(2).Set3(0., 1., 0.);
8289  dof_map[idx(0,0,p)] = 3;
8290  Nodes.IntPoint(3).Set3(0., 0., 1.);
8291 
8292  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
8293  int o = 4;
8294  for (int i = 1; i < p; i++) // (0,1)
8295  {
8296  dof_map[idx(i,0,0)] = o;
8297  Nodes.IntPoint(o++).Set3(double(i)/p, 0., 0.);
8298  }
8299  for (int i = 1; i < p; i++) // (0,2)
8300  {
8301  dof_map[idx(0,i,0)] = o;
8302  Nodes.IntPoint(o++).Set3(0., double(i)/p, 0.);
8303  }
8304  for (int i = 1; i < p; i++) // (0,3)
8305  {
8306  dof_map[idx(0,0,i)] = o;
8307  Nodes.IntPoint(o++).Set3(0., 0., double(i)/p);
8308  }
8309  for (int i = 1; i < p; i++) // (1,2)
8310  {
8311  dof_map[idx(p-i,i,0)] = o;
8312  Nodes.IntPoint(o++).Set3(double(p-i)/p, double(i)/p, 0.);
8313  }
8314  for (int i = 1; i < p; i++) // (1,3)
8315  {
8316  dof_map[idx(p-i,0,i)] = o;
8317  Nodes.IntPoint(o++).Set3(double(p-i)/p, 0., double(i)/p);
8318  }
8319  for (int i = 1; i < p; i++) // (2,3)
8320  {
8321  dof_map[idx(0,p-i,i)] = o;
8322  Nodes.IntPoint(o++).Set3(0., double(p-i)/p, double(i)/p);
8323  }
8324 
8325  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
8326  for (int j = 1; j < p; j++)
8327  for (int i = 1; i + j < p; i++) // (1,2,3)
8328  {
8329  dof_map[idx(p-i-j,i,j)] = o;
8330  Nodes.IntPoint(o++).Set3(double(p-i-j)/p, double(i)/p, double(j)/p);
8331  }
8332  for (int j = 1; j < p; j++)
8333  for (int i = 1; i + j < p; i++) // (0,3,2)
8334  {
8335  dof_map[idx(0,j,i)] = o;
8336  Nodes.IntPoint(o++).Set3(0., double(j)/p, double(i)/p);
8337  }
8338  for (int j = 1; j < p; j++)
8339  for (int i = 1; i + j < p; i++) // (0,1,3)
8340  {
8341  dof_map[idx(i,0,j)] = o;
8342  Nodes.IntPoint(o++).Set3(double(i)/p, 0., double(j)/p);
8343  }
8344  for (int j = 1; j < p; j++)
8345  for (int i = 1; i + j < p; i++) // (0,2,1)
8346  {
8347  dof_map[idx(j,i,0)] = o;
8348  Nodes.IntPoint(o++).Set3(double(j)/p, double(i)/p, 0.);
8349  }
8350 
8351  // interior
8352  for (int k = 1; k < p; k++)
8353  for (int j = 1; j + k < p; j++)
8354  for (int i = 1; i + j + k < p; i++)
8355  {
8356  dof_map[idx(i,j,k)] = o;
8357  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8358  }
8359 }
8360 
8361 // static method
8363  const int p, const double l1, const double l2, const double l3,
8364  double *shape)
8365 {
8366  const double l4 = 1. - l1 - l2 - l3;
8367 
8368  // The basis functions are the terms in the expansion:
8369  // (l1 + l2 + l3 + l4)^p =
8370  // \sum_{k=0}^p \binom{p}{k} l3^k
8371  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8372  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8373  const int *bp = Poly_1D::Binom(p);
8374  double l3k = 1.;
8375  for (int o = 0, k = 0; k <= p; k++)
8376  {
8377  const int *bpk = Poly_1D::Binom(p - k);
8378  const double ek = bp[k]*l3k;
8379  double l2j = 1.;
8380  for (int j = 0; j <= p - k; j++)
8381  {
8382  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape[o]);
8383  double ekj = ek*bpk[j]*l2j;
8384  for (int i = 0; i <= p - k - j; i++)
8385  {
8386  shape[o++] *= ekj;
8387  }
8388  l2j *= l2;
8389  }
8390  l3k *= l3;
8391  }
8392 }
8393 
8394 // static method
8396  const int p, const double l1, const double l2, const double l3,
8397  double *dshape_1d, double *dshape)
8398 {
8399  const int dof = ((p + 1)*(p + 2)*(p + 3))/6;
8400  const double l4 = 1. - l1 - l2 - l3;
8401 
8402  // For the x derivatives, differentiate the terms of the expression:
8403  // \sum_{k=0}^p \binom{p}{k} l3^k
8404  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8405  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8406  const int *bp = Poly_1D::Binom(p);
8407  double l3k = 1.;
8408  for (int o = 0, k = 0; k <= p; k++)
8409  {
8410  const int *bpk = Poly_1D::Binom(p - k);
8411  const double ek = bp[k]*l3k;
8412  double l2j = 1.;
8413  for (int j = 0; j <= p - k; j++)
8414  {
8415  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
8416  double ekj = ek*bpk[j]*l2j;
8417  for (int i = 0; i <= p - k - j; i++)
8418  {
8419  dshape[o++] = dshape_1d[i]*ekj;
8420  }
8421  l2j *= l2;
8422  }
8423  l3k *= l3;
8424  }
8425  // For the y derivatives, differentiate the terms of the expression:
8426  // \sum_{k=0}^p \binom{p}{k} l3^k
8427  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
8428  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
8429  l3k = 1.;
8430  for (int ok = 0, k = 0; k <= p; k++)
8431  {
8432  const int *bpk = Poly_1D::Binom(p - k);
8433  const double ek = bp[k]*l3k;
8434  double l1i = 1.;
8435  for (int i = 0; i <= p - k; i++)
8436  {
8437  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
8438  double eki = ek*bpk[i]*l1i;
8439  int o = ok + i;
8440  for (int j = 0; j <= p - k - i; j++)
8441  {
8442  dshape[dof + o] = dshape_1d[j]*eki;
8443  o += p - k - j + 1;
8444  }
8445  l1i *= l1;
8446  }
8447  l3k *= l3;
8448  ok += ((p - k + 2)*(p - k + 1))/2;
8449  }
8450  // For the z derivatives, differentiate the terms of the expression:
8451  // \sum_{j=0}^p \binom{p}{j} l2^j
8452  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
8453  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
8454  double l2j = 1.;
8455  for (int j = 0; j <= p; j++)
8456  {
8457  const int *bpj = Poly_1D::Binom(p - j);
8458  const double ej = bp[j]*l2j;
8459  double l1i = 1.;
8460  for (int i = 0; i <= p - j; i++)
8461  {
8462  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
8463  double eji = ej*bpj[i]*l1i;
8464  int m = ((p + 2)*(p + 1))/2;
8465  int n = ((p - j + 2)*(p - j + 1))/2;
8466  for (int o = i, k = 0; k <= p - j - i; k++)
8467  {
8468  // m = ((p - k + 2)*(p - k + 1))/2;
8469  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
8470  o += m;
8471  dshape[2*dof + o - n] = dshape_1d[k]*eji;
8472  m -= p - k + 1;
8473  n -= p - k - j + 1;
8474  }
8475  l1i *= l1;
8476  }
8477  l2j *= l2;
8478  }
8479 }
8480 
8482  Vector &shape) const
8483 {
8484 #ifdef MFEM_THREAD_SAFE
8485  Vector m_shape(Dof);
8486 #endif
8487  CalcShape(Order, ip.x, ip.y, ip.z, m_shape.GetData());
8488  for (int i = 0; i < Dof; i++)
8489  {
8490  shape(dof_map[i]) = m_shape(i);
8491  }
8492 }
8493 
8495  DenseMatrix &dshape) const
8496 {
8497 #ifdef MFEM_THREAD_SAFE
8498  Vector dshape_1d(Order + 1);
8500 #endif
8501  CalcDShape(Order, ip.x, ip.y, ip.z, dshape_1d.GetData(), m_dshape.Data());
8502  for (int d = 0; d < 3; d++)
8503  {
8504  for (int i = 0; i < Dof; i++)
8505  {
8506  dshape(dof_map[i],d) = m_dshape(i,d);
8507  }
8508  }
8509 }
8510 
8511 
8513  const int btype)
8514  : NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
8515  p, FunctionSpace::Qk),
8516  TriangleFE(p, btype),
8517  SegmentFE(p, btype)
8518 {
8519 #ifndef MFEM_THREAD_SAFE
8520  t_shape.SetSize(TriangleFE.GetDof());
8521  s_shape.SetSize(SegmentFE.GetDof());
8522  t_dshape.SetSize(TriangleFE.GetDof(), 2);
8523  s_dshape.SetSize(SegmentFE.GetDof(), 1);
8524 #endif
8525 
8526  t_dof.SetSize(Dof);
8527  s_dof.SetSize(Dof);
8528 
8529  // Nodal DoFs
8530  t_dof[0] = 0; s_dof[0] = 0;
8531  t_dof[1] = 1; s_dof[1] = 0;
8532  t_dof[2] = 2; s_dof[2] = 0;
8533  t_dof[3] = 0; s_dof[3] = 1;
8534  t_dof[4] = 1; s_dof[4] = 1;
8535  t_dof[5] = 2; s_dof[5] = 1;
8536 
8537  // Edge DoFs
8538  int ne = p-1;
8539  for (int i=1; i<p; i++)
8540  {
8541  t_dof[5 + 0 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 0 * ne + i] = 0;
8542  t_dof[5 + 1 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 1 * ne + i] = 0;
8543  t_dof[5 + 2 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 2 * ne + i] = 0;
8544  t_dof[5 + 3 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 3 * ne + i] = 1;
8545  t_dof[5 + 4 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 4 * ne + i] = 1;
8546  t_dof[5 + 5 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 5 * ne + i] = 1;
8547  t_dof[5 + 6 * ne + i] = 0; s_dof[5 + 6 * ne + i] = i + 1;
8548  t_dof[5 + 7 * ne + i] = 1; s_dof[5 + 7 * ne + i] = i + 1;
8549  t_dof[5 + 8 * ne + i] = 2; s_dof[5 + 8 * ne + i] = i + 1;
8550  }
8551 
8552  // Triangular Face DoFs
8553  int k=0;
8554  int nt = (p-1)*(p-2)/2;
8555  for (int j=1; j<p; j++)
8556  {
8557  for (int i=1; i<p-j; i++)
8558  {
8559  int l = j - p + (((2 * p - 1) - i) * i) / 2;
8560  t_dof[6 + 9 * ne + k] = 3 * p + l; s_dof[6 + 9 * ne + k] = 0;
8561  t_dof[6 + 9 * ne + nt + k] = 3 * p + k; s_dof[6 + 9 * ne + nt + k] = 1;
8562  k++;
8563  }
8564  }
8565 
8566  // Quadrilateral Face DoFs
8567  k=0;
8568  int nq = (p-1)*(p-1);
8569  for (int j=1; j<p; j++)
8570  {
8571  for (int i=1; i<p; i++)
8572  {
8573  t_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 2 + 0 * ne + i;
8574  t_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 2 + 1 * ne + i;
8575  t_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 2 + 2 * ne + i;
8576 
8577  s_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 1 + j;
8578  s_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 1 + j;
8579  s_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 1 + j;
8580 
8581  k++;
8582  }
8583  }
8584 
8585  // Interior DoFs
8586  int m=0;
8587  for (int k=1; k<p; k++)
8588  {
8589  int l=0;
8590  for (int j=1; j<p; j++)
8591  {
8592  for (int i=1; i<j; i++)
8593  {
8594  t_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 3 * p + l;
8595  s_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 1 + k;
8596  l++; m++;
8597  }
8598  }
8599  }
8600 
8601  // Define Nodes
8602  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
8603  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
8604  for (int i=0; i<Dof; i++)
8605  {
8606  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
8607  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
8608  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
8609  }
8610 }
8611 
8613  Vector &shape) const
8614 {
8615 #ifdef MFEM_THREAD_SAFE
8616  Vector t_shape(TriangleFE.GetDof());
8617  Vector s_shape(SegmentFE.GetDof());
8618 #endif
8619 
8620  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
8621 
8622  TriangleFE.CalcShape(ip, t_shape);
8623  SegmentFE.CalcShape(ipz, s_shape);
8624 
8625  for (int i=0; i<Dof; i++)
8626  {
8627  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
8628  }
8629 }
8630 
8632  DenseMatrix &dshape) const
8633 {
8634 #ifdef MFEM_THREAD_SAFE
8635  Vector t_shape(TriangleFE.GetDof());
8636  DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
8637  Vector s_shape(SegmentFE.GetDof());
8638  DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
8639 #endif
8640 
8641  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
8642 
8643  TriangleFE.CalcShape(ip, t_shape);
8644  TriangleFE.CalcDShape(ip, t_dshape);
8645  SegmentFE.CalcShape(ipz, s_shape);
8646  SegmentFE.CalcDShape(ipz, s_dshape);
8647 
8648  for (int i=0; i<Dof; i++)
8649  {
8650  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
8651  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
8652  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
8653  }
8654 }
8655 
8656 
8658  : PositiveFiniteElement(3, Geometry::PRISM,
8659  ((p + 1)*(p + 1)*(p + 2))/2, p, FunctionSpace::Qk),
8660  TriangleFE(p),
8661  SegmentFE(p)
8662 {
8663 #ifndef MFEM_THREAD_SAFE
8668 #endif
8669 
8670  t_dof.SetSize(Dof);
8671  s_dof.SetSize(Dof);
8672 
8673  // Nodal DoFs
8674  t_dof[0] = 0; s_dof[0] = 0;
8675  t_dof[1] = 1; s_dof[1] = 0;
8676  t_dof[2] = 2; s_dof[2] = 0;
8677  t_dof[3] = 0; s_dof[3] = 1;
8678  t_dof[4] = 1; s_dof[4] = 1;
8679  t_dof[5] = 2; s_dof[5] = 1;
8680 
8681  // Edge DoFs
8682  int ne = p-1;
8683  for (int i=1; i<p; i++)
8684  {
8685  t_dof[5 + 0 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 0 * ne + i] = 0;
8686  t_dof[5 + 1 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 1 * ne + i] = 0;
8687  t_dof[5 + 2 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 2 * ne + i] = 0;
8688  t_dof[5 + 3 * ne + i] = 2 + 0 * ne + i; s_dof[5 + 3 * ne + i] = 1;
8689  t_dof[5 + 4 * ne + i] = 2 + 1 * ne + i; s_dof[5 + 4 * ne + i] = 1;
8690  t_dof[5 + 5 * ne + i] = 2 + 2 * ne + i; s_dof[5 + 5 * ne + i] = 1;
8691  t_dof[5 + 6 * ne + i] = 0; s_dof[5 + 6 * ne + i] = i + 1;
8692  t_dof[5 + 7 * ne + i] = 1; s_dof[5 + 7 * ne + i] = i + 1;
8693  t_dof[5 + 8 * ne + i] = 2; s_dof[5 + 8 * ne + i] = i + 1;
8694  }
8695 
8696  // Triangular Face DoFs
8697  int k=0;
8698  int nt = (p-1)*(p-2)/2;
8699  for (int j=1; j<p; j++)
8700  {
8701  for (int i=1; i<j; i++)
8702  {
8703  t_dof[6 + 9 * ne + k] = 3 * p + k; s_dof[6 + 9 * ne + k] = 0;
8704  t_dof[6 + 9 * ne + nt + k] = 3 * p + k; s_dof[6 + 9 * ne + nt + k] = 1;
8705  k++;
8706  }
8707  }
8708 
8709  // Quadrilateral Face DoFs
8710  k=0;
8711  int nq = (p-1)*(p-1);
8712  for (int j=1; j<p; j++)
8713  {
8714  for (int i=1; i<p; i++)
8715  {
8716  t_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 2 + 0 * ne + i;
8717  t_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 2 + 1 * ne + i;
8718  t_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 2 + 2 * ne + i;
8719 
8720  s_dof[6 + 9 * ne + 2 * nt + 0 * nq + k] = 1 + j;
8721  s_dof[6 + 9 * ne + 2 * nt + 1 * nq + k] = 1 + j;
8722  s_dof[6 + 9 * ne + 2 * nt + 2 * nq + k] = 1 + j;
8723 
8724  k++;
8725  }
8726  }
8727 
8728  // Interior DoFs
8729  int m=0;
8730  for (int k=1; k<p; k++)
8731  {
8732  int l=0;
8733  for (int j=1; j<p; j++)
8734  {
8735  for (int i=1; i<j; i++)
8736  {
8737  t_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 3 * p + l;
8738  s_dof[6 + 9 * ne + 2 * nt + 3 * nq + m] = 1 + k;
8739  l++; m++;
8740  }
8741  }
8742  }
8743 
8744  // Define Nodes
8745  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
8746  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
8747  for (int i=0; i<Dof; i++)
8748  {
8749  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
8750  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
8751  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
8752  }
8753 }
8754 
8756  Vector &shape) const
8757 {
8758 #ifdef MFEM_THREAD_SAFE
8761 #endif
8762 
8763  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
8764 
8766  SegmentFE.CalcShape(ipz, s_shape);
8767 
8768  for (int i=0; i<Dof; i++)
8769  {
8770  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
8771  }
8772 }
8773 
8775  DenseMatrix &dshape) const
8776 {
8777 #ifdef MFEM_THREAD_SAFE
8782 #endif
8783 
8784  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
8785 
8788  SegmentFE.CalcShape(ipz, s_shape);
8790 
8791  for (int i=0; i<Dof; i++)
8792  {
8793  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
8794  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
8795  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
8796  }
8797 }
8798 
8799 
8800 L2_SegmentElement::L2_SegmentElement(const int p, const int btype)
8801  : NodalTensorFiniteElement(1, p, VerifyOpen(btype), L2_DOF_MAP)
8802 {
8803  const double *op = poly1d.OpenPoints(p, btype);
8804 
8805 #ifndef MFEM_THREAD_SAFE
8806  shape_x.SetSize(p + 1);
8807  dshape_x.SetDataAndSize(NULL, p + 1);
8808 #endif
8809 
8810  for (int i = 0; i <= p; i++)
8811  {
8812  Nodes.IntPoint(i).x = op[i];
8813  }
8814 }
8815 
8817  Vector &shape) const
8818 {
8819  basis1d.Eval(ip.x, shape);
8820 }
8821 
8823  DenseMatrix &dshape) const
8824 {
8825 #ifdef MFEM_THREAD_SAFE
8826  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8827 #else
8828  dshape_x.SetData(dshape.Data());
8829 #endif
8830  basis1d.Eval(ip.x, shape_x, dshape_x);
8831 }
8832 
8833 void L2_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8834 {
8835  const int p = Order;
8836  const double *op = poly1d.OpenPoints(p, b_type);
8837 
8838  switch (vertex)
8839  {
8840  case 0:
8841  for (int i = 0; i <= p; i++)
8842  {
8843  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8844  }
8845  break;
8846 
8847  case 1:
8848  for (int i = 0; i <= p; i++)
8849  {
8850  dofs(i) = poly1d.CalcDelta(p,op[i]);
8851  }
8852  break;
8853  }
8854 }
8855 
8856 
8858  : PositiveTensorFiniteElement(1, p, L2_DOF_MAP)
8859 {
8860 #ifndef MFEM_THREAD_SAFE
8861  shape_x.SetSize(p + 1);
8862  dshape_x.SetDataAndSize(NULL, p + 1);
8863 #endif
8864 
8865  if (p == 0)
8866  {
8867  Nodes.IntPoint(0).x = 0.5;
8868  }
8869  else
8870  {
8871  for (int i = 0; i <= p; i++)
8872  {
8873  Nodes.IntPoint(i).x = double(i)/p;
8874  }
8875  }
8876 }
8877 
8879  Vector &shape) const
8880 {
8881  Poly_1D::CalcBernstein(Order, ip.x, shape);
8882 }
8883 
8885  DenseMatrix &dshape) const
8886 {
8887 #ifdef MFEM_THREAD_SAFE
8888  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8889 #else
8890  dshape_x.SetData(dshape.Data());
8891 #endif
8892  Poly_1D::CalcBernstein(Order, ip.x, shape_x, dshape_x);
8893 }
8894 
8895 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8896 {
8897  dofs = 0.0;
8898  dofs[vertex*Order] = 1.0;
8899 }
8900 
8901 
8903  : NodalTensorFiniteElement(2, p, VerifyOpen(btype), L2_DOF_MAP)
8904 {
8905  const double *op = poly1d.OpenPoints(p, b_type);
8906 
8907 #ifndef MFEM_THREAD_SAFE
8908  shape_x.SetSize(p + 1);
8909  shape_y.SetSize(p + 1);
8910  dshape_x.SetSize(p + 1);
8911  dshape_y.SetSize(p + 1);
8912 #endif
8913 
8914  for (int o = 0, j = 0; j <= p; j++)
8915  for (int i = 0; i <= p; i++)
8916  {
8917  Nodes.IntPoint(o++).Set2(op[i], op[j]);
8918  }
8919 }
8920 
8922  Vector &shape) const
8923 {
8924  const int p = Order;
8925 
8926 #ifdef MFEM_THREAD_SAFE
8927  Vector shape_x(p+1), shape_y(p+1);
8928 #endif
8929 
8930  basis1d.Eval(ip.x, shape_x);
8931  basis1d.Eval(ip.y, shape_y);
8932 
8933  for (int o = 0, j = 0; j <= p; j++)
8934  for (int i = 0; i <= p; i++)
8935  {
8936  shape(o++) = shape_x(i)*shape_y(j);
8937  }
8938 }
8939 
8941  DenseMatrix &dshape) const
8942 {
8943  const int p = Order;
8944 
8945 #ifdef MFEM_THREAD_SAFE
8946  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8947 #endif
8948 
8949  basis1d.Eval(ip.x, shape_x, dshape_x);
8950  basis1d.Eval(ip.y, shape_y, dshape_y);
8951 
8952  for (int o = 0, j = 0; j <= p; j++)
8953  for (int i = 0; i <= p; i++)
8954  {
8955  dshape(o,0) = dshape_x(i)* shape_y(j);
8956  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8957  }
8958 }
8959 
8960 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
8961 {
8962  const int p = Order;
8963  const double *op = poly1d.OpenPoints(p, b_type);
8964 
8965 #ifdef MFEM_THREAD_SAFE
8966  Vector shape_x(p+1), shape_y(p+1);
8967 #endif
8968 
8969  for (int i = 0; i <= p; i++)
8970  {
8971  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8972  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8973  }
8974 
8975  switch (vertex)
8976  {
8977  case 0:
8978  for (int o = 0, j = 0; j <= p; j++)
8979  for (int i = 0; i <= p; i++)
8980  {
8981  dofs[o++] = shape_x(i)*shape_x(j);
8982  }
8983  break;
8984  case 1:
8985  for (int o = 0, j = 0; j <= p; j++)
8986  for (int i = 0; i <= p; i++)
8987  {
8988  dofs[o++] = shape_y(i)*shape_x(j);
8989  }
8990  break;
8991  case 2:
8992  for (int o = 0, j = 0; j <= p; j++)
8993  for (int i = 0; i <= p; i++)
8994  {
8995  dofs[o++] = shape_y(i)*shape_y(j);
8996  }
8997  break;
8998  case 3:
8999  for (int o = 0, j = 0; j <= p; j++)
9000  for (int i = 0; i <= p; i++)
9001  {
9002  dofs[o++] = shape_x(i)*shape_y(j);
9003  }
9004  break;
9005  }
9006 }
9007 
9008 
9010  : PositiveTensorFiniteElement(2, p, L2_DOF_MAP)
9011 {
9012 #ifndef MFEM_THREAD_SAFE
9013  shape_x.SetSize(p + 1);
9014  shape_y.SetSize(p + 1);
9015  dshape_x.SetSize(p + 1);
9016  dshape_y.SetSize(p + 1);
9017 #endif
9018 
9019  if (p == 0)
9020  {
9021  Nodes.IntPoint(0).Set2(0.5, 0.5);
9022  }
9023  else
9024  {
9025  for (int o = 0, j = 0; j <= p; j++)
9026  for (int i = 0; i <= p; i++)
9027  {
9028  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
9029  }
9030  }
9031 }
9032 
9034  Vector &shape) const
9035 {
9036  const int p = Order;
9037 
9038 #ifdef MFEM_THREAD_SAFE
9039  Vector shape_x(p+1), shape_y(p+1);
9040 #endif
9041 
9042  Poly_1D::CalcBernstein(p, ip.x, shape_x);
9043  Poly_1D::CalcBernstein(p, ip.y, shape_y);
9044 
9045  for (int o = 0, j = 0; j <= p; j++)
9046  for (int i = 0; i <= p; i++)
9047  {
9048  shape(o++) = shape_x(i)*shape_y(j);
9049  }
9050 }
9051 
9053  DenseMatrix &dshape) const
9054 {
9055  const int p = Order;
9056 
9057 #ifdef MFEM_THREAD_SAFE
9058  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
9059 #endif
9060 
9061  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
9062  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
9063 
9064  for (int o = 0, j = 0; j <= p; j++)
9065  for (int i = 0; i <= p; i++)
9066  {
9067  dshape(o,0) = dshape_x(i)* shape_y(j);
9068  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
9069  }
9070 }
9071 
9073 {
9074  const int p = Order;
9075 
9076  dofs = 0.0;
9077  switch (vertex)
9078  {
9079  case 0: dofs[0] = 1.0; break;
9080  case 1: dofs[p] = 1.0; break;
9081  case 2: dofs[p*(p + 2)] = 1.0; break;
9082  case 3: dofs[p*(p + 1)] = 1.0; break;
9083  }
9084 }
9085 
9086 
9087 L2_HexahedronElement::L2_HexahedronElement(const int p, const int btype)
9088  : NodalTensorFiniteElement(3, p, VerifyOpen(btype), L2_DOF_MAP)
9089 {
9090  const double *op = poly1d.OpenPoints(p, btype);
9091 
9092 #ifndef MFEM_THREAD_SAFE
9093  shape_x.SetSize(p + 1);
9094  shape_y.SetSize(p + 1);
9095  shape_z.SetSize(p + 1);
9096  dshape_x.SetSize(p + 1);
9097  dshape_y.SetSize(p + 1);
9098  dshape_z.SetSize(p + 1);
9099 #endif
9100 
9101  for (int o = 0, k = 0; k <= p; k++)
9102  for (int j = 0; j <= p; j++)
9103  for (int i = 0; i <= p; i++)
9104  {
9105  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
9106  }
9107 }
9108 
9110  Vector &shape) const
9111 {
9112  const int p = Order;
9113 
9114 #ifdef MFEM_THREAD_SAFE
9115  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9116 #endif
9117 
9118  basis1d.Eval(ip.x, shape_x);
9119  basis1d.Eval(ip.y, shape_y);
9120  basis1d.Eval(ip.z, shape_z);
9121 
9122  for (int o = 0, k = 0; k <= p; k++)
9123  for (int j = 0; j <= p; j++)
9124  for (int i = 0; i <= p; i++)
9125  {
9126  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
9127  }
9128 }
9129 
9131  DenseMatrix &dshape) const
9132 {
9133  const int p = Order;
9134 
9135 #ifdef MFEM_THREAD_SAFE
9136  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9137  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
9138 #endif
9139 
9140  basis1d.Eval(ip.x, shape_x, dshape_x);
9141  basis1d.Eval(ip.y, shape_y, dshape_y);
9142  basis1d.Eval(ip.z, shape_z, dshape_z);
9143 
9144  for (int o = 0, k = 0; k <= p; k++)
9145  for (int j = 0; j <= p; j++)
9146  for (int i = 0; i <= p; i++)
9147  {
9148  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
9149  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
9150  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
9151  }
9152 }
9153 
9154 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9155 {
9156  const int p = Order;
9157  const double *op = poly1d.OpenPoints(p, b_type);
9158 
9159 #ifdef MFEM_THREAD_SAFE
9160  Vector shape_x(p+1), shape_y(p+1);
9161 #endif
9162 
9163  for (int i = 0; i <= p; i++)
9164  {
9165  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
9166  shape_y(i) = poly1d.CalcDelta(p,op[i]);
9167  }
9168 
9169  switch (vertex)
9170  {
9171  case 0:
9172  for (int o = 0, k = 0; k <= p; k++)
9173  for (int j = 0; j <= p; j++)
9174  for (int i = 0; i <= p; i++)
9175  {
9176  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
9177  }
9178  break;
9179  case 1:
9180  for (int o = 0, k = 0; k <= p; k++)
9181  for (int j = 0; j <= p; j++)
9182  for (int i = 0; i <= p; i++)
9183  {
9184  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
9185  }
9186  break;
9187  case 2:
9188  for (int o = 0, k = 0; k <= p; k++)
9189  for (int j = 0; j <= p; j++)
9190  for (int i = 0; i <= p; i++)
9191  {
9192  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
9193  }
9194  break;
9195  case 3:
9196  for (int o = 0, k = 0; k <= p; k++)
9197  for (int j = 0; j <= p; j++)
9198  for (int i = 0; i <= p; i++)
9199  {
9200  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
9201  }
9202  break;
9203  case 4:
9204  for (int o = 0, k = 0; k <= p; k++)
9205  for (int j = 0; j <= p; j++)
9206  for (int i = 0; i <= p; i++)
9207  {
9208  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
9209  }
9210  break;
9211  case 5:
9212  for (int o = 0, k = 0; k <= p; k++)
9213  for (int j = 0; j <= p; j++)
9214  for (int i = 0; i <= p; i++)
9215  {
9216  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
9217  }
9218  break;
9219  case 6:
9220  for (int o = 0, k = 0; k <= p; k++)
9221  for (int j = 0; j <= p; j++)
9222  for (int i = 0; i <= p; i++)
9223  {
9224  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
9225  }
9226  break;
9227  case 7:
9228  for (int o = 0, k = 0; k <= p; k++)
9229  for (int j = 0; j <= p; j++)
9230  for (int i = 0; i <= p; i++)
9231  {
9232  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
9233  }
9234  break;
9235  }
9236 }
9237 
9238 
9240  : PositiveTensorFiniteElement(3, p, L2_DOF_MAP)
9241 {
9242 #ifndef MFEM_THREAD_SAFE
9243  shape_x.SetSize(p + 1);
9244  shape_y.SetSize(p + 1);
9245  shape_z.SetSize(p + 1);
9246  dshape_x.SetSize(p + 1);
9247  dshape_y.SetSize(p + 1);
9248  dshape_z.SetSize(p + 1);
9249 #endif
9250 
9251  if (p == 0)
9252  {
9253  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
9254  }
9255  else
9256  {
9257  for (int o = 0, k = 0; k <= p; k++)
9258  for (int j = 0; j <= p; j++)
9259  for (int i = 0; i <= p; i++)
9260  {
9261  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
9262  }
9263  }
9264 }
9265 
9267  Vector &shape) const
9268 {
9269  const int p = Order;
9270 
9271 #ifdef MFEM_THREAD_SAFE
9272  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9273 #endif
9274 
9275  Poly_1D::CalcBernstein(p, ip.x, shape_x);
9276  Poly_1D::CalcBernstein(p, ip.y, shape_y);
9277  Poly_1D::CalcBernstein(p, ip.z, shape_z);
9278 
9279  for (int o = 0, k = 0; k <= p; k++)
9280  for (int j = 0; j <= p; j++)
9281  for (int i = 0; i <= p; i++)
9282  {
9283  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
9284  }
9285 }
9286 
9288  DenseMatrix &dshape) const
9289 {
9290  const int p = Order;
9291 
9292 #ifdef MFEM_THREAD_SAFE
9293  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
9294  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
9295 #endif
9296 
9297  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
9298  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
9299  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
9300 
9301  for (int o = 0, k = 0; k <= p; k++)
9302  for (int j = 0; j <= p; j++)
9303  for (int i = 0; i <= p; i++)
9304  {
9305  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
9306  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
9307  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
9308  }
9309 }
9310 
9311 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9312 {
9313  const int p = Order;
9314 
9315  dofs = 0.0;
9316  switch (vertex)
9317  {
9318  case 0: dofs[0] = 1.0; break;
9319  case 1: dofs[p] = 1.0; break;
9320  case 2: dofs[p*(p + 2)] = 1.0; break;
9321  case 3: dofs[p*(p + 1)] = 1.0; break;
9322  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
9323  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
9324  case 6: dofs[Dof - 1] = 1.0; break;
9325  case 7: dofs[Dof - p - 1] = 1.0; break;
9326  }
9327 }
9328 
9329 
9330 L2_TriangleElement::L2_TriangleElement(const int p, const int btype)
9331  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
9332  FunctionSpace::Pk)
9333 {
9334  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
9335 
9336 #ifndef MFEM_THREAD_SAFE
9337  shape_x.SetSize(p + 1);
9338  shape_y.SetSize(p + 1);
9339  shape_l.SetSize(p + 1);
9340  dshape_x.SetSize(p + 1);
9341  dshape_y.SetSize(p + 1);
9342  dshape_l.SetSize(p + 1);
9343  u.SetSize(Dof);
9344  du.SetSize(Dof, Dim);
9345 #else
9346  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9347 #endif
9348 
9349  for (int o = 0, j = 0; j <= p; j++)
9350  for (int i = 0; i + j <= p; i++)
9351  {
9352  double w = op[i] + op[j] + op[p-i-j];
9353  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
9354  }
9355 
9356  DenseMatrix T(Dof);
9357  for (int k = 0; k < Dof; k++)
9358  {
9359  IntegrationPoint &ip = Nodes.IntPoint(k);
9360  poly1d.CalcBasis(p, ip.x, shape_x);
9361  poly1d.CalcBasis(p, ip.y, shape_y);
9362  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9363 
9364  for (int o = 0, j = 0; j <= p; j++)
9365  for (int i = 0; i + j <= p; i++)
9366  {
9367  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9368  }
9369  }
9370 
9371  Ti.Factor(T);
9372  // mfem::out << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
9373 }
9374 
9376  Vector &shape) const
9377 {
9378  const int p = Order;
9379 
9380 #ifdef MFEM_THREAD_SAFE
9381  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
9382 #endif
9383 
9384  poly1d.CalcBasis(p, ip.x, shape_x);
9385  poly1d.CalcBasis(p, ip.y, shape_y);
9386  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9387 
9388  for (int o = 0, j = 0; j <= p; j++)
9389  for (int i = 0; i + j <= p; i++)
9390  {
9391  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9392  }
9393 
9394  Ti.Mult(u, shape);
9395 }
9396 
9398  DenseMatrix &dshape) const
9399 {
9400  const int p = Order;
9401 
9402 #ifdef MFEM_THREAD_SAFE
9403  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9404  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
9405  DenseMatrix du(Dof, Dim);
9406 #endif
9407 
9408  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9409  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9410  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
9411 
9412  for (int o = 0, j = 0; j <= p; j++)
9413  for (int i = 0; i + j <= p; i++)
9414  {
9415  int k = p - i - j;
9416  du(o,0) = ((dshape_x(i)* shape_l(k)) -
9417  ( shape_x(i)*dshape_l(k)))*shape_y(j);
9418  du(o,1) = ((dshape_y(j)* shape_l(k)) -
9419  ( shape_y(j)*dshape_l(k)))*shape_x(i);
9420  o++;
9421  }
9422 
9423  Ti.Mult(du, dshape);
9424 }
9425 
9426 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
9427 {
9428  switch (vertex)
9429  {
9430  case 0:
9431  for (int i = 0; i < Dof; i++)
9432  {
9433  const IntegrationPoint &ip = Nodes.IntPoint(i);
9434  dofs[i] = pow(1.0 - ip.x - ip.y, Order);
9435  }
9436  break;
9437  case 1:
9438  for (int i = 0; i < Dof; i++)
9439  {
9440  const IntegrationPoint &ip = Nodes.IntPoint(i);
9441  dofs[i] = pow(ip.x, Order);
9442  }
9443  break;
9444  case 2:
9445  for (int i = 0; i < Dof; i++)
9446  {
9447  const IntegrationPoint &ip = Nodes.IntPoint(i);
9448  dofs[i] = pow(ip.y, Order);
9449  }
9450  break;
9451  }
9452 }
9453 
9454 
9456  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
9457  FunctionSpace::Pk)
9458 {
9459 #ifndef MFEM_THREAD_SAFE
9460  dshape_1d.SetSize(p + 1);
9461 #endif
9462 
9463  if (p == 0)
9464  {
9465  Nodes.IntPoint(0).Set2(1./3, 1./3);
9466  }
9467  else
9468  {
9469  for (int o = 0, j = 0; j <= p; j++)
9470  for (int i = 0; i + j <= p; i++)
9471  {
9472  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
9473  }
9474  }
9475 }
9476 
9478  Vector &shape) const
9479 {
9480  H1Pos_TriangleElement::CalcShape(Order, ip.x, ip.y, shape.GetData());
9481 }
9482 
9484  DenseMatrix &dshape) const
9485 {
9486 #ifdef MFEM_THREAD_SAFE
9487  Vector dshape_1d(Order + 1);
9488 #endif
9489 
9490  H1Pos_TriangleElement::CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(),
9491  dshape.Data());
9492 }
9493 
9494 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
9495 {
9496  dofs = 0.0;
9497  switch (vertex)
9498  {
9499  case 0: dofs[0] = 1.0; break;
9500  case 1: dofs[Order] = 1.0; break;
9501  case 2: dofs[Dof-1] = 1.0; break;
9502  }
9503 }
9504 
9505 
9507  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
9508  p, FunctionSpace::Pk)
9509 {
9510  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
9511 
9512 #ifndef MFEM_THREAD_SAFE
9513  shape_x.SetSize(p + 1);
9514  shape_y.SetSize(p + 1);
9515  shape_z.SetSize(p + 1);
9516  shape_l.SetSize(p + 1);
9517  dshape_x.SetSize(p + 1);
9518  dshape_y.SetSize(p + 1);
9519  dshape_z.SetSize(p + 1);
9520  dshape_l.SetSize(p + 1);
9521  u.SetSize(Dof);
9522  du.SetSize(Dof, Dim);
9523 #else
9524  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9525 #endif
9526 
9527  for (int o = 0, k = 0; k <= p; k++)
9528  for (int j = 0; j + k <= p; j++)
9529  for (int i = 0; i + j + k <= p; i++)
9530  {
9531  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
9532  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
9533  }
9534 
9535  DenseMatrix T(Dof);
9536  for (int m = 0; m < Dof; m++)
9537  {
9538  IntegrationPoint &ip = Nodes.IntPoint(m);
9539  poly1d.CalcBasis(p, ip.x, shape_x);
9540  poly1d.CalcBasis(p, ip.y, shape_y);
9541  poly1d.CalcBasis(p, ip.z, shape_z);
9542  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9543 
9544  for (int o = 0, k = 0; k <= p; k++)
9545  for (int j = 0; j + k <= p; j++)
9546  for (int i = 0; i + j + k <= p; i++)
9547  {
9548  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9549  }
9550  }
9551 
9552  Ti.Factor(T);
9553  // mfem::out << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
9554 }
9555 
9557  Vector &shape) const
9558 {
9559  const int p = Order;
9560 
9561 #ifdef MFEM_THREAD_SAFE
9562  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9563  Vector u(Dof);
9564 #endif
9565 
9566  poly1d.CalcBasis(p, ip.x, shape_x);
9567  poly1d.CalcBasis(p, ip.y, shape_y);
9568  poly1d.CalcBasis(p, ip.z, shape_z);
9569  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9570 
9571  for (int o = 0, k = 0; k <= p; k++)
9572  for (int j = 0; j + k <= p; j++)
9573  for (int i = 0; i + j + k <= p; i++)
9574  {
9575  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9576  }
9577 
9578  Ti.Mult(u, shape);
9579 }
9580 
9582  DenseMatrix &dshape) const
9583 {
9584  const int p = Order;
9585 
9586 #ifdef MFEM_THREAD_SAFE
9587  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9588  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
9589  DenseMatrix du(Dof, Dim);
9590 #endif
9591 
9592  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9593  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9594  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
9595  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
9596 
9597  for (int o = 0, k = 0; k <= p; k++)
9598  for (int j = 0; j + k <= p; j++)
9599  for (int i = 0; i + j + k <= p; i++)
9600  {
9601  int l = p - i - j - k;
9602  du(o,0) = ((dshape_x(i)* shape_l(l)) -
9603  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
9604  du(o,1) = ((dshape_y(j)* shape_l(l)) -
9605  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
9606  du(o,2) = ((dshape_z(k)* shape_l(l)) -
9607  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
9608  o++;
9609  }
9610 
9611  Ti.Mult(du, dshape);
9612 }
9613 
9614 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9615 {
9616  switch (vertex)
9617  {
9618  case 0:
9619  for (int i = 0; i < Dof; i++)
9620  {
9621  const IntegrationPoint &ip = Nodes.IntPoint(i);
9622  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, Order);
9623  }
9624  break;
9625  case 1:
9626  for (int i = 0; i < Dof; i++)
9627  {
9628  const IntegrationPoint &ip = Nodes.IntPoint(i);
9629  dofs[i] = pow(ip.x, Order);
9630  }
9631  break;
9632  case 2:
9633  for (int i = 0; i < Dof; i++)
9634  {
9635  const IntegrationPoint &ip = Nodes.IntPoint(i);
9636  dofs[i] = pow(ip.y, Order);
9637  }
9638  case 3:
9639  for (int i = 0; i < Dof; i++)
9640  {
9641  const IntegrationPoint &ip = Nodes.IntPoint(i);
9642  dofs[i] = pow(ip.z, Order);
9643  }
9644  break;
9645  }
9646 }
9647 
9648 
9650  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
9651  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
9652 {
9653 #ifndef MFEM_THREAD_SAFE
9654  dshape_1d.SetSize(p + 1);
9655 #endif
9656 
9657  if (p == 0)
9658  {
9659  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
9660  }
9661  else
9662  {
9663  for (int o = 0, k = 0; k <= p; k++)
9664  for (int j = 0; j + k <= p; j++)
9665  for (int i = 0; i + j + k <= p; i++)
9666  {
9667  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
9668  }
9669  }
9670 }
9671 
9673  Vector &shape) const
9674 {
9676  shape.GetData());
9677 }
9678 
9680  DenseMatrix &dshape) const
9681 {
9682 #ifdef MFEM_THREAD_SAFE
9683  Vector dshape_1d(Order + 1);
9684 #endif
9685 
9687  dshape_1d.GetData(), dshape.Data());
9688 }
9689 
9690 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9691 {
9692  dofs = 0.0;
9693  switch (vertex)
9694  {
9695  case 0: dofs[0] = 1.0; break;
9696  case 1: dofs[Order] = 1.0; break;
9697  case 2: dofs[(Order*(Order+3))/2] = 1.0; break;
9698  case 3: dofs[Dof-1] = 1.0; break;
9699  }
9700 }
9701 
9702 
9703 L2_WedgeElement::L2_WedgeElement(const int p, const int btype)
9704  : NodalFiniteElement(3, Geometry::PRISM, ((p + 1)*(p + 1)*(p + 2))/2,
9705  p, FunctionSpace::Qk),
9706  TriangleFE(p, btype),
9707  SegmentFE(p, btype)
9708 {
9709 #ifndef MFEM_THREAD_SAFE
9710  t_shape.SetSize(TriangleFE.GetDof());
9711  s_shape.SetSize(SegmentFE.GetDof());
9712  t_dshape.SetSize(TriangleFE.GetDof(), 2);
9713  s_dshape.SetSize(SegmentFE.GetDof(), 1);
9714 #endif
9715 
9716  t_dof.SetSize(Dof);
9717  s_dof.SetSize(Dof);
9718 
9719  // Interior DoFs
9720  int m=0;
9721  for (int k=0; k<=p; k++)
9722  {
9723  int l=0;
9724  for (int j=0; j<=p; j++)
9725  {
9726  for (int i=0; i<=j; i++)
9727  {
9728  t_dof[m] = l;
9729  s_dof[m] = k;
9730  l++; m++;
9731  }
9732  }
9733  }
9734 
9735  // Define Nodes
9736  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
9737  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
9738  for (int i=0; i<Dof; i++)
9739  {
9740  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
9741  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
9742  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
9743  }
9744 }
9745 
9747  Vector &shape) const
9748 {
9749 #ifdef MFEM_THREAD_SAFE
9750  Vector t_shape(TriangleFE.GetDof());
9751  Vector s_shape(SegmentFE.GetDof());
9752 #endif
9753 
9754  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9755 
9756  TriangleFE.CalcShape(ip, t_shape);
9757  SegmentFE.CalcShape(ipz, s_shape);
9758 
9759  for (int i=0; i<Dof; i++)
9760  {
9761  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
9762  }
9763 }
9764 
9766  DenseMatrix &dshape) const
9767 {
9768 #ifdef MFEM_THREAD_SAFE
9769  Vector t_shape(TriangleFE.GetDof());
9770  DenseMatrix t_dshape(TriangleFE.GetDof(), 2);
9771  Vector s_shape(SegmentFE.GetDof());
9772  DenseMatrix s_dshape(SegmentFE.GetDof(), 1);
9773 #endif
9774 
9775  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9776 
9777  TriangleFE.CalcShape(ip, t_shape);
9778  TriangleFE.CalcDShape(ip, t_dshape);
9779  SegmentFE.CalcShape(ipz, s_shape);
9780  SegmentFE.CalcDShape(ipz, s_dshape);
9781 
9782  for (int i=0; i<Dof; i++)
9783  {
9784  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
9785  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
9786  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
9787  }
9788 }
9789 
9790 
9792  : PositiveFiniteElement(3, Geometry::PRISM,
9793  ((p + 1)*(p + 1)*(p + 2))/2, p, FunctionSpace::Qk),
9794  TriangleFE(p),
9795  SegmentFE(p)
9796 {
9797 #ifndef MFEM_THREAD_SAFE
9802 #endif
9803 
9804  t_dof.SetSize(Dof);
9805  s_dof.SetSize(Dof);
9806 
9807  // Interior DoFs
9808  int m=0;
9809  for (int k=0; k<=p; k++)
9810  {
9811  int l=0;
9812  for (int j=0; j<=p; j++)
9813  {
9814  for (int i=0; i<=j; i++)
9815  {
9816  t_dof[m] = l;
9817  s_dof[m] = k;
9818  l++; m++;
9819  }
9820  }
9821  }
9822 
9823  // Define Nodes
9824  const IntegrationRule & t_Nodes = TriangleFE.GetNodes();
9825  const IntegrationRule & s_Nodes = SegmentFE.GetNodes();
9826  for (int i=0; i<Dof; i++)
9827  {
9828  Nodes.IntPoint(i).x = t_Nodes.IntPoint(t_dof[i]).x;
9829  Nodes.IntPoint(i).y = t_Nodes.IntPoint(t_dof[i]).y;
9830  Nodes.IntPoint(i).z = s_Nodes.IntPoint(s_dof[i]).x;
9831  }
9832 }
9833 
9835  Vector &shape) const
9836 {
9837 #ifdef MFEM_THREAD_SAFE
9840 #endif
9841 
9842  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9843 
9845  SegmentFE.CalcShape(ipz, s_shape);
9846 
9847  for (int i=0; i<Dof; i++)
9848  {
9849  shape[i] = t_shape[t_dof[i]] * s_shape[s_dof[i]];
9850  }
9851 }
9852 
9854  DenseMatrix &dshape) const
9855 {
9856 #ifdef MFEM_THREAD_SAFE
9861 #endif
9862 
9863  IntegrationPoint ipz; ipz.x = ip.z; ipz.y = 0.0; ipz.z = 0.0;
9864 
9867  SegmentFE.CalcShape(ipz, s_shape);
9869 
9870  for (int i=0; i<Dof; i++)
9871  {
9872  dshape(i, 0) = t_dshape(t_dof[i],0) * s_shape[s_dof[i]];
9873  dshape(i, 1) = t_dshape(t_dof[i],1) * s_shape[s_dof[i]];
9874  dshape(i, 2) = t_shape[t_dof[i]] * s_dshape(s_dof[i],0);
9875  }
9876 }
9877 
9878 
9879 const double RT_QuadrilateralElement::nk[8] =
9880 { 0., -1., 1., 0., 0., 1., -1., 0. };
9881 
9883  const int cb_type,
9884  const int ob_type)
9885  : VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p + 1,
9886  H_DIV, FunctionSpace::Qk),
9887  cbasis1d(poly1d.GetBasis(p + 1, VerifyClosed(cb_type))),
9888  obasis1d(poly1d.GetBasis(p, VerifyOpen(ob_type))),
9889  dof_map(Dof), dof2nk(Dof)
9890 {
9891  const double *cp = poly1d.ClosedPoints(p + 1, cb_type);
9892  const double *op = poly1d.OpenPoints(p, ob_type);
9893  const int dof2 = Dof/2;
9894 
9895 #ifndef MFEM_THREAD_SAFE
9896  shape_cx.SetSize(p + 2);
9897  shape_ox.SetSize(p + 1);
9898  shape_cy.SetSize(p + 2);
9899  shape_oy.SetSize(p + 1);
9900  dshape_cx.SetSize(p + 2);
9901  dshape_cy.SetSize(p + 2);
9902 #endif
9903 
9904  // edges
9905  int o = 0;
9906  for (int i = 0; i <= p; i++) // (0,1)
9907  {
9908  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
9909  }
9910  for (int i = 0; i <= p; i++) // (1,2)
9911  {
9912  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
9913  }
9914  for (int i = 0; i <= p; i++) // (2,3)
9915  {
9916  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
9917  }
9918  for (int i = 0; i <= p; i++) // (3,0)
9919  {
9920  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
9921  }
9922 
9923  // interior
9924  for (int j = 0; j <= p; j++) // x-components
9925  for (int i = 1; i <= p; i++)
9926  {
9927  dof_map[0*dof2 + i + j*(p + 2)] = o++;
9928  }
9929  for (int j = 1; j <= p; j++) // y-components
9930  for (int i = 0; i <= p; i++)
9931  {
9932  dof_map[1*dof2 + i + j*(p + 1)] = o++;
9933  }
9934 
9935  // dof orientations
9936  // x-components
9937  for (int j = 0; j <= p; j++)
9938  for (int i = 0; i <= p/2; i++)
9939  {
9940  int idx = 0*dof2 + i + j*(p + 2);
9941  dof_map[idx] = -1 - dof_map[idx];
9942  }
9943  if (p%2 == 1)
9944  for (int j = p/2 + 1; j <= p; j++)
9945  {
9946  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
9947  dof_map[idx] = -1 - dof_map[idx];
9948  }
9949  // y-components
9950  for (int j = 0; j <= p/2; j++)
9951  for (int i = 0; i <= p; i++)
9952  {
9953  int idx = 1*dof2 + i + j*(p + 1);
9954  dof_map[idx] = -1 - dof_map[idx];
9955  }
9956  if (p%2 == 1)
9957  for (int i = 0; i <= p/2; i++)
9958  {
9959  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
9960  dof_map[idx] = -1 - dof_map[idx];
9961  }
9962 
9963  o = 0;
9964  for (int j = 0; j <= p; j++)
9965  for (int i = 0; i <= p + 1; i++)
9966  {
9967  int idx;
9968  if ((idx = dof_map[o++]) < 0)
9969  {
9970  idx = -1 - idx;
9971  dof2nk[idx] = 3;
9972  }
9973  else
9974  {
9975  dof2nk[idx] = 1;
9976  }
9977  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
9978  }
9979  for (int j = 0; j <= p + 1; j++)
9980  for (int i = 0; i <= p; i++)
9981  {
9982  int idx;
9983  if ((idx = dof_map[o++]) < 0)
9984  {
9985  idx = -1 - idx;
9986  dof2nk[idx] = 0;
9987  }
9988  else
9989  {
9990  dof2nk[idx] = 2;
9991  }
9992  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
9993  }
9994 }
9995 
9997  DenseMatrix &shape) const
9998 {
9999  const int pp1 = Order;
10000 
10001 #ifdef MFEM_THREAD_SAFE
10002  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10003 #endif
10004 
10005  cbasis1d.Eval(ip.x, shape_cx);
10006  obasis1d.Eval(ip.x, shape_ox);
10007  cbasis1d.Eval(ip.y, shape_cy);
10008  obasis1d.Eval(ip.y, shape_oy);
10009 
10010  int o = 0;
10011  for (int j = 0; j < pp1; j++)
10012  for (int i = 0; i <= pp1; i++)
10013  {
10014  int idx, s;
10015  if ((idx = dof_map[o++]) < 0)
10016  {
10017  idx = -1 - idx, s = -1;
10018  }
10019  else
10020  {
10021  s = +1;
10022  }
10023  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
10024  shape(idx,1) = 0.;
10025  }
10026  for (int j = 0; j <= pp1; j++)
10027  for (int i = 0; i < pp1; i++)
10028  {
10029  int idx, s;
10030  if ((idx = dof_map[o++]) < 0)
10031  {
10032  idx = -1 - idx, s = -1;
10033  }
10034  else
10035  {
10036  s = +1;
10037  }
10038  shape(idx,0) = 0.;
10039  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
10040  }
10041 }
10042 
10044  Vector &divshape) const
10045 {
10046  const int pp1 = Order;
10047 
10048 #ifdef MFEM_THREAD_SAFE
10049  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10050  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
10051 #endif
10052 
10053  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10054  obasis1d.Eval(ip.x, shape_ox);
10055  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10056  obasis1d.Eval(ip.y, shape_oy);
10057 
10058  int o = 0;
10059  for (int j = 0; j < pp1; j++)
10060  for (int i = 0; i <= pp1; i++)
10061  {
10062  int idx, s;
10063  if ((idx = dof_map[o++]) < 0)
10064  {
10065  idx = -1 - idx, s = -1;
10066  }
10067  else
10068  {
10069  s = +1;
10070  }
10071  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
10072  }
10073  for (int j = 0; j <= pp1; j++)
10074  for (int i = 0; i < pp1; i++)
10075  {
10076  int idx, s;
10077  if ((idx = dof_map[o++]) < 0)
10078  {
10079  idx = -1 - idx, s = -1;
10080  }
10081  else
10082  {
10083  s = +1;
10084  }
10085  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
10086  }
10087 }
10088 
10089 
10090 const double RT_HexahedronElement::nk[18] =
10091 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
10092 
10094  const int cb_type,
10095  const int ob_type)
10096  : VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 1)*(p + 2), p + 1,
10097  H_DIV, FunctionSpace::Qk),
10098  cbasis1d(poly1d.GetBasis(p + 1, VerifyClosed(cb_type))),
10099  obasis1d(poly1d.GetBasis(p, VerifyOpen(ob_type))),
10100  dof_map(Dof), dof2nk(Dof)
10101 {
10102  const double *cp = poly1d.ClosedPoints(p + 1, cb_type);
10103  const double *op = poly1d.OpenPoints(p, ob_type);
10104  const int dof3 = Dof/3;
10105 
10106 #ifndef MFEM_THREAD_SAFE
10107  shape_cx.SetSize(p + 2);
10108  shape_ox.SetSize(p + 1);
10109  shape_cy.SetSize(p + 2);
10110  shape_oy.SetSize(p + 1);
10111  shape_cz.SetSize(p + 2);
10112  shape_oz.SetSize(p + 1);
10113  dshape_cx.SetSize(p + 2);
10114  dshape_cy.SetSize(p + 2);
10115  dshape_cz.SetSize(p + 2);
10116 #endif
10117 
10118  // faces
10119  int o = 0;
10120  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
10121  for (int i = 0; i <= p; i++)
10122  {
10123  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
10124  }
10125  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
10126  for (int i = 0; i <= p; i++)
10127  {
10128  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
10129  }
10130  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
10131  for (int i = 0; i <= p; i++)
10132  {
10133  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
10134  }
10135  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
10136  for (int i = 0; i <= p; i++)
10137  {
10138  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
10139  }
10140  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
10141  for (int i = 0; i <= p; i++)
10142  {
10143  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
10144  }
10145  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
10146  for (int i = 0; i <= p; i++)
10147  {
10148  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
10149  }
10150 
10151  // interior
10152  // x-components
10153  for (int k = 0; k <= p; k++)
10154  for (int j = 0; j <= p; j++)
10155  for (int i = 1; i <= p; i++)
10156  {
10157  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
10158  }
10159  // y-components
10160  for (int k = 0; k <= p; k++)
10161  for (int j = 1; j <= p; j++)
10162  for (int i = 0; i <= p; i++)
10163  {
10164  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
10165  }
10166  // z-components
10167  for (int k = 1; k <= p; k++)
10168  for (int j = 0; j <= p; j++)
10169  for (int i = 0; i <= p; i++)
10170  {
10171  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
10172  }
10173 
10174  // dof orientations
10175  // for odd p, do not change the orientations in the mid-planes
10176  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
10177  // respectively.
10178  // x-components
10179  for (int k = 0; k <= p; k++)
10180  for (int j = 0; j <= p; j++)
10181  for (int i = 0; i <= p/2; i++)
10182  {
10183  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
10184  dof_map[idx] = -1 - dof_map[idx];
10185  }
10186  // y-components
10187  for (int k = 0; k <= p; k++)
10188  for (int j = 0; j <= p/2; j++)
10189  for (int i = 0; i <= p; i++)
10190  {
10191  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
10192  dof_map[idx] = -1 - dof_map[idx];
10193  }
10194  // z-components
10195  for (int k = 0; k <= p/2; k++)
10196  for (int j = 0; j <= p; j++)
10197  for (int i = 0; i <= p; i++)
10198  {
10199  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
10200  dof_map[idx] = -1 - dof_map[idx];
10201  }
10202 
10203  o = 0;
10204  // x-components
10205  for (int k = 0; k <= p; k++)
10206  for (int j = 0; j <= p; j++)
10207  for (int i = 0; i <= p + 1; i++)
10208  {
10209  int idx;
10210  if ((idx = dof_map[o++]) < 0)
10211  {
10212  idx = -1 - idx;
10213  dof2nk[idx] = 4;
10214  }
10215  else
10216  {
10217  dof2nk[idx] = 2;
10218  }
10219  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
10220  }
10221  // y-components
10222  for (int k = 0; k <= p; k++)
10223  for (int j = 0; j <= p + 1; j++)
10224  for (int i = 0; i <= p; i++)
10225  {
10226  int idx;
10227  if ((idx = dof_map[o++]) < 0)
10228  {
10229  idx = -1 - idx;
10230  dof2nk[idx] = 1;
10231  }
10232  else
10233  {
10234  dof2nk[idx] = 3;
10235  }
10236  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
10237  }
10238  // z-components
10239  for (int k = 0; k <= p + 1; k++)
10240  for (int j = 0; j <= p; j++)
10241  for (int i = 0; i <= p; i++)
10242  {
10243  int idx;
10244  if ((idx = dof_map[o++]) < 0)
10245  {
10246  idx = -1 - idx;
10247  dof2nk[idx] = 0;
10248  }
10249  else
10250  {
10251  dof2nk[idx] = 5;
10252  }
10253  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
10254  }
10255 }
10256 
10258  DenseMatrix &shape) const
10259 {
10260  const int pp1 = Order;
10261 
10262 #ifdef MFEM_THREAD_SAFE
10263  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10264  Vector shape_cz(pp1 + 1), shape_oz(pp1);
10265 #endif
10266 
10267  cbasis1d.Eval(ip.x, shape_cx);
10268  obasis1d.Eval(ip.x, shape_ox);
10269  cbasis1d.Eval(ip.y, shape_cy);
10270  obasis1d.Eval(ip.y, shape_oy);
10271  cbasis1d.Eval(ip.z, shape_cz);
10272  obasis1d.Eval(ip.z, shape_oz);
10273 
10274  int o = 0;
10275  // x-components
10276  for (int k = 0; k < pp1; k++)
10277  for (int j = 0; j < pp1; j++)
10278  for (int i = 0; i <= pp1; i++)
10279  {
10280  int idx, s;
10281  if ((idx = dof_map[o++]) < 0)
10282  {
10283  idx = -1 - idx, s = -1;
10284  }
10285  else
10286  {
10287  s = +1;
10288  }
10289  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
10290  shape(idx,1) = 0.;
10291  shape(idx,2) = 0.;
10292  }
10293  // y-components
10294  for (int k = 0; k < pp1; k++)
10295  for (int j = 0; j <= pp1; j++)
10296  for (int i = 0; i < pp1; i++)
10297  {
10298  int idx, s;
10299  if ((idx = dof_map[o++]) < 0)
10300  {
10301  idx = -1 - idx, s = -1;
10302  }
10303  else
10304  {
10305  s = +1;
10306  }
10307  shape(idx,0) = 0.;
10308  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
10309  shape(idx,2) = 0.;
10310  }
10311  // z-components
10312  for (int k = 0; k <= pp1; k++)
10313  for (int j = 0; j < pp1; j++)
10314  for (int i = 0; i < pp1; i++)
10315  {
10316  int idx, s;
10317  if ((idx = dof_map[o++]) < 0)
10318  {
10319  idx = -1 - idx, s = -1;
10320  }
10321  else
10322  {
10323  s = +1;
10324  }
10325  shape(idx,0) = 0.;
10326  shape(idx,1) = 0.;
10327  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
10328  }
10329 }
10330 
10332  Vector &divshape) const
10333 {
10334  const int pp1 = Order;
10335 
10336 #ifdef MFEM_THREAD_SAFE
10337  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
10338  Vector shape_cz(pp1 + 1), shape_oz(pp1);
10339  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
10340 #endif
10341 
10342  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10343  obasis1d.Eval(ip.x, shape_ox);
10344  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10345  obasis1d.Eval(ip.y, shape_oy);
10346  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
10347  obasis1d.Eval(ip.z, shape_oz);
10348 
10349  int o = 0;
10350  // x-components
10351  for (int k = 0; k < pp1; k++)
10352  for (int j = 0; j < pp1; j++)
10353  for (int i = 0; i <= pp1; i++)
10354  {
10355  int idx, s;
10356  if ((idx = dof_map[o++]) < 0)
10357  {
10358  idx = -1 - idx, s = -1;
10359  }
10360  else
10361  {
10362  s = +1;
10363  }
10364  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
10365  }
10366  // y-components
10367  for (int k = 0; k < pp1; k++)
10368  for (int j = 0; j <= pp1; j++)
10369  for (int i = 0; i < pp1; i++)
10370  {
10371  int idx, s;
10372  if ((idx = dof_map[o++]) < 0)
10373  {
10374  idx = -1 - idx, s = -1;
10375  }
10376  else
10377  {
10378  s = +1;
10379  }
10380  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
10381  }
10382  // z-components
10383  for (int k = 0; k <= pp1; k++)
10384  for (int j = 0; j < pp1; j++)
10385  for (int i = 0; i < pp1; i++)
10386  {
10387  int idx, s;
10388  if ((idx = dof_map[o++]) < 0)
10389  {
10390  idx = -1 - idx, s = -1;
10391  }
10392  else
10393  {
10394  s = +1;
10395  }
10396  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
10397  }
10398 }
10399 
10400 
10401 const double RT_TriangleElement::nk[6] =
10402 { 0., -1., 1., 1., -1., 0. };
10403 
10404 const double RT_TriangleElement::c = 1./3.;
10405 
10407  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
10408  H_DIV, FunctionSpace::Pk),
10409  dof2nk(Dof)
10410 {
10411  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
10412  const double *bop = poly1d.OpenPoints(p);
10413 
10414 #ifndef MFEM_THREAD_SAFE
10415  shape_x.SetSize(p + 1);
10416  shape_y.SetSize(p + 1);
10417  shape_l.SetSize(p + 1);
10418  dshape_x.SetSize(p + 1);
10419  dshape_y.SetSize(p + 1);
10420  dshape_l.SetSize(p + 1);
10421  u.SetSize(Dof, Dim);
10422  divu.SetSize(Dof);
10423 #else
10424  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10425 #endif
10426 
10427  // edges
10428  int o = 0;
10429  for (int i = 0; i <= p; i++) // (0,1)
10430  {
10431  Nodes.IntPoint(o).Set2(bop[i], 0.);
10432  dof2nk[o++] = 0;
10433  }
10434  for (int i = 0; i <= p; i++) // (1,2)
10435  {
10436  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
10437  dof2nk[o++] = 1;
10438  }
10439  for (int i = 0; i <= p; i++) // (2,0)
10440  {
10441  Nodes.IntPoint(o).Set2(0., bop[p-i]);
10442  dof2nk[o++] = 2;
10443  }
10444 
10445  // interior
10446  for (int j = 0; j < p; j++)
10447  for (int i = 0; i + j < p; i++)
10448  {
10449  double w = iop[i] + iop[j] + iop[p-1-i-j];
10450  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
10451  dof2nk[o++] = 0;
10452  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
10453  dof2nk[o++] = 2;
10454  }
10455 
10456  DenseMatrix T(Dof);
10457  for (int k = 0; k < Dof; k++)
10458  {
10459  const IntegrationPoint &ip = Nodes.IntPoint(k);
10460  poly1d.CalcBasis(p, ip.x, shape_x);
10461  poly1d.CalcBasis(p, ip.y, shape_y);
10462  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
10463  const double *n_k = nk + 2*dof2nk[k];
10464 
10465  o = 0;
10466  for (int j = 0; j <= p; j++)
10467  for (int i = 0; i + j <= p; i++)
10468  {
10469  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
10470  T(o++, k) = s*n_k[0];
10471  T(o++, k) = s*n_k[1];
10472  }
10473  for (int i = 0; i <= p; i++)
10474  {
10475  double s = shape_x(i)*shape_y(p-i);
10476  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
10477  }
10478  }
10479 
10480  Ti.Factor(T);
10481  // mfem::out << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
10482 }
10483 
10485  DenseMatrix &shape) const
10486 {
10487  const int p = Order - 1;
10488 
10489 #ifdef MFEM_THREAD_SAFE
10490  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10491  DenseMatrix u(Dof, Dim);
10492 #endif
10493 
10494  poly1d.CalcBasis(p, ip.x, shape_x);
10495  poly1d.CalcBasis(p, ip.y, shape_y);
10496  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
10497 
10498  int o = 0;
10499  for (int j = 0; j <= p; j++)
10500  for (int i = 0; i + j <= p; i++)
10501  {
10502  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
10503  u(o,0) = s; u(o,1) = 0; o++;
10504  u(o,0) = 0; u(o,1) = s; o++;
10505  }
10506  for (int i = 0; i <= p; i++)
10507  {
10508  double s = shape_x(i)*shape_y(p-i);
10509  u(o,0) = (ip.x - c)*s;
10510  u(o,1) = (ip.y - c)*s;
10511  o++;
10512  }
10513 
10514  Ti.Mult(u, shape);
10515 }
10516 
10518  Vector &divshape) const
10519 {
10520  const int p = Order - 1;
10521 
10522 #ifdef MFEM_THREAD_SAFE
10523  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
10524  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
10525  Vector divu(Dof);
10526 #endif
10527 
10528  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
10529  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
10530  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
10531 
10532  int o = 0;
10533  for (int j = 0; j <= p; j++)
10534  for (int i = 0; i + j <= p; i++)
10535  {
10536  int k = p - i - j;
10537  divu(o++) = (dshape_x(i)*shape_l(k) -
10538  shape_x(i)*dshape_l(k))*shape_y(j);
10539  divu(o++) = (dshape_y(j)*shape_l(k) -
10540  shape_y(j)*dshape_l(k))*shape_x(i);
10541  }
10542  for (int i = 0; i <= p; i++)
10543  {
10544  int j = p - i;
10545  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
10546  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
10547  }
10548 
10549  Ti.Mult(divu, divshape);
10550 }
10551 
10552 
10553 const double RT_TetrahedronElement::nk[12] =
10554 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
10555 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
10556 
10557 const double RT_TetrahedronElement::c = 1./4.;
10558 
10560  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
10561  p + 1, H_DIV, FunctionSpace::Pk),
10562  dof2nk(Dof)
10563 {
10564  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
10565  const double *bop = poly1d.OpenPoints(p);
10566 
10567 #ifndef MFEM_THREAD_SAFE
10568  shape_x.SetSize(p + 1);
10569  shape_y.SetSize(p + 1);
10570  shape_z.SetSize(p + 1);
10571  shape_l.SetSize(p + 1);
10572  dshape_x.SetSize(p + 1);
10573  dshape_y.SetSize(p + 1);
10574  dshape_z.SetSize(p + 1);
10575  dshape_l.SetSize(p + 1);
10576  u.SetSize(Dof, Dim);
10577  divu.SetSize(Dof);
10578 #else
10579  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10580 #endif
10581 
10582  int o = 0;
10583  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
10584  // the constructor of H1_TetrahedronElement)
10585  for (int j = 0; j <= p; j++)
10586  for (int i = 0; i + j <= p; i++) // (1,2,3)
10587  {
10588  double w = bop[i] + bop[j] + bop[p-i-j];
10589  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
10590  dof2nk[o++] = 0;
10591  }
10592  for (int j = 0; j <= p; j++)
10593  for (int i = 0; i + j <= p; i++) // (0,3,2)
10594  {
10595  double w = bop[i] + bop[j] + bop[p-i-j];
10596  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
10597  dof2nk[o++] = 1;
10598  }
10599  for (int j = 0; j <= p; j++)
10600  for (int i = 0; i + j <= p; i++) // (0,1,3)
10601  {
10602  double w = bop[i] + bop[j] + bop[p-i-j];
10603  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
10604  dof2nk[o++] = 2;
10605  }
10606  for (int j = 0; j <= p; j++)
10607  for (int i = 0; i + j <= p; i++) // (0,2,1)
10608  {
10609  double w = bop[i] + bop[j] + bop[p-i-j];
10610  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
10611  dof2nk[o++] = 3;
10612  }
10613 
10614  // interior
10615  for (int k = 0; k < p; k++)
10616  for (int j = 0; j + k < p; j++)
10617  for (int i = 0; i + j + k < p; i++)
10618  {
10619  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
10620  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10621  dof2nk[o++] = 1;
10622  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10623  dof2nk[o++] = 2;
10624  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10625  dof2nk[o++] = 3;
10626  }
10627 
10628  DenseMatrix T(Dof);
10629  for (int m = 0; m < Dof; m++)
10630  {
10631  const IntegrationPoint &ip = Nodes.IntPoint(m);
10632  poly1d.CalcBasis(p, ip.x, shape_x);
10633  poly1d.CalcBasis(p, ip.y, shape_y);
10634  poly1d.CalcBasis(p, ip.z, shape_z);
10635  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
10636  const double *nm = nk + 3*dof2nk[m];
10637 
10638  o = 0;
10639  for (int k = 0; k <= p; k++)
10640  for (int j = 0; j + k <= p; j++)
10641  for (int i = 0; i + j + k <= p; i++)
10642  {
10643  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
10644  T(o++, m) = s * nm[0];
10645  T(o++, m) = s * nm[1];
10646  T(o++, m) = s * nm[2];
10647  }
10648  for (int j = 0; j <= p; j++)
10649  for (int i = 0; i + j <= p; i++)
10650  {
10651  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
10652  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
10653  (ip.z - c)*nm[2]);
10654  }
10655  }
10656 
10657  Ti.Factor(T);
10658  // mfem::out << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
10659 }
10660 
10662  DenseMatrix &shape) const
10663 {
10664  const int p = Order - 1;
10665 
10666 #ifdef MFEM_THREAD_SAFE
10667  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10668  DenseMatrix u(Dof, Dim);
10669 #endif
10670 
10671  poly1d.CalcBasis(p, ip.x, shape_x);
10672  poly1d.CalcBasis(p, ip.y, shape_y);
10673  poly1d.CalcBasis(p, ip.z, shape_z);
10674  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
10675 
10676  int o = 0;
10677  for (int k = 0; k <= p; k++)
10678  for (int j = 0; j + k <= p; j++)
10679  for (int i = 0; i + j + k <= p; i++)
10680  {
10681  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
10682  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
10683  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
10684  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
10685  }
10686  for (int j = 0; j <= p; j++)
10687  for (int i = 0; i + j <= p; i++)
10688  {
10689  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
10690  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
10691  o++;
10692  }
10693 
10694  Ti.Mult(u, shape);
10695 }
10696 
10698  Vector &divshape) const
10699 {
10700  const int p = Order - 1;
10701 
10702 #ifdef MFEM_THREAD_SAFE
10703  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
10704  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
10705  Vector divu(Dof);
10706 #endif
10707 
10708  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
10709  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
10710  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
10711  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10712 
10713  int o = 0;
10714  for (int k = 0; k <= p; k++)
10715  for (int j = 0; j + k <= p; j++)
10716  for (int i = 0; i + j + k <= p; i++)
10717  {
10718  int l = p - i - j - k;
10719  divu(o++) = (dshape_x(i)*shape_l(l) -
10720  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
10721  divu(o++) = (dshape_y(j)*shape_l(l) -
10722  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
10723  divu(o++) = (dshape_z(k)*shape_l(l) -
10724  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
10725  }
10726  for (int j = 0; j <= p; j++)
10727  for (int i = 0; i + j <= p; i++)
10728  {
10729  int k = p - i - j;
10730  divu(o++) =
10731  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
10732  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
10733  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
10734  }
10735 
10736  Ti.Mult(divu, divshape);
10737 }
10738 
10739 
10740 const double ND_HexahedronElement::tk[18] =
10741 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
10742 
10744  const int cb_type, const int ob_type)
10745  : VectorFiniteElement(3, Geometry::CUBE, 3*p*(p + 1)*(p + 1), p,
10746  H_CURL, FunctionSpace::Qk),
10747  cbasis1d(poly1d.GetBasis(p, VerifyClosed(cb_type))),
10748  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(ob_type))),
10749  dof_map(Dof), dof2tk(Dof)
10750 {
10751  const double *cp = poly1d.ClosedPoints(p, cb_type);
10752  const double *op = poly1d.OpenPoints(p - 1, ob_type);
10753  const int dof3 = Dof/3;
10754 
10755 #ifndef MFEM_THREAD_SAFE
10756  shape_cx.SetSize(p + 1);
10757  shape_ox.SetSize(p);
10758  shape_cy.SetSize(p + 1);
10759  shape_oy.SetSize(p);
10760  shape_cz.SetSize(p + 1);
10761  shape_oz.SetSize(p);
10762  dshape_cx.SetSize(p + 1);
10763  dshape_cy.SetSize(p + 1);
10764  dshape_cz.SetSize(p + 1);
10765 #endif
10766 
10767  // edges
10768  int o = 0;
10769  for (int i = 0; i < p; i++) // (0,1)
10770  {
10771  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
10772  }
10773  for (int i = 0; i < p; i++) // (1,2)
10774  {
10775  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
10776  }
10777  for (int i = 0; i < p; i++) // (3,2)
10778  {
10779  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
10780  }
10781  for (int i = 0; i < p; i++) // (0,3)
10782  {
10783  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
10784  }
10785  for (int i = 0; i < p; i++) // (4,5)
10786  {
10787  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
10788  }
10789  for (int i = 0; i < p; i++) // (5,6)
10790  {
10791  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
10792  }
10793  for (int i = 0; i < p; i++) // (7,6)
10794  {
10795  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
10796  }
10797  for (int i = 0; i < p; i++) // (4,7)
10798  {
10799  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
10800  }
10801  for (int i = 0; i < p; i++) // (0,4)
10802  {
10803  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
10804  }
10805  for (int i = 0; i < p; i++) // (1,5)
10806  {
10807  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
10808  }
10809  for (int i = 0; i < p; i++) // (2,6)
10810  {
10811  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
10812  }
10813  for (int i = 0; i < p; i++) // (3,7)
10814  {
10815  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
10816  }
10817 
10818  // faces
10819  // (3,2,1,0) -- bottom
10820  for (int j = 1; j < p; j++) // x - components
10821  for (int i = 0; i < p; i++)
10822  {
10823  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
10824  }
10825  for (int j = 0; j < p; j++) // y - components
10826  for (int i = 1; i < p; i++)
10827  {
10828  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
10829  }
10830  // (0,1,5,4) -- front
10831  for (int k = 1; k < p; k++) // x - components
10832  for (int i = 0; i < p; i++)
10833  {
10834  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
10835  }
10836  for (int k = 0; k < p; k++) // z - components
10837  for (int i = 1; i < p; i++ )
10838  {
10839  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
10840  }
10841  // (1,2,6,5) -- right
10842  for (int k = 1; k < p; k++) // y - components
10843  for (int j = 0; j < p; j++)
10844  {
10845  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
10846  }
10847  for (int k = 0; k < p; k++) // z - components
10848  for (int j = 1; j < p; j++)
10849  {
10850  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
10851  }
10852  // (2,3,7,6) -- back
10853  for (int k = 1; k < p; k++) // x - components
10854  for (int i = 0; i < p; i++)
10855  {
10856  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
10857  }
10858  for (int k = 0; k < p; k++) // z - components
10859  for (int i = 1; i < p; i++)
10860  {
10861  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
10862  }
10863  // (3,0,4,7) -- left
10864  for (int k = 1; k < p; k++) // y - components
10865  for (int j = 0; j < p; j++)
10866  {
10867  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
10868  }
10869  for (int k = 0; k < p; k++) // z - components
10870  for (int j = 1; j < p; j++)
10871  {
10872  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
10873  }
10874  // (4,5,6,7) -- top
10875  for (int j = 1; j < p; j++) // x - components
10876  for (int i = 0; i < p; i++)
10877  {
10878  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
10879  }
10880  for (int j = 0; j < p; j++) // y - components
10881  for (int i = 1; i < p; i++)
10882  {
10883  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
10884  }
10885 
10886  // interior
10887  // x-components
10888  for (int k = 1; k < p; k++)
10889  for (int j = 1; j < p; j++)
10890  for (int i = 0; i < p; i++)
10891  {
10892  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
10893  }
10894  // y-components
10895  for (int k = 1; k < p; k++)
10896  for (int j = 0; j < p; j++)
10897  for (int i = 1; i < p; i++)
10898  {
10899  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
10900  }
10901  // z-components
10902  for (int k = 0; k < p; k++)
10903  for (int j = 1; j < p; j++)
10904  for (int i = 1; i < p; i++)
10905  {
10906  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
10907  }
10908 
10909  // set dof2tk and Nodes
10910  o = 0;
10911  // x-components
10912  for (int k = 0; k <= p; k++)
10913  for (int j = 0; j <= p; j++)
10914  for (int i = 0; i < p; i++)
10915  {
10916  int idx;
10917  if ((idx = dof_map[o++]) < 0)
10918  {
10919  dof2tk[idx = -1 - idx] = 3;
10920  }
10921  else
10922  {
10923  dof2tk[idx] = 0;
10924  }
10925  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
10926  }
10927  // y-components
10928  for (int k = 0; k <= p; k++)
10929  for (int j = 0; j < p; j++)
10930  for (int i = 0; i <= p; i++)
10931  {
10932  int idx;
10933  if ((idx = dof_map[o++]) < 0)
10934  {
10935  dof2tk[idx = -1 - idx] = 4;
10936  }
10937  else
10938  {
10939  dof2tk[idx] = 1;
10940  }
10941  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
10942  }
10943  // z-components
10944  for (int k = 0; k < p; k++)
10945  for (int j = 0; j <= p; j++)
10946  for (int i = 0; i <= p; i++)
10947  {
10948  int idx;
10949  if ((idx = dof_map[o++]) < 0)
10950  {
10951  dof2tk[idx = -1 - idx] = 5;
10952  }
10953  else
10954  {
10955  dof2tk[idx] = 2;
10956  }
10957  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
10958  }
10959 }
10960 
10962  DenseMatrix &shape) const
10963 {
10964  const int p = Order;
10965 
10966 #ifdef MFEM_THREAD_SAFE
10967  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10968  Vector shape_cz(p + 1), shape_oz(p);
10969 #endif
10970 
10971  cbasis1d.Eval(ip.x, shape_cx);
10972  obasis1d.Eval(ip.x, shape_ox);
10973  cbasis1d.Eval(ip.y, shape_cy);
10974  obasis1d.Eval(ip.y, shape_oy);
10975  cbasis1d.Eval(ip.z, shape_cz);
10976  obasis1d.Eval(ip.z, shape_oz);
10977 
10978  int o = 0;
10979  // x-components
10980  for (int k = 0; k <= p; k++)
10981  for (int j = 0; j <= p; j++)
10982  for (int i = 0; i < p; i++)
10983  {
10984  int idx, s;
10985  if ((idx = dof_map[o++]) < 0)
10986  {
10987  idx = -1 - idx, s = -1;
10988  }
10989  else
10990  {
10991  s = +1;
10992  }
10993  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
10994  shape(idx,1) = 0.;
10995  shape(idx,2) = 0.;
10996  }
10997  // y-components
10998  for (int k = 0; k <= p; k++)
10999  for (int j = 0; j < p; j++)
11000  for (int i = 0; i <= p; i++)
11001  {
11002  int idx, s;
11003  if ((idx = dof_map[o++]) < 0)
11004  {
11005  idx = -1 - idx, s = -1;
11006  }
11007  else
11008  {
11009  s = +1;
11010  }
11011  shape(idx,0) = 0.;
11012  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
11013  shape(idx,2) = 0.;
11014  }
11015  // z-components
11016  for (int k = 0; k < p; k++)
11017  for (int j = 0; j <= p; j++)
11018  for (int i = 0; i <= p; i++)
11019  {
11020  int idx, s;
11021  if ((idx = dof_map[o++]) < 0)
11022  {
11023  idx = -1 - idx, s = -1;
11024  }
11025  else
11026  {
11027  s = +1;
11028  }
11029  shape(idx,0) = 0.;
11030  shape(idx,1) = 0.;
11031  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
11032  }
11033 }
11034 
11036  DenseMatrix &curl_shape) const
11037 {
11038  const int p = Order;
11039 
11040 #ifdef MFEM_THREAD_SAFE
11041  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11042  Vector shape_cz(p + 1), shape_oz(p);
11043  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
11044 #endif
11045 
11046  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11047  obasis1d.Eval(ip.x, shape_ox);
11048  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11049  obasis1d.Eval(ip.y, shape_oy);
11050  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
11051  obasis1d.Eval(ip.z, shape_oz);
11052 
11053  int o = 0;
11054  // x-components
11055  for (int k = 0; k <= p; k++)
11056  for (int j = 0; j <= p; j++)
11057  for (int i = 0; i < p; i++)
11058  {
11059  int idx, s;
11060  if ((idx = dof_map[o++]) < 0)
11061  {
11062  idx = -1 - idx, s = -1;
11063  }
11064  else
11065  {
11066  s = +1;
11067  }
11068  curl_shape(idx,0) = 0.;
11069  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
11070  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
11071  }
11072  // y-components
11073  for (int k = 0; k <= p; k++)
11074  for (int j = 0; j < p; j++)
11075  for (int i = 0; i <= p; i++)
11076  {
11077  int idx, s;
11078  if ((idx = dof_map[o++]) < 0)
11079  {
11080  idx = -1 - idx, s = -1;
11081  }
11082  else
11083  {
11084  s = +1;
11085  }
11086  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
11087  curl_shape(idx,1) = 0.;
11088  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
11089  }
11090  // z-components
11091  for (int k = 0; k < p; k++)
11092  for (int j = 0; j <= p; j++)
11093  for (int i = 0; i <= p; i++)
11094  {
11095  int idx, s;
11096  if ((idx = dof_map[o++]) < 0)
11097  {
11098  idx = -1 - idx, s = -1;
11099  }
11100  else
11101  {
11102  s = +1;
11103  }
11104  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
11105  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
11106  curl_shape(idx,2) = 0.;
11107  }
11108 }
11109 
11110 
11111 const double ND_QuadrilateralElement::tk[8] =
11112 { 1.,0., 0.,1., -1.,0., 0.,-1. };
11113 
11115  const int cb_type,
11116  const int ob_type)
11117  : VectorFiniteElement(2, Geometry::SQUARE, 2*p*(p + 1), p,
11118  H_CURL, FunctionSpace::Qk),
11119  cbasis1d(poly1d.GetBasis(p, VerifyClosed(cb_type))),
11120  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(ob_type))),
11121  dof_map(Dof), dof2tk(Dof)
11122 {
11123  const double *cp = poly1d.ClosedPoints(p, cb_type);
11124  const double *op = poly1d.OpenPoints(p - 1, ob_type);
11125  const int dof2 = Dof/2;
11126 
11127 #ifndef MFEM_THREAD_SAFE
11128  shape_cx.SetSize(p + 1);
11129  shape_ox.SetSize(p);
11130  shape_cy.SetSize(p + 1);
11131  shape_oy.SetSize(p);
11132  dshape_cx.SetSize(p + 1);
11133  dshape_cy.SetSize(p + 1);
11134 #endif
11135 
11136  // edges
11137  int o = 0;
11138  for (int i = 0; i < p; i++) // (0,1)
11139  {
11140  dof_map[0*dof2 + i + 0*p] = o++;
11141  }
11142  for (int j = 0; j < p; j++) // (1,2)
11143  {
11144  dof_map[1*dof2 + p + j*(p + 1)] = o++;
11145  }
11146  for (int i = 0; i < p; i++) // (2,3)
11147  {
11148  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
11149  }
11150  for (int j = 0; j < p; j++) // (3,0)
11151  {
11152  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
11153  }
11154 
11155  // interior
11156  // x-components
11157  for (int j = 1; j < p; j++)
11158  for (int i = 0; i < p; i++)
11159  {
11160  dof_map[0*dof2 + i + j*p] = o++;
11161  }
11162  // y-components
11163  for (int j = 0; j < p; j++)
11164  for (int i = 1; i < p; i++)
11165  {
11166  dof_map[1*dof2 + i + j*(p + 1)] = o++;
11167  }
11168 
11169  // set dof2tk and Nodes
11170  o = 0;
11171  // x-components
11172  for (int j = 0; j <= p; j++)
11173  for (int i = 0; i < p; i++)
11174  {
11175  int idx;
11176  if ((idx = dof_map[o++]) < 0)
11177  {
11178  dof2tk[idx = -1 - idx] = 2;
11179  }
11180  else
11181  {
11182  dof2tk[idx] = 0;
11183  }
11184  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
11185  }
11186  // y-components
11187  for (int j = 0; j < p; j++)
11188  for (int i = 0; i <= p; i++)
11189  {
11190  int idx;
11191  if ((idx = dof_map[o++]) < 0)
11192  {
11193  dof2tk[idx = -1 - idx] = 3;
11194  }
11195  else
11196  {
11197  dof2tk[idx] = 1;
11198  }
11199  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
11200  }
11201 }
11202 
11204  DenseMatrix &shape) const
11205 {
11206  const int p = Order;
11207 
11208 #ifdef MFEM_THREAD_SAFE
11209  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11210 #endif
11211 
11212  cbasis1d.Eval(ip.x, shape_cx);
11213  obasis1d.Eval(ip.x, shape_ox);
11214  cbasis1d.Eval(ip.y, shape_cy);
11215  obasis1d.Eval(ip.y, shape_oy);
11216 
11217  int o = 0;
11218  // x-components
11219  for (int j = 0; j <= p; j++)
11220  for (int i = 0; i < p; i++)
11221  {
11222  int idx, s;
11223  if ((idx = dof_map[o++]) < 0)
11224  {
11225  idx = -1 - idx, s = -1;
11226  }
11227  else
11228  {
11229  s = +1;
11230  }
11231  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
11232  shape(idx,1) = 0.;
11233  }
11234  // y-components
11235  for (int j = 0; j < p; j++)
11236  for (int i = 0; i <= p; i++)
11237  {
11238  int idx, s;
11239  if ((idx = dof_map[o++]) < 0)
11240  {
11241  idx = -1 - idx, s = -1;
11242  }
11243  else
11244  {
11245  s = +1;
11246  }
11247  shape(idx,0) = 0.;
11248  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
11249  }
11250 }
11251 
11253  DenseMatrix &curl_shape) const
11254 {
11255  const int p = Order;
11256 
11257 #ifdef MFEM_THREAD_SAFE
11258  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
11259  Vector dshape_cx(p + 1), dshape_cy(p + 1);
11260 #endif
11261 
11262  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
11263  obasis1d.Eval(ip.x, shape_ox);
11264  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
11265  obasis1d.Eval(ip.y, shape_oy);
11266 
11267  int o = 0;
11268  // x-components
11269  for (int j = 0; j <= p; j++)
11270  for (int i = 0; i < p; i++)
11271  {
11272  int idx, s;
11273  if ((idx = dof_map[o++]) < 0)
11274  {
11275  idx = -1 - idx, s = -1;
11276  }
11277  else
11278  {
11279  s = +1;
11280  }
11281  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
11282  }
11283  // y-components
11284  for (int j = 0; j < p; j++)
11285  for (int i = 0; i <= p; i++)
11286  {
11287  int idx, s;
11288  if ((idx = dof_map[o++]) < 0)
11289  {
11290  idx = -1 - idx, s = -1;
11291  }
11292  else
11293  {
11294  s = +1;
11295  }
11296  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
11297  }
11298 }
11299 
11300 
11301 const double ND_TetrahedronElement::tk[18] =
11302 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
11303 
11304 const double ND_TetrahedronElement::c = 1./4.;
11305 
11307  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
11308  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
11309 {
11310  const double *eop = poly1d.OpenPoints(p - 1);
11311  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
11312  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
11313 
11314  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
11315 
11316 #ifndef MFEM_THREAD_SAFE
11317  shape_x.SetSize(p);
11318  shape_y.SetSize(p);
11319  shape_z.SetSize(p);
11320  shape_l.SetSize(p);
11321  dshape_x.SetSize(p);
11322  dshape_y.SetSize(p);
11323  dshape_z.SetSize(p);
11324  dshape_l.SetSize(p);
11325  u.SetSize(Dof, Dim);
11326 #else
11327  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
11328 #endif
11329 
11330  int o = 0;
11331  // edges
11332  for (int i = 0; i < p; i++) // (0,1)
11333  {
11334  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
11335  dof2tk[o++] = 0;
11336  }
11337  for (int i = 0; i < p; i++) // (0,2)
11338  {
11339  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
11340  dof2tk[o++] = 1;
11341  }
11342  for (int i = 0; i < p; i++) // (0,3)
11343  {
11344  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
11345  dof2tk[o++] = 2;
11346  }
11347  for (int i = 0; i < p; i++) // (1,2)
11348  {
11349  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
11350  dof2tk[o++] = 3;
11351  }
11352  for (int i = 0; i < p; i++) // (1,3)
11353  {
11354  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
11355  dof2tk[o++] = 4;
11356  }
11357  for (int i = 0; i < p; i++) // (2,3)
11358  {
11359  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
11360  dof2tk[o++] = 5;
11361  }
11362 
11363  // faces
11364  for (int j = 0; j <= pm2; j++) // (1,2,3)
11365  for (int i = 0; i + j <= pm2; i++)
11366  {
11367  double w = fop[i] + fop[j] + fop[pm2-i-j];
11368  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
11369  dof2tk[o++] = 3;
11370  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
11371  dof2tk[o++] = 4;
11372  }
11373  for (int j = 0; j <= pm2; j++) // (0,3,2)
11374  for (int i = 0; i + j <= pm2; i++)
11375  {
11376  double w = fop[i] + fop[j] + fop[pm2-i-j];
11377  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
11378  dof2tk[o++] = 2;
11379  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
11380  dof2tk[o++] = 1;
11381  }
11382  for (int j = 0; j <= pm2; j++) // (0,1,3)
11383  for (int i = 0; i + j <= pm2; i++)
11384  {
11385  double w = fop[i] + fop[j] + fop[pm2-i-j];
11386  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
11387  dof2tk[o++] = 0;
11388  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
11389  dof2tk[o++] = 2;
11390  }
11391  for (int j = 0; j <= pm2; j++) // (0,2,1)
11392  for (int i = 0; i + j <= pm2; i++)
11393  {
11394  double w = fop[i] + fop[j] + fop[pm2-i-j];
11395  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
11396  dof2tk[o++] = 1;
11397  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
11398  dof2tk[o++] = 0;
11399  }
11400 
11401  // interior
11402  for (int k = 0; k <= pm3; k++)
11403  for (int j = 0; j + k <= pm3; j++)
11404  for (int i = 0; i + j + k <= pm3; i++)
11405  {
11406  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
11407  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11408  dof2tk[o++] = 0;
11409  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11410  dof2tk[o++] = 1;
11411  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
11412  dof2tk[o++] = 2;
11413  }
11414 
11415  DenseMatrix T(Dof);
11416  for (int m = 0; m < Dof; m++)
11417  {
11418  const IntegrationPoint &ip = Nodes.IntPoint(m);
11419  const double *tm = tk + 3*dof2tk[m];
11420  o = 0;
11421 
11422  poly1d.CalcBasis(pm1, ip.x, shape_x);
11423  poly1d.CalcBasis(pm1, ip.y, shape_y);
11424  poly1d.CalcBasis(pm1, ip.z, shape_z);
11425  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
11426 
11427  for (int k = 0; k <= pm1; k++)
11428  for (int j = 0; j + k <= pm1; j++)
11429  for (int i = 0; i + j + k <= pm1; i++)
11430  {
11431  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
11432  T(o++, m) = s * tm[0];
11433  T(o++, m) = s * tm[1];
11434  T(o++, m) = s * tm[2];
11435  }
11436  for (int k = 0; k <= pm1; k++)
11437  for (int j = 0; j + k <= pm1; j++)
11438  {
11439  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
11440  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
11441  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
11442  }
11443  for (int k = 0; k <= pm1; k++)
11444  {
11445  T(o++, m) =
11446  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
11447  }
11448  }
11449 
11450  Ti.Factor(T);
11451  // mfem::out << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
11452 }
11453 
11455  DenseMatrix &shape) const
11456 {
11457  const int pm1 = Order - 1;
11458 
11459 #ifdef MFEM_THREAD_SAFE
11460  const int p = Order;
11461  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
11462  DenseMatrix u(Dof, Dim);
11463 #endif
11464 
11465  poly1d.CalcBasis(pm1, ip.x, shape_x);
11466  poly1d.CalcBasis(pm1, ip.y, shape_y);
11467  poly1d.CalcBasis(pm1, ip.z, shape_z);
11468  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
11469 
11470  int n = 0;
11471  for (int k = 0; k <= pm1; k++)
11472  for (int j = 0; j + k <= pm1; j++)
11473  for (int i = 0; i + j + k <= pm1; i++)
11474  {
11475  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
11476  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
11477  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
11478  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
11479  }
11480  for (int k = 0; k <= pm1; k++)
11481  for (int j = 0; j + k <= pm1; j++)
11482  {
11483  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
11484  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
11485  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
11486  }
11487  for (int k = 0; k <= pm1; k++)
11488  {
11489  double s = shape_y(pm1-k)*shape_z(k);
11490  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
11491  }
11492 
11493  Ti.Mult(u, shape);
11494 }
11495 
11497  DenseMatrix &curl_shape) const
11498 {
11499  const int pm1 = Order - 1;
11500 
11501 #ifdef MFEM_THREAD_SAFE
11502  const int p = Order;
11503  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
11504  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
11505  DenseMatrix u(Dof, Dim);
11506 #endif
11507 
11508  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
11509  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
11510  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
11511  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
11512 
11513  int n = 0;
11514  for (int k = 0; k <= pm1; k++)
11515  for (int j = 0; j + k <= pm1; j++)
11516  for (int i = 0; i + j + k <= pm1; i++)
11517  {
11518  int l = pm1-i-j-k;
11519  const double dx = (dshape_x(i)*shape_l(l) -
11520  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
11521  const double dy = (dshape_y(j)*shape_l(l) -
11522  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
11523  const double dz = (dshape_z(k)*shape_l(l) -
11524  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
11525 
11526  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
11527  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
11528  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
11529  }
11530  for (int k = 0; k <= pm1; k++)
11531  for (int j = 0; j + k <= pm1; j++)
11532  {
11533  int i = pm1 - j - k;
11534  // s = shape_x(i)*shape_y(j)*shape_z(k);
11535  // curl of s*(ip.y - c, -(ip.x - c), 0):
11536  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
11537  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
11538  u(n,2) =
11539  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
11540  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
11541  n++;
11542  // curl of s*(ip.z - c, 0, -(ip.x - c)):
11543  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
11544  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
11545  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
11546  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
11547  n++;
11548  }
11549  for (int k = 0; k <= pm1; k++)
11550  {
11551  int j = pm1 - k;
11552  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
11553  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
11554  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
11555  u(n,1) = 0.;
11556  u(n,2) = 0.; n++;
11557  }
11558 
11559  Ti.Mult(u, curl_shape);
11560 }
11561 
11562 
11563 const double ND_TriangleElement::tk[8] =
11564 { 1.,0., -1.,1., 0.,-1., 0.,1. };
11565 
11566 const double ND_TriangleElement::c = 1./3.;
11567 
11569  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
11570  H_CURL, FunctionSpace::Pk),
11571  dof2tk(Dof)
11572 {
11573  const double *eop = poly1d.OpenPoints(p - 1);
11574  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
11575 
11576  const int pm1 = p - 1, pm2 = p - 2;
11577 
11578 #ifndef MFEM_THREAD_SAFE
11579  shape_x.SetSize(p);
11580  shape_y.SetSize(p);
11581  shape_l.SetSize(p);
11582  dshape_x.SetSize(p);
11583  dshape_y.SetSize(p);
11584  dshape_l.SetSize(p);
11585  u.SetSize(Dof, Dim);
11586  curlu.SetSize(Dof);
11587 #else
11588  Vector shape_x(p), shape_y(p), shape_l(p);
11589 #endif
11590 
11591  int n = 0;
11592  // edges
11593  for (int i = 0; i < p; i++) // (0,1)
11594  {
11595  Nodes.IntPoint(n).Set2(eop[i], 0.);
11596  dof2tk[n++] = 0;
11597  }
11598  for (int i = 0; i < p; i++) // (1,2)
11599  {
11600  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
11601  dof2tk[n++] = 1;
11602  }
11603  for (int i = 0; i < p; i++) // (2,0)
11604  {
11605  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
11606  dof2tk[n++] = 2;
11607  }
11608 
11609  // interior
11610  for (int j = 0; j <= pm2; j++)
11611  for (int i = 0; i + j <= pm2; i++)
11612  {
11613  double w = iop[i] + iop[j] + iop[pm2-i-j];
11614  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
11615  dof2tk[n++] = 0;
11616  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
11617  dof2tk[n++] = 3;
11618  }
11619 
11620  DenseMatrix T(Dof);
11621  for (int m = 0; m < Dof; m++)
11622  {
11623  const IntegrationPoint &ip = Nodes.IntPoint(m);
11624  const double *tm = tk + 2*dof2tk[m];
11625  n = 0;
11626 
11627  poly1d.CalcBasis(pm1, ip.x, shape_x);
11628  poly1d.CalcBasis(pm1, ip.y, shape_y);
11629  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
11630 
11631  for (int j = 0; j <= pm1; j++)
11632  for (int i = 0; i + j <= pm1; i++)
11633  {
11634  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
11635  T(n++, m) = s * tm[0];
11636  T(n++, m) = s * tm[1];
11637  }
11638  for (int j = 0; j <= pm1; j++)
11639  {
11640  T(n++, m) =
11641  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
11642  }
11643  }
11644 
11645  Ti.Factor(T);
11646  // mfem::out << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
11647 }
11648 
11650  DenseMatrix &shape) const
11651 {
11652  const int pm1 = Order - 1;
11653 
11654 #ifdef MFEM_THREAD_SAFE
11655  const int p = Order;
11656  Vector shape_x(p), shape_y(p), shape_l(p);
11657  DenseMatrix u(Dof, Dim);
11658 #endif
11659 
11660  poly1d.CalcBasis(pm1, ip.x, shape_x);
11661  poly1d.CalcBasis(pm1, ip.y, shape_y);
11662  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
11663 
11664  int n = 0;
11665  for (int j = 0; j <= pm1; j++)
11666  for (int i = 0; i + j <= pm1; i++)
11667  {
11668  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
11669  u(n,0) = s; u(n,1) = 0; n++;
11670  u(n,0) = 0; u(n,1) = s; n++;
11671  }
11672  for (int j = 0; j <= pm1; j++)
11673  {
11674  double s = shape_x(pm1-j)*shape_y(j);
11675  u(n,0) = s*(ip.y - c);
11676  u(n,1) = -s*(ip.x - c);
11677  n++;
11678  }
11679 
11680  Ti.Mult(u, shape);
11681 }
11682 
11684  DenseMatrix &curl_shape) const
11685 {
11686  const int pm1 = Order - 1;
11687 
11688 #ifdef MFEM_THREAD_SAFE
11689  const int p = Order;
11690  Vector shape_x(p), shape_y(p), shape_l(p);
11691  Vector dshape_x(p), dshape_y(p), dshape_l(p);
11692  Vector curlu(Dof);
11693 #endif
11694 
11695  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
11696  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
11697  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
11698 
11699  int n = 0;
11700  for (int j = 0; j <= pm1; j++)
11701  for (int i = 0; i + j <= pm1; i++)
11702  {
11703  int l = pm1-i-j;
11704  const double dx = (dshape_x(i)*shape_l(l) -
11705  shape_x(i)*dshape_l(l)) * shape_y(j);
11706  const double dy = (dshape_y(j)*shape_l(l) -
11707  shape_y(j)*dshape_l(l)) * shape_x(i);
11708 
11709  curlu(n++) = -dy;
11710  curlu(n++) = dx;
11711  }
11712 
11713  for (int j = 0; j <= pm1; j++)
11714  {
11715  int i = pm1 - j;
11716  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
11717  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
11718  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
11719  }
11720 
11721  Vector curl2d(curl_shape.Data(),Dof);
11722  Ti.Mult(curlu, curl2d);
11723 }
11724 
11725 
11726 const double ND_SegmentElement::tk[1] = { 1. };
11727 
11728 ND_SegmentElement::ND_SegmentElement(const int p, const int ob_type)
11729  : VectorFiniteElement(1, Geometry::SEGMENT, p, p - 1,
11730  H_CURL, FunctionSpace::Pk),
11731  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(ob_type))),
11732  dof2tk(Dof)
11733 {
11734  const double *op = poly1d.OpenPoints(p - 1, ob_type);
11735 
11736  // set dof2tk and Nodes
11737  for (int i = 0; i < p; i++)
11738  {
11739  dof2tk[i] = 0;
11740  Nodes.IntPoint(i).x = op[i];
11741  }
11742 }
11743 
11745  DenseMatrix &shape) const
11746 {
11747  Vector vshape(shape.Data(), Dof);
11748 
11749  obasis1d.Eval(ip.x, vshape);
11750 }
11751 
11753 {
11754  Order = kv[0]->GetOrder();
11755  Dof = Order + 1;
11756 
11757  weights.SetSize(Dof);
11758  shape_x.SetSize(Dof);
11759 }
11760 
11762  Vector &shape) const
11763 {
11764  kv[0]->CalcShape(shape, ijk[0], ip.x);
11765 
11766  double sum = 0.0;
11767  for (int i = 0; i <= Order; i++)
11768  {
11769  sum += (shape(i) *= weights(i));
11770  }
11771 
11772  shape /= sum;
11773 }
11774 
11776  DenseMatrix &dshape) const
11777 {
11778  Vector grad(dshape.Data(), Dof);
11779 
11780  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
11781  kv[0]->CalcDShape(grad, ijk[0], ip.x);
11782 
11783  double sum = 0.0, dsum = 0.0;
11784  for (int i = 0; i <= Order; i++)
11785  {
11786  sum += (shape_x(i) *= weights(i));
11787  dsum += ( grad(i) *= weights(i));
11788  }
11789 
11790  sum = 1.0/sum;
11791  add(sum, grad, -dsum*sum*sum, shape_x, grad);
11792 }
11793 
11795 {
11796  Orders[0] = kv[0]->GetOrder();
11797  Orders[1] = kv[1]->GetOrder();
11798  shape_x.SetSize(Orders[0]+1);
11799  shape_y.SetSize(Orders[1]+1);
11800  dshape_x.SetSize(Orders[0]+1);
11801  dshape_y.SetSize(Orders[1]+1);
11802 
11803  Order = max(Orders[0], Orders[1]);
11804  Dof = (Orders[0] + 1)*(Orders[1] + 1);
11805  u.SetSize(Dof);
11806  weights.SetSize(Dof);
11807 }
11808 
11810  Vector &shape) const
11811 {
11812  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
11813  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
11814 
11815  double sum = 0.0;
11816  for (int o = 0, j = 0; j <= Orders[1]; j++)
11817  {
11818  const double sy = shape_y(j);
11819  for (int i = 0; i <= Orders[0]; i++, o++)
11820  {
11821  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
11822  }
11823  }
11824 
11825  shape /= sum;
11826 }
11827 
11829  DenseMatrix &dshape) const
11830 {
11831  double sum, dsum[2];
11832 
11833  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
11834  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
11835 
11836  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
11837  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
11838 
11839  sum = dsum[0] = dsum[1] = 0.0;
11840  for (int o = 0, j = 0; j <= Orders[1]; j++)
11841  {
11842  const double sy = shape_y(j), dsy = dshape_y(j);
11843  for (int i = 0; i <= Orders[0]; i++, o++)
11844  {
11845  sum += ( u(o) = shape_x(i)*sy*weights(o) );
11846 
11847  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
11848  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
11849  }
11850  }
11851 
11852  sum = 1.0/sum;
11853  dsum[0] *= sum*sum;
11854  dsum[1] *= sum*sum;
11855 
11856  for (int o = 0; o < Dof; o++)
11857  {
11858  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11859  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11860  }
11861 }
11862 
11863 //---------------------------------------------------------------------
11865 {
11866  Orders[0] = kv[0]->GetOrder();
11867  Orders[1] = kv[1]->GetOrder();
11868  Orders[2] = kv[2]->GetOrder();
11869  shape_x.SetSize(Orders[0]+1);
11870  shape_y.SetSize(Orders[1]+1);
11871  shape_z.SetSize(Orders[2]+1);
11872 
11873  dshape_x.SetSize(Orders[0]+1);
11874  dshape_y.SetSize(Orders[1]+1);
11875  dshape_z.SetSize(Orders[2]+1);
11876 
11877  Order = max(max(Orders[0], Orders[1]), Orders[2]);
11878  Dof = (Orders[0] + 1)*(Orders[1] + 1)*(Orders[2] + 1);
11879  u.SetSize(Dof);
11880  weights.SetSize(Dof);
11881 }
11882 
11884  Vector &shape) const
11885 {
11886  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
11887  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
11888  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
11889 
11890  double sum = 0.0;
11891  for (int o = 0, k = 0; k <= Orders[2]; k++)
11892  {
11893  const double sz = shape_z(k);
11894  for (int j = 0; j <= Orders[1]; j++)
11895  {
11896  const double sy_sz = shape_y(j)*sz;
11897  for (int i = 0; i <= Orders[0]; i++, o++)
11898  {
11899  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
11900  }
11901  }
11902  }
11903 
11904  shape /= sum;
11905 }
11906 
11908  DenseMatrix &dshape) const
11909 {
11910  double sum, dsum[3];
11911 
11912  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
11913  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
11914  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
11915 
11916  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
11917  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
11918  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
11919 
11920  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
11921  for (int o = 0, k = 0; k <= Orders[2]; k++)
11922  {
11923  const double sz = shape_z(k), dsz = dshape_z(k);
11924  for (int j = 0; j <= Orders[1]; j++)
11925  {
11926  const double sy_sz = shape_y(j)* sz;
11927  const double dsy_sz = dshape_y(j)* sz;
11928  const double sy_dsz = shape_y(j)*dsz;
11929  for (int i = 0; i <= Orders[0]; i++, o++)
11930  {
11931  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
11932 
11933  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
11934  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
11935  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
11936  }
11937  }
11938  }
11939 
11940  sum = 1.0/sum;
11941  dsum[0] *= sum*sum;
11942  dsum[1] *= sum*sum;
11943  dsum[2] *= sum*sum;
11944 
11945  for (int o = 0; o < Dof; o++)
11946  {
11947  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11948  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11949  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
11950  }
11951 }
11952 
11953 
11954 // Global object definitions
11955 
11956 
11957 // Object declared in mesh/triangle.hpp.
11958 // Defined here to ensure it is constructed before 'Geometries'.
11960 
11961 // Object declared in mesh/tetrahedron.hpp.
11962 // Defined here to ensure it is constructed before 'Geometries'.
11964 
11965 // Object declared in mesh/wedge.hpp.
11966 // Defined here to ensure it is constructed after 'poly1d' and before
11967 // 'Geometries'.
11969 
11970 // Object declared in geom.hpp.
11971 // Construct 'Geometries' after 'TriangleFE', 'TetrahedronFE', and 'WedgeFE'.
11973 
11974 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:237
Implements CalcDivShape methods.
Definition: fe.hpp:290
Abstract class for Finite Elements.
Definition: fe.hpp:229
RefinedLinear3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:4550
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1662
void Set(const double *p, const int dim)
Definition: intrules.hpp:32
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:8921
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:3450
ND_SegmentElement(const int p, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:11728
int Size() const
Logical size of the array.
Definition: array.hpp:118
const DenseMatrix & AdjugateJacobian()
Definition: eltrans.hpp:73
DenseMatrix curlshape_J
Definition: fe.hpp:698
void Get(double *p, const int dim) const
Definition: intrules.hpp:46
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:6349
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:305
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7591
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:3187
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:4128
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:1410
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:85
L2Pos_WedgeElement(const int p)
Definition: fe.cpp:9791
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9311
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:11828
Linear3DFiniteElement()
Construct a linear FE on tetrahedron.
Definition: fe.cpp:2585
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:44
static double CalcDelta(const int p, const double x)
Definition: fe.hpp:1774
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:3369
For scalar fields; preserves volume integrals.
Definition: fe.hpp:274
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9072
void ProjectMatrixCoefficient_RT(const double *nk, const Array< int > &d2n, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:764
int NumCols() const
Definition: array.hpp:326
void ProjectMatrixCoefficient_ND(const double *tk, const Array< int > &d2t, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:940
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:10661
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:40
RefinedBiLinear2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4782
NodalTensorFiniteElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:7163
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:1980
void LocalInterpolation_RT(const VectorFiniteElement &cfe, const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1034
L2Pos_TriangleElement(const int p)
Definition: fe.cpp:9455
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:877
H1Pos_SegmentElement(const int p)
Definition: fe.cpp:7533
Basis(const int p, const double *nodes, EvalType etype=Barycentric)
Create a nodal or positive (Bernstein) basis.
Definition: fe.cpp:6454
Tensor product representation using 1D matrices/tensors with dimensions using 1D number of quadrature...
Definition: fe.hpp:151
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:177
Geometry::Type GeomType
Geometry::Type of the reference element.
Definition: fe.hpp:233
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:5394
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:130
Array< const KnotVector * > kv
Definition: fe.hpp:2849
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:2824
void CalcPhysDivShape(ElementTransformation &Trans, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in physical space at the po...
Definition: fe.cpp:61
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2602
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9494
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:3141
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the vector coefficient in the element described by T at the point ip, storing the result in ...
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3421
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:1776
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:7571
PositiveTensorFiniteElement(const int dims, const int p, const DofMapType dmtype)
Definition: fe.cpp:7172
void GivePolyPoints(const int np, double *pts, const int type)
Definition: intrules.cpp:609
L2Pos_TetrahedronElement(const int p)
Definition: fe.cpp:9649
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:8774
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:490
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:721
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:400
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:10043
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:5456
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:3911
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1331
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:451
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:1800
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:2158
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:2069
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:2906
FiniteElement(int D, Geometry::Type G, int Do, int O, int F=FunctionSpace::Pk)
Definition: fe.cpp:25
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:476
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
evaluate derivatives of shape function - constant 0
Definition: fe.cpp:2556
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:42
H1Pos_SegmentElement SegmentFE
Definition: fe.hpp:2136
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1220
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7236
virtual void Eval(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the matrix coefficient in the element described by T at the point ip, storing the result in ...
H1Pos_TetrahedronElement(const int p)
Definition: fe.cpp:8260
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:11761
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:8940
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
Definition: densemat.cpp:320
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:53
LagrangeHexFiniteElement(int degree)
Definition: fe.cpp:4180
TensorBasisElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:6963
Bernstein polynomials.
Definition: fe.hpp:35
L2_SegmentElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:8800
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition: fe.hpp:315
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:2919
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:4034
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:4342
int nqpt
Number of quadrature points. When mode is TENSOR, this is the 1D number.
Definition: fe.hpp:163
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:3986
int Size() const
Returns the size of the vector.
Definition: vector.hpp:150
Array< double > Gt
Transpose of G.
Definition: fe.hpp:202
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:553
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:11775
int ndof
Number of degrees of freedom = number of basis functions. When mode is TENSOR, this is the 1D number...
Definition: fe.hpp:159
static int GetQuadrature1D(int b_type)
Get the corresponding Quadrature1D constant, when that makes sense; otherwise return Quadrature1D::In...
Definition: fe.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:10517
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:9853
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:5622
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:866
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:2571
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:11752
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:2229
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:111
const DenseMatrix & InverseJacobian()
Definition: eltrans.hpp:76
RefinedTriLinear3DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4929
DenseMatrix vshape
Definition: fe.hpp:242
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:4167
Quadratic3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:2641
int GetMapType() const
Definition: fe.hpp:331
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:8816
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:5972
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:6159
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:4250
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:3018
const IntegrationPoint & GetIntPoint()
Definition: eltrans.hpp:55
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9614
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
Nodal interpolation.
Definition: fe.cpp:223
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:2281
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:9679
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:2849
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:2841
const IntegrationPoint & GetCenter(int GeomType)
Return the center of the given Geometry::Type, GeomType.
Definition: geom.hpp:70
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:8878
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:7288
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:904
H1Pos_HexahedronElement(const int p)
Definition: fe.cpp:7666
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:161
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:159
static void CalcShape(const int p, const double x, const double y, const double z, double *shape)
Definition: fe.cpp:8362
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
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1292
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:7638
Linear2DFiniteElement()
Construct a linear FE on triangle.
Definition: fe.cpp:1234
const double * ClosedPoints(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.hpp:1734
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:2698
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:6294
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:238
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5118
H1_HexahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7378
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:11649
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:1201
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:2301
void CalcPhysCurlShape(ElementTransformation &Trans, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in physical space at the point de...
Definition: fe.cpp:75
L2Pos_HexahedronElement(const int p)
Definition: fe.cpp:9239
ND_TriangleElement(const int p)
Definition: fe.cpp:11568
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:10697
static void CalcDShape(const int p, const double x, const double y, const double z, double *dshape_1d, double *dshape)
Definition: fe.cpp:8395
static void CalcBasis(const int p, const double x, double *u)
Definition: fe.hpp:1750
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
evaluate shape function - constant 1
Definition: fe.cpp:2550
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:2329
static void CalcBinomTerms(const int p, const double x, const double y, double *u)
Compute the terms in the expansion of the binomial (x + y)^p.
Definition: fe.cpp:6695
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:105
const double * GetPoints(const int p, const int btype)
Get the coordinates of the points of the given BasisType, btype.
Definition: fe.cpp:6888
H1Pos_TriangleElement(const int p)
Definition: fe.cpp:8115
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:3623
Cubic3DFiniteElement()
Construct a cubic FE on tetrahedron.
Definition: fe.cpp:2376
Linear1DFiniteElement()
Construct a linear FE on interval.
Definition: fe.cpp:1213
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4491
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:6282
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:1849
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:4290
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:169
Geometry::Type GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:308
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:1467
static void CalcShape(const int p, const double x, const double y, double *shape)
Definition: fe.cpp:8170
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:2872
Array< int > s_dof
Definition: fe.hpp:2357
void SetSize(int m, int n)
Definition: array.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:2469
Geometry Geometries
Definition: fe.cpp:11972
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:240
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:3929
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:696
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Definition: densemat.cpp:224
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:3204
int Dof
Number of degrees of freedom.
Definition: fe.hpp:237
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:8822
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1427
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1438
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1686
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:36
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:8631
RefinedLinear1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:4380
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7448
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7659
ND_HexahedronElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:10743
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:1953
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:9397
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:7811
Poly_1D::Basis & basis1d
Definition: fe.hpp:1805
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4407
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:146
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:3562
static void ChebyshevPoints(const int p, double *x)
Definition: fe.cpp:6663
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
Definition: densemat.cpp:3898
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint, using the method SetIntPoint().
Definition: eltrans.hpp:68
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:6419
H1Pos_WedgeElement(const int p)
Definition: fe.cpp:8657
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:4152
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:6260
int GetSpaceDim() const
Get the dimension of the target (physical) space.
Definition: eltrans.hpp:94
ND_TetrahedronElement(const int p)
Definition: fe.cpp:11306
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:9483
Array< int > t_dof
Definition: fe.hpp:2357
Mode mode
Describes the contents of the B, Bt, G, and Gt arrays, see Mode.
Definition: fe.hpp:155
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
H1_QuadrilateralElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7264
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:1207
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:2244
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:658
class FiniteElement * FE
The FiniteElement that created and owns this object.
Definition: fe.hpp:130
const IntegrationRule & GetNodes() const
Definition: fe.hpp:364
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5509
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1508
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9154
static int VerifyOpen(int b_type)
Definition: fe.hpp:541
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:2676
L2Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:9009
const int * ijk
Definition: fe.hpp:2850
P0SegmentFiniteElement(int Ord=0)
Definition: fe.cpp:2812
static void CalcDShape(const int p, const double x, const double y, double *dshape_1d, double *dshape)
Definition: fe.cpp:8196
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:9746
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:3164
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:11883
DenseMatrix curlshape
Definition: fe.hpp:698
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
Definition: densemat.cpp:3920
Class for linear FE on tetrahedron.
Definition: fe.hpp:1102
H1_SegmentElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7180
void Set2(const double x1, const double x2)
Definition: intrules.hpp:75
virtual ~FiniteElement()
Definition: fe.cpp:214
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:10257
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:5560
void CalcPhysDShape(ElementTransformation &Trans, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in physical space at the poi...
Definition: fe.cpp:195
Class for linear FE on triangle.
Definition: fe.hpp:822
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:9375
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:9996
void SetRow(int r, const Vector &row)
Definition: densemat.cpp:2905
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:2108
L2_QuadrilateralElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:8902
void SetData(double *d)
Definition: vector.hpp:118
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:3821
Basis & GetBasis(const int p, const int btype)
Get a Poly_1D::Basis object of the given degree and BasisType, btype.
Definition: fe.cpp:6912
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1283
void GetColumn(int c, Vector &col) const
Definition: densemat.cpp:2396
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2611
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:10331
const double * OpenPoints(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.hpp:1731
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:8011
void trans(const Vector &x, Vector &p)
Definition: toroid.cpp:239
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1532
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:8612
class H1_WedgeElement WedgeFE
L2_WedgeElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9703
void ScalarLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
&quot;Interpolation&quot; defined through local L2-projection.
Definition: fe.cpp:257
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:1610
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:1013
L2_TetrahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9506
static const int MaxDim
Definition: geom.hpp:42
Array< int > t_dof
Definition: fe.hpp:2133
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:9477
void Threshold(double eps)
Replace small entries, abs(a_ij) &lt;= eps, with zero.
Definition: densemat.cpp:2921
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3240
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:11907
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:1624
DenseMatrix m_dshape
Definition: fe.hpp:2035
int Dim
Dimension of reference space.
Definition: fe.hpp:232
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:11252
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:9033
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:65
IntegrationRule Nodes
Definition: fe.hpp:240
Array< int > dof_map
Definition: fe.hpp:1804
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1494
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:9266
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:7551
Array< double > Bt
Transpose of B.
Definition: fe.hpp:180
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7733
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3873
int Orders[Geometry::MaxDim]
Anisotropic orders.
Definition: fe.hpp:239
double * Data() const
Returns the matrix data array.
Definition: densemat.hpp:94
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:11683
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:3033
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4805
void LocalInterpolation_ND(const VectorFiniteElement &cfe, const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1073
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &ddshape) const
Definition: fe.cpp:8069
H1Pos_TriangleElement TriangleFE
Definition: fe.hpp:2135
ND_QuadrilateralElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:11114
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:2930
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:733
DenseMatrix Jinv
Definition: fe.hpp:697
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8833
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:311
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:8036
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Definition: globals.hpp:69
Base class Coefficient that may optionally depend on time.
Definition: coefficient.hpp:31
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1378
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:5590
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:9672
void CalcPhysShape(ElementTransformation &Trans, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in physical space at the point ...
Definition: fe.cpp:185
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:618
DenseMatrix t_dshape
Definition: fe.hpp:2131
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1245
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4975
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:4672
DenseMatrix t_dshape
Definition: fe.hpp:2355
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:6646
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:3723
DenseMatrix s_dshape
Definition: fe.hpp:2131
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:54
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1313
H1_TetrahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7895
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:11864
DenseMatrix s_dshape
Definition: fe.hpp:2355
Structure representing the matrices/tensors needed to evaluate (in reference space) the values...
Definition: fe.hpp:125
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:9834
class Linear3DFiniteElement TetrahedronFE
Definition: fe.cpp:11963
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:9581
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:10961
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3097
L2Pos_TriangleElement TriangleFE
Definition: fe.hpp:2359
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:125
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1735
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2756
Linear2DFiniteElement TriangleFE
Definition: fe.cpp:11959
Array< double > B
Basis functions evaluated at quadrature points.
Definition: fe.hpp:174
Quad1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:1419
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:7688
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:100
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:206
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1367
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1274
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:68
H1Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:7598
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:9765
void LocalRestriction_ND(const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &R) const
Definition: fe.cpp:1153
H1_TriangleElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7740
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1227
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9426
Mode
Type of data stored in the arrays B, Bt, G, and Gt.
Definition: fe.hpp:138
Full multidimensional representation which does not use tensor product structure. The ordering of the...
Definition: fe.hpp:143
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:142
L2Pos_SegmentElement SegmentFE
Definition: fe.hpp:2360
const Poly_1D::Basis & GetBasis1D() const
Definition: fe.hpp:1819
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:7709
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:8884
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:2577
No derivatives implemented.
Definition: fe.hpp:288
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:9287
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:744
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:7403
Array< DofToQuad * > dof2quad_array
Container for all DofToQuad objects created by the FiniteElement.
Definition: fe.hpp:247
H1_WedgeElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:8512
Array< int > s_dof
Definition: fe.hpp:2133
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:1402
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:3537
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:11454
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:3297
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:11203
static int VerifyClosed(int b_type)
Definition: fe.hpp:535
Implements CalcCurlShape methods.
Definition: fe.hpp:291
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:582
int DerivRangeType
Definition: fe.hpp:234
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:3045
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:728
virtual void GetLocalRestriction(ElementTransformation &Trans, DenseMatrix &R) const
Return a local restriction matrix R (Dof x Dof) mapping fine dofs to coarse dofs. ...
Definition: fe.cpp:117
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8895
RefinedLinear2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:4426
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:6214
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:387
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4388
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:4116
Array< double > G
Gradients/divergences/curls of basis functions evaluated at quadrature points.
Definition: fe.hpp:195
Array< int > dof_map
Definition: fe.hpp:2037
RT_TetrahedronElement(const int p)
Definition: fe.cpp:10559
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:5770
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:4321
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:7217
double infinity()
Define a shortcut for std::numeric_limits&lt;double&gt;::infinity()
Definition: vector.hpp:42
BiQuad2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:1639
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:2631
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:3334
P0TriangleFiniteElement()
Construct P0 triangle finite element.
Definition: fe.cpp:2543
static int VerifyNodal(int b_type)
Definition: fe.hpp:546
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:2818
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
Evaluate the coefficient in the element described by T at the point ip.
RT_TriangleElement(const int p)
Definition: fe.cpp:10406
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:7198
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:11744
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:11035
void Eval(const double x, Vector &u) const
Definition: fe.cpp:6512
L2Pos_SegmentElement(const int p)
Definition: fe.cpp:8857
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:4585
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5825
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:3725
void InvertLinearTrans(ElementTransformation &trans, const IntegrationPoint &pt, Vector &x)
Definition: fe.cpp:406
Vector data type.
Definition: vector.hpp:48
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:5756
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:173
static void CalcBernstein(const int p, const double x, double *u)
Definition: fe.hpp:1790
virtual void Transform(const IntegrationPoint &, Vector &)=0
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:11794
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:7618
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:9130
For scalar fields; preserves point values.
Definition: fe.hpp:273
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1560
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:10484
Quad2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:1477
void LocalRestriction_RT(const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &R) const
Definition: fe.cpp:1110
static bool CheckPoint(int GeomType, const IntegrationPoint &ip)
Check if the given point is inside the given reference element.
Definition: geom.cpp:348
Describes the space on each element.
Definition: fe.hpp:207
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2772
void pts(int iphi, int t, double x[])
virtual void GetTransferMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
Return interpolation matrix, I, which maps dofs from a coarse element, fe, to the fine dofs on this f...
Definition: fe.cpp:123
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5675
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:9052
RT_HexahedronElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:10093
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:11496
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:4173
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:1878
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1253
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:2441
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &ddshape) const
Definition: fe.cpp:7862
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:2883
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:88
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7329
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:5726
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:3941
RT_QuadrilateralElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:9882
virtual const DofToQuad & GetDofToQuad(const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:297
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4856
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:11809
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:923
int GetRangeType() const
Definition: fe.hpp:327
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:1356
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:368
int Order
Order/degree of the shape functions.
Definition: fe.hpp:237
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3239
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:8755
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:4146
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:7424
L2_HexahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9087
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:422
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:7307
static void CalcDBinomTerms(const int p, const double x, const double y, double *d)
Definition: fe.cpp:6759
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:5339
const IntegrationRule * IntRule
IntegrationRule that defines the quadrature points at which the basis functions of the FE are evaluat...
Definition: fe.hpp:135
TriLinear3DFiniteElement()
Construct a tri-linear FE on cube.
Definition: fe.cpp:2720
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:148
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1457
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:9109
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4443
const DofToQuad & GetTensorDofToQuad(const class TensorBasisElement &tb, const IntegrationRule &ir, DofToQuad::Mode mode) const
Definition: fe.cpp:345
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:3902
L2_TriangleElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:9330
BiLinear2DFiniteElement()
Construct a bilinear FE on quadrilateral.
Definition: fe.cpp:1261
Poly_1D poly1d
Definition: fe.cpp:6960
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:6402
Lagrange1DFiniteElement(int degree)
Definition: fe.cpp:3954
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2982
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:6095
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9690
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8960
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:1323
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:7833
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:839
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:614