MFEM  v3.3.2
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
fe.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Finite Element classes
13 
14 #include "fe.hpp"
15 #include "../mesh/nurbs.hpp"
16 #include "bilininteg.hpp"
17 #include <cmath>
18 
19 namespace mfem
20 {
21 
22 using namespace std;
23 
24 FiniteElement::FiniteElement(int D, int G, int Do, int O, int F)
25  : Nodes(Do)
26 {
27  Dim = D ; GeomType = G ; Dof = Do ; Order = O ; FuncSpace = F;
28  RangeType = SCALAR;
29  MapType = VALUE;
30  DerivType = NONE;
33 #ifndef MFEM_THREAD_SAFE
35 #endif
36 }
37 
39  const IntegrationPoint &ip, DenseMatrix &shape) const
40 {
41  mfem_error ("FiniteElement::CalcVShape (ip, ...)\n"
42  " is not implemented for this class!");
43 }
44 
47 {
48  mfem_error ("FiniteElement::CalcVShape (trans, ...)\n"
49  " is not implemented for this class!");
50 }
51 
53  const IntegrationPoint &ip, Vector &divshape) const
54 {
55  mfem_error ("FiniteElement::CalcDivShape (ip, ...)\n"
56  " is not implemented for this class!");
57 }
58 
60  ElementTransformation &Trans, Vector &div_shape) const
61 {
62  CalcDivShape(Trans.GetIntPoint(), div_shape);
63  div_shape *= (1.0 / Trans.Weight());
64 }
65 
67  DenseMatrix &curl_shape) const
68 {
69  mfem_error ("FiniteElement::CalcCurlShape (ip, ...)\n"
70  " is not implemented for this class!");
71 }
72 
74  DenseMatrix &curl_shape) const
75 {
76  switch (Dim)
77  {
78  case 3:
79  {
80 #ifdef MFEM_THREAD_SAFE
82 #endif
84  MultABt(vshape, Trans.Jacobian(), curl_shape);
85  curl_shape *= (1.0 / Trans.Weight());
86  break;
87  }
88  case 2:
89  // This is valid for both 2x2 and 3x2 Jacobians
90  CalcCurlShape(Trans.GetIntPoint(), curl_shape);
91  curl_shape *= (1.0 / Trans.Weight());
92  break;
93  default:
94  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
95  }
96 }
97 
98 void FiniteElement::GetFaceDofs(int face, int **dofs, int *ndofs) const
99 {
100  mfem_error ("FiniteElement::GetFaceDofs (...)");
101 }
102 
104  DenseMatrix &h) const
105 {
106  mfem_error ("FiniteElement::CalcHessian (...) is not overloaded !");
107 }
108 
110  DenseMatrix &I) const
111 {
112  mfem_error ("GetLocalInterpolation (...) is not overloaded !");
113 }
114 
116  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
117 {
118  mfem_error ("FiniteElement::Project (...) is not overloaded !");
119 }
120 
123 {
124  mfem_error ("FiniteElement::Project (...) (vector) is not overloaded !");
125 }
126 
128  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
129 {
130  mfem_error("FiniteElement::ProjectMatrixCoefficient() is not overloaded !");
131 }
132 
133 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
134 {
135  mfem_error("FiniteElement::ProjectDelta(...) is not implemented for "
136  "this element!");
137 }
138 
141 {
142  mfem_error("FiniteElement::Project(...) (fe version) is not implemented "
143  "for this element!");
144 }
145 
148  DenseMatrix &grad) const
149 {
150  mfem_error("FiniteElement::ProjectGrad(...) is not implemented for "
151  "this element!");
152 }
153 
156  DenseMatrix &curl) const
157 {
158  mfem_error("FiniteElement::ProjectCurl(...) is not implemented for "
159  "this element!");
160 }
161 
164  DenseMatrix &div) const
165 {
166  mfem_error("FiniteElement::ProjectDiv(...) is not implemented for "
167  "this element!");
168 }
169 
171  Vector &shape) const
172 {
173  CalcShape(Trans.GetIntPoint(), shape);
174  if (MapType == INTEGRAL)
175  {
176  shape /= Trans.Weight();
177  }
178 }
179 
181  DenseMatrix &dshape) const
182 {
183  MFEM_ASSERT(MapType == VALUE, "");
184 #ifdef MFEM_THREAD_SAFE
186 #endif
187  CalcDShape(Trans.GetIntPoint(), vshape);
188  Mult(vshape, Trans.InverseJacobian(), dshape);
189 }
190 
193  const NodalFiniteElement &fine_fe) const
194 {
195  double v[3];
196  Vector vv (v, Dim);
197  IntegrationPoint f_ip;
198 
199 #ifdef MFEM_THREAD_SAFE
200  Vector c_shape(Dof);
201 #endif
202 
203  MFEM_ASSERT(MapType == fine_fe.GetMapType(), "");
204 
205  for (int i = 0; i < fine_fe.Dof; i++)
206  {
207  Trans.Transform (fine_fe.Nodes.IntPoint (i), vv);
208  f_ip.Set(v, Dim);
209  CalcShape (f_ip, c_shape);
210  for (int j = 0; j < Dof; j++)
211  if (fabs (I (i,j) = c_shape (j)) < 1.0e-12)
212  {
213  I (i,j) = 0.0;
214  }
215  }
216  if (MapType == INTEGRAL)
217  {
218  // assuming Trans is linear; this should be ok for all refinement types
220  I *= Trans.Weight();
221  }
222 }
223 
226  DenseMatrix &curl) const
227 {
228  MFEM_ASSERT(GetMapType() == FiniteElement::INTEGRAL, "");
229 
230  DenseMatrix curl_shape(fe.GetDof(), 1);
231 
232  curl.SetSize(Dof, fe.GetDof());
233  for (int i = 0; i < Dof; i++)
234  {
235  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
236  for (int j = 0; j < fe.GetDof(); j++)
237  {
238  curl(i,j) = curl_shape(j,0);
239  }
240  }
241 }
242 
244  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
245 {
246  for (int i = 0; i < Dof; i++)
247  {
248  const IntegrationPoint &ip = Nodes.IntPoint(i);
249  // some coefficients expect that Trans.IntPoint is the same
250  // as the second argument of Eval
251  Trans.SetIntPoint(&ip);
252  dofs(i) = coeff.Eval (Trans, ip);
253  if (MapType == INTEGRAL)
254  {
255  dofs(i) *= Trans.Weight();
256  }
257  }
258 }
259 
262 {
263  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*Dof, "");
264  Vector x(vc.GetVDim());
265 
266  for (int i = 0; i < Dof; i++)
267  {
268  const IntegrationPoint &ip = Nodes.IntPoint(i);
269  Trans.SetIntPoint(&ip);
270  vc.Eval (x, Trans, ip);
271  if (MapType == INTEGRAL)
272  {
273  x *= Trans.Weight();
274  }
275  for (int j = 0; j < x.Size(); j++)
276  {
277  dofs(Dof*j+i) = x(j);
278  }
279  }
280 }
281 
283  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
284 {
285  // (mc.height x mc.width) @ DOFs -> (Dof x mc.width x mc.height) in dofs
286  MFEM_ASSERT(dofs.Size() == mc.GetHeight()*mc.GetWidth()*Dof, "");
287  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
288 
289  for (int k = 0; k < Dof; k++)
290  {
291  T.SetIntPoint(&Nodes.IntPoint(k));
292  mc.Eval(MQ, T, Nodes.IntPoint(k));
293  if (MapType == INTEGRAL) { MQ *= T.Weight(); }
294  for (int r = 0; r < MQ.Height(); r++)
295  {
296  for (int d = 0; d < MQ.Width(); d++)
297  {
298  dofs(k+Dof*(d+MQ.Width()*r)) = MQ(r,d);
299  }
300  }
301  }
302 }
303 
306 {
307  if (fe.GetRangeType() == SCALAR)
308  {
309  MFEM_ASSERT(MapType == fe.GetMapType(), "");
310 
311  Vector shape(fe.GetDof());
312 
313  I.SetSize(Dof, fe.GetDof());
314  for (int k = 0; k < Dof; k++)
315  {
316  fe.CalcShape(Nodes.IntPoint(k), shape);
317  for (int j = 0; j < shape.Size(); j++)
318  {
319  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
320  }
321  }
322  }
323  else
324  {
325  DenseMatrix vshape(fe.GetDof(), Dim);
326 
327  I.SetSize(Dim*Dof, fe.GetDof());
328  for (int k = 0; k < Dof; k++)
329  {
330  Trans.SetIntPoint(&Nodes.IntPoint(k));
331  fe.CalcVShape(Trans, vshape);
332  if (MapType == INTEGRAL)
333  {
334  vshape *= Trans.Weight();
335  }
336  for (int j = 0; j < vshape.Height(); j++)
337  for (int d = 0; d < vshape.Width(); d++)
338  {
339  I(k+d*Dof,j) = vshape(j,d);
340  }
341  }
342  }
343 }
344 
347  DenseMatrix &grad) const
348 {
349  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
350  MFEM_ASSERT(Trans.GetSpaceDim() == Dim, "")
351 
352  DenseMatrix dshape(fe.GetDof(), Dim), grad_k(fe.GetDof(), Dim), Jinv(Dim);
353 
354  grad.SetSize(Dim*Dof, fe.GetDof());
355  for (int k = 0; k < Dof; k++)
356  {
357  const IntegrationPoint &ip = Nodes.IntPoint(k);
358  fe.CalcDShape(ip, dshape);
359  Trans.SetIntPoint(&ip);
360  CalcInverse(Trans.Jacobian(), Jinv);
361  Mult(dshape, Jinv, grad_k);
362  if (MapType == INTEGRAL)
363  {
364  grad_k *= Trans.Weight();
365  }
366  for (int j = 0; j < grad_k.Height(); j++)
367  for (int d = 0; d < Dim; d++)
368  {
369  grad(k+d*Dof,j) = grad_k(j,d);
370  }
371  }
372 }
373 
376  DenseMatrix &div) const
377 {
378  double detJ;
379  Vector div_shape(fe.GetDof());
380 
381  div.SetSize(Dof, fe.GetDof());
382  for (int k = 0; k < Dof; k++)
383  {
384  const IntegrationPoint &ip = Nodes.IntPoint(k);
385  fe.CalcDivShape(ip, div_shape);
386  if (MapType == VALUE)
387  {
388  Trans.SetIntPoint(&ip);
389  detJ = Trans.Weight();
390  for (int j = 0; j < div_shape.Size(); j++)
391  {
392  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
393  }
394  }
395  else
396  {
397  for (int j = 0; j < div_shape.Size(); j++)
398  {
399  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
400  }
401  }
402  }
403 }
404 
407  const PositiveFiniteElement &fine_fe) const
408 {
409  // General interpolation, defined based on L2 projection
410 
411  double v[3];
412  Vector vv (v, Dim);
413  IntegrationPoint f_ip;
414 
415  const int fs = fine_fe.GetDof(), cs = this->GetDof();
416  I.SetSize(fs, cs);
417  Vector fine_shape(fs), coarse_shape(cs);
418  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
419  const int ir_order = GetOrder() + fine_fe.GetOrder();
420  const IntegrationRule &ir = IntRules.Get(fine_fe.GetGeomType(), ir_order);
421 
422  for (int i = 0; i < ir.GetNPoints(); i++)
423  {
424  const IntegrationPoint &ip = ir.IntPoint(i);
425  fine_fe.CalcShape(ip, fine_shape);
426  Trans.Transform(ip, vv);
427  f_ip.Set(v, Dim);
428  this->CalcShape(f_ip, coarse_shape);
429 
430  AddMult_a_VVt(ip.weight, fine_shape, fine_mass);
431  AddMult_a_VWt(ip.weight, fine_shape, coarse_shape, fine_coarse_mass);
432  }
433 
434  DenseMatrixInverse fine_mass_inv(fine_mass);
435  fine_mass_inv.Mult(fine_coarse_mass, I);
436 
437  if (MapType == INTEGRAL)
438  {
439  // assuming Trans is linear; this should be ok for all refinement types
441  I *= Trans.Weight();
442  }
443 }
444 
446  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
447 {
448  for (int i = 0; i < Dof; i++)
449  {
450  const IntegrationPoint &ip = Nodes.IntPoint(i);
451  Trans.SetIntPoint(&ip);
452  dofs(i) = coeff.Eval(Trans, ip);
453  }
454 }
455 
458 {
459  const NodalFiniteElement *nfe =
460  dynamic_cast<const NodalFiniteElement *>(&fe);
461 
462  if (nfe && Dof == nfe->GetDof())
463  {
464  nfe->Project(*this, Trans, I);
465  I.Invert();
466  }
467  else
468  {
469  // local L2 projection
470  DenseMatrix pos_mass, mixed_mass;
471  MassIntegrator mass_integ;
472 
473  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
474  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
475 
476  DenseMatrixInverse pos_mass_inv(pos_mass);
477  I.SetSize(Dof, fe.GetDof());
478  pos_mass_inv.Mult(mixed_mass, I);
479  }
480 }
481 
482 
483 void VectorFiniteElement::CalcShape (
484  const IntegrationPoint &ip, Vector &shape ) const
485 {
486  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
487  " VectorFiniteElements!");
488 }
489 
490 void VectorFiniteElement::CalcDShape (
491  const IntegrationPoint &ip, DenseMatrix &dshape ) const
492 {
493  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
494  " VectorFiniteElements!");
495 }
496 
498 {
499  switch (MapType)
500  {
501  case H_DIV:
502  DerivType = DIV;
505  break;
506  case H_CURL:
507  switch (Dim)
508  {
509  case 3: // curl: 3D H_CURL -> 3D H_DIV
510  DerivType = CURL;
513  break;
514  case 2:
515  // curl: 2D H_CURL -> INTEGRAL
516  DerivType = CURL;
519  break;
520  case 1:
521  DerivType = NONE;
524  break;
525  default:
526  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
527  }
528  break;
529  default:
530  MFEM_ABORT("Invalid MapType = " << MapType);
531  }
532 }
533 
535  ElementTransformation &Trans, DenseMatrix &shape) const
536 {
537  MFEM_ASSERT(MapType == H_DIV, "");
538 #ifdef MFEM_THREAD_SAFE
540 #endif
541  CalcVShape(Trans.GetIntPoint(), vshape);
542  MultABt(vshape, Trans.Jacobian(), shape);
543  shape *= (1.0 / Trans.Weight());
544 }
545 
547  ElementTransformation &Trans, DenseMatrix &shape) const
548 {
549  MFEM_ASSERT(MapType == H_CURL, "");
550 #ifdef MFEM_THREAD_SAFE
552 #endif
553  CalcVShape(Trans.GetIntPoint(), vshape);
554  Mult(vshape, Trans.InverseJacobian(), shape);
555 }
556 
558  const double *nk, const Array<int> &d2n,
560 {
561  double vk[3];
562  const int sdim = Trans.GetSpaceDim();
563  MFEM_ASSERT(vc.GetVDim() == sdim, "");
564  Vector xk(vk, sdim);
565  const bool square_J = (Dim == sdim);
566 
567  for (int k = 0; k < Dof; k++)
568  {
569  Trans.SetIntPoint(&Nodes.IntPoint(k));
570  vc.Eval(xk, Trans, Nodes.IntPoint(k));
571  // dof_k = nk^t adj(J) xk
572  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*Dim);
573  if (!square_J) { dofs(k) /= Trans.Weight(); }
574  }
575 }
576 
578  const double *nk, const Array<int> &d2n,
579  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
580 {
581  // project the rows of the matrix coefficient in an RT space
582 
583  const int sdim = T.GetSpaceDim();
584  MFEM_ASSERT(mc.GetWidth() == sdim, "");
585  const bool square_J = (Dim == sdim);
586  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
587  Vector nk_phys(sdim), dofs_k(MQ.Height());
588  MFEM_ASSERT(dofs.Size() == Dof*MQ.Height(), "");
589 
590  for (int k = 0; k < Dof; k++)
591  {
592  T.SetIntPoint(&Nodes.IntPoint(k));
593  mc.Eval(MQ, T, Nodes.IntPoint(k));
594  // nk_phys = adj(J)^t nk
595  T.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, nk_phys);
596  if (!square_J) { nk_phys /= T.Weight(); }
597  MQ.Mult(nk_phys, dofs_k);
598  for (int r = 0; r < MQ.Height(); r++)
599  {
600  dofs(k+Dof*r) = dofs_k(r);
601  }
602  }
603 }
604 
606  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
608 {
609  if (fe.GetRangeType() == SCALAR)
610  {
611  double vk[3];
612  Vector shape(fe.GetDof());
613  int sdim = Trans.GetSpaceDim();
614 
615  I.SetSize(Dof, sdim*fe.GetDof());
616  for (int k = 0; k < Dof; k++)
617  {
618  const IntegrationPoint &ip = Nodes.IntPoint(k);
619 
620  fe.CalcShape(ip, shape);
621  Trans.SetIntPoint(&ip);
622  Trans.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, vk);
623  if (fe.GetMapType() == INTEGRAL)
624  {
625  double w = 1.0/Trans.Weight();
626  for (int d = 0; d < Dim; d++)
627  {
628  vk[d] *= w;
629  }
630  }
631 
632  for (int j = 0; j < shape.Size(); j++)
633  {
634  double s = shape(j);
635  if (fabs(s) < 1e-12)
636  {
637  s = 0.0;
638  }
639  for (int d = 0; d < sdim; d++)
640  {
641  I(k,j+d*shape.Size()) = s*vk[d];
642  }
643  }
644  }
645  }
646  else
647  {
648  mfem_error("VectorFiniteElement::Project_RT (fe version)");
649  }
650 }
651 
653  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
655 {
656  if (Dim != 2)
657  {
658  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
659  }
660 
661  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
662  Vector grad_k(fe.GetDof());
663  double tk[2];
664 
665  grad.SetSize(Dof, fe.GetDof());
666  for (int k = 0; k < Dof; k++)
667  {
668  fe.CalcDShape(Nodes.IntPoint(k), dshape);
669  tk[0] = nk[d2n[k]*Dim+1];
670  tk[1] = -nk[d2n[k]*Dim];
671  dshape.Mult(tk, grad_k);
672  for (int j = 0; j < grad_k.Size(); j++)
673  {
674  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
675  }
676  }
677 }
678 
680  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
682 {
683 #ifdef MFEM_THREAD_SAFE
686  DenseMatrix J(Dim, Dim);
687 #else
688  curlshape.SetSize(fe.GetDof(), Dim);
689  curlshape_J.SetSize(fe.GetDof(), Dim);
690  J.SetSize(Dim, Dim);
691 #endif
692 
693  Vector curl_k(fe.GetDof());
694 
695  curl.SetSize(Dof, fe.GetDof());
696  for (int k = 0; k < Dof; k++)
697  {
698  const IntegrationPoint &ip = Nodes.IntPoint(k);
699 
700  // calculate J^t * J / |J|
701  Trans.SetIntPoint(&ip);
702  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
703  J *= 1.0 / Trans.Weight();
704 
705  // transform curl of shapes (rows) by J^t * J / |J|
706  fe.CalcCurlShape(ip, curlshape);
708 
709  curlshape_J.Mult(tk + d2t[k]*Dim, curl_k);
710  for (int j = 0; j < curl_k.Size(); j++)
711  {
712  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
713  }
714  }
715 }
716 
718  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
720 {
721  DenseMatrix curl_shape(fe.GetDof(), Dim);
722  Vector curl_k(fe.GetDof());
723 
724  curl.SetSize(Dof, fe.GetDof());
725  for (int k = 0; k < Dof; k++)
726  {
727  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
728  curl_shape.Mult(nk + d2n[k]*Dim, curl_k);
729  for (int j = 0; j < curl_k.Size(); j++)
730  {
731  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
732  }
733  }
734 }
735 
737  const double *tk, const Array<int> &d2t,
739 {
740  double vk[3];
741  Vector xk(vk, vc.GetVDim());
742 
743  for (int k = 0; k < Dof; k++)
744  {
745  Trans.SetIntPoint(&Nodes.IntPoint(k));
746 
747  vc.Eval(xk, Trans, Nodes.IntPoint(k));
748  // dof_k = xk^t J tk
749  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*Dim, vk);
750  }
751 }
752 
754  const double *tk, const Array<int> &d2t,
755  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
756 {
757  // project the rows of the matrix coefficient in an ND space
758 
759  const int sdim = T.GetSpaceDim();
760  MFEM_ASSERT(mc.GetWidth() == sdim, "");
761  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
762  Vector tk_phys(sdim), dofs_k(MQ.Height());
763  MFEM_ASSERT(dofs.Size() == Dof*MQ.Height(), "");
764 
765  for (int k = 0; k < Dof; k++)
766  {
767  T.SetIntPoint(&Nodes.IntPoint(k));
768  mc.Eval(MQ, T, Nodes.IntPoint(k));
769  // tk_phys = J tk
770  T.Jacobian().Mult(tk + d2t[k]*Dim, tk_phys);
771  MQ.Mult(tk_phys, dofs_k);
772  for (int r = 0; r < MQ.Height(); r++)
773  {
774  dofs(k+Dof*r) = dofs_k(r);
775  }
776  }
777 }
778 
780  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
782 {
783  if (fe.GetRangeType() == SCALAR)
784  {
785  int sdim = Trans.GetSpaceDim();
786  double vk[3];
787  Vector shape(fe.GetDof());
788 
789  I.SetSize(Dof, sdim*fe.GetDof());
790  for (int k = 0; k < Dof; k++)
791  {
792  const IntegrationPoint &ip = Nodes.IntPoint(k);
793 
794  fe.CalcShape(ip, shape);
795  Trans.SetIntPoint(&ip);
796  Trans.Jacobian().Mult(tk + d2t[k]*Dim, vk);
797  if (fe.GetMapType() == INTEGRAL)
798  {
799  double w = 1.0/Trans.Weight();
800  for (int d = 0; d < sdim; d++)
801  {
802  vk[d] *= w;
803  }
804  }
805 
806  for (int j = 0; j < shape.Size(); j++)
807  {
808  double s = shape(j);
809  if (fabs(s) < 1e-12)
810  {
811  s = 0.0;
812  }
813  for (int d = 0; d < sdim; d++)
814  {
815  I(k, j + d*shape.Size()) = s*vk[d];
816  }
817  }
818  }
819  }
820  else
821  {
822  mfem_error("VectorFiniteElement::Project_ND (fe version)");
823  }
824 }
825 
827  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
829 {
830  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
831 
832  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
833  Vector grad_k(fe.GetDof());
834 
835  grad.SetSize(Dof, fe.GetDof());
836  for (int k = 0; k < Dof; k++)
837  {
838  fe.CalcDShape(Nodes.IntPoint(k), dshape);
839  dshape.Mult(tk + d2t[k]*Dim, grad_k);
840  for (int j = 0; j < grad_k.Size(); j++)
841  {
842  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
843  }
844  }
845 }
846 
848  const double *nk, const Array<int> &d2n, ElementTransformation &Trans,
849  DenseMatrix &I) const
850 {
851  double vk[3];
852  Vector xk(vk, Dim);
853  IntegrationPoint ip;
854 #ifdef MFEM_THREAD_SAFE
856 #endif
857 
858  // assuming Trans is linear; this should be ok for all refinement types
860  const DenseMatrix &adjJ = Trans.AdjugateJacobian();
861  for (int k = 0; k < Dof; k++)
862  {
863  Trans.Transform(Nodes.IntPoint(k), xk);
864  ip.Set3(vk);
865  CalcVShape(ip, vshape);
866  // xk = |J| J^{-t} n_k
867  adjJ.MultTranspose(nk + d2n[k]*Dim, vk);
868  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,Dof
869  for (int j = 0; j < Dof; j++)
870  {
871  double Ikj = 0.;
872  for (int i = 0; i < Dim; i++)
873  {
874  Ikj += vshape(j, i) * vk[i];
875  }
876  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
877  }
878  }
879 }
880 
882  const double *tk, const Array<int> &d2t, ElementTransformation &Trans,
883  DenseMatrix &I) const
884 {
885  double vk[3];
886  Vector xk(vk, Dim);
887  IntegrationPoint ip;
888 #ifdef MFEM_THREAD_SAFE
890 #endif
891 
892  // assuming Trans is linear; this should be ok for all refinement types
894  const DenseMatrix &J = Trans.Jacobian();
895  for (int k = 0; k < Dof; k++)
896  {
897  Trans.Transform(Nodes.IntPoint(k), xk);
898  ip.Set3(vk);
899  CalcVShape(ip, vshape);
900  // xk = J t_k
901  J.Mult(tk + d2t[k]*Dim, vk);
902  // I_k = vshape_k.J.t_k, k=1,...,Dof
903  for (int j = 0; j < Dof; j++)
904  {
905  double Ikj = 0.;
906  for (int i = 0; i < Dim; i++)
907  {
908  Ikj += vshape(j, i) * vk[i];
909  }
910  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
911  }
912  }
913 }
914 
915 
917  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
918 {
919  Nodes.IntPoint(0).x = 0.0;
920 }
921 
923  Vector &shape) const
924 {
925  shape(0) = 1.;
926 }
927 
929  DenseMatrix &dshape) const
930 {
931  // dshape is (1 x 0) - nothing to compute
932 }
933 
935  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
936 {
937  Nodes.IntPoint(0).x = 0.0;
938  Nodes.IntPoint(1).x = 1.0;
939 }
940 
942  Vector &shape) const
943 {
944  shape(0) = 1. - ip.x;
945  shape(1) = ip.x;
946 }
947 
949  DenseMatrix &dshape) const
950 {
951  dshape(0,0) = -1.;
952  dshape(1,0) = 1.;
953 }
954 
956  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
957 {
958  Nodes.IntPoint(0).x = 0.0;
959  Nodes.IntPoint(0).y = 0.0;
960  Nodes.IntPoint(1).x = 1.0;
961  Nodes.IntPoint(1).y = 0.0;
962  Nodes.IntPoint(2).x = 0.0;
963  Nodes.IntPoint(2).y = 1.0;
964 }
965 
967  Vector &shape) const
968 {
969  shape(0) = 1. - ip.x - ip.y;
970  shape(1) = ip.x;
971  shape(2) = ip.y;
972 }
973 
975  DenseMatrix &dshape) const
976 {
977  dshape(0,0) = -1.; dshape(0,1) = -1.;
978  dshape(1,0) = 1.; dshape(1,1) = 0.;
979  dshape(2,0) = 0.; dshape(2,1) = 1.;
980 }
981 
983  : NodalFiniteElement(2, Geometry::SQUARE , 4, 1, FunctionSpace::Qk)
984 {
985  Nodes.IntPoint(0).x = 0.0;
986  Nodes.IntPoint(0).y = 0.0;
987  Nodes.IntPoint(1).x = 1.0;
988  Nodes.IntPoint(1).y = 0.0;
989  Nodes.IntPoint(2).x = 1.0;
990  Nodes.IntPoint(2).y = 1.0;
991  Nodes.IntPoint(3).x = 0.0;
992  Nodes.IntPoint(3).y = 1.0;
993 }
994 
996  Vector &shape) const
997 {
998  shape(0) = (1. - ip.x) * (1. - ip.y) ;
999  shape(1) = ip.x * (1. - ip.y) ;
1000  shape(2) = ip.x * ip.y ;
1001  shape(3) = (1. - ip.x) * ip.y ;
1002 }
1003 
1005  DenseMatrix &dshape) const
1006 {
1007  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
1008  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
1009  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
1010  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
1011 }
1012 
1014  const IntegrationPoint &ip, DenseMatrix &h) const
1015 {
1016  h(0,0) = 0.; h(0,1) = 1.; h(0,2) = 0.;
1017  h(1,0) = 0.; h(1,1) = -1.; h(1,2) = 0.;
1018  h(2,0) = 0.; h(2,1) = 1.; h(2,2) = 0.;
1019  h(3,0) = 0.; h(3,1) = -1.; h(3,2) = 0.;
1020 }
1021 
1022 
1024  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
1025 {
1026  Nodes.IntPoint(0).x = 1./6.;
1027  Nodes.IntPoint(0).y = 1./6.;
1028  Nodes.IntPoint(1).x = 2./3.;
1029  Nodes.IntPoint(1).y = 1./6.;
1030  Nodes.IntPoint(2).x = 1./6.;
1031  Nodes.IntPoint(2).y = 2./3.;
1032 }
1033 
1035  Vector &shape) const
1036 {
1037  const double x = ip.x, y = ip.y;
1038 
1039  shape(0) = 5./3. - 2. * (x + y);
1040  shape(1) = 2. * (x - 1./6.);
1041  shape(2) = 2. * (y - 1./6.);
1042 }
1043 
1045  DenseMatrix &dshape) const
1046 {
1047  dshape(0,0) = -2.; dshape(0,1) = -2.;
1048  dshape(1,0) = 2.; dshape(1,1) = 0.;
1049  dshape(2,0) = 0.; dshape(2,1) = 2.;
1050 }
1051 
1053 {
1054  dofs(vertex) = 2./3.;
1055  dofs((vertex+1)%3) = 1./6.;
1056  dofs((vertex+2)%3) = 1./6.;
1057 }
1058 
1059 
1060 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
1061 const double GaussBiLinear2DFiniteElement::p[] =
1062 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
1063 
1065  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1066 {
1067  Nodes.IntPoint(0).x = p[0];
1068  Nodes.IntPoint(0).y = p[0];
1069  Nodes.IntPoint(1).x = p[1];
1070  Nodes.IntPoint(1).y = p[0];
1071  Nodes.IntPoint(2).x = p[1];
1072  Nodes.IntPoint(2).y = p[1];
1073  Nodes.IntPoint(3).x = p[0];
1074  Nodes.IntPoint(3).y = p[1];
1075 }
1076 
1078  Vector &shape) const
1079 {
1080  const double x = ip.x, y = ip.y;
1081 
1082  shape(0) = 3. * (p[1] - x) * (p[1] - y);
1083  shape(1) = 3. * (x - p[0]) * (p[1] - y);
1084  shape(2) = 3. * (x - p[0]) * (y - p[0]);
1085  shape(3) = 3. * (p[1] - x) * (y - p[0]);
1086 }
1087 
1089  DenseMatrix &dshape) const
1090 {
1091  const double x = ip.x, y = ip.y;
1092 
1093  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
1094  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
1095  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
1096  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
1097 }
1098 
1100 {
1101 #if 1
1102  dofs(vertex) = p[1]*p[1];
1103  dofs((vertex+1)%4) = p[0]*p[1];
1104  dofs((vertex+2)%4) = p[0]*p[0];
1105  dofs((vertex+3)%4) = p[0]*p[1];
1106 #else
1107  dofs = 1.0;
1108 #endif
1109 }
1110 
1111 
1113  : NodalFiniteElement(2, Geometry::SQUARE , 3, 1, FunctionSpace::Qk)
1114 {
1115  Nodes.IntPoint(0).x = 0.0;
1116  Nodes.IntPoint(0).y = 0.0;
1117  Nodes.IntPoint(1).x = 1.0;
1118  Nodes.IntPoint(1).y = 0.0;
1119  Nodes.IntPoint(2).x = 0.0;
1120  Nodes.IntPoint(2).y = 1.0;
1121 }
1122 
1124  Vector &shape) const
1125 {
1126  shape(0) = 1. - ip.x - ip.y;
1127  shape(1) = ip.x;
1128  shape(2) = ip.y;
1129 }
1130 
1132  DenseMatrix &dshape) const
1133 {
1134  dshape(0,0) = -1.; dshape(0,1) = -1.;
1135  dshape(1,0) = 1.; dshape(1,1) = 0.;
1136  dshape(2,0) = 0.; dshape(2,1) = 1.;
1137 }
1138 
1139 
1141  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
1142 {
1143  Nodes.IntPoint(0).x = 0.0;
1144  Nodes.IntPoint(1).x = 1.0;
1145  Nodes.IntPoint(2).x = 0.5;
1146 }
1147 
1149  Vector &shape) const
1150 {
1151  double x = ip.x;
1152  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
1153 
1154  shape(0) = l1 * (-l3);
1155  shape(1) = l2 * l3;
1156  shape(2) = 4. * l1 * l2;
1157 }
1158 
1160  DenseMatrix &dshape) const
1161 {
1162  double x = ip.x;
1163 
1164  dshape(0,0) = 4. * x - 3.;
1165  dshape(1,0) = 4. * x - 1.;
1166  dshape(2,0) = 4. - 8. * x;
1167 }
1168 
1169 
1171  : PositiveFiniteElement(1, Geometry::SEGMENT, 3, 2)
1172 {
1173  Nodes.IntPoint(0).x = 0.0;
1174  Nodes.IntPoint(1).x = 1.0;
1175  Nodes.IntPoint(2).x = 0.5;
1176 }
1177 
1179  Vector &shape) const
1180 {
1181  const double x = ip.x, x1 = 1. - x;
1182 
1183  shape(0) = x1 * x1;
1184  shape(1) = x * x;
1185  shape(2) = 2. * x * x1;
1186 }
1187 
1189  DenseMatrix &dshape) const
1190 {
1191  const double x = ip.x;
1192 
1193  dshape(0,0) = 2. * x - 2.;
1194  dshape(1,0) = 2. * x;
1195  dshape(2,0) = 2. - 4. * x;
1196 }
1197 
1199  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1200 {
1201  Nodes.IntPoint(0).x = 0.0;
1202  Nodes.IntPoint(0).y = 0.0;
1203  Nodes.IntPoint(1).x = 1.0;
1204  Nodes.IntPoint(1).y = 0.0;
1205  Nodes.IntPoint(2).x = 0.0;
1206  Nodes.IntPoint(2).y = 1.0;
1207  Nodes.IntPoint(3).x = 0.5;
1208  Nodes.IntPoint(3).y = 0.0;
1209  Nodes.IntPoint(4).x = 0.5;
1210  Nodes.IntPoint(4).y = 0.5;
1211  Nodes.IntPoint(5).x = 0.0;
1212  Nodes.IntPoint(5).y = 0.5;
1213 }
1214 
1216  Vector &shape) const
1217 {
1218  double x = ip.x, y = ip.y;
1219  double l1 = 1.-x-y, l2 = x, l3 = y;
1220 
1221  shape(0) = l1 * (2. * l1 - 1.);
1222  shape(1) = l2 * (2. * l2 - 1.);
1223  shape(2) = l3 * (2. * l3 - 1.);
1224  shape(3) = 4. * l1 * l2;
1225  shape(4) = 4. * l2 * l3;
1226  shape(5) = 4. * l3 * l1;
1227 }
1228 
1230  DenseMatrix &dshape) const
1231 {
1232  double x = ip.x, y = ip.y;
1233 
1234  dshape(0,0) =
1235  dshape(0,1) = 4. * (x + y) - 3.;
1236 
1237  dshape(1,0) = 4. * x - 1.;
1238  dshape(1,1) = 0.;
1239 
1240  dshape(2,0) = 0.;
1241  dshape(2,1) = 4. * y - 1.;
1242 
1243  dshape(3,0) = -4. * (2. * x + y - 1.);
1244  dshape(3,1) = -4. * x;
1245 
1246  dshape(4,0) = 4. * y;
1247  dshape(4,1) = 4. * x;
1248 
1249  dshape(5,0) = -4. * y;
1250  dshape(5,1) = -4. * (x + 2. * y - 1.);
1251 }
1252 
1254  DenseMatrix &h) const
1255 {
1256  h(0,0) = 4.;
1257  h(0,1) = 4.;
1258  h(0,2) = 4.;
1259 
1260  h(1,0) = 4.;
1261  h(1,1) = 0.;
1262  h(1,2) = 0.;
1263 
1264  h(2,0) = 0.;
1265  h(2,1) = 0.;
1266  h(2,2) = 4.;
1267 
1268  h(3,0) = -8.;
1269  h(3,1) = -4.;
1270  h(3,2) = 0.;
1271 
1272  h(4,0) = 0.;
1273  h(4,1) = 4.;
1274  h(4,2) = 0.;
1275 
1276  h(5,0) = 0.;
1277  h(5,1) = -4.;
1278  h(5,2) = -8.;
1279 }
1280 
1281 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1282 {
1283 #if 0
1284  dofs = 1.;
1285 #else
1286  dofs = 0.;
1287  dofs(vertex) = 1.;
1288  switch (vertex)
1289  {
1290  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1291  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1292  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1293  }
1294 #endif
1295 }
1296 
1297 
1298 const double GaussQuad2DFiniteElement::p[] =
1299 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1300 
1302  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1303 {
1304  Nodes.IntPoint(0).x = p[0];
1305  Nodes.IntPoint(0).y = p[0];
1306  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1307  Nodes.IntPoint(1).y = p[0];
1308  Nodes.IntPoint(2).x = p[0];
1309  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1310  Nodes.IntPoint(3).x = p[1];
1311  Nodes.IntPoint(3).y = p[1];
1312  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1313  Nodes.IntPoint(4).y = p[1];
1314  Nodes.IntPoint(5).x = p[1];
1315  Nodes.IntPoint(5).y = 1. - 2. * p[1];
1316 
1317  for (int i = 0; i < 6; i++)
1318  {
1319  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
1320  A(0,i) = 1.;
1321  A(1,i) = x;
1322  A(2,i) = y;
1323  A(3,i) = x * x;
1324  A(4,i) = x * y;
1325  A(5,i) = y * y;
1326  }
1327 
1328  A.Invert();
1329 }
1330 
1332  Vector &shape) const
1333 {
1334  const double x = ip.x, y = ip.y;
1335  pol(0) = 1.;
1336  pol(1) = x;
1337  pol(2) = y;
1338  pol(3) = x * x;
1339  pol(4) = x * y;
1340  pol(5) = y * y;
1341 
1342  A.Mult(pol, shape);
1343 }
1344 
1346  DenseMatrix &dshape) const
1347 {
1348  const double x = ip.x, y = ip.y;
1349  D(0,0) = 0.; D(0,1) = 0.;
1350  D(1,0) = 1.; D(1,1) = 0.;
1351  D(2,0) = 0.; D(2,1) = 1.;
1352  D(3,0) = 2. * x; D(3,1) = 0.;
1353  D(4,0) = y; D(4,1) = x;
1354  D(5,0) = 0.; D(5,1) = 2. * y;
1355 
1356  Mult(A, D, dshape);
1357 }
1358 
1359 
1361  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1362 {
1363  Nodes.IntPoint(0).x = 0.0;
1364  Nodes.IntPoint(0).y = 0.0;
1365  Nodes.IntPoint(1).x = 1.0;
1366  Nodes.IntPoint(1).y = 0.0;
1367  Nodes.IntPoint(2).x = 1.0;
1368  Nodes.IntPoint(2).y = 1.0;
1369  Nodes.IntPoint(3).x = 0.0;
1370  Nodes.IntPoint(3).y = 1.0;
1371  Nodes.IntPoint(4).x = 0.5;
1372  Nodes.IntPoint(4).y = 0.0;
1373  Nodes.IntPoint(5).x = 1.0;
1374  Nodes.IntPoint(5).y = 0.5;
1375  Nodes.IntPoint(6).x = 0.5;
1376  Nodes.IntPoint(6).y = 1.0;
1377  Nodes.IntPoint(7).x = 0.0;
1378  Nodes.IntPoint(7).y = 0.5;
1379  Nodes.IntPoint(8).x = 0.5;
1380  Nodes.IntPoint(8).y = 0.5;
1381 }
1382 
1384  Vector &shape) const
1385 {
1386  double x = ip.x, y = ip.y;
1387  double l1x, l2x, l3x, l1y, l2y, l3y;
1388 
1389  l1x = (x - 1.) * (2. * x - 1);
1390  l2x = 4. * x * (1. - x);
1391  l3x = x * (2. * x - 1.);
1392  l1y = (y - 1.) * (2. * y - 1);
1393  l2y = 4. * y * (1. - y);
1394  l3y = y * (2. * y - 1.);
1395 
1396  shape(0) = l1x * l1y;
1397  shape(4) = l2x * l1y;
1398  shape(1) = l3x * l1y;
1399  shape(7) = l1x * l2y;
1400  shape(8) = l2x * l2y;
1401  shape(5) = l3x * l2y;
1402  shape(3) = l1x * l3y;
1403  shape(6) = l2x * l3y;
1404  shape(2) = l3x * l3y;
1405 }
1406 
1408  DenseMatrix &dshape) const
1409 {
1410  double x = ip.x, y = ip.y;
1411  double l1x, l2x, l3x, l1y, l2y, l3y;
1412  double d1x, d2x, d3x, d1y, d2y, d3y;
1413 
1414  l1x = (x - 1.) * (2. * x - 1);
1415  l2x = 4. * x * (1. - x);
1416  l3x = x * (2. * x - 1.);
1417  l1y = (y - 1.) * (2. * y - 1);
1418  l2y = 4. * y * (1. - y);
1419  l3y = y * (2. * y - 1.);
1420 
1421  d1x = 4. * x - 3.;
1422  d2x = 4. - 8. * x;
1423  d3x = 4. * x - 1.;
1424  d1y = 4. * y - 3.;
1425  d2y = 4. - 8. * y;
1426  d3y = 4. * y - 1.;
1427 
1428  dshape(0,0) = d1x * l1y;
1429  dshape(0,1) = l1x * d1y;
1430 
1431  dshape(4,0) = d2x * l1y;
1432  dshape(4,1) = l2x * d1y;
1433 
1434  dshape(1,0) = d3x * l1y;
1435  dshape(1,1) = l3x * d1y;
1436 
1437  dshape(7,0) = d1x * l2y;
1438  dshape(7,1) = l1x * d2y;
1439 
1440  dshape(8,0) = d2x * l2y;
1441  dshape(8,1) = l2x * d2y;
1442 
1443  dshape(5,0) = d3x * l2y;
1444  dshape(5,1) = l3x * d2y;
1445 
1446  dshape(3,0) = d1x * l3y;
1447  dshape(3,1) = l1x * d3y;
1448 
1449  dshape(6,0) = d2x * l3y;
1450  dshape(6,1) = l2x * d3y;
1451 
1452  dshape(2,0) = d3x * l3y;
1453  dshape(2,1) = l3x * d3y;
1454 }
1455 
1456 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1457 {
1458 #if 0
1459  dofs = 1.;
1460 #else
1461  dofs = 0.;
1462  dofs(vertex) = 1.;
1463  switch (vertex)
1464  {
1465  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
1466  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
1467  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
1468  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
1469  }
1470  dofs(8) = 1./16.;
1471 #endif
1472 }
1473 
1475  : PositiveFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1476 {
1477  Nodes.IntPoint(0).x = 0.0;
1478  Nodes.IntPoint(0).y = 0.0;
1479  Nodes.IntPoint(1).x = 1.0;
1480  Nodes.IntPoint(1).y = 0.0;
1481  Nodes.IntPoint(2).x = 1.0;
1482  Nodes.IntPoint(2).y = 1.0;
1483  Nodes.IntPoint(3).x = 0.0;
1484  Nodes.IntPoint(3).y = 1.0;
1485  Nodes.IntPoint(4).x = 0.5;
1486  Nodes.IntPoint(4).y = 0.0;
1487  Nodes.IntPoint(5).x = 1.0;
1488  Nodes.IntPoint(5).y = 0.5;
1489  Nodes.IntPoint(6).x = 0.5;
1490  Nodes.IntPoint(6).y = 1.0;
1491  Nodes.IntPoint(7).x = 0.0;
1492  Nodes.IntPoint(7).y = 0.5;
1493  Nodes.IntPoint(8).x = 0.5;
1494  Nodes.IntPoint(8).y = 0.5;
1495 }
1496 
1498  Vector &shape) const
1499 {
1500  double x = ip.x, y = ip.y;
1501  double l1x, l2x, l3x, l1y, l2y, l3y;
1502 
1503  l1x = (1. - x) * (1. - x);
1504  l2x = 2. * x * (1. - x);
1505  l3x = x * x;
1506  l1y = (1. - y) * (1. - y);
1507  l2y = 2. * y * (1. - y);
1508  l3y = y * y;
1509 
1510  shape(0) = l1x * l1y;
1511  shape(4) = l2x * l1y;
1512  shape(1) = l3x * l1y;
1513  shape(7) = l1x * l2y;
1514  shape(8) = l2x * l2y;
1515  shape(5) = l3x * l2y;
1516  shape(3) = l1x * l3y;
1517  shape(6) = l2x * l3y;
1518  shape(2) = l3x * l3y;
1519 }
1520 
1522  DenseMatrix &dshape) const
1523 {
1524  double x = ip.x, y = ip.y;
1525  double l1x, l2x, l3x, l1y, l2y, l3y;
1526  double d1x, d2x, d3x, d1y, d2y, d3y;
1527 
1528  l1x = (1. - x) * (1. - x);
1529  l2x = 2. * x * (1. - x);
1530  l3x = x * x;
1531  l1y = (1. - y) * (1. - y);
1532  l2y = 2. * y * (1. - y);
1533  l3y = y * y;
1534 
1535  d1x = 2. * x - 2.;
1536  d2x = 2. - 4. * x;
1537  d3x = 2. * x;
1538  d1y = 2. * y - 2.;
1539  d2y = 2. - 4. * y;
1540  d3y = 2. * y;
1541 
1542  dshape(0,0) = d1x * l1y;
1543  dshape(0,1) = l1x * d1y;
1544 
1545  dshape(4,0) = d2x * l1y;
1546  dshape(4,1) = l2x * d1y;
1547 
1548  dshape(1,0) = d3x * l1y;
1549  dshape(1,1) = l3x * d1y;
1550 
1551  dshape(7,0) = d1x * l2y;
1552  dshape(7,1) = l1x * d2y;
1553 
1554  dshape(8,0) = d2x * l2y;
1555  dshape(8,1) = l2x * d2y;
1556 
1557  dshape(5,0) = d3x * l2y;
1558  dshape(5,1) = l3x * d2y;
1559 
1560  dshape(3,0) = d1x * l3y;
1561  dshape(3,1) = l1x * d3y;
1562 
1563  dshape(6,0) = d2x * l3y;
1564  dshape(6,1) = l2x * d3y;
1565 
1566  dshape(2,0) = d3x * l3y;
1567  dshape(2,1) = l3x * d3y;
1568 }
1569 
1572 {
1573  double s[9];
1574  IntegrationPoint tr_ip;
1575  Vector xx(&tr_ip.x, 2), shape(s, 9);
1576 
1577  for (int i = 0; i < 9; i++)
1578  {
1579  Trans.Transform(Nodes.IntPoint(i), xx);
1580  CalcShape(tr_ip, shape);
1581  for (int j = 0; j < 9; j++)
1582  if (fabs(I(i,j) = s[j]) < 1.0e-12)
1583  {
1584  I(i,j) = 0.0;
1585  }
1586  }
1587  for (int i = 0; i < 9; i++)
1588  {
1589  double *d = &I(0,i);
1590  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1591  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1592  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1593  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1594  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1595  0.25 * (d[0] + d[1] + d[2] + d[3]);
1596  }
1597 }
1598 
1600  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
1601 {
1602  double *d = dofs;
1603 
1604  for (int i = 0; i < 9; i++)
1605  {
1606  const IntegrationPoint &ip = Nodes.IntPoint(i);
1607  Trans.SetIntPoint(&ip);
1608  d[i] = coeff.Eval(Trans, ip);
1609  }
1610  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1611  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1612  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1613  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1614  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1615  0.25 * (d[0] + d[1] + d[2] + d[3]);
1616 }
1617 
1620  Vector &dofs) const
1621 {
1622  double v[3];
1623  Vector x (v, vc.GetVDim());
1624 
1625  for (int i = 0; i < 9; i++)
1626  {
1627  const IntegrationPoint &ip = Nodes.IntPoint(i);
1628  Trans.SetIntPoint(&ip);
1629  vc.Eval (x, Trans, ip);
1630  for (int j = 0; j < x.Size(); j++)
1631  {
1632  dofs(9*j+i) = v[j];
1633  }
1634  }
1635  for (int j = 0; j < x.Size(); j++)
1636  {
1637  double *d = &dofs(9*j);
1638 
1639  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1640  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1641  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1642  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1643  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1644  0.25 * (d[0] + d[1] + d[2] + d[3]);
1645  }
1646 }
1647 
1648 
1650  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1651 {
1652  const double p1 = 0.5*(1.-sqrt(3./5.));
1653 
1654  Nodes.IntPoint(0).x = p1;
1655  Nodes.IntPoint(0).y = p1;
1656  Nodes.IntPoint(4).x = 0.5;
1657  Nodes.IntPoint(4).y = p1;
1658  Nodes.IntPoint(1).x = 1.-p1;
1659  Nodes.IntPoint(1).y = p1;
1660  Nodes.IntPoint(7).x = p1;
1661  Nodes.IntPoint(7).y = 0.5;
1662  Nodes.IntPoint(8).x = 0.5;
1663  Nodes.IntPoint(8).y = 0.5;
1664  Nodes.IntPoint(5).x = 1.-p1;
1665  Nodes.IntPoint(5).y = 0.5;
1666  Nodes.IntPoint(3).x = p1;
1667  Nodes.IntPoint(3).y = 1.-p1;
1668  Nodes.IntPoint(6).x = 0.5;
1669  Nodes.IntPoint(6).y = 1.-p1;
1670  Nodes.IntPoint(2).x = 1.-p1;
1671  Nodes.IntPoint(2).y = 1.-p1;
1672 }
1673 
1675  Vector &shape) const
1676 {
1677  const double a = sqrt(5./3.);
1678  const double p1 = 0.5*(1.-sqrt(3./5.));
1679 
1680  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1681  double l1x, l2x, l3x, l1y, l2y, l3y;
1682 
1683  l1x = (x - 1.) * (2. * x - 1);
1684  l2x = 4. * x * (1. - x);
1685  l3x = x * (2. * x - 1.);
1686  l1y = (y - 1.) * (2. * y - 1);
1687  l2y = 4. * y * (1. - y);
1688  l3y = y * (2. * y - 1.);
1689 
1690  shape(0) = l1x * l1y;
1691  shape(4) = l2x * l1y;
1692  shape(1) = l3x * l1y;
1693  shape(7) = l1x * l2y;
1694  shape(8) = l2x * l2y;
1695  shape(5) = l3x * l2y;
1696  shape(3) = l1x * l3y;
1697  shape(6) = l2x * l3y;
1698  shape(2) = l3x * l3y;
1699 }
1700 
1702  DenseMatrix &dshape) const
1703 {
1704  const double a = sqrt(5./3.);
1705  const double p1 = 0.5*(1.-sqrt(3./5.));
1706 
1707  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1708  double l1x, l2x, l3x, l1y, l2y, l3y;
1709  double d1x, d2x, d3x, d1y, d2y, d3y;
1710 
1711  l1x = (x - 1.) * (2. * x - 1);
1712  l2x = 4. * x * (1. - x);
1713  l3x = x * (2. * x - 1.);
1714  l1y = (y - 1.) * (2. * y - 1);
1715  l2y = 4. * y * (1. - y);
1716  l3y = y * (2. * y - 1.);
1717 
1718  d1x = a * (4. * x - 3.);
1719  d2x = a * (4. - 8. * x);
1720  d3x = a * (4. * x - 1.);
1721  d1y = a * (4. * y - 3.);
1722  d2y = a * (4. - 8. * y);
1723  d3y = a * (4. * y - 1.);
1724 
1725  dshape(0,0) = d1x * l1y;
1726  dshape(0,1) = l1x * d1y;
1727 
1728  dshape(4,0) = d2x * l1y;
1729  dshape(4,1) = l2x * d1y;
1730 
1731  dshape(1,0) = d3x * l1y;
1732  dshape(1,1) = l3x * d1y;
1733 
1734  dshape(7,0) = d1x * l2y;
1735  dshape(7,1) = l1x * d2y;
1736 
1737  dshape(8,0) = d2x * l2y;
1738  dshape(8,1) = l2x * d2y;
1739 
1740  dshape(5,0) = d3x * l2y;
1741  dshape(5,1) = l3x * d2y;
1742 
1743  dshape(3,0) = d1x * l3y;
1744  dshape(3,1) = l1x * d3y;
1745 
1746  dshape(6,0) = d2x * l3y;
1747  dshape(6,1) = l2x * d3y;
1748 
1749  dshape(2,0) = d3x * l3y;
1750  dshape(2,1) = l3x * d3y;
1751 }
1752 
1754  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
1755 {
1756  Nodes.IntPoint(0).x = 0.;
1757  Nodes.IntPoint(0).y = 0.;
1758  Nodes.IntPoint(1).x = 1.;
1759  Nodes.IntPoint(1).y = 0.;
1760  Nodes.IntPoint(2).x = 1.;
1761  Nodes.IntPoint(2).y = 1.;
1762  Nodes.IntPoint(3).x = 0.;
1763  Nodes.IntPoint(3).y = 1.;
1764  Nodes.IntPoint(4).x = 1./3.;
1765  Nodes.IntPoint(4).y = 0.;
1766  Nodes.IntPoint(5).x = 2./3.;
1767  Nodes.IntPoint(5).y = 0.;
1768  Nodes.IntPoint(6).x = 1.;
1769  Nodes.IntPoint(6).y = 1./3.;
1770  Nodes.IntPoint(7).x = 1.;
1771  Nodes.IntPoint(7).y = 2./3.;
1772  Nodes.IntPoint(8).x = 2./3.;
1773  Nodes.IntPoint(8).y = 1.;
1774  Nodes.IntPoint(9).x = 1./3.;
1775  Nodes.IntPoint(9).y = 1.;
1776  Nodes.IntPoint(10).x = 0.;
1777  Nodes.IntPoint(10).y = 2./3.;
1778  Nodes.IntPoint(11).x = 0.;
1779  Nodes.IntPoint(11).y = 1./3.;
1780  Nodes.IntPoint(12).x = 1./3.;
1781  Nodes.IntPoint(12).y = 1./3.;
1782  Nodes.IntPoint(13).x = 2./3.;
1783  Nodes.IntPoint(13).y = 1./3.;
1784  Nodes.IntPoint(14).x = 1./3.;
1785  Nodes.IntPoint(14).y = 2./3.;
1786  Nodes.IntPoint(15).x = 2./3.;
1787  Nodes.IntPoint(15).y = 2./3.;
1788 }
1789 
1791  const IntegrationPoint &ip, Vector &shape) const
1792 {
1793  double x = ip.x, y = ip.y;
1794 
1795  double w1x, w2x, w3x, w1y, w2y, w3y;
1796  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1797 
1798  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1799  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1800 
1801  l0x = (- 4.5) * w1x * w2x * w3x;
1802  l1x = ( 13.5) * x * w2x * w3x;
1803  l2x = (-13.5) * x * w1x * w3x;
1804  l3x = ( 4.5) * x * w1x * w2x;
1805 
1806  l0y = (- 4.5) * w1y * w2y * w3y;
1807  l1y = ( 13.5) * y * w2y * w3y;
1808  l2y = (-13.5) * y * w1y * w3y;
1809  l3y = ( 4.5) * y * w1y * w2y;
1810 
1811  shape(0) = l0x * l0y;
1812  shape(1) = l3x * l0y;
1813  shape(2) = l3x * l3y;
1814  shape(3) = l0x * l3y;
1815  shape(4) = l1x * l0y;
1816  shape(5) = l2x * l0y;
1817  shape(6) = l3x * l1y;
1818  shape(7) = l3x * l2y;
1819  shape(8) = l2x * l3y;
1820  shape(9) = l1x * l3y;
1821  shape(10) = l0x * l2y;
1822  shape(11) = l0x * l1y;
1823  shape(12) = l1x * l1y;
1824  shape(13) = l2x * l1y;
1825  shape(14) = l1x * l2y;
1826  shape(15) = l2x * l2y;
1827 }
1828 
1830  const IntegrationPoint &ip, DenseMatrix &dshape) const
1831 {
1832  double x = ip.x, y = ip.y;
1833 
1834  double w1x, w2x, w3x, w1y, w2y, w3y;
1835  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1836  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1837 
1838  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1839  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1840 
1841  l0x = (- 4.5) * w1x * w2x * w3x;
1842  l1x = ( 13.5) * x * w2x * w3x;
1843  l2x = (-13.5) * x * w1x * w3x;
1844  l3x = ( 4.5) * x * w1x * w2x;
1845 
1846  l0y = (- 4.5) * w1y * w2y * w3y;
1847  l1y = ( 13.5) * y * w2y * w3y;
1848  l2y = (-13.5) * y * w1y * w3y;
1849  l3y = ( 4.5) * y * w1y * w2y;
1850 
1851  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1852  d1x = 9. + (-45. + 40.5 * x) * x;
1853  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1854  d3x = 1. + (- 9. + 13.5 * x) * x;
1855 
1856  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1857  d1y = 9. + (-45. + 40.5 * y) * y;
1858  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1859  d3y = 1. + (- 9. + 13.5 * y) * y;
1860 
1861  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
1862  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
1863  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
1864  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
1865  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
1866  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
1867  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
1868  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
1869  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
1870  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
1871  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
1872  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
1873  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
1874  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
1875  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
1876  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
1877 }
1878 
1880  const IntegrationPoint &ip, DenseMatrix &h) const
1881 {
1882  double x = ip.x, y = ip.y;
1883 
1884  double w1x, w2x, w3x, w1y, w2y, w3y;
1885  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1886  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1887  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
1888 
1889  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1890  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1891 
1892  l0x = (- 4.5) * w1x * w2x * w3x;
1893  l1x = ( 13.5) * x * w2x * w3x;
1894  l2x = (-13.5) * x * w1x * w3x;
1895  l3x = ( 4.5) * x * w1x * w2x;
1896 
1897  l0y = (- 4.5) * w1y * w2y * w3y;
1898  l1y = ( 13.5) * y * w2y * w3y;
1899  l2y = (-13.5) * y * w1y * w3y;
1900  l3y = ( 4.5) * y * w1y * w2y;
1901 
1902  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1903  d1x = 9. + (-45. + 40.5 * x) * x;
1904  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1905  d3x = 1. + (- 9. + 13.5 * x) * x;
1906 
1907  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1908  d1y = 9. + (-45. + 40.5 * y) * y;
1909  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1910  d3y = 1. + (- 9. + 13.5 * y) * y;
1911 
1912  h0x = -27. * x + 18.;
1913  h1x = 81. * x - 45.;
1914  h2x = -81. * x + 36.;
1915  h3x = 27. * x - 9.;
1916 
1917  h0y = -27. * y + 18.;
1918  h1y = 81. * y - 45.;
1919  h2y = -81. * y + 36.;
1920  h3y = 27. * y - 9.;
1921 
1922  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
1923  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
1924  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
1925  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
1926  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
1927  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
1928  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
1929  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
1930  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
1931  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
1932  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
1933  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
1934  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
1935  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
1936  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
1937  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
1938 }
1939 
1940 
1942  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
1943 {
1944  Nodes.IntPoint(0).x = 0.0;
1945  Nodes.IntPoint(1).x = 1.0;
1946  Nodes.IntPoint(2).x = 0.33333333333333333333;
1947  Nodes.IntPoint(3).x = 0.66666666666666666667;
1948 }
1949 
1951  Vector &shape) const
1952 {
1953  double x = ip.x;
1954  double l1 = x,
1955  l2 = (1.0-x),
1956  l3 = (0.33333333333333333333-x),
1957  l4 = (0.66666666666666666667-x);
1958 
1959  shape(0) = 4.5 * l2 * l3 * l4;
1960  shape(1) = 4.5 * l1 * l3 * l4;
1961  shape(2) = 13.5 * l1 * l2 * l4;
1962  shape(3) = -13.5 * l1 * l2 * l3;
1963 }
1964 
1966  DenseMatrix &dshape) const
1967 {
1968  double x = ip.x;
1969 
1970  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
1971  dshape(1,0) = 1. - x * (9. - 13.5 * x);
1972  dshape(2,0) = 9. - x * (45. - 40.5 * x);
1973  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
1974 }
1975 
1976 
1978  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
1979 {
1980  Nodes.IntPoint(0).x = 0.0;
1981  Nodes.IntPoint(0).y = 0.0;
1982  Nodes.IntPoint(1).x = 1.0;
1983  Nodes.IntPoint(1).y = 0.0;
1984  Nodes.IntPoint(2).x = 0.0;
1985  Nodes.IntPoint(2).y = 1.0;
1986  Nodes.IntPoint(3).x = 0.33333333333333333333;
1987  Nodes.IntPoint(3).y = 0.0;
1988  Nodes.IntPoint(4).x = 0.66666666666666666667;
1989  Nodes.IntPoint(4).y = 0.0;
1990  Nodes.IntPoint(5).x = 0.66666666666666666667;
1991  Nodes.IntPoint(5).y = 0.33333333333333333333;
1992  Nodes.IntPoint(6).x = 0.33333333333333333333;
1993  Nodes.IntPoint(6).y = 0.66666666666666666667;
1994  Nodes.IntPoint(7).x = 0.0;
1995  Nodes.IntPoint(7).y = 0.66666666666666666667;
1996  Nodes.IntPoint(8).x = 0.0;
1997  Nodes.IntPoint(8).y = 0.33333333333333333333;
1998  Nodes.IntPoint(9).x = 0.33333333333333333333;
1999  Nodes.IntPoint(9).y = 0.33333333333333333333;
2000 }
2001 
2003  Vector &shape) const
2004 {
2005  double x = ip.x, y = ip.y;
2006  double l1 = (-1. + x + y),
2007  lx = (-1. + 3.*x),
2008  ly = (-1. + 3.*y);
2009 
2010  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
2011  shape(1) = 0.5*x*(lx - 1.)*lx;
2012  shape(2) = 0.5*y*(-1. + ly)*ly;
2013  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
2014  shape(4) = -4.5*x*lx*l1;
2015  shape(5) = 4.5*x*lx*y;
2016  shape(6) = 4.5*x*y*ly;
2017  shape(7) = -4.5*y*l1*ly;
2018  shape(8) = 4.5*y*l1*(1. + 3.*l1);
2019  shape(9) = -27.*x*y*l1;
2020 }
2021 
2023  DenseMatrix &dshape) const
2024 {
2025  double x = ip.x, y = ip.y;
2026 
2027  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2028  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
2029  dshape(2,0) = 0.;
2030  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
2031  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
2032  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
2033  dshape(6,0) = 4.5*y*(-1. + 3.*y);
2034  dshape(7,0) = 4.5*(1. - 3.*y)*y;
2035  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
2036  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
2037 
2038  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2039  dshape(1,1) = 0.;
2040  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
2041  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
2042  dshape(4,1) = 4.5*(1. - 3.*x)*x;
2043  dshape(5,1) = 4.5*x*(-1. + 3.*x);
2044  dshape(6,1) = 4.5*x*(-1. + 6.*y);
2045  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
2046  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
2047  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
2048 }
2049 
2051  DenseMatrix &h) const
2052 {
2053  double x = ip.x, y = ip.y;
2054 
2055  h(0,0) = 18.-27.*(x+y);
2056  h(0,1) = 18.-27.*(x+y);
2057  h(0,2) = 18.-27.*(x+y);
2058 
2059  h(1,0) = -9.+27.*x;
2060  h(1,1) = 0.;
2061  h(1,2) = 0.;
2062 
2063  h(2,0) = 0.;
2064  h(2,1) = 0.;
2065  h(2,2) = -9.+27.*y;
2066 
2067  h(3,0) = -45.+81.*x+54.*y;
2068  h(3,1) = -22.5+54.*x+27.*y;
2069  h(3,2) = 27.*x;
2070 
2071  h(4,0) = 36.-81.*x-27.*y;
2072  h(4,1) = 4.5-27.*x;
2073  h(4,2) = 0.;
2074 
2075  h(5,0) = 27.*y;
2076  h(5,1) = -4.5+27.*x;
2077  h(5,2) = 0.;
2078 
2079  h(6,0) = 0.;
2080  h(6,1) = -4.5+27.*y;
2081  h(6,2) = 27.*x;
2082 
2083  h(7,0) = 0.;
2084  h(7,1) = 4.5-27.*y;
2085  h(7,2) = 36.-27.*x-81.*y;
2086 
2087  h(8,0) = 27.*y;
2088  h(8,1) = -22.5+27.*x+54.*y;
2089  h(8,2) = -45.+54.*x+81.*y;
2090 
2091  h(9,0) = -54.*y;
2092  h(9,1) = 27.-54.*(x+y);
2093  h(9,2) = -54.*x;
2094 }
2095 
2096 
2098  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
2099 {
2100  Nodes.IntPoint(0).x = 0;
2101  Nodes.IntPoint(0).y = 0;
2102  Nodes.IntPoint(0).z = 0;
2103  Nodes.IntPoint(1).x = 1.;
2104  Nodes.IntPoint(1).y = 0;
2105  Nodes.IntPoint(1).z = 0;
2106  Nodes.IntPoint(2).x = 0;
2107  Nodes.IntPoint(2).y = 1.;
2108  Nodes.IntPoint(2).z = 0;
2109  Nodes.IntPoint(3).x = 0;
2110  Nodes.IntPoint(3).y = 0;
2111  Nodes.IntPoint(3).z = 1.;
2112  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
2113  Nodes.IntPoint(4).y = 0;
2114  Nodes.IntPoint(4).z = 0;
2115  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
2116  Nodes.IntPoint(5).y = 0;
2117  Nodes.IntPoint(5).z = 0;
2118  Nodes.IntPoint(6).x = 0;
2119  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
2120  Nodes.IntPoint(6).z = 0;
2121  Nodes.IntPoint(7).x = 0;
2122  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
2123  Nodes.IntPoint(7).z = 0;
2124  Nodes.IntPoint(8).x = 0;
2125  Nodes.IntPoint(8).y = 0;
2126  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
2127  Nodes.IntPoint(9).x = 0;
2128  Nodes.IntPoint(9).y = 0;
2129  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
2130  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
2131  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
2132  Nodes.IntPoint(10).z = 0;
2133  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
2134  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
2135  Nodes.IntPoint(11).z = 0;
2136  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
2137  Nodes.IntPoint(12).y = 0;
2138  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
2139  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
2140  Nodes.IntPoint(13).y = 0;
2141  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
2142  Nodes.IntPoint(14).x = 0;
2143  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
2144  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
2145  Nodes.IntPoint(15).x = 0;
2146  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
2147  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
2148  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
2149  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
2150  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
2151  Nodes.IntPoint(17).x = 0;
2152  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
2153  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
2154  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
2155  Nodes.IntPoint(18).y = 0;
2156  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
2157  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
2158  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
2159  Nodes.IntPoint(19).z = 0;
2160 }
2161 
2163  Vector &shape) const
2164 {
2165  double x = ip.x, y = ip.y, z = ip.z;
2166 
2167  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
2168  (-1 + 3*x + 3*y + 3*z))/2.;
2169  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2170  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
2171  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
2172  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2173  shape(19) = -27*x*y*(-1 + x + y + z);
2174  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
2175  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
2176  shape(11) = (9*x*y*(-1 + 3*y))/2.;
2177  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
2178  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2179  shape(18) = -27*x*z*(-1 + x + y + z);
2180  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
2181  shape(17) = -27*y*z*(-1 + x + y + z);
2182  shape(16) = 27*x*y*z;
2183  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
2184  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
2185  shape(13) = (9*x*z*(-1 + 3*z))/2.;
2186  shape(15) = (9*y*z*(-1 + 3*z))/2.;
2187  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
2188 }
2189 
2191  DenseMatrix &dshape) const
2192 {
2193  double x = ip.x, y = ip.y, z = ip.z;
2194 
2195  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2196  x*(-4 + 6*y + 6*z)))/2.;
2197  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2198  x*(-4 + 6*y + 6*z)))/2.;
2199  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2200  x*(-4 + 6*y + 6*z)))/2.;
2201  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
2202  2*x*(-5 + 6*y + 6*z)))/2.;
2203  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2204  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2205  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
2206  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
2207  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
2208  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
2209  dshape(1,1) = 0;
2210  dshape(1,2) = 0;
2211  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2212  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
2213  x*(-5 + 12*y + 6*z)))/2.;
2214  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2215  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
2216  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
2217  dshape(19,2) = -27*x*y;
2218  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
2219  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
2220  dshape(10,2) = 0;
2221  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
2222  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
2223  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
2224  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
2225  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
2226  dshape(11,2) = 0;
2227  dshape(2,0) = 0;
2228  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
2229  dshape(2,2) = 0;
2230  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2231  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2232  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
2233  x*(-5 + 6*y + 12*z)))/2.;
2234  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
2235  dshape(18,1) = -27*x*z;
2236  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
2237  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
2238  dshape(12,1) = 0;
2239  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
2240  dshape(17,0) = -27*y*z;
2241  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
2242  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
2243  dshape(16,0) = 27*y*z;
2244  dshape(16,1) = 27*x*z;
2245  dshape(16,2) = 27*x*y;
2246  dshape(14,0) = 0;
2247  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
2248  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
2249  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
2250  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
2251  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
2252  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
2253  dshape(13,1) = 0;
2254  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
2255  dshape(15,0) = 0;
2256  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
2257  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
2258  dshape(3,0) = 0;
2259  dshape(3,1) = 0;
2260  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
2261 }
2262 
2263 
2265  : NodalFiniteElement(2, Geometry::TRIANGLE , 1, 0)
2266 {
2267  Nodes.IntPoint(0).x = 0.333333333333333333;
2268  Nodes.IntPoint(0).y = 0.333333333333333333;
2269 }
2270 
2272  Vector &shape) const
2273 {
2274  shape(0) = 1.0;
2275 }
2276 
2278  DenseMatrix &dshape) const
2279 {
2280  dshape(0,0) = 0.0;
2281  dshape(0,1) = 0.0;
2282 }
2283 
2284 
2286  : NodalFiniteElement(2, Geometry::SQUARE , 1, 0, FunctionSpace::Qk)
2287 {
2288  Nodes.IntPoint(0).x = 0.5;
2289  Nodes.IntPoint(0).y = 0.5;
2290 }
2291 
2293  Vector &shape) const
2294 {
2295  shape(0) = 1.0;
2296 }
2297 
2299  DenseMatrix &dshape) const
2300 {
2301  dshape(0,0) = 0.0;
2302  dshape(0,1) = 0.0;
2303 }
2304 
2305 
2307  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
2308 {
2309  Nodes.IntPoint(0).x = 0.0;
2310  Nodes.IntPoint(0).y = 0.0;
2311  Nodes.IntPoint(0).z = 0.0;
2312  Nodes.IntPoint(1).x = 1.0;
2313  Nodes.IntPoint(1).y = 0.0;
2314  Nodes.IntPoint(1).z = 0.0;
2315  Nodes.IntPoint(2).x = 0.0;
2316  Nodes.IntPoint(2).y = 1.0;
2317  Nodes.IntPoint(2).z = 0.0;
2318  Nodes.IntPoint(3).x = 0.0;
2319  Nodes.IntPoint(3).y = 0.0;
2320  Nodes.IntPoint(3).z = 1.0;
2321 }
2322 
2324  Vector &shape) const
2325 {
2326  shape(0) = 1. - ip.x - ip.y - ip.z;
2327  shape(1) = ip.x;
2328  shape(2) = ip.y;
2329  shape(3) = ip.z;
2330 }
2331 
2333  DenseMatrix &dshape) const
2334 {
2335  if (dshape.Height() == 4)
2336  {
2337  double *A = &dshape(0,0);
2338  A[0] = -1.; A[4] = -1.; A[8] = -1.;
2339  A[1] = 1.; A[5] = 0.; A[9] = 0.;
2340  A[2] = 0.; A[6] = 1.; A[10] = 0.;
2341  A[3] = 0.; A[7] = 0.; A[11] = 1.;
2342  }
2343  else
2344  {
2345  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
2346  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
2347  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
2348  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
2349  }
2350 }
2351 
2352 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
2353 const
2354 {
2355  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
2356 
2357  *ndofs = 3;
2358  *dofs = face_dofs[face];
2359 }
2360 
2361 
2363  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
2364 {
2365  Nodes.IntPoint(0).x = 0.0;
2366  Nodes.IntPoint(0).y = 0.0;
2367  Nodes.IntPoint(0).z = 0.0;
2368  Nodes.IntPoint(1).x = 1.0;
2369  Nodes.IntPoint(1).y = 0.0;
2370  Nodes.IntPoint(1).z = 0.0;
2371  Nodes.IntPoint(2).x = 0.0;
2372  Nodes.IntPoint(2).y = 1.0;
2373  Nodes.IntPoint(2).z = 0.0;
2374  Nodes.IntPoint(3).x = 0.0;
2375  Nodes.IntPoint(3).y = 0.0;
2376  Nodes.IntPoint(3).z = 1.0;
2377  Nodes.IntPoint(4).x = 0.5;
2378  Nodes.IntPoint(4).y = 0.0;
2379  Nodes.IntPoint(4).z = 0.0;
2380  Nodes.IntPoint(5).x = 0.0;
2381  Nodes.IntPoint(5).y = 0.5;
2382  Nodes.IntPoint(5).z = 0.0;
2383  Nodes.IntPoint(6).x = 0.0;
2384  Nodes.IntPoint(6).y = 0.0;
2385  Nodes.IntPoint(6).z = 0.5;
2386  Nodes.IntPoint(7).x = 0.5;
2387  Nodes.IntPoint(7).y = 0.5;
2388  Nodes.IntPoint(7).z = 0.0;
2389  Nodes.IntPoint(8).x = 0.5;
2390  Nodes.IntPoint(8).y = 0.0;
2391  Nodes.IntPoint(8).z = 0.5;
2392  Nodes.IntPoint(9).x = 0.0;
2393  Nodes.IntPoint(9).y = 0.5;
2394  Nodes.IntPoint(9).z = 0.5;
2395 }
2396 
2398  Vector &shape) const
2399 {
2400  double L0, L1, L2, L3;
2401 
2402  L0 = 1. - ip.x - ip.y - ip.z;
2403  L1 = ip.x;
2404  L2 = ip.y;
2405  L3 = ip.z;
2406 
2407  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
2408  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
2409  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
2410  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
2411  shape(4) = 4.0 * L0 * L1;
2412  shape(5) = 4.0 * L0 * L2;
2413  shape(6) = 4.0 * L0 * L3;
2414  shape(7) = 4.0 * L1 * L2;
2415  shape(8) = 4.0 * L1 * L3;
2416  shape(9) = 4.0 * L2 * L3;
2417 }
2418 
2420  DenseMatrix &dshape) const
2421 {
2422  double x, y, z, L0;
2423 
2424  x = ip.x;
2425  y = ip.y;
2426  z = ip.z;
2427  L0 = 1.0 - x - y - z;
2428 
2429  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
2430  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
2431  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
2432  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
2433  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
2434  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
2435  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
2436  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
2437  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
2438  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
2439 }
2440 
2442  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
2443 {
2444  Nodes.IntPoint(0).x = 0.0;
2445  Nodes.IntPoint(0).y = 0.0;
2446  Nodes.IntPoint(0).z = 0.0;
2447 
2448  Nodes.IntPoint(1).x = 1.0;
2449  Nodes.IntPoint(1).y = 0.0;
2450  Nodes.IntPoint(1).z = 0.0;
2451 
2452  Nodes.IntPoint(2).x = 1.0;
2453  Nodes.IntPoint(2).y = 1.0;
2454  Nodes.IntPoint(2).z = 0.0;
2455 
2456  Nodes.IntPoint(3).x = 0.0;
2457  Nodes.IntPoint(3).y = 1.0;
2458  Nodes.IntPoint(3).z = 0.0;
2459 
2460  Nodes.IntPoint(4).x = 0.0;
2461  Nodes.IntPoint(4).y = 0.0;
2462  Nodes.IntPoint(4).z = 1.0;
2463 
2464  Nodes.IntPoint(5).x = 1.0;
2465  Nodes.IntPoint(5).y = 0.0;
2466  Nodes.IntPoint(5).z = 1.0;
2467 
2468  Nodes.IntPoint(6).x = 1.0;
2469  Nodes.IntPoint(6).y = 1.0;
2470  Nodes.IntPoint(6).z = 1.0;
2471 
2472  Nodes.IntPoint(7).x = 0.0;
2473  Nodes.IntPoint(7).y = 1.0;
2474  Nodes.IntPoint(7).z = 1.0;
2475 }
2476 
2478  Vector &shape) const
2479 {
2480  double x = ip.x, y = ip.y, z = ip.z;
2481  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2482 
2483  shape(0) = ox * oy * oz;
2484  shape(1) = x * oy * oz;
2485  shape(2) = x * y * oz;
2486  shape(3) = ox * y * oz;
2487  shape(4) = ox * oy * z;
2488  shape(5) = x * oy * z;
2489  shape(6) = x * y * z;
2490  shape(7) = ox * y * z;
2491 }
2492 
2494  DenseMatrix &dshape) const
2495 {
2496  double x = ip.x, y = ip.y, z = ip.z;
2497  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2498 
2499  dshape(0,0) = - oy * oz;
2500  dshape(0,1) = - ox * oz;
2501  dshape(0,2) = - ox * oy;
2502 
2503  dshape(1,0) = oy * oz;
2504  dshape(1,1) = - x * oz;
2505  dshape(1,2) = - x * oy;
2506 
2507  dshape(2,0) = y * oz;
2508  dshape(2,1) = x * oz;
2509  dshape(2,2) = - x * y;
2510 
2511  dshape(3,0) = - y * oz;
2512  dshape(3,1) = ox * oz;
2513  dshape(3,2) = - ox * y;
2514 
2515  dshape(4,0) = - oy * z;
2516  dshape(4,1) = - ox * z;
2517  dshape(4,2) = ox * oy;
2518 
2519  dshape(5,0) = oy * z;
2520  dshape(5,1) = - x * z;
2521  dshape(5,2) = x * oy;
2522 
2523  dshape(6,0) = y * z;
2524  dshape(6,1) = x * z;
2525  dshape(6,2) = x * y;
2526 
2527  dshape(7,0) = - y * z;
2528  dshape(7,1) = ox * z;
2529  dshape(7,2) = ox * y;
2530 }
2531 
2533  : NodalFiniteElement(1, Geometry::SEGMENT , 1, Ord) // defaul Ord = 0
2534 {
2535  Nodes.IntPoint(0).x = 0.5;
2536 }
2537 
2539  Vector &shape) const
2540 {
2541  shape(0) = 1.0;
2542 }
2543 
2545  DenseMatrix &dshape) const
2546 {
2547  dshape(0,0) = 0.0;
2548 }
2549 
2551  : NodalFiniteElement(2, Geometry::TRIANGLE , 3, 1)
2552 {
2553  Nodes.IntPoint(0).x = 0.5;
2554  Nodes.IntPoint(0).y = 0.0;
2555  Nodes.IntPoint(1).x = 0.5;
2556  Nodes.IntPoint(1).y = 0.5;
2557  Nodes.IntPoint(2).x = 0.0;
2558  Nodes.IntPoint(2).y = 0.5;
2559 }
2560 
2562  Vector &shape) const
2563 {
2564  shape(0) = 1.0 - 2.0 * ip.y;
2565  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
2566  shape(2) = 1.0 - 2.0 * ip.x;
2567 }
2568 
2570  DenseMatrix &dshape) const
2571 {
2572  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
2573  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
2574  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
2575 }
2576 
2578 // the FunctionSpace should be rotated (45 degrees) Q_1
2579 // i.e. the span of { 1, x, y, x^2 - y^2 }
2580  : NodalFiniteElement(2, Geometry::SQUARE , 4, 2, FunctionSpace::Qk)
2581 {
2582  Nodes.IntPoint(0).x = 0.5;
2583  Nodes.IntPoint(0).y = 0.0;
2584  Nodes.IntPoint(1).x = 1.0;
2585  Nodes.IntPoint(1).y = 0.5;
2586  Nodes.IntPoint(2).x = 0.5;
2587  Nodes.IntPoint(2).y = 1.0;
2588  Nodes.IntPoint(3).x = 0.0;
2589  Nodes.IntPoint(3).y = 0.5;
2590 }
2591 
2593  Vector &shape) const
2594 {
2595  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
2596 
2597  shape(0) = l2 * l3;
2598  shape(1) = l1 * l3;
2599  shape(2) = l1 * l4;
2600  shape(3) = l2 * l4;
2601 }
2602 
2604  DenseMatrix &dshape) const
2605 {
2606  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
2607 
2608  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
2609  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
2610  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
2611  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
2612 }
2613 
2614 
2616  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
2617 {
2618  Nodes.IntPoint(0).x = 0.5;
2619  Nodes.IntPoint(0).y = 0.0;
2620  Nodes.IntPoint(1).x = 0.5;
2621  Nodes.IntPoint(1).y = 0.5;
2622  Nodes.IntPoint(2).x = 0.0;
2623  Nodes.IntPoint(2).y = 0.5;
2624 }
2625 
2627  DenseMatrix &shape) const
2628 {
2629  double x = ip.x, y = ip.y;
2630 
2631  shape(0,0) = x;
2632  shape(0,1) = y - 1.;
2633  shape(1,0) = x;
2634  shape(1,1) = y;
2635  shape(2,0) = x - 1.;
2636  shape(2,1) = y;
2637 }
2638 
2640  Vector &divshape) const
2641 {
2642  divshape(0) = 2.;
2643  divshape(1) = 2.;
2644  divshape(2) = 2.;
2645 }
2646 
2647 const double RT0TriangleFiniteElement::nk[3][2] =
2648 { {0, -1}, {1, 1}, {-1, 0} };
2649 
2652 {
2653  int k, j;
2654 #ifdef MFEM_THREAD_SAFE
2656  DenseMatrix Jinv(Dim);
2657 #endif
2658 
2659 #ifdef MFEM_DEBUG
2660  for (k = 0; k < 3; k++)
2661  {
2663  for (j = 0; j < 3; j++)
2664  {
2665  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2666  if (j == k) { d -= 1.0; }
2667  if (fabs(d) > 1.0e-12)
2668  {
2669  mfem::err << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
2670  " k = " << k << ", j = " << j << ", d = " << d << endl;
2671  mfem_error();
2672  }
2673  }
2674  }
2675 #endif
2676 
2677  IntegrationPoint ip;
2678  ip.x = ip.y = 0.0;
2679  Trans.SetIntPoint (&ip);
2680  // Trans must be linear
2681  // set Jinv = |J| J^{-t} = adj(J)^t
2682  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2683  double vk[2];
2684  Vector xk (vk, 2);
2685 
2686  for (k = 0; k < 3; k++)
2687  {
2688  Trans.Transform (Nodes.IntPoint (k), xk);
2689  ip.x = vk[0]; ip.y = vk[1];
2690  CalcVShape (ip, vshape);
2691  // vk = |J| J^{-t} nk
2692  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2693  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2694  for (j = 0; j < 3; j++)
2695  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2696  {
2697  I(k,j) = 0.0;
2698  }
2699  }
2700 }
2701 
2704  Vector &dofs) const
2705 {
2706  double vk[2];
2707  Vector xk (vk, 2);
2708 #ifdef MFEM_THREAD_SAFE
2709  DenseMatrix Jinv(Dim);
2710 #endif
2711 
2712  for (int k = 0; k < 3; k++)
2713  {
2714  Trans.SetIntPoint (&Nodes.IntPoint (k));
2715  // set Jinv = |J| J^{-t} = adj(J)^t
2716  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2717 
2718  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2719  // xk^t |J| J^{-t} nk
2720  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2721  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2722  }
2723 }
2724 
2726  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
2727 {
2728  Nodes.IntPoint(0).x = 0.5;
2729  Nodes.IntPoint(0).y = 0.0;
2730  Nodes.IntPoint(1).x = 1.0;
2731  Nodes.IntPoint(1).y = 0.5;
2732  Nodes.IntPoint(2).x = 0.5;
2733  Nodes.IntPoint(2).y = 1.0;
2734  Nodes.IntPoint(3).x = 0.0;
2735  Nodes.IntPoint(3).y = 0.5;
2736 }
2737 
2739  DenseMatrix &shape) const
2740 {
2741  double x = ip.x, y = ip.y;
2742 
2743  shape(0,0) = 0;
2744  shape(0,1) = y - 1.;
2745  shape(1,0) = x;
2746  shape(1,1) = 0;
2747  shape(2,0) = 0;
2748  shape(2,1) = y;
2749  shape(3,0) = x - 1.;
2750  shape(3,1) = 0;
2751 }
2752 
2754  Vector &divshape) const
2755 {
2756  divshape(0) = 1.;
2757  divshape(1) = 1.;
2758  divshape(2) = 1.;
2759  divshape(3) = 1.;
2760 }
2761 
2762 const double RT0QuadFiniteElement::nk[4][2] =
2763 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
2764 
2767 {
2768  int k, j;
2769 #ifdef MFEM_THREAD_SAFE
2771  DenseMatrix Jinv(Dim);
2772 #endif
2773 
2774 #ifdef MFEM_DEBUG
2775  for (k = 0; k < 4; k++)
2776  {
2778  for (j = 0; j < 4; j++)
2779  {
2780  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2781  if (j == k) { d -= 1.0; }
2782  if (fabs(d) > 1.0e-12)
2783  {
2784  mfem::err << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
2785  " k = " << k << ", j = " << j << ", d = " << d << endl;
2786  mfem_error();
2787  }
2788  }
2789  }
2790 #endif
2791 
2792  IntegrationPoint ip;
2793  ip.x = ip.y = 0.0;
2794  Trans.SetIntPoint (&ip);
2795  // Trans must be linear (more to have embedding?)
2796  // set Jinv = |J| J^{-t} = adj(J)^t
2797  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2798  double vk[2];
2799  Vector xk (vk, 2);
2800 
2801  for (k = 0; k < 4; k++)
2802  {
2803  Trans.Transform (Nodes.IntPoint (k), xk);
2804  ip.x = vk[0]; ip.y = vk[1];
2805  CalcVShape (ip, vshape);
2806  // vk = |J| J^{-t} nk
2807  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2808  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2809  for (j = 0; j < 4; j++)
2810  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2811  {
2812  I(k,j) = 0.0;
2813  }
2814  }
2815 }
2816 
2819  Vector &dofs) const
2820 {
2821  double vk[2];
2822  Vector xk (vk, 2);
2823 #ifdef MFEM_THREAD_SAFE
2824  DenseMatrix Jinv(Dim);
2825 #endif
2826 
2827  for (int k = 0; k < 4; k++)
2828  {
2829  Trans.SetIntPoint (&Nodes.IntPoint (k));
2830  // set Jinv = |J| J^{-t} = adj(J)^t
2831  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2832 
2833  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2834  // xk^t |J| J^{-t} nk
2835  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2836  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2837  }
2838 }
2839 
2841  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
2842 {
2843  Nodes.IntPoint(0).x = 0.33333333333333333333;
2844  Nodes.IntPoint(0).y = 0.0;
2845  Nodes.IntPoint(1).x = 0.66666666666666666667;
2846  Nodes.IntPoint(1).y = 0.0;
2847  Nodes.IntPoint(2).x = 0.66666666666666666667;
2848  Nodes.IntPoint(2).y = 0.33333333333333333333;
2849  Nodes.IntPoint(3).x = 0.33333333333333333333;
2850  Nodes.IntPoint(3).y = 0.66666666666666666667;
2851  Nodes.IntPoint(4).x = 0.0;
2852  Nodes.IntPoint(4).y = 0.66666666666666666667;
2853  Nodes.IntPoint(5).x = 0.0;
2854  Nodes.IntPoint(5).y = 0.33333333333333333333;
2855  Nodes.IntPoint(6).x = 0.33333333333333333333;
2856  Nodes.IntPoint(6).y = 0.33333333333333333333;
2857  Nodes.IntPoint(7).x = 0.33333333333333333333;
2858  Nodes.IntPoint(7).y = 0.33333333333333333333;
2859 }
2860 
2862  DenseMatrix &shape) const
2863 {
2864  double x = ip.x, y = ip.y;
2865 
2866  shape(0,0) = -2 * x * (-1 + x + 2 * y);
2867  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
2868  shape(1,0) = 2 * x * (x - y);
2869  shape(1,1) = 2 * (x - y) * (-1 + y);
2870  shape(2,0) = 2 * x * (-1 + 2 * x + y);
2871  shape(2,1) = 2 * y * (-1 + 2 * x + y);
2872  shape(3,0) = 2 * x * (-1 + x + 2 * y);
2873  shape(3,1) = 2 * y * (-1 + x + 2 * y);
2874  shape(4,0) = -2 * (-1 + x) * (x - y);
2875  shape(4,1) = 2 * y * (-x + y);
2876  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
2877  shape(5,1) = -2 * y * (-1 + 2 * x + y);
2878  shape(6,0) = -3 * x * (-2 + 2 * x + y);
2879  shape(6,1) = -3 * y * (-1 + 2 * x + y);
2880  shape(7,0) = -3 * x * (-1 + x + 2 * y);
2881  shape(7,1) = -3 * y * (-2 + x + 2 * y);
2882 }
2883 
2885  Vector &divshape) const
2886 {
2887  double x = ip.x, y = ip.y;
2888 
2889  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
2890  divshape(1) = 2 + 6 * x - 6 * y;
2891  divshape(2) = -4 + 12 * x + 6 * y;
2892  divshape(3) = -4 + 6 * x + 12 * y;
2893  divshape(4) = 2 - 6 * x + 6 * y;
2894  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
2895  divshape(6) = -9 * (-1 + 2 * x + y);
2896  divshape(7) = -9 * (-1 + x + 2 * y);
2897 }
2898 
2899 const double RT1TriangleFiniteElement::nk[8][2] =
2900 {
2901  { 0,-1}, { 0,-1},
2902  { 1, 1}, { 1, 1},
2903  {-1, 0}, {-1, 0},
2904  { 1, 0}, { 0, 1}
2905 };
2906 
2909 {
2910  int k, j;
2911 #ifdef MFEM_THREAD_SAFE
2913  DenseMatrix Jinv(Dim);
2914 #endif
2915 
2916 #ifdef MFEM_DEBUG
2917  for (k = 0; k < 8; k++)
2918  {
2920  for (j = 0; j < 8; j++)
2921  {
2922  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2923  if (j == k) { d -= 1.0; }
2924  if (fabs(d) > 1.0e-12)
2925  {
2926  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
2927  " k = " << k << ", j = " << j << ", d = " << d << endl;
2928  mfem_error();
2929  }
2930  }
2931  }
2932 #endif
2933 
2934  IntegrationPoint ip;
2935  ip.x = ip.y = 0.0;
2936  Trans.SetIntPoint (&ip);
2937  // Trans must be linear (more to have embedding?)
2938  // set Jinv = |J| J^{-t} = adj(J)^t
2939  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2940  double vk[2];
2941  Vector xk (vk, 2);
2942 
2943  for (k = 0; k < 8; k++)
2944  {
2945  Trans.Transform (Nodes.IntPoint (k), xk);
2946  ip.x = vk[0]; ip.y = vk[1];
2947  CalcVShape (ip, vshape);
2948  // vk = |J| J^{-t} nk
2949  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2950  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2951  for (j = 0; j < 8; j++)
2952  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2953  {
2954  I(k,j) = 0.0;
2955  }
2956  }
2957 }
2958 
2961 {
2962  double vk[2];
2963  Vector xk (vk, 2);
2964 #ifdef MFEM_THREAD_SAFE
2965  DenseMatrix Jinv(Dim);
2966 #endif
2967 
2968  for (int k = 0; k < 8; k++)
2969  {
2970  Trans.SetIntPoint (&Nodes.IntPoint (k));
2971  // set Jinv = |J| J^{-t} = adj(J)^t
2972  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2973 
2974  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2975  // xk^t |J| J^{-t} nk
2976  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2977  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2978  dofs(k) *= 0.5;
2979  }
2980 }
2981 
2983  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
2984 {
2985  // y = 0
2986  Nodes.IntPoint(0).x = 1./3.;
2987  Nodes.IntPoint(0).y = 0.0;
2988  Nodes.IntPoint(1).x = 2./3.;
2989  Nodes.IntPoint(1).y = 0.0;
2990  // x = 1
2991  Nodes.IntPoint(2).x = 1.0;
2992  Nodes.IntPoint(2).y = 1./3.;
2993  Nodes.IntPoint(3).x = 1.0;
2994  Nodes.IntPoint(3).y = 2./3.;
2995  // y = 1
2996  Nodes.IntPoint(4).x = 2./3.;
2997  Nodes.IntPoint(4).y = 1.0;
2998  Nodes.IntPoint(5).x = 1./3.;
2999  Nodes.IntPoint(5).y = 1.0;
3000  // x = 0
3001  Nodes.IntPoint(6).x = 0.0;
3002  Nodes.IntPoint(6).y = 2./3.;
3003  Nodes.IntPoint(7).x = 0.0;
3004  Nodes.IntPoint(7).y = 1./3.;
3005  // x = 0.5 (interior)
3006  Nodes.IntPoint(8).x = 0.5;
3007  Nodes.IntPoint(8).y = 1./3.;
3008  Nodes.IntPoint(9).x = 0.5;
3009  Nodes.IntPoint(9).y = 2./3.;
3010  // y = 0.5 (interior)
3011  Nodes.IntPoint(10).x = 1./3.;
3012  Nodes.IntPoint(10).y = 0.5;
3013  Nodes.IntPoint(11).x = 2./3.;
3014  Nodes.IntPoint(11).y = 0.5;
3015 }
3016 
3018  DenseMatrix &shape) const
3019 {
3020  double x = ip.x, y = ip.y;
3021 
3022  // y = 0
3023  shape(0,0) = 0;
3024  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
3025  shape(1,0) = 0;
3026  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
3027  // x = 1
3028  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
3029  shape(2,1) = 0;
3030  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
3031  shape(3,1) = 0;
3032  // y = 1
3033  shape(4,0) = 0;
3034  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
3035  shape(5,0) = 0;
3036  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
3037  // x = 0
3038  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
3039  shape(6,1) = 0;
3040  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
3041  shape(7,1) = 0;
3042  // x = 0.5 (interior)
3043  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
3044  shape(8,1) = 0;
3045  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
3046  shape(9,1) = 0;
3047  // y = 0.5 (interior)
3048  shape(10,0) = 0;
3049  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
3050  shape(11,0) = 0;
3051  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
3052 }
3053 
3055  Vector &divshape) const
3056 {
3057  double x = ip.x, y = ip.y;
3058 
3059  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
3060  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
3061  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
3062  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
3063  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
3064  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
3065  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
3066  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
3067  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
3068  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
3069  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
3070  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
3071 }
3072 
3073 const double RT1QuadFiniteElement::nk[12][2] =
3074 {
3075  // y = 0
3076  {0,-1}, {0,-1},
3077  // X = 1
3078  {1, 0}, {1, 0},
3079  // y = 1
3080  {0, 1}, {0, 1},
3081  // x = 0
3082  {-1,0}, {-1,0},
3083  // x = 0.5 (interior)
3084  {1, 0}, {1, 0},
3085  // y = 0.5 (interior)
3086  {0, 1}, {0, 1}
3087 };
3088 
3091 {
3092  int k, j;
3093 #ifdef MFEM_THREAD_SAFE
3095  DenseMatrix Jinv(Dim);
3096 #endif
3097 
3098 #ifdef MFEM_DEBUG
3099  for (k = 0; k < 12; k++)
3100  {
3102  for (j = 0; j < 12; j++)
3103  {
3104  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3105  if (j == k) { d -= 1.0; }
3106  if (fabs(d) > 1.0e-12)
3107  {
3108  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3109  " k = " << k << ", j = " << j << ", d = " << d << endl;
3110  mfem_error();
3111  }
3112  }
3113  }
3114 #endif
3115 
3116  IntegrationPoint ip;
3117  ip.x = ip.y = 0.0;
3118  Trans.SetIntPoint (&ip);
3119  // Trans must be linear (more to have embedding?)
3120  // set Jinv = |J| J^{-t} = adj(J)^t
3121  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3122  double vk[2];
3123  Vector xk (vk, 2);
3124 
3125  for (k = 0; k < 12; k++)
3126  {
3127  Trans.Transform (Nodes.IntPoint (k), xk);
3128  ip.x = vk[0]; ip.y = vk[1];
3129  CalcVShape (ip, vshape);
3130  // vk = |J| J^{-t} nk
3131  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3132  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3133  for (j = 0; j < 12; j++)
3134  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3135  {
3136  I(k,j) = 0.0;
3137  }
3138  }
3139 }
3140 
3143 {
3144  double vk[2];
3145  Vector xk (vk, 2);
3146 #ifdef MFEM_THREAD_SAFE
3147  DenseMatrix Jinv(Dim);
3148 #endif
3149 
3150  for (int k = 0; k < 12; k++)
3151  {
3152  Trans.SetIntPoint (&Nodes.IntPoint (k));
3153  // set Jinv = |J| J^{-t} = adj(J)^t
3154  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3155 
3156  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3157  // xk^t |J| J^{-t} nk
3158  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3159  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3160  }
3161 }
3162 
3163 const double RT2TriangleFiniteElement::M[15][15] =
3164 {
3165  {
3166  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
3167  0, 24.442740046346700787, -16.647580015448900262, -12.,
3168  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
3169  12., 30.590320061795601049, 15.295160030897800524
3170  },
3171  {
3172  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
3173  -15., 10.5
3174  },
3175  {
3176  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
3177  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
3178  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
3179  12., -6.5903200617956010489, -3.2951600308978005244
3180  },
3181  {
3182  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
3183  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
3184  0, -3.2951600308978005244
3185  },
3186  {
3187  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
3188  36., 10.5
3189  },
3190  {
3191  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
3192  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
3193  0, 15.295160030897800524
3194  },
3195  {
3196  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
3197  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
3198  -0.76209992275549868892, 4.1189500386222506555, -12.,
3199  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
3200  12.
3201  },
3202  {
3203  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
3204  -15., -15.
3205  },
3206  {
3207  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
3208  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
3209  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
3210  30.590320061795601049, 12.
3211  },
3212  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
3213  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
3214  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
3215  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
3216  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
3217  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
3218 };
3219 
3221  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
3222 {
3223  const double p = 0.11270166537925831148;
3224 
3225  Nodes.IntPoint(0).x = p;
3226  Nodes.IntPoint(0).y = 0.0;
3227  Nodes.IntPoint(1).x = 0.5;
3228  Nodes.IntPoint(1).y = 0.0;
3229  Nodes.IntPoint(2).x = 1.-p;
3230  Nodes.IntPoint(2).y = 0.0;
3231  Nodes.IntPoint(3).x = 1.-p;
3232  Nodes.IntPoint(3).y = p;
3233  Nodes.IntPoint(4).x = 0.5;
3234  Nodes.IntPoint(4).y = 0.5;
3235  Nodes.IntPoint(5).x = p;
3236  Nodes.IntPoint(5).y = 1.-p;
3237  Nodes.IntPoint(6).x = 0.0;
3238  Nodes.IntPoint(6).y = 1.-p;
3239  Nodes.IntPoint(7).x = 0.0;
3240  Nodes.IntPoint(7).y = 0.5;
3241  Nodes.IntPoint(8).x = 0.0;
3242  Nodes.IntPoint(8).y = p;
3243  Nodes.IntPoint(9).x = 0.25;
3244  Nodes.IntPoint(9).y = 0.25;
3245  Nodes.IntPoint(10).x = 0.25;
3246  Nodes.IntPoint(10).y = 0.25;
3247  Nodes.IntPoint(11).x = 0.5;
3248  Nodes.IntPoint(11).y = 0.25;
3249  Nodes.IntPoint(12).x = 0.5;
3250  Nodes.IntPoint(12).y = 0.25;
3251  Nodes.IntPoint(13).x = 0.25;
3252  Nodes.IntPoint(13).y = 0.5;
3253  Nodes.IntPoint(14).x = 0.25;
3254  Nodes.IntPoint(14).y = 0.5;
3255 }
3256 
3258  DenseMatrix &shape) const
3259 {
3260  double x = ip.x, y = ip.y;
3261 
3262  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
3263  x*x*y, x*y*y
3264  };
3265  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
3266  x*x*y, x*y*y, y*y*y
3267  };
3268 
3269  for (int i = 0; i < 15; i++)
3270  {
3271  double cx = 0.0, cy = 0.0;
3272  for (int j = 0; j < 15; j++)
3273  {
3274  cx += M[i][j] * Bx[j];
3275  cy += M[i][j] * By[j];
3276  }
3277  shape(i,0) = cx;
3278  shape(i,1) = cy;
3279  }
3280 }
3281 
3283  Vector &divshape) const
3284 {
3285  double x = ip.x, y = ip.y;
3286 
3287  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
3288  4.*x*x, 4.*x*y, 4.*y*y
3289  };
3290 
3291  for (int i = 0; i < 15; i++)
3292  {
3293  double div = 0.0;
3294  for (int j = 0; j < 15; j++)
3295  {
3296  div += M[i][j] * DivB[j];
3297  }
3298  divshape(i) = div;
3299  }
3300 }
3301 
3302 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
3303 
3304 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
3305 
3307  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
3308 {
3309  // y = 0 (pt[0])
3310  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
3311  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
3312  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
3313  // x = 1 (pt[3])
3314  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
3315  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
3316  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
3317  // y = 1 (pt[3])
3318  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
3319  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
3320  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
3321  // x = 0 (pt[0])
3322  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
3323  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
3324  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
3325  // x = pt[1] (interior)
3326  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
3327  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
3328  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
3329  // x = pt[2] (interior)
3330  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
3331  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
3332  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
3333  // y = pt[1] (interior)
3334  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
3335  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
3336  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
3337  // y = pt[2] (interior)
3338  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
3339  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
3340  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
3341 }
3342 
3344  DenseMatrix &shape) const
3345 {
3346  double x = ip.x, y = ip.y;
3347 
3348  double ax0 = pt[0] - x;
3349  double ax1 = pt[1] - x;
3350  double ax2 = pt[2] - x;
3351  double ax3 = pt[3] - x;
3352 
3353  double by0 = dpt[0] - y;
3354  double by1 = dpt[1] - y;
3355  double by2 = dpt[2] - y;
3356 
3357  double ay0 = pt[0] - y;
3358  double ay1 = pt[1] - y;
3359  double ay2 = pt[2] - y;
3360  double ay3 = pt[3] - y;
3361 
3362  double bx0 = dpt[0] - x;
3363  double bx1 = dpt[1] - x;
3364  double bx2 = dpt[2] - x;
3365 
3366  double A01 = pt[0] - pt[1];
3367  double A02 = pt[0] - pt[2];
3368  double A12 = pt[1] - pt[2];
3369  double A03 = pt[0] - pt[3];
3370  double A13 = pt[1] - pt[3];
3371  double A23 = pt[2] - pt[3];
3372 
3373  double B01 = dpt[0] - dpt[1];
3374  double B02 = dpt[0] - dpt[2];
3375  double B12 = dpt[1] - dpt[2];
3376 
3377  double tx0 = (bx1*bx2)/(B01*B02);
3378  double tx1 = -(bx0*bx2)/(B01*B12);
3379  double tx2 = (bx0*bx1)/(B02*B12);
3380 
3381  double ty0 = (by1*by2)/(B01*B02);
3382  double ty1 = -(by0*by2)/(B01*B12);
3383  double ty2 = (by0*by1)/(B02*B12);
3384 
3385  // y = 0 (p[0])
3386  shape(0, 0) = 0;
3387  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
3388  shape(1, 0) = 0;
3389  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
3390  shape(2, 0) = 0;
3391  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
3392  // x = 1 (p[3])
3393  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
3394  shape(3, 1) = 0;
3395  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
3396  shape(4, 1) = 0;
3397  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
3398  shape(5, 1) = 0;
3399  // y = 1 (p[3])
3400  shape(6, 0) = 0;
3401  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
3402  shape(7, 0) = 0;
3403  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
3404  shape(8, 0) = 0;
3405  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
3406  // x = 0 (p[0])
3407  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
3408  shape(9, 1) = 0;
3409  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
3410  shape(10, 1) = 0;
3411  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
3412  shape(11, 1) = 0;
3413  // x = p[1] (interior)
3414  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
3415  shape(12, 1) = 0;
3416  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
3417  shape(13, 1) = 0;
3418  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
3419  shape(14, 1) = 0;
3420  // x = p[2] (interior)
3421  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
3422  shape(15, 1) = 0;
3423  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
3424  shape(16, 1) = 0;
3425  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
3426  shape(17, 1) = 0;
3427  // y = p[1] (interior)
3428  shape(18, 0) = 0;
3429  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
3430  shape(19, 0) = 0;
3431  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
3432  shape(20, 0) = 0;
3433  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
3434  // y = p[2] (interior)
3435  shape(21, 0) = 0;
3436  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
3437  shape(22, 0) = 0;
3438  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
3439  shape(23, 0) = 0;
3440  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
3441 }
3442 
3444  Vector &divshape) const
3445 {
3446  double x = ip.x, y = ip.y;
3447 
3448  double a01 = pt[0]*pt[1];
3449  double a02 = pt[0]*pt[2];
3450  double a12 = pt[1]*pt[2];
3451  double a03 = pt[0]*pt[3];
3452  double a13 = pt[1]*pt[3];
3453  double a23 = pt[2]*pt[3];
3454 
3455  double bx0 = dpt[0] - x;
3456  double bx1 = dpt[1] - x;
3457  double bx2 = dpt[2] - x;
3458 
3459  double by0 = dpt[0] - y;
3460  double by1 = dpt[1] - y;
3461  double by2 = dpt[2] - y;
3462 
3463  double A01 = pt[0] - pt[1];
3464  double A02 = pt[0] - pt[2];
3465  double A12 = pt[1] - pt[2];
3466  double A03 = pt[0] - pt[3];
3467  double A13 = pt[1] - pt[3];
3468  double A23 = pt[2] - pt[3];
3469 
3470  double A012 = pt[0] + pt[1] + pt[2];
3471  double A013 = pt[0] + pt[1] + pt[3];
3472  double A023 = pt[0] + pt[2] + pt[3];
3473  double A123 = pt[1] + pt[2] + pt[3];
3474 
3475  double B01 = dpt[0] - dpt[1];
3476  double B02 = dpt[0] - dpt[2];
3477  double B12 = dpt[1] - dpt[2];
3478 
3479  double tx0 = (bx1*bx2)/(B01*B02);
3480  double tx1 = -(bx0*bx2)/(B01*B12);
3481  double tx2 = (bx0*bx1)/(B02*B12);
3482 
3483  double ty0 = (by1*by2)/(B01*B02);
3484  double ty1 = -(by0*by2)/(B01*B12);
3485  double ty2 = (by0*by1)/(B02*B12);
3486 
3487  // y = 0 (p[0])
3488  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
3489  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
3490  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
3491  // x = 1 (p[3])
3492  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
3493  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
3494  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
3495  // y = 1 (p[3])
3496  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
3497  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
3498  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
3499  // x = 0 (p[0])
3500  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
3501  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
3502  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
3503  // x = p[1] (interior)
3504  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
3505  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
3506  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
3507  // x = p[2] (interior)
3508  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
3509  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
3510  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
3511  // y = p[1] (interior)
3512  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
3513  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
3514  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
3515  // y = p[2] (interior)
3516  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
3517  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
3518  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
3519 }
3520 
3521 const double RT2QuadFiniteElement::nk[24][2] =
3522 {
3523  // y = 0
3524  {0,-1}, {0,-1}, {0,-1},
3525  // x = 1
3526  {1, 0}, {1, 0}, {1, 0},
3527  // y = 1
3528  {0, 1}, {0, 1}, {0, 1},
3529  // x = 0
3530  {-1,0}, {-1,0}, {-1,0},
3531  // x = p[1] (interior)
3532  {1, 0}, {1, 0}, {1, 0},
3533  // x = p[2] (interior)
3534  {1, 0}, {1, 0}, {1, 0},
3535  // y = p[1] (interior)
3536  {0, 1}, {0, 1}, {0, 1},
3537  // y = p[1] (interior)
3538  {0, 1}, {0, 1}, {0, 1}
3539 };
3540 
3543 {
3544  int k, j;
3545 #ifdef MFEM_THREAD_SAFE
3547  DenseMatrix Jinv(Dim);
3548 #endif
3549 
3550 #ifdef MFEM_DEBUG
3551  for (k = 0; k < 24; k++)
3552  {
3554  for (j = 0; j < 24; j++)
3555  {
3556  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3557  if (j == k) { d -= 1.0; }
3558  if (fabs(d) > 1.0e-12)
3559  {
3560  mfem::err << "RT2QuadFiniteElement::GetLocalInterpolation (...)\n"
3561  " k = " << k << ", j = " << j << ", d = " << d << endl;
3562  mfem_error();
3563  }
3564  }
3565  }
3566 #endif
3567 
3568  IntegrationPoint ip;
3569  ip.x = ip.y = 0.0;
3570  Trans.SetIntPoint (&ip);
3571  // Trans must be linear (more to have embedding?)
3572  // set Jinv = |J| J^{-t} = adj(J)^t
3573  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3574  double vk[2];
3575  Vector xk (vk, 2);
3576 
3577  for (k = 0; k < 24; k++)
3578  {
3579  Trans.Transform (Nodes.IntPoint (k), xk);
3580  ip.x = vk[0]; ip.y = vk[1];
3581  CalcVShape (ip, vshape);
3582  // vk = |J| J^{-t} nk
3583  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3584  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3585  for (j = 0; j < 24; j++)
3586  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3587  {
3588  I(k,j) = 0.0;
3589  }
3590  }
3591 }
3592 
3595 {
3596  double vk[2];
3597  Vector xk (vk, 2);
3598 #ifdef MFEM_THREAD_SAFE
3599  DenseMatrix Jinv(Dim);
3600 #endif
3601 
3602  for (int k = 0; k < 24; k++)
3603  {
3604  Trans.SetIntPoint (&Nodes.IntPoint (k));
3605  // set Jinv = |J| J^{-t} = adj(J)^t
3606  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3607 
3608  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3609  // xk^t |J| J^{-t} nk
3610  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3611  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3612  }
3613 }
3614 
3616  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
3617 {
3618  Nodes.IntPoint(0).x = 0.33333333333333333333;
3619  Nodes.IntPoint(1).x = 0.66666666666666666667;
3620 }
3621 
3623  Vector &shape) const
3624 {
3625  double x = ip.x;
3626 
3627  shape(0) = 2. - 3. * x;
3628  shape(1) = 3. * x - 1.;
3629 }
3630 
3632  DenseMatrix &dshape) const
3633 {
3634  dshape(0,0) = -3.;
3635  dshape(1,0) = 3.;
3636 }
3637 
3638 
3640  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
3641 {
3642  const double p = 0.11270166537925831148;
3643 
3644  Nodes.IntPoint(0).x = p;
3645  Nodes.IntPoint(1).x = 0.5;
3646  Nodes.IntPoint(2).x = 1.-p;
3647 }
3648 
3650  Vector &shape) const
3651 {
3652  const double p = 0.11270166537925831148;
3653  const double w = 1./((1-2*p)*(1-2*p));
3654  double x = ip.x;
3655 
3656  shape(0) = (2*x-1)*(x-1+p)*w;
3657  shape(1) = 4*(x-1+p)*(p-x)*w;
3658  shape(2) = (2*x-1)*(x-p)*w;
3659 }
3660 
3662  DenseMatrix &dshape) const
3663 {
3664  const double p = 0.11270166537925831148;
3665  const double w = 1./((1-2*p)*(1-2*p));
3666  double x = ip.x;
3667 
3668  dshape(0,0) = (-3+4*x+2*p)*w;
3669  dshape(1,0) = (4-8*x)*w;
3670  dshape(2,0) = (-1+4*x-2*p)*w;
3671 }
3672 
3673 
3675  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
3676 {
3677  int i, m = degree;
3678 
3679  Nodes.IntPoint(0).x = 0.0;
3680  Nodes.IntPoint(1).x = 1.0;
3681  for (i = 1; i < m; i++)
3682  {
3683  Nodes.IntPoint(i+1).x = double(i) / m;
3684  }
3685 
3686  rwk.SetSize(degree+1);
3687 #ifndef MFEM_THREAD_SAFE
3688  rxxk.SetSize(degree+1);
3689 #endif
3690 
3691  rwk(0) = 1.0;
3692  for (i = 1; i <= m; i++)
3693  {
3694  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
3695  }
3696  for (i = 0; i < m/2+1; i++)
3697  {
3698  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
3699  }
3700  for (i = m-1; i >= 0; i -= 2)
3701  {
3702  rwk(i) = -rwk(i);
3703  }
3704 }
3705 
3707  Vector &shape) const
3708 {
3709  double w, wk, x = ip.x;
3710  int i, k, m = GetOrder();
3711 
3712 #ifdef MFEM_THREAD_SAFE
3713  Vector rxxk(m+1);
3714 #endif
3715 
3716  k = (int) floor ( m * x + 0.5 );
3717  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
3718 
3719  wk = 1.0;
3720  for (i = 0; i <= m; i++)
3721  if (i != k)
3722  {
3723  wk *= ( rxxk(i) = x - (double)(i) / m );
3724  }
3725  w = wk * ( rxxk(k) = x - (double)(k) / m );
3726 
3727  if (k != 0)
3728  {
3729  shape(0) = w * rwk(0) / rxxk(0);
3730  }
3731  else
3732  {
3733  shape(0) = wk * rwk(0);
3734  }
3735  if (k != m)
3736  {
3737  shape(1) = w * rwk(m) / rxxk(m);
3738  }
3739  else
3740  {
3741  shape(1) = wk * rwk(k);
3742  }
3743  for (i = 1; i < m; i++)
3744  if (i != k)
3745  {
3746  shape(i+1) = w * rwk(i) / rxxk(i);
3747  }
3748  else
3749  {
3750  shape(k+1) = wk * rwk(k);
3751  }
3752 }
3753 
3755  DenseMatrix &dshape) const
3756 {
3757  double s, srx, w, wk, x = ip.x;
3758  int i, k, m = GetOrder();
3759 
3760 #ifdef MFEM_THREAD_SAFE
3761  Vector rxxk(m+1);
3762 #endif
3763 
3764  k = (int) floor ( m * x + 0.5 );
3765  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
3766 
3767  wk = 1.0;
3768  for (i = 0; i <= m; i++)
3769  if (i != k)
3770  {
3771  wk *= ( rxxk(i) = x - (double)(i) / m );
3772  }
3773  w = wk * ( rxxk(k) = x - (double)(k) / m );
3774 
3775  for (i = 0; i <= m; i++)
3776  {
3777  rxxk(i) = 1.0 / rxxk(i);
3778  }
3779  srx = 0.0;
3780  for (i = 0; i <= m; i++)
3781  if (i != k)
3782  {
3783  srx += rxxk(i);
3784  }
3785  s = w * srx + wk;
3786 
3787  if (k != 0)
3788  {
3789  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
3790  }
3791  else
3792  {
3793  dshape(0,0) = wk * srx * rwk(0);
3794  }
3795  if (k != m)
3796  {
3797  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
3798  }
3799  else
3800  {
3801  dshape(1,0) = wk * srx * rwk(k);
3802  }
3803  for (i = 1; i < m; i++)
3804  if (i != k)
3805  {
3806  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
3807  }
3808  else
3809  {
3810  dshape(k+1,0) = wk * srx * rwk(k);
3811  }
3812 }
3813 
3814 
3816  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
3817 {
3818  Nodes.IntPoint(0).x = 0.33333333333333333333;
3819  Nodes.IntPoint(0).y = 0.33333333333333333333;
3820  Nodes.IntPoint(0).z = 0.33333333333333333333;
3821 
3822  Nodes.IntPoint(1).x = 0.0;
3823  Nodes.IntPoint(1).y = 0.33333333333333333333;
3824  Nodes.IntPoint(1).z = 0.33333333333333333333;
3825 
3826  Nodes.IntPoint(2).x = 0.33333333333333333333;
3827  Nodes.IntPoint(2).y = 0.0;
3828  Nodes.IntPoint(2).z = 0.33333333333333333333;
3829 
3830  Nodes.IntPoint(3).x = 0.33333333333333333333;
3831  Nodes.IntPoint(3).y = 0.33333333333333333333;
3832  Nodes.IntPoint(3).z = 0.0;
3833 
3834 }
3835 
3837  Vector &shape) const
3838 {
3839  double L0, L1, L2, L3;
3840 
3841  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
3842  shape(0) = 1.0 - 3.0 * L0;
3843  shape(1) = 1.0 - 3.0 * L1;
3844  shape(2) = 1.0 - 3.0 * L2;
3845  shape(3) = 1.0 - 3.0 * L3;
3846 }
3847 
3849  DenseMatrix &dshape) const
3850 {
3851  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
3852  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
3853  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
3854  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
3855 }
3856 
3857 
3859  : NodalFiniteElement(3, Geometry::TETRAHEDRON , 1, 0)
3860 {
3861  Nodes.IntPoint(0).x = 0.25;
3862  Nodes.IntPoint(0).y = 0.25;
3863  Nodes.IntPoint(0).z = 0.25;
3864 }
3865 
3867  Vector &shape) const
3868 {
3869  shape(0) = 1.0;
3870 }
3871 
3873  DenseMatrix &dshape) const
3874 {
3875  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3876 }
3877 
3878 
3880  : NodalFiniteElement(3, Geometry::CUBE, 1, 0, FunctionSpace::Qk)
3881 {
3882  Nodes.IntPoint(0).x = 0.5;
3883  Nodes.IntPoint(0).y = 0.5;
3884  Nodes.IntPoint(0).z = 0.5;
3885 }
3886 
3888  Vector &shape) const
3889 {
3890  shape(0) = 1.0;
3891 }
3892 
3894  DenseMatrix &dshape) const
3895 {
3896  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3897 }
3898 
3899 
3901  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
3902  degree, FunctionSpace::Qk)
3903 {
3904  if (degree == 2)
3905  {
3906  I = new int[Dof];
3907  J = new int[Dof];
3908  K = new int[Dof];
3909  // nodes
3910  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3911  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3912  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3913  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3914  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3915  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3916  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3917  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3918  // edges
3919  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3920  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
3921  I[10] = 2; J[10] = 1; K[10] = 0;
3922  I[11] = 0; J[11] = 2; K[11] = 0;
3923  I[12] = 2; J[12] = 0; K[12] = 1;
3924  I[13] = 1; J[13] = 2; K[13] = 1;
3925  I[14] = 2; J[14] = 1; K[14] = 1;
3926  I[15] = 0; J[15] = 2; K[15] = 1;
3927  I[16] = 0; J[16] = 0; K[16] = 2;
3928  I[17] = 1; J[17] = 0; K[17] = 2;
3929  I[18] = 1; J[18] = 1; K[18] = 2;
3930  I[19] = 0; J[19] = 1; K[19] = 2;
3931  // faces
3932  I[20] = 2; J[20] = 2; K[20] = 0;
3933  I[21] = 2; J[21] = 0; K[21] = 2;
3934  I[22] = 1; J[22] = 2; K[22] = 2;
3935  I[23] = 2; J[23] = 1; K[23] = 2;
3936  I[24] = 0; J[24] = 2; K[24] = 2;
3937  I[25] = 2; J[25] = 2; K[25] = 1;
3938  // element
3939  I[26] = 2; J[26] = 2; K[26] = 2;
3940  }
3941  else if (degree == 3)
3942  {
3943  I = new int[Dof];
3944  J = new int[Dof];
3945  K = new int[Dof];
3946  // nodes
3947  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3948  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3949  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3950  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3951  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3952  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3953  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3954  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3955  // edges
3956  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3957  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
3958  I[10] = 1; J[10] = 2; K[10] = 0;
3959  I[11] = 1; J[11] = 3; K[11] = 0;
3960  I[12] = 2; J[12] = 1; K[12] = 0;
3961  I[13] = 3; J[13] = 1; K[13] = 0;
3962  I[14] = 0; J[14] = 2; K[14] = 0;
3963  I[15] = 0; J[15] = 3; K[15] = 0;
3964  I[16] = 2; J[16] = 0; K[16] = 1;
3965  I[17] = 3; J[17] = 0; K[17] = 1;
3966  I[18] = 1; J[18] = 2; K[18] = 1;
3967  I[19] = 1; J[19] = 3; K[19] = 1;
3968  I[20] = 2; J[20] = 1; K[20] = 1;
3969  I[21] = 3; J[21] = 1; K[21] = 1;
3970  I[22] = 0; J[22] = 2; K[22] = 1;
3971  I[23] = 0; J[23] = 3; K[23] = 1;
3972  I[24] = 0; J[24] = 0; K[24] = 2;
3973  I[25] = 0; J[25] = 0; K[25] = 3;
3974  I[26] = 1; J[26] = 0; K[26] = 2;
3975  I[27] = 1; J[27] = 0; K[27] = 3;
3976  I[28] = 1; J[28] = 1; K[28] = 2;
3977  I[29] = 1; J[29] = 1; K[29] = 3;
3978  I[30] = 0; J[30] = 1; K[30] = 2;
3979  I[31] = 0; J[31] = 1; K[31] = 3;
3980  // faces
3981  I[32] = 2; J[32] = 3; K[32] = 0;
3982  I[33] = 3; J[33] = 3; K[33] = 0;
3983  I[34] = 2; J[34] = 2; K[34] = 0;
3984  I[35] = 3; J[35] = 2; K[35] = 0;
3985  I[36] = 2; J[36] = 0; K[36] = 2;
3986  I[37] = 3; J[37] = 0; K[37] = 2;
3987  I[38] = 2; J[38] = 0; K[38] = 3;
3988  I[39] = 3; J[39] = 0; K[39] = 3;
3989  I[40] = 1; J[40] = 2; K[40] = 2;
3990  I[41] = 1; J[41] = 3; K[41] = 2;
3991  I[42] = 1; J[42] = 2; K[42] = 3;
3992  I[43] = 1; J[43] = 3; K[43] = 3;
3993  I[44] = 3; J[44] = 1; K[44] = 2;
3994  I[45] = 2; J[45] = 1; K[45] = 2;
3995  I[46] = 3; J[46] = 1; K[46] = 3;
3996  I[47] = 2; J[47] = 1; K[47] = 3;
3997  I[48] = 0; J[48] = 3; K[48] = 2;
3998  I[49] = 0; J[49] = 2; K[49] = 2;
3999  I[50] = 0; J[50] = 3; K[50] = 3;
4000  I[51] = 0; J[51] = 2; K[51] = 3;
4001  I[52] = 2; J[52] = 2; K[52] = 1;
4002  I[53] = 3; J[53] = 2; K[53] = 1;
4003  I[54] = 2; J[54] = 3; K[54] = 1;
4004  I[55] = 3; J[55] = 3; K[55] = 1;
4005  // element
4006  I[56] = 2; J[56] = 2; K[56] = 2;
4007  I[57] = 3; J[57] = 2; K[57] = 2;
4008  I[58] = 3; J[58] = 3; K[58] = 2;
4009  I[59] = 2; J[59] = 3; K[59] = 2;
4010  I[60] = 2; J[60] = 2; K[60] = 3;
4011  I[61] = 3; J[61] = 2; K[61] = 3;
4012  I[62] = 3; J[62] = 3; K[62] = 3;
4013  I[63] = 2; J[63] = 3; K[63] = 3;
4014  }
4015  else
4016  {
4017  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
4018  }
4019 
4020  fe1d = new Lagrange1DFiniteElement(degree);
4021  dof1d = fe1d -> GetDof();
4022 
4023 #ifndef MFEM_THREAD_SAFE
4024  shape1dx.SetSize(dof1d);
4025  shape1dy.SetSize(dof1d);
4026  shape1dz.SetSize(dof1d);
4027 
4028  dshape1dx.SetSize(dof1d,1);
4029  dshape1dy.SetSize(dof1d,1);
4030  dshape1dz.SetSize(dof1d,1);
4031 #endif
4032 
4033  for (int n = 0; n < Dof; n++)
4034  {
4035  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
4036  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
4037  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
4038  }
4039 }
4040 
4042  Vector &shape) const
4043 {
4044  IntegrationPoint ipy, ipz;
4045  ipy.x = ip.y;
4046  ipz.x = ip.z;
4047 
4048 #ifdef MFEM_THREAD_SAFE
4049  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4050 #endif
4051 
4052  fe1d -> CalcShape(ip, shape1dx);
4053  fe1d -> CalcShape(ipy, shape1dy);
4054  fe1d -> CalcShape(ipz, shape1dz);
4055 
4056  for (int n = 0; n < Dof; n++)
4057  {
4058  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
4059  }
4060 }
4061 
4063  DenseMatrix &dshape) const
4064 {
4065  IntegrationPoint ipy, ipz;
4066  ipy.x = ip.y;
4067  ipz.x = ip.z;
4068 
4069 #ifdef MFEM_THREAD_SAFE
4070  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4071  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
4072 #endif
4073 
4074  fe1d -> CalcShape(ip, shape1dx);
4075  fe1d -> CalcShape(ipy, shape1dy);
4076  fe1d -> CalcShape(ipz, shape1dz);
4077 
4078  fe1d -> CalcDShape(ip, dshape1dx);
4079  fe1d -> CalcDShape(ipy, dshape1dy);
4080  fe1d -> CalcDShape(ipz, dshape1dz);
4081 
4082  for (int n = 0; n < Dof; n++)
4083  {
4084  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
4085  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
4086  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
4087  }
4088 }
4089 
4091 {
4092  delete fe1d;
4093 
4094  delete [] I;
4095  delete [] J;
4096  delete [] K;
4097 }
4098 
4099 
4101  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
4102 {
4103  Nodes.IntPoint(0).x = 0.0;
4104  Nodes.IntPoint(1).x = 1.0;
4105  Nodes.IntPoint(2).x = 0.5;
4106 }
4107 
4109  Vector &shape) const
4110 {
4111  double x = ip.x;
4112 
4113  if (x <= 0.5)
4114  {
4115  shape(0) = 1.0 - 2.0 * x;
4116  shape(1) = 0.0;
4117  shape(2) = 2.0 * x;
4118  }
4119  else
4120  {
4121  shape(0) = 0.0;
4122  shape(1) = 2.0 * x - 1.0;
4123  shape(2) = 2.0 - 2.0 * x;
4124  }
4125 }
4126 
4128  DenseMatrix &dshape) const
4129 {
4130  double x = ip.x;
4131 
4132  if (x <= 0.5)
4133  {
4134  dshape(0,0) = - 2.0;
4135  dshape(1,0) = 0.0;
4136  dshape(2,0) = 2.0;
4137  }
4138  else
4139  {
4140  dshape(0,0) = 0.0;
4141  dshape(1,0) = 2.0;
4142  dshape(2,0) = - 2.0;
4143  }
4144 }
4145 
4147  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
4148 {
4149  Nodes.IntPoint(0).x = 0.0;
4150  Nodes.IntPoint(0).y = 0.0;
4151  Nodes.IntPoint(1).x = 1.0;
4152  Nodes.IntPoint(1).y = 0.0;
4153  Nodes.IntPoint(2).x = 0.0;
4154  Nodes.IntPoint(2).y = 1.0;
4155  Nodes.IntPoint(3).x = 0.5;
4156  Nodes.IntPoint(3).y = 0.0;
4157  Nodes.IntPoint(4).x = 0.5;
4158  Nodes.IntPoint(4).y = 0.5;
4159  Nodes.IntPoint(5).x = 0.0;
4160  Nodes.IntPoint(5).y = 0.5;
4161 }
4162 
4164  Vector &shape) const
4165 {
4166  int i;
4167 
4168  double L0, L1, L2;
4169  L0 = 2.0 * ( 1. - ip.x - ip.y );
4170  L1 = 2.0 * ( ip.x );
4171  L2 = 2.0 * ( ip.y );
4172 
4173  // The reference triangle is split in 4 triangles as follows:
4174  //
4175  // T0 - 0,3,5
4176  // T1 - 1,3,4
4177  // T2 - 2,4,5
4178  // T3 - 3,4,5
4179 
4180  for (i = 0; i < 6; i++)
4181  {
4182  shape(i) = 0.0;
4183  }
4184 
4185  if (L0 >= 1.0) // T0
4186  {
4187  shape(0) = L0 - 1.0;
4188  shape(3) = L1;
4189  shape(5) = L2;
4190  }
4191  else if (L1 >= 1.0) // T1
4192  {
4193  shape(3) = L0;
4194  shape(1) = L1 - 1.0;
4195  shape(4) = L2;
4196  }
4197  else if (L2 >= 1.0) // T2
4198  {
4199  shape(5) = L0;
4200  shape(4) = L1;
4201  shape(2) = L2 - 1.0;
4202  }
4203  else // T3
4204  {
4205  shape(3) = 1.0 - L2;
4206  shape(4) = 1.0 - L0;
4207  shape(5) = 1.0 - L1;
4208  }
4209 }
4210 
4212  DenseMatrix &dshape) const
4213 {
4214  int i,j;
4215 
4216  double L0, L1, L2;
4217  L0 = 2.0 * ( 1. - ip.x - ip.y );
4218  L1 = 2.0 * ( ip.x );
4219  L2 = 2.0 * ( ip.y );
4220 
4221  double DL0[2], DL1[2], DL2[2];
4222  DL0[0] = -2.0; DL0[1] = -2.0;
4223  DL1[0] = 2.0; DL1[1] = 0.0;
4224  DL2[0] = 0.0; DL2[1] = 2.0;
4225 
4226  for (i = 0; i < 6; i++)
4227  for (j = 0; j < 2; j++)
4228  {
4229  dshape(i,j) = 0.0;
4230  }
4231 
4232  if (L0 >= 1.0) // T0
4233  {
4234  for (j = 0; j < 2; j++)
4235  {
4236  dshape(0,j) = DL0[j];
4237  dshape(3,j) = DL1[j];
4238  dshape(5,j) = DL2[j];
4239  }
4240  }
4241  else if (L1 >= 1.0) // T1
4242  {
4243  for (j = 0; j < 2; j++)
4244  {
4245  dshape(3,j) = DL0[j];
4246  dshape(1,j) = DL1[j];
4247  dshape(4,j) = DL2[j];
4248  }
4249  }
4250  else if (L2 >= 1.0) // T2
4251  {
4252  for (j = 0; j < 2; j++)
4253  {
4254  dshape(5,j) = DL0[j];
4255  dshape(4,j) = DL1[j];
4256  dshape(2,j) = DL2[j];
4257  }
4258  }
4259  else // T3
4260  {
4261  for (j = 0; j < 2; j++)
4262  {
4263  dshape(3,j) = - DL2[j];
4264  dshape(4,j) = - DL0[j];
4265  dshape(5,j) = - DL1[j];
4266  }
4267  }
4268 }
4269 
4271  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
4272 {
4273  Nodes.IntPoint(0).x = 0.0;
4274  Nodes.IntPoint(0).y = 0.0;
4275  Nodes.IntPoint(0).z = 0.0;
4276  Nodes.IntPoint(1).x = 1.0;
4277  Nodes.IntPoint(1).y = 0.0;
4278  Nodes.IntPoint(1).z = 0.0;
4279  Nodes.IntPoint(2).x = 0.0;
4280  Nodes.IntPoint(2).y = 1.0;
4281  Nodes.IntPoint(2).z = 0.0;
4282  Nodes.IntPoint(3).x = 0.0;
4283  Nodes.IntPoint(3).y = 0.0;
4284  Nodes.IntPoint(3).z = 1.0;
4285  Nodes.IntPoint(4).x = 0.5;
4286  Nodes.IntPoint(4).y = 0.0;
4287  Nodes.IntPoint(4).z = 0.0;
4288  Nodes.IntPoint(5).x = 0.0;
4289  Nodes.IntPoint(5).y = 0.5;
4290  Nodes.IntPoint(5).z = 0.0;
4291  Nodes.IntPoint(6).x = 0.0;
4292  Nodes.IntPoint(6).y = 0.0;
4293  Nodes.IntPoint(6).z = 0.5;
4294  Nodes.IntPoint(7).x = 0.5;
4295  Nodes.IntPoint(7).y = 0.5;
4296  Nodes.IntPoint(7).z = 0.0;
4297  Nodes.IntPoint(8).x = 0.5;
4298  Nodes.IntPoint(8).y = 0.0;
4299  Nodes.IntPoint(8).z = 0.5;
4300  Nodes.IntPoint(9).x = 0.0;
4301  Nodes.IntPoint(9).y = 0.5;
4302  Nodes.IntPoint(9).z = 0.5;
4303 }
4304 
4306  Vector &shape) const
4307 {
4308  int i;
4309 
4310  double L0, L1, L2, L3, L4, L5;
4311  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4312  L1 = 2.0 * ( ip.x );
4313  L2 = 2.0 * ( ip.y );
4314  L3 = 2.0 * ( ip.z );
4315  L4 = 2.0 * ( ip.x + ip.y );
4316  L5 = 2.0 * ( ip.y + ip.z );
4317 
4318  // The reference tetrahedron is split in 8 tetrahedra as follows:
4319  //
4320  // T0 - 0,4,5,6
4321  // T1 - 1,4,7,8
4322  // T2 - 2,5,7,9
4323  // T3 - 3,6,8,9
4324  // T4 - 4,5,6,8
4325  // T5 - 4,5,7,8
4326  // T6 - 5,6,8,9
4327  // T7 - 5,7,8,9
4328 
4329  for (i = 0; i < 10; i++)
4330  {
4331  shape(i) = 0.0;
4332  }
4333 
4334  if (L0 >= 1.0) // T0
4335  {
4336  shape(0) = L0 - 1.0;
4337  shape(4) = L1;
4338  shape(5) = L2;
4339  shape(6) = L3;
4340  }
4341  else if (L1 >= 1.0) // T1
4342  {
4343  shape(4) = L0;
4344  shape(1) = L1 - 1.0;
4345  shape(7) = L2;
4346  shape(8) = L3;
4347  }
4348  else if (L2 >= 1.0) // T2
4349  {
4350  shape(5) = L0;
4351  shape(7) = L1;
4352  shape(2) = L2 - 1.0;
4353  shape(9) = L3;
4354  }
4355  else if (L3 >= 1.0) // T3
4356  {
4357  shape(6) = L0;
4358  shape(8) = L1;
4359  shape(9) = L2;
4360  shape(3) = L3 - 1.0;
4361  }
4362  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4363  {
4364  shape(4) = 1.0 - L5;
4365  shape(5) = L2;
4366  shape(6) = 1.0 - L4;
4367  shape(8) = 1.0 - L0;
4368  }
4369  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4370  {
4371  shape(4) = 1.0 - L5;
4372  shape(5) = 1.0 - L1;
4373  shape(7) = L4 - 1.0;
4374  shape(8) = L3;
4375  }
4376  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4377  {
4378  shape(5) = 1.0 - L3;
4379  shape(6) = 1.0 - L4;
4380  shape(8) = L1;
4381  shape(9) = L5 - 1.0;
4382  }
4383  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4384  {
4385  shape(5) = L0;
4386  shape(7) = L4 - 1.0;
4387  shape(8) = 1.0 - L2;
4388  shape(9) = L5 - 1.0;
4389  }
4390 }
4391 
4393  DenseMatrix &dshape) const
4394 {
4395  int i,j;
4396 
4397  double L0, L1, L2, L3, L4, L5;
4398  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4399  L1 = 2.0 * ( ip.x );
4400  L2 = 2.0 * ( ip.y );
4401  L3 = 2.0 * ( ip.z );
4402  L4 = 2.0 * ( ip.x + ip.y );
4403  L5 = 2.0 * ( ip.y + ip.z );
4404 
4405  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
4406  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
4407  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
4408  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
4409  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
4410  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
4411  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
4412 
4413  for (i = 0; i < 10; i++)
4414  for (j = 0; j < 3; j++)
4415  {
4416  dshape(i,j) = 0.0;
4417  }
4418 
4419  if (L0 >= 1.0) // T0
4420  {
4421  for (j = 0; j < 3; j++)
4422  {
4423  dshape(0,j) = DL0[j];
4424  dshape(4,j) = DL1[j];
4425  dshape(5,j) = DL2[j];
4426  dshape(6,j) = DL3[j];
4427  }
4428  }
4429  else if (L1 >= 1.0) // T1
4430  {
4431  for (j = 0; j < 3; j++)
4432  {
4433  dshape(4,j) = DL0[j];
4434  dshape(1,j) = DL1[j];
4435  dshape(7,j) = DL2[j];
4436  dshape(8,j) = DL3[j];
4437  }
4438  }
4439  else if (L2 >= 1.0) // T2
4440  {
4441  for (j = 0; j < 3; j++)
4442  {
4443  dshape(5,j) = DL0[j];
4444  dshape(7,j) = DL1[j];
4445  dshape(2,j) = DL2[j];
4446  dshape(9,j) = DL3[j];
4447  }
4448  }
4449  else if (L3 >= 1.0) // T3
4450  {
4451  for (j = 0; j < 3; j++)
4452  {
4453  dshape(6,j) = DL0[j];
4454  dshape(8,j) = DL1[j];
4455  dshape(9,j) = DL2[j];
4456  dshape(3,j) = DL3[j];
4457  }
4458  }
4459  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4460  {
4461  for (j = 0; j < 3; j++)
4462  {
4463  dshape(4,j) = - DL5[j];
4464  dshape(5,j) = DL2[j];
4465  dshape(6,j) = - DL4[j];
4466  dshape(8,j) = - DL0[j];
4467  }
4468  }
4469  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4470  {
4471  for (j = 0; j < 3; j++)
4472  {
4473  dshape(4,j) = - DL5[j];
4474  dshape(5,j) = - DL1[j];
4475  dshape(7,j) = DL4[j];
4476  dshape(8,j) = DL3[j];
4477  }
4478  }
4479  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4480  {
4481  for (j = 0; j < 3; j++)
4482  {
4483  dshape(5,j) = - DL3[j];
4484  dshape(6,j) = - DL4[j];
4485  dshape(8,j) = DL1[j];
4486  dshape(9,j) = DL5[j];
4487  }
4488  }
4489  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4490  {
4491  for (j = 0; j < 3; j++)
4492  {
4493  dshape(5,j) = DL0[j];
4494  dshape(7,j) = DL4[j];
4495  dshape(8,j) = - DL2[j];
4496  dshape(9,j) = DL5[j];
4497  }
4498  }
4499 }
4500 
4501 
4503  : NodalFiniteElement(2, Geometry::SQUARE , 9, 1, FunctionSpace::rQk)
4504 {
4505  Nodes.IntPoint(0).x = 0.0;
4506  Nodes.IntPoint(0).y = 0.0;
4507  Nodes.IntPoint(1).x = 1.0;
4508  Nodes.IntPoint(1).y = 0.0;
4509  Nodes.IntPoint(2).x = 1.0;
4510  Nodes.IntPoint(2).y = 1.0;
4511  Nodes.IntPoint(3).x = 0.0;
4512  Nodes.IntPoint(3).y = 1.0;
4513  Nodes.IntPoint(4).x = 0.5;
4514  Nodes.IntPoint(4).y = 0.0;
4515  Nodes.IntPoint(5).x = 1.0;
4516  Nodes.IntPoint(5).y = 0.5;
4517  Nodes.IntPoint(6).x = 0.5;
4518  Nodes.IntPoint(6).y = 1.0;
4519  Nodes.IntPoint(7).x = 0.0;
4520  Nodes.IntPoint(7).y = 0.5;
4521  Nodes.IntPoint(8).x = 0.5;
4522  Nodes.IntPoint(8).y = 0.5;
4523 }
4524 
4526  Vector &shape) const
4527 {
4528  int i;
4529  double x = ip.x, y = ip.y;
4530  double Lx, Ly;
4531  Lx = 2.0 * ( 1. - x );
4532  Ly = 2.0 * ( 1. - y );
4533 
4534  // The reference square is split in 4 squares as follows:
4535  //
4536  // T0 - 0,4,7,8
4537  // T1 - 1,4,5,8
4538  // T2 - 2,5,6,8
4539  // T3 - 3,6,7,8
4540 
4541  for (i = 0; i < 9; i++)
4542  {
4543  shape(i) = 0.0;
4544  }
4545 
4546  if ((x <= 0.5) && (y <= 0.5)) // T0
4547  {
4548  shape(0) = (Lx - 1.0) * (Ly - 1.0);
4549  shape(4) = (2.0 - Lx) * (Ly - 1.0);
4550  shape(8) = (2.0 - Lx) * (2.0 - Ly);
4551  shape(7) = (Lx - 1.0) * (2.0 - Ly);
4552  }
4553  else if ((x >= 0.5) && (y <= 0.5)) // T1
4554  {
4555  shape(4) = Lx * (Ly - 1.0);
4556  shape(1) = (1.0 - Lx) * (Ly - 1.0);
4557  shape(5) = (1.0 - Lx) * (2.0 - Ly);
4558  shape(8) = Lx * (2.0 - Ly);
4559  }
4560  else if ((x >= 0.5) && (y >= 0.5)) // T2
4561  {
4562  shape(8) = Lx * Ly ;
4563  shape(5) = (1.0 - Lx) * Ly ;
4564  shape(2) = (1.0 - Lx) * (1.0 - Ly);
4565  shape(6) = Lx * (1.0 - Ly);
4566  }
4567  else if ((x <= 0.5) && (y >= 0.5)) // T3
4568  {
4569  shape(7) = (Lx - 1.0) * Ly ;
4570  shape(8) = (2.0 - Lx) * Ly ;
4571  shape(6) = (2.0 - Lx) * (1.0 - Ly);
4572  shape(3) = (Lx - 1.0) * (1.0 - Ly);
4573  }
4574 }
4575 
4577  DenseMatrix &dshape) const
4578 {
4579  int i,j;
4580  double x = ip.x, y = ip.y;
4581  double Lx, Ly;
4582  Lx = 2.0 * ( 1. - x );
4583  Ly = 2.0 * ( 1. - y );
4584 
4585  for (i = 0; i < 9; i++)
4586  for (j = 0; j < 2; j++)
4587  {
4588  dshape(i,j) = 0.0;
4589  }
4590 
4591  if ((x <= 0.5) && (y <= 0.5)) // T0
4592  {
4593  dshape(0,0) = 2.0 * (1.0 - Ly);
4594  dshape(0,1) = 2.0 * (1.0 - Lx);
4595 
4596  dshape(4,0) = 2.0 * (Ly - 1.0);
4597  dshape(4,1) = -2.0 * (2.0 - Lx);
4598 
4599  dshape(8,0) = 2.0 * (2.0 - Ly);
4600  dshape(8,1) = 2.0 * (2.0 - Lx);
4601 
4602  dshape(7,0) = -2.0 * (2.0 - Ly);
4603  dshape(7,0) = 2.0 * (Lx - 1.0);
4604  }
4605  else if ((x >= 0.5) && (y <= 0.5)) // T1
4606  {
4607  dshape(4,0) = -2.0 * (Ly - 1.0);
4608  dshape(4,1) = -2.0 * Lx;
4609 
4610  dshape(1,0) = 2.0 * (Ly - 1.0);
4611  dshape(1,1) = -2.0 * (1.0 - Lx);
4612 
4613  dshape(5,0) = 2.0 * (2.0 - Ly);
4614  dshape(5,1) = 2.0 * (1.0 - Lx);
4615 
4616  dshape(8,0) = -2.0 * (2.0 - Ly);
4617  dshape(8,1) = 2.0 * Lx;
4618  }
4619  else if ((x >= 0.5) && (y >= 0.5)) // T2
4620  {
4621  dshape(8,0) = -2.0 * Ly;
4622  dshape(8,1) = -2.0 * Lx;
4623 
4624  dshape(5,0) = 2.0 * Ly;
4625  dshape(5,1) = -2.0 * (1.0 - Lx);
4626 
4627  dshape(2,0) = 2.0 * (1.0 - Ly);
4628  dshape(2,1) = 2.0 * (1.0 - Lx);
4629 
4630  dshape(6,0) = -2.0 * (1.0 - Ly);
4631  dshape(6,1) = 2.0 * Lx;
4632  }
4633  else if ((x <= 0.5) && (y >= 0.5)) // T3
4634  {
4635  dshape(7,0) = -2.0 * Ly;
4636  dshape(7,1) = -2.0 * (Lx - 1.0);
4637 
4638  dshape(8,0) = 2.0 * Ly ;
4639  dshape(8,1) = -2.0 * (2.0 - Lx);
4640 
4641  dshape(6,0) = 2.0 * (1.0 - Ly);
4642  dshape(6,1) = 2.0 * (2.0 - Lx);
4643 
4644  dshape(3,0) = -2.0 * (1.0 - Ly);
4645  dshape(3,1) = 2.0 * (Lx - 1.0);
4646  }
4647 }
4648 
4650  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
4651 {
4652  double I[27];
4653  double J[27];
4654  double K[27];
4655  // nodes
4656  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
4657  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
4658  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
4659  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
4660  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
4661  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
4662  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
4663  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
4664  // edges
4665  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
4666  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
4667  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
4668  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
4669  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
4670  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
4671  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
4672  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
4673  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
4674  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
4675  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
4676  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
4677  // faces
4678  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
4679  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
4680  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
4681  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
4682  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
4683  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
4684  // element
4685  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
4686 
4687  for (int n = 0; n < 27; n++)
4688  {
4689  Nodes.IntPoint(n).x = I[n];
4690  Nodes.IntPoint(n).y = J[n];
4691  Nodes.IntPoint(n).z = K[n];
4692  }
4693 }
4694 
4696  Vector &shape) const
4697 {
4698  int i, N[8];
4699  double Lx, Ly, Lz;
4700  double x = ip.x, y = ip.y, z = ip.z;
4701 
4702  for (i = 0; i < 27; i++)
4703  {
4704  shape(i) = 0.0;
4705  }
4706 
4707  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4708  {
4709  Lx = 1.0 - 2.0 * x;
4710  Ly = 1.0 - 2.0 * y;
4711  Lz = 1.0 - 2.0 * z;
4712 
4713  N[0] = 0;
4714  N[1] = 8;
4715  N[2] = 20;
4716  N[3] = 11;
4717  N[4] = 16;
4718  N[5] = 21;
4719  N[6] = 26;
4720  N[7] = 24;
4721  }
4722  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4723  {
4724  Lx = 2.0 - 2.0 * x;
4725  Ly = 1.0 - 2.0 * y;
4726  Lz = 1.0 - 2.0 * z;
4727 
4728  N[0] = 8;
4729  N[1] = 1;
4730  N[2] = 9;
4731  N[3] = 20;
4732  N[4] = 21;
4733  N[5] = 17;
4734  N[6] = 22;
4735  N[7] = 26;
4736  }
4737  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4738  {
4739  Lx = 2.0 - 2.0 * x;
4740  Ly = 2.0 - 2.0 * y;
4741  Lz = 1.0 - 2.0 * z;
4742 
4743  N[0] = 20;
4744  N[1] = 9;
4745  N[2] = 2;
4746  N[3] = 10;
4747  N[4] = 26;
4748  N[5] = 22;
4749  N[6] = 18;
4750  N[7] = 23;
4751  }
4752  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4753  {
4754  Lx = 1.0 - 2.0 * x;
4755  Ly = 2.0 - 2.0 * y;
4756  Lz = 1.0 - 2.0 * z;
4757 
4758  N[0] = 11;
4759  N[1] = 20;
4760  N[2] = 10;
4761  N[3] = 3;
4762  N[4] = 24;
4763  N[5] = 26;
4764  N[6] = 23;
4765  N[7] = 19;
4766  }
4767  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4768  {
4769  Lx = 1.0 - 2.0 * x;
4770  Ly = 1.0 - 2.0 * y;
4771  Lz = 2.0 - 2.0 * z;
4772 
4773  N[0] = 16;
4774  N[1] = 21;
4775  N[2] = 26;
4776  N[3] = 24;
4777  N[4] = 4;
4778  N[5] = 12;
4779  N[6] = 25;
4780  N[7] = 15;
4781  }
4782  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4783  {
4784  Lx = 2.0 - 2.0 * x;
4785  Ly = 1.0 - 2.0 * y;
4786  Lz = 2.0 - 2.0 * z;
4787 
4788  N[0] = 21;
4789  N[1] = 17;
4790  N[2] = 22;
4791  N[3] = 26;
4792  N[4] = 12;
4793  N[5] = 5;
4794  N[6] = 13;
4795  N[7] = 25;
4796  }
4797  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4798  {
4799  Lx = 2.0 - 2.0 * x;
4800  Ly = 2.0 - 2.0 * y;
4801  Lz = 2.0 - 2.0 * z;
4802 
4803  N[0] = 26;
4804  N[1] = 22;
4805  N[2] = 18;
4806  N[3] = 23;
4807  N[4] = 25;
4808  N[5] = 13;
4809  N[6] = 6;
4810  N[7] = 14;
4811  }
4812  else // T7
4813  {
4814  Lx = 1.0 - 2.0 * x;
4815  Ly = 2.0 - 2.0 * y;
4816  Lz = 2.0 - 2.0 * z;
4817 
4818  N[0] = 24;
4819  N[1] = 26;
4820  N[2] = 23;
4821  N[3] = 19;
4822  N[4] = 15;
4823  N[5] = 25;
4824  N[6] = 14;
4825  N[7] = 7;
4826  }
4827 
4828  shape(N[0]) = Lx * Ly * Lz;
4829  shape(N[1]) = (1 - Lx) * Ly * Lz;
4830  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
4831  shape(N[3]) = Lx * (1 - Ly) * Lz;
4832  shape(N[4]) = Lx * Ly * (1 - Lz);
4833  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
4834  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
4835  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
4836 }
4837 
4839  DenseMatrix &dshape) const
4840 {
4841  int i, j, N[8];
4842  double Lx, Ly, Lz;
4843  double x = ip.x, y = ip.y, z = ip.z;
4844 
4845  for (i = 0; i < 27; i++)
4846  for (j = 0; j < 3; j++)
4847  {
4848  dshape(i,j) = 0.0;
4849  }
4850 
4851  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4852  {
4853  Lx = 1.0 - 2.0 * x;
4854  Ly = 1.0 - 2.0 * y;
4855  Lz = 1.0 - 2.0 * z;
4856 
4857  N[0] = 0;
4858  N[1] = 8;
4859  N[2] = 20;
4860  N[3] = 11;
4861  N[4] = 16;
4862  N[5] = 21;
4863  N[6] = 26;
4864  N[7] = 24;
4865  }
4866  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4867  {
4868  Lx = 2.0 - 2.0 * x;
4869  Ly = 1.0 - 2.0 * y;
4870  Lz = 1.0 - 2.0 * z;
4871 
4872  N[0] = 8;
4873  N[1] = 1;
4874  N[2] = 9;
4875  N[3] = 20;
4876  N[4] = 21;
4877  N[5] = 17;
4878  N[6] = 22;
4879  N[7] = 26;
4880  }
4881  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4882  {
4883  Lx = 2.0 - 2.0 * x;
4884  Ly = 2.0 - 2.0 * y;
4885  Lz = 1.0 - 2.0 * z;
4886 
4887  N[0] = 20;
4888  N[1] = 9;
4889  N[2] = 2;
4890  N[3] = 10;
4891  N[4] = 26;
4892  N[5] = 22;
4893  N[6] = 18;
4894  N[7] = 23;
4895  }
4896  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4897  {
4898  Lx = 1.0 - 2.0 * x;
4899  Ly = 2.0 - 2.0 * y;
4900  Lz = 1.0 - 2.0 * z;
4901 
4902  N[0] = 11;
4903  N[1] = 20;
4904  N[2] = 10;
4905  N[3] = 3;
4906  N[4] = 24;
4907  N[5] = 26;
4908  N[6] = 23;
4909  N[7] = 19;
4910  }
4911  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4912  {
4913  Lx = 1.0 - 2.0 * x;
4914  Ly = 1.0 - 2.0 * y;
4915  Lz = 2.0 - 2.0 * z;
4916 
4917  N[0] = 16;
4918  N[1] = 21;
4919  N[2] = 26;
4920  N[3] = 24;
4921  N[4] = 4;
4922  N[5] = 12;
4923  N[6] = 25;
4924  N[7] = 15;
4925  }
4926  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4927  {
4928  Lx = 2.0 - 2.0 * x;
4929  Ly = 1.0 - 2.0 * y;
4930  Lz = 2.0 - 2.0 * z;
4931 
4932  N[0] = 21;
4933  N[1] = 17;
4934  N[2] = 22;
4935  N[3] = 26;
4936  N[4] = 12;
4937  N[5] = 5;
4938  N[6] = 13;
4939  N[7] = 25;
4940  }
4941  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4942  {
4943  Lx = 2.0 - 2.0 * x;
4944  Ly = 2.0 - 2.0 * y;
4945  Lz = 2.0 - 2.0 * z;
4946 
4947  N[0] = 26;
4948  N[1] = 22;
4949  N[2] = 18;
4950  N[3] = 23;
4951  N[4] = 25;
4952  N[5] = 13;
4953  N[6] = 6;
4954  N[7] = 14;
4955  }
4956  else // T7
4957  {
4958  Lx = 1.0 - 2.0 * x;
4959  Ly = 2.0 - 2.0 * y;
4960  Lz = 2.0 - 2.0 * z;
4961 
4962  N[0] = 24;
4963  N[1] = 26;
4964  N[2] = 23;
4965  N[3] = 19;
4966  N[4] = 15;
4967  N[5] = 25;
4968  N[6] = 14;
4969  N[7] = 7;
4970  }
4971 
4972  dshape(N[0],0) = -2.0 * Ly * Lz ;
4973  dshape(N[0],1) = -2.0 * Lx * Lz ;
4974  dshape(N[0],2) = -2.0 * Lx * Ly ;
4975 
4976  dshape(N[1],0) = 2.0 * Ly * Lz ;
4977  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
4978  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
4979 
4980  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
4981  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
4982  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
4983 
4984  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
4985  dshape(N[3],1) = 2.0 * Lx * Lz ;
4986  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
4987 
4988  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
4989  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
4990  dshape(N[4],2) = 2.0 * Lx * Ly ;
4991 
4992  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
4993  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
4994  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
4995 
4996  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
4997  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
4998  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
4999 
5000  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
5001  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
5002  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
5003 }
5004 
5005 
5007  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
5008 {
5009  // not real nodes ...
5010  Nodes.IntPoint(0).x = 0.5;
5011  Nodes.IntPoint(0).y = 0.0;
5012  Nodes.IntPoint(0).z = 0.0;
5013 
5014  Nodes.IntPoint(1).x = 1.0;
5015  Nodes.IntPoint(1).y = 0.5;
5016  Nodes.IntPoint(1).z = 0.0;
5017 
5018  Nodes.IntPoint(2).x = 0.5;
5019  Nodes.IntPoint(2).y = 1.0;
5020  Nodes.IntPoint(2).z = 0.0;
5021 
5022  Nodes.IntPoint(3).x = 0.0;
5023  Nodes.IntPoint(3).y = 0.5;
5024  Nodes.IntPoint(3).z = 0.0;
5025 
5026  Nodes.IntPoint(4).x = 0.5;
5027  Nodes.IntPoint(4).y = 0.0;
5028  Nodes.IntPoint(4).z = 1.0;
5029 
5030  Nodes.IntPoint(5).x = 1.0;
5031  Nodes.IntPoint(5).y = 0.5;
5032  Nodes.IntPoint(5).z = 1.0;
5033 
5034  Nodes.IntPoint(6).x = 0.5;
5035  Nodes.IntPoint(6).y = 1.0;
5036  Nodes.IntPoint(6).z = 1.0;
5037 
5038  Nodes.IntPoint(7).x = 0.0;
5039  Nodes.IntPoint(7).y = 0.5;
5040  Nodes.IntPoint(7).z = 1.0;
5041 
5042  Nodes.IntPoint(8).x = 0.0;
5043  Nodes.IntPoint(8).y = 0.0;
5044  Nodes.IntPoint(8).z = 0.5;
5045 
5046  Nodes.IntPoint(9).x = 1.0;
5047  Nodes.IntPoint(9).y = 0.0;
5048  Nodes.IntPoint(9).z = 0.5;
5049 
5050  Nodes.IntPoint(10).x= 1.0;
5051  Nodes.IntPoint(10).y= 1.0;
5052  Nodes.IntPoint(10).z= 0.5;
5053 
5054  Nodes.IntPoint(11).x= 0.0;
5055  Nodes.IntPoint(11).y= 1.0;
5056  Nodes.IntPoint(11).z= 0.5;
5057 }
5058 
5060  DenseMatrix &shape) const
5061 {
5062  double x = ip.x, y = ip.y, z = ip.z;
5063 
5064  shape(0,0) = (1. - y) * (1. - z);
5065  shape(0,1) = 0.;
5066  shape(0,2) = 0.;
5067 
5068  shape(2,0) = y * (1. - z);
5069  shape(2,1) = 0.;
5070  shape(2,2) = 0.;
5071 
5072  shape(4,0) = z * (1. - y);
5073  shape(4,1) = 0.;
5074  shape(4,2) = 0.;
5075 
5076  shape(6,0) = y * z;
5077  shape(6,1) = 0.;
5078  shape(6,2) = 0.;
5079 
5080  shape(1,0) = 0.;
5081  shape(1,1) = x * (1. - z);
5082  shape(1,2) = 0.;
5083 
5084  shape(3,0) = 0.;
5085  shape(3,1) = (1. - x) * (1. - z);
5086  shape(3,2) = 0.;
5087 
5088  shape(5,0) = 0.;
5089  shape(5,1) = x * z;
5090  shape(5,2) = 0.;
5091 
5092  shape(7,0) = 0.;
5093  shape(7,1) = (1. - x) * z;
5094  shape(7,2) = 0.;
5095 
5096  shape(8,0) = 0.;
5097  shape(8,1) = 0.;
5098  shape(8,2) = (1. - x) * (1. - y);
5099 
5100  shape(9,0) = 0.;
5101  shape(9,1) = 0.;
5102  shape(9,2) = x * (1. - y);
5103 
5104  shape(10,0) = 0.;
5105  shape(10,1) = 0.;
5106  shape(10,2) = x * y;
5107 
5108  shape(11,0) = 0.;
5109  shape(11,1) = 0.;
5110  shape(11,2) = y * (1. - x);
5111 
5112 }
5113 
5115  DenseMatrix &curl_shape)
5116 const
5117 {
5118  double x = ip.x, y = ip.y, z = ip.z;
5119 
5120  curl_shape(0,0) = 0.;
5121  curl_shape(0,1) = y - 1.;
5122  curl_shape(0,2) = 1. - z;
5123 
5124  curl_shape(2,0) = 0.;
5125  curl_shape(2,1) = -y;
5126  curl_shape(2,2) = z - 1.;
5127 
5128  curl_shape(4,0) = 0;
5129  curl_shape(4,1) = 1. - y;
5130  curl_shape(4,2) = z;
5131 
5132  curl_shape(6,0) = 0.;
5133  curl_shape(6,1) = y;
5134  curl_shape(6,2) = -z;
5135 
5136  curl_shape(1,0) = x;
5137  curl_shape(1,1) = 0.;
5138  curl_shape(1,2) = 1. - z;
5139 
5140  curl_shape(3,0) = 1. - x;
5141  curl_shape(3,1) = 0.;
5142  curl_shape(3,2) = z - 1.;
5143 
5144  curl_shape(5,0) = -x;
5145  curl_shape(5,1) = 0.;
5146  curl_shape(5,2) = z;
5147 
5148  curl_shape(7,0) = x - 1.;
5149  curl_shape(7,1) = 0.;
5150  curl_shape(7,2) = -z;
5151 
5152  curl_shape(8,0) = x - 1.;
5153  curl_shape(8,1) = 1. - y;
5154  curl_shape(8,2) = 0.;
5155 
5156  curl_shape(9,0) = -x;
5157  curl_shape(9,1) = y - 1.;
5158  curl_shape(9,2) = 0;
5159 
5160  curl_shape(10,0) = x;
5161  curl_shape(10,1) = -y;
5162  curl_shape(10,2) = 0.;
5163 
5164  curl_shape(11,0) = 1. - x;
5165  curl_shape(11,1) = y;
5166  curl_shape(11,2) = 0.;
5167 }
5168 
5169 const double Nedelec1HexFiniteElement::tk[12][3] =
5170 {
5171  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5172  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5173  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
5174 };
5175 
5178 {
5179  int k, j;
5180 #ifdef MFEM_THREAD_SAFE
5182 #endif
5183 
5184 #ifdef MFEM_DEBUG
5185  for (k = 0; k < 12; k++)
5186  {
5188  for (j = 0; j < 12; j++)
5189  {
5190  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5191  vshape(j,2)*tk[k][2] );
5192  if (j == k) { d -= 1.0; }
5193  if (fabs(d) > 1.0e-12)
5194  {
5195  mfem::err << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
5196  " k = " << k << ", j = " << j << ", d = " << d << endl;
5197  mfem_error();
5198  }
5199  }
5200  }
5201 #endif
5202 
5203  IntegrationPoint ip;
5204  ip.x = ip.y = ip.z = 0.0;
5205  Trans.SetIntPoint (&ip);
5206  // Trans must be linear (more to have embedding?)
5207  const DenseMatrix &J = Trans.Jacobian();
5208  double vk[3];
5209  Vector xk (vk, 3);
5210 
5211  for (k = 0; k < 12; k++)
5212  {
5213  Trans.Transform (Nodes.IntPoint (k), xk);
5214  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5215  CalcVShape (ip, vshape);
5216  // vk = J tk
5217  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5218  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5219  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5220  for (j = 0; j < 12; j++)
5221  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5222  vshape(j,2)*vk[2])) < 1.0e-12)
5223  {
5224  I(k,j) = 0.0;
5225  }
5226  }
5227 }
5228 
5231  Vector &dofs) const
5232 {
5233  double vk[3];
5234  Vector xk (vk, 3);
5235 
5236  for (int k = 0; k < 12; k++)
5237  {
5238  Trans.SetIntPoint (&Nodes.IntPoint (k));
5239  const DenseMatrix &J = Trans.Jacobian();
5240 
5241  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5242  // xk^t J tk
5243  dofs(k) =
5244  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5245  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5246  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5247  }
5248 }
5249 
5250 
5252  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
5253 {
5254  // not real nodes ...
5255  Nodes.IntPoint(0).x = 0.5;
5256  Nodes.IntPoint(0).y = 0.0;
5257  Nodes.IntPoint(0).z = 0.0;
5258 
5259  Nodes.IntPoint(1).x = 0.0;
5260  Nodes.IntPoint(1).y = 0.5;
5261  Nodes.IntPoint(1).z = 0.0;
5262 
5263  Nodes.IntPoint(2).x = 0.0;
5264  Nodes.IntPoint(2).y = 0.0;
5265  Nodes.IntPoint(2).z = 0.5;
5266 
5267  Nodes.IntPoint(3).x = 0.5;
5268  Nodes.IntPoint(3).y = 0.5;
5269  Nodes.IntPoint(3).z = 0.0;
5270 
5271  Nodes.IntPoint(4).x = 0.5;
5272  Nodes.IntPoint(4).y = 0.0;
5273  Nodes.IntPoint(4).z = 0.5;
5274 
5275  Nodes.IntPoint(5).x = 0.0;
5276  Nodes.IntPoint(5).y = 0.5;
5277  Nodes.IntPoint(5).z = 0.5;
5278 }
5279 
5281  DenseMatrix &shape) const
5282 {
5283  double x = ip.x, y = ip.y, z = ip.z;
5284 
5285  shape(0,0) = 1. - y - z;
5286  shape(0,1) = x;
5287  shape(0,2) = x;
5288 
5289  shape(1,0) = y;
5290  shape(1,1) = 1. - x - z;
5291  shape(1,2) = y;
5292 
5293  shape(2,0) = z;
5294  shape(2,1) = z;
5295  shape(2,2) = 1. - x - y;
5296 
5297  shape(3,0) = -y;
5298  shape(3,1) = x;
5299  shape(3,2) = 0.;
5300 
5301  shape(4,0) = -z;
5302  shape(4,1) = 0.;
5303  shape(4,2) = x;
5304 
5305  shape(5,0) = 0.;
5306  shape(5,1) = -z;
5307  shape(5,2) = y;
5308 }
5309 
5311  DenseMatrix &curl_shape)
5312 const
5313 {
5314  curl_shape(0,0) = 0.;
5315  curl_shape(0,1) = -2.;
5316  curl_shape(0,2) = 2.;
5317 
5318  curl_shape(1,0) = 2.;
5319  curl_shape(1,1) = 0.;
5320  curl_shape(1,2) = -2.;
5321 
5322  curl_shape(2,0) = -2.;
5323  curl_shape(2,1) = 2.;
5324  curl_shape(2,2) = 0.;
5325 
5326  curl_shape(3,0) = 0.;
5327  curl_shape(3,1) = 0.;
5328  curl_shape(3,2) = 2.;
5329 
5330  curl_shape(4,0) = 0.;
5331  curl_shape(4,1) = -2.;
5332  curl_shape(4,2) = 0.;
5333 
5334  curl_shape(5,0) = 2.;
5335  curl_shape(5,1) = 0.;
5336  curl_shape(5,2) = 0.;
5337 }
5338 
5339 const double Nedelec1TetFiniteElement::tk[6][3] =
5340 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
5341 
5344 {
5345  int k, j;
5346 #ifdef MFEM_THREAD_SAFE
5348 #endif
5349 
5350 #ifdef MFEM_DEBUG
5351  for (k = 0; k < 6; k++)
5352  {
5354  for (j = 0; j < 6; j++)
5355  {
5356  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5357  vshape(j,2)*tk[k][2] );
5358  if (j == k) { d -= 1.0; }
5359  if (fabs(d) > 1.0e-12)
5360  {
5361  mfem::err << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
5362  " k = " << k << ", j = " << j << ", d = " << d << endl;
5363  mfem_error();
5364  }
5365  }
5366  }
5367 #endif
5368 
5369  IntegrationPoint ip;
5370  ip.x = ip.y = ip.z = 0.0;
5371  Trans.SetIntPoint (&ip);
5372  // Trans must be linear
5373  const DenseMatrix &J = Trans.Jacobian();
5374  double vk[3];
5375  Vector xk (vk, 3);
5376 
5377  for (k = 0; k < 6; k++)
5378  {
5379  Trans.Transform (Nodes.IntPoint (k), xk);
5380  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5381  CalcVShape (ip, vshape);
5382  // vk = J tk
5383  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5384  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5385  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5386  for (j = 0; j < 6; j++)
5387  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5388  vshape(j,2)*vk[2])) < 1.0e-12)
5389  {
5390  I(k,j) = 0.0;
5391  }
5392  }
5393 }
5394 
5397  Vector &dofs) const
5398 {
5399  double vk[3];
5400  Vector xk (vk, 3);
5401 
5402  for (int k = 0; k < 6; k++)
5403  {
5404  Trans.SetIntPoint (&Nodes.IntPoint (k));
5405  const DenseMatrix &J = Trans.Jacobian();
5406 
5407  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5408  // xk^t J tk
5409  dofs(k) =
5410  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5411  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5412  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5413  }
5414 }
5415 
5417  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
5418 {
5419  // not real nodes ...
5420  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
5421  Nodes.IntPoint(0).x = 0.5;
5422  Nodes.IntPoint(0).y = 0.5;
5423  Nodes.IntPoint(0).z = 0.0;
5424 
5425  Nodes.IntPoint(1).x = 0.5;
5426  Nodes.IntPoint(1).y = 0.0;
5427  Nodes.IntPoint(1).z = 0.5;
5428 
5429  Nodes.IntPoint(2).x = 1.0;
5430  Nodes.IntPoint(2).y = 0.5;
5431  Nodes.IntPoint(2).z = 0.5;
5432 
5433  Nodes.IntPoint(3).x = 0.5;
5434  Nodes.IntPoint(3).y = 1.0;
5435  Nodes.IntPoint(3).z = 0.5;
5436 
5437  Nodes.IntPoint(4).x = 0.0;
5438  Nodes.IntPoint(4).y = 0.5;
5439  Nodes.IntPoint(4).z = 0.5;
5440 
5441  Nodes.IntPoint(5).x = 0.5;
5442  Nodes.IntPoint(5).y = 0.5;
5443  Nodes.IntPoint(5).z = 1.0;
5444 }
5445 
5447  DenseMatrix &shape) const
5448 {
5449  double x = ip.x, y = ip.y, z = ip.z;
5450  // z = 0
5451  shape(0,0) = 0.;
5452  shape(0,1) = 0.;
5453  shape(0,2) = z - 1.;
5454  // y = 0
5455  shape(1,0) = 0.;
5456  shape(1,1) = y - 1.;
5457  shape(1,2) = 0.;
5458  // x = 1
5459  shape(2,0) = x;
5460  shape(2,1) = 0.;
5461  shape(2,2) = 0.;
5462  // y = 1
5463  shape(3,0) = 0.;
5464  shape(3,1) = y;
5465  shape(3,2) = 0.;
5466  // x = 0
5467  shape(4,0) = x - 1.;
5468  shape(4,1) = 0.;
5469  shape(4,2) = 0.;
5470  // z = 1
5471  shape(5,0) = 0.;
5472  shape(5,1) = 0.;
5473  shape(5,2) = z;
5474 }
5475 
5477  Vector &divshape) const
5478 {
5479  divshape(0) = 1.;
5480  divshape(1) = 1.;
5481  divshape(2) = 1.;
5482  divshape(3) = 1.;
5483  divshape(4) = 1.;
5484  divshape(5) = 1.;
5485 }
5486 
5487 const double RT0HexFiniteElement::nk[6][3] =
5488 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
5489 
5492 {
5493  int k, j;
5494 #ifdef MFEM_THREAD_SAFE
5496  DenseMatrix Jinv(Dim);
5497 #endif
5498 
5499 #ifdef MFEM_DEBUG
5500  for (k = 0; k < 6; k++)
5501  {
5503  for (j = 0; j < 6; j++)
5504  {
5505  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5506  vshape(j,2)*nk[k][2] );
5507  if (j == k) { d -= 1.0; }
5508  if (fabs(d) > 1.0e-12)
5509  {
5510  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5511  " k = " << k << ", j = " << j << ", d = " << d << endl;
5512  mfem_error();
5513  }
5514  }
5515  }
5516 #endif
5517 
5518  IntegrationPoint ip;
5519  ip.x = ip.y = ip.z = 0.0;
5520  Trans.SetIntPoint (&ip);
5521  // Trans must be linear
5522  // set Jinv = |J| J^{-t} = adj(J)^t
5523  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5524  double vk[3];
5525  Vector xk (vk, 3);
5526 
5527  for (k = 0; k < 6; k++)
5528  {
5529  Trans.Transform (Nodes.IntPoint (k), xk);
5530  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5531  CalcVShape (ip, vshape);
5532  // vk = |J| J^{-t} nk
5533  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5534  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5535  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5536  for (j = 0; j < 6; j++)
5537  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5538  vshape(j,2)*vk[2])) < 1.0e-12)
5539  {
5540  I(k,j) = 0.0;
5541  }
5542  }
5543 }
5544 
5547  Vector &dofs) const
5548 {
5549  double vk[3];
5550  Vector xk (vk, 3);
5551 #ifdef MFEM_THREAD_SAFE
5552  DenseMatrix Jinv(Dim);
5553 #endif
5554 
5555  for (int k = 0; k < 6; k++)
5556  {
5557  Trans.SetIntPoint (&Nodes.IntPoint (k));
5558  // set Jinv = |J| J^{-t} = adj(J)^t
5559  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5560 
5561  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5562  // xk^t |J| J^{-t} nk
5563  dofs(k) =
5564  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5565  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5566  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5567  }
5568 }
5569 
5571  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
5572 {
5573  // z = 0
5574  Nodes.IntPoint(2).x = 1./3.;
5575  Nodes.IntPoint(2).y = 1./3.;
5576  Nodes.IntPoint(2).z = 0.0;
5577  Nodes.IntPoint(3).x = 2./3.;
5578  Nodes.IntPoint(3).y = 1./3.;
5579  Nodes.IntPoint(3).z = 0.0;
5580  Nodes.IntPoint(0).x = 1./3.;
5581  Nodes.IntPoint(0).y = 2./3.;
5582  Nodes.IntPoint(0).z = 0.0;
5583  Nodes.IntPoint(1).x = 2./3.;
5584  Nodes.IntPoint(1).y = 2./3.;
5585  Nodes.IntPoint(1).z = 0.0;
5586  // y = 0
5587  Nodes.IntPoint(4).x = 1./3.;
5588  Nodes.IntPoint(4).y = 0.0;
5589  Nodes.IntPoint(4).z = 1./3.;
5590  Nodes.IntPoint(5).x = 2./3.;
5591  Nodes.IntPoint(5).y = 0.0;
5592  Nodes.IntPoint(5).z = 1./3.;
5593  Nodes.IntPoint(6).x = 1./3.;
5594  Nodes.IntPoint(6).y = 0.0;
5595  Nodes.IntPoint(6).z = 2./3.;
5596  Nodes.IntPoint(7).x = 2./3.;
5597  Nodes.IntPoint(7).y = 0.0;
5598  Nodes.IntPoint(7).z = 2./3.;
5599  // x = 1
5600  Nodes.IntPoint(8).x = 1.0;
5601  Nodes.IntPoint(8).y = 1./3.;
5602  Nodes.IntPoint(8).z = 1./3.;
5603  Nodes.IntPoint(9).x = 1.0;
5604  Nodes.IntPoint(9).y = 2./3.;
5605  Nodes.IntPoint(9).z = 1./3.;
5606  Nodes.IntPoint(10).x = 1.0;
5607  Nodes.IntPoint(10).y = 1./3.;
5608  Nodes.IntPoint(10).z = 2./3.;
5609  Nodes.IntPoint(11).x = 1.0;
5610  Nodes.IntPoint(11).y = 2./3.;
5611  Nodes.IntPoint(11).z = 2./3.;
5612  // y = 1
5613  Nodes.IntPoint(13).x = 1./3.;
5614  Nodes.IntPoint(13).y = 1.0;
5615  Nodes.IntPoint(13).z = 1./3.;
5616  Nodes.IntPoint(12).x = 2./3.;
5617  Nodes.IntPoint(12).y = 1.0;
5618  Nodes.IntPoint(12).z = 1./3.;
5619  Nodes.IntPoint(15).x = 1./3.;
5620  Nodes.IntPoint(15).y = 1.0;
5621  Nodes.IntPoint(15).z = 2./3.;
5622  Nodes.IntPoint(14).x = 2./3.;
5623  Nodes.IntPoint(14).y = 1.0;
5624  Nodes.IntPoint(14).z = 2./3.;
5625  // x = 0
5626  Nodes.IntPoint(17).x = 0.0;
5627  Nodes.IntPoint(17).y = 1./3.;
5628  Nodes.IntPoint(17).z = 1./3.;
5629  Nodes.IntPoint(16).x = 0.0;
5630  Nodes.IntPoint(16).y = 2./3.;
5631  Nodes.IntPoint(16).z = 1./3.;
5632  Nodes.IntPoint(19).x = 0.0;
5633  Nodes.IntPoint(19).y = 1./3.;
5634  Nodes.IntPoint(19).z = 2./3.;
5635  Nodes.IntPoint(18).x = 0.0;
5636  Nodes.IntPoint(18).y = 2./3.;
5637  Nodes.IntPoint(18).z = 2./3.;
5638  // z = 1
5639  Nodes.IntPoint(20).x = 1./3.;
5640  Nodes.IntPoint(20).y = 1./3.;
5641  Nodes.IntPoint(20).z = 1.0;
5642  Nodes.IntPoint(21).x = 2./3.;
5643  Nodes.IntPoint(21).y = 1./3.;
5644  Nodes.IntPoint(21).z = 1.0;
5645  Nodes.IntPoint(22).x = 1./3.;
5646  Nodes.IntPoint(22).y = 2./3.;
5647  Nodes.IntPoint(22).z = 1.0;
5648  Nodes.IntPoint(23).x = 2./3.;
5649  Nodes.IntPoint(23).y = 2./3.;
5650  Nodes.IntPoint(23).z = 1.0;
5651  // x = 0.5 (interior)
5652  Nodes.IntPoint(24).x = 0.5;
5653  Nodes.IntPoint(24).y = 1./3.;
5654  Nodes.IntPoint(24).z = 1./3.;
5655  Nodes.IntPoint(25).x = 0.5;
5656  Nodes.IntPoint(25).y = 1./3.;
5657  Nodes.IntPoint(25).z = 2./3.;
5658  Nodes.IntPoint(26).x = 0.5;
5659  Nodes.IntPoint(26).y = 2./3.;
5660  Nodes.IntPoint(26).z = 1./3.;
5661  Nodes.IntPoint(27).x = 0.5;
5662  Nodes.IntPoint(27).y = 2./3.;
5663  Nodes.IntPoint(27).z = 2./3.;
5664  // y = 0.5 (interior)
5665  Nodes.IntPoint(28).x = 1./3.;
5666  Nodes.IntPoint(28).y = 0.5;
5667  Nodes.IntPoint(28).z = 1./3.;
5668  Nodes.IntPoint(29).x = 1./3.;
5669  Nodes.IntPoint(29).y = 0.5;
5670  Nodes.IntPoint(29).z = 2./3.;
5671  Nodes.IntPoint(30).x = 2./3.;
5672  Nodes.IntPoint(30).y = 0.5;
5673  Nodes.IntPoint(30).z = 1./3.;
5674  Nodes.IntPoint(31).x = 2./3.;
5675  Nodes.IntPoint(31).y = 0.5;
5676  Nodes.IntPoint(31).z = 2./3.;
5677  // z = 0.5 (interior)
5678  Nodes.IntPoint(32).x = 1./3.;
5679  Nodes.IntPoint(32).y = 1./3.;
5680  Nodes.IntPoint(32).z = 0.5;
5681  Nodes.IntPoint(33).x = 1./3.;
5682  Nodes.IntPoint(33).y = 2./3.;
5683  Nodes.IntPoint(33).z = 0.5;
5684  Nodes.IntPoint(34).x = 2./3.;
5685  Nodes.IntPoint(34).y = 1./3.;
5686  Nodes.IntPoint(34).z = 0.5;
5687  Nodes.IntPoint(35).x = 2./3.;
5688  Nodes.IntPoint(35).y = 2./3.;
5689  Nodes.IntPoint(35).z = 0.5;
5690 }
5691 
5693  DenseMatrix &shape) const
5694 {
5695  double x = ip.x, y = ip.y, z = ip.z;
5696  // z = 0
5697  shape(2,0) = 0.;
5698  shape(2,1) = 0.;
5699  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5700  shape(3,0) = 0.;
5701  shape(3,1) = 0.;
5702  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5703  shape(0,0) = 0.;
5704  shape(0,1) = 0.;
5705  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5706  shape(1,0) = 0.;
5707  shape(1,1) = 0.;
5708  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5709  // y = 0
5710  shape(4,0) = 0.;
5711  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5712  shape(4,2) = 0.;
5713  shape(5,0) = 0.;
5714  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5715  shape(5,2) = 0.;
5716  shape(6,0) = 0.;
5717  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5718  shape(6,2) = 0.;
5719  shape(7,0) = 0.;
5720  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5721  shape(7,2) = 0.;
5722  // x = 1
5723  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5724  shape(8,1) = 0.;
5725  shape(8,2) = 0.;
5726  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5727  shape(9,1) = 0.;
5728  shape(9,2) = 0.;
5729  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5730  shape(10,1) = 0.;
5731  shape(10,2) = 0.;
5732  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5733  shape(11,1) = 0.;
5734  shape(11,2) = 0.;
5735  // y = 1
5736  shape(13,0) = 0.;
5737  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5738  shape(13,2) = 0.;
5739  shape(12,0) = 0.;
5740  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5741  shape(12,2) = 0.;
5742  shape(15,0) = 0.;
5743  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5744  shape(15,2) = 0.;
5745  shape(14,0) = 0.;
5746  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5747  shape(14,2) = 0.;
5748  // x = 0
5749  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5750  shape(17,1) = 0.;
5751  shape(17,2) = 0.;
5752  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5753  shape(16,1) = 0.;
5754  shape(16,2) = 0.;
5755  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5756  shape(19,1) = 0.;
5757  shape(19,2) = 0.;
5758  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5759  shape(18,1) = 0.;
5760  shape(18,2) = 0.;
5761  // z = 1
5762  shape(20,0) = 0.;
5763  shape(20,1) = 0.;
5764  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5765  shape(21,0) = 0.;
5766  shape(21,1) = 0.;
5767  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5768  shape(22,0) = 0.;
5769  shape(22,1) = 0.;
5770  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5771  shape(23,0) = 0.;
5772  shape(23,1) = 0.;
5773  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5774  // x = 0.5 (interior)
5775  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5776  shape(24,1) = 0.;
5777  shape(24,2) = 0.;
5778  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5779  shape(25,1) = 0.;
5780  shape(25,2) = 0.;
5781  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5782  shape(26,1) = 0.;
5783  shape(26,2) = 0.;
5784  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5785  shape(27,1) = 0.;
5786  shape(27,2) = 0.;
5787  // y = 0.5 (interior)
5788  shape(28,0) = 0.;
5789  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5790  shape(28,2) = 0.;
5791  shape(29,0) = 0.;
5792  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5793  shape(29,2) = 0.;
5794  shape(30,0) = 0.;
5795  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5796  shape(30,2) = 0.;
5797  shape(31,0) = 0.;
5798  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5799  shape(31,2) = 0.;
5800  // z = 0.5 (interior)
5801  shape(32,0) = 0.;
5802  shape(32,1) = 0.;
5803  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5804  shape(33,0) = 0.;
5805  shape(33,1) = 0.;
5806  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5807  shape(34,0) = 0.;
5808  shape(34,1) = 0.;
5809  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5810  shape(35,0) = 0.;
5811  shape(35,1) = 0.;
5812  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5813 }
5814 
5816  Vector &divshape) const
5817 {
5818  double x = ip.x, y = ip.y, z = ip.z;
5819  // z = 0
5820  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5821  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5822  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5823  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5824  // y = 0
5825  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5826  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5827  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5828  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5829  // x = 1
5830  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5831  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5832  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5833  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5834  // y = 1
5835  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5836  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5837  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5838  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5839  // x = 0
5840  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5841  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5842  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5843  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5844  // z = 1
5845  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5846  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5847  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5848  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5849  // x = 0.5 (interior)
5850  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5851  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5852  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5853  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5854  // y = 0.5 (interior)
5855  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5856  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5857  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5858  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5859  // z = 0.5 (interior)
5860  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5861  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5862  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5863  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5864 }
5865 
5866 const double RT1HexFiniteElement::nk[36][3] =
5867 {
5868  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
5869  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
5870  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5871  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5872  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
5873  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
5874  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5875  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5876  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
5877 };
5878 
5881 {
5882  int k, j;
5883 #ifdef MFEM_THREAD_SAFE
5885  DenseMatrix Jinv(Dim);
5886 #endif
5887 
5888 #ifdef MFEM_DEBUG
5889  for (k = 0; k < 36; k++)
5890  {
5892  for (j = 0; j < 36; j++)
5893  {
5894  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5895  vshape(j,2)*nk[k][2] );
5896  if (j == k) { d -= 1.0; }
5897  if (fabs(d) > 1.0e-12)
5898  {
5899  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5900  " k = " << k << ", j = " << j << ", d = " << d << endl;
5901  mfem_error();
5902  }
5903  }
5904  }
5905 #endif
5906 
5907  IntegrationPoint ip;
5908  ip.x = ip.y = ip.z = 0.0;
5909  Trans.SetIntPoint (&ip);
5910  // Trans must be linear
5911  // set Jinv = |J| J^{-t} = adj(J)^t
5912  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5913  double vk[3];
5914  Vector xk (vk, 3);
5915 
5916  for (k = 0; k < 36; k++)
5917  {
5918  Trans.Transform (Nodes.IntPoint (k), xk);
5919  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5920  CalcVShape (ip, vshape);
5921  // vk = |J| J^{-t} nk
5922  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5923  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5924  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5925  for (j = 0; j < 36; j++)
5926  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5927  vshape(j,2)*vk[2])) < 1.0e-12)
5928  {
5929  I(k,j) = 0.0;
5930  }
5931  }
5932 }
5933 
5936  Vector &dofs) const
5937 {
5938  double vk[3];
5939  Vector xk (vk, 3);
5940 #ifdef MFEM_THREAD_SAFE
5941  DenseMatrix Jinv(Dim);
5942 #endif
5943 
5944  for (int k = 0; k < 36; k++)
5945  {
5946  Trans.SetIntPoint (&Nodes.IntPoint (k));
5947  // set Jinv = |J| J^{-t} = adj(J)^t
5948  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5949 
5950  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5951  // xk^t |J| J^{-t} nk
5952  dofs(k) =
5953  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5954  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5955  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5956  }
5957 }
5958 
5960  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
5961 {
5962  // not real nodes ...
5963  Nodes.IntPoint(0).x = 0.33333333333333333333;
5964  Nodes.IntPoint(0).y = 0.33333333333333333333;
5965  Nodes.IntPoint(0).z = 0.33333333333333333333;
5966 
5967  Nodes.IntPoint(1).x = 0.0;
5968  Nodes.IntPoint(1).y = 0.33333333333333333333;
5969  Nodes.IntPoint(1).z = 0.33333333333333333333;
5970 
5971  Nodes.IntPoint(2).x = 0.33333333333333333333;
5972  Nodes.IntPoint(2).y = 0.0;
5973  Nodes.IntPoint(2).z = 0.33333333333333333333;
5974 
5975  Nodes.IntPoint(3).x = 0.33333333333333333333;
5976  Nodes.IntPoint(3).y = 0.33333333333333333333;
5977  Nodes.IntPoint(3).z = 0.0;
5978 }
5979 
5981  DenseMatrix &shape) const
5982 {
5983  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
5984 
5985  shape(0,0) = x2;
5986  shape(0,1) = y2;
5987  shape(0,2) = z2;
5988 
5989  shape(1,0) = x2 - 2.0;
5990  shape(1,1) = y2;
5991  shape(1,2) = z2;
5992 
5993  shape(2,0) = x2;
5994  shape(2,1) = y2 - 2.0;
5995  shape(2,2) = z2;
5996 
5997  shape(3,0) = x2;
5998  shape(3,1) = y2;
5999  shape(3,2) = z2 - 2.0;
6000 }
6001 
6003  Vector &divshape) const
6004 {
6005  divshape(0) = 6.0;
6006  divshape(1) = 6.0;
6007  divshape(2) = 6.0;
6008  divshape(3) = 6.0;
6009 }
6010 
6011 const double RT0TetFiniteElement::nk[4][3] =
6012 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
6013 
6016 {
6017  int k, j;
6018 #ifdef MFEM_THREAD_SAFE
6020  DenseMatrix Jinv(Dim);
6021 #endif
6022 
6023 #ifdef MFEM_DEBUG
6024  for (k = 0; k < 4; k++)
6025  {
6027  for (j = 0; j < 4; j++)
6028  {
6029  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6030  vshape(j,2)*nk[k][2] );
6031  if (j == k) { d -= 1.0; }
6032  if (fabs(d) > 1.0e-12)
6033  {
6034  mfem::err << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
6035  " k = " << k << ", j = " << j << ", d = " << d << endl;
6036  mfem_error();
6037  }
6038  }
6039  }
6040 #endif
6041 
6042  IntegrationPoint ip;
6043  ip.x = ip.y = ip.z = 0.0;
6044  Trans.SetIntPoint (&ip);
6045  // Trans must be linear
6046  // set Jinv = |J| J^{-t} = adj(J)^t
6047  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6048  double vk[3];
6049  Vector xk (vk, 3);
6050 
6051  for (k = 0; k < 4; k++)
6052  {
6053  Trans.Transform (Nodes.IntPoint (k), xk);
6054  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6055  CalcVShape (ip, vshape);
6056  // vk = |J| J^{-t} nk
6057  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6058  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6059  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6060  for (j = 0; j < 4; j++)
6061  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6062  vshape(j,2)*vk[2])) < 1.0e-12)
6063  {
6064  I(k,j) = 0.0;
6065  }
6066  }
6067 }
6068 
6071  Vector &dofs) const
6072 {
6073  double vk[3];
6074  Vector xk (vk, 3);
6075 #ifdef MFEM_THREAD_SAFE
6076  DenseMatrix Jinv(Dim);
6077 #endif
6078 
6079  for (int k = 0; k < 4; k++)
6080  {
6081  Trans.SetIntPoint (&Nodes.IntPoint (k));
6082  // set Jinv = |J| J^{-t} = adj(J)^t
6083  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6084 
6085  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6086  // xk^t |J| J^{-t} nk
6087  dofs(k) =
6088  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6089  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6090  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6091  }
6092 }
6093 
6095  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
6096 {
6097  Nodes.IntPoint(0).x = 0.5;
6098  Nodes.IntPoint(0).y = 0.5;
6099  Nodes.IntPoint(0).z = 0.0;
6100 
6101  Nodes.IntPoint(1).x = 0.5;
6102  Nodes.IntPoint(1).y = 0.0;
6103  Nodes.IntPoint(1).z = 0.5;
6104 
6105  Nodes.IntPoint(2).x = 1.0;
6106  Nodes.IntPoint(2).y = 0.5;
6107  Nodes.IntPoint(2).z = 0.5;
6108 
6109  Nodes.IntPoint(3).x = 0.5;
6110  Nodes.IntPoint(3).y = 1.0;
6111  Nodes.IntPoint(3).z = 0.5;
6112 
6113  Nodes.IntPoint(4).x = 0.0;
6114  Nodes.IntPoint(4).y = 0.5;
6115  Nodes.IntPoint(4).z = 0.5;
6116 
6117  Nodes.IntPoint(5).x = 0.5;
6118  Nodes.IntPoint(5).y = 0.5;
6119  Nodes.IntPoint(5).z = 1.0;
6120 }
6121 
6123  Vector &shape) const
6124 {
6125  double x = 2. * ip.x - 1.;
6126  double y = 2. * ip.y - 1.;
6127  double z = 2. * ip.z - 1.;
6128  double f5 = x * x - y * y;
6129  double f6 = y * y - z * z;
6130 
6131  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
6132  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
6133  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
6134  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
6135  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
6136  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
6137 }
6138 
6140  DenseMatrix &dshape) const
6141 {
6142  const double a = 2./3.;
6143 
6144  double xt = a * (1. - 2. * ip.x);
6145  double yt = a * (1. - 2. * ip.y);
6146  double zt = a * (1. - 2. * ip.z);
6147 
6148  dshape(0,0) = xt;
6149  dshape(0,1) = yt;
6150  dshape(0,2) = -1. - 2. * zt;
6151 
6152  dshape(1,0) = xt;
6153  dshape(1,1) = -1. - 2. * yt;
6154  dshape(1,2) = zt;
6155 
6156  dshape(2,0) = 1. - 2. * xt;
6157  dshape(2,1) = yt;
6158  dshape(2,2) = zt;
6159 
6160  dshape(3,0) = xt;
6161  dshape(3,1) = 1. - 2. * yt;
6162  dshape(3,2) = zt;
6163 
6164  dshape(4,0) = -1. - 2. * xt;
6165  dshape(4,1) = yt;
6166  dshape(4,2) = zt;
6167 
6168  dshape(5,0) = xt;
6169  dshape(5,1) = yt;
6170  dshape(5,2) = 1. - 2. * zt;
6171 }
6172 
6173 
6174 Poly_1D::Basis::Basis(const int p, const double *nodes, int _mode)
6175  : x(p + 1), w(p + 1)
6176 {
6177  mode = _mode;
6178  if (mode == 0)
6179  {
6180  DenseMatrix A(p + 1);
6181  for (int i = 0; i <= p; i++)
6182  {
6183  CalcBasis(p, nodes[i], x);
6184  for (int j = 0; j <= p; j++)
6185  {
6186  A(j, i) = x(j);
6187  }
6188  }
6189 
6190  Ai.Factor(A);
6191  // mfem::out << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
6192  }
6193  else
6194  {
6195  x = nodes;
6196  w = 1.0;
6197  for (int i = 0; i <= p; i++)
6198  {
6199  for (int j = 0; j < i; j++)
6200  {
6201  double xij = x(i) - x(j);
6202  w(i) *= xij;
6203  w(j) *= -xij;
6204  }
6205  }
6206  for (int i = 0; i <= p; i++)
6207  {
6208  w(i) = 1.0/w(i);
6209  }
6210 
6211 #ifdef MFEM_DEBUG
6212  // Make sure the nodes are increasing
6213  for (int i = 0; i < p; i++)
6214  {
6215  if (x(i) >= x(i+1))
6216  {
6217  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
6218  }
6219  }
6220 #endif
6221  }
6222 }
6223 
6224 void Poly_1D::Basis::Eval(const double y, Vector &u) const
6225 {
6226  if (mode == 0)
6227  {
6228  CalcBasis(Ai.Width() - 1, y, x);
6229  Ai.Mult(x, u);
6230  }
6231  else
6232  {
6233  int i, k, p = x.Size() - 1;
6234  double l, lk;
6235 
6236  if (p == 0)
6237  {
6238  u(0) = 1.0;
6239  return;
6240  }
6241 
6242  lk = 1.0;
6243  for (k = 0; k < p; k++)
6244  {
6245  if (y >= (x(k) + x(k+1))/2)
6246  {
6247  lk *= y - x(k);
6248  }
6249  else
6250  {
6251  for (i = k+1; i <= p; i++)
6252  {
6253  lk *= y - x(i);
6254  }
6255  break;
6256  }
6257  }
6258  l = lk * (y - x(k));
6259 
6260  for (i = 0; i < k; i++)
6261  {
6262  u(i) = l * w(i) / (y - x(i));
6263  }
6264  u(k) = lk * w(k);
6265  for (i++; i <= p; i++)
6266  {
6267  u(i) = l * w(i) / (y - x(i));
6268  }
6269  }
6270 }
6271 
6272 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
6273 {
6274  if (mode == 0)
6275  {
6276  CalcBasis(Ai.Width() - 1, y, x, w);
6277  Ai.Mult(x, u);
6278  Ai.Mult(w, d);
6279  }
6280  else
6281  {
6282  int i, k, p = x.Size() - 1;
6283  double l, lp, lk, sk, si;
6284 
6285  if (p == 0)
6286  {
6287  u(0) = 1.0;
6288  d(0) = 0.0;
6289  return;
6290  }
6291 
6292  lk = 1.0;
6293  for (k = 0; k < p; k++)
6294  {
6295  if (y >= (x(k) + x(k+1))/2)
6296  {
6297  lk *= y - x(k);
6298  }
6299  else
6300  {
6301  for (i = k+1; i <= p; i++)
6302  {
6303  lk *= y - x(i);
6304  }
6305  break;
6306  }
6307  }
6308  l = lk * (y - x(k));
6309 
6310  sk = 0.0;
6311  for (i = 0; i < k; i++)
6312  {
6313  si = 1.0/(y - x(i));
6314  sk += si;
6315  u(i) = l * si * w(i);
6316  }
6317  u(k) = lk * w(k);
6318  for (i++; i <= p; i++)
6319  {
6320  si = 1.0/(y - x(i));
6321  sk += si;
6322  u(i) = l * si * w(i);
6323  }
6324  lp = l * sk + lk;
6325 
6326  for (i = 0; i < k; i++)
6327  {
6328  d(i) = (lp * w(i) - u(i))/(y - x(i));
6329  }
6330  d(k) = sk * u(k);
6331  for (i++; i <= p; i++)
6332  {
6333  d(i) = (lp * w(i) - u(i))/(y - x(i));
6334  }
6335  }
6336 }
6337 
6338 const int *Poly_1D::Binom(const int p)
6339 {
6340  if (binom.NumCols() <= p)
6341  {
6342  binom.SetSize(p + 1, p + 1);
6343  for (int i = 0; i <= p; i++)
6344  {
6345  binom(i,0) = binom(i,i) = 1;
6346  for (int j = 1; j < i; j++)
6347  {
6348  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
6349  }
6350  }
6351  }
6352  return binom[p];
6353 }
6354 
6355 void Poly_1D::ChebyshevPoints(const int p, double *x)
6356 {
6357  for (int i = 0; i <= p; i++)
6358  {
6359  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
6360  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
6361  x[i] = s*s;
6362  }
6363 }
6364 
6365 void Poly_1D::CalcMono(const int p, const double x, double *u)
6366 {
6367  double xn;
6368  u[0] = xn = 1.;
6369  for (int n = 1; n <= p; n++)
6370  {
6371  u[n] = (xn *= x);
6372  }
6373 }
6374 
6375 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
6376 {
6377  double xn;
6378  u[0] = xn = 1.;
6379  d[0] = 0.;
6380  for (int n = 1; n <= p; n++)
6381  {
6382  d[n] = n * xn;
6383  u[n] = (xn *= x);
6384  }
6385 }
6386 
6387 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6388  double *u)
6389 {
6390  if (p == 0)
6391  {
6392  u[0] = 1.;
6393  }
6394  else
6395  {
6396  int i;
6397  const int *b = Binom(p);
6398  double z = x;
6399 
6400  for (i = 1; i < p; i++)
6401  {
6402  u[i] = b[i]*z;
6403  z *= x;
6404  }
6405  u[p] = z;
6406  z = y;
6407  for (i--; i > 0; i--)
6408  {
6409  u[i] *= z;
6410  z *= y;
6411  }
6412  u[0] = z;
6413  }
6414 }
6415 
6416 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6417  double *u, double *d)
6418 {
6419  if (p == 0)
6420  {
6421  u[0] = 1.;
6422  d[0] = 0.;
6423  }
6424  else
6425  {
6426  int i;
6427  const int *b = Binom(p);
6428  const double xpy = x + y, ptx = p*x;
6429  double z = 1.;
6430 
6431  for (i = 1; i < p; i++)
6432  {
6433  d[i] = b[i]*z*(i*xpy - ptx);
6434  z *= x;
6435  u[i] = b[i]*z;
6436  }
6437  d[p] = p*z;
6438  u[p] = z*x;
6439  z = 1.;
6440  for (i--; i > 0; i--)
6441  {
6442  d[i] *= z;
6443  z *= y;
6444  u[i] *= z;
6445  }
6446  d[0] = -p*z;
6447  u[0] = z*y;
6448  }
6449 }
6450 
6451 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
6452  double *d)
6453 {
6454  if (p == 0)
6455  {
6456  d[0] = 0.;
6457  }
6458  else
6459  {
6460  int i;
6461  const int *b = Binom(p);
6462  const double xpy = x + y, ptx = p*x;
6463  double z = 1.;
6464 
6465  for (i = 1; i < p; i++)
6466  {
6467  d[i] = b[i]*z*(i*xpy - ptx);
6468  z *= x;
6469  }
6470  d[p] = p*z;
6471  z = 1.;
6472  for (i--; i > 0; i--)
6473  {
6474  d[i] *= z;
6475  z *= y;
6476  }
6477  d[0] = -p*z;
6478  }
6479 }
6480 
6481 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
6482 {
6483  // use the recursive definition for [-1,1]:
6484  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6485  double z;
6486  u[0] = 1.;
6487  if (p == 0) { return; }
6488  u[1] = z = 2.*x - 1.;
6489  for (int n = 1; n < p; n++)
6490  {
6491  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6492  }
6493 }
6494 
6495 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
6496 {
6497  // use the recursive definition for [-1,1]:
6498  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6499  // for the derivative use, z in [-1,1]:
6500  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
6501  double z;
6502  u[0] = 1.;
6503  d[0] = 0.;
6504  if (p == 0) { return; }
6505  u[1] = z = 2.*x - 1.;
6506  d[1] = 2.;
6507  for (int n = 1; n < p; n++)
6508  {
6509  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6510  d[n+1] = (4*n + 2)*u[n] + d[n-1];
6511  }
6512 }
6513 
6514 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
6515 {
6516  // recursive definition, z in [-1,1]
6517  // T_0(z) = 1, T_1(z) = z
6518  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6519  double z;
6520  u[0] = 1.;
6521  if (p == 0) { return; }
6522  u[1] = z = 2.*x - 1.;
6523  for (int n = 1; n < p; n++)
6524  {
6525  u[n+1] = 2*z*u[n] - u[n-1];
6526  }
6527 }
6528 
6529 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
6530 {
6531  // recursive definition, z in [-1,1]
6532  // T_0(z) = 1, T_1(z) = z
6533  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6534  // T'_n(z) = n*U_{n-1}(z)
6535  // U_0(z) = 1 U_1(z) = 2*z
6536  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
6537  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
6538  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
6539  double z;
6540  u[0] = 1.;
6541  d[0] = 0.;
6542  if (p == 0) { return; }
6543  u[1] = z = 2.*x - 1.;
6544  d[1] = 2.;
6545  for (int n = 1; n < p; n++)
6546  {
6547  u[n+1] = 2*z*u[n] - u[n-1];
6548  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
6549  }
6550 }
6551 
6552 const double *Poly_1D::GetPoints(const int p, const int type)
6553 {
6554  MFEM_ASSERT(type != Quadrature1D::Invalid, "invalid point type");
6555 
6556  if (points_container.find(type) == points_container.end())
6557  {
6558  points_container[type] = new Array<double*>;
6559  }
6560  Array<double*> &pts = *points_container[type];
6561  if (pts.Size() <= p)
6562  {
6563  pts.SetSize(p + 1, NULL);
6564  }
6565  if (pts[p] == NULL)
6566  {
6567  pts[p] = new double[p + 1];
6568  quad_func.GivePolyPoints(p+1, pts[p], type);
6569  }
6570  return pts[p];
6571 }
6572 
6573 Poly_1D::Basis &Poly_1D::GetBasis(const int p, const int type)
6574 {
6575  MFEM_ASSERT(type != Quadrature1D::Invalid, "invalid point type");
6576 
6577  if ( bases_container.find(type) == bases_container.end() )
6578  {
6579  // we haven't been asked for basis or points of this type yet
6580  bases_container[type] = new Array<Basis*>;
6581  }
6582  Array<Basis*> &bases = *bases_container[type];
6583  if (bases.Size() <= p)
6584  {
6585  bases.SetSize(p + 1, NULL);
6586  }
6587  if (bases[p] == NULL)
6588  {
6589  bases[p] = new Basis(p, GetPoints(p, type));
6590  }
6591  return *bases[p];
6592 }
6593 
6595 {
6596  for (std::map<int, Array<double*>*>::iterator it = points_container.begin();
6597  it != points_container.end() ; ++it)
6598  {
6599  Array<double*>& pts = *it->second;
6600  for ( int i = 0 ; i < pts.Size() ; ++i )
6601  {
6602  delete [] pts[i];
6603  }
6604  delete it->second;
6605  }
6606 
6607  for (std::map<int, Array<Basis*>*>::iterator it = bases_container.begin();
6608  it != bases_container.end() ; ++it )
6609  {
6610  Array<Basis*>& bases = *it->second;
6611  for ( int i = 0 ; i < bases.Size() ; ++i )
6612  {
6613  delete bases[i];
6614  }
6615  delete it->second;
6616  }
6617 }
6618 
6620 Array2D<int> Poly_1D::binom;
6621 
6622 
6623 H1_SegmentElement::H1_SegmentElement(const int p, const int type)
6624  : NodalFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
6625  pt_type(VerifyClosed(type)),
6626  basis1d(poly1d.ClosedBasis(p, pt_type)),
6627  dof_map(Dof)
6628 {
6629  const double *cp = poly1d.ClosedPoints(p, pt_type);
6630 
6631 #ifndef MFEM_THREAD_SAFE
6632  shape_x.SetSize(p+1);
6633  dshape_x.SetSize(p+1);
6634 #endif
6635 
6636  Nodes.IntPoint(0).x = cp[0];
6637  Nodes.IntPoint(1).x = cp[p];
6638  dof_map[0] = 0;
6639  dof_map[p] = 1;
6640  for (int i = 1; i < p; i++)
6641  {
6642  Nodes.IntPoint(i+1).x = cp[i];
6643  dof_map[i] = i+1;
6644  }
6645 }
6646 
6648  Vector &shape) const
6649 {
6650  const int p = Order;
6651 
6652 #ifdef MFEM_THREAD_SAFE
6653  Vector shape_x(p+1);
6654 #endif
6655 
6656  basis1d.Eval(ip.x, shape_x);
6657 
6658  shape(0) = shape_x(0);
6659  shape(1) = shape_x(p);
6660  for (int i = 1; i < p; i++)
6661  {
6662  shape(i+1) = shape_x(i);
6663  }
6664 }
6665 
6667  DenseMatrix &dshape) const
6668 {
6669  const int p = Order;
6670 
6671 #ifdef MFEM_THREAD_SAFE
6672  Vector shape_x(p+1), dshape_x(p+1);
6673 #endif
6674 
6675  basis1d.Eval(ip.x, shape_x, dshape_x);
6676 
6677  dshape(0,0) = dshape_x(0);
6678  dshape(1,0) = dshape_x(p);
6679  for (int i = 1; i < p; i++)
6680  {
6681  dshape(i+1,0) = dshape_x(i);
6682  }
6683 }
6684 
6685 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
6686 {
6687  const int p = Order;
6688  const double *cp = poly1d.ClosedPoints(p, pt_type);
6689 
6690  switch (vertex)
6691  {
6692  case 0:
6693  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
6694  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
6695  for (int i = 1; i < p; i++)
6696  {
6697  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6698  }
6699  break;
6700 
6701  case 1:
6702  dofs(0) = poly1d.CalcDelta(p, cp[0]);
6703  dofs(1) = poly1d.CalcDelta(p, cp[p]);
6704  for (int i = 1; i < p; i++)
6705  {
6706  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
6707  }
6708  break;
6709  }
6710 }
6711 
6712 
6714  : NodalFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
6715  FunctionSpace::Qk),
6716  pt_type(VerifyClosed(type)),
6717  basis1d(poly1d.ClosedBasis(p, pt_type)),
6718  dof_map((p + 1)*(p + 1))
6719 {
6720  const double *cp = poly1d.ClosedPoints(p, pt_type);
6721 
6722  const int p1 = p + 1;
6723 
6724 #ifndef MFEM_THREAD_SAFE
6725  shape_x.SetSize(p1);
6726  shape_y.SetSize(p1);
6727  dshape_x.SetSize(p1);
6728  dshape_y.SetSize(p1);
6729 #endif
6730 
6731  // vertices
6732  dof_map[0 + 0*p1] = 0;
6733  dof_map[p + 0*p1] = 1;
6734  dof_map[p + p*p1] = 2;
6735  dof_map[0 + p*p1] = 3;
6736 
6737  // edges
6738  int o = 4;
6739  for (int i = 1; i < p; i++)
6740  {
6741  dof_map[i + 0*p1] = o++;
6742  }
6743  for (int i = 1; i < p; i++)
6744  {
6745  dof_map[p + i*p1] = o++;
6746  }
6747  for (int i = 1; i < p; i++)
6748  {
6749  dof_map[(p-i) + p*p1] = o++;
6750  }
6751  for (int i = 1; i < p; i++)
6752  {
6753  dof_map[0 + (p-i)*p1] = o++;
6754  }
6755 
6756  // interior
6757  for (int j = 1; j < p; j++)
6758  for (int i = 1; i < p; i++)
6759  {
6760  dof_map[i + j*p1] = o++;
6761  }
6762 
6763  o = 0;
6764  for (int j = 0; j <= p; j++)
6765  {
6766  for (int i = 0; i <= p; i++)
6767  {
6768  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
6769  }
6770  }
6771 }
6772 
6774  Vector &shape) const
6775 {
6776  const int p = Order;
6777 
6778 #ifdef MFEM_THREAD_SAFE
6779  Vector shape_x(p+1), shape_y(p+1);
6780 #endif
6781 
6782  basis1d.Eval(ip.x, shape_x);
6783  basis1d.Eval(ip.y, shape_y);
6784 
6785  for (int o = 0, j = 0; j <= p; j++)
6786  for (int i = 0; i <= p; i++)
6787  {
6788  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
6789  }
6790 }
6791 
6793  DenseMatrix &dshape) const
6794 {
6795  const int p = Order;
6796 
6797 #ifdef MFEM_THREAD_SAFE
6798  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
6799 #endif
6800 
6801  basis1d.Eval(ip.x, shape_x, dshape_x);
6802  basis1d.Eval(ip.y, shape_y, dshape_y);
6803 
6804  for (int o = 0, j = 0; j <= p; j++)
6805  {
6806  for (int i = 0; i <= p; i++)
6807  {
6808  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
6809  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
6810  }
6811  }
6812 }
6813 
6814 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
6815 {
6816  const int p = Order;
6817  const double *cp = poly1d.ClosedPoints(p, pt_type);
6818 
6819 #ifdef MFEM_THREAD_SAFE
6820  Vector shape_x(p+1), shape_y(p+1);
6821 #endif
6822 
6823  for (int i = 0; i <= p; i++)
6824  {
6825  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6826  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
6827  }
6828 
6829  switch (vertex)
6830  {
6831  case 0:
6832  for (int o = 0, j = 0; j <= p; j++)
6833  for (int i = 0; i <= p; i++)
6834  {
6835  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
6836  }
6837  break;
6838  case 1:
6839  for (int o = 0, j = 0; j <= p; j++)
6840  for (int i = 0; i <= p; i++)
6841  {
6842  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
6843  }
6844  break;
6845  case 2:
6846  for (int o = 0, j = 0; j <= p; j++)
6847  for (int i = 0; i <= p; i++)
6848  {
6849  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
6850  }
6851  break;
6852  case 3:
6853  for (int o = 0, j = 0; j <= p; j++)
6854  for (int i = 0; i <= p; i++)
6855  {
6856  dofs(dof_map[o++]) = shape_x(i)*shape_y(j);
6857  }
6858  break;
6859  }
6860 }
6861 
6862 
6864  : NodalFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
6865  FunctionSpace::Qk),
6866  pt_type(VerifyClosed(type)),
6867  basis1d(poly1d.ClosedBasis(p, pt_type)),
6868  dof_map((p + 1)*(p + 1)*(p + 1))
6869 {
6870  const double *cp = poly1d.ClosedPoints(p, pt_type);
6871 
6872  const int p1 = p + 1;
6873 
6874 #ifndef MFEM_THREAD_SAFE
6875  shape_x.SetSize(p1);
6876  shape_y.SetSize(p1);
6877  shape_z.SetSize(p1);
6878  dshape_x.SetSize(p1);
6879  dshape_y.SetSize(p1);
6880  dshape_z.SetSize(p1);
6881 #endif
6882 
6883  // vertices
6884  dof_map[0 + (0 + 0*p1)*p1] = 0;
6885  dof_map[p + (0 + 0*p1)*p1] = 1;
6886  dof_map[p + (p + 0*p1)*p1] = 2;
6887  dof_map[0 + (p + 0*p1)*p1] = 3;
6888  dof_map[0 + (0 + p*p1)*p1] = 4;
6889  dof_map[p + (0 + p*p1)*p1] = 5;
6890  dof_map[p + (p + p*p1)*p1] = 6;
6891  dof_map[0 + (p + p*p1)*p1] = 7;
6892 
6893  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
6894  int o = 8;
6895  for (int i = 1; i < p; i++)
6896  {
6897  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
6898  }
6899  for (int i = 1; i < p; i++)
6900  {
6901  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
6902  }
6903  for (int i = 1; i < p; i++)
6904  {
6905  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
6906  }
6907  for (int i = 1; i < p; i++)
6908  {
6909  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
6910  }
6911  for (int i = 1; i < p; i++)
6912  {
6913  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
6914  }
6915  for (int i = 1; i < p; i++)
6916  {
6917  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
6918  }
6919  for (int i = 1; i < p; i++)
6920  {
6921  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
6922  }
6923  for (int i = 1; i < p; i++)
6924  {
6925  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
6926  }
6927  for (int i = 1; i < p; i++)
6928  {
6929  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
6930  }
6931  for (int i = 1; i < p; i++)
6932  {
6933  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
6934  }
6935  for (int i = 1; i < p; i++)
6936  {
6937  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
6938  }
6939  for (int i = 1; i < p; i++)
6940  {
6941  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
6942  }
6943 
6944  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
6945  for (int j = 1; j < p; j++)
6946  for (int i = 1; i < p; i++)
6947  {
6948  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
6949  }
6950  for (int j = 1; j < p; j++)
6951  for (int i = 1; i < p; i++)
6952  {
6953  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
6954  }
6955  for (int j = 1; j < p; j++)
6956  for (int i = 1; i < p; i++)
6957  {
6958  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
6959  }
6960  for (int j = 1; j < p; j++)
6961  for (int i = 1; i < p; i++)
6962  {
6963  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
6964  }
6965  for (int j = 1; j < p; j++)
6966  for (int i = 1; i < p; i++)
6967  {
6968  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
6969  }
6970  for (int j = 1; j < p; j++)
6971  for (int i = 1; i < p; i++)
6972  {
6973  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
6974  }
6975 
6976  // interior
6977  for (int k = 1; k < p; k++)
6978  for (int j = 1; j < p; j++)
6979  for (int i = 1; i < p; i++)
6980  {
6981  dof_map[i + (j + k*p1)*p1] = o++;
6982  }
6983 
6984  o = 0;
6985  for (int k = 0; k <= p; k++)
6986  for (int j = 0; j <= p; j++)
6987  for (int i = 0; i <= p; i++)
6988  {
6989  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
6990  }
6991 }
6992 
6994  Vector &shape) const
6995 {
6996  const int p = Order;
6997 
6998 #ifdef MFEM_THREAD_SAFE
6999  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7000 #endif
7001 
7002  basis1d.Eval(ip.x, shape_x);
7003  basis1d.Eval(ip.y, shape_y);
7004  basis1d.Eval(ip.z, shape_z);
7005 
7006  for (int o = 0, k = 0; k <= p; k++)
7007  for (int j = 0; j <= p; j++)
7008  for (int i = 0; i <= p; i++)
7009  {
7010  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7011  }
7012 }
7013 
7015  DenseMatrix &dshape) const
7016 {
7017  const int p = Order;
7018 
7019 #ifdef MFEM_THREAD_SAFE
7020  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7021  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7022 #endif
7023 
7024  basis1d.Eval(ip.x, shape_x, dshape_x);
7025  basis1d.Eval(ip.y, shape_y, dshape_y);
7026  basis1d.Eval(ip.z, shape_z, dshape_z);
7027 
7028  for (int o = 0, k = 0; k <= p; k++)
7029  for (int j = 0; j <= p; j++)
7030  for (int i = 0; i <= p; i++)
7031  {
7032  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7033  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7034  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7035  }
7036 }
7037 
7038 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7039 {
7040  const int p = Order;
7041  const double *cp = poly1d.ClosedPoints(p,pt_type);
7042 
7043 #ifdef MFEM_THREAD_SAFE
7044  Vector shape_x(p+1), shape_y(p+1);
7045 #endif
7046 
7047  for (int i = 0; i <= p; i++)
7048  {
7049  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7050  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7051  }
7052 
7053  switch (vertex)
7054  {
7055  case 0:
7056  for (int o = 0, k = 0; k <= p; k++)
7057  for (int j = 0; j <= p; j++)
7058  for (int i = 0; i <= p; i++)
7059  {
7060  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
7061  }
7062  break;
7063  case 1:
7064  for (int o = 0, k = 0; k <= p; k++)
7065  for (int j = 0; j <= p; j++)
7066  for (int i = 0; i <= p; i++)
7067  {
7068  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
7069  }
7070  break;
7071  case 2:
7072  for (int o = 0, k = 0; k <= p; k++)
7073  for (int j = 0; j <= p; j++)
7074  for (int i = 0; i <= p; i++)
7075  {
7076  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
7077  }
7078  break;
7079  case 3:
7080  for (int o = 0, k = 0; k <= p; k++)
7081  for (int j = 0; j <= p; j++)
7082  for (int i = 0; i <= p; i++)
7083  {
7084  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
7085  }
7086  break;
7087  case 4:
7088  for (int o = 0, k = 0; k <= p; k++)
7089  for (int j = 0; j <= p; j++)
7090  for (int i = 0; i <= p; i++)
7091  {
7092  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
7093  }
7094  break;
7095  case 5:
7096  for (int o = 0, k = 0; k <= p; k++)
7097  for (int j = 0; j <= p; j++)
7098  for (int i = 0; i <= p; i++)
7099  {
7100  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
7101  }
7102  break;
7103  case 6:
7104  for (int o = 0, k = 0; k <= p; k++)
7105  for (int j = 0; j <= p; j++)
7106  for (int i = 0; i <= p; i++)
7107  {
7108  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
7109  }
7110  break;
7111  case 7:
7112  for (int o = 0, k = 0; k <= p; k++)
7113  for (int j = 0; j <= p; j++)
7114  for (int i = 0; i <= p; i++)
7115  {
7116  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
7117  }
7118  break;
7119  }
7120 }
7121 
7122 
7124  : PositiveFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
7125  dof_map(Dof)
7126 {
7127 #ifndef MFEM_THREAD_SAFE
7128  // thread private versions; see class header.
7129  shape_x.SetSize(p+1);
7130  dshape_x.SetSize(p+1);
7131 #endif
7132 
7133  // Endpoints need to be first in the list, so reorder them.
7134  Nodes.IntPoint(0).x = 0.0;
7135  Nodes.IntPoint(1).x = 1.0;
7136  dof_map[0] = 0;
7137  dof_map[p] = 1;
7138  for (int i = 1; i < p; i++)
7139  {
7140  Nodes.IntPoint(i+1).x = double(i)/p;
7141  dof_map[i] = i+1;
7142  }
7143 }
7144 
7146  Vector &shape) const
7147 {
7148  const int p = Order;
7149 
7150 #ifdef MFEM_THREAD_SAFE
7151  Vector shape_x(p+1);
7152 #endif
7153 
7154  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7155 
7156  // Endpoints need to be first in the list, so reorder them.
7157  shape(0) = shape_x(0);
7158  shape(1) = shape_x(p);
7159  for (int i = 1; i < p; i++)
7160  {
7161  shape(i+1) = shape_x(i);
7162  }
7163 }
7164 
7166  DenseMatrix &dshape) const
7167 {
7168  const int p = Order;
7169 
7170 #ifdef MFEM_THREAD_SAFE
7171  Vector shape_x(p+1), dshape_x(p+1);
7172 #endif
7173 
7174  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7175 
7176  // Endpoints need to be first in the list, so reorder them.
7177  dshape(0,0) = dshape_x(0);
7178  dshape(1,0) = dshape_x(p);
7179  for (int i = 1; i < p; i++)
7180  {
7181  dshape(i+1,0) = dshape_x(i);
7182  }
7183 }
7184 
7185 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7186 {
7187  dofs = 0.0;
7188  dofs[vertex] = 1.0;
7189 }
7190 
7191 
7193  : PositiveFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
7194  FunctionSpace::Qk),
7195  dof_map((p + 1)*(p + 1))
7196 {
7197  const int p1 = p + 1;
7198 
7199 #ifndef MFEM_THREAD_SAFE
7200  shape_x.SetSize(p1);
7201  shape_y.SetSize(p1);
7202  dshape_x.SetSize(p1);
7203  dshape_y.SetSize(p1);
7204 #endif
7205 
7206  // vertices must be the first ones in the list of DOF's for
7207  // this element. So we need to reorder the points.
7208  dof_map[0 + 0*p1] = 0;
7209  dof_map[p + 0*p1] = 1;
7210  dof_map[p + p*p1] = 2;
7211  dof_map[0 + p*p1] = 3;
7212 
7213  // edges
7214  int o = 4;
7215  for (int i = 1; i < p; i++)
7216  {
7217  dof_map[i + 0*p1] = o++;
7218  }
7219  for (int i = 1; i < p; i++)
7220  {
7221  dof_map[p + i*p1] = o++;
7222  }
7223  for (int i = 1; i < p; i++)
7224  {
7225  dof_map[(p-i) + p*p1] = o++;
7226  }
7227  for (int i = 1; i < p; i++)
7228  {
7229  dof_map[0 + (p-i)*p1] = o++;
7230  }
7231 
7232  // interior
7233  for (int j = 1; j < p; j++)
7234  for (int i = 1; i < p; i++)
7235  {
7236  dof_map[i + j*p1] = o++;
7237  }
7238 
7239  o = 0;
7240  for (int j = 0; j <= p; j++)
7241  for (int i = 0; i <= p; i++)
7242  {
7243  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
7244  }
7245 }
7246 
7248  Vector &shape) const
7249 {
7250  const int p = Order;
7251 
7252 #ifdef MFEM_THREAD_SAFE
7253  Vector shape_x(p+1), shape_y(p+1);
7254 #endif
7255 
7256  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7257  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7258 
7259  // Reorder so that vertices are at the beginning of the list
7260  for (int o = 0, j = 0; j <= p; j++)
7261  for (int i = 0; i <= p; i++)
7262  {
7263  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7264  }
7265 }
7266 
7268  DenseMatrix &dshape) const
7269 {
7270  const int p = Order;
7271 
7272 #ifdef MFEM_THREAD_SAFE
7273  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7274 #endif
7275 
7276  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7277  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7278 
7279  // Reorder so that vertices are at the beginning of the list
7280  for (int o = 0, j = 0; j <= p; j++)
7281  for (int i = 0; i <= p; i++)
7282  {
7283  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7284  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7285  }
7286 }
7287 
7289 {
7290  dofs = 0.0;
7291  dofs[vertex] = 1.0;
7292 }
7293 
7294 
7296  : PositiveFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
7297  FunctionSpace::Qk),
7298  dof_map((p + 1)*(p + 1)*(p + 1))
7299 {
7300  const int p1 = p + 1;
7301 
7302 #ifndef MFEM_THREAD_SAFE
7303  shape_x.SetSize(p1);
7304  shape_y.SetSize(p1);
7305  shape_z.SetSize(p1);
7306  dshape_x.SetSize(p1);
7307  dshape_y.SetSize(p1);
7308  dshape_z.SetSize(p1);
7309 #endif
7310 
7311  // vertices must be the first ones in the list of DOF's for
7312  // this element. So we need to reorder the points.
7313  dof_map[0 + (0 + 0*p1)*p1] = 0;
7314  dof_map[p + (0 + 0*p1)*p1] = 1;
7315  dof_map[p + (p + 0*p1)*p1] = 2;
7316  dof_map[0 + (p + 0*p1)*p1] = 3;
7317  dof_map[0 + (0 + p*p1)*p1] = 4;
7318  dof_map[p + (0 + p*p1)*p1] = 5;
7319  dof_map[p + (p + p*p1)*p1] = 6;
7320  dof_map[0 + (p + p*p1)*p1] = 7;
7321 
7322  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
7323  int o = 8;
7324  for (int i = 1; i < p; i++)
7325  {
7326  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
7327  }
7328  for (int i = 1; i < p; i++)
7329  {
7330  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
7331  }
7332  for (int i = 1; i < p; i++)
7333  {
7334  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
7335  }
7336  for (int i = 1; i < p; i++)
7337  {
7338  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
7339  }
7340  for (int i = 1; i < p; i++)
7341  {
7342  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
7343  }
7344  for (int i = 1; i < p; i++)
7345  {
7346  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
7347  }
7348  for (int i = 1; i < p; i++)
7349  {
7350  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
7351  }
7352  for (int i = 1; i < p; i++)
7353  {
7354  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
7355  }
7356  for (int i = 1; i < p; i++)
7357  {
7358  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
7359  }
7360  for (int i = 1; i < p; i++)
7361  {
7362  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
7363  }
7364  for (int i = 1; i < p; i++)
7365  {
7366  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
7367  }
7368  for (int i = 1; i < p; i++)
7369  {
7370  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
7371  }
7372 
7373  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7374  for (int j = 1; j < p; j++)
7375  for (int i = 1; i < p; i++)
7376  {
7377  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
7378  }
7379  for (int j = 1; j < p; j++)
7380  for (int i = 1; i < p; i++)
7381  {
7382  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
7383  }
7384  for (int j = 1; j < p; j++)
7385  for (int i = 1; i < p; i++)
7386  {
7387  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
7388  }
7389  for (int j = 1; j < p; j++)
7390  for (int i = 1; i < p; i++)
7391  {
7392  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
7393  }
7394  for (int j = 1; j < p; j++)
7395  for (int i = 1; i < p; i++)
7396  {
7397  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
7398  }
7399  for (int j = 1; j < p; j++)
7400  for (int i = 1; i < p; i++)
7401  {
7402  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
7403  }
7404 
7405  // interior
7406  for (int k = 1; k < p; k++)
7407  for (int j = 1; j < p; j++)
7408  for (int i = 1; i < p; i++)
7409  {
7410  dof_map[i + (j + k*p1)*p1] = o++;
7411  }
7412 
7413  o = 0;
7414  for (int k = 0; k <= p; k++)
7415  for (int j = 0; j <= p; j++)
7416  for (int i = 0; i <= p; i++)
7417  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
7418  double(k)/p);
7419 }
7420 
7422  Vector &shape) const
7423 {
7424  const int p = Order;
7425 
7426 #ifdef MFEM_THREAD_SAFE
7427  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7428 #endif
7429 
7430  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7431  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7432  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
7433 
7434  for (int o = 0, k = 0; k <= p; k++)
7435  for (int j = 0; j <= p; j++)
7436  for (int i = 0; i <= p; i++)
7437  {
7438  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7439  }
7440 }
7441 
7443  DenseMatrix &dshape) const
7444 {
7445  const int p = Order;
7446 
7447 #ifdef MFEM_THREAD_SAFE
7448  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7449  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7450 #endif
7451 
7452  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7453  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7454  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
7455 
7456  for (int o = 0, k = 0; k <= p; k++)
7457  for (int j = 0; j <= p; j++)
7458  for (int i = 0; i <= p; i++)
7459  {
7460  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7461  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7462  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7463  }
7464 }
7465 
7466 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7467 {
7468  dofs = 0.0;
7469  dofs[vertex] = 1.0;
7470 }
7471 
7472 
7473 H1_TriangleElement::H1_TriangleElement(const int p, const int type)
7474  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7475  FunctionSpace::Pk)
7476 {
7477  const double *cp = poly1d.ClosedPoints(p, VerifyClosed(type));
7478 
7479 #ifndef MFEM_THREAD_SAFE
7480  shape_x.SetSize(p + 1);
7481  shape_y.SetSize(p + 1);
7482  shape_l.SetSize(p + 1);
7483  dshape_x.SetSize(p + 1);
7484  dshape_y.SetSize(p + 1);
7485  dshape_l.SetSize(p + 1);
7486  u.SetSize(Dof);
7487  du.SetSize(Dof, Dim);
7488 #else
7489  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7490 #endif
7491 
7492  // vertices
7493  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
7494  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
7495  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
7496 
7497  // edges
7498  int o = 3;
7499  for (int i = 1; i < p; i++)
7500  {
7501  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
7502  }
7503  for (int i = 1; i < p; i++)
7504  {
7505  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
7506  }
7507  for (int i = 1; i < p; i++)
7508  {
7509  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
7510  }
7511 
7512  // interior
7513  for (int j = 1; j < p; j++)
7514  for (int i = 1; i + j < p; i++)
7515  {
7516  const double w = cp[i] + cp[j] + cp[p-i-j];
7517  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
7518  }
7519 
7520  DenseMatrix T(Dof);
7521  for (int k = 0; k < Dof; k++)
7522  {
7523  IntegrationPoint &ip = Nodes.IntPoint(k);
7524  poly1d.CalcBasis(p, ip.x, shape_x);
7525  poly1d.CalcBasis(p, ip.y, shape_y);
7526  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7527 
7528  o = 0;
7529  for (int j = 0; j <= p; j++)
7530  for (int i = 0; i + j <= p; i++)
7531  {
7532  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7533  }
7534  }
7535 
7536  Ti.Factor(T);
7537  // mfem::out << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
7538 }
7539 
7541  Vector &shape) const
7542 {
7543  const int p = Order;
7544 
7545 #ifdef MFEM_THREAD_SAFE
7546  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
7547 #endif
7548 
7549  poly1d.CalcBasis(p, ip.x, shape_x);
7550  poly1d.CalcBasis(p, ip.y, shape_y);
7551  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7552 
7553  for (int o = 0, j = 0; j <= p; j++)
7554  for (int i = 0; i + j <= p; i++)
7555  {
7556  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7557  }
7558 
7559  Ti.Mult(u, shape);
7560 }
7561 
7563  DenseMatrix &dshape) const
7564 {
7565  const int p = Order;
7566 
7567 #ifdef MFEM_THREAD_SAFE
7568  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7569  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
7570  DenseMatrix du(Dof, Dim);
7571 #endif
7572 
7573  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7574  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7575  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
7576 
7577  for (int o = 0, j = 0; j <= p; j++)
7578  for (int i = 0; i + j <= p; i++)
7579  {
7580  int k = p - i - j;
7581  du(o,0) = ((dshape_x(i)* shape_l(k)) -
7582  ( shape_x(i)*dshape_l(k)))*shape_y(j);
7583  du(o,1) = ((dshape_y(j)* shape_l(k)) -
7584  ( shape_y(j)*dshape_l(k)))*shape_x(i);
7585  o++;
7586  }
7587 
7588  Ti.Mult(du, dshape);
7589 }
7590 
7591 
7593  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
7594  p, FunctionSpace::Pk)
7595 {
7596  const double *cp = poly1d.ClosedPoints(p, VerifyClosed(type));
7597 
7598 #ifndef MFEM_THREAD_SAFE
7599  shape_x.SetSize(p + 1);
7600  shape_y.SetSize(p + 1);
7601  shape_z.SetSize(p + 1);
7602  shape_l.SetSize(p + 1);
7603  dshape_x.SetSize(p + 1);
7604  dshape_y.SetSize(p + 1);
7605  dshape_z.SetSize(p + 1);
7606  dshape_l.SetSize(p + 1);
7607  u.SetSize(Dof);
7608  du.SetSize(Dof, Dim);
7609 #else
7610  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7611 #endif
7612 
7613  // vertices
7614  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
7615  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
7616  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
7617  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
7618 
7619  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7620  int o = 4;
7621  for (int i = 1; i < p; i++) // (0,1)
7622  {
7623  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
7624  }
7625  for (int i = 1; i < p; i++) // (0,2)
7626  {
7627  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
7628  }
7629  for (int i = 1; i < p; i++) // (0,3)
7630  {
7631  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
7632  }
7633  for (int i = 1; i < p; i++) // (1,2)
7634  {
7635  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
7636  }
7637  for (int i = 1; i < p; i++) // (1,3)
7638  {
7639  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
7640  }
7641  for (int i = 1; i < p; i++) // (2,3)
7642  {
7643  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
7644  }
7645 
7646  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7647  for (int j = 1; j < p; j++)
7648  for (int i = 1; i + j < p; i++) // (1,2,3)
7649  {
7650  double w = cp[i] + cp[j] + cp[p-i-j];
7651  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
7652  }
7653  for (int j = 1; j < p; j++)
7654  for (int i = 1; i + j < p; i++) // (0,3,2)
7655  {
7656  double w = cp[i] + cp[j] + cp[p-i-j];
7657  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
7658  }
7659  for (int j = 1; j < p; j++)
7660  for (int i = 1; i + j < p; i++) // (0,1,3)
7661  {
7662  double w = cp[i] + cp[j] + cp[p-i-j];
7663  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
7664  }
7665  for (int j = 1; j < p; j++)
7666  for (int i = 1; i + j < p; i++) // (0,2,1)
7667  {
7668  double w = cp[i] + cp[j] + cp[p-i-j];
7669  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
7670  }
7671 
7672  // interior
7673  for (int k = 1; k < p; k++)
7674  for (int j = 1; j + k < p; j++)
7675  for (int i = 1; i + j + k < p; i++)
7676  {
7677  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
7678  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
7679  }
7680 
7681  DenseMatrix T(Dof);
7682  for (int m = 0; m < Dof; m++)
7683  {
7684  IntegrationPoint &ip = Nodes.IntPoint(m);
7685  poly1d.CalcBasis(p, ip.x, shape_x);
7686  poly1d.CalcBasis(p, ip.y, shape_y);
7687  poly1d.CalcBasis(p, ip.z, shape_z);
7688  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7689 
7690  o = 0;
7691  for (int k = 0; k <= p; k++)
7692  for (int j = 0; j + k <= p; j++)
7693  for (int i = 0; i + j + k <= p; i++)
7694  {
7695  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7696  }
7697  }
7698 
7699  Ti.Factor(T);
7700  // mfem::out << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
7701 }
7702 
7704  Vector &shape) const
7705 {
7706  const int p = Order;
7707 
7708 #ifdef MFEM_THREAD_SAFE
7709  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7710  Vector u(Dof);
7711 #endif
7712 
7713  poly1d.CalcBasis(p, ip.x, shape_x);
7714  poly1d.CalcBasis(p, ip.y, shape_y);
7715  poly1d.CalcBasis(p, ip.z, shape_z);
7716  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7717 
7718  for (int o = 0, k = 0; k <= p; k++)
7719  for (int j = 0; j + k <= p; j++)
7720  for (int i = 0; i + j + k <= p; i++)
7721  {
7722  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7723  }
7724 
7725  Ti.Mult(u, shape);
7726 }
7727 
7729  DenseMatrix &dshape) const
7730 {
7731  const int p = Order;
7732 
7733 #ifdef MFEM_THREAD_SAFE
7734  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7735  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
7736  DenseMatrix du(Dof, Dim);
7737 #endif
7738 
7739  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7740  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7741  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
7742  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
7743 
7744  for (int o = 0, k = 0; k <= p; k++)
7745  for (int j = 0; j + k <= p; j++)
7746  for (int i = 0; i + j + k <= p; i++)
7747  {
7748  int l = p - i - j - k;
7749  du(o,0) = ((dshape_x(i)* shape_l(l)) -
7750  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
7751  du(o,1) = ((dshape_y(j)* shape_l(l)) -
7752  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
7753  du(o,2) = ((dshape_z(k)* shape_l(l)) -
7754  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
7755  o++;
7756  }
7757 
7758  Ti.Mult(du, dshape);
7759 }
7760 
7761 
7763  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7764  FunctionSpace::Pk)
7765 {
7766 #ifndef MFEM_THREAD_SAFE
7767  m_shape.SetSize(Dof);
7768  dshape_1d.SetSize(p + 1);
7769  m_dshape.SetSize(Dof, Dim);
7770 #endif
7771  dof_map.SetSize(Dof);
7772 
7773  struct Index
7774  {
7775  int p2p3;
7776  Index(int p) { p2p3 = 2*p + 3; }
7777  int operator()(int i, int j) { return ((p2p3-j)*j)/2+i; }
7778  };
7779  Index idx(p);
7780 
7781  // vertices
7782  dof_map[idx(0,0)] = 0;
7783  Nodes.IntPoint(0).Set2(0., 0.);
7784  dof_map[idx(p,0)] = 1;
7785  Nodes.IntPoint(1).Set2(1., 0.);
7786  dof_map[idx(0,p)] = 2;
7787  Nodes.IntPoint(2).Set2(0., 1.);
7788 
7789  // edges
7790  int o = 3;
7791  for (int i = 1; i < p; i++)
7792  {
7793  dof_map[idx(i,0)] = o;
7794  Nodes.IntPoint(o++).Set2(double(i)/p, 0.);
7795  }
7796  for (int i = 1; i < p; i++)
7797  {
7798  dof_map[idx(p-i,i)] = o;
7799  Nodes.IntPoint(o++).Set2(double(p-i)/p, double(i)/p);
7800  }
7801  for (int i = 1; i < p; i++)
7802  {
7803  dof_map[idx(0,p-i)] = o;
7804  Nodes.IntPoint(o++).Set2(0., double(p-i)/p);
7805  }
7806 
7807  // interior
7808  for (int j = 1; j < p; j++)
7809  for (int i = 1; i + j < p; i++)
7810  {
7811  dof_map[idx(i,j)] = o;
7812  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
7813  }
7814 }
7815 
7816 // static method
7818  const int p, const double l1, const double l2, double *shape)
7819 {
7820  const double l3 = 1. - l1 - l2;
7821 
7822  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
7823  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
7824  // Another expression is given by the terms of the expansion:
7825  // (l1 + l2 + l3)^p =
7826  // \sum_{j=0}^p \binom{p}{j} l2^j
7827  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
7828  const int *bp = Poly_1D::Binom(p);
7829  double z = 1.;
7830  for (int o = 0, j = 0; j <= p; j++)
7831  {
7832  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape[o]);
7833  double s = bp[j]*z;
7834  for (int i = 0; i <= p - j; i++)
7835  {
7836  shape[o++] *= s;
7837  }
7838  z *= l2;
7839  }
7840 }
7841 
7842 // static method
7844  const int p, const double l1, const double l2,
7845  double *dshape_1d, double *dshape)
7846 {
7847  const int dof = ((p + 1)*(p + 2))/2;
7848  const double l3 = 1. - l1 - l2;
7849 
7850  const int *bp = Poly_1D::Binom(p);
7851  double z = 1.;
7852  for (int o = 0, j = 0; j <= p; j++)
7853  {
7854  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
7855  double s = bp[j]*z;
7856  for (int i = 0; i <= p - j; i++)
7857  {
7858  dshape[o++] = s*dshape_1d[i];
7859  }
7860  z *= l2;
7861  }
7862  z = 1.;
7863  for (int i = 0; i <= p; i++)
7864  {
7865  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
7866  double s = bp[i]*z;
7867  for (int o = i, j = 0; j <= p - i; j++)
7868  {
7869  dshape[dof + o] = s*dshape_1d[j];
7870  o += p + 1 - j;
7871  }
7872  z *= l1;
7873  }
7874 }
7875 
7877  Vector &shape) const
7878 {
7879 #ifdef MFEM_THREAD_SAFE
7880  Vector m_shape(Dof);
7881 #endif
7882  CalcShape(Order, ip.x, ip.y, m_shape.GetData());
7883  for (int i = 0; i < Dof; i++)
7884  {
7885  shape(dof_map[i]) = m_shape(i);
7886  }
7887 }
7888 
7890  DenseMatrix &dshape) const
7891 {
7892 #ifdef MFEM_THREAD_SAFE
7893  Vector dshape_1d(Order + 1);
7895 #endif
7896  CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(), m_dshape.Data());
7897  for (int d = 0; d < 2; d++)
7898  {
7899  for (int i = 0; i < Dof; i++)
7900  {
7901  dshape(dof_map[i],d) = m_dshape(i,d);
7902  }
7903  }
7904 }
7905 
7906 
7908  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
7909  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
7910 {
7911 #ifndef MFEM_THREAD_SAFE
7912  m_shape.SetSize(Dof);
7913  dshape_1d.SetSize(p + 1);
7914  m_dshape.SetSize(Dof, Dim);
7915 #endif
7916  dof_map.SetSize(Dof);
7917 
7918  struct Index
7919  {
7920  int p, dof;
7921  int tri(int k) { return (k*(k + 1))/2; }
7922  int tet(int k) { return (k*(k + 1)*(k + 2))/6; }
7923  Index(int p_) { p = p_; dof = tet(p + 1); }
7924  int operator()(int i, int j, int k)
7925  { return dof - tet(p - k) - tri(p + 1 - k - j) + i; }
7926  };
7927  Index idx(p);
7928 
7929  // vertices
7930  dof_map[idx(0,0,0)] = 0;
7931  Nodes.IntPoint(0).Set3(0., 0., 0.);
7932  dof_map[idx(p,0,0)] = 1;
7933  Nodes.IntPoint(1).Set3(1., 0., 0.);
7934  dof_map[idx(0,p,0)] = 2;
7935  Nodes.IntPoint(2).Set3(0., 1., 0.);
7936  dof_map[idx(0,0,p)] = 3;
7937  Nodes.IntPoint(3).Set3(0., 0., 1.);
7938 
7939  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7940  int o = 4;
7941  for (int i = 1; i < p; i++) // (0,1)
7942  {
7943  dof_map[idx(i,0,0)] = o;
7944  Nodes.IntPoint(o++).Set3(double(i)/p, 0., 0.);
7945  }
7946  for (int i = 1; i < p; i++) // (0,2)
7947  {
7948  dof_map[idx(0,i,0)] = o;
7949  Nodes.IntPoint(o++).Set3(0., double(i)/p, 0.);
7950  }
7951  for (int i = 1; i < p; i++) // (0,3)
7952  {
7953  dof_map[idx(0,0,i)] = o;
7954  Nodes.IntPoint(o++).Set3(0., 0., double(i)/p);
7955  }
7956  for (int i = 1; i < p; i++) // (1,2)
7957  {
7958  dof_map[idx(p-i,i,0)] = o;
7959  Nodes.IntPoint(o++).Set3(double(p-i)/p, double(i)/p, 0.);
7960  }
7961  for (int i = 1; i < p; i++) // (1,3)
7962  {
7963  dof_map[idx(p-i,0,i)] = o;
7964  Nodes.IntPoint(o++).Set3(double(p-i)/p, 0., double(i)/p);
7965  }
7966  for (int i = 1; i < p; i++) // (2,3)
7967  {
7968  dof_map[idx(0,p-i,i)] = o;
7969  Nodes.IntPoint(o++).Set3(0., double(p-i)/p, double(i)/p);
7970  }
7971 
7972  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7973  for (int j = 1; j < p; j++)
7974  for (int i = 1; i + j < p; i++) // (1,2,3)
7975  {
7976  dof_map[idx(p-i-j,i,j)] = o;
7977  Nodes.IntPoint(o++).Set3(double(p-i-j)/p, double(i)/p, double(j)/p);
7978  }
7979  for (int j = 1; j < p; j++)
7980  for (int i = 1; i + j < p; i++) // (0,3,2)
7981  {
7982  dof_map[idx(0,j,i)] = o;
7983  Nodes.IntPoint(o++).Set3(0., double(j)/p, double(i)/p);
7984  }
7985  for (int j = 1; j < p; j++)
7986  for (int i = 1; i + j < p; i++) // (0,1,3)
7987  {
7988  dof_map[idx(i,0,j)] = o;
7989  Nodes.IntPoint(o++).Set3(double(i)/p, 0., double(j)/p);
7990  }
7991  for (int j = 1; j < p; j++)
7992  for (int i = 1; i + j < p; i++) // (0,2,1)
7993  {
7994  dof_map[idx(j,i,0)] = o;
7995  Nodes.IntPoint(o++).Set3(double(j)/p, double(i)/p, 0.);
7996  }
7997 
7998  // interior
7999  for (int k = 1; k < p; k++)
8000  for (int j = 1; j + k < p; j++)
8001  for (int i = 1; i + j + k < p; i++)
8002  {
8003  dof_map[idx(i,j,k)] = o;
8004  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8005  }
8006 }
8007 
8008 // static method
8010  const int p, const double l1, const double l2, const double l3,
8011  double *shape)
8012 {
8013  const double l4 = 1. - l1 - l2 - l3;
8014 
8015  // The basis functions are the terms in the expansion:
8016  // (l1 + l2 + l3 + l4)^p =
8017  // \sum_{k=0}^p \binom{p}{k} l3^k
8018  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8019  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8020  const int *bp = Poly_1D::Binom(p);
8021  double l3k = 1.;
8022  for (int o = 0, k = 0; k <= p; k++)
8023  {
8024  const int *bpk = Poly_1D::Binom(p - k);
8025  const double ek = bp[k]*l3k;
8026  double l2j = 1.;
8027  for (int j = 0; j <= p - k; j++)
8028  {
8029  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape[o]);
8030  double ekj = ek*bpk[j]*l2j;
8031  for (int i = 0; i <= p - k - j; i++)
8032  {
8033  shape[o++] *= ekj;
8034  }
8035  l2j *= l2;
8036  }
8037  l3k *= l3;
8038  }
8039 }
8040 
8041 // static method
8043  const int p, const double l1, const double l2, const double l3,
8044  double *dshape_1d, double *dshape)
8045 {
8046  const int dof = ((p + 1)*(p + 2)*(p + 3))/6;
8047  const double l4 = 1. - l1 - l2 - l3;
8048 
8049  // For the x derivatives, differentiate the terms of the expression:
8050  // \sum_{k=0}^p \binom{p}{k} l3^k
8051  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8052  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8053  const int *bp = Poly_1D::Binom(p);
8054  double l3k = 1.;
8055  for (int o = 0, k = 0; k <= p; k++)
8056  {
8057  const int *bpk = Poly_1D::Binom(p - k);
8058  const double ek = bp[k]*l3k;
8059  double l2j = 1.;
8060  for (int j = 0; j <= p - k; j++)
8061  {
8062  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
8063  double ekj = ek*bpk[j]*l2j;
8064  for (int i = 0; i <= p - k - j; i++)
8065  {
8066  dshape[o++] = dshape_1d[i]*ekj;
8067  }
8068  l2j *= l2;
8069  }
8070  l3k *= l3;
8071  }
8072  // For the y derivatives, differentiate the terms of the expression:
8073  // \sum_{k=0}^p \binom{p}{k} l3^k
8074  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
8075  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
8076  l3k = 1.;
8077  for (int ok = 0, k = 0; k <= p; k++)
8078  {
8079  const int *bpk = Poly_1D::Binom(p - k);
8080  const double ek = bp[k]*l3k;
8081  double l1i = 1.;
8082  for (int i = 0; i <= p - k; i++)
8083  {
8084  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
8085  double eki = ek*bpk[i]*l1i;
8086  int o = ok + i;
8087  for (int j = 0; j <= p - k - i; j++)
8088  {
8089  dshape[dof + o] = dshape_1d[j]*eki;
8090  o += p - k - j + 1;
8091  }
8092  l1i *= l1;
8093  }
8094  l3k *= l3;
8095  ok += ((p - k + 2)*(p - k + 1))/2;
8096  }
8097  // For the z derivatives, differentiate the terms of the expression:
8098  // \sum_{j=0}^p \binom{p}{j} l2^j
8099  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
8100  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
8101  double l2j = 1.;
8102  for (int j = 0; j <= p; j++)
8103  {
8104  const int *bpj = Poly_1D::Binom(p - j);
8105  const double ej = bp[j]*l2j;
8106  double l1i = 1.;
8107  for (int i = 0; i <= p - j; i++)
8108  {
8109  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
8110  double eji = ej*bpj[i]*l1i;
8111  int m = ((p + 2)*(p + 1))/2;
8112  int n = ((p - j + 2)*(p - j + 1))/2;
8113  for (int o = i, k = 0; k <= p - j - i; k++)
8114  {
8115  // m = ((p - k + 2)*(p - k + 1))/2;
8116  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
8117  o += m;
8118  dshape[2*dof + o - n] = dshape_1d[k]*eji;
8119  m -= p - k + 1;
8120  n -= p - k - j + 1;
8121  }
8122  l1i *= l1;
8123  }
8124  l2j *= l2;
8125  }
8126 }
8127 
8129  Vector &shape) const
8130 {
8131 #ifdef MFEM_THREAD_SAFE
8132  Vector m_shape(Dof);
8133 #endif
8134  CalcShape(Order, ip.x, ip.y, ip.z, m_shape.GetData());
8135  for (int i = 0; i < Dof; i++)
8136  {
8137  shape(dof_map[i]) = m_shape(i);
8138  }
8139 }
8140 
8142  DenseMatrix &dshape) const
8143 {
8144 #ifdef MFEM_THREAD_SAFE
8145  Vector dshape_1d(Order + 1);
8147 #endif
8148  CalcDShape(Order, ip.x, ip.y, ip.z, dshape_1d.GetData(), m_dshape.Data());
8149  for (int d = 0; d < 3; d++)
8150  {
8151  for (int i = 0; i < Dof; i++)
8152  {
8153  dshape(dof_map[i],d) = m_dshape(i,d);
8154  }
8155  }
8156 }
8157 
8158 
8159 L2_SegmentElement::L2_SegmentElement(const int p, const int type)
8160  : NodalFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
8161  type(VerifyOpen(type)),
8162  basis1d(poly1d.OpenBasis(p, type))
8163 {
8164  const double *op = poly1d.OpenPoints(p, type);
8165 
8166 #ifndef MFEM_THREAD_SAFE
8167  shape_x.SetSize(p + 1);
8168  dshape_x.SetDataAndSize(NULL, p + 1);
8169 #endif
8170 
8171  for (int i = 0; i <= p; i++)
8172  {
8173  Nodes.IntPoint(i).x = op[i];
8174  }
8175 }
8176 
8178  Vector &shape) const
8179 {
8180  basis1d.Eval(ip.x, shape);
8181 }
8182 
8184  DenseMatrix &dshape) const
8185 {
8186 #ifdef MFEM_THREAD_SAFE
8187  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8188 #else
8189  dshape_x.SetData(dshape.Data());
8190 #endif
8191  basis1d.Eval(ip.x, shape_x, dshape_x);
8192 }
8193 
8194 void L2_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8195 {
8196  const int p = Order;
8197  const double *op = poly1d.OpenPoints(p,type);
8198 
8199  switch (vertex)
8200  {
8201  case 0:
8202  for (int i = 0; i <= p; i++)
8203  {
8204  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8205  }
8206  break;
8207 
8208  case 1:
8209  for (int i = 0; i <= p; i++)
8210  {
8211  dofs(i) = poly1d.CalcDelta(p,op[i]);
8212  }
8213  break;
8214  }
8215 }
8216 
8217 
8219  : PositiveFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk)
8220 {
8221 #ifndef MFEM_THREAD_SAFE
8222  shape_x.SetSize(p + 1);
8223  dshape_x.SetDataAndSize(NULL, p + 1);
8224 #endif
8225 
8226  if (p == 0)
8227  {
8228  Nodes.IntPoint(0).x = 0.5;
8229  }
8230  else
8231  {
8232  for (int i = 0; i <= p; i++)
8233  {
8234  Nodes.IntPoint(i).x = double(i)/p;
8235  }
8236  }
8237 }
8238 
8240  Vector &shape) const
8241 {
8242  Poly_1D::CalcBernstein(Order, ip.x, shape);
8243 }
8244 
8246  DenseMatrix &dshape) const
8247 {
8248 #ifdef MFEM_THREAD_SAFE
8249  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8250 #else
8251  dshape_x.SetData(dshape.Data());
8252 #endif
8253  Poly_1D::CalcBernstein(Order, ip.x, shape_x, dshape_x);
8254 }
8255 
8256 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8257 {
8258  dofs = 0.0;
8259  dofs[vertex*Order] = 1.0;
8260 }
8261 
8262 
8264  : NodalFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
8265  FunctionSpace::Qk),
8266  type(VerifyOpen(_type)),
8267  basis1d(poly1d.OpenBasis(p, type))
8268 {
8269  const double *op = poly1d.OpenPoints(p, type);
8270 
8271 #ifndef MFEM_THREAD_SAFE
8272  shape_x.SetSize(p + 1);
8273  shape_y.SetSize(p + 1);
8274  dshape_x.SetSize(p + 1);
8275  dshape_y.SetSize(p + 1);
8276 #endif
8277 
8278  for (int o = 0, j = 0; j <= p; j++)
8279  for (int i = 0; i <= p; i++)
8280  {
8281  Nodes.IntPoint(o++).Set2(op[i], op[j]);
8282  }
8283 }
8284 
8286  Vector &shape) const
8287 {
8288  const int p = Order;
8289 
8290 #ifdef MFEM_THREAD_SAFE
8291  Vector shape_x(p+1), shape_y(p+1);
8292 #endif
8293 
8294  basis1d.Eval(ip.x, shape_x);
8295  basis1d.Eval(ip.y, shape_y);
8296 
8297  for (int o = 0, j = 0; j <= p; j++)
8298  for (int i = 0; i <= p; i++)
8299  {
8300  shape(o++) = shape_x(i)*shape_y(j);
8301  }
8302 }
8303 
8305  DenseMatrix &dshape) const
8306 {
8307  const int p = Order;
8308 
8309 #ifdef MFEM_THREAD_SAFE
8310  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8311 #endif
8312 
8313  basis1d.Eval(ip.x, shape_x, dshape_x);
8314  basis1d.Eval(ip.y, shape_y, dshape_y);
8315 
8316  for (int o = 0, j = 0; j <= p; j++)
8317  for (int i = 0; i <= p; i++)
8318  {
8319  dshape(o,0) = dshape_x(i)* shape_y(j);
8320  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8321  }
8322 }
8323 
8324 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
8325 {
8326  const int p = Order;
8327  const double *op = poly1d.OpenPoints(p, type);
8328 
8329 #ifdef MFEM_THREAD_SAFE
8330  Vector shape_x(p+1), shape_y(p+1);
8331 #endif
8332 
8333  for (int i = 0; i <= p; i++)
8334  {
8335  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8336  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8337  }
8338 
8339  switch (vertex)
8340  {
8341  case 0:
8342  for (int o = 0, j = 0; j <= p; j++)
8343  for (int i = 0; i <= p; i++)
8344  {
8345  dofs[o++] = shape_x(i)*shape_x(j);
8346  }
8347  break;
8348  case 1:
8349  for (int o = 0, j = 0; j <= p; j++)
8350  for (int i = 0; i <= p; i++)
8351  {
8352  dofs[o++] = shape_y(i)*shape_x(j);
8353  }
8354  break;
8355  case 2:
8356  for (int o = 0, j = 0; j <= p; j++)
8357  for (int i = 0; i <= p; i++)
8358  {
8359  dofs[o++] = shape_y(i)*shape_y(j);
8360  }
8361  break;
8362  case 3:
8363  for (int o = 0, j = 0; j <= p; j++)
8364  for (int i = 0; i <= p; i++)
8365  {
8366  dofs[o++] = shape_x(i)*shape_y(j);
8367  }
8368  break;
8369  }
8370 }
8371 
8372 
8374  : PositiveFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
8375  FunctionSpace::Qk)
8376 {
8377 #ifndef MFEM_THREAD_SAFE
8378  shape_x.SetSize(p + 1);
8379  shape_y.SetSize(p + 1);
8380  dshape_x.SetSize(p + 1);
8381  dshape_y.SetSize(p + 1);
8382 #endif
8383 
8384  if (p == 0)
8385  {
8386  Nodes.IntPoint(0).Set2(0.5, 0.5);
8387  }
8388  else
8389  {
8390  for (int o = 0, j = 0; j <= p; j++)
8391  for (int i = 0; i <= p; i++)
8392  {
8393  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8394  }
8395  }
8396 }
8397 
8399  Vector &shape) const
8400 {
8401  const int p = Order;
8402 
8403 #ifdef MFEM_THREAD_SAFE
8404  Vector shape_x(p+1), shape_y(p+1);
8405 #endif
8406 
8407  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8408  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8409 
8410  for (int o = 0, j = 0; j <= p; j++)
8411  for (int i = 0; i <= p; i++)
8412  {
8413  shape(o++) = shape_x(i)*shape_y(j);
8414  }
8415 }
8416 
8418  DenseMatrix &dshape) const
8419 {
8420  const int p = Order;
8421 
8422 #ifdef MFEM_THREAD_SAFE
8423  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8424 #endif
8425 
8426  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8427  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8428 
8429  for (int o = 0, j = 0; j <= p; j++)
8430  for (int i = 0; i <= p; i++)
8431  {
8432  dshape(o,0) = dshape_x(i)* shape_y(j);
8433  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8434  }
8435 }
8436 
8438 {
8439  const int p = Order;
8440 
8441  dofs = 0.0;
8442  switch (vertex)
8443  {
8444  case 0: dofs[0] = 1.0; break;
8445  case 1: dofs[p] = 1.0; break;
8446  case 2: dofs[p*(p + 2)] = 1.0; break;
8447  case 3: dofs[p*(p + 1)] = 1.0; break;
8448  }
8449 }
8450 
8451 
8452 L2_HexahedronElement::L2_HexahedronElement(const int p, const int _type)
8453  : NodalFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
8454  FunctionSpace::Qk),
8455  type(VerifyOpen(_type)),
8456  basis1d(poly1d.OpenBasis(p, type))
8457 {
8458  const double *op = poly1d.OpenPoints(p, type);
8459 
8460 #ifndef MFEM_THREAD_SAFE
8461  shape_x.SetSize(p + 1);
8462  shape_y.SetSize(p + 1);
8463  shape_z.SetSize(p + 1);
8464  dshape_x.SetSize(p + 1);
8465  dshape_y.SetSize(p + 1);
8466  dshape_z.SetSize(p + 1);
8467 #endif
8468 
8469  for (int o = 0, k = 0; k <= p; k++)
8470  for (int j = 0; j <= p; j++)
8471  for (int i = 0; i <= p; i++)
8472  {
8473  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
8474  }
8475 }
8476 
8478  Vector &shape) const
8479 {
8480  const int p = Order;
8481 
8482 #ifdef MFEM_THREAD_SAFE
8483  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8484 #endif
8485 
8486  basis1d.Eval(ip.x, shape_x);
8487  basis1d.Eval(ip.y, shape_y);
8488  basis1d.Eval(ip.z, shape_z);
8489 
8490  for (int o = 0, k = 0; k <= p; k++)
8491  for (int j = 0; j <= p; j++)
8492  for (int i = 0; i <= p; i++)
8493  {
8494  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8495  }
8496 }
8497 
8499  DenseMatrix &dshape) const
8500 {
8501  const int p = Order;
8502 
8503 #ifdef MFEM_THREAD_SAFE
8504  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8505  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8506 #endif
8507 
8508  basis1d.Eval(ip.x, shape_x, dshape_x);
8509  basis1d.Eval(ip.y, shape_y, dshape_y);
8510  basis1d.Eval(ip.z, shape_z, dshape_z);
8511 
8512  for (int o = 0, k = 0; k <= p; k++)
8513  for (int j = 0; j <= p; j++)
8514  for (int i = 0; i <= p; i++)
8515  {
8516  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8517  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8518  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8519  }
8520 }
8521 
8522 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8523 {
8524  const int p = Order;
8525  const double *op = poly1d.OpenPoints(p, type);
8526 
8527 #ifdef MFEM_THREAD_SAFE
8528  Vector shape_x(p+1), shape_y(p+1);
8529 #endif
8530 
8531  for (int i = 0; i <= p; i++)
8532  {
8533  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8534  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8535  }
8536 
8537  switch (vertex)
8538  {
8539  case 0:
8540  for (int o = 0, k = 0; k <= p; k++)
8541  for (int j = 0; j <= p; j++)
8542  for (int i = 0; i <= p; i++)
8543  {
8544  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
8545  }
8546  break;
8547  case 1:
8548  for (int o = 0, k = 0; k <= p; k++)
8549  for (int j = 0; j <= p; j++)
8550  for (int i = 0; i <= p; i++)
8551  {
8552  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
8553  }
8554  break;
8555  case 2:
8556  for (int o = 0, k = 0; k <= p; k++)
8557  for (int j = 0; j <= p; j++)
8558  for (int i = 0; i <= p; i++)
8559  {
8560  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
8561  }
8562  break;
8563  case 3:
8564  for (int o = 0, k = 0; k <= p; k++)
8565  for (int j = 0; j <= p; j++)
8566  for (int i = 0; i <= p; i++)
8567  {
8568  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
8569  }
8570  break;
8571  case 4:
8572  for (int o = 0, k = 0; k <= p; k++)
8573  for (int j = 0; j <= p; j++)
8574  for (int i = 0; i <= p; i++)
8575  {
8576  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
8577  }
8578  break;
8579  case 5:
8580  for (int o = 0, k = 0; k <= p; k++)
8581  for (int j = 0; j <= p; j++)
8582  for (int i = 0; i <= p; i++)
8583  {
8584  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
8585  }
8586  break;
8587  case 6:
8588  for (int o = 0, k = 0; k <= p; k++)
8589  for (int j = 0; j <= p; j++)
8590  for (int i = 0; i <= p; i++)
8591  {
8592  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
8593  }
8594  break;
8595  case 7:
8596  for (int o = 0, k = 0; k <= p; k++)
8597  for (int j = 0; j <= p; j++)
8598  for (int i = 0; i <= p; i++)
8599  {
8600  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
8601  }
8602  break;
8603  }
8604 }
8605 
8606 
8608  : PositiveFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
8609  FunctionSpace::Qk)
8610 {
8611 #ifndef MFEM_THREAD_SAFE
8612  shape_x.SetSize(p + 1);
8613  shape_y.SetSize(p + 1);
8614  shape_z.SetSize(p + 1);
8615  dshape_x.SetSize(p + 1);
8616  dshape_y.SetSize(p + 1);
8617  dshape_z.SetSize(p + 1);
8618 #endif
8619 
8620  if (p == 0)
8621  {
8622  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
8623  }
8624  else
8625  {
8626  for (int o = 0, k = 0; k <= p; k++)
8627  for (int j = 0; j <= p; j++)
8628  for (int i = 0; i <= p; i++)
8629  {
8630  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8631  }
8632  }
8633 }
8634 
8636  Vector &shape) const
8637 {
8638  const int p = Order;
8639 
8640 #ifdef MFEM_THREAD_SAFE
8641  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8642 #endif
8643 
8644  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8645  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8646  Poly_1D::CalcBernstein(p, ip.z, shape_z);
8647 
8648  for (int o = 0, k = 0; k <= p; k++)
8649  for (int j = 0; j <= p; j++)
8650  for (int i = 0; i <= p; i++)
8651  {
8652  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8653  }
8654 }
8655 
8657  DenseMatrix &dshape) const
8658 {
8659  const int p = Order;
8660 
8661 #ifdef MFEM_THREAD_SAFE
8662  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8663  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8664 #endif
8665 
8666  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8667  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8668  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
8669 
8670  for (int o = 0, k = 0; k <= p; k++)
8671  for (int j = 0; j <= p; j++)
8672  for (int i = 0; i <= p; i++)
8673  {
8674  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8675  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8676  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8677  }
8678 }
8679 
8680 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8681 {
8682  const int p = Order;
8683 
8684  dofs = 0.0;
8685  switch (vertex)
8686  {
8687  case 0: dofs[0] = 1.0; break;
8688  case 1: dofs[p] = 1.0; break;
8689  case 2: dofs[p*(p + 2)] = 1.0; break;
8690  case 3: dofs[p*(p + 1)] = 1.0; break;
8691  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
8692  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
8693  case 6: dofs[Dof - 1] = 1.0; break;
8694  case 7: dofs[Dof - p - 1] = 1.0; break;
8695  }
8696 }
8697 
8698 
8699 L2_TriangleElement::L2_TriangleElement(const int p, const int type)
8700  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8701  FunctionSpace::Pk)
8702 {
8703  const double *op = poly1d.OpenPoints(p, VerifyOpen(type));
8704 
8705 #ifndef MFEM_THREAD_SAFE
8706  shape_x.SetSize(p + 1);
8707  shape_y.SetSize(p + 1);
8708  shape_l.SetSize(p + 1);
8709  dshape_x.SetSize(p + 1);
8710  dshape_y.SetSize(p + 1);
8711  dshape_l.SetSize(p + 1);
8712  u.SetSize(Dof);
8713  du.SetSize(Dof, Dim);
8714 #else
8715  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8716 #endif
8717 
8718  for (int o = 0, j = 0; j <= p; j++)
8719  for (int i = 0; i + j <= p; i++)
8720  {
8721  double w = op[i] + op[j] + op[p-i-j];
8722  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
8723  }
8724 
8725  DenseMatrix T(Dof);
8726  for (int k = 0; k < Dof; k++)
8727  {
8728  IntegrationPoint &ip = Nodes.IntPoint(k);
8729  poly1d.CalcBasis(p, ip.x, shape_x);
8730  poly1d.CalcBasis(p, ip.y, shape_y);
8731  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8732 
8733  for (int o = 0, j = 0; j <= p; j++)
8734  for (int i = 0; i + j <= p; i++)
8735  {
8736  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8737  }
8738  }
8739 
8740  Ti.Factor(T);
8741  // mfem::out << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
8742 }
8743 
8745  Vector &shape) const
8746 {
8747  const int p = Order;
8748 
8749 #ifdef MFEM_THREAD_SAFE
8750  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
8751 #endif
8752 
8753  poly1d.CalcBasis(p, ip.x, shape_x);
8754  poly1d.CalcBasis(p, ip.y, shape_y);
8755  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8756 
8757  for (int o = 0, j = 0; j <= p; j++)
8758  for (int i = 0; i + j <= p; i++)
8759  {
8760  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8761  }
8762 
8763  Ti.Mult(u, shape);
8764 }
8765 
8767  DenseMatrix &dshape) const
8768 {
8769  const int p = Order;
8770 
8771 #ifdef MFEM_THREAD_SAFE
8772  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8773  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8774  DenseMatrix du(Dof, Dim);
8775 #endif
8776 
8777  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8778  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8779  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
8780 
8781  for (int o = 0, j = 0; j <= p; j++)
8782  for (int i = 0; i + j <= p; i++)
8783  {
8784  int k = p - i - j;
8785  du(o,0) = ((dshape_x(i)* shape_l(k)) -
8786  ( shape_x(i)*dshape_l(k)))*shape_y(j);
8787  du(o,1) = ((dshape_y(j)* shape_l(k)) -
8788  ( shape_y(j)*dshape_l(k)))*shape_x(i);
8789  o++;
8790  }
8791 
8792  Ti.Mult(du, dshape);
8793 }
8794 
8795 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8796 {
8797  switch (vertex)
8798  {
8799  case 0:
8800  for (int i = 0; i < Dof; i++)
8801  {
8802  const IntegrationPoint &ip = Nodes.IntPoint(i);
8803  dofs[i] = pow(1.0 - ip.x - ip.y, Order);
8804  }
8805  break;
8806  case 1:
8807  for (int i = 0; i < Dof; i++)
8808  {
8809  const IntegrationPoint &ip = Nodes.IntPoint(i);
8810  dofs[i] = pow(ip.x, Order);
8811  }
8812  break;
8813  case 2:
8814  for (int i = 0; i < Dof; i++)
8815  {
8816  const IntegrationPoint &ip = Nodes.IntPoint(i);
8817  dofs[i] = pow(ip.y, Order);
8818  }
8819  break;
8820  }
8821 }
8822 
8823 
8825  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8826  FunctionSpace::Pk)
8827 {
8828 #ifndef MFEM_THREAD_SAFE
8829  dshape_1d.SetSize(p + 1);
8830 #endif
8831 
8832  if (p == 0)
8833  {
8834  Nodes.IntPoint(0).Set2(1./3, 1./3);
8835  }
8836  else
8837  {
8838  for (int o = 0, j = 0; j <= p; j++)
8839  for (int i = 0; i + j <= p; i++)
8840  {
8841  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8842  }
8843  }
8844 }
8845 
8847  Vector &shape) const
8848 {
8849  H1Pos_TriangleElement::CalcShape(Order, ip.x, ip.y, shape.GetData());
8850 }
8851 
8853  DenseMatrix &dshape) const
8854 {
8855 #ifdef MFEM_THREAD_SAFE
8856  Vector dshape_1d(Order + 1);
8857 #endif
8858 
8859  H1Pos_TriangleElement::CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(),
8860  dshape.Data());
8861 }
8862 
8863 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8864 {
8865  dofs = 0.0;
8866  switch (vertex)
8867  {
8868  case 0: dofs[0] = 1.0; break;
8869  case 1: dofs[Order] = 1.0; break;
8870  case 2: dofs[Dof-1] = 1.0; break;
8871  }
8872 }
8873 
8874 
8876  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
8877  p, FunctionSpace::Pk)
8878 {
8879  const double *op = poly1d.OpenPoints(p, VerifyOpen(type));
8880 
8881 #ifndef MFEM_THREAD_SAFE
8882  shape_x.SetSize(p + 1);
8883  shape_y.SetSize(p + 1);
8884  shape_z.SetSize(p + 1);
8885  shape_l.SetSize(p + 1);
8886  dshape_x.SetSize(p + 1);
8887  dshape_y.SetSize(p + 1);
8888  dshape_z.SetSize(p + 1);
8889  dshape_l.SetSize(p + 1);
8890  u.SetSize(Dof);
8891  du.SetSize(Dof, Dim);
8892 #else
8893  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8894 #endif
8895 
8896  for (int o = 0, k = 0; k <= p; k++)
8897  for (int j = 0; j + k <= p; j++)
8898  for (int i = 0; i + j + k <= p; i++)
8899  {
8900  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
8901  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
8902  }
8903 
8904  DenseMatrix T(Dof);
8905  for (int m = 0; m < Dof; m++)
8906  {
8907  IntegrationPoint &ip = Nodes.IntPoint(m);
8908  poly1d.CalcBasis(p, ip.x, shape_x);
8909  poly1d.CalcBasis(p, ip.y, shape_y);
8910  poly1d.CalcBasis(p, ip.z, shape_z);
8911  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8912 
8913  for (int o = 0, k = 0; k <= p; k++)
8914  for (int j = 0; j + k <= p; j++)
8915  for (int i = 0; i + j + k <= p; i++)
8916  {
8917  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8918  }
8919  }
8920 
8921  Ti.Factor(T);
8922  // mfem::out << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8923 }
8924 
8926  Vector &shape) const
8927 {
8928  const int p = Order;
8929 
8930 #ifdef MFEM_THREAD_SAFE
8931  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8932  Vector u(Dof);
8933 #endif
8934 
8935  poly1d.CalcBasis(p, ip.x, shape_x);
8936  poly1d.CalcBasis(p, ip.y, shape_y);
8937  poly1d.CalcBasis(p, ip.z, shape_z);
8938  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8939 
8940  for (int o = 0, k = 0; k <= p; k++)
8941  for (int j = 0; j + k <= p; j++)
8942  for (int i = 0; i + j + k <= p; i++)
8943  {
8944  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8945  }
8946 
8947  Ti.Mult(u, shape);
8948 }
8949 
8951  DenseMatrix &dshape) const
8952 {
8953  const int p = Order;
8954 
8955 #ifdef MFEM_THREAD_SAFE
8956  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8957  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8958  DenseMatrix du(Dof, Dim);
8959 #endif
8960 
8961  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8962  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8963  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
8964  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
8965 
8966  for (int o = 0, k = 0; k <= p; k++)
8967  for (int j = 0; j + k <= p; j++)
8968  for (int i = 0; i + j + k <= p; i++)
8969  {
8970  int l = p - i - j - k;
8971  du(o,0) = ((dshape_x(i)* shape_l(l)) -
8972  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
8973  du(o,1) = ((dshape_y(j)* shape_l(l)) -
8974  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
8975  du(o,2) = ((dshape_z(k)* shape_l(l)) -
8976  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
8977  o++;
8978  }
8979 
8980  Ti.Mult(du, dshape);
8981 }
8982 
8983 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8984 {
8985  switch (vertex)
8986  {
8987  case 0:
8988  for (int i = 0; i < Dof; i++)
8989  {
8990  const IntegrationPoint &ip = Nodes.IntPoint(i);
8991  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, Order);
8992  }
8993  break;
8994  case 1:
8995  for (int i = 0; i < Dof; i++)
8996  {
8997  const IntegrationPoint &ip = Nodes.IntPoint(i);
8998  dofs[i] = pow(ip.x, Order);
8999  }
9000  break;
9001  case 2:
9002  for (int i = 0; i < Dof; i++)
9003  {
9004  const IntegrationPoint &ip = Nodes.IntPoint(i);
9005  dofs[i] = pow(ip.y, Order);
9006  }
9007  case 3:
9008  for (int i = 0; i < Dof; i++)
9009  {
9010  const IntegrationPoint &ip = Nodes.IntPoint(i);
9011  dofs[i] = pow(ip.z, Order);
9012  }
9013  break;
9014  }
9015 }
9016 
9017 
9019  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
9020  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
9021 {
9022 #ifndef MFEM_THREAD_SAFE
9023  dshape_1d.SetSize(p + 1);
9024 #endif
9025 
9026  if (p == 0)
9027  {
9028  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
9029  }
9030  else
9031  {
9032  for (int o = 0, k = 0; k <= p; k++)
9033  for (int j = 0; j + k <= p; j++)
9034  for (int i = 0; i + j + k <= p; i++)
9035  {
9036  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
9037  }
9038  }
9039 }
9040 
9042  Vector &shape) const
9043 {
9045  shape.GetData());
9046 }
9047 
9049  DenseMatrix &dshape) const
9050 {
9051 #ifdef MFEM_THREAD_SAFE
9052  Vector dshape_1d(Order + 1);
9053 #endif
9054 
9056  dshape_1d.GetData(), dshape.Data());
9057 }
9058 
9059 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9060 {
9061  dofs = 0.0;
9062  switch (vertex)
9063  {
9064  case 0: dofs[0] = 1.0; break;
9065  case 1: dofs[Order] = 1.0; break;
9066  case 2: dofs[(Order*(Order+3))/2] = 1.0; break;
9067  case 3: dofs[Dof-1] = 1.0; break;
9068  }
9069 }
9070 
9071 
9072 const double RT_QuadrilateralElement::nk[8] =
9073 { 0., -1., 1., 0., 0., 1., -1., 0. };
9074 
9076  const int cp_type,
9077  const int op_type)
9078  : VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p + 1,
9079  H_DIV, FunctionSpace::Qk),
9080  cbasis1d(poly1d.ClosedBasis(p + 1, VerifyClosed(cp_type))),
9081  obasis1d(poly1d.OpenBasis(p, VerifyOpen(op_type))),
9082  dof_map(Dof), dof2nk(Dof)
9083 {
9084  const double *cp = poly1d.ClosedPoints(p + 1, cp_type);
9085  const double *op = poly1d.OpenPoints(p, op_type);
9086  const int dof2 = Dof/2;
9087 
9088 #ifndef MFEM_THREAD_SAFE
9089  shape_cx.SetSize(p + 2);
9090  shape_ox.SetSize(p + 1);
9091  shape_cy.SetSize(p + 2);
9092  shape_oy.SetSize(p + 1);
9093  dshape_cx.SetSize(p + 2);
9094  dshape_cy.SetSize(p + 2);
9095 #endif
9096 
9097  // edges
9098  int o = 0;
9099  for (int i = 0; i <= p; i++) // (0,1)
9100  {
9101  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
9102  }
9103  for (int i = 0; i <= p; i++) // (1,2)
9104  {
9105  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
9106  }
9107  for (int i = 0; i <= p; i++) // (2,3)
9108  {
9109  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
9110  }
9111  for (int i = 0; i <= p; i++) // (3,0)
9112  {
9113  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
9114  }
9115 
9116  // interior
9117  for (int j = 0; j <= p; j++) // x-components
9118  for (int i = 1; i <= p; i++)
9119  {
9120  dof_map[0*dof2 + i + j*(p + 2)] = o++;
9121  }
9122  for (int j = 1; j <= p; j++) // y-components
9123  for (int i = 0; i <= p; i++)
9124  {
9125  dof_map[1*dof2 + i + j*(p + 1)] = o++;
9126  }
9127 
9128  // dof orientations
9129  // x-components
9130  for (int j = 0; j <= p; j++)
9131  for (int i = 0; i <= p/2; i++)
9132  {
9133  int idx = 0*dof2 + i + j*(p + 2);
9134  dof_map[idx] = -1 - dof_map[idx];
9135  }
9136  if (p%2 == 1)
9137  for (int j = p/2 + 1; j <= p; j++)
9138  {
9139  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
9140  dof_map[idx] = -1 - dof_map[idx];
9141  }
9142  // y-components
9143  for (int j = 0; j <= p/2; j++)
9144  for (int i = 0; i <= p; i++)
9145  {
9146  int idx = 1*dof2 + i + j*(p + 1);
9147  dof_map[idx] = -1 - dof_map[idx];
9148  }
9149  if (p%2 == 1)
9150  for (int i = 0; i <= p/2; i++)
9151  {
9152  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
9153  dof_map[idx] = -1 - dof_map[idx];
9154  }
9155 
9156  o = 0;
9157  for (int j = 0; j <= p; j++)
9158  for (int i = 0; i <= p + 1; i++)
9159  {
9160  int idx;
9161  if ((idx = dof_map[o++]) < 0)
9162  {
9163  idx = -1 - idx;
9164  dof2nk[idx] = 3;
9165  }
9166  else
9167  {
9168  dof2nk[idx] = 1;
9169  }
9170  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
9171  }
9172  for (int j = 0; j <= p + 1; j++)
9173  for (int i = 0; i <= p; i++)
9174  {
9175  int idx;
9176  if ((idx = dof_map[o++]) < 0)
9177  {
9178  idx = -1 - idx;
9179  dof2nk[idx] = 0;
9180  }
9181  else
9182  {
9183  dof2nk[idx] = 2;
9184  }
9185  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
9186  }
9187 }
9188 
9190  DenseMatrix &shape) const
9191 {
9192  const int pp1 = Order;
9193 
9194 #ifdef MFEM_THREAD_SAFE
9195  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9196 #endif
9197 
9198  cbasis1d.Eval(ip.x, shape_cx);
9199  obasis1d.Eval(ip.x, shape_ox);
9200  cbasis1d.Eval(ip.y, shape_cy);
9201  obasis1d.Eval(ip.y, shape_oy);
9202 
9203  int o = 0;
9204  for (int j = 0; j < pp1; j++)
9205  for (int i = 0; i <= pp1; i++)
9206  {
9207  int idx, s;
9208  if ((idx = dof_map[o++]) < 0)
9209  {
9210  idx = -1 - idx, s = -1;
9211  }
9212  else
9213  {
9214  s = +1;
9215  }
9216  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
9217  shape(idx,1) = 0.;
9218  }
9219  for (int j = 0; j <= pp1; j++)
9220  for (int i = 0; i < pp1; i++)
9221  {
9222  int idx, s;
9223  if ((idx = dof_map[o++]) < 0)
9224  {
9225  idx = -1 - idx, s = -1;
9226  }
9227  else
9228  {
9229  s = +1;
9230  }
9231  shape(idx,0) = 0.;
9232  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
9233  }
9234 }
9235 
9237  Vector &divshape) const
9238 {
9239  const int pp1 = Order;
9240 
9241 #ifdef MFEM_THREAD_SAFE
9242  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9243  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
9244 #endif
9245 
9246  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9247  obasis1d.Eval(ip.x, shape_ox);
9248  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9249  obasis1d.Eval(ip.y, shape_oy);
9250 
9251  int o = 0;
9252  for (int j = 0; j < pp1; j++)
9253  for (int i = 0; i <= pp1; i++)
9254  {
9255  int idx, s;
9256  if ((idx = dof_map[o++]) < 0)
9257  {
9258  idx = -1 - idx, s = -1;
9259  }
9260  else
9261  {
9262  s = +1;
9263  }
9264  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
9265  }
9266  for (int j = 0; j <= pp1; j++)
9267  for (int i = 0; i < pp1; i++)
9268  {
9269  int idx, s;
9270  if ((idx = dof_map[o++]) < 0)
9271  {
9272  idx = -1 - idx, s = -1;
9273  }
9274  else
9275  {
9276  s = +1;
9277  }
9278  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
9279  }
9280 }
9281 
9282 
9283 const double RT_HexahedronElement::nk[18] =
9284 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
9285 
9287  const int cp_type,
9288  const int op_type)
9289  : VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 1)*(p + 2), p + 1,
9290  H_DIV, FunctionSpace::Qk),
9291  cbasis1d(poly1d.ClosedBasis(p + 1, VerifyClosed(cp_type))),
9292  obasis1d(poly1d.OpenBasis(p, VerifyOpen(op_type))),
9293  dof_map(Dof), dof2nk(Dof)
9294 {
9295  const double *cp = poly1d.ClosedPoints(p + 1, cp_type);
9296  const double *op = poly1d.OpenPoints(p, op_type);
9297  const int dof3 = Dof/3;
9298 
9299 #ifndef MFEM_THREAD_SAFE
9300  shape_cx.SetSize(p + 2);
9301  shape_ox.SetSize(p + 1);
9302  shape_cy.SetSize(p + 2);
9303  shape_oy.SetSize(p + 1);
9304  shape_cz.SetSize(p + 2);
9305  shape_oz.SetSize(p + 1);
9306  dshape_cx.SetSize(p + 2);
9307  dshape_cy.SetSize(p + 2);
9308  dshape_cz.SetSize(p + 2);
9309 #endif
9310 
9311  // faces
9312  int o = 0;
9313  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
9314  for (int i = 0; i <= p; i++)
9315  {
9316  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
9317  }
9318  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
9319  for (int i = 0; i <= p; i++)
9320  {
9321  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
9322  }
9323  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
9324  for (int i = 0; i <= p; i++)
9325  {
9326  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
9327  }
9328  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
9329  for (int i = 0; i <= p; i++)
9330  {
9331  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
9332  }
9333  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
9334  for (int i = 0; i <= p; i++)
9335  {
9336  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
9337  }
9338  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
9339  for (int i = 0; i <= p; i++)
9340  {
9341  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
9342  }
9343 
9344  // interior
9345  // x-components
9346  for (int k = 0; k <= p; k++)
9347  for (int j = 0; j <= p; j++)
9348  for (int i = 1; i <= p; i++)
9349  {
9350  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
9351  }
9352  // y-components
9353  for (int k = 0; k <= p; k++)
9354  for (int j = 1; j <= p; j++)
9355  for (int i = 0; i <= p; i++)
9356  {
9357  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
9358  }
9359  // z-components
9360  for (int k = 1; k <= p; k++)
9361  for (int j = 0; j <= p; j++)
9362  for (int i = 0; i <= p; i++)
9363  {
9364  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
9365  }
9366 
9367  // dof orientations
9368  // for odd p, do not change the orientations in the mid-planes
9369  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
9370  // respectively.
9371  // x-components
9372  for (int k = 0; k <= p; k++)
9373  for (int j = 0; j <= p; j++)
9374  for (int i = 0; i <= p/2; i++)
9375  {
9376  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
9377  dof_map[idx] = -1 - dof_map[idx];
9378  }
9379  // y-components
9380  for (int k = 0; k <= p; k++)
9381  for (int j = 0; j <= p/2; j++)
9382  for (int i = 0; i <= p; i++)
9383  {
9384  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
9385  dof_map[idx] = -1 - dof_map[idx];
9386  }
9387  // z-components
9388  for (int k = 0; k <= p/2; k++)
9389  for (int j = 0; j <= p; j++)
9390  for (int i = 0; i <= p; i++)
9391  {
9392  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
9393  dof_map[idx] = -1 - dof_map[idx];
9394  }
9395 
9396  o = 0;
9397  // x-components
9398  for (int k = 0; k <= p; k++)
9399  for (int j = 0; j <= p; j++)
9400  for (int i = 0; i <= p + 1; i++)
9401  {
9402  int idx;
9403  if ((idx = dof_map[o++]) < 0)
9404  {
9405  idx = -1 - idx;
9406  dof2nk[idx] = 4;
9407  }
9408  else
9409  {
9410  dof2nk[idx] = 2;
9411  }
9412  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
9413  }
9414  // y-components
9415  for (int k = 0; k <= p; k++)
9416  for (int j = 0; j <= p + 1; j++)
9417  for (int i = 0; i <= p; i++)
9418  {
9419  int idx;
9420  if ((idx = dof_map[o++]) < 0)
9421  {
9422  idx = -1 - idx;
9423  dof2nk[idx] = 1;
9424  }
9425  else
9426  {
9427  dof2nk[idx] = 3;
9428  }
9429  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
9430  }
9431  // z-components
9432  for (int k = 0; k <= p + 1; k++)
9433  for (int j = 0; j <= p; j++)
9434  for (int i = 0; i <= p; i++)
9435  {
9436  int idx;
9437  if ((idx = dof_map[o++]) < 0)
9438  {
9439  idx = -1 - idx;
9440  dof2nk[idx] = 0;
9441  }
9442  else
9443  {
9444  dof2nk[idx] = 5;
9445  }
9446  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
9447  }
9448 }
9449 
9451  DenseMatrix &shape) const
9452 {
9453  const int pp1 = Order;
9454 
9455 #ifdef MFEM_THREAD_SAFE
9456  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9457  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9458 #endif
9459 
9460  cbasis1d.Eval(ip.x, shape_cx);
9461  obasis1d.Eval(ip.x, shape_ox);
9462  cbasis1d.Eval(ip.y, shape_cy);
9463  obasis1d.Eval(ip.y, shape_oy);
9464  cbasis1d.Eval(ip.z, shape_cz);
9465  obasis1d.Eval(ip.z, shape_oz);
9466 
9467  int o = 0;
9468  // x-components
9469  for (int k = 0; k < pp1; k++)
9470  for (int j = 0; j < pp1; j++)
9471  for (int i = 0; i <= pp1; i++)
9472  {
9473  int idx, s;
9474  if ((idx = dof_map[o++]) < 0)
9475  {
9476  idx = -1 - idx, s = -1;
9477  }
9478  else
9479  {
9480  s = +1;
9481  }
9482  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
9483  shape(idx,1) = 0.;
9484  shape(idx,2) = 0.;
9485  }
9486  // y-components
9487  for (int k = 0; k < pp1; k++)
9488  for (int j = 0; j <= pp1; j++)
9489  for (int i = 0; i < pp1; i++)
9490  {
9491  int idx, s;
9492  if ((idx = dof_map[o++]) < 0)
9493  {
9494  idx = -1 - idx, s = -1;
9495  }
9496  else
9497  {
9498  s = +1;
9499  }
9500  shape(idx,0) = 0.;
9501  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
9502  shape(idx,2) = 0.;
9503  }
9504  // z-components
9505  for (int k = 0; k <= pp1; k++)
9506  for (int j = 0; j < pp1; j++)
9507  for (int i = 0; i < pp1; i++)
9508  {
9509  int idx, s;
9510  if ((idx = dof_map[o++]) < 0)
9511  {
9512  idx = -1 - idx, s = -1;
9513  }
9514  else
9515  {
9516  s = +1;
9517  }
9518  shape(idx,0) = 0.;
9519  shape(idx,1) = 0.;
9520  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
9521  }
9522 }
9523 
9525  Vector &divshape) const
9526 {
9527  const int pp1 = Order;
9528 
9529 #ifdef MFEM_THREAD_SAFE
9530  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9531  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9532  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
9533 #endif
9534 
9535  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9536  obasis1d.Eval(ip.x, shape_ox);
9537  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9538  obasis1d.Eval(ip.y, shape_oy);
9539  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
9540  obasis1d.Eval(ip.z, shape_oz);
9541 
9542  int o = 0;
9543  // x-components
9544  for (int k = 0; k < pp1; k++)
9545  for (int j = 0; j < pp1; j++)
9546  for (int i = 0; i <= pp1; i++)
9547  {
9548  int idx, s;
9549  if ((idx = dof_map[o++]) < 0)
9550  {
9551  idx = -1 - idx, s = -1;
9552  }
9553  else
9554  {
9555  s = +1;
9556  }
9557  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
9558  }
9559  // y-components
9560  for (int k = 0; k < pp1; k++)
9561  for (int j = 0; j <= pp1; j++)
9562  for (int i = 0; i < pp1; i++)
9563  {
9564  int idx, s;
9565  if ((idx = dof_map[o++]) < 0)
9566  {
9567  idx = -1 - idx, s = -1;
9568  }
9569  else
9570  {
9571  s = +1;
9572  }
9573  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
9574  }
9575  // z-components
9576  for (int k = 0; k <= pp1; k++)
9577  for (int j = 0; j < pp1; j++)
9578  for (int i = 0; i < pp1; i++)
9579  {
9580  int idx, s;
9581  if ((idx = dof_map[o++]) < 0)
9582  {
9583  idx = -1 - idx, s = -1;
9584  }
9585  else
9586  {
9587  s = +1;
9588  }
9589  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
9590  }
9591 }
9592 
9593 
9594 const double RT_TriangleElement::nk[6] =
9595 { 0., -1., 1., 1., -1., 0. };
9596 
9597 const double RT_TriangleElement::c = 1./3.;
9598 
9600  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
9601  H_DIV, FunctionSpace::Pk),
9602  dof2nk(Dof)
9603 {
9604  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9605  const double *bop = poly1d.OpenPoints(p);
9606 
9607 #ifndef MFEM_THREAD_SAFE
9608  shape_x.SetSize(p + 1);
9609  shape_y.SetSize(p + 1);
9610  shape_l.SetSize(p + 1);
9611  dshape_x.SetSize(p + 1);
9612  dshape_y.SetSize(p + 1);
9613  dshape_l.SetSize(p + 1);
9614  u.SetSize(Dof, Dim);
9615  divu.SetSize(Dof);
9616 #else
9617  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9618 #endif
9619 
9620  // edges
9621  int o = 0;
9622  for (int i = 0; i <= p; i++) // (0,1)
9623  {
9624  Nodes.IntPoint(o).Set2(bop[i], 0.);
9625  dof2nk[o++] = 0;
9626  }
9627  for (int i = 0; i <= p; i++) // (1,2)
9628  {
9629  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
9630  dof2nk[o++] = 1;
9631  }
9632  for (int i = 0; i <= p; i++) // (2,0)
9633  {
9634  Nodes.IntPoint(o).Set2(0., bop[p-i]);
9635  dof2nk[o++] = 2;
9636  }
9637 
9638  // interior
9639  for (int j = 0; j < p; j++)
9640  for (int i = 0; i + j < p; i++)
9641  {
9642  double w = iop[i] + iop[j] + iop[p-1-i-j];
9643  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9644  dof2nk[o++] = 0;
9645  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9646  dof2nk[o++] = 2;
9647  }
9648 
9649  DenseMatrix T(Dof);
9650  for (int k = 0; k < Dof; k++)
9651  {
9652  const IntegrationPoint &ip = Nodes.IntPoint(k);
9653  poly1d.CalcBasis(p, ip.x, shape_x);
9654  poly1d.CalcBasis(p, ip.y, shape_y);
9655  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9656  const double *n_k = nk + 2*dof2nk[k];
9657 
9658  o = 0;
9659  for (int j = 0; j <= p; j++)
9660  for (int i = 0; i + j <= p; i++)
9661  {
9662  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9663  T(o++, k) = s*n_k[0];
9664  T(o++, k) = s*n_k[1];
9665  }
9666  for (int i = 0; i <= p; i++)
9667  {
9668  double s = shape_x(i)*shape_y(p-i);
9669  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
9670  }
9671  }
9672 
9673  Ti.Factor(T);
9674  // mfem::out << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
9675 }
9676 
9678  DenseMatrix &shape) const
9679 {
9680  const int p = Order - 1;
9681 
9682 #ifdef MFEM_THREAD_SAFE
9683  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9684  DenseMatrix u(Dof, Dim);
9685 #endif
9686 
9687  poly1d.CalcBasis(p, ip.x, shape_x);
9688  poly1d.CalcBasis(p, ip.y, shape_y);
9689  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9690 
9691  int o = 0;
9692  for (int j = 0; j <= p; j++)
9693  for (int i = 0; i + j <= p; i++)
9694  {
9695  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9696  u(o,0) = s; u(o,1) = 0; o++;
9697  u(o,0) = 0; u(o,1) = s; o++;
9698  }
9699  for (int i = 0; i <= p; i++)
9700  {
9701  double s = shape_x(i)*shape_y(p-i);
9702  u(o,0) = (ip.x - c)*s;
9703  u(o,1) = (ip.y - c)*s;
9704  o++;
9705  }
9706 
9707  Ti.Mult(u, shape);
9708 }
9709 
9711  Vector &divshape) const
9712 {
9713  const int p = Order - 1;
9714 
9715 #ifdef MFEM_THREAD_SAFE
9716  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9717  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
9718  Vector divu(Dof);
9719 #endif
9720 
9721  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9722  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9723  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
9724 
9725  int o = 0;
9726  for (int j = 0; j <= p; j++)
9727  for (int i = 0; i + j <= p; i++)
9728  {
9729  int k = p - i - j;
9730  divu(o++) = (dshape_x(i)*shape_l(k) -
9731  shape_x(i)*dshape_l(k))*shape_y(j);
9732  divu(o++) = (dshape_y(j)*shape_l(k) -
9733  shape_y(j)*dshape_l(k))*shape_x(i);
9734  }
9735  for (int i = 0; i <= p; i++)
9736  {
9737  int j = p - i;
9738  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
9739  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
9740  }
9741 
9742  Ti.Mult(divu, divshape);
9743 }
9744 
9745 
9746 const double RT_TetrahedronElement::nk[12] =
9747 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
9748 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
9749 
9750 const double RT_TetrahedronElement::c = 1./4.;
9751 
9753  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
9754  p + 1, H_DIV, FunctionSpace::Pk),
9755  dof2nk(Dof)
9756 {
9757  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9758  const double *bop = poly1d.OpenPoints(p);
9759 
9760 #ifndef MFEM_THREAD_SAFE
9761  shape_x.SetSize(p + 1);
9762  shape_y.SetSize(p + 1);
9763  shape_z.SetSize(p + 1);
9764  shape_l.SetSize(p + 1);
9765  dshape_x.SetSize(p + 1);
9766  dshape_y.SetSize(p + 1);
9767  dshape_z.SetSize(p + 1);
9768  dshape_l.SetSize(p + 1);
9769  u.SetSize(Dof, Dim);
9770  divu.SetSize(Dof);
9771 #else
9772  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9773 #endif
9774 
9775  int o = 0;
9776  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
9777  // the constructor of H1_TetrahedronElement)
9778  for (int j = 0; j <= p; j++)
9779  for (int i = 0; i + j <= p; i++) // (1,2,3)
9780  {
9781  double w = bop[i] + bop[j] + bop[p-i-j];
9782  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
9783  dof2nk[o++] = 0;
9784  }
9785  for (int j = 0; j <= p; j++)
9786  for (int i = 0; i + j <= p; i++) // (0,3,2)
9787  {
9788  double w = bop[i] + bop[j] + bop[p-i-j];
9789  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
9790  dof2nk[o++] = 1;
9791  }
9792  for (int j = 0; j <= p; j++)
9793  for (int i = 0; i + j <= p; i++) // (0,1,3)
9794  {
9795  double w = bop[i] + bop[j] + bop[p-i-j];
9796  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
9797  dof2nk[o++] = 2;
9798  }
9799  for (int j = 0; j <= p; j++)
9800  for (int i = 0; i + j <= p; i++) // (0,2,1)
9801  {
9802  double w = bop[i] + bop[j] + bop[p-i-j];
9803  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
9804  dof2nk[o++] = 3;
9805  }
9806 
9807  // interior
9808  for (int k = 0; k < p; k++)
9809  for (int j = 0; j + k < p; j++)
9810  for (int i = 0; i + j + k < p; i++)
9811  {
9812  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
9813  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9814  dof2nk[o++] = 1;
9815  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9816  dof2nk[o++] = 2;
9817  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9818  dof2nk[o++] = 3;
9819  }
9820 
9821  DenseMatrix T(Dof);
9822  for (int m = 0; m < Dof; m++)
9823  {
9824  const IntegrationPoint &ip = Nodes.IntPoint(m);
9825  poly1d.CalcBasis(p, ip.x, shape_x);
9826  poly1d.CalcBasis(p, ip.y, shape_y);
9827  poly1d.CalcBasis(p, ip.z, shape_z);
9828  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9829  const double *nm = nk + 3*dof2nk[m];
9830 
9831  o = 0;
9832  for (int k = 0; k <= p; k++)
9833  for (int j = 0; j + k <= p; j++)
9834  for (int i = 0; i + j + k <= p; i++)
9835  {
9836  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9837  T(o++, m) = s * nm[0];
9838  T(o++, m) = s * nm[1];
9839  T(o++, m) = s * nm[2];
9840  }
9841  for (int j = 0; j <= p; j++)
9842  for (int i = 0; i + j <= p; i++)
9843  {
9844  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9845  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
9846  (ip.z - c)*nm[2]);
9847  }
9848  }
9849 
9850  Ti.Factor(T);
9851  // mfem::out << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
9852 }
9853 
9855  DenseMatrix &shape) const
9856 {
9857  const int p = Order - 1;
9858 
9859 #ifdef MFEM_THREAD_SAFE
9860  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9861  DenseMatrix u(Dof, Dim);
9862 #endif
9863 
9864  poly1d.CalcBasis(p, ip.x, shape_x);
9865  poly1d.CalcBasis(p, ip.y, shape_y);
9866  poly1d.CalcBasis(p, ip.z, shape_z);
9867  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9868 
9869  int o = 0;
9870  for (int k = 0; k <= p; k++)
9871  for (int j = 0; j + k <= p; j++)
9872  for (int i = 0; i + j + k <= p; i++)
9873  {
9874  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9875  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
9876  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
9877  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
9878  }
9879  for (int j = 0; j <= p; j++)
9880  for (int i = 0; i + j <= p; i++)
9881  {
9882  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9883  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
9884  o++;
9885  }
9886 
9887  Ti.Mult(u, shape);
9888 }
9889 
9891  Vector &divshape) const
9892 {
9893  const int p = Order - 1;
9894 
9895 #ifdef MFEM_THREAD_SAFE
9896  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9897  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
9898  Vector divu(Dof);
9899 #endif
9900 
9901  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9902  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9903  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
9904  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
9905 
9906  int o = 0;
9907  for (int k = 0; k <= p; k++)
9908  for (int j = 0; j + k <= p; j++)
9909  for (int i = 0; i + j + k <= p; i++)
9910  {
9911  int l = p - i - j - k;
9912  divu(o++) = (dshape_x(i)*shape_l(l) -
9913  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
9914  divu(o++) = (dshape_y(j)*shape_l(l) -
9915  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
9916  divu(o++) = (dshape_z(k)*shape_l(l) -
9917  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
9918  }
9919  for (int j = 0; j <= p; j++)
9920  for (int i = 0; i + j <= p; i++)
9921  {
9922  int k = p - i - j;
9923  divu(o++) =
9924  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
9925  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
9926  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
9927  }
9928 
9929  Ti.Mult(divu, divshape);
9930 }
9931 
9932 
9933 const double ND_HexahedronElement::tk[18] =
9934 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
9935 
9937  const int cp_type, const int op_type)
9938  : VectorFiniteElement(3, Geometry::CUBE, 3*p*(p + 1)*(p + 1), p,
9939  H_CURL, FunctionSpace::Qk),
9940  cbasis1d(poly1d.ClosedBasis(p, VerifyClosed(cp_type))),
9941  obasis1d(poly1d.OpenBasis(p - 1, VerifyOpen(op_type))),
9942  dof_map(Dof), dof2tk(Dof)
9943 {
9944  const double *cp = poly1d.ClosedPoints(p, cp_type);
9945  const double *op = poly1d.OpenPoints(p - 1, op_type);
9946  const int dof3 = Dof/3;
9947 
9948 #ifndef MFEM_THREAD_SAFE
9949  shape_cx.SetSize(p + 1);
9950  shape_ox.SetSize(p);
9951  shape_cy.SetSize(p + 1);
9952  shape_oy.SetSize(p);
9953  shape_cz.SetSize(p + 1);
9954  shape_oz.SetSize(p);
9955  dshape_cx.SetSize(p + 1);
9956  dshape_cy.SetSize(p + 1);
9957  dshape_cz.SetSize(p + 1);
9958 #endif
9959 
9960  // edges
9961  int o = 0;
9962  for (int i = 0; i < p; i++) // (0,1)
9963  {
9964  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
9965  }
9966  for (int i = 0; i < p; i++) // (1,2)
9967  {
9968  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
9969  }
9970  for (int i = 0; i < p; i++) // (3,2)
9971  {
9972  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
9973  }
9974  for (int i = 0; i < p; i++) // (0,3)
9975  {
9976  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
9977  }
9978  for (int i = 0; i < p; i++) // (4,5)
9979  {
9980  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
9981  }
9982  for (int i = 0; i < p; i++) // (5,6)
9983  {
9984  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
9985  }
9986  for (int i = 0; i < p; i++) // (7,6)
9987  {
9988  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
9989  }
9990  for (int i = 0; i < p; i++) // (4,7)
9991  {
9992  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
9993  }
9994  for (int i = 0; i < p; i++) // (0,4)
9995  {
9996  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
9997  }
9998  for (int i = 0; i < p; i++) // (1,5)
9999  {
10000  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
10001  }
10002  for (int i = 0; i < p; i++) // (2,6)
10003  {
10004  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
10005  }
10006  for (int i = 0; i < p; i++) // (3,7)
10007  {
10008  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
10009  }
10010 
10011  // faces
10012  // (3,2,1,0) -- bottom
10013  for (int j = 1; j < p; j++) // x - components
10014  for (int i = 0; i < p; i++)
10015  {
10016  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
10017  }
10018  for (int j = 0; j < p; j++) // y - components
10019  for (int i = 1; i < p; i++)
10020  {
10021  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
10022  }
10023  // (0,1,5,4) -- front
10024  for (int k = 1; k < p; k++) // x - components
10025  for (int i = 0; i < p; i++)
10026  {
10027  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
10028  }
10029  for (int k = 0; k < p; k++) // z - components
10030  for (int i = 1; i < p; i++ )
10031  {
10032  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
10033  }
10034  // (1,2,6,5) -- right
10035  for (int k = 1; k < p; k++) // y - components
10036  for (int j = 0; j < p; j++)
10037  {
10038  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
10039  }
10040  for (int k = 0; k < p; k++) // z - components
10041  for (int j = 1; j < p; j++)
10042  {
10043  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
10044  }
10045  // (2,3,7,6) -- back
10046  for (int k = 1; k < p; k++) // x - components
10047  for (int i = 0; i < p; i++)
10048  {
10049  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
10050  }
10051  for (int k = 0; k < p; k++) // z - components
10052  for (int i = 1; i < p; i++)
10053  {
10054  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
10055  }
10056  // (3,0,4,7) -- left
10057  for (int k = 1; k < p; k++) // y - components
10058  for (int j = 0; j < p; j++)
10059  {
10060  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
10061  }
10062  for (int k = 0; k < p; k++) // z - components
10063  for (int j = 1; j < p; j++)
10064  {
10065  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
10066  }
10067  // (4,5,6,7) -- top
10068  for (int j = 1; j < p; j++) // x - components
10069  for (int i = 0; i < p; i++)
10070  {
10071  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
10072  }
10073  for (int j = 0; j < p; j++) // y - components
10074  for (int i = 1; i < p; i++)
10075  {
10076  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
10077  }
10078 
10079  // interior
10080  // x-components
10081  for (int k = 1; k < p; k++)
10082  for (int j = 1; j < p; j++)
10083  for (int i = 0; i < p; i++)
10084  {
10085  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
10086  }
10087  // y-components
10088  for (int k = 1; k < p; k++)
10089  for (int j = 0; j < p; j++)
10090  for (int i = 1; i < p; i++)
10091  {
10092  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
10093  }
10094  // z-components
10095  for (int k = 0; k < p; k++)
10096  for (int j = 1; j < p; j++)
10097  for (int i = 1; i < p; i++)
10098  {
10099  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
10100  }
10101 
10102  // set dof2tk and Nodes
10103  o = 0;
10104  // x-components
10105  for (int k = 0; k <= p; k++)
10106  for (int j = 0; j <= p; j++)
10107  for (int i = 0; i < p; i++)
10108  {
10109  int idx;
10110  if ((idx = dof_map[o++]) < 0)
10111  {
10112  dof2tk[idx = -1 - idx] = 3;
10113  }
10114  else
10115  {
10116  dof2tk[idx] = 0;
10117  }
10118  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
10119  }
10120  // y-components
10121  for (int k = 0; k <= p; k++)
10122  for (int j = 0; j < p; j++)
10123  for (int i = 0; i <= p; i++)
10124  {
10125  int idx;
10126  if ((idx = dof_map[o++]) < 0)
10127  {
10128  dof2tk[idx = -1 - idx] = 4;
10129  }
10130  else
10131  {
10132  dof2tk[idx] = 1;
10133  }
10134  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
10135  }
10136  // z-components
10137  for (int k = 0; k < p; k++)
10138  for (int j = 0; j <= p; j++)
10139  for (int i = 0; i <= p; i++)
10140  {
10141  int idx;
10142  if ((idx = dof_map[o++]) < 0)
10143  {
10144  dof2tk[idx = -1 - idx] = 5;
10145  }
10146  else
10147  {
10148  dof2tk[idx] = 2;
10149  }
10150  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
10151  }
10152 }
10153 
10155  DenseMatrix &shape) const
10156 {
10157  const int p = Order;
10158 
10159 #ifdef MFEM_THREAD_SAFE
10160  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10161  Vector shape_cz(p + 1), shape_oz(p);
10162 #endif
10163 
10164  cbasis1d.Eval(ip.x, shape_cx);
10165  obasis1d.Eval(ip.x, shape_ox);
10166  cbasis1d.Eval(ip.y, shape_cy);
10167  obasis1d.Eval(ip.y, shape_oy);
10168  cbasis1d.Eval(ip.z, shape_cz);
10169  obasis1d.Eval(ip.z, shape_oz);
10170 
10171  int o = 0;
10172  // x-components
10173  for (int k = 0; k <= p; k++)
10174  for (int j = 0; j <= p; j++)
10175  for (int i = 0; i < p; i++)
10176  {
10177  int idx, s;
10178  if ((idx = dof_map[o++]) < 0)
10179  {
10180  idx = -1 - idx, s = -1;
10181  }
10182  else
10183  {
10184  s = +1;
10185  }
10186  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
10187  shape(idx,1) = 0.;
10188  shape(idx,2) = 0.;
10189  }
10190  // y-components
10191  for (int k = 0; k <= p; k++)
10192  for (int j = 0; j < p; j++)
10193  for (int i = 0; i <= p; i++)
10194  {
10195  int idx, s;
10196  if ((idx = dof_map[o++]) < 0)
10197  {
10198  idx = -1 - idx, s = -1;
10199  }
10200  else
10201  {
10202  s = +1;
10203  }
10204  shape(idx,0) = 0.;
10205  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
10206  shape(idx,2) = 0.;
10207  }
10208  // z-components
10209  for (int k = 0; k < p; k++)
10210  for (int j = 0; j <= p; j++)
10211  for (int i = 0; i <= p; i++)
10212  {
10213  int idx, s;
10214  if ((idx = dof_map[o++]) < 0)
10215  {
10216  idx = -1 - idx, s = -1;
10217  }
10218  else
10219  {
10220  s = +1;
10221  }
10222  shape(idx,0) = 0.;
10223  shape(idx,1) = 0.;
10224  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
10225  }
10226 }
10227 
10229  DenseMatrix &curl_shape) const
10230 {
10231  const int p = Order;
10232 
10233 #ifdef MFEM_THREAD_SAFE
10234  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10235  Vector shape_cz(p + 1), shape_oz(p);
10236  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
10237 #endif
10238 
10239  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10240  obasis1d.Eval(ip.x, shape_ox);
10241  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10242  obasis1d.Eval(ip.y, shape_oy);
10243  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
10244  obasis1d.Eval(ip.z, shape_oz);
10245 
10246  int o = 0;
10247  // x-components
10248  for (int k = 0; k <= p; k++)
10249  for (int j = 0; j <= p; j++)
10250  for (int i = 0; i < p; i++)
10251  {
10252  int idx, s;
10253  if ((idx = dof_map[o++]) < 0)
10254  {
10255  idx = -1 - idx, s = -1;
10256  }
10257  else
10258  {
10259  s = +1;
10260  }
10261  curl_shape(idx,0) = 0.;
10262  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
10263  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
10264  }
10265  // y-components
10266  for (int k = 0; k <= p; k++)
10267  for (int j = 0; j < p; j++)
10268  for (int i = 0; i <= p; i++)
10269  {
10270  int idx, s;
10271  if ((idx = dof_map[o++]) < 0)
10272  {
10273  idx = -1 - idx, s = -1;
10274  }
10275  else
10276  {
10277  s = +1;
10278  }
10279  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
10280  curl_shape(idx,1) = 0.;
10281  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
10282  }
10283  // z-components
10284  for (int k = 0; k < p; k++)
10285  for (int j = 0; j <= p; j++)
10286  for (int i = 0; i <= p; i++)
10287  {
10288  int idx, s;
10289  if ((idx = dof_map[o++]) < 0)
10290  {
10291  idx = -1 - idx, s = -1;
10292  }
10293  else
10294  {
10295  s = +1;
10296  }
10297  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
10298  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
10299  curl_shape(idx,2) = 0.;
10300  }
10301 }
10302 
10303 
10304 const double ND_QuadrilateralElement::tk[8] =
10305 { 1.,0., 0.,1., -1.,0., 0.,-1. };
10306 
10308  const int cp_type,
10309  const int op_type)
10310  : VectorFiniteElement(2, Geometry::SQUARE, 2*p*(p + 1), p,
10311  H_CURL, FunctionSpace::Qk),
10312  cbasis1d(poly1d.ClosedBasis(p, VerifyClosed(cp_type))),
10313  obasis1d(poly1d.OpenBasis(p - 1, VerifyOpen(op_type))),
10314  dof_map(Dof), dof2tk(Dof)
10315 {
10316  const double *cp = poly1d.ClosedPoints(p, cp_type);
10317  const double *op = poly1d.OpenPoints(p - 1, op_type);
10318  const int dof2 = Dof/2;
10319 
10320 #ifndef MFEM_THREAD_SAFE
10321  shape_cx.SetSize(p + 1);
10322  shape_ox.SetSize(p);
10323  shape_cy.SetSize(p + 1);
10324  shape_oy.SetSize(p);
10325  dshape_cx.SetSize(p + 1);
10326  dshape_cy.SetSize(p + 1);
10327 #endif
10328 
10329  // edges
10330  int o = 0;
10331  for (int i = 0; i < p; i++) // (0,1)
10332  {
10333  dof_map[0*dof2 + i + 0*p] = o++;
10334  }
10335  for (int j = 0; j < p; j++) // (1,2)
10336  {
10337  dof_map[1*dof2 + p + j*(p + 1)] = o++;
10338  }
10339  for (int i = 0; i < p; i++) // (2,3)
10340  {
10341  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
10342  }
10343  for (int j = 0; j < p; j++) // (3,0)
10344  {
10345  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
10346  }
10347 
10348  // interior
10349  // x-components
10350  for (int j = 1; j < p; j++)
10351  for (int i = 0; i < p; i++)
10352  {
10353  dof_map[0*dof2 + i + j*p] = o++;
10354  }
10355  // y-components
10356  for (int j = 0; j < p; j++)
10357  for (int i = 1; i < p; i++)
10358  {
10359  dof_map[1*dof2 + i + j*(p + 1)] = o++;
10360  }
10361 
10362  // set dof2tk and Nodes
10363  o = 0;
10364  // x-components
10365  for (int j = 0; j <= p; j++)
10366  for (int i = 0; i < p; i++)
10367  {
10368  int idx;
10369  if ((idx = dof_map[o++]) < 0)
10370  {
10371  dof2tk[idx = -1 - idx] = 2;
10372  }
10373  else
10374  {
10375  dof2tk[idx] = 0;
10376  }
10377  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
10378  }
10379  // y-components
10380  for (int j = 0; j < p; j++)
10381  for (int i = 0; i <= p; i++)
10382  {
10383  int idx;
10384  if ((idx = dof_map[o++]) < 0)
10385  {
10386  dof2tk[idx = -1 - idx] = 3;
10387  }
10388  else
10389  {
10390  dof2tk[idx] = 1;
10391  }
10392  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
10393  }
10394 }
10395 
10397  DenseMatrix &shape) const
10398 {
10399  const int p = Order;
10400 
10401 #ifdef MFEM_THREAD_SAFE
10402  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10403 #endif
10404 
10405  cbasis1d.Eval(ip.x, shape_cx);
10406  obasis1d.Eval(ip.x, shape_ox);
10407  cbasis1d.Eval(ip.y, shape_cy);
10408  obasis1d.Eval(ip.y, shape_oy);
10409 
10410  int o = 0;
10411  // x-components
10412  for (int j = 0; j <= p; j++)
10413  for (int i = 0; i < p; i++)
10414  {
10415  int idx, s;
10416  if ((idx = dof_map[o++]) < 0)
10417  {
10418  idx = -1 - idx, s = -1;
10419  }
10420  else
10421  {
10422  s = +1;
10423  }
10424  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
10425  shape(idx,1) = 0.;
10426  }
10427  // y-components
10428  for (int j = 0; j < p; j++)
10429  for (int i = 0; i <= p; i++)
10430  {
10431  int idx, s;
10432  if ((idx = dof_map[o++]) < 0)
10433  {
10434  idx = -1 - idx, s = -1;
10435  }
10436  else
10437  {
10438  s = +1;
10439  }
10440  shape(idx,0) = 0.;
10441  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
10442  }
10443 }
10444 
10446  DenseMatrix &curl_shape) const
10447 {
10448  const int p = Order;
10449 
10450 #ifdef MFEM_THREAD_SAFE
10451  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10452  Vector dshape_cx(p + 1), dshape_cy(p + 1);
10453 #endif
10454 
10455  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10456  obasis1d.Eval(ip.x, shape_ox);
10457  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10458  obasis1d.Eval(ip.y, shape_oy);
10459 
10460  int o = 0;
10461  // x-components
10462  for (int j = 0; j <= p; j++)
10463  for (int i = 0; i < p; i++)
10464  {
10465  int idx, s;
10466  if ((idx = dof_map[o++]) < 0)
10467  {
10468  idx = -1 - idx, s = -1;
10469  }
10470  else
10471  {
10472  s = +1;
10473  }
10474  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
10475  }
10476  // y-components
10477  for (int j = 0; j < p; j++)
10478  for (int i = 0; i <= p; i++)
10479  {
10480  int idx, s;
10481  if ((idx = dof_map[o++]) < 0)
10482  {
10483  idx = -1 - idx, s = -1;
10484  }
10485  else
10486  {
10487  s = +1;
10488  }
10489  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
10490  }
10491 }
10492 
10493 
10494 const double ND_TetrahedronElement::tk[18] =
10495 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
10496 
10497 const double ND_TetrahedronElement::c = 1./4.;
10498 
10500  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
10501  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
10502 {
10503  const double *eop = poly1d.OpenPoints(p - 1);
10504  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10505  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
10506 
10507  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
10508 
10509 #ifndef MFEM_THREAD_SAFE
10510  shape_x.SetSize(p);
10511  shape_y.SetSize(p);
10512  shape_z.SetSize(p);
10513  shape_l.SetSize(p);
10514  dshape_x.SetSize(p);
10515  dshape_y.SetSize(p);
10516  dshape_z.SetSize(p);
10517  dshape_l.SetSize(p);
10518  u.SetSize(Dof, Dim);
10519 #else
10520  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10521 #endif
10522 
10523  int o = 0;
10524  // edges
10525  for (int i = 0; i < p; i++) // (0,1)
10526  {
10527  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
10528  dof2tk[o++] = 0;
10529  }
10530  for (int i = 0; i < p; i++) // (0,2)
10531  {
10532  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
10533  dof2tk[o++] = 1;
10534  }
10535  for (int i = 0; i < p; i++) // (0,3)
10536  {
10537  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
10538  dof2tk[o++] = 2;
10539  }
10540  for (int i = 0; i < p; i++) // (1,2)
10541  {
10542  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
10543  dof2tk[o++] = 3;
10544  }
10545  for (int i = 0; i < p; i++) // (1,3)
10546  {
10547  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
10548  dof2tk[o++] = 4;
10549  }
10550  for (int i = 0; i < p; i++) // (2,3)
10551  {
10552  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
10553  dof2tk[o++] = 5;
10554  }
10555 
10556  // faces
10557  for (int j = 0; j <= pm2; j++) // (1,2,3)
10558  for (int i = 0; i + j <= pm2; i++)
10559  {
10560  double w = fop[i] + fop[j] + fop[pm2-i-j];
10561  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10562  dof2tk[o++] = 3;
10563  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10564  dof2tk[o++] = 4;
10565  }
10566  for (int j = 0; j <= pm2; j++) // (0,3,2)
10567  for (int i = 0; i + j <= pm2; i++)
10568  {
10569  double w = fop[i] + fop[j] + fop[pm2-i-j];
10570  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10571  dof2tk[o++] = 2;
10572  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10573  dof2tk[o++] = 1;
10574  }
10575  for (int j = 0; j <= pm2; j++) // (0,1,3)
10576  for (int i = 0; i + j <= pm2; i++)
10577  {
10578  double w = fop[i] + fop[j] + fop[pm2-i-j];
10579  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10580  dof2tk[o++] = 0;
10581  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10582  dof2tk[o++] = 2;
10583  }
10584  for (int j = 0; j <= pm2; j++) // (0,2,1)
10585  for (int i = 0; i + j <= pm2; i++)
10586  {
10587  double w = fop[i] + fop[j] + fop[pm2-i-j];
10588  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10589  dof2tk[o++] = 1;
10590  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10591  dof2tk[o++] = 0;
10592  }
10593 
10594  // interior
10595  for (int k = 0; k <= pm3; k++)
10596  for (int j = 0; j + k <= pm3; j++)
10597  for (int i = 0; i + j + k <= pm3; i++)
10598  {
10599  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
10600  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10601  dof2tk[o++] = 0;
10602  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10603  dof2tk[o++] = 1;
10604  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10605  dof2tk[o++] = 2;
10606  }
10607 
10608  DenseMatrix T(Dof);
10609  for (int m = 0; m < Dof; m++)
10610  {
10611  const IntegrationPoint &ip = Nodes.IntPoint(m);
10612  const double *tm = tk + 3*dof2tk[m];
10613  o = 0;
10614 
10615  poly1d.CalcBasis(pm1, ip.x, shape_x);
10616  poly1d.CalcBasis(pm1, ip.y, shape_y);
10617  poly1d.CalcBasis(pm1, ip.z, shape_z);
10618  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10619 
10620  for (int k = 0; k <= pm1; k++)
10621  for (int j = 0; j + k <= pm1; j++)
10622  for (int i = 0; i + j + k <= pm1; i++)
10623  {
10624  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10625  T(o++, m) = s * tm[0];
10626  T(o++, m) = s * tm[1];
10627  T(o++, m) = s * tm[2];
10628  }
10629  for (int k = 0; k <= pm1; k++)
10630  for (int j = 0; j + k <= pm1; j++)
10631  {
10632  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10633  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10634  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
10635  }
10636  for (int k = 0; k <= pm1; k++)
10637  {
10638  T(o++, m) =
10639  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
10640  }
10641  }
10642 
10643  Ti.Factor(T);
10644  // mfem::out << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
10645 }
10646 
10648  DenseMatrix &shape) const
10649 {
10650  const int pm1 = Order - 1;
10651 
10652 #ifdef MFEM_THREAD_SAFE
10653  const int p = Order;
10654  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10655  DenseMatrix u(Dof, Dim);
10656 #endif
10657 
10658  poly1d.CalcBasis(pm1, ip.x, shape_x);
10659  poly1d.CalcBasis(pm1, ip.y, shape_y);
10660  poly1d.CalcBasis(pm1, ip.z, shape_z);
10661  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10662 
10663  int n = 0;
10664  for (int k = 0; k <= pm1; k++)
10665  for (int j = 0; j + k <= pm1; j++)
10666  for (int i = 0; i + j + k <= pm1; i++)
10667  {
10668  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10669  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
10670  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
10671  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
10672  }
10673  for (int k = 0; k <= pm1; k++)
10674  for (int j = 0; j + k <= pm1; j++)
10675  {
10676  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10677  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
10678  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
10679  }
10680  for (int k = 0; k <= pm1; k++)
10681  {
10682  double s = shape_y(pm1-k)*shape_z(k);
10683  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
10684  }
10685 
10686  Ti.Mult(u, shape);
10687 }
10688 
10690  DenseMatrix &curl_shape) const
10691 {
10692  const int pm1 = Order - 1;
10693 
10694 #ifdef MFEM_THREAD_SAFE
10695  const int p = Order;
10696  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10697  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
10698  DenseMatrix u(Dof, Dim);
10699 #endif
10700 
10701  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10702  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10703  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
10704  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10705 
10706  int n = 0;
10707  for (int k = 0; k <= pm1; k++)
10708  for (int j = 0; j + k <= pm1; j++)
10709  for (int i = 0; i + j + k <= pm1; i++)
10710  {
10711  int l = pm1-i-j-k;
10712  const double dx = (dshape_x(i)*shape_l(l) -
10713  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
10714  const double dy = (dshape_y(j)*shape_l(l) -
10715  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
10716  const double dz = (dshape_z(k)*shape_l(l) -
10717  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
10718 
10719  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
10720  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
10721  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
10722  }
10723  for (int k = 0; k <= pm1; k++)
10724  for (int j = 0; j + k <= pm1; j++)
10725  {
10726  int i = pm1 - j - k;
10727  // s = shape_x(i)*shape_y(j)*shape_z(k);
10728  // curl of s*(ip.y - c, -(ip.x - c), 0):
10729  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
10730  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
10731  u(n,2) =
10732  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
10733  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
10734  n++;
10735  // curl of s*(ip.z - c, 0, -(ip.x - c)):
10736  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
10737  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
10738  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
10739  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
10740  n++;
10741  }
10742  for (int k = 0; k <= pm1; k++)
10743  {
10744  int j = pm1 - k;
10745  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
10746  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
10747  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
10748  u(n,1) = 0.;
10749  u(n,2) = 0.; n++;
10750  }
10751 
10752  Ti.Mult(u, curl_shape);
10753 }
10754 
10755 
10756 const double ND_TriangleElement::tk[8] =
10757 { 1.,0., -1.,1., 0.,-1., 0.,1. };
10758 
10759 const double ND_TriangleElement::c = 1./3.;
10760 
10762  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
10763  H_CURL, FunctionSpace::Pk),
10764  dof2tk(Dof)
10765 {
10766  const double *eop = poly1d.OpenPoints(p - 1);
10767  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10768 
10769  const int pm1 = p - 1, pm2 = p - 2;
10770 
10771 #ifndef MFEM_THREAD_SAFE
10772  shape_x.SetSize(p);
10773  shape_y.SetSize(p);
10774  shape_l.SetSize(p);
10775  dshape_x.SetSize(p);
10776  dshape_y.SetSize(p);
10777  dshape_l.SetSize(p);
10778  u.SetSize(Dof, Dim);
10779  curlu.SetSize(Dof);
10780 #else
10781  Vector shape_x(p), shape_y(p), shape_l(p);
10782 #endif
10783 
10784  int n = 0;
10785  // edges
10786  for (int i = 0; i < p; i++) // (0,1)
10787  {
10788  Nodes.IntPoint(n).Set2(eop[i], 0.);
10789  dof2tk[n++] = 0;
10790  }
10791  for (int i = 0; i < p; i++) // (1,2)
10792  {
10793  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
10794  dof2tk[n++] = 1;
10795  }
10796  for (int i = 0; i < p; i++) // (2,0)
10797  {
10798  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
10799  dof2tk[n++] = 2;
10800  }
10801 
10802  // interior
10803  for (int j = 0; j <= pm2; j++)
10804  for (int i = 0; i + j <= pm2; i++)
10805  {
10806  double w = iop[i] + iop[j] + iop[pm2-i-j];
10807  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10808  dof2tk[n++] = 0;
10809  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10810  dof2tk[n++] = 3;
10811  }
10812 
10813  DenseMatrix T(Dof);
10814  for (int m = 0; m < Dof; m++)
10815  {
10816  const IntegrationPoint &ip = Nodes.IntPoint(m);
10817  const double *tm = tk + 2*dof2tk[m];
10818  n = 0;
10819 
10820  poly1d.CalcBasis(pm1, ip.x, shape_x);
10821  poly1d.CalcBasis(pm1, ip.y, shape_y);
10822  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10823 
10824  for (int j = 0; j <= pm1; j++)
10825  for (int i = 0; i + j <= pm1; i++)
10826  {
10827  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10828  T(n++, m) = s * tm[0];
10829  T(n++, m) = s * tm[1];
10830  }
10831  for (int j = 0; j <= pm1; j++)
10832  {
10833  T(n++, m) =
10834  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10835  }
10836  }
10837 
10838  Ti.Factor(T);
10839  // mfem::out << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
10840 }
10841 
10843  DenseMatrix &shape) const
10844 {
10845  const int pm1 = Order - 1;
10846 
10847 #ifdef MFEM_THREAD_SAFE
10848  const int p = Order;
10849  Vector shape_x(p), shape_y(p), shape_l(p);
10850  DenseMatrix u(Dof, Dim);
10851 #endif
10852 
10853  poly1d.CalcBasis(pm1, ip.x, shape_x);
10854  poly1d.CalcBasis(pm1, ip.y, shape_y);
10855  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10856 
10857  int n = 0;
10858  for (int j = 0; j <= pm1; j++)
10859  for (int i = 0; i + j <= pm1; i++)
10860  {
10861  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10862  u(n,0) = s; u(n,1) = 0; n++;
10863  u(n,0) = 0; u(n,1) = s; n++;
10864  }
10865  for (int j = 0; j <= pm1; j++)
10866  {
10867  double s = shape_x(pm1-j)*shape_y(j);
10868  u(n,0) = s*(ip.y - c);
10869  u(n,1) = -s*(ip.x - c);
10870  n++;
10871  }
10872 
10873  Ti.Mult(u, shape);
10874 }
10875 
10877  DenseMatrix &curl_shape) const
10878 {
10879  const int pm1 = Order - 1;
10880 
10881 #ifdef MFEM_THREAD_SAFE
10882  const int p = Order;
10883  Vector shape_x(p), shape_y(p), shape_l(p);
10884  Vector dshape_x(p), dshape_y(p), dshape_l(p);
10885  Vector curlu(Dof);
10886 #endif
10887 
10888  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10889  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10890  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
10891 
10892  int n = 0;
10893  for (int j = 0; j <= pm1; j++)
10894  for (int i = 0; i + j <= pm1; i++)
10895  {
10896  int l = pm1-i-j;
10897  const double dx = (dshape_x(i)*shape_l(l) -
10898  shape_x(i)*dshape_l(l)) * shape_y(j);
10899  const double dy = (dshape_y(j)*shape_l(l) -
10900  shape_y(j)*dshape_l(l)) * shape_x(i);
10901 
10902  curlu(n++) = -dy;
10903  curlu(n++) = dx;
10904  }
10905 
10906  for (int j = 0; j <= pm1; j++)
10907  {
10908  int i = pm1 - j;
10909  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
10910  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
10911  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
10912  }
10913 
10914  Vector curl2d(curl_shape.Data(),Dof);
10915  Ti.Mult(curlu, curl2d);
10916 }
10917 
10918 
10919 const double ND_SegmentElement::tk[1] = { 1. };
10920 
10921 ND_SegmentElement::ND_SegmentElement(const int p, const int op_type)
10922  : VectorFiniteElement(1, Geometry::SEGMENT, p, p - 1,
10923  H_CURL, FunctionSpace::Pk),
10924  obasis1d(poly1d.OpenBasis(p - 1, VerifyOpen(op_type))),
10925  dof2tk(Dof)
10926 {
10927  const double *op = poly1d.OpenPoints(p - 1, op_type);
10928 
10929  // set dof2tk and Nodes
10930  for (int i = 0; i < p; i++)
10931  {
10932  dof2tk[i] = 0;
10933  Nodes.IntPoint(i).x = op[i];
10934  }
10935 }
10936 
10938  DenseMatrix &shape) const
10939 {
10940  Vector vshape(shape.Data(), Dof);
10941 
10942  obasis1d.Eval(ip.x, vshape);
10943 }
10944 
10945 
10947  Vector &shape) const
10948 {
10949  kv[0]->CalcShape(shape, ijk[0], ip.x);
10950 
10951  double sum = 0.0;
10952  for (int i = 0; i <= Order; i++)
10953  {
10954  sum += (shape(i) *= weights(i));
10955  }
10956 
10957  shape /= sum;
10958 }
10959 
10961  DenseMatrix &dshape) const
10962 {
10963  Vector grad(dshape.Data(), Dof);
10964 
10965  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
10966  kv[0]->CalcDShape(grad, ijk[0], ip.x);
10967 
10968  double sum = 0.0, dsum = 0.0;
10969  for (int i = 0; i <= Order; i++)
10970  {
10971  sum += (shape_x(i) *= weights(i));
10972  dsum += ( grad(i) *= weights(i));
10973  }
10974 
10975  sum = 1.0/sum;
10976  add(sum, grad, -dsum*sum*sum, shape_x, grad);
10977 }
10978 
10980  Vector &shape) const
10981 {
10982  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
10983  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
10984 
10985  double sum = 0.0;
10986  for (int o = 0, j = 0; j <= Order; j++)
10987  {
10988  const double sy = shape_y(j);
10989  for (int i = 0; i <= Order; i++, o++)
10990  {
10991  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
10992  }
10993  }
10994 
10995  shape /= sum;
10996 }
10997 
10999  DenseMatrix &dshape) const
11000 {
11001  double sum, dsum[2];
11002 
11003  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
11004  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
11005 
11006  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
11007  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
11008 
11009  sum = dsum[0] = dsum[1] = 0.0;
11010  for (int o = 0, j = 0; j <= Order; j++)
11011  {
11012  const double sy = shape_y(j), dsy = dshape_y(j);
11013  for (int i = 0; i <= Order; i++, o++)
11014  {
11015  sum += ( u(o) = shape_x(i)*sy*weights(o) );
11016 
11017  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
11018  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
11019  }
11020  }
11021 
11022  sum = 1.0/sum;
11023  dsum[0] *= sum*sum;
11024  dsum[1] *= sum*sum;
11025 
11026  for (int o = 0; o < Dof; o++)
11027  {
11028  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11029  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11030  }
11031 }
11032 
11034  Vector &shape) const
11035 {
11036  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
11037  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
11038  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
11039 
11040  double sum = 0.0;
11041  for (int o = 0, k = 0; k <= Order; k++)
11042  {
11043  const double sz = shape_z(k);
11044  for (int j = 0; j <= Order; j++)
11045  {
11046  const double sy_sz = shape_y(j)*sz;
11047  for (int i = 0; i <= Order; i++, o++)
11048  {
11049  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
11050  }
11051  }
11052  }
11053 
11054  shape /= sum;
11055 }
11056 
11058  DenseMatrix &dshape) const
11059 {
11060  double sum, dsum[3];
11061 
11062  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
11063  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
11064  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
11065 
11066  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
11067  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
11068  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
11069 
11070  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
11071  for (int o = 0, k = 0; k <= Order; k++)
11072  {
11073  const double sz = shape_z(k), dsz = dshape_z(k);
11074  for (int j = 0; j <= Order; j++)
11075  {
11076  const double sy_sz = shape_y(j)* sz;
11077  const double dsy_sz = dshape_y(j)* sz;
11078  const double sy_dsz = shape_y(j)*dsz;
11079  for (int i = 0; i <= Order; i++, o++)
11080  {
11081  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
11082 
11083  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
11084  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
11085  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
11086  }
11087  }
11088  }
11089 
11090  sum = 1.0/sum;
11091  dsum[0] *= sum*sum;
11092  dsum[1] *= sum*sum;
11093  dsum[2] *= sum*sum;
11094 
11095  for (int o = 0; o < Dof; o++)
11096  {
11097  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11098  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11099  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
11100  }
11101 }
11102 
11103 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:222
Abstract class for Finite Elements.
Definition: fe.hpp:47
RefinedLinear3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:4270
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1383
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:8285
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:3362
int Size() const
Logical size of the array.
Definition: array.hpp:110
const DenseMatrix & AdjugateJacobian()
Definition: eltrans.hpp:72
DenseMatrix curlshape_J
Definition: fe.hpp:413
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:6069
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:116
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7185
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2907
L2_SegmentElement(const int p, const int type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8159
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:3848
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:1131
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:83
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8680
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:10998
Linear3DFiniteElement()
Construct a linear FE on tetrahedron.
Definition: fe.cpp:2306
static double CalcDelta(const int p, const double x)
Definition: fe.hpp:1450
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:3089
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8437
void ProjectMatrixCoefficient_RT(const double *nk, const Array< int > &d2n, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:577
int NumCols() const
Definition: array.hpp:287
void ProjectMatrixCoefficient_ND(const double *tk, const Array< int > &d2t, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:753
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:9854
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:38
RefinedBiLinear2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4502
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:1701
L2Pos_TriangleElement(const int p)
Definition: fe.cpp:8824
const IntegrationRule & Get(int GeomType, int Order)
Returns an integration rule for given GeomType and Order.
Definition: intrules.cpp:861
H1Pos_SegmentElement(const int p)
Definition: fe.cpp:7123
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:162
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:5114
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:115
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:2544
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:59
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2323
const double * OpenPoints(const int p, const int type=Quadrature1D::GaussLegendre)
Definition: fe.hpp:1411
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8863
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:2861
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3141
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:1497
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:7165
void GivePolyPoints(const int np, double *pts, const int type)
Definition: intrules.cpp:596
L2Pos_TetrahedronElement(const int p)
Definition: fe.cpp:9018
Array< KnotVector * > kv
Definition: fe.hpp:2283
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:282
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:534
L2_TriangleElement(const int p, const int type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8699
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:320
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:9236
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5176
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:3631
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1052
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:243
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:1521
void LocalInterpolation_ND(const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:881
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1879
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:1790
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:2626
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:468
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
evaluate derivatives of shape function - constant 0
Definition: fe.cpp:2277
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:42
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:941
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6685
virtual void Eval(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip)=0
H1Pos_TetrahedronElement(const int p)
Definition: fe.cpp:7907
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:10946
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:8304
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
Definition: densemat.cpp:290
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:52
LagrangeHexFiniteElement(int degree)
Definition: fe.cpp:3900
int GetOrder() const
Returns the order of the finite element.
Definition: fe.hpp:125
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:2639
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:3754
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:4062
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:3706
int Size() const
Returns the size of the vector.
Definition: vector.hpp:113
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:345
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:10960
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:9710
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5342
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:679
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:2292
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:1950
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:109
const DenseMatrix & InverseJacobian()
Definition: eltrans.hpp:75
RefinedTriLinear3DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4649
DenseMatrix vshape
Definition: fe.hpp:58
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:3887
Quadratic3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:2362
int GetMapType() const
Definition: fe.hpp:134
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:8177
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:5692
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5879
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:4142
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:2738
const IntegrationPoint & GetIntPoint()
Definition: eltrans.hpp:54
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8983
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:2002
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:9048
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:2569
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:2561
const IntegrationPoint & GetCenter(int GeomType)
Return the center of the given Geometry::Type, GeomType.
Definition: geom.hpp:61
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:8239
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:6773
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:717
H1Pos_HexahedronElement(const int p)
Definition: fe.cpp:7295
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:146
double * GetData() const
Definition: vector.hpp:121
static void CalcShape(const int p, const double x, const double y, const double z, double *shape)
Definition: fe.cpp:8009
H1_SegmentElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:6623
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:8925
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1013
H1_TetrahedronElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:7592
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:7267
Linear2DFiniteElement()
Construct a linear FE on triangle.
Definition: fe.cpp:955
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:2419
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:6014
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:264
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4838
L2_QuadrilateralElement(const int p, const int _type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8263
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:10842
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:922
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:2022
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:73
L2Pos_HexahedronElement(const int p)
Definition: fe.cpp:8607
ND_TriangleElement(const int p)
Definition: fe.cpp:10761
RT_QuadrilateralElement(const int p, const int cp_type=Quadrature1D::GaussLobatto, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:9075
const double * GetPoints(const int p, const int type)
Get the coordinates of the points of the given Quadrature1D type.
Definition: fe.cpp:6552
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:9890
Implements CalcDivShape methods.
Definition: fe.hpp:102
static void CalcDShape(const int p, const double x, const double y, const double z, double *dshape_1d, double *dshape)
Definition: fe.cpp:8042
static void CalcBasis(const int p, const double x, double *u)
Definition: fe.hpp:1434
H1_HexahedronElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:6863
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
evaluate shape function - constant 1
Definition: fe.cpp:2271
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:2050
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:6387
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:103
H1Pos_TriangleElement(const int p)
Definition: fe.cpp:7762
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:3343
static int VerifyOpen(int pt_type)
Definition: fe.hpp:295
Cubic3DFiniteElement()
Construct a cubic FE on tetrahedron.
Definition: fe.cpp:2097
Linear1DFiniteElement()
Construct a linear FE on interval.
Definition: fe.cpp:934
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4211
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:6002
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1570
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:4175
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:154
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:1188
static void CalcShape(const int p, const double x, const double y, double *shape)
Definition: fe.cpp:7817
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:2592
void SetSize(int m, int n)
Definition: array.hpp:284
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:2190
Geometry Geometries
Definition: geom.cpp:759
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:225
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:3649
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:721
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Definition: densemat.cpp:194
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:3120
int Dof
Number of degrees of freedom.
Definition: fe.hpp:50
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:8183
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1148
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1159
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1407
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:36
RefinedLinear1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:4100
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7038
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7288
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:1674
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:8766
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:7540
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4127
void LocalInterpolation_RT(const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:847
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:3282
static void ChebyshevPoints(const int p, double *x)
Definition: fe.cpp:6355
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
Definition: densemat.cpp:3785
const DenseMatrix & Jacobian()
Return the Jacobian matrix of the transformation at the currently set IntegrationPoint, using the method SetIntPoint().
Definition: eltrans.hpp:67
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:6139
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:3872
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:5980
int GetSpaceDim() const
Get the dimension of the target (physical) space.
Definition: eltrans.hpp:93
ND_TetrahedronElement(const int p)
Definition: fe.cpp:10499
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:8852
int DerivMapType
Definition: fe.hpp:50
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...
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:928
For scalar fields; preserves point values.
Definition: fe.hpp:85
int GeomType
Geometry::Type of the reference element.
Definition: fe.hpp:50
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:1965
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:627
const IntegrationRule & GetNodes() const
Definition: fe.hpp:167
For scalar fields; preserves volume integrals.
Definition: fe.hpp:86
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5229
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1229
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8522
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:2397
L2Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:8373
P0SegmentFiniteElement(int Ord=0)
Definition: fe.cpp:2532
static void CalcDShape(const int p, const double x, const double y, double *dshape_1d, double *dshape)
Definition: fe.cpp:7843
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:2884
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:11033
Implements CalcCurlShape methods.
Definition: fe.hpp:103
DenseMatrix curlshape
Definition: fe.hpp:413
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
Definition: densemat.cpp:3807
void Set2(const double x1, const double x2)
Definition: intrules.hpp:73
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:9450
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:5280
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:180
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:8744
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:9189
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:1829
void SetData(double *d)
Definition: vector.hpp:87
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:3541
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1004
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2332
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:9524
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:7703
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) 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:1331
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:826
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:8846
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3156
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:11057
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:1345
int GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:119
DenseMatrix m_dshape
Definition: fe.hpp:1639
int Dim
Dimension of reference space.
Definition: fe.hpp:50
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:10445
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:8398
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:63
IntegrationRule Nodes
Definition: fe.hpp:56
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1215
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:8635
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:7145
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7466
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3593
double * Data() const
Returns the matrix data array.
Definition: densemat.hpp:92
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:10876
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:2753
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4525
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2650
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:546
DenseMatrix Jinv
Definition: fe.hpp:412
No derivatives implemented.
Definition: fe.hpp:100
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8194
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:122
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:7728
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:1099
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:5310
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:9041
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:170
void mfem_error(const char *msg)
Definition: error.cpp:107
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:503
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:966
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4695
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:4392
static const int * Binom(const int p)
Get a poiner to an array containing the binomial coefficients &quot;p choose k&quot; for k=0,...,p for the given p.
Definition: fe.cpp:6338
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:3443
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:52
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1034
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:8950
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:10154
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2817
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:94
FiniteElement(int D, int G, int Do, int O, int F=FunctionSpace::Pk)
Definition: fe.cpp:24
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1456
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2477
ND_HexahedronElement(const int p, const int cp_type=Quadrature1D::GaussLobatto, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:9936
Quad1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:1140
RT_HexahedronElement(const int p, const int cp_type=Quadrature1D::GaussLobatto, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:9286
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:7421
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:98
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:1088
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:995
Basis & ClosedBasis(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.hpp:1428
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:66
H1Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:7192
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:948
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8795
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:127
Basis & GetBasis(const int p, const int type)
Get a Poly_1D::Basis object of the given degree and Quadrature1D type.
Definition: fe.cpp:6573
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:7442
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:8245
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:2298
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:8656
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:557
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:6993
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:1123
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:3257
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:10647
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:3017
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:10396
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:374
static int VerifyClosed(int pt_type)
Definition: fe.hpp:288
int DerivRangeType
Definition: fe.hpp:50
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2765
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:767
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8256
RefinedLinear2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:4146
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const NodalFiniteElement &fine_fe) const
Definition: fe.cpp:191
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5934
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:224
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4108
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:3836
Array< int > dof_map
Definition: fe.hpp:1641
RT_TetrahedronElement(const int p)
Definition: fe.cpp:9752
ND_QuadrilateralElement(const int p, const int cp_type=Quadrature1D::GaussLobatto, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:10307
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5490
L2_TetrahedronElement(const int p, const int type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8875
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:4041
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:6666
BiQuad2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:1360
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:2352
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:3054
P0TriangleFiniteElement()
Construct P0 triangle finite element.
Definition: fe.cpp:2264
const double * ClosedPoints(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.hpp:1414
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:2538
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
RT_TriangleElement(const int p)
Definition: fe.cpp:9599
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:6647
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:10937
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:10228
void Eval(const double x, Vector &u) const
Definition: fe.cpp:6224
L2Pos_SegmentElement(const int p)
Definition: fe.cpp:8218
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:4305
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5545
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:3637
Vector data type.
Definition: vector.hpp:41
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:5476
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:143
static void CalcBernstein(const int p, const double x, double *u)
Definition: fe.hpp:1466
virtual void Transform(const IntegrationPoint &, Vector &)=0
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:7247
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:8498
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1281
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:9677
Quad2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:1198
Describes the space on each element.
Definition: fe.hpp:29
H1_QuadrilateralElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:6713
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2493
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5395
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:8417
void PositiveLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const PositiveFiniteElement &fine_fe) const
Definition: fe.cpp:405
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:10689
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:3893
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:1599
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:974
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:2162
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:2603
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:86
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6814
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:5446
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:3661
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4576
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:10979
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:736
int GetRangeType() const
Definition: fe.hpp:130
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:1077
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:343
int Order
Order/degree of the shape functions.
Definition: fe.hpp:50
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2959
H1_TriangleElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:7473
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:3866
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:7014
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:6792
Basis(const int p, const double *nodes, const int _mode=1)
Definition: fe.cpp:6174
static void CalcDBinomTerms(const int p, const double x, const double y, double *d)
Definition: fe.cpp:6451
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:5059
TriLinear3DFiniteElement()
Construct a tri-linear FE on cube.
Definition: fe.cpp:2441
ND_SegmentElement(const int p, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:10921
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:133
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:1178
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:8477
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4163
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:3622
BiLinear2DFiniteElement()
Construct a bilinear FE on quadrilateral.
Definition: fe.cpp:982
L2_HexahedronElement(const int p, const int _type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8452
Poly_1D poly1d
Definition: fe.cpp:6619
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:6122
Lagrange1DFiniteElement(int degree)
Definition: fe.cpp:3674
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2702
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:5815
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9059
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8324
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:1044
const int ir_order
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:7562
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:652
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:445