MFEM  v3.4
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
fe.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Finite Element classes
13 
14 #include "fe.hpp"
15 #include "fe_coll.hpp"
16 #include "../mesh/nurbs.hpp"
17 #include "bilininteg.hpp"
18 #include <cmath>
19 
20 namespace mfem
21 {
22 
23 using namespace std;
24 
25 FiniteElement::FiniteElement(int D, int G, int Do, int O, int F)
26  : Nodes(Do)
27 {
28  Dim = D ; GeomType = G ; Dof = Do ; Order = O ; FuncSpace = F;
29  RangeType = SCALAR;
30  MapType = VALUE;
31  DerivType = NONE;
34  for (int i = 0; i < Geometry::MaxDim; i++) { Orders[i] = -1; }
35 #ifndef MFEM_THREAD_SAFE
37 #endif
38 }
39 
41  const IntegrationPoint &ip, DenseMatrix &shape) const
42 {
43  mfem_error ("FiniteElement::CalcVShape (ip, ...)\n"
44  " is not implemented for this class!");
45 }
46 
49 {
50  mfem_error ("FiniteElement::CalcVShape (trans, ...)\n"
51  " is not implemented for this class!");
52 }
53 
55  const IntegrationPoint &ip, Vector &divshape) const
56 {
57  mfem_error ("FiniteElement::CalcDivShape (ip, ...)\n"
58  " is not implemented for this class!");
59 }
60 
62  ElementTransformation &Trans, Vector &div_shape) const
63 {
64  CalcDivShape(Trans.GetIntPoint(), div_shape);
65  div_shape *= (1.0 / Trans.Weight());
66 }
67 
69  DenseMatrix &curl_shape) const
70 {
71  mfem_error ("FiniteElement::CalcCurlShape (ip, ...)\n"
72  " is not implemented for this class!");
73 }
74 
76  DenseMatrix &curl_shape) const
77 {
78  switch (Dim)
79  {
80  case 3:
81  {
82 #ifdef MFEM_THREAD_SAFE
84 #endif
86  MultABt(vshape, Trans.Jacobian(), curl_shape);
87  curl_shape *= (1.0 / Trans.Weight());
88  break;
89  }
90  case 2:
91  // This is valid for both 2x2 and 3x2 Jacobians
92  CalcCurlShape(Trans.GetIntPoint(), curl_shape);
93  curl_shape *= (1.0 / Trans.Weight());
94  break;
95  default:
96  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
97  }
98 }
99 
100 void FiniteElement::GetFaceDofs(int face, int **dofs, int *ndofs) const
101 {
102  mfem_error ("FiniteElement::GetFaceDofs (...)");
103 }
104 
106  DenseMatrix &h) const
107 {
108  mfem_error ("FiniteElement::CalcHessian (...) is not overloaded !");
109 }
110 
112  DenseMatrix &I) const
113 {
114  mfem_error ("GetLocalInterpolation (...) is not overloaded !");
115 }
116 
119  DenseMatrix &I) const
120 {
121  MFEM_ABORT("method is not overloaded !");
122 }
123 
125  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
126 {
127  mfem_error ("FiniteElement::Project (...) is not overloaded !");
128 }
129 
132 {
133  mfem_error ("FiniteElement::Project (...) (vector) is not overloaded !");
134 }
135 
137  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
138 {
139  mfem_error("FiniteElement::ProjectMatrixCoefficient() is not overloaded !");
140 }
141 
142 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
143 {
144  mfem_error("FiniteElement::ProjectDelta(...) is not implemented for "
145  "this element!");
146 }
147 
150 {
151  mfem_error("FiniteElement::Project(...) (fe version) is not implemented "
152  "for this element!");
153 }
154 
157  DenseMatrix &grad) const
158 {
159  mfem_error("FiniteElement::ProjectGrad(...) is not implemented for "
160  "this element!");
161 }
162 
165  DenseMatrix &curl) const
166 {
167  mfem_error("FiniteElement::ProjectCurl(...) is not implemented for "
168  "this element!");
169 }
170 
173  DenseMatrix &div) const
174 {
175  mfem_error("FiniteElement::ProjectDiv(...) is not implemented for "
176  "this element!");
177 }
178 
180  Vector &shape) const
181 {
182  CalcShape(Trans.GetIntPoint(), shape);
183  if (MapType == INTEGRAL)
184  {
185  shape /= Trans.Weight();
186  }
187 }
188 
190  DenseMatrix &dshape) const
191 {
192  MFEM_ASSERT(MapType == VALUE, "");
193 #ifdef MFEM_THREAD_SAFE
195 #endif
196  CalcDShape(Trans.GetIntPoint(), vshape);
197  Mult(vshape, Trans.InverseJacobian(), dshape);
198 }
199 
200 
203  const ScalarFiniteElement &fine_fe) const
204 {
205  double v[Geometry::MaxDim];
206  Vector vv (v, Dim);
207  IntegrationPoint f_ip;
208 
209 #ifdef MFEM_THREAD_SAFE
210  Vector c_shape(Dof);
211 #endif
212 
213  MFEM_ASSERT(MapType == fine_fe.GetMapType(), "");
214 
215  I.SetSize(fine_fe.Dof, Dof);
216  for (int i = 0; i < fine_fe.Dof; i++)
217  {
218  Trans.Transform(fine_fe.Nodes.IntPoint(i), vv);
219  f_ip.Set(v, Dim);
220  CalcShape(f_ip, c_shape);
221  for (int j = 0; j < Dof; j++)
222  if (fabs(I(i,j) = c_shape(j)) < 1.0e-12)
223  {
224  I(i,j) = 0.0;
225  }
226  }
227  if (MapType == INTEGRAL)
228  {
229  // assuming Trans is linear; this should be ok for all refinement types
231  I *= Trans.Weight();
232  }
233 }
234 
237  const ScalarFiniteElement &fine_fe) const
238 {
239  // General "interpolation", defined by L2 projection
240 
241  double v[Geometry::MaxDim];
242  Vector vv (v, Dim);
243  IntegrationPoint f_ip;
244 
245  const int fs = fine_fe.GetDof(), cs = this->GetDof();
246  I.SetSize(fs, cs);
247  Vector fine_shape(fs), coarse_shape(cs);
248  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
249  const int ir_order = GetOrder() + fine_fe.GetOrder();
250  const IntegrationRule &ir = IntRules.Get(fine_fe.GetGeomType(), ir_order);
251 
252  for (int i = 0; i < ir.GetNPoints(); i++)
253  {
254  const IntegrationPoint &ip = ir.IntPoint(i);
255  fine_fe.CalcShape(ip, fine_shape);
256  Trans.Transform(ip, vv);
257  f_ip.Set(v, Dim);
258  this->CalcShape(f_ip, coarse_shape);
259 
260  AddMult_a_VVt(ip.weight, fine_shape, fine_mass);
261  AddMult_a_VWt(ip.weight, fine_shape, coarse_shape, fine_coarse_mass);
262  }
263 
264  DenseMatrixInverse fine_mass_inv(fine_mass);
265  fine_mass_inv.Mult(fine_coarse_mass, I);
266 
267  if (MapType == INTEGRAL)
268  {
269  // assuming Trans is linear; this should be ok for all refinement types
271  I *= Trans.Weight();
272  }
273 }
274 
275 
278  DenseMatrix &curl) const
279 {
280  MFEM_ASSERT(GetMapType() == FiniteElement::INTEGRAL, "");
281 
282  DenseMatrix curl_shape(fe.GetDof(), 1);
283 
284  curl.SetSize(Dof, fe.GetDof());
285  for (int i = 0; i < Dof; i++)
286  {
287  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
288  for (int j = 0; j < fe.GetDof(); j++)
289  {
290  curl(i,j) = curl_shape(j,0);
291  }
292  }
293 }
294 
296  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
297 {
298  for (int i = 0; i < Dof; i++)
299  {
300  const IntegrationPoint &ip = Nodes.IntPoint(i);
301  // some coefficients expect that Trans.IntPoint is the same
302  // as the second argument of Eval
303  Trans.SetIntPoint(&ip);
304  dofs(i) = coeff.Eval (Trans, ip);
305  if (MapType == INTEGRAL)
306  {
307  dofs(i) *= Trans.Weight();
308  }
309  }
310 }
311 
314 {
315  MFEM_ASSERT(dofs.Size() == vc.GetVDim()*Dof, "");
316  Vector x(vc.GetVDim());
317 
318  for (int i = 0; i < Dof; i++)
319  {
320  const IntegrationPoint &ip = Nodes.IntPoint(i);
321  Trans.SetIntPoint(&ip);
322  vc.Eval (x, Trans, ip);
323  if (MapType == INTEGRAL)
324  {
325  x *= Trans.Weight();
326  }
327  for (int j = 0; j < x.Size(); j++)
328  {
329  dofs(Dof*j+i) = x(j);
330  }
331  }
332 }
333 
335  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
336 {
337  // (mc.height x mc.width) @ DOFs -> (Dof x mc.width x mc.height) in dofs
338  MFEM_ASSERT(dofs.Size() == mc.GetHeight()*mc.GetWidth()*Dof, "");
339  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
340 
341  for (int k = 0; k < Dof; k++)
342  {
343  T.SetIntPoint(&Nodes.IntPoint(k));
344  mc.Eval(MQ, T, Nodes.IntPoint(k));
345  if (MapType == INTEGRAL) { MQ *= T.Weight(); }
346  for (int r = 0; r < MQ.Height(); r++)
347  {
348  for (int d = 0; d < MQ.Width(); d++)
349  {
350  dofs(k+Dof*(d+MQ.Width()*r)) = MQ(r,d);
351  }
352  }
353  }
354 }
355 
358 {
359  if (fe.GetRangeType() == SCALAR)
360  {
361  MFEM_ASSERT(MapType == fe.GetMapType(), "");
362 
363  Vector shape(fe.GetDof());
364 
365  I.SetSize(Dof, fe.GetDof());
366  for (int k = 0; k < Dof; k++)
367  {
368  fe.CalcShape(Nodes.IntPoint(k), shape);
369  for (int j = 0; j < shape.Size(); j++)
370  {
371  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
372  }
373  }
374  }
375  else
376  {
377  DenseMatrix vshape(fe.GetDof(), Trans.GetSpaceDim());
378 
379  I.SetSize(vshape.Width()*Dof, fe.GetDof());
380  for (int k = 0; k < Dof; k++)
381  {
382  Trans.SetIntPoint(&Nodes.IntPoint(k));
383  fe.CalcVShape(Trans, vshape);
384  if (MapType == INTEGRAL)
385  {
386  vshape *= Trans.Weight();
387  }
388  for (int j = 0; j < vshape.Height(); j++)
389  for (int d = 0; d < vshape.Width(); d++)
390  {
391  I(k+d*Dof,j) = vshape(j,d);
392  }
393  }
394  }
395 }
396 
399  DenseMatrix &grad) const
400 {
401  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
402  MFEM_ASSERT(Trans.GetSpaceDim() == Dim, "")
403 
404  DenseMatrix dshape(fe.GetDof(), Dim), grad_k(fe.GetDof(), Dim), Jinv(Dim);
405 
406  grad.SetSize(Dim*Dof, fe.GetDof());
407  for (int k = 0; k < Dof; k++)
408  {
409  const IntegrationPoint &ip = Nodes.IntPoint(k);
410  fe.CalcDShape(ip, dshape);
411  Trans.SetIntPoint(&ip);
412  CalcInverse(Trans.Jacobian(), Jinv);
413  Mult(dshape, Jinv, grad_k);
414  if (MapType == INTEGRAL)
415  {
416  grad_k *= Trans.Weight();
417  }
418  for (int j = 0; j < grad_k.Height(); j++)
419  for (int d = 0; d < Dim; d++)
420  {
421  grad(k+d*Dof,j) = grad_k(j,d);
422  }
423  }
424 }
425 
428  DenseMatrix &div) const
429 {
430  double detJ;
431  Vector div_shape(fe.GetDof());
432 
433  div.SetSize(Dof, fe.GetDof());
434  for (int k = 0; k < Dof; k++)
435  {
436  const IntegrationPoint &ip = Nodes.IntPoint(k);
437  fe.CalcDivShape(ip, div_shape);
438  if (MapType == VALUE)
439  {
440  Trans.SetIntPoint(&ip);
441  detJ = Trans.Weight();
442  for (int j = 0; j < div_shape.Size(); j++)
443  {
444  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
445  }
446  }
447  else
448  {
449  for (int j = 0; j < div_shape.Size(); j++)
450  {
451  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
452  }
453  }
454  }
455 }
456 
457 
459  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
460 {
461  for (int i = 0; i < Dof; i++)
462  {
463  const IntegrationPoint &ip = Nodes.IntPoint(i);
464  Trans.SetIntPoint(&ip);
465  dofs(i) = coeff.Eval(Trans, ip);
466  }
467 }
468 
471 {
472  const NodalFiniteElement *nfe =
473  dynamic_cast<const NodalFiniteElement *>(&fe);
474 
475  if (nfe && Dof == nfe->GetDof())
476  {
477  nfe->Project(*this, Trans, I);
478  I.Invert();
479  }
480  else
481  {
482  // local L2 projection
483  DenseMatrix pos_mass, mixed_mass;
484  MassIntegrator mass_integ;
485 
486  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
487  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
488 
489  DenseMatrixInverse pos_mass_inv(pos_mass);
490  I.SetSize(Dof, fe.GetDof());
491  pos_mass_inv.Mult(mixed_mass, I);
492  }
493 }
494 
495 
496 void VectorFiniteElement::CalcShape (
497  const IntegrationPoint &ip, Vector &shape ) const
498 {
499  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
500  " VectorFiniteElements!");
501 }
502 
503 void VectorFiniteElement::CalcDShape (
504  const IntegrationPoint &ip, DenseMatrix &dshape ) const
505 {
506  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
507  " VectorFiniteElements!");
508 }
509 
511 {
512  switch (MapType)
513  {
514  case H_DIV:
515  DerivType = DIV;
518  break;
519  case H_CURL:
520  switch (Dim)
521  {
522  case 3: // curl: 3D H_CURL -> 3D H_DIV
523  DerivType = CURL;
526  break;
527  case 2:
528  // curl: 2D H_CURL -> INTEGRAL
529  DerivType = CURL;
532  break;
533  case 1:
534  DerivType = NONE;
537  break;
538  default:
539  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
540  }
541  break;
542  default:
543  MFEM_ABORT("Invalid MapType = " << MapType);
544  }
545 }
546 
548  ElementTransformation &Trans, DenseMatrix &shape) const
549 {
550  MFEM_ASSERT(MapType == H_DIV, "");
551 #ifdef MFEM_THREAD_SAFE
553 #endif
554  CalcVShape(Trans.GetIntPoint(), vshape);
555  MultABt(vshape, Trans.Jacobian(), shape);
556  shape *= (1.0 / Trans.Weight());
557 }
558 
560  ElementTransformation &Trans, DenseMatrix &shape) const
561 {
562  MFEM_ASSERT(MapType == H_CURL, "");
563 #ifdef MFEM_THREAD_SAFE
565 #endif
566  CalcVShape(Trans.GetIntPoint(), vshape);
567  Mult(vshape, Trans.InverseJacobian(), shape);
568 }
569 
571  const double *nk, const Array<int> &d2n,
573 {
574  double vk[Geometry::MaxDim];
575  const int sdim = Trans.GetSpaceDim();
576  MFEM_ASSERT(vc.GetVDim() == sdim, "");
577  Vector xk(vk, sdim);
578  const bool square_J = (Dim == sdim);
579 
580  for (int k = 0; k < Dof; k++)
581  {
582  Trans.SetIntPoint(&Nodes.IntPoint(k));
583  vc.Eval(xk, Trans, Nodes.IntPoint(k));
584  // dof_k = nk^t adj(J) xk
585  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*Dim);
586  if (!square_J) { dofs(k) /= Trans.Weight(); }
587  }
588 }
589 
591  const double *nk, const Array<int> &d2n,
592  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
593 {
594  // project the rows of the matrix coefficient in an RT space
595 
596  const int sdim = T.GetSpaceDim();
597  MFEM_ASSERT(mc.GetWidth() == sdim, "");
598  const bool square_J = (Dim == sdim);
599  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
600  Vector nk_phys(sdim), dofs_k(MQ.Height());
601  MFEM_ASSERT(dofs.Size() == Dof*MQ.Height(), "");
602 
603  for (int k = 0; k < Dof; k++)
604  {
605  T.SetIntPoint(&Nodes.IntPoint(k));
606  mc.Eval(MQ, T, Nodes.IntPoint(k));
607  // nk_phys = adj(J)^t nk
608  T.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, nk_phys);
609  if (!square_J) { nk_phys /= T.Weight(); }
610  MQ.Mult(nk_phys, dofs_k);
611  for (int r = 0; r < MQ.Height(); r++)
612  {
613  dofs(k+Dof*r) = dofs_k(r);
614  }
615  }
616 }
617 
619  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
621 {
622  if (fe.GetRangeType() == SCALAR)
623  {
624  double vk[Geometry::MaxDim];
625  Vector shape(fe.GetDof());
626  int sdim = Trans.GetSpaceDim();
627 
628  I.SetSize(Dof, sdim*fe.GetDof());
629  for (int k = 0; k < Dof; k++)
630  {
631  const IntegrationPoint &ip = Nodes.IntPoint(k);
632 
633  fe.CalcShape(ip, shape);
634  Trans.SetIntPoint(&ip);
635  Trans.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, vk);
636  if (fe.GetMapType() == INTEGRAL)
637  {
638  double w = 1.0/Trans.Weight();
639  for (int d = 0; d < Dim; d++)
640  {
641  vk[d] *= w;
642  }
643  }
644 
645  for (int j = 0; j < shape.Size(); j++)
646  {
647  double s = shape(j);
648  if (fabs(s) < 1e-12)
649  {
650  s = 0.0;
651  }
652  for (int d = 0; d < sdim; d++)
653  {
654  I(k,j+d*shape.Size()) = s*vk[d];
655  }
656  }
657  }
658  }
659  else
660  {
661  mfem_error("VectorFiniteElement::Project_RT (fe version)");
662  }
663 }
664 
666  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
668 {
669  if (Dim != 2)
670  {
671  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
672  }
673 
674  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
675  Vector grad_k(fe.GetDof());
676  double tk[2];
677 
678  grad.SetSize(Dof, fe.GetDof());
679  for (int k = 0; k < Dof; k++)
680  {
681  fe.CalcDShape(Nodes.IntPoint(k), dshape);
682  tk[0] = nk[d2n[k]*Dim+1];
683  tk[1] = -nk[d2n[k]*Dim];
684  dshape.Mult(tk, grad_k);
685  for (int j = 0; j < grad_k.Size(); j++)
686  {
687  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
688  }
689  }
690 }
691 
693  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
695 {
696 #ifdef MFEM_THREAD_SAFE
699  DenseMatrix J(Dim, Dim);
700 #else
701  curlshape.SetSize(fe.GetDof(), Dim);
702  curlshape_J.SetSize(fe.GetDof(), Dim);
703  J.SetSize(Dim, Dim);
704 #endif
705 
706  Vector curl_k(fe.GetDof());
707 
708  curl.SetSize(Dof, fe.GetDof());
709  for (int k = 0; k < Dof; k++)
710  {
711  const IntegrationPoint &ip = Nodes.IntPoint(k);
712 
713  // calculate J^t * J / |J|
714  Trans.SetIntPoint(&ip);
715  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
716  J *= 1.0 / Trans.Weight();
717 
718  // transform curl of shapes (rows) by J^t * J / |J|
719  fe.CalcCurlShape(ip, curlshape);
721 
722  curlshape_J.Mult(tk + d2t[k]*Dim, curl_k);
723  for (int j = 0; j < curl_k.Size(); j++)
724  {
725  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
726  }
727  }
728 }
729 
731  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
733 {
734  DenseMatrix curl_shape(fe.GetDof(), Dim);
735  Vector curl_k(fe.GetDof());
736 
737  curl.SetSize(Dof, fe.GetDof());
738  for (int k = 0; k < Dof; k++)
739  {
740  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
741  curl_shape.Mult(nk + d2n[k]*Dim, curl_k);
742  for (int j = 0; j < curl_k.Size(); j++)
743  {
744  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
745  }
746  }
747 }
748 
750  const double *tk, const Array<int> &d2t,
752 {
753  double vk[Geometry::MaxDim];
754  Vector xk(vk, vc.GetVDim());
755 
756  for (int k = 0; k < Dof; k++)
757  {
758  Trans.SetIntPoint(&Nodes.IntPoint(k));
759 
760  vc.Eval(xk, Trans, Nodes.IntPoint(k));
761  // dof_k = xk^t J tk
762  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*Dim, vk);
763  }
764 }
765 
767  const double *tk, const Array<int> &d2t,
768  MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
769 {
770  // project the rows of the matrix coefficient in an ND space
771 
772  const int sdim = T.GetSpaceDim();
773  MFEM_ASSERT(mc.GetWidth() == sdim, "");
774  DenseMatrix MQ(mc.GetHeight(), mc.GetWidth());
775  Vector tk_phys(sdim), dofs_k(MQ.Height());
776  MFEM_ASSERT(dofs.Size() == Dof*MQ.Height(), "");
777 
778  for (int k = 0; k < Dof; k++)
779  {
780  T.SetIntPoint(&Nodes.IntPoint(k));
781  mc.Eval(MQ, T, Nodes.IntPoint(k));
782  // tk_phys = J tk
783  T.Jacobian().Mult(tk + d2t[k]*Dim, tk_phys);
784  MQ.Mult(tk_phys, dofs_k);
785  for (int r = 0; r < MQ.Height(); r++)
786  {
787  dofs(k+Dof*r) = dofs_k(r);
788  }
789  }
790 }
791 
793  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
795 {
796  if (fe.GetRangeType() == SCALAR)
797  {
798  int sdim = Trans.GetSpaceDim();
799  double vk[Geometry::MaxDim];
800  Vector shape(fe.GetDof());
801 
802  I.SetSize(Dof, sdim*fe.GetDof());
803  for (int k = 0; k < Dof; k++)
804  {
805  const IntegrationPoint &ip = Nodes.IntPoint(k);
806 
807  fe.CalcShape(ip, shape);
808  Trans.SetIntPoint(&ip);
809  Trans.Jacobian().Mult(tk + d2t[k]*Dim, vk);
810  if (fe.GetMapType() == INTEGRAL)
811  {
812  double w = 1.0/Trans.Weight();
813  for (int d = 0; d < sdim; d++)
814  {
815  vk[d] *= w;
816  }
817  }
818 
819  for (int j = 0; j < shape.Size(); j++)
820  {
821  double s = shape(j);
822  if (fabs(s) < 1e-12)
823  {
824  s = 0.0;
825  }
826  for (int d = 0; d < sdim; d++)
827  {
828  I(k, j + d*shape.Size()) = s*vk[d];
829  }
830  }
831  }
832  }
833  else
834  {
835  mfem_error("VectorFiniteElement::Project_ND (fe version)");
836  }
837 }
838 
840  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
842 {
843  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
844 
845  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
846  Vector grad_k(fe.GetDof());
847 
848  grad.SetSize(Dof, fe.GetDof());
849  for (int k = 0; k < Dof; k++)
850  {
851  fe.CalcDShape(Nodes.IntPoint(k), dshape);
852  dshape.Mult(tk + d2t[k]*Dim, grad_k);
853  for (int j = 0; j < grad_k.Size(); j++)
854  {
855  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
856  }
857  }
858 }
859 
861  const VectorFiniteElement &cfe, const double *nk, const Array<int> &d2n,
863 {
864  MFEM_ASSERT(MapType == cfe.GetMapType(), "");
865 
866  double vk[Geometry::MaxDim];
867  Vector xk(vk, Dim);
868  IntegrationPoint ip;
869 #ifdef MFEM_THREAD_SAFE
870  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
871 #else
872  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
873 #endif
874  I.SetSize(Dof, vshape.Height());
875 
876  // assuming Trans is linear; this should be ok for all refinement types
878  const DenseMatrix &adjJ = Trans.AdjugateJacobian();
879  for (int k = 0; k < Dof; k++)
880  {
881  Trans.Transform(Nodes.IntPoint(k), xk);
882  ip.Set3(vk);
883  cfe.CalcVShape(ip, vshape);
884  // xk = |J| J^{-t} n_k
885  adjJ.MultTranspose(nk + d2n[k]*Dim, vk);
886  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,Dof
887  for (int j = 0; j < vshape.Height(); j++)
888  {
889  double Ikj = 0.;
890  for (int i = 0; i < Dim; i++)
891  {
892  Ikj += vshape(j, i) * vk[i];
893  }
894  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
895  }
896  }
897 }
898 
900  const VectorFiniteElement &cfe, const double *tk, const Array<int> &d2t,
902 {
903  double vk[Geometry::MaxDim];
904  Vector xk(vk, Dim);
905  IntegrationPoint ip;
906 #ifdef MFEM_THREAD_SAFE
907  DenseMatrix vshape(cfe.GetDof(), cfe.GetDim());
908 #else
909  DenseMatrix vshape(cfe.vshape.Data(), cfe.GetDof(), cfe.GetDim());
910 #endif
911  I.SetSize(Dof, vshape.Height());
912 
913  // assuming Trans is linear; this should be ok for all refinement types
915  const DenseMatrix &J = Trans.Jacobian();
916  for (int k = 0; k < Dof; k++)
917  {
918  Trans.Transform(Nodes.IntPoint(k), xk);
919  ip.Set3(vk);
920  cfe.CalcVShape(ip, vshape);
921  // xk = J t_k
922  J.Mult(tk + d2t[k]*Dim, vk);
923  // I_k = vshape_k.J.t_k, k=1,...,Dof
924  for (int j = 0; j < vshape.Height(); j++)
925  {
926  double Ikj = 0.;
927  for (int i = 0; i < Dim; i++)
928  {
929  Ikj += vshape(j, i) * vk[i];
930  }
931  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
932  }
933  }
934 }
935 
936 
938  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
939 {
940  Nodes.IntPoint(0).x = 0.0;
941 }
942 
944  Vector &shape) const
945 {
946  shape(0) = 1.;
947 }
948 
950  DenseMatrix &dshape) const
951 {
952  // dshape is (1 x 0) - nothing to compute
953 }
954 
956  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
957 {
958  Nodes.IntPoint(0).x = 0.0;
959  Nodes.IntPoint(1).x = 1.0;
960 }
961 
963  Vector &shape) const
964 {
965  shape(0) = 1. - ip.x;
966  shape(1) = ip.x;
967 }
968 
970  DenseMatrix &dshape) const
971 {
972  dshape(0,0) = -1.;
973  dshape(1,0) = 1.;
974 }
975 
977  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
978 {
979  Nodes.IntPoint(0).x = 0.0;
980  Nodes.IntPoint(0).y = 0.0;
981  Nodes.IntPoint(1).x = 1.0;
982  Nodes.IntPoint(1).y = 0.0;
983  Nodes.IntPoint(2).x = 0.0;
984  Nodes.IntPoint(2).y = 1.0;
985 }
986 
988  Vector &shape) const
989 {
990  shape(0) = 1. - ip.x - ip.y;
991  shape(1) = ip.x;
992  shape(2) = ip.y;
993 }
994 
996  DenseMatrix &dshape) const
997 {
998  dshape(0,0) = -1.; dshape(0,1) = -1.;
999  dshape(1,0) = 1.; dshape(1,1) = 0.;
1000  dshape(2,0) = 0.; dshape(2,1) = 1.;
1001 }
1002 
1004  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1005 {
1006  Nodes.IntPoint(0).x = 0.0;
1007  Nodes.IntPoint(0).y = 0.0;
1008  Nodes.IntPoint(1).x = 1.0;
1009  Nodes.IntPoint(1).y = 0.0;
1010  Nodes.IntPoint(2).x = 1.0;
1011  Nodes.IntPoint(2).y = 1.0;
1012  Nodes.IntPoint(3).x = 0.0;
1013  Nodes.IntPoint(3).y = 1.0;
1014 }
1015 
1017  Vector &shape) const
1018 {
1019  shape(0) = (1. - ip.x) * (1. - ip.y) ;
1020  shape(1) = ip.x * (1. - ip.y) ;
1021  shape(2) = ip.x * ip.y ;
1022  shape(3) = (1. - ip.x) * ip.y ;
1023 }
1024 
1026  DenseMatrix &dshape) const
1027 {
1028  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
1029  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
1030  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
1031  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
1032 }
1033 
1035  const IntegrationPoint &ip, DenseMatrix &h) const
1036 {
1037  h(0,0) = 0.; h(0,1) = 1.; h(0,2) = 0.;
1038  h(1,0) = 0.; h(1,1) = -1.; h(1,2) = 0.;
1039  h(2,0) = 0.; h(2,1) = 1.; h(2,2) = 0.;
1040  h(3,0) = 0.; h(3,1) = -1.; h(3,2) = 0.;
1041 }
1042 
1043 
1045  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
1046 {
1047  Nodes.IntPoint(0).x = 1./6.;
1048  Nodes.IntPoint(0).y = 1./6.;
1049  Nodes.IntPoint(1).x = 2./3.;
1050  Nodes.IntPoint(1).y = 1./6.;
1051  Nodes.IntPoint(2).x = 1./6.;
1052  Nodes.IntPoint(2).y = 2./3.;
1053 }
1054 
1056  Vector &shape) const
1057 {
1058  const double x = ip.x, y = ip.y;
1059 
1060  shape(0) = 5./3. - 2. * (x + y);
1061  shape(1) = 2. * (x - 1./6.);
1062  shape(2) = 2. * (y - 1./6.);
1063 }
1064 
1066  DenseMatrix &dshape) const
1067 {
1068  dshape(0,0) = -2.; dshape(0,1) = -2.;
1069  dshape(1,0) = 2.; dshape(1,1) = 0.;
1070  dshape(2,0) = 0.; dshape(2,1) = 2.;
1071 }
1072 
1074 {
1075  dofs(vertex) = 2./3.;
1076  dofs((vertex+1)%3) = 1./6.;
1077  dofs((vertex+2)%3) = 1./6.;
1078 }
1079 
1080 
1081 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
1082 const double GaussBiLinear2DFiniteElement::p[] =
1083 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
1084 
1086  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
1087 {
1088  Nodes.IntPoint(0).x = p[0];
1089  Nodes.IntPoint(0).y = p[0];
1090  Nodes.IntPoint(1).x = p[1];
1091  Nodes.IntPoint(1).y = p[0];
1092  Nodes.IntPoint(2).x = p[1];
1093  Nodes.IntPoint(2).y = p[1];
1094  Nodes.IntPoint(3).x = p[0];
1095  Nodes.IntPoint(3).y = p[1];
1096 }
1097 
1099  Vector &shape) const
1100 {
1101  const double x = ip.x, y = ip.y;
1102 
1103  shape(0) = 3. * (p[1] - x) * (p[1] - y);
1104  shape(1) = 3. * (x - p[0]) * (p[1] - y);
1105  shape(2) = 3. * (x - p[0]) * (y - p[0]);
1106  shape(3) = 3. * (p[1] - x) * (y - p[0]);
1107 }
1108 
1110  DenseMatrix &dshape) const
1111 {
1112  const double x = ip.x, y = ip.y;
1113 
1114  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
1115  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
1116  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
1117  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
1118 }
1119 
1121 {
1122 #if 1
1123  dofs(vertex) = p[1]*p[1];
1124  dofs((vertex+1)%4) = p[0]*p[1];
1125  dofs((vertex+2)%4) = p[0]*p[0];
1126  dofs((vertex+3)%4) = p[0]*p[1];
1127 #else
1128  dofs = 1.0;
1129 #endif
1130 }
1131 
1132 
1134  : NodalFiniteElement(2, Geometry::SQUARE, 3, 1, FunctionSpace::Qk)
1135 {
1136  Nodes.IntPoint(0).x = 0.0;
1137  Nodes.IntPoint(0).y = 0.0;
1138  Nodes.IntPoint(1).x = 1.0;
1139  Nodes.IntPoint(1).y = 0.0;
1140  Nodes.IntPoint(2).x = 0.0;
1141  Nodes.IntPoint(2).y = 1.0;
1142 }
1143 
1145  Vector &shape) const
1146 {
1147  shape(0) = 1. - ip.x - ip.y;
1148  shape(1) = ip.x;
1149  shape(2) = ip.y;
1150 }
1151 
1153  DenseMatrix &dshape) const
1154 {
1155  dshape(0,0) = -1.; dshape(0,1) = -1.;
1156  dshape(1,0) = 1.; dshape(1,1) = 0.;
1157  dshape(2,0) = 0.; dshape(2,1) = 1.;
1158 }
1159 
1160 
1162  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
1163 {
1164  Nodes.IntPoint(0).x = 0.0;
1165  Nodes.IntPoint(1).x = 1.0;
1166  Nodes.IntPoint(2).x = 0.5;
1167 }
1168 
1170  Vector &shape) const
1171 {
1172  double x = ip.x;
1173  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
1174 
1175  shape(0) = l1 * (-l3);
1176  shape(1) = l2 * l3;
1177  shape(2) = 4. * l1 * l2;
1178 }
1179 
1181  DenseMatrix &dshape) const
1182 {
1183  double x = ip.x;
1184 
1185  dshape(0,0) = 4. * x - 3.;
1186  dshape(1,0) = 4. * x - 1.;
1187  dshape(2,0) = 4. - 8. * x;
1188 }
1189 
1190 
1192  : PositiveFiniteElement(1, Geometry::SEGMENT, 3, 2)
1193 {
1194  Nodes.IntPoint(0).x = 0.0;
1195  Nodes.IntPoint(1).x = 1.0;
1196  Nodes.IntPoint(2).x = 0.5;
1197 }
1198 
1200  Vector &shape) const
1201 {
1202  const double x = ip.x, x1 = 1. - x;
1203 
1204  shape(0) = x1 * x1;
1205  shape(1) = x * x;
1206  shape(2) = 2. * x * x1;
1207 }
1208 
1210  DenseMatrix &dshape) const
1211 {
1212  const double x = ip.x;
1213 
1214  dshape(0,0) = 2. * x - 2.;
1215  dshape(1,0) = 2. * x;
1216  dshape(2,0) = 2. - 4. * x;
1217 }
1218 
1220  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1221 {
1222  Nodes.IntPoint(0).x = 0.0;
1223  Nodes.IntPoint(0).y = 0.0;
1224  Nodes.IntPoint(1).x = 1.0;
1225  Nodes.IntPoint(1).y = 0.0;
1226  Nodes.IntPoint(2).x = 0.0;
1227  Nodes.IntPoint(2).y = 1.0;
1228  Nodes.IntPoint(3).x = 0.5;
1229  Nodes.IntPoint(3).y = 0.0;
1230  Nodes.IntPoint(4).x = 0.5;
1231  Nodes.IntPoint(4).y = 0.5;
1232  Nodes.IntPoint(5).x = 0.0;
1233  Nodes.IntPoint(5).y = 0.5;
1234 }
1235 
1237  Vector &shape) const
1238 {
1239  double x = ip.x, y = ip.y;
1240  double l1 = 1.-x-y, l2 = x, l3 = y;
1241 
1242  shape(0) = l1 * (2. * l1 - 1.);
1243  shape(1) = l2 * (2. * l2 - 1.);
1244  shape(2) = l3 * (2. * l3 - 1.);
1245  shape(3) = 4. * l1 * l2;
1246  shape(4) = 4. * l2 * l3;
1247  shape(5) = 4. * l3 * l1;
1248 }
1249 
1251  DenseMatrix &dshape) const
1252 {
1253  double x = ip.x, y = ip.y;
1254 
1255  dshape(0,0) =
1256  dshape(0,1) = 4. * (x + y) - 3.;
1257 
1258  dshape(1,0) = 4. * x - 1.;
1259  dshape(1,1) = 0.;
1260 
1261  dshape(2,0) = 0.;
1262  dshape(2,1) = 4. * y - 1.;
1263 
1264  dshape(3,0) = -4. * (2. * x + y - 1.);
1265  dshape(3,1) = -4. * x;
1266 
1267  dshape(4,0) = 4. * y;
1268  dshape(4,1) = 4. * x;
1269 
1270  dshape(5,0) = -4. * y;
1271  dshape(5,1) = -4. * (x + 2. * y - 1.);
1272 }
1273 
1275  DenseMatrix &h) const
1276 {
1277  h(0,0) = 4.;
1278  h(0,1) = 4.;
1279  h(0,2) = 4.;
1280 
1281  h(1,0) = 4.;
1282  h(1,1) = 0.;
1283  h(1,2) = 0.;
1284 
1285  h(2,0) = 0.;
1286  h(2,1) = 0.;
1287  h(2,2) = 4.;
1288 
1289  h(3,0) = -8.;
1290  h(3,1) = -4.;
1291  h(3,2) = 0.;
1292 
1293  h(4,0) = 0.;
1294  h(4,1) = 4.;
1295  h(4,2) = 0.;
1296 
1297  h(5,0) = 0.;
1298  h(5,1) = -4.;
1299  h(5,2) = -8.;
1300 }
1301 
1302 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1303 {
1304 #if 0
1305  dofs = 1.;
1306 #else
1307  dofs = 0.;
1308  dofs(vertex) = 1.;
1309  switch (vertex)
1310  {
1311  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1312  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1313  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1314  }
1315 #endif
1316 }
1317 
1318 
1319 const double GaussQuad2DFiniteElement::p[] =
1320 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1321 
1323  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1324 {
1325  Nodes.IntPoint(0).x = p[0];
1326  Nodes.IntPoint(0).y = p[0];
1327  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1328  Nodes.IntPoint(1).y = p[0];
1329  Nodes.IntPoint(2).x = p[0];
1330  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1331  Nodes.IntPoint(3).x = p[1];
1332  Nodes.IntPoint(3).y = p[1];
1333  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1334  Nodes.IntPoint(4).y = p[1];
1335  Nodes.IntPoint(5).x = p[1];
1336  Nodes.IntPoint(5).y = 1. - 2. * p[1];
1337 
1338  for (int i = 0; i < 6; i++)
1339  {
1340  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
1341  A(0,i) = 1.;
1342  A(1,i) = x;
1343  A(2,i) = y;
1344  A(3,i) = x * x;
1345  A(4,i) = x * y;
1346  A(5,i) = y * y;
1347  }
1348 
1349  A.Invert();
1350 }
1351 
1353  Vector &shape) const
1354 {
1355  const double x = ip.x, y = ip.y;
1356  pol(0) = 1.;
1357  pol(1) = x;
1358  pol(2) = y;
1359  pol(3) = x * x;
1360  pol(4) = x * y;
1361  pol(5) = y * y;
1362 
1363  A.Mult(pol, shape);
1364 }
1365 
1367  DenseMatrix &dshape) const
1368 {
1369  const double x = ip.x, y = ip.y;
1370  D(0,0) = 0.; D(0,1) = 0.;
1371  D(1,0) = 1.; D(1,1) = 0.;
1372  D(2,0) = 0.; D(2,1) = 1.;
1373  D(3,0) = 2. * x; D(3,1) = 0.;
1374  D(4,0) = y; D(4,1) = x;
1375  D(5,0) = 0.; D(5,1) = 2. * y;
1376 
1377  Mult(A, D, dshape);
1378 }
1379 
1380 
1382  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1383 {
1384  Nodes.IntPoint(0).x = 0.0;
1385  Nodes.IntPoint(0).y = 0.0;
1386  Nodes.IntPoint(1).x = 1.0;
1387  Nodes.IntPoint(1).y = 0.0;
1388  Nodes.IntPoint(2).x = 1.0;
1389  Nodes.IntPoint(2).y = 1.0;
1390  Nodes.IntPoint(3).x = 0.0;
1391  Nodes.IntPoint(3).y = 1.0;
1392  Nodes.IntPoint(4).x = 0.5;
1393  Nodes.IntPoint(4).y = 0.0;
1394  Nodes.IntPoint(5).x = 1.0;
1395  Nodes.IntPoint(5).y = 0.5;
1396  Nodes.IntPoint(6).x = 0.5;
1397  Nodes.IntPoint(6).y = 1.0;
1398  Nodes.IntPoint(7).x = 0.0;
1399  Nodes.IntPoint(7).y = 0.5;
1400  Nodes.IntPoint(8).x = 0.5;
1401  Nodes.IntPoint(8).y = 0.5;
1402 }
1403 
1405  Vector &shape) const
1406 {
1407  double x = ip.x, y = ip.y;
1408  double l1x, l2x, l3x, l1y, l2y, l3y;
1409 
1410  l1x = (x - 1.) * (2. * x - 1);
1411  l2x = 4. * x * (1. - x);
1412  l3x = x * (2. * x - 1.);
1413  l1y = (y - 1.) * (2. * y - 1);
1414  l2y = 4. * y * (1. - y);
1415  l3y = y * (2. * y - 1.);
1416 
1417  shape(0) = l1x * l1y;
1418  shape(4) = l2x * l1y;
1419  shape(1) = l3x * l1y;
1420  shape(7) = l1x * l2y;
1421  shape(8) = l2x * l2y;
1422  shape(5) = l3x * l2y;
1423  shape(3) = l1x * l3y;
1424  shape(6) = l2x * l3y;
1425  shape(2) = l3x * l3y;
1426 }
1427 
1429  DenseMatrix &dshape) const
1430 {
1431  double x = ip.x, y = ip.y;
1432  double l1x, l2x, l3x, l1y, l2y, l3y;
1433  double d1x, d2x, d3x, d1y, d2y, d3y;
1434 
1435  l1x = (x - 1.) * (2. * x - 1);
1436  l2x = 4. * x * (1. - x);
1437  l3x = x * (2. * x - 1.);
1438  l1y = (y - 1.) * (2. * y - 1);
1439  l2y = 4. * y * (1. - y);
1440  l3y = y * (2. * y - 1.);
1441 
1442  d1x = 4. * x - 3.;
1443  d2x = 4. - 8. * x;
1444  d3x = 4. * x - 1.;
1445  d1y = 4. * y - 3.;
1446  d2y = 4. - 8. * y;
1447  d3y = 4. * y - 1.;
1448 
1449  dshape(0,0) = d1x * l1y;
1450  dshape(0,1) = l1x * d1y;
1451 
1452  dshape(4,0) = d2x * l1y;
1453  dshape(4,1) = l2x * d1y;
1454 
1455  dshape(1,0) = d3x * l1y;
1456  dshape(1,1) = l3x * d1y;
1457 
1458  dshape(7,0) = d1x * l2y;
1459  dshape(7,1) = l1x * d2y;
1460 
1461  dshape(8,0) = d2x * l2y;
1462  dshape(8,1) = l2x * d2y;
1463 
1464  dshape(5,0) = d3x * l2y;
1465  dshape(5,1) = l3x * d2y;
1466 
1467  dshape(3,0) = d1x * l3y;
1468  dshape(3,1) = l1x * d3y;
1469 
1470  dshape(6,0) = d2x * l3y;
1471  dshape(6,1) = l2x * d3y;
1472 
1473  dshape(2,0) = d3x * l3y;
1474  dshape(2,1) = l3x * d3y;
1475 }
1476 
1477 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1478 {
1479 #if 0
1480  dofs = 1.;
1481 #else
1482  dofs = 0.;
1483  dofs(vertex) = 1.;
1484  switch (vertex)
1485  {
1486  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
1487  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
1488  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
1489  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
1490  }
1491  dofs(8) = 1./16.;
1492 #endif
1493 }
1494 
1496  : PositiveFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1497 {
1498  Nodes.IntPoint(0).x = 0.0;
1499  Nodes.IntPoint(0).y = 0.0;
1500  Nodes.IntPoint(1).x = 1.0;
1501  Nodes.IntPoint(1).y = 0.0;
1502  Nodes.IntPoint(2).x = 1.0;
1503  Nodes.IntPoint(2).y = 1.0;
1504  Nodes.IntPoint(3).x = 0.0;
1505  Nodes.IntPoint(3).y = 1.0;
1506  Nodes.IntPoint(4).x = 0.5;
1507  Nodes.IntPoint(4).y = 0.0;
1508  Nodes.IntPoint(5).x = 1.0;
1509  Nodes.IntPoint(5).y = 0.5;
1510  Nodes.IntPoint(6).x = 0.5;
1511  Nodes.IntPoint(6).y = 1.0;
1512  Nodes.IntPoint(7).x = 0.0;
1513  Nodes.IntPoint(7).y = 0.5;
1514  Nodes.IntPoint(8).x = 0.5;
1515  Nodes.IntPoint(8).y = 0.5;
1516 }
1517 
1519  Vector &shape) const
1520 {
1521  double x = ip.x, y = ip.y;
1522  double l1x, l2x, l3x, l1y, l2y, l3y;
1523 
1524  l1x = (1. - x) * (1. - x);
1525  l2x = 2. * x * (1. - x);
1526  l3x = x * x;
1527  l1y = (1. - y) * (1. - y);
1528  l2y = 2. * y * (1. - y);
1529  l3y = y * y;
1530 
1531  shape(0) = l1x * l1y;
1532  shape(4) = l2x * l1y;
1533  shape(1) = l3x * l1y;
1534  shape(7) = l1x * l2y;
1535  shape(8) = l2x * l2y;
1536  shape(5) = l3x * l2y;
1537  shape(3) = l1x * l3y;
1538  shape(6) = l2x * l3y;
1539  shape(2) = l3x * l3y;
1540 }
1541 
1543  DenseMatrix &dshape) const
1544 {
1545  double x = ip.x, y = ip.y;
1546  double l1x, l2x, l3x, l1y, l2y, l3y;
1547  double d1x, d2x, d3x, d1y, d2y, d3y;
1548 
1549  l1x = (1. - x) * (1. - x);
1550  l2x = 2. * x * (1. - x);
1551  l3x = x * x;
1552  l1y = (1. - y) * (1. - y);
1553  l2y = 2. * y * (1. - y);
1554  l3y = y * y;
1555 
1556  d1x = 2. * x - 2.;
1557  d2x = 2. - 4. * x;
1558  d3x = 2. * x;
1559  d1y = 2. * y - 2.;
1560  d2y = 2. - 4. * y;
1561  d3y = 2. * y;
1562 
1563  dshape(0,0) = d1x * l1y;
1564  dshape(0,1) = l1x * d1y;
1565 
1566  dshape(4,0) = d2x * l1y;
1567  dshape(4,1) = l2x * d1y;
1568 
1569  dshape(1,0) = d3x * l1y;
1570  dshape(1,1) = l3x * d1y;
1571 
1572  dshape(7,0) = d1x * l2y;
1573  dshape(7,1) = l1x * d2y;
1574 
1575  dshape(8,0) = d2x * l2y;
1576  dshape(8,1) = l2x * d2y;
1577 
1578  dshape(5,0) = d3x * l2y;
1579  dshape(5,1) = l3x * d2y;
1580 
1581  dshape(3,0) = d1x * l3y;
1582  dshape(3,1) = l1x * d3y;
1583 
1584  dshape(6,0) = d2x * l3y;
1585  dshape(6,1) = l2x * d3y;
1586 
1587  dshape(2,0) = d3x * l3y;
1588  dshape(2,1) = l3x * d3y;
1589 }
1590 
1593 {
1594  double s[9];
1595  IntegrationPoint tr_ip;
1596  Vector xx(&tr_ip.x, 2), shape(s, 9);
1597 
1598  for (int i = 0; i < 9; i++)
1599  {
1600  Trans.Transform(Nodes.IntPoint(i), xx);
1601  CalcShape(tr_ip, shape);
1602  for (int j = 0; j < 9; j++)
1603  if (fabs(I(i,j) = s[j]) < 1.0e-12)
1604  {
1605  I(i,j) = 0.0;
1606  }
1607  }
1608  for (int i = 0; i < 9; i++)
1609  {
1610  double *d = &I(0,i);
1611  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1612  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1613  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1614  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1615  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1616  0.25 * (d[0] + d[1] + d[2] + d[3]);
1617  }
1618 }
1619 
1621  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
1622 {
1623  double *d = dofs;
1624 
1625  for (int i = 0; i < 9; i++)
1626  {
1627  const IntegrationPoint &ip = Nodes.IntPoint(i);
1628  Trans.SetIntPoint(&ip);
1629  d[i] = coeff.Eval(Trans, ip);
1630  }
1631  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1632  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1633  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1634  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1635  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1636  0.25 * (d[0] + d[1] + d[2] + d[3]);
1637 }
1638 
1641  Vector &dofs) const
1642 {
1643  double v[3];
1644  Vector x (v, vc.GetVDim());
1645 
1646  for (int i = 0; i < 9; i++)
1647  {
1648  const IntegrationPoint &ip = Nodes.IntPoint(i);
1649  Trans.SetIntPoint(&ip);
1650  vc.Eval (x, Trans, ip);
1651  for (int j = 0; j < x.Size(); j++)
1652  {
1653  dofs(9*j+i) = v[j];
1654  }
1655  }
1656  for (int j = 0; j < x.Size(); j++)
1657  {
1658  double *d = &dofs(9*j);
1659 
1660  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1661  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1662  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1663  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1664  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1665  0.25 * (d[0] + d[1] + d[2] + d[3]);
1666  }
1667 }
1668 
1669 
1671  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1672 {
1673  const double p1 = 0.5*(1.-sqrt(3./5.));
1674 
1675  Nodes.IntPoint(0).x = p1;
1676  Nodes.IntPoint(0).y = p1;
1677  Nodes.IntPoint(4).x = 0.5;
1678  Nodes.IntPoint(4).y = p1;
1679  Nodes.IntPoint(1).x = 1.-p1;
1680  Nodes.IntPoint(1).y = p1;
1681  Nodes.IntPoint(7).x = p1;
1682  Nodes.IntPoint(7).y = 0.5;
1683  Nodes.IntPoint(8).x = 0.5;
1684  Nodes.IntPoint(8).y = 0.5;
1685  Nodes.IntPoint(5).x = 1.-p1;
1686  Nodes.IntPoint(5).y = 0.5;
1687  Nodes.IntPoint(3).x = p1;
1688  Nodes.IntPoint(3).y = 1.-p1;
1689  Nodes.IntPoint(6).x = 0.5;
1690  Nodes.IntPoint(6).y = 1.-p1;
1691  Nodes.IntPoint(2).x = 1.-p1;
1692  Nodes.IntPoint(2).y = 1.-p1;
1693 }
1694 
1696  Vector &shape) const
1697 {
1698  const double a = sqrt(5./3.);
1699  const double p1 = 0.5*(1.-sqrt(3./5.));
1700 
1701  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1702  double l1x, l2x, l3x, l1y, l2y, l3y;
1703 
1704  l1x = (x - 1.) * (2. * x - 1);
1705  l2x = 4. * x * (1. - x);
1706  l3x = x * (2. * x - 1.);
1707  l1y = (y - 1.) * (2. * y - 1);
1708  l2y = 4. * y * (1. - y);
1709  l3y = y * (2. * y - 1.);
1710 
1711  shape(0) = l1x * l1y;
1712  shape(4) = l2x * l1y;
1713  shape(1) = l3x * l1y;
1714  shape(7) = l1x * l2y;
1715  shape(8) = l2x * l2y;
1716  shape(5) = l3x * l2y;
1717  shape(3) = l1x * l3y;
1718  shape(6) = l2x * l3y;
1719  shape(2) = l3x * l3y;
1720 }
1721 
1723  DenseMatrix &dshape) const
1724 {
1725  const double a = sqrt(5./3.);
1726  const double p1 = 0.5*(1.-sqrt(3./5.));
1727 
1728  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1729  double l1x, l2x, l3x, l1y, l2y, l3y;
1730  double d1x, d2x, d3x, d1y, d2y, d3y;
1731 
1732  l1x = (x - 1.) * (2. * x - 1);
1733  l2x = 4. * x * (1. - x);
1734  l3x = x * (2. * x - 1.);
1735  l1y = (y - 1.) * (2. * y - 1);
1736  l2y = 4. * y * (1. - y);
1737  l3y = y * (2. * y - 1.);
1738 
1739  d1x = a * (4. * x - 3.);
1740  d2x = a * (4. - 8. * x);
1741  d3x = a * (4. * x - 1.);
1742  d1y = a * (4. * y - 3.);
1743  d2y = a * (4. - 8. * y);
1744  d3y = a * (4. * y - 1.);
1745 
1746  dshape(0,0) = d1x * l1y;
1747  dshape(0,1) = l1x * d1y;
1748 
1749  dshape(4,0) = d2x * l1y;
1750  dshape(4,1) = l2x * d1y;
1751 
1752  dshape(1,0) = d3x * l1y;
1753  dshape(1,1) = l3x * d1y;
1754 
1755  dshape(7,0) = d1x * l2y;
1756  dshape(7,1) = l1x * d2y;
1757 
1758  dshape(8,0) = d2x * l2y;
1759  dshape(8,1) = l2x * d2y;
1760 
1761  dshape(5,0) = d3x * l2y;
1762  dshape(5,1) = l3x * d2y;
1763 
1764  dshape(3,0) = d1x * l3y;
1765  dshape(3,1) = l1x * d3y;
1766 
1767  dshape(6,0) = d2x * l3y;
1768  dshape(6,1) = l2x * d3y;
1769 
1770  dshape(2,0) = d3x * l3y;
1771  dshape(2,1) = l3x * d3y;
1772 }
1773 
1775  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
1776 {
1777  Nodes.IntPoint(0).x = 0.;
1778  Nodes.IntPoint(0).y = 0.;
1779  Nodes.IntPoint(1).x = 1.;
1780  Nodes.IntPoint(1).y = 0.;
1781  Nodes.IntPoint(2).x = 1.;
1782  Nodes.IntPoint(2).y = 1.;
1783  Nodes.IntPoint(3).x = 0.;
1784  Nodes.IntPoint(3).y = 1.;
1785  Nodes.IntPoint(4).x = 1./3.;
1786  Nodes.IntPoint(4).y = 0.;
1787  Nodes.IntPoint(5).x = 2./3.;
1788  Nodes.IntPoint(5).y = 0.;
1789  Nodes.IntPoint(6).x = 1.;
1790  Nodes.IntPoint(6).y = 1./3.;
1791  Nodes.IntPoint(7).x = 1.;
1792  Nodes.IntPoint(7).y = 2./3.;
1793  Nodes.IntPoint(8).x = 2./3.;
1794  Nodes.IntPoint(8).y = 1.;
1795  Nodes.IntPoint(9).x = 1./3.;
1796  Nodes.IntPoint(9).y = 1.;
1797  Nodes.IntPoint(10).x = 0.;
1798  Nodes.IntPoint(10).y = 2./3.;
1799  Nodes.IntPoint(11).x = 0.;
1800  Nodes.IntPoint(11).y = 1./3.;
1801  Nodes.IntPoint(12).x = 1./3.;
1802  Nodes.IntPoint(12).y = 1./3.;
1803  Nodes.IntPoint(13).x = 2./3.;
1804  Nodes.IntPoint(13).y = 1./3.;
1805  Nodes.IntPoint(14).x = 1./3.;
1806  Nodes.IntPoint(14).y = 2./3.;
1807  Nodes.IntPoint(15).x = 2./3.;
1808  Nodes.IntPoint(15).y = 2./3.;
1809 }
1810 
1812  const IntegrationPoint &ip, Vector &shape) const
1813 {
1814  double x = ip.x, y = ip.y;
1815 
1816  double w1x, w2x, w3x, w1y, w2y, w3y;
1817  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1818 
1819  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1820  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1821 
1822  l0x = (- 4.5) * w1x * w2x * w3x;
1823  l1x = ( 13.5) * x * w2x * w3x;
1824  l2x = (-13.5) * x * w1x * w3x;
1825  l3x = ( 4.5) * x * w1x * w2x;
1826 
1827  l0y = (- 4.5) * w1y * w2y * w3y;
1828  l1y = ( 13.5) * y * w2y * w3y;
1829  l2y = (-13.5) * y * w1y * w3y;
1830  l3y = ( 4.5) * y * w1y * w2y;
1831 
1832  shape(0) = l0x * l0y;
1833  shape(1) = l3x * l0y;
1834  shape(2) = l3x * l3y;
1835  shape(3) = l0x * l3y;
1836  shape(4) = l1x * l0y;
1837  shape(5) = l2x * l0y;
1838  shape(6) = l3x * l1y;
1839  shape(7) = l3x * l2y;
1840  shape(8) = l2x * l3y;
1841  shape(9) = l1x * l3y;
1842  shape(10) = l0x * l2y;
1843  shape(11) = l0x * l1y;
1844  shape(12) = l1x * l1y;
1845  shape(13) = l2x * l1y;
1846  shape(14) = l1x * l2y;
1847  shape(15) = l2x * l2y;
1848 }
1849 
1851  const IntegrationPoint &ip, DenseMatrix &dshape) const
1852 {
1853  double x = ip.x, y = ip.y;
1854 
1855  double w1x, w2x, w3x, w1y, w2y, w3y;
1856  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1857  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1858 
1859  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1860  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1861 
1862  l0x = (- 4.5) * w1x * w2x * w3x;
1863  l1x = ( 13.5) * x * w2x * w3x;
1864  l2x = (-13.5) * x * w1x * w3x;
1865  l3x = ( 4.5) * x * w1x * w2x;
1866 
1867  l0y = (- 4.5) * w1y * w2y * w3y;
1868  l1y = ( 13.5) * y * w2y * w3y;
1869  l2y = (-13.5) * y * w1y * w3y;
1870  l3y = ( 4.5) * y * w1y * w2y;
1871 
1872  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1873  d1x = 9. + (-45. + 40.5 * x) * x;
1874  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1875  d3x = 1. + (- 9. + 13.5 * x) * x;
1876 
1877  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1878  d1y = 9. + (-45. + 40.5 * y) * y;
1879  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1880  d3y = 1. + (- 9. + 13.5 * y) * y;
1881 
1882  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
1883  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
1884  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
1885  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
1886  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
1887  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
1888  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
1889  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
1890  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
1891  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
1892  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
1893  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
1894  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
1895  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
1896  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
1897  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
1898 }
1899 
1901  const IntegrationPoint &ip, DenseMatrix &h) const
1902 {
1903  double x = ip.x, y = ip.y;
1904 
1905  double w1x, w2x, w3x, w1y, w2y, w3y;
1906  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1907  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1908  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
1909 
1910  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1911  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1912 
1913  l0x = (- 4.5) * w1x * w2x * w3x;
1914  l1x = ( 13.5) * x * w2x * w3x;
1915  l2x = (-13.5) * x * w1x * w3x;
1916  l3x = ( 4.5) * x * w1x * w2x;
1917 
1918  l0y = (- 4.5) * w1y * w2y * w3y;
1919  l1y = ( 13.5) * y * w2y * w3y;
1920  l2y = (-13.5) * y * w1y * w3y;
1921  l3y = ( 4.5) * y * w1y * w2y;
1922 
1923  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1924  d1x = 9. + (-45. + 40.5 * x) * x;
1925  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1926  d3x = 1. + (- 9. + 13.5 * x) * x;
1927 
1928  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1929  d1y = 9. + (-45. + 40.5 * y) * y;
1930  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1931  d3y = 1. + (- 9. + 13.5 * y) * y;
1932 
1933  h0x = -27. * x + 18.;
1934  h1x = 81. * x - 45.;
1935  h2x = -81. * x + 36.;
1936  h3x = 27. * x - 9.;
1937 
1938  h0y = -27. * y + 18.;
1939  h1y = 81. * y - 45.;
1940  h2y = -81. * y + 36.;
1941  h3y = 27. * y - 9.;
1942 
1943  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
1944  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
1945  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
1946  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
1947  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
1948  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
1949  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
1950  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
1951  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
1952  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
1953  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
1954  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
1955  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
1956  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
1957  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
1958  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
1959 }
1960 
1961 
1963  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
1964 {
1965  Nodes.IntPoint(0).x = 0.0;
1966  Nodes.IntPoint(1).x = 1.0;
1967  Nodes.IntPoint(2).x = 0.33333333333333333333;
1968  Nodes.IntPoint(3).x = 0.66666666666666666667;
1969 }
1970 
1972  Vector &shape) const
1973 {
1974  double x = ip.x;
1975  double l1 = x,
1976  l2 = (1.0-x),
1977  l3 = (0.33333333333333333333-x),
1978  l4 = (0.66666666666666666667-x);
1979 
1980  shape(0) = 4.5 * l2 * l3 * l4;
1981  shape(1) = 4.5 * l1 * l3 * l4;
1982  shape(2) = 13.5 * l1 * l2 * l4;
1983  shape(3) = -13.5 * l1 * l2 * l3;
1984 }
1985 
1987  DenseMatrix &dshape) const
1988 {
1989  double x = ip.x;
1990 
1991  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
1992  dshape(1,0) = 1. - x * (9. - 13.5 * x);
1993  dshape(2,0) = 9. - x * (45. - 40.5 * x);
1994  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
1995 }
1996 
1997 
1999  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
2000 {
2001  Nodes.IntPoint(0).x = 0.0;
2002  Nodes.IntPoint(0).y = 0.0;
2003  Nodes.IntPoint(1).x = 1.0;
2004  Nodes.IntPoint(1).y = 0.0;
2005  Nodes.IntPoint(2).x = 0.0;
2006  Nodes.IntPoint(2).y = 1.0;
2007  Nodes.IntPoint(3).x = 0.33333333333333333333;
2008  Nodes.IntPoint(3).y = 0.0;
2009  Nodes.IntPoint(4).x = 0.66666666666666666667;
2010  Nodes.IntPoint(4).y = 0.0;
2011  Nodes.IntPoint(5).x = 0.66666666666666666667;
2012  Nodes.IntPoint(5).y = 0.33333333333333333333;
2013  Nodes.IntPoint(6).x = 0.33333333333333333333;
2014  Nodes.IntPoint(6).y = 0.66666666666666666667;
2015  Nodes.IntPoint(7).x = 0.0;
2016  Nodes.IntPoint(7).y = 0.66666666666666666667;
2017  Nodes.IntPoint(8).x = 0.0;
2018  Nodes.IntPoint(8).y = 0.33333333333333333333;
2019  Nodes.IntPoint(9).x = 0.33333333333333333333;
2020  Nodes.IntPoint(9).y = 0.33333333333333333333;
2021 }
2022 
2024  Vector &shape) const
2025 {
2026  double x = ip.x, y = ip.y;
2027  double l1 = (-1. + x + y),
2028  lx = (-1. + 3.*x),
2029  ly = (-1. + 3.*y);
2030 
2031  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
2032  shape(1) = 0.5*x*(lx - 1.)*lx;
2033  shape(2) = 0.5*y*(-1. + ly)*ly;
2034  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
2035  shape(4) = -4.5*x*lx*l1;
2036  shape(5) = 4.5*x*lx*y;
2037  shape(6) = 4.5*x*y*ly;
2038  shape(7) = -4.5*y*l1*ly;
2039  shape(8) = 4.5*y*l1*(1. + 3.*l1);
2040  shape(9) = -27.*x*y*l1;
2041 }
2042 
2044  DenseMatrix &dshape) const
2045 {
2046  double x = ip.x, y = ip.y;
2047 
2048  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2049  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
2050  dshape(2,0) = 0.;
2051  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
2052  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
2053  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
2054  dshape(6,0) = 4.5*y*(-1. + 3.*y);
2055  dshape(7,0) = 4.5*(1. - 3.*y)*y;
2056  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
2057  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
2058 
2059  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
2060  dshape(1,1) = 0.;
2061  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
2062  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
2063  dshape(4,1) = 4.5*(1. - 3.*x)*x;
2064  dshape(5,1) = 4.5*x*(-1. + 3.*x);
2065  dshape(6,1) = 4.5*x*(-1. + 6.*y);
2066  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
2067  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
2068  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
2069 }
2070 
2072  DenseMatrix &h) const
2073 {
2074  double x = ip.x, y = ip.y;
2075 
2076  h(0,0) = 18.-27.*(x+y);
2077  h(0,1) = 18.-27.*(x+y);
2078  h(0,2) = 18.-27.*(x+y);
2079 
2080  h(1,0) = -9.+27.*x;
2081  h(1,1) = 0.;
2082  h(1,2) = 0.;
2083 
2084  h(2,0) = 0.;
2085  h(2,1) = 0.;
2086  h(2,2) = -9.+27.*y;
2087 
2088  h(3,0) = -45.+81.*x+54.*y;
2089  h(3,1) = -22.5+54.*x+27.*y;
2090  h(3,2) = 27.*x;
2091 
2092  h(4,0) = 36.-81.*x-27.*y;
2093  h(4,1) = 4.5-27.*x;
2094  h(4,2) = 0.;
2095 
2096  h(5,0) = 27.*y;
2097  h(5,1) = -4.5+27.*x;
2098  h(5,2) = 0.;
2099 
2100  h(6,0) = 0.;
2101  h(6,1) = -4.5+27.*y;
2102  h(6,2) = 27.*x;
2103 
2104  h(7,0) = 0.;
2105  h(7,1) = 4.5-27.*y;
2106  h(7,2) = 36.-27.*x-81.*y;
2107 
2108  h(8,0) = 27.*y;
2109  h(8,1) = -22.5+27.*x+54.*y;
2110  h(8,2) = -45.+54.*x+81.*y;
2111 
2112  h(9,0) = -54.*y;
2113  h(9,1) = 27.-54.*(x+y);
2114  h(9,2) = -54.*x;
2115 }
2116 
2117 
2119  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
2120 {
2121  Nodes.IntPoint(0).x = 0;
2122  Nodes.IntPoint(0).y = 0;
2123  Nodes.IntPoint(0).z = 0;
2124  Nodes.IntPoint(1).x = 1.;
2125  Nodes.IntPoint(1).y = 0;
2126  Nodes.IntPoint(1).z = 0;
2127  Nodes.IntPoint(2).x = 0;
2128  Nodes.IntPoint(2).y = 1.;
2129  Nodes.IntPoint(2).z = 0;
2130  Nodes.IntPoint(3).x = 0;
2131  Nodes.IntPoint(3).y = 0;
2132  Nodes.IntPoint(3).z = 1.;
2133  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
2134  Nodes.IntPoint(4).y = 0;
2135  Nodes.IntPoint(4).z = 0;
2136  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
2137  Nodes.IntPoint(5).y = 0;
2138  Nodes.IntPoint(5).z = 0;
2139  Nodes.IntPoint(6).x = 0;
2140  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
2141  Nodes.IntPoint(6).z = 0;
2142  Nodes.IntPoint(7).x = 0;
2143  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
2144  Nodes.IntPoint(7).z = 0;
2145  Nodes.IntPoint(8).x = 0;
2146  Nodes.IntPoint(8).y = 0;
2147  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
2148  Nodes.IntPoint(9).x = 0;
2149  Nodes.IntPoint(9).y = 0;
2150  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
2151  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
2152  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
2153  Nodes.IntPoint(10).z = 0;
2154  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
2155  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
2156  Nodes.IntPoint(11).z = 0;
2157  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
2158  Nodes.IntPoint(12).y = 0;
2159  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
2160  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
2161  Nodes.IntPoint(13).y = 0;
2162  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
2163  Nodes.IntPoint(14).x = 0;
2164  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
2165  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
2166  Nodes.IntPoint(15).x = 0;
2167  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
2168  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
2169  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
2170  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
2171  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
2172  Nodes.IntPoint(17).x = 0;
2173  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
2174  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
2175  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
2176  Nodes.IntPoint(18).y = 0;
2177  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
2178  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
2179  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
2180  Nodes.IntPoint(19).z = 0;
2181 }
2182 
2184  Vector &shape) const
2185 {
2186  double x = ip.x, y = ip.y, z = ip.z;
2187 
2188  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
2189  (-1 + 3*x + 3*y + 3*z))/2.;
2190  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2191  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
2192  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
2193  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2194  shape(19) = -27*x*y*(-1 + x + y + z);
2195  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
2196  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
2197  shape(11) = (9*x*y*(-1 + 3*y))/2.;
2198  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
2199  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2200  shape(18) = -27*x*z*(-1 + x + y + z);
2201  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
2202  shape(17) = -27*y*z*(-1 + x + y + z);
2203  shape(16) = 27*x*y*z;
2204  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
2205  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
2206  shape(13) = (9*x*z*(-1 + 3*z))/2.;
2207  shape(15) = (9*y*z*(-1 + 3*z))/2.;
2208  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
2209 }
2210 
2212  DenseMatrix &dshape) const
2213 {
2214  double x = ip.x, y = ip.y, z = ip.z;
2215 
2216  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2217  x*(-4 + 6*y + 6*z)))/2.;
2218  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2219  x*(-4 + 6*y + 6*z)))/2.;
2220  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2221  x*(-4 + 6*y + 6*z)))/2.;
2222  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
2223  2*x*(-5 + 6*y + 6*z)))/2.;
2224  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2225  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2226  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
2227  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
2228  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
2229  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
2230  dshape(1,1) = 0;
2231  dshape(1,2) = 0;
2232  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2233  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
2234  x*(-5 + 12*y + 6*z)))/2.;
2235  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2236  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
2237  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
2238  dshape(19,2) = -27*x*y;
2239  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
2240  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
2241  dshape(10,2) = 0;
2242  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
2243  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
2244  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
2245  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
2246  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
2247  dshape(11,2) = 0;
2248  dshape(2,0) = 0;
2249  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
2250  dshape(2,2) = 0;
2251  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2252  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2253  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
2254  x*(-5 + 6*y + 12*z)))/2.;
2255  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
2256  dshape(18,1) = -27*x*z;
2257  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
2258  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
2259  dshape(12,1) = 0;
2260  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
2261  dshape(17,0) = -27*y*z;
2262  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
2263  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
2264  dshape(16,0) = 27*y*z;
2265  dshape(16,1) = 27*x*z;
2266  dshape(16,2) = 27*x*y;
2267  dshape(14,0) = 0;
2268  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
2269  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
2270  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
2271  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
2272  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
2273  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
2274  dshape(13,1) = 0;
2275  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
2276  dshape(15,0) = 0;
2277  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
2278  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
2279  dshape(3,0) = 0;
2280  dshape(3,1) = 0;
2281  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
2282 }
2283 
2284 
2286  : NodalFiniteElement(2, Geometry::TRIANGLE, 1, 0)
2287 {
2288  Nodes.IntPoint(0).x = 0.333333333333333333;
2289  Nodes.IntPoint(0).y = 0.333333333333333333;
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(2, Geometry::SQUARE, 1, 0, FunctionSpace::Qk)
2308 {
2309  Nodes.IntPoint(0).x = 0.5;
2310  Nodes.IntPoint(0).y = 0.5;
2311 }
2312 
2314  Vector &shape) const
2315 {
2316  shape(0) = 1.0;
2317 }
2318 
2320  DenseMatrix &dshape) const
2321 {
2322  dshape(0,0) = 0.0;
2323  dshape(0,1) = 0.0;
2324 }
2325 
2326 
2328  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
2329 {
2330  Nodes.IntPoint(0).x = 0.0;
2331  Nodes.IntPoint(0).y = 0.0;
2332  Nodes.IntPoint(0).z = 0.0;
2333  Nodes.IntPoint(1).x = 1.0;
2334  Nodes.IntPoint(1).y = 0.0;
2335  Nodes.IntPoint(1).z = 0.0;
2336  Nodes.IntPoint(2).x = 0.0;
2337  Nodes.IntPoint(2).y = 1.0;
2338  Nodes.IntPoint(2).z = 0.0;
2339  Nodes.IntPoint(3).x = 0.0;
2340  Nodes.IntPoint(3).y = 0.0;
2341  Nodes.IntPoint(3).z = 1.0;
2342 }
2343 
2345  Vector &shape) const
2346 {
2347  shape(0) = 1. - ip.x - ip.y - ip.z;
2348  shape(1) = ip.x;
2349  shape(2) = ip.y;
2350  shape(3) = ip.z;
2351 }
2352 
2354  DenseMatrix &dshape) const
2355 {
2356  if (dshape.Height() == 4)
2357  {
2358  double *A = &dshape(0,0);
2359  A[0] = -1.; A[4] = -1.; A[8] = -1.;
2360  A[1] = 1.; A[5] = 0.; A[9] = 0.;
2361  A[2] = 0.; A[6] = 1.; A[10] = 0.;
2362  A[3] = 0.; A[7] = 0.; A[11] = 1.;
2363  }
2364  else
2365  {
2366  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
2367  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
2368  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
2369  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
2370  }
2371 }
2372 
2373 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
2374 const
2375 {
2376  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
2377 
2378  *ndofs = 3;
2379  *dofs = face_dofs[face];
2380 }
2381 
2382 
2384  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
2385 {
2386  Nodes.IntPoint(0).x = 0.0;
2387  Nodes.IntPoint(0).y = 0.0;
2388  Nodes.IntPoint(0).z = 0.0;
2389  Nodes.IntPoint(1).x = 1.0;
2390  Nodes.IntPoint(1).y = 0.0;
2391  Nodes.IntPoint(1).z = 0.0;
2392  Nodes.IntPoint(2).x = 0.0;
2393  Nodes.IntPoint(2).y = 1.0;
2394  Nodes.IntPoint(2).z = 0.0;
2395  Nodes.IntPoint(3).x = 0.0;
2396  Nodes.IntPoint(3).y = 0.0;
2397  Nodes.IntPoint(3).z = 1.0;
2398  Nodes.IntPoint(4).x = 0.5;
2399  Nodes.IntPoint(4).y = 0.0;
2400  Nodes.IntPoint(4).z = 0.0;
2401  Nodes.IntPoint(5).x = 0.0;
2402  Nodes.IntPoint(5).y = 0.5;
2403  Nodes.IntPoint(5).z = 0.0;
2404  Nodes.IntPoint(6).x = 0.0;
2405  Nodes.IntPoint(6).y = 0.0;
2406  Nodes.IntPoint(6).z = 0.5;
2407  Nodes.IntPoint(7).x = 0.5;
2408  Nodes.IntPoint(7).y = 0.5;
2409  Nodes.IntPoint(7).z = 0.0;
2410  Nodes.IntPoint(8).x = 0.5;
2411  Nodes.IntPoint(8).y = 0.0;
2412  Nodes.IntPoint(8).z = 0.5;
2413  Nodes.IntPoint(9).x = 0.0;
2414  Nodes.IntPoint(9).y = 0.5;
2415  Nodes.IntPoint(9).z = 0.5;
2416 }
2417 
2419  Vector &shape) const
2420 {
2421  double L0, L1, L2, L3;
2422 
2423  L0 = 1. - ip.x - ip.y - ip.z;
2424  L1 = ip.x;
2425  L2 = ip.y;
2426  L3 = ip.z;
2427 
2428  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
2429  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
2430  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
2431  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
2432  shape(4) = 4.0 * L0 * L1;
2433  shape(5) = 4.0 * L0 * L2;
2434  shape(6) = 4.0 * L0 * L3;
2435  shape(7) = 4.0 * L1 * L2;
2436  shape(8) = 4.0 * L1 * L3;
2437  shape(9) = 4.0 * L2 * L3;
2438 }
2439 
2441  DenseMatrix &dshape) const
2442 {
2443  double x, y, z, L0;
2444 
2445  x = ip.x;
2446  y = ip.y;
2447  z = ip.z;
2448  L0 = 1.0 - x - y - z;
2449 
2450  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
2451  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
2452  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
2453  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
2454  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
2455  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
2456  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
2457  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
2458  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
2459  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
2460 }
2461 
2463  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
2464 {
2465  Nodes.IntPoint(0).x = 0.0;
2466  Nodes.IntPoint(0).y = 0.0;
2467  Nodes.IntPoint(0).z = 0.0;
2468 
2469  Nodes.IntPoint(1).x = 1.0;
2470  Nodes.IntPoint(1).y = 0.0;
2471  Nodes.IntPoint(1).z = 0.0;
2472 
2473  Nodes.IntPoint(2).x = 1.0;
2474  Nodes.IntPoint(2).y = 1.0;
2475  Nodes.IntPoint(2).z = 0.0;
2476 
2477  Nodes.IntPoint(3).x = 0.0;
2478  Nodes.IntPoint(3).y = 1.0;
2479  Nodes.IntPoint(3).z = 0.0;
2480 
2481  Nodes.IntPoint(4).x = 0.0;
2482  Nodes.IntPoint(4).y = 0.0;
2483  Nodes.IntPoint(4).z = 1.0;
2484 
2485  Nodes.IntPoint(5).x = 1.0;
2486  Nodes.IntPoint(5).y = 0.0;
2487  Nodes.IntPoint(5).z = 1.0;
2488 
2489  Nodes.IntPoint(6).x = 1.0;
2490  Nodes.IntPoint(6).y = 1.0;
2491  Nodes.IntPoint(6).z = 1.0;
2492 
2493  Nodes.IntPoint(7).x = 0.0;
2494  Nodes.IntPoint(7).y = 1.0;
2495  Nodes.IntPoint(7).z = 1.0;
2496 }
2497 
2499  Vector &shape) const
2500 {
2501  double x = ip.x, y = ip.y, z = ip.z;
2502  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2503 
2504  shape(0) = ox * oy * oz;
2505  shape(1) = x * oy * oz;
2506  shape(2) = x * y * oz;
2507  shape(3) = ox * y * oz;
2508  shape(4) = ox * oy * z;
2509  shape(5) = x * oy * z;
2510  shape(6) = x * y * z;
2511  shape(7) = ox * y * z;
2512 }
2513 
2515  DenseMatrix &dshape) const
2516 {
2517  double x = ip.x, y = ip.y, z = ip.z;
2518  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2519 
2520  dshape(0,0) = - oy * oz;
2521  dshape(0,1) = - ox * oz;
2522  dshape(0,2) = - ox * oy;
2523 
2524  dshape(1,0) = oy * oz;
2525  dshape(1,1) = - x * oz;
2526  dshape(1,2) = - x * oy;
2527 
2528  dshape(2,0) = y * oz;
2529  dshape(2,1) = x * oz;
2530  dshape(2,2) = - x * y;
2531 
2532  dshape(3,0) = - y * oz;
2533  dshape(3,1) = ox * oz;
2534  dshape(3,2) = - ox * y;
2535 
2536  dshape(4,0) = - oy * z;
2537  dshape(4,1) = - ox * z;
2538  dshape(4,2) = ox * oy;
2539 
2540  dshape(5,0) = oy * z;
2541  dshape(5,1) = - x * z;
2542  dshape(5,2) = x * oy;
2543 
2544  dshape(6,0) = y * z;
2545  dshape(6,1) = x * z;
2546  dshape(6,2) = x * y;
2547 
2548  dshape(7,0) = - y * z;
2549  dshape(7,1) = ox * z;
2550  dshape(7,2) = ox * y;
2551 }
2552 
2554  : NodalFiniteElement(1, Geometry::SEGMENT, 1, Ord) // defaul Ord = 0
2555 {
2556  Nodes.IntPoint(0).x = 0.5;
2557 }
2558 
2560  Vector &shape) const
2561 {
2562  shape(0) = 1.0;
2563 }
2564 
2566  DenseMatrix &dshape) const
2567 {
2568  dshape(0,0) = 0.0;
2569 }
2570 
2572  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
2573 {
2574  Nodes.IntPoint(0).x = 0.5;
2575  Nodes.IntPoint(0).y = 0.0;
2576  Nodes.IntPoint(1).x = 0.5;
2577  Nodes.IntPoint(1).y = 0.5;
2578  Nodes.IntPoint(2).x = 0.0;
2579  Nodes.IntPoint(2).y = 0.5;
2580 }
2581 
2583  Vector &shape) const
2584 {
2585  shape(0) = 1.0 - 2.0 * ip.y;
2586  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
2587  shape(2) = 1.0 - 2.0 * ip.x;
2588 }
2589 
2591  DenseMatrix &dshape) const
2592 {
2593  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
2594  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
2595  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
2596 }
2597 
2599 // the FunctionSpace should be rotated (45 degrees) Q_1
2600 // i.e. the span of { 1, x, y, x^2 - y^2 }
2601  : NodalFiniteElement(2, Geometry::SQUARE, 4, 2, FunctionSpace::Qk)
2602 {
2603  Nodes.IntPoint(0).x = 0.5;
2604  Nodes.IntPoint(0).y = 0.0;
2605  Nodes.IntPoint(1).x = 1.0;
2606  Nodes.IntPoint(1).y = 0.5;
2607  Nodes.IntPoint(2).x = 0.5;
2608  Nodes.IntPoint(2).y = 1.0;
2609  Nodes.IntPoint(3).x = 0.0;
2610  Nodes.IntPoint(3).y = 0.5;
2611 }
2612 
2614  Vector &shape) const
2615 {
2616  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
2617 
2618  shape(0) = l2 * l3;
2619  shape(1) = l1 * l3;
2620  shape(2) = l1 * l4;
2621  shape(3) = l2 * l4;
2622 }
2623 
2625  DenseMatrix &dshape) const
2626 {
2627  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
2628 
2629  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
2630  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
2631  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
2632  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
2633 }
2634 
2635 
2637  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
2638 {
2639  Nodes.IntPoint(0).x = 0.5;
2640  Nodes.IntPoint(0).y = 0.0;
2641  Nodes.IntPoint(1).x = 0.5;
2642  Nodes.IntPoint(1).y = 0.5;
2643  Nodes.IntPoint(2).x = 0.0;
2644  Nodes.IntPoint(2).y = 0.5;
2645 }
2646 
2648  DenseMatrix &shape) const
2649 {
2650  double x = ip.x, y = ip.y;
2651 
2652  shape(0,0) = x;
2653  shape(0,1) = y - 1.;
2654  shape(1,0) = x;
2655  shape(1,1) = y;
2656  shape(2,0) = x - 1.;
2657  shape(2,1) = y;
2658 }
2659 
2661  Vector &divshape) const
2662 {
2663  divshape(0) = 2.;
2664  divshape(1) = 2.;
2665  divshape(2) = 2.;
2666 }
2667 
2668 const double RT0TriangleFiniteElement::nk[3][2] =
2669 { {0, -1}, {1, 1}, {-1, 0} };
2670 
2673 {
2674  int k, j;
2675 #ifdef MFEM_THREAD_SAFE
2677  DenseMatrix Jinv(Dim);
2678 #endif
2679 
2680 #ifdef MFEM_DEBUG
2681  for (k = 0; k < 3; k++)
2682  {
2684  for (j = 0; j < 3; j++)
2685  {
2686  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2687  if (j == k) { d -= 1.0; }
2688  if (fabs(d) > 1.0e-12)
2689  {
2690  mfem::err << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
2691  " k = " << k << ", j = " << j << ", d = " << d << endl;
2692  mfem_error();
2693  }
2694  }
2695  }
2696 #endif
2697 
2698  IntegrationPoint ip;
2699  ip.x = ip.y = 0.0;
2700  Trans.SetIntPoint (&ip);
2701  // Trans must be linear
2702  // set Jinv = |J| J^{-t} = adj(J)^t
2703  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2704  double vk[2];
2705  Vector xk (vk, 2);
2706 
2707  for (k = 0; k < 3; k++)
2708  {
2709  Trans.Transform (Nodes.IntPoint (k), xk);
2710  ip.x = vk[0]; ip.y = vk[1];
2711  CalcVShape (ip, vshape);
2712  // vk = |J| J^{-t} nk
2713  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2714  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2715  for (j = 0; j < 3; j++)
2716  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2717  {
2718  I(k,j) = 0.0;
2719  }
2720  }
2721 }
2722 
2725  Vector &dofs) const
2726 {
2727  double vk[2];
2728  Vector xk (vk, 2);
2729 #ifdef MFEM_THREAD_SAFE
2730  DenseMatrix Jinv(Dim);
2731 #endif
2732 
2733  for (int k = 0; k < 3; k++)
2734  {
2735  Trans.SetIntPoint (&Nodes.IntPoint (k));
2736  // set Jinv = |J| J^{-t} = adj(J)^t
2737  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2738 
2739  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2740  // xk^t |J| J^{-t} nk
2741  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2742  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2743  }
2744 }
2745 
2747  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
2748 {
2749  Nodes.IntPoint(0).x = 0.5;
2750  Nodes.IntPoint(0).y = 0.0;
2751  Nodes.IntPoint(1).x = 1.0;
2752  Nodes.IntPoint(1).y = 0.5;
2753  Nodes.IntPoint(2).x = 0.5;
2754  Nodes.IntPoint(2).y = 1.0;
2755  Nodes.IntPoint(3).x = 0.0;
2756  Nodes.IntPoint(3).y = 0.5;
2757 }
2758 
2760  DenseMatrix &shape) const
2761 {
2762  double x = ip.x, y = ip.y;
2763 
2764  shape(0,0) = 0;
2765  shape(0,1) = y - 1.;
2766  shape(1,0) = x;
2767  shape(1,1) = 0;
2768  shape(2,0) = 0;
2769  shape(2,1) = y;
2770  shape(3,0) = x - 1.;
2771  shape(3,1) = 0;
2772 }
2773 
2775  Vector &divshape) const
2776 {
2777  divshape(0) = 1.;
2778  divshape(1) = 1.;
2779  divshape(2) = 1.;
2780  divshape(3) = 1.;
2781 }
2782 
2783 const double RT0QuadFiniteElement::nk[4][2] =
2784 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
2785 
2788 {
2789  int k, j;
2790 #ifdef MFEM_THREAD_SAFE
2792  DenseMatrix Jinv(Dim);
2793 #endif
2794 
2795 #ifdef MFEM_DEBUG
2796  for (k = 0; k < 4; k++)
2797  {
2799  for (j = 0; j < 4; j++)
2800  {
2801  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2802  if (j == k) { d -= 1.0; }
2803  if (fabs(d) > 1.0e-12)
2804  {
2805  mfem::err << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
2806  " k = " << k << ", j = " << j << ", d = " << d << endl;
2807  mfem_error();
2808  }
2809  }
2810  }
2811 #endif
2812 
2813  IntegrationPoint ip;
2814  ip.x = ip.y = 0.0;
2815  Trans.SetIntPoint (&ip);
2816  // Trans must be linear (more to have embedding?)
2817  // set Jinv = |J| J^{-t} = adj(J)^t
2818  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2819  double vk[2];
2820  Vector xk (vk, 2);
2821 
2822  for (k = 0; k < 4; k++)
2823  {
2824  Trans.Transform (Nodes.IntPoint (k), xk);
2825  ip.x = vk[0]; ip.y = vk[1];
2826  CalcVShape (ip, vshape);
2827  // vk = |J| J^{-t} nk
2828  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2829  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2830  for (j = 0; j < 4; j++)
2831  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2832  {
2833  I(k,j) = 0.0;
2834  }
2835  }
2836 }
2837 
2840  Vector &dofs) const
2841 {
2842  double vk[2];
2843  Vector xk (vk, 2);
2844 #ifdef MFEM_THREAD_SAFE
2845  DenseMatrix Jinv(Dim);
2846 #endif
2847 
2848  for (int k = 0; k < 4; k++)
2849  {
2850  Trans.SetIntPoint (&Nodes.IntPoint (k));
2851  // set Jinv = |J| J^{-t} = adj(J)^t
2852  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2853 
2854  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2855  // xk^t |J| J^{-t} nk
2856  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2857  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2858  }
2859 }
2860 
2862  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
2863 {
2864  Nodes.IntPoint(0).x = 0.33333333333333333333;
2865  Nodes.IntPoint(0).y = 0.0;
2866  Nodes.IntPoint(1).x = 0.66666666666666666667;
2867  Nodes.IntPoint(1).y = 0.0;
2868  Nodes.IntPoint(2).x = 0.66666666666666666667;
2869  Nodes.IntPoint(2).y = 0.33333333333333333333;
2870  Nodes.IntPoint(3).x = 0.33333333333333333333;
2871  Nodes.IntPoint(3).y = 0.66666666666666666667;
2872  Nodes.IntPoint(4).x = 0.0;
2873  Nodes.IntPoint(4).y = 0.66666666666666666667;
2874  Nodes.IntPoint(5).x = 0.0;
2875  Nodes.IntPoint(5).y = 0.33333333333333333333;
2876  Nodes.IntPoint(6).x = 0.33333333333333333333;
2877  Nodes.IntPoint(6).y = 0.33333333333333333333;
2878  Nodes.IntPoint(7).x = 0.33333333333333333333;
2879  Nodes.IntPoint(7).y = 0.33333333333333333333;
2880 }
2881 
2883  DenseMatrix &shape) const
2884 {
2885  double x = ip.x, y = ip.y;
2886 
2887  shape(0,0) = -2 * x * (-1 + x + 2 * y);
2888  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
2889  shape(1,0) = 2 * x * (x - y);
2890  shape(1,1) = 2 * (x - y) * (-1 + y);
2891  shape(2,0) = 2 * x * (-1 + 2 * x + y);
2892  shape(2,1) = 2 * y * (-1 + 2 * x + y);
2893  shape(3,0) = 2 * x * (-1 + x + 2 * y);
2894  shape(3,1) = 2 * y * (-1 + x + 2 * y);
2895  shape(4,0) = -2 * (-1 + x) * (x - y);
2896  shape(4,1) = 2 * y * (-x + y);
2897  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
2898  shape(5,1) = -2 * y * (-1 + 2 * x + y);
2899  shape(6,0) = -3 * x * (-2 + 2 * x + y);
2900  shape(6,1) = -3 * y * (-1 + 2 * x + y);
2901  shape(7,0) = -3 * x * (-1 + x + 2 * y);
2902  shape(7,1) = -3 * y * (-2 + x + 2 * y);
2903 }
2904 
2906  Vector &divshape) const
2907 {
2908  double x = ip.x, y = ip.y;
2909 
2910  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
2911  divshape(1) = 2 + 6 * x - 6 * y;
2912  divshape(2) = -4 + 12 * x + 6 * y;
2913  divshape(3) = -4 + 6 * x + 12 * y;
2914  divshape(4) = 2 - 6 * x + 6 * y;
2915  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
2916  divshape(6) = -9 * (-1 + 2 * x + y);
2917  divshape(7) = -9 * (-1 + x + 2 * y);
2918 }
2919 
2920 const double RT1TriangleFiniteElement::nk[8][2] =
2921 {
2922  { 0,-1}, { 0,-1},
2923  { 1, 1}, { 1, 1},
2924  {-1, 0}, {-1, 0},
2925  { 1, 0}, { 0, 1}
2926 };
2927 
2930 {
2931  int k, j;
2932 #ifdef MFEM_THREAD_SAFE
2934  DenseMatrix Jinv(Dim);
2935 #endif
2936 
2937 #ifdef MFEM_DEBUG
2938  for (k = 0; k < 8; k++)
2939  {
2941  for (j = 0; j < 8; j++)
2942  {
2943  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2944  if (j == k) { d -= 1.0; }
2945  if (fabs(d) > 1.0e-12)
2946  {
2947  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
2948  " k = " << k << ", j = " << j << ", d = " << d << endl;
2949  mfem_error();
2950  }
2951  }
2952  }
2953 #endif
2954 
2955  IntegrationPoint ip;
2956  ip.x = ip.y = 0.0;
2957  Trans.SetIntPoint (&ip);
2958  // Trans must be linear (more to have embedding?)
2959  // set Jinv = |J| J^{-t} = adj(J)^t
2960  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2961  double vk[2];
2962  Vector xk (vk, 2);
2963 
2964  for (k = 0; k < 8; k++)
2965  {
2966  Trans.Transform (Nodes.IntPoint (k), xk);
2967  ip.x = vk[0]; ip.y = vk[1];
2968  CalcVShape (ip, vshape);
2969  // vk = |J| J^{-t} nk
2970  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2971  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2972  for (j = 0; j < 8; j++)
2973  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2974  {
2975  I(k,j) = 0.0;
2976  }
2977  }
2978 }
2979 
2982 {
2983  double vk[2];
2984  Vector xk (vk, 2);
2985 #ifdef MFEM_THREAD_SAFE
2986  DenseMatrix Jinv(Dim);
2987 #endif
2988 
2989  for (int k = 0; k < 8; k++)
2990  {
2991  Trans.SetIntPoint (&Nodes.IntPoint (k));
2992  // set Jinv = |J| J^{-t} = adj(J)^t
2993  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2994 
2995  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2996  // xk^t |J| J^{-t} nk
2997  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2998  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2999  dofs(k) *= 0.5;
3000  }
3001 }
3002 
3004  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
3005 {
3006  // y = 0
3007  Nodes.IntPoint(0).x = 1./3.;
3008  Nodes.IntPoint(0).y = 0.0;
3009  Nodes.IntPoint(1).x = 2./3.;
3010  Nodes.IntPoint(1).y = 0.0;
3011  // x = 1
3012  Nodes.IntPoint(2).x = 1.0;
3013  Nodes.IntPoint(2).y = 1./3.;
3014  Nodes.IntPoint(3).x = 1.0;
3015  Nodes.IntPoint(3).y = 2./3.;
3016  // y = 1
3017  Nodes.IntPoint(4).x = 2./3.;
3018  Nodes.IntPoint(4).y = 1.0;
3019  Nodes.IntPoint(5).x = 1./3.;
3020  Nodes.IntPoint(5).y = 1.0;
3021  // x = 0
3022  Nodes.IntPoint(6).x = 0.0;
3023  Nodes.IntPoint(6).y = 2./3.;
3024  Nodes.IntPoint(7).x = 0.0;
3025  Nodes.IntPoint(7).y = 1./3.;
3026  // x = 0.5 (interior)
3027  Nodes.IntPoint(8).x = 0.5;
3028  Nodes.IntPoint(8).y = 1./3.;
3029  Nodes.IntPoint(9).x = 0.5;
3030  Nodes.IntPoint(9).y = 2./3.;
3031  // y = 0.5 (interior)
3032  Nodes.IntPoint(10).x = 1./3.;
3033  Nodes.IntPoint(10).y = 0.5;
3034  Nodes.IntPoint(11).x = 2./3.;
3035  Nodes.IntPoint(11).y = 0.5;
3036 }
3037 
3039  DenseMatrix &shape) const
3040 {
3041  double x = ip.x, y = ip.y;
3042 
3043  // y = 0
3044  shape(0,0) = 0;
3045  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
3046  shape(1,0) = 0;
3047  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
3048  // x = 1
3049  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
3050  shape(2,1) = 0;
3051  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
3052  shape(3,1) = 0;
3053  // y = 1
3054  shape(4,0) = 0;
3055  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
3056  shape(5,0) = 0;
3057  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
3058  // x = 0
3059  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
3060  shape(6,1) = 0;
3061  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
3062  shape(7,1) = 0;
3063  // x = 0.5 (interior)
3064  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
3065  shape(8,1) = 0;
3066  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
3067  shape(9,1) = 0;
3068  // y = 0.5 (interior)
3069  shape(10,0) = 0;
3070  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
3071  shape(11,0) = 0;
3072  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
3073 }
3074 
3076  Vector &divshape) const
3077 {
3078  double x = ip.x, y = ip.y;
3079 
3080  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
3081  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
3082  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
3083  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
3084  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
3085  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
3086  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
3087  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
3088  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
3089  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
3090  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
3091  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
3092 }
3093 
3094 const double RT1QuadFiniteElement::nk[12][2] =
3095 {
3096  // y = 0
3097  {0,-1}, {0,-1},
3098  // X = 1
3099  {1, 0}, {1, 0},
3100  // y = 1
3101  {0, 1}, {0, 1},
3102  // x = 0
3103  {-1,0}, {-1,0},
3104  // x = 0.5 (interior)
3105  {1, 0}, {1, 0},
3106  // y = 0.5 (interior)
3107  {0, 1}, {0, 1}
3108 };
3109 
3112 {
3113  int k, j;
3114 #ifdef MFEM_THREAD_SAFE
3116  DenseMatrix Jinv(Dim);
3117 #endif
3118 
3119 #ifdef MFEM_DEBUG
3120  for (k = 0; k < 12; k++)
3121  {
3123  for (j = 0; j < 12; j++)
3124  {
3125  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3126  if (j == k) { d -= 1.0; }
3127  if (fabs(d) > 1.0e-12)
3128  {
3129  mfem::err << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3130  " k = " << k << ", j = " << j << ", d = " << d << endl;
3131  mfem_error();
3132  }
3133  }
3134  }
3135 #endif
3136 
3137  IntegrationPoint ip;
3138  ip.x = ip.y = 0.0;
3139  Trans.SetIntPoint (&ip);
3140  // Trans must be linear (more to have embedding?)
3141  // set Jinv = |J| J^{-t} = adj(J)^t
3142  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3143  double vk[2];
3144  Vector xk (vk, 2);
3145 
3146  for (k = 0; k < 12; k++)
3147  {
3148  Trans.Transform (Nodes.IntPoint (k), xk);
3149  ip.x = vk[0]; ip.y = vk[1];
3150  CalcVShape (ip, vshape);
3151  // vk = |J| J^{-t} nk
3152  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3153  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3154  for (j = 0; j < 12; j++)
3155  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3156  {
3157  I(k,j) = 0.0;
3158  }
3159  }
3160 }
3161 
3164 {
3165  double vk[2];
3166  Vector xk (vk, 2);
3167 #ifdef MFEM_THREAD_SAFE
3168  DenseMatrix Jinv(Dim);
3169 #endif
3170 
3171  for (int k = 0; k < 12; k++)
3172  {
3173  Trans.SetIntPoint (&Nodes.IntPoint (k));
3174  // set Jinv = |J| J^{-t} = adj(J)^t
3175  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3176 
3177  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3178  // xk^t |J| J^{-t} nk
3179  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3180  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3181  }
3182 }
3183 
3184 const double RT2TriangleFiniteElement::M[15][15] =
3185 {
3186  {
3187  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
3188  0, 24.442740046346700787, -16.647580015448900262, -12.,
3189  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
3190  12., 30.590320061795601049, 15.295160030897800524
3191  },
3192  {
3193  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
3194  -15., 10.5
3195  },
3196  {
3197  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
3198  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
3199  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
3200  12., -6.5903200617956010489, -3.2951600308978005244
3201  },
3202  {
3203  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
3204  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
3205  0, -3.2951600308978005244
3206  },
3207  {
3208  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
3209  36., 10.5
3210  },
3211  {
3212  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
3213  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
3214  0, 15.295160030897800524
3215  },
3216  {
3217  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
3218  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
3219  -0.76209992275549868892, 4.1189500386222506555, -12.,
3220  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
3221  12.
3222  },
3223  {
3224  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
3225  -15., -15.
3226  },
3227  {
3228  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
3229  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
3230  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
3231  30.590320061795601049, 12.
3232  },
3233  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
3234  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
3235  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
3236  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
3237  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
3238  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
3239 };
3240 
3242  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
3243 {
3244  const double p = 0.11270166537925831148;
3245 
3246  Nodes.IntPoint(0).x = p;
3247  Nodes.IntPoint(0).y = 0.0;
3248  Nodes.IntPoint(1).x = 0.5;
3249  Nodes.IntPoint(1).y = 0.0;
3250  Nodes.IntPoint(2).x = 1.-p;
3251  Nodes.IntPoint(2).y = 0.0;
3252  Nodes.IntPoint(3).x = 1.-p;
3253  Nodes.IntPoint(3).y = p;
3254  Nodes.IntPoint(4).x = 0.5;
3255  Nodes.IntPoint(4).y = 0.5;
3256  Nodes.IntPoint(5).x = p;
3257  Nodes.IntPoint(5).y = 1.-p;
3258  Nodes.IntPoint(6).x = 0.0;
3259  Nodes.IntPoint(6).y = 1.-p;
3260  Nodes.IntPoint(7).x = 0.0;
3261  Nodes.IntPoint(7).y = 0.5;
3262  Nodes.IntPoint(8).x = 0.0;
3263  Nodes.IntPoint(8).y = p;
3264  Nodes.IntPoint(9).x = 0.25;
3265  Nodes.IntPoint(9).y = 0.25;
3266  Nodes.IntPoint(10).x = 0.25;
3267  Nodes.IntPoint(10).y = 0.25;
3268  Nodes.IntPoint(11).x = 0.5;
3269  Nodes.IntPoint(11).y = 0.25;
3270  Nodes.IntPoint(12).x = 0.5;
3271  Nodes.IntPoint(12).y = 0.25;
3272  Nodes.IntPoint(13).x = 0.25;
3273  Nodes.IntPoint(13).y = 0.5;
3274  Nodes.IntPoint(14).x = 0.25;
3275  Nodes.IntPoint(14).y = 0.5;
3276 }
3277 
3279  DenseMatrix &shape) const
3280 {
3281  double x = ip.x, y = ip.y;
3282 
3283  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
3284  x*x*y, x*y*y
3285  };
3286  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
3287  x*x*y, x*y*y, y*y*y
3288  };
3289 
3290  for (int i = 0; i < 15; i++)
3291  {
3292  double cx = 0.0, cy = 0.0;
3293  for (int j = 0; j < 15; j++)
3294  {
3295  cx += M[i][j] * Bx[j];
3296  cy += M[i][j] * By[j];
3297  }
3298  shape(i,0) = cx;
3299  shape(i,1) = cy;
3300  }
3301 }
3302 
3304  Vector &divshape) const
3305 {
3306  double x = ip.x, y = ip.y;
3307 
3308  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
3309  4.*x*x, 4.*x*y, 4.*y*y
3310  };
3311 
3312  for (int i = 0; i < 15; i++)
3313  {
3314  double div = 0.0;
3315  for (int j = 0; j < 15; j++)
3316  {
3317  div += M[i][j] * DivB[j];
3318  }
3319  divshape(i) = div;
3320  }
3321 }
3322 
3323 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
3324 
3325 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
3326 
3328  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
3329 {
3330  // y = 0 (pt[0])
3331  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
3332  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
3333  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
3334  // x = 1 (pt[3])
3335  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
3336  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
3337  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
3338  // y = 1 (pt[3])
3339  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
3340  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
3341  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
3342  // x = 0 (pt[0])
3343  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
3344  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
3345  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
3346  // x = pt[1] (interior)
3347  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
3348  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
3349  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
3350  // x = pt[2] (interior)
3351  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
3352  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
3353  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
3354  // y = pt[1] (interior)
3355  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
3356  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
3357  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
3358  // y = pt[2] (interior)
3359  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
3360  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
3361  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
3362 }
3363 
3365  DenseMatrix &shape) const
3366 {
3367  double x = ip.x, y = ip.y;
3368 
3369  double ax0 = pt[0] - x;
3370  double ax1 = pt[1] - x;
3371  double ax2 = pt[2] - x;
3372  double ax3 = pt[3] - x;
3373 
3374  double by0 = dpt[0] - y;
3375  double by1 = dpt[1] - y;
3376  double by2 = dpt[2] - y;
3377 
3378  double ay0 = pt[0] - y;
3379  double ay1 = pt[1] - y;
3380  double ay2 = pt[2] - y;
3381  double ay3 = pt[3] - y;
3382 
3383  double bx0 = dpt[0] - x;
3384  double bx1 = dpt[1] - x;
3385  double bx2 = dpt[2] - x;
3386 
3387  double A01 = pt[0] - pt[1];
3388  double A02 = pt[0] - pt[2];
3389  double A12 = pt[1] - pt[2];
3390  double A03 = pt[0] - pt[3];
3391  double A13 = pt[1] - pt[3];
3392  double A23 = pt[2] - pt[3];
3393 
3394  double B01 = dpt[0] - dpt[1];
3395  double B02 = dpt[0] - dpt[2];
3396  double B12 = dpt[1] - dpt[2];
3397 
3398  double tx0 = (bx1*bx2)/(B01*B02);
3399  double tx1 = -(bx0*bx2)/(B01*B12);
3400  double tx2 = (bx0*bx1)/(B02*B12);
3401 
3402  double ty0 = (by1*by2)/(B01*B02);
3403  double ty1 = -(by0*by2)/(B01*B12);
3404  double ty2 = (by0*by1)/(B02*B12);
3405 
3406  // y = 0 (p[0])
3407  shape(0, 0) = 0;
3408  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
3409  shape(1, 0) = 0;
3410  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
3411  shape(2, 0) = 0;
3412  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
3413  // x = 1 (p[3])
3414  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
3415  shape(3, 1) = 0;
3416  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
3417  shape(4, 1) = 0;
3418  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
3419  shape(5, 1) = 0;
3420  // y = 1 (p[3])
3421  shape(6, 0) = 0;
3422  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
3423  shape(7, 0) = 0;
3424  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
3425  shape(8, 0) = 0;
3426  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
3427  // x = 0 (p[0])
3428  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
3429  shape(9, 1) = 0;
3430  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
3431  shape(10, 1) = 0;
3432  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
3433  shape(11, 1) = 0;
3434  // x = p[1] (interior)
3435  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
3436  shape(12, 1) = 0;
3437  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
3438  shape(13, 1) = 0;
3439  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
3440  shape(14, 1) = 0;
3441  // x = p[2] (interior)
3442  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
3443  shape(15, 1) = 0;
3444  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
3445  shape(16, 1) = 0;
3446  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
3447  shape(17, 1) = 0;
3448  // y = p[1] (interior)
3449  shape(18, 0) = 0;
3450  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
3451  shape(19, 0) = 0;
3452  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
3453  shape(20, 0) = 0;
3454  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
3455  // y = p[2] (interior)
3456  shape(21, 0) = 0;
3457  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
3458  shape(22, 0) = 0;
3459  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
3460  shape(23, 0) = 0;
3461  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
3462 }
3463 
3465  Vector &divshape) const
3466 {
3467  double x = ip.x, y = ip.y;
3468 
3469  double a01 = pt[0]*pt[1];
3470  double a02 = pt[0]*pt[2];
3471  double a12 = pt[1]*pt[2];
3472  double a03 = pt[0]*pt[3];
3473  double a13 = pt[1]*pt[3];
3474  double a23 = pt[2]*pt[3];
3475 
3476  double bx0 = dpt[0] - x;
3477  double bx1 = dpt[1] - x;
3478  double bx2 = dpt[2] - x;
3479 
3480  double by0 = dpt[0] - y;
3481  double by1 = dpt[1] - y;
3482  double by2 = dpt[2] - y;
3483 
3484  double A01 = pt[0] - pt[1];
3485  double A02 = pt[0] - pt[2];
3486  double A12 = pt[1] - pt[2];
3487  double A03 = pt[0] - pt[3];
3488  double A13 = pt[1] - pt[3];
3489  double A23 = pt[2] - pt[3];
3490 
3491  double A012 = pt[0] + pt[1] + pt[2];
3492  double A013 = pt[0] + pt[1] + pt[3];
3493  double A023 = pt[0] + pt[2] + pt[3];
3494  double A123 = pt[1] + pt[2] + pt[3];
3495 
3496  double B01 = dpt[0] - dpt[1];
3497  double B02 = dpt[0] - dpt[2];
3498  double B12 = dpt[1] - dpt[2];
3499 
3500  double tx0 = (bx1*bx2)/(B01*B02);
3501  double tx1 = -(bx0*bx2)/(B01*B12);
3502  double tx2 = (bx0*bx1)/(B02*B12);
3503 
3504  double ty0 = (by1*by2)/(B01*B02);
3505  double ty1 = -(by0*by2)/(B01*B12);
3506  double ty2 = (by0*by1)/(B02*B12);
3507 
3508  // y = 0 (p[0])
3509  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
3510  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
3511  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
3512  // x = 1 (p[3])
3513  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
3514  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
3515  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
3516  // y = 1 (p[3])
3517  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
3518  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
3519  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
3520  // x = 0 (p[0])
3521  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
3522  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
3523  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
3524  // x = p[1] (interior)
3525  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
3526  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
3527  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
3528  // x = p[2] (interior)
3529  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
3530  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
3531  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
3532  // y = p[1] (interior)
3533  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
3534  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
3535  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
3536  // y = p[2] (interior)
3537  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
3538  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
3539  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
3540 }
3541 
3542 const double RT2QuadFiniteElement::nk[24][2] =
3543 {
3544  // y = 0
3545  {0,-1}, {0,-1}, {0,-1},
3546  // x = 1
3547  {1, 0}, {1, 0}, {1, 0},
3548  // y = 1
3549  {0, 1}, {0, 1}, {0, 1},
3550  // x = 0
3551  {-1,0}, {-1,0}, {-1,0},
3552  // x = p[1] (interior)
3553  {1, 0}, {1, 0}, {1, 0},
3554  // x = p[2] (interior)
3555  {1, 0}, {1, 0}, {1, 0},
3556  // y = p[1] (interior)
3557  {0, 1}, {0, 1}, {0, 1},
3558  // y = p[1] (interior)
3559  {0, 1}, {0, 1}, {0, 1}
3560 };
3561 
3564 {
3565  int k, j;
3566 #ifdef MFEM_THREAD_SAFE
3568  DenseMatrix Jinv(Dim);
3569 #endif
3570 
3571 #ifdef MFEM_DEBUG
3572  for (k = 0; k < 24; k++)
3573  {
3575  for (j = 0; j < 24; j++)
3576  {
3577  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3578  if (j == k) { d -= 1.0; }
3579  if (fabs(d) > 1.0e-12)
3580  {
3581  mfem::err << "RT2QuadFiniteElement::GetLocalInterpolation (...)\n"
3582  " k = " << k << ", j = " << j << ", d = " << d << endl;
3583  mfem_error();
3584  }
3585  }
3586  }
3587 #endif
3588 
3589  IntegrationPoint ip;
3590  ip.x = ip.y = 0.0;
3591  Trans.SetIntPoint (&ip);
3592  // Trans must be linear (more to have embedding?)
3593  // set Jinv = |J| J^{-t} = adj(J)^t
3594  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3595  double vk[2];
3596  Vector xk (vk, 2);
3597 
3598  for (k = 0; k < 24; k++)
3599  {
3600  Trans.Transform (Nodes.IntPoint (k), xk);
3601  ip.x = vk[0]; ip.y = vk[1];
3602  CalcVShape (ip, vshape);
3603  // vk = |J| J^{-t} nk
3604  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3605  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3606  for (j = 0; j < 24; j++)
3607  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3608  {
3609  I(k,j) = 0.0;
3610  }
3611  }
3612 }
3613 
3616 {
3617  double vk[2];
3618  Vector xk (vk, 2);
3619 #ifdef MFEM_THREAD_SAFE
3620  DenseMatrix Jinv(Dim);
3621 #endif
3622 
3623  for (int k = 0; k < 24; k++)
3624  {
3625  Trans.SetIntPoint (&Nodes.IntPoint (k));
3626  // set Jinv = |J| J^{-t} = adj(J)^t
3627  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3628 
3629  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3630  // xk^t |J| J^{-t} nk
3631  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3632  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3633  }
3634 }
3635 
3637  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
3638 {
3639  Nodes.IntPoint(0).x = 0.33333333333333333333;
3640  Nodes.IntPoint(1).x = 0.66666666666666666667;
3641 }
3642 
3644  Vector &shape) const
3645 {
3646  double x = ip.x;
3647 
3648  shape(0) = 2. - 3. * x;
3649  shape(1) = 3. * x - 1.;
3650 }
3651 
3653  DenseMatrix &dshape) const
3654 {
3655  dshape(0,0) = -3.;
3656  dshape(1,0) = 3.;
3657 }
3658 
3659 
3661  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
3662 {
3663  const double p = 0.11270166537925831148;
3664 
3665  Nodes.IntPoint(0).x = p;
3666  Nodes.IntPoint(1).x = 0.5;
3667  Nodes.IntPoint(2).x = 1.-p;
3668 }
3669 
3671  Vector &shape) const
3672 {
3673  const double p = 0.11270166537925831148;
3674  const double w = 1./((1-2*p)*(1-2*p));
3675  double x = ip.x;
3676 
3677  shape(0) = (2*x-1)*(x-1+p)*w;
3678  shape(1) = 4*(x-1+p)*(p-x)*w;
3679  shape(2) = (2*x-1)*(x-p)*w;
3680 }
3681 
3683  DenseMatrix &dshape) const
3684 {
3685  const double p = 0.11270166537925831148;
3686  const double w = 1./((1-2*p)*(1-2*p));
3687  double x = ip.x;
3688 
3689  dshape(0,0) = (-3+4*x+2*p)*w;
3690  dshape(1,0) = (4-8*x)*w;
3691  dshape(2,0) = (-1+4*x-2*p)*w;
3692 }
3693 
3694 
3696  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
3697 {
3698  int i, m = degree;
3699 
3700  Nodes.IntPoint(0).x = 0.0;
3701  Nodes.IntPoint(1).x = 1.0;
3702  for (i = 1; i < m; i++)
3703  {
3704  Nodes.IntPoint(i+1).x = double(i) / m;
3705  }
3706 
3707  rwk.SetSize(degree+1);
3708 #ifndef MFEM_THREAD_SAFE
3709  rxxk.SetSize(degree+1);
3710 #endif
3711 
3712  rwk(0) = 1.0;
3713  for (i = 1; i <= m; i++)
3714  {
3715  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
3716  }
3717  for (i = 0; i < m/2+1; i++)
3718  {
3719  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
3720  }
3721  for (i = m-1; i >= 0; i -= 2)
3722  {
3723  rwk(i) = -rwk(i);
3724  }
3725 }
3726 
3728  Vector &shape) const
3729 {
3730  double w, wk, x = ip.x;
3731  int i, k, m = GetOrder();
3732 
3733 #ifdef MFEM_THREAD_SAFE
3734  Vector rxxk(m+1);
3735 #endif
3736 
3737  k = (int) floor ( m * x + 0.5 );
3738  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
3739 
3740  wk = 1.0;
3741  for (i = 0; i <= m; i++)
3742  if (i != k)
3743  {
3744  wk *= ( rxxk(i) = x - (double)(i) / m );
3745  }
3746  w = wk * ( rxxk(k) = x - (double)(k) / m );
3747 
3748  if (k != 0)
3749  {
3750  shape(0) = w * rwk(0) / rxxk(0);
3751  }
3752  else
3753  {
3754  shape(0) = wk * rwk(0);
3755  }
3756  if (k != m)
3757  {
3758  shape(1) = w * rwk(m) / rxxk(m);
3759  }
3760  else
3761  {
3762  shape(1) = wk * rwk(k);
3763  }
3764  for (i = 1; i < m; i++)
3765  if (i != k)
3766  {
3767  shape(i+1) = w * rwk(i) / rxxk(i);
3768  }
3769  else
3770  {
3771  shape(k+1) = wk * rwk(k);
3772  }
3773 }
3774 
3776  DenseMatrix &dshape) const
3777 {
3778  double s, srx, w, wk, x = ip.x;
3779  int i, k, m = GetOrder();
3780 
3781 #ifdef MFEM_THREAD_SAFE
3782  Vector rxxk(m+1);
3783 #endif
3784 
3785  k = (int) floor ( m * x + 0.5 );
3786  k = k > m ? m : k < 0 ? 0 : k; // clamp k to [0,m]
3787 
3788  wk = 1.0;
3789  for (i = 0; i <= m; i++)
3790  if (i != k)
3791  {
3792  wk *= ( rxxk(i) = x - (double)(i) / m );
3793  }
3794  w = wk * ( rxxk(k) = x - (double)(k) / m );
3795 
3796  for (i = 0; i <= m; i++)
3797  {
3798  rxxk(i) = 1.0 / rxxk(i);
3799  }
3800  srx = 0.0;
3801  for (i = 0; i <= m; i++)
3802  if (i != k)
3803  {
3804  srx += rxxk(i);
3805  }
3806  s = w * srx + wk;
3807 
3808  if (k != 0)
3809  {
3810  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
3811  }
3812  else
3813  {
3814  dshape(0,0) = wk * srx * rwk(0);
3815  }
3816  if (k != m)
3817  {
3818  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
3819  }
3820  else
3821  {
3822  dshape(1,0) = wk * srx * rwk(k);
3823  }
3824  for (i = 1; i < m; i++)
3825  if (i != k)
3826  {
3827  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
3828  }
3829  else
3830  {
3831  dshape(k+1,0) = wk * srx * rwk(k);
3832  }
3833 }
3834 
3835 
3837  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
3838 {
3839  Nodes.IntPoint(0).x = 0.33333333333333333333;
3840  Nodes.IntPoint(0).y = 0.33333333333333333333;
3841  Nodes.IntPoint(0).z = 0.33333333333333333333;
3842 
3843  Nodes.IntPoint(1).x = 0.0;
3844  Nodes.IntPoint(1).y = 0.33333333333333333333;
3845  Nodes.IntPoint(1).z = 0.33333333333333333333;
3846 
3847  Nodes.IntPoint(2).x = 0.33333333333333333333;
3848  Nodes.IntPoint(2).y = 0.0;
3849  Nodes.IntPoint(2).z = 0.33333333333333333333;
3850 
3851  Nodes.IntPoint(3).x = 0.33333333333333333333;
3852  Nodes.IntPoint(3).y = 0.33333333333333333333;
3853  Nodes.IntPoint(3).z = 0.0;
3854 
3855 }
3856 
3858  Vector &shape) const
3859 {
3860  double L0, L1, L2, L3;
3861 
3862  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
3863  shape(0) = 1.0 - 3.0 * L0;
3864  shape(1) = 1.0 - 3.0 * L1;
3865  shape(2) = 1.0 - 3.0 * L2;
3866  shape(3) = 1.0 - 3.0 * L3;
3867 }
3868 
3870  DenseMatrix &dshape) const
3871 {
3872  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
3873  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
3874  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
3875  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
3876 }
3877 
3878 
3880  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 1, 0)
3881 {
3882  Nodes.IntPoint(0).x = 0.25;
3883  Nodes.IntPoint(0).y = 0.25;
3884  Nodes.IntPoint(0).z = 0.25;
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, 1, 0, FunctionSpace::Qk)
3902 {
3903  Nodes.IntPoint(0).x = 0.5;
3904  Nodes.IntPoint(0).y = 0.5;
3905  Nodes.IntPoint(0).z = 0.5;
3906 }
3907 
3909  Vector &shape) const
3910 {
3911  shape(0) = 1.0;
3912 }
3913 
3915  DenseMatrix &dshape) const
3916 {
3917  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3918 }
3919 
3920 
3922  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
3923  degree, FunctionSpace::Qk)
3924 {
3925  if (degree == 2)
3926  {
3927  I = new int[Dof];
3928  J = new int[Dof];
3929  K = new int[Dof];
3930  // nodes
3931  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3932  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3933  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3934  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3935  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3936  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3937  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3938  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3939  // edges
3940  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3941  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
3942  I[10] = 2; J[10] = 1; K[10] = 0;
3943  I[11] = 0; J[11] = 2; K[11] = 0;
3944  I[12] = 2; J[12] = 0; K[12] = 1;
3945  I[13] = 1; J[13] = 2; K[13] = 1;
3946  I[14] = 2; J[14] = 1; K[14] = 1;
3947  I[15] = 0; J[15] = 2; K[15] = 1;
3948  I[16] = 0; J[16] = 0; K[16] = 2;
3949  I[17] = 1; J[17] = 0; K[17] = 2;
3950  I[18] = 1; J[18] = 1; K[18] = 2;
3951  I[19] = 0; J[19] = 1; K[19] = 2;
3952  // faces
3953  I[20] = 2; J[20] = 2; K[20] = 0;
3954  I[21] = 2; J[21] = 0; K[21] = 2;
3955  I[22] = 1; J[22] = 2; K[22] = 2;
3956  I[23] = 2; J[23] = 1; K[23] = 2;
3957  I[24] = 0; J[24] = 2; K[24] = 2;
3958  I[25] = 2; J[25] = 2; K[25] = 1;
3959  // element
3960  I[26] = 2; J[26] = 2; K[26] = 2;
3961  }
3962  else if (degree == 3)
3963  {
3964  I = new int[Dof];
3965  J = new int[Dof];
3966  K = new int[Dof];
3967  // nodes
3968  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3969  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3970  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3971  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3972  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3973  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3974  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3975  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3976  // edges
3977  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3978  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
3979  I[10] = 1; J[10] = 2; K[10] = 0;
3980  I[11] = 1; J[11] = 3; K[11] = 0;
3981  I[12] = 2; J[12] = 1; K[12] = 0;
3982  I[13] = 3; J[13] = 1; K[13] = 0;
3983  I[14] = 0; J[14] = 2; K[14] = 0;
3984  I[15] = 0; J[15] = 3; K[15] = 0;
3985  I[16] = 2; J[16] = 0; K[16] = 1;
3986  I[17] = 3; J[17] = 0; K[17] = 1;
3987  I[18] = 1; J[18] = 2; K[18] = 1;
3988  I[19] = 1; J[19] = 3; K[19] = 1;
3989  I[20] = 2; J[20] = 1; K[20] = 1;
3990  I[21] = 3; J[21] = 1; K[21] = 1;
3991  I[22] = 0; J[22] = 2; K[22] = 1;
3992  I[23] = 0; J[23] = 3; K[23] = 1;
3993  I[24] = 0; J[24] = 0; K[24] = 2;
3994  I[25] = 0; J[25] = 0; K[25] = 3;
3995  I[26] = 1; J[26] = 0; K[26] = 2;
3996  I[27] = 1; J[27] = 0; K[27] = 3;
3997  I[28] = 1; J[28] = 1; K[28] = 2;
3998  I[29] = 1; J[29] = 1; K[29] = 3;
3999  I[30] = 0; J[30] = 1; K[30] = 2;
4000  I[31] = 0; J[31] = 1; K[31] = 3;
4001  // faces
4002  I[32] = 2; J[32] = 3; K[32] = 0;
4003  I[33] = 3; J[33] = 3; K[33] = 0;
4004  I[34] = 2; J[34] = 2; K[34] = 0;
4005  I[35] = 3; J[35] = 2; K[35] = 0;
4006  I[36] = 2; J[36] = 0; K[36] = 2;
4007  I[37] = 3; J[37] = 0; K[37] = 2;
4008  I[38] = 2; J[38] = 0; K[38] = 3;
4009  I[39] = 3; J[39] = 0; K[39] = 3;
4010  I[40] = 1; J[40] = 2; K[40] = 2;
4011  I[41] = 1; J[41] = 3; K[41] = 2;
4012  I[42] = 1; J[42] = 2; K[42] = 3;
4013  I[43] = 1; J[43] = 3; K[43] = 3;
4014  I[44] = 3; J[44] = 1; K[44] = 2;
4015  I[45] = 2; J[45] = 1; K[45] = 2;
4016  I[46] = 3; J[46] = 1; K[46] = 3;
4017  I[47] = 2; J[47] = 1; K[47] = 3;
4018  I[48] = 0; J[48] = 3; K[48] = 2;
4019  I[49] = 0; J[49] = 2; K[49] = 2;
4020  I[50] = 0; J[50] = 3; K[50] = 3;
4021  I[51] = 0; J[51] = 2; K[51] = 3;
4022  I[52] = 2; J[52] = 2; K[52] = 1;
4023  I[53] = 3; J[53] = 2; K[53] = 1;
4024  I[54] = 2; J[54] = 3; K[54] = 1;
4025  I[55] = 3; J[55] = 3; K[55] = 1;
4026  // element
4027  I[56] = 2; J[56] = 2; K[56] = 2;
4028  I[57] = 3; J[57] = 2; K[57] = 2;
4029  I[58] = 3; J[58] = 3; K[58] = 2;
4030  I[59] = 2; J[59] = 3; K[59] = 2;
4031  I[60] = 2; J[60] = 2; K[60] = 3;
4032  I[61] = 3; J[61] = 2; K[61] = 3;
4033  I[62] = 3; J[62] = 3; K[62] = 3;
4034  I[63] = 2; J[63] = 3; K[63] = 3;
4035  }
4036  else
4037  {
4038  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
4039  }
4040 
4041  fe1d = new Lagrange1DFiniteElement(degree);
4042  dof1d = fe1d -> GetDof();
4043 
4044 #ifndef MFEM_THREAD_SAFE
4045  shape1dx.SetSize(dof1d);
4046  shape1dy.SetSize(dof1d);
4047  shape1dz.SetSize(dof1d);
4048 
4049  dshape1dx.SetSize(dof1d,1);
4050  dshape1dy.SetSize(dof1d,1);
4051  dshape1dz.SetSize(dof1d,1);
4052 #endif
4053 
4054  for (int n = 0; n < Dof; n++)
4055  {
4056  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
4057  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
4058  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
4059  }
4060 }
4061 
4063  Vector &shape) 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 #endif
4072 
4073  fe1d -> CalcShape(ip, shape1dx);
4074  fe1d -> CalcShape(ipy, shape1dy);
4075  fe1d -> CalcShape(ipz, shape1dz);
4076 
4077  for (int n = 0; n < Dof; n++)
4078  {
4079  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
4080  }
4081 }
4082 
4084  DenseMatrix &dshape) const
4085 {
4086  IntegrationPoint ipy, ipz;
4087  ipy.x = ip.y;
4088  ipz.x = ip.z;
4089 
4090 #ifdef MFEM_THREAD_SAFE
4091  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
4092  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
4093 #endif
4094 
4095  fe1d -> CalcShape(ip, shape1dx);
4096  fe1d -> CalcShape(ipy, shape1dy);
4097  fe1d -> CalcShape(ipz, shape1dz);
4098 
4099  fe1d -> CalcDShape(ip, dshape1dx);
4100  fe1d -> CalcDShape(ipy, dshape1dy);
4101  fe1d -> CalcDShape(ipz, dshape1dz);
4102 
4103  for (int n = 0; n < Dof; n++)
4104  {
4105  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
4106  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
4107  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
4108  }
4109 }
4110 
4112 {
4113  delete fe1d;
4114 
4115  delete [] I;
4116  delete [] J;
4117  delete [] K;
4118 }
4119 
4120 
4122  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
4123 {
4124  Nodes.IntPoint(0).x = 0.0;
4125  Nodes.IntPoint(1).x = 1.0;
4126  Nodes.IntPoint(2).x = 0.5;
4127 }
4128 
4130  Vector &shape) const
4131 {
4132  double x = ip.x;
4133 
4134  if (x <= 0.5)
4135  {
4136  shape(0) = 1.0 - 2.0 * x;
4137  shape(1) = 0.0;
4138  shape(2) = 2.0 * x;
4139  }
4140  else
4141  {
4142  shape(0) = 0.0;
4143  shape(1) = 2.0 * x - 1.0;
4144  shape(2) = 2.0 - 2.0 * x;
4145  }
4146 }
4147 
4149  DenseMatrix &dshape) const
4150 {
4151  double x = ip.x;
4152 
4153  if (x <= 0.5)
4154  {
4155  dshape(0,0) = - 2.0;
4156  dshape(1,0) = 0.0;
4157  dshape(2,0) = 2.0;
4158  }
4159  else
4160  {
4161  dshape(0,0) = 0.0;
4162  dshape(1,0) = 2.0;
4163  dshape(2,0) = - 2.0;
4164  }
4165 }
4166 
4168  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
4169 {
4170  Nodes.IntPoint(0).x = 0.0;
4171  Nodes.IntPoint(0).y = 0.0;
4172  Nodes.IntPoint(1).x = 1.0;
4173  Nodes.IntPoint(1).y = 0.0;
4174  Nodes.IntPoint(2).x = 0.0;
4175  Nodes.IntPoint(2).y = 1.0;
4176  Nodes.IntPoint(3).x = 0.5;
4177  Nodes.IntPoint(3).y = 0.0;
4178  Nodes.IntPoint(4).x = 0.5;
4179  Nodes.IntPoint(4).y = 0.5;
4180  Nodes.IntPoint(5).x = 0.0;
4181  Nodes.IntPoint(5).y = 0.5;
4182 }
4183 
4185  Vector &shape) const
4186 {
4187  int i;
4188 
4189  double L0, L1, L2;
4190  L0 = 2.0 * ( 1. - ip.x - ip.y );
4191  L1 = 2.0 * ( ip.x );
4192  L2 = 2.0 * ( ip.y );
4193 
4194  // The reference triangle is split in 4 triangles as follows:
4195  //
4196  // T0 - 0,3,5
4197  // T1 - 1,3,4
4198  // T2 - 2,4,5
4199  // T3 - 3,4,5
4200 
4201  for (i = 0; i < 6; i++)
4202  {
4203  shape(i) = 0.0;
4204  }
4205 
4206  if (L0 >= 1.0) // T0
4207  {
4208  shape(0) = L0 - 1.0;
4209  shape(3) = L1;
4210  shape(5) = L2;
4211  }
4212  else if (L1 >= 1.0) // T1
4213  {
4214  shape(3) = L0;
4215  shape(1) = L1 - 1.0;
4216  shape(4) = L2;
4217  }
4218  else if (L2 >= 1.0) // T2
4219  {
4220  shape(5) = L0;
4221  shape(4) = L1;
4222  shape(2) = L2 - 1.0;
4223  }
4224  else // T3
4225  {
4226  shape(3) = 1.0 - L2;
4227  shape(4) = 1.0 - L0;
4228  shape(5) = 1.0 - L1;
4229  }
4230 }
4231 
4233  DenseMatrix &dshape) const
4234 {
4235  int i,j;
4236 
4237  double L0, L1, L2;
4238  L0 = 2.0 * ( 1. - ip.x - ip.y );
4239  L1 = 2.0 * ( ip.x );
4240  L2 = 2.0 * ( ip.y );
4241 
4242  double DL0[2], DL1[2], DL2[2];
4243  DL0[0] = -2.0; DL0[1] = -2.0;
4244  DL1[0] = 2.0; DL1[1] = 0.0;
4245  DL2[0] = 0.0; DL2[1] = 2.0;
4246 
4247  for (i = 0; i < 6; i++)
4248  for (j = 0; j < 2; j++)
4249  {
4250  dshape(i,j) = 0.0;
4251  }
4252 
4253  if (L0 >= 1.0) // T0
4254  {
4255  for (j = 0; j < 2; j++)
4256  {
4257  dshape(0,j) = DL0[j];
4258  dshape(3,j) = DL1[j];
4259  dshape(5,j) = DL2[j];
4260  }
4261  }
4262  else if (L1 >= 1.0) // T1
4263  {
4264  for (j = 0; j < 2; j++)
4265  {
4266  dshape(3,j) = DL0[j];
4267  dshape(1,j) = DL1[j];
4268  dshape(4,j) = DL2[j];
4269  }
4270  }
4271  else if (L2 >= 1.0) // T2
4272  {
4273  for (j = 0; j < 2; j++)
4274  {
4275  dshape(5,j) = DL0[j];
4276  dshape(4,j) = DL1[j];
4277  dshape(2,j) = DL2[j];
4278  }
4279  }
4280  else // T3
4281  {
4282  for (j = 0; j < 2; j++)
4283  {
4284  dshape(3,j) = - DL2[j];
4285  dshape(4,j) = - DL0[j];
4286  dshape(5,j) = - DL1[j];
4287  }
4288  }
4289 }
4290 
4292  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
4293 {
4294  Nodes.IntPoint(0).x = 0.0;
4295  Nodes.IntPoint(0).y = 0.0;
4296  Nodes.IntPoint(0).z = 0.0;
4297  Nodes.IntPoint(1).x = 1.0;
4298  Nodes.IntPoint(1).y = 0.0;
4299  Nodes.IntPoint(1).z = 0.0;
4300  Nodes.IntPoint(2).x = 0.0;
4301  Nodes.IntPoint(2).y = 1.0;
4302  Nodes.IntPoint(2).z = 0.0;
4303  Nodes.IntPoint(3).x = 0.0;
4304  Nodes.IntPoint(3).y = 0.0;
4305  Nodes.IntPoint(3).z = 1.0;
4306  Nodes.IntPoint(4).x = 0.5;
4307  Nodes.IntPoint(4).y = 0.0;
4308  Nodes.IntPoint(4).z = 0.0;
4309  Nodes.IntPoint(5).x = 0.0;
4310  Nodes.IntPoint(5).y = 0.5;
4311  Nodes.IntPoint(5).z = 0.0;
4312  Nodes.IntPoint(6).x = 0.0;
4313  Nodes.IntPoint(6).y = 0.0;
4314  Nodes.IntPoint(6).z = 0.5;
4315  Nodes.IntPoint(7).x = 0.5;
4316  Nodes.IntPoint(7).y = 0.5;
4317  Nodes.IntPoint(7).z = 0.0;
4318  Nodes.IntPoint(8).x = 0.5;
4319  Nodes.IntPoint(8).y = 0.0;
4320  Nodes.IntPoint(8).z = 0.5;
4321  Nodes.IntPoint(9).x = 0.0;
4322  Nodes.IntPoint(9).y = 0.5;
4323  Nodes.IntPoint(9).z = 0.5;
4324 }
4325 
4327  Vector &shape) const
4328 {
4329  int i;
4330 
4331  double L0, L1, L2, L3, L4, L5;
4332  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4333  L1 = 2.0 * ( ip.x );
4334  L2 = 2.0 * ( ip.y );
4335  L3 = 2.0 * ( ip.z );
4336  L4 = 2.0 * ( ip.x + ip.y );
4337  L5 = 2.0 * ( ip.y + ip.z );
4338 
4339  // The reference tetrahedron is split in 8 tetrahedra as follows:
4340  //
4341  // T0 - 0,4,5,6
4342  // T1 - 1,4,7,8
4343  // T2 - 2,5,7,9
4344  // T3 - 3,6,8,9
4345  // T4 - 4,5,6,8
4346  // T5 - 4,5,7,8
4347  // T6 - 5,6,8,9
4348  // T7 - 5,7,8,9
4349 
4350  for (i = 0; i < 10; i++)
4351  {
4352  shape(i) = 0.0;
4353  }
4354 
4355  if (L0 >= 1.0) // T0
4356  {
4357  shape(0) = L0 - 1.0;
4358  shape(4) = L1;
4359  shape(5) = L2;
4360  shape(6) = L3;
4361  }
4362  else if (L1 >= 1.0) // T1
4363  {
4364  shape(4) = L0;
4365  shape(1) = L1 - 1.0;
4366  shape(7) = L2;
4367  shape(8) = L3;
4368  }
4369  else if (L2 >= 1.0) // T2
4370  {
4371  shape(5) = L0;
4372  shape(7) = L1;
4373  shape(2) = L2 - 1.0;
4374  shape(9) = L3;
4375  }
4376  else if (L3 >= 1.0) // T3
4377  {
4378  shape(6) = L0;
4379  shape(8) = L1;
4380  shape(9) = L2;
4381  shape(3) = L3 - 1.0;
4382  }
4383  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4384  {
4385  shape(4) = 1.0 - L5;
4386  shape(5) = L2;
4387  shape(6) = 1.0 - L4;
4388  shape(8) = 1.0 - L0;
4389  }
4390  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4391  {
4392  shape(4) = 1.0 - L5;
4393  shape(5) = 1.0 - L1;
4394  shape(7) = L4 - 1.0;
4395  shape(8) = L3;
4396  }
4397  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4398  {
4399  shape(5) = 1.0 - L3;
4400  shape(6) = 1.0 - L4;
4401  shape(8) = L1;
4402  shape(9) = L5 - 1.0;
4403  }
4404  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4405  {
4406  shape(5) = L0;
4407  shape(7) = L4 - 1.0;
4408  shape(8) = 1.0 - L2;
4409  shape(9) = L5 - 1.0;
4410  }
4411 }
4412 
4414  DenseMatrix &dshape) const
4415 {
4416  int i,j;
4417 
4418  double L0, L1, L2, L3, L4, L5;
4419  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4420  L1 = 2.0 * ( ip.x );
4421  L2 = 2.0 * ( ip.y );
4422  L3 = 2.0 * ( ip.z );
4423  L4 = 2.0 * ( ip.x + ip.y );
4424  L5 = 2.0 * ( ip.y + ip.z );
4425 
4426  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
4427  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
4428  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
4429  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
4430  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
4431  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
4432  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
4433 
4434  for (i = 0; i < 10; i++)
4435  for (j = 0; j < 3; j++)
4436  {
4437  dshape(i,j) = 0.0;
4438  }
4439 
4440  if (L0 >= 1.0) // T0
4441  {
4442  for (j = 0; j < 3; j++)
4443  {
4444  dshape(0,j) = DL0[j];
4445  dshape(4,j) = DL1[j];
4446  dshape(5,j) = DL2[j];
4447  dshape(6,j) = DL3[j];
4448  }
4449  }
4450  else if (L1 >= 1.0) // T1
4451  {
4452  for (j = 0; j < 3; j++)
4453  {
4454  dshape(4,j) = DL0[j];
4455  dshape(1,j) = DL1[j];
4456  dshape(7,j) = DL2[j];
4457  dshape(8,j) = DL3[j];
4458  }
4459  }
4460  else if (L2 >= 1.0) // T2
4461  {
4462  for (j = 0; j < 3; j++)
4463  {
4464  dshape(5,j) = DL0[j];
4465  dshape(7,j) = DL1[j];
4466  dshape(2,j) = DL2[j];
4467  dshape(9,j) = DL3[j];
4468  }
4469  }
4470  else if (L3 >= 1.0) // T3
4471  {
4472  for (j = 0; j < 3; j++)
4473  {
4474  dshape(6,j) = DL0[j];
4475  dshape(8,j) = DL1[j];
4476  dshape(9,j) = DL2[j];
4477  dshape(3,j) = DL3[j];
4478  }
4479  }
4480  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4481  {
4482  for (j = 0; j < 3; j++)
4483  {
4484  dshape(4,j) = - DL5[j];
4485  dshape(5,j) = DL2[j];
4486  dshape(6,j) = - DL4[j];
4487  dshape(8,j) = - DL0[j];
4488  }
4489  }
4490  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4491  {
4492  for (j = 0; j < 3; j++)
4493  {
4494  dshape(4,j) = - DL5[j];
4495  dshape(5,j) = - DL1[j];
4496  dshape(7,j) = DL4[j];
4497  dshape(8,j) = DL3[j];
4498  }
4499  }
4500  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4501  {
4502  for (j = 0; j < 3; j++)
4503  {
4504  dshape(5,j) = - DL3[j];
4505  dshape(6,j) = - DL4[j];
4506  dshape(8,j) = DL1[j];
4507  dshape(9,j) = DL5[j];
4508  }
4509  }
4510  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4511  {
4512  for (j = 0; j < 3; j++)
4513  {
4514  dshape(5,j) = DL0[j];
4515  dshape(7,j) = DL4[j];
4516  dshape(8,j) = - DL2[j];
4517  dshape(9,j) = DL5[j];
4518  }
4519  }
4520 }
4521 
4522 
4524  : NodalFiniteElement(2, Geometry::SQUARE, 9, 1, FunctionSpace::rQk)
4525 {
4526  Nodes.IntPoint(0).x = 0.0;
4527  Nodes.IntPoint(0).y = 0.0;
4528  Nodes.IntPoint(1).x = 1.0;
4529  Nodes.IntPoint(1).y = 0.0;
4530  Nodes.IntPoint(2).x = 1.0;
4531  Nodes.IntPoint(2).y = 1.0;
4532  Nodes.IntPoint(3).x = 0.0;
4533  Nodes.IntPoint(3).y = 1.0;
4534  Nodes.IntPoint(4).x = 0.5;
4535  Nodes.IntPoint(4).y = 0.0;
4536  Nodes.IntPoint(5).x = 1.0;
4537  Nodes.IntPoint(5).y = 0.5;
4538  Nodes.IntPoint(6).x = 0.5;
4539  Nodes.IntPoint(6).y = 1.0;
4540  Nodes.IntPoint(7).x = 0.0;
4541  Nodes.IntPoint(7).y = 0.5;
4542  Nodes.IntPoint(8).x = 0.5;
4543  Nodes.IntPoint(8).y = 0.5;
4544 }
4545 
4547  Vector &shape) const
4548 {
4549  int i;
4550  double x = ip.x, y = ip.y;
4551  double Lx, Ly;
4552  Lx = 2.0 * ( 1. - x );
4553  Ly = 2.0 * ( 1. - y );
4554 
4555  // The reference square is split in 4 squares as follows:
4556  //
4557  // T0 - 0,4,7,8
4558  // T1 - 1,4,5,8
4559  // T2 - 2,5,6,8
4560  // T3 - 3,6,7,8
4561 
4562  for (i = 0; i < 9; i++)
4563  {
4564  shape(i) = 0.0;
4565  }
4566 
4567  if ((x <= 0.5) && (y <= 0.5)) // T0
4568  {
4569  shape(0) = (Lx - 1.0) * (Ly - 1.0);
4570  shape(4) = (2.0 - Lx) * (Ly - 1.0);
4571  shape(8) = (2.0 - Lx) * (2.0 - Ly);
4572  shape(7) = (Lx - 1.0) * (2.0 - Ly);
4573  }
4574  else if ((x >= 0.5) && (y <= 0.5)) // T1
4575  {
4576  shape(4) = Lx * (Ly - 1.0);
4577  shape(1) = (1.0 - Lx) * (Ly - 1.0);
4578  shape(5) = (1.0 - Lx) * (2.0 - Ly);
4579  shape(8) = Lx * (2.0 - Ly);
4580  }
4581  else if ((x >= 0.5) && (y >= 0.5)) // T2
4582  {
4583  shape(8) = Lx * Ly ;
4584  shape(5) = (1.0 - Lx) * Ly ;
4585  shape(2) = (1.0 - Lx) * (1.0 - Ly);
4586  shape(6) = Lx * (1.0 - Ly);
4587  }
4588  else if ((x <= 0.5) && (y >= 0.5)) // T3
4589  {
4590  shape(7) = (Lx - 1.0) * Ly ;
4591  shape(8) = (2.0 - Lx) * Ly ;
4592  shape(6) = (2.0 - Lx) * (1.0 - Ly);
4593  shape(3) = (Lx - 1.0) * (1.0 - Ly);
4594  }
4595 }
4596 
4598  DenseMatrix &dshape) const
4599 {
4600  int i,j;
4601  double x = ip.x, y = ip.y;
4602  double Lx, Ly;
4603  Lx = 2.0 * ( 1. - x );
4604  Ly = 2.0 * ( 1. - y );
4605 
4606  for (i = 0; i < 9; i++)
4607  for (j = 0; j < 2; j++)
4608  {
4609  dshape(i,j) = 0.0;
4610  }
4611 
4612  if ((x <= 0.5) && (y <= 0.5)) // T0
4613  {
4614  dshape(0,0) = 2.0 * (1.0 - Ly);
4615  dshape(0,1) = 2.0 * (1.0 - Lx);
4616 
4617  dshape(4,0) = 2.0 * (Ly - 1.0);
4618  dshape(4,1) = -2.0 * (2.0 - Lx);
4619 
4620  dshape(8,0) = 2.0 * (2.0 - Ly);
4621  dshape(8,1) = 2.0 * (2.0 - Lx);
4622 
4623  dshape(7,0) = -2.0 * (2.0 - Ly);
4624  dshape(7,0) = 2.0 * (Lx - 1.0);
4625  }
4626  else if ((x >= 0.5) && (y <= 0.5)) // T1
4627  {
4628  dshape(4,0) = -2.0 * (Ly - 1.0);
4629  dshape(4,1) = -2.0 * Lx;
4630 
4631  dshape(1,0) = 2.0 * (Ly - 1.0);
4632  dshape(1,1) = -2.0 * (1.0 - Lx);
4633 
4634  dshape(5,0) = 2.0 * (2.0 - Ly);
4635  dshape(5,1) = 2.0 * (1.0 - Lx);
4636 
4637  dshape(8,0) = -2.0 * (2.0 - Ly);
4638  dshape(8,1) = 2.0 * Lx;
4639  }
4640  else if ((x >= 0.5) && (y >= 0.5)) // T2
4641  {
4642  dshape(8,0) = -2.0 * Ly;
4643  dshape(8,1) = -2.0 * Lx;
4644 
4645  dshape(5,0) = 2.0 * Ly;
4646  dshape(5,1) = -2.0 * (1.0 - Lx);
4647 
4648  dshape(2,0) = 2.0 * (1.0 - Ly);
4649  dshape(2,1) = 2.0 * (1.0 - Lx);
4650 
4651  dshape(6,0) = -2.0 * (1.0 - Ly);
4652  dshape(6,1) = 2.0 * Lx;
4653  }
4654  else if ((x <= 0.5) && (y >= 0.5)) // T3
4655  {
4656  dshape(7,0) = -2.0 * Ly;
4657  dshape(7,1) = -2.0 * (Lx - 1.0);
4658 
4659  dshape(8,0) = 2.0 * Ly ;
4660  dshape(8,1) = -2.0 * (2.0 - Lx);
4661 
4662  dshape(6,0) = 2.0 * (1.0 - Ly);
4663  dshape(6,1) = 2.0 * (2.0 - Lx);
4664 
4665  dshape(3,0) = -2.0 * (1.0 - Ly);
4666  dshape(3,1) = 2.0 * (Lx - 1.0);
4667  }
4668 }
4669 
4671  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
4672 {
4673  double I[27];
4674  double J[27];
4675  double K[27];
4676  // nodes
4677  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
4678  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
4679  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
4680  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
4681  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
4682  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
4683  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
4684  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
4685  // edges
4686  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
4687  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
4688  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
4689  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
4690  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
4691  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
4692  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
4693  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
4694  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
4695  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
4696  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
4697  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
4698  // faces
4699  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
4700  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
4701  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
4702  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
4703  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
4704  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
4705  // element
4706  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
4707 
4708  for (int n = 0; n < 27; n++)
4709  {
4710  Nodes.IntPoint(n).x = I[n];
4711  Nodes.IntPoint(n).y = J[n];
4712  Nodes.IntPoint(n).z = K[n];
4713  }
4714 }
4715 
4717  Vector &shape) const
4718 {
4719  int i, N[8];
4720  double Lx, Ly, Lz;
4721  double x = ip.x, y = ip.y, z = ip.z;
4722 
4723  for (i = 0; i < 27; i++)
4724  {
4725  shape(i) = 0.0;
4726  }
4727 
4728  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4729  {
4730  Lx = 1.0 - 2.0 * x;
4731  Ly = 1.0 - 2.0 * y;
4732  Lz = 1.0 - 2.0 * z;
4733 
4734  N[0] = 0;
4735  N[1] = 8;
4736  N[2] = 20;
4737  N[3] = 11;
4738  N[4] = 16;
4739  N[5] = 21;
4740  N[6] = 26;
4741  N[7] = 24;
4742  }
4743  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4744  {
4745  Lx = 2.0 - 2.0 * x;
4746  Ly = 1.0 - 2.0 * y;
4747  Lz = 1.0 - 2.0 * z;
4748 
4749  N[0] = 8;
4750  N[1] = 1;
4751  N[2] = 9;
4752  N[3] = 20;
4753  N[4] = 21;
4754  N[5] = 17;
4755  N[6] = 22;
4756  N[7] = 26;
4757  }
4758  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4759  {
4760  Lx = 2.0 - 2.0 * x;
4761  Ly = 2.0 - 2.0 * y;
4762  Lz = 1.0 - 2.0 * z;
4763 
4764  N[0] = 20;
4765  N[1] = 9;
4766  N[2] = 2;
4767  N[3] = 10;
4768  N[4] = 26;
4769  N[5] = 22;
4770  N[6] = 18;
4771  N[7] = 23;
4772  }
4773  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4774  {
4775  Lx = 1.0 - 2.0 * x;
4776  Ly = 2.0 - 2.0 * y;
4777  Lz = 1.0 - 2.0 * z;
4778 
4779  N[0] = 11;
4780  N[1] = 20;
4781  N[2] = 10;
4782  N[3] = 3;
4783  N[4] = 24;
4784  N[5] = 26;
4785  N[6] = 23;
4786  N[7] = 19;
4787  }
4788  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4789  {
4790  Lx = 1.0 - 2.0 * x;
4791  Ly = 1.0 - 2.0 * y;
4792  Lz = 2.0 - 2.0 * z;
4793 
4794  N[0] = 16;
4795  N[1] = 21;
4796  N[2] = 26;
4797  N[3] = 24;
4798  N[4] = 4;
4799  N[5] = 12;
4800  N[6] = 25;
4801  N[7] = 15;
4802  }
4803  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4804  {
4805  Lx = 2.0 - 2.0 * x;
4806  Ly = 1.0 - 2.0 * y;
4807  Lz = 2.0 - 2.0 * z;
4808 
4809  N[0] = 21;
4810  N[1] = 17;
4811  N[2] = 22;
4812  N[3] = 26;
4813  N[4] = 12;
4814  N[5] = 5;
4815  N[6] = 13;
4816  N[7] = 25;
4817  }
4818  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4819  {
4820  Lx = 2.0 - 2.0 * x;
4821  Ly = 2.0 - 2.0 * y;
4822  Lz = 2.0 - 2.0 * z;
4823 
4824  N[0] = 26;
4825  N[1] = 22;
4826  N[2] = 18;
4827  N[3] = 23;
4828  N[4] = 25;
4829  N[5] = 13;
4830  N[6] = 6;
4831  N[7] = 14;
4832  }
4833  else // T7
4834  {
4835  Lx = 1.0 - 2.0 * x;
4836  Ly = 2.0 - 2.0 * y;
4837  Lz = 2.0 - 2.0 * z;
4838 
4839  N[0] = 24;
4840  N[1] = 26;
4841  N[2] = 23;
4842  N[3] = 19;
4843  N[4] = 15;
4844  N[5] = 25;
4845  N[6] = 14;
4846  N[7] = 7;
4847  }
4848 
4849  shape(N[0]) = Lx * Ly * Lz;
4850  shape(N[1]) = (1 - Lx) * Ly * Lz;
4851  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
4852  shape(N[3]) = Lx * (1 - Ly) * Lz;
4853  shape(N[4]) = Lx * Ly * (1 - Lz);
4854  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
4855  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
4856  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
4857 }
4858 
4860  DenseMatrix &dshape) const
4861 {
4862  int i, j, N[8];
4863  double Lx, Ly, Lz;
4864  double x = ip.x, y = ip.y, z = ip.z;
4865 
4866  for (i = 0; i < 27; i++)
4867  for (j = 0; j < 3; j++)
4868  {
4869  dshape(i,j) = 0.0;
4870  }
4871 
4872  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4873  {
4874  Lx = 1.0 - 2.0 * x;
4875  Ly = 1.0 - 2.0 * y;
4876  Lz = 1.0 - 2.0 * z;
4877 
4878  N[0] = 0;
4879  N[1] = 8;
4880  N[2] = 20;
4881  N[3] = 11;
4882  N[4] = 16;
4883  N[5] = 21;
4884  N[6] = 26;
4885  N[7] = 24;
4886  }
4887  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4888  {
4889  Lx = 2.0 - 2.0 * x;
4890  Ly = 1.0 - 2.0 * y;
4891  Lz = 1.0 - 2.0 * z;
4892 
4893  N[0] = 8;
4894  N[1] = 1;
4895  N[2] = 9;
4896  N[3] = 20;
4897  N[4] = 21;
4898  N[5] = 17;
4899  N[6] = 22;
4900  N[7] = 26;
4901  }
4902  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4903  {
4904  Lx = 2.0 - 2.0 * x;
4905  Ly = 2.0 - 2.0 * y;
4906  Lz = 1.0 - 2.0 * z;
4907 
4908  N[0] = 20;
4909  N[1] = 9;
4910  N[2] = 2;
4911  N[3] = 10;
4912  N[4] = 26;
4913  N[5] = 22;
4914  N[6] = 18;
4915  N[7] = 23;
4916  }
4917  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4918  {
4919  Lx = 1.0 - 2.0 * x;
4920  Ly = 2.0 - 2.0 * y;
4921  Lz = 1.0 - 2.0 * z;
4922 
4923  N[0] = 11;
4924  N[1] = 20;
4925  N[2] = 10;
4926  N[3] = 3;
4927  N[4] = 24;
4928  N[5] = 26;
4929  N[6] = 23;
4930  N[7] = 19;
4931  }
4932  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4933  {
4934  Lx = 1.0 - 2.0 * x;
4935  Ly = 1.0 - 2.0 * y;
4936  Lz = 2.0 - 2.0 * z;
4937 
4938  N[0] = 16;
4939  N[1] = 21;
4940  N[2] = 26;
4941  N[3] = 24;
4942  N[4] = 4;
4943  N[5] = 12;
4944  N[6] = 25;
4945  N[7] = 15;
4946  }
4947  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4948  {
4949  Lx = 2.0 - 2.0 * x;
4950  Ly = 1.0 - 2.0 * y;
4951  Lz = 2.0 - 2.0 * z;
4952 
4953  N[0] = 21;
4954  N[1] = 17;
4955  N[2] = 22;
4956  N[3] = 26;
4957  N[4] = 12;
4958  N[5] = 5;
4959  N[6] = 13;
4960  N[7] = 25;
4961  }
4962  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4963  {
4964  Lx = 2.0 - 2.0 * x;
4965  Ly = 2.0 - 2.0 * y;
4966  Lz = 2.0 - 2.0 * z;
4967 
4968  N[0] = 26;
4969  N[1] = 22;
4970  N[2] = 18;
4971  N[3] = 23;
4972  N[4] = 25;
4973  N[5] = 13;
4974  N[6] = 6;
4975  N[7] = 14;
4976  }
4977  else // T7
4978  {
4979  Lx = 1.0 - 2.0 * x;
4980  Ly = 2.0 - 2.0 * y;
4981  Lz = 2.0 - 2.0 * z;
4982 
4983  N[0] = 24;
4984  N[1] = 26;
4985  N[2] = 23;
4986  N[3] = 19;
4987  N[4] = 15;
4988  N[5] = 25;
4989  N[6] = 14;
4990  N[7] = 7;
4991  }
4992 
4993  dshape(N[0],0) = -2.0 * Ly * Lz ;
4994  dshape(N[0],1) = -2.0 * Lx * Lz ;
4995  dshape(N[0],2) = -2.0 * Lx * Ly ;
4996 
4997  dshape(N[1],0) = 2.0 * Ly * Lz ;
4998  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
4999  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
5000 
5001  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
5002  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
5003  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
5004 
5005  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
5006  dshape(N[3],1) = 2.0 * Lx * Lz ;
5007  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
5008 
5009  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
5010  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
5011  dshape(N[4],2) = 2.0 * Lx * Ly ;
5012 
5013  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
5014  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
5015  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
5016 
5017  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
5018  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
5019  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
5020 
5021  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
5022  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
5023  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
5024 }
5025 
5026 
5028  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
5029 {
5030  // not real nodes ...
5031  Nodes.IntPoint(0).x = 0.5;
5032  Nodes.IntPoint(0).y = 0.0;
5033  Nodes.IntPoint(0).z = 0.0;
5034 
5035  Nodes.IntPoint(1).x = 1.0;
5036  Nodes.IntPoint(1).y = 0.5;
5037  Nodes.IntPoint(1).z = 0.0;
5038 
5039  Nodes.IntPoint(2).x = 0.5;
5040  Nodes.IntPoint(2).y = 1.0;
5041  Nodes.IntPoint(2).z = 0.0;
5042 
5043  Nodes.IntPoint(3).x = 0.0;
5044  Nodes.IntPoint(3).y = 0.5;
5045  Nodes.IntPoint(3).z = 0.0;
5046 
5047  Nodes.IntPoint(4).x = 0.5;
5048  Nodes.IntPoint(4).y = 0.0;
5049  Nodes.IntPoint(4).z = 1.0;
5050 
5051  Nodes.IntPoint(5).x = 1.0;
5052  Nodes.IntPoint(5).y = 0.5;
5053  Nodes.IntPoint(5).z = 1.0;
5054 
5055  Nodes.IntPoint(6).x = 0.5;
5056  Nodes.IntPoint(6).y = 1.0;
5057  Nodes.IntPoint(6).z = 1.0;
5058 
5059  Nodes.IntPoint(7).x = 0.0;
5060  Nodes.IntPoint(7).y = 0.5;
5061  Nodes.IntPoint(7).z = 1.0;
5062 
5063  Nodes.IntPoint(8).x = 0.0;
5064  Nodes.IntPoint(8).y = 0.0;
5065  Nodes.IntPoint(8).z = 0.5;
5066 
5067  Nodes.IntPoint(9).x = 1.0;
5068  Nodes.IntPoint(9).y = 0.0;
5069  Nodes.IntPoint(9).z = 0.5;
5070 
5071  Nodes.IntPoint(10).x= 1.0;
5072  Nodes.IntPoint(10).y= 1.0;
5073  Nodes.IntPoint(10).z= 0.5;
5074 
5075  Nodes.IntPoint(11).x= 0.0;
5076  Nodes.IntPoint(11).y= 1.0;
5077  Nodes.IntPoint(11).z= 0.5;
5078 }
5079 
5081  DenseMatrix &shape) const
5082 {
5083  double x = ip.x, y = ip.y, z = ip.z;
5084 
5085  shape(0,0) = (1. - y) * (1. - z);
5086  shape(0,1) = 0.;
5087  shape(0,2) = 0.;
5088 
5089  shape(2,0) = y * (1. - z);
5090  shape(2,1) = 0.;
5091  shape(2,2) = 0.;
5092 
5093  shape(4,0) = z * (1. - y);
5094  shape(4,1) = 0.;
5095  shape(4,2) = 0.;
5096 
5097  shape(6,0) = y * z;
5098  shape(6,1) = 0.;
5099  shape(6,2) = 0.;
5100 
5101  shape(1,0) = 0.;
5102  shape(1,1) = x * (1. - z);
5103  shape(1,2) = 0.;
5104 
5105  shape(3,0) = 0.;
5106  shape(3,1) = (1. - x) * (1. - z);
5107  shape(3,2) = 0.;
5108 
5109  shape(5,0) = 0.;
5110  shape(5,1) = x * z;
5111  shape(5,2) = 0.;
5112 
5113  shape(7,0) = 0.;
5114  shape(7,1) = (1. - x) * z;
5115  shape(7,2) = 0.;
5116 
5117  shape(8,0) = 0.;
5118  shape(8,1) = 0.;
5119  shape(8,2) = (1. - x) * (1. - y);
5120 
5121  shape(9,0) = 0.;
5122  shape(9,1) = 0.;
5123  shape(9,2) = x * (1. - y);
5124 
5125  shape(10,0) = 0.;
5126  shape(10,1) = 0.;
5127  shape(10,2) = x * y;
5128 
5129  shape(11,0) = 0.;
5130  shape(11,1) = 0.;
5131  shape(11,2) = y * (1. - x);
5132 
5133 }
5134 
5136  DenseMatrix &curl_shape)
5137 const
5138 {
5139  double x = ip.x, y = ip.y, z = ip.z;
5140 
5141  curl_shape(0,0) = 0.;
5142  curl_shape(0,1) = y - 1.;
5143  curl_shape(0,2) = 1. - z;
5144 
5145  curl_shape(2,0) = 0.;
5146  curl_shape(2,1) = -y;
5147  curl_shape(2,2) = z - 1.;
5148 
5149  curl_shape(4,0) = 0;
5150  curl_shape(4,1) = 1. - y;
5151  curl_shape(4,2) = z;
5152 
5153  curl_shape(6,0) = 0.;
5154  curl_shape(6,1) = y;
5155  curl_shape(6,2) = -z;
5156 
5157  curl_shape(1,0) = x;
5158  curl_shape(1,1) = 0.;
5159  curl_shape(1,2) = 1. - z;
5160 
5161  curl_shape(3,0) = 1. - x;
5162  curl_shape(3,1) = 0.;
5163  curl_shape(3,2) = z - 1.;
5164 
5165  curl_shape(5,0) = -x;
5166  curl_shape(5,1) = 0.;
5167  curl_shape(5,2) = z;
5168 
5169  curl_shape(7,0) = x - 1.;
5170  curl_shape(7,1) = 0.;
5171  curl_shape(7,2) = -z;
5172 
5173  curl_shape(8,0) = x - 1.;
5174  curl_shape(8,1) = 1. - y;
5175  curl_shape(8,2) = 0.;
5176 
5177  curl_shape(9,0) = -x;
5178  curl_shape(9,1) = y - 1.;
5179  curl_shape(9,2) = 0;
5180 
5181  curl_shape(10,0) = x;
5182  curl_shape(10,1) = -y;
5183  curl_shape(10,2) = 0.;
5184 
5185  curl_shape(11,0) = 1. - x;
5186  curl_shape(11,1) = y;
5187  curl_shape(11,2) = 0.;
5188 }
5189 
5190 const double Nedelec1HexFiniteElement::tk[12][3] =
5191 {
5192  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5193  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5194  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
5195 };
5196 
5199 {
5200  int k, j;
5201 #ifdef MFEM_THREAD_SAFE
5203 #endif
5204 
5205 #ifdef MFEM_DEBUG
5206  for (k = 0; k < 12; k++)
5207  {
5209  for (j = 0; j < 12; j++)
5210  {
5211  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5212  vshape(j,2)*tk[k][2] );
5213  if (j == k) { d -= 1.0; }
5214  if (fabs(d) > 1.0e-12)
5215  {
5216  mfem::err << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
5217  " k = " << k << ", j = " << j << ", d = " << d << endl;
5218  mfem_error();
5219  }
5220  }
5221  }
5222 #endif
5223 
5224  IntegrationPoint ip;
5225  ip.x = ip.y = ip.z = 0.0;
5226  Trans.SetIntPoint (&ip);
5227  // Trans must be linear (more to have embedding?)
5228  const DenseMatrix &J = Trans.Jacobian();
5229  double vk[3];
5230  Vector xk (vk, 3);
5231 
5232  for (k = 0; k < 12; k++)
5233  {
5234  Trans.Transform (Nodes.IntPoint (k), xk);
5235  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5236  CalcVShape (ip, vshape);
5237  // vk = J tk
5238  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5239  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5240  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5241  for (j = 0; j < 12; j++)
5242  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5243  vshape(j,2)*vk[2])) < 1.0e-12)
5244  {
5245  I(k,j) = 0.0;
5246  }
5247  }
5248 }
5249 
5252  Vector &dofs) const
5253 {
5254  double vk[3];
5255  Vector xk (vk, 3);
5256 
5257  for (int k = 0; k < 12; k++)
5258  {
5259  Trans.SetIntPoint (&Nodes.IntPoint (k));
5260  const DenseMatrix &J = Trans.Jacobian();
5261 
5262  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5263  // xk^t J tk
5264  dofs(k) =
5265  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5266  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5267  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5268  }
5269 }
5270 
5271 
5273  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
5274 {
5275  // not real nodes ...
5276  Nodes.IntPoint(0).x = 0.5;
5277  Nodes.IntPoint(0).y = 0.0;
5278  Nodes.IntPoint(0).z = 0.0;
5279 
5280  Nodes.IntPoint(1).x = 0.0;
5281  Nodes.IntPoint(1).y = 0.5;
5282  Nodes.IntPoint(1).z = 0.0;
5283 
5284  Nodes.IntPoint(2).x = 0.0;
5285  Nodes.IntPoint(2).y = 0.0;
5286  Nodes.IntPoint(2).z = 0.5;
5287 
5288  Nodes.IntPoint(3).x = 0.5;
5289  Nodes.IntPoint(3).y = 0.5;
5290  Nodes.IntPoint(3).z = 0.0;
5291 
5292  Nodes.IntPoint(4).x = 0.5;
5293  Nodes.IntPoint(4).y = 0.0;
5294  Nodes.IntPoint(4).z = 0.5;
5295 
5296  Nodes.IntPoint(5).x = 0.0;
5297  Nodes.IntPoint(5).y = 0.5;
5298  Nodes.IntPoint(5).z = 0.5;
5299 }
5300 
5302  DenseMatrix &shape) const
5303 {
5304  double x = ip.x, y = ip.y, z = ip.z;
5305 
5306  shape(0,0) = 1. - y - z;
5307  shape(0,1) = x;
5308  shape(0,2) = x;
5309 
5310  shape(1,0) = y;
5311  shape(1,1) = 1. - x - z;
5312  shape(1,2) = y;
5313 
5314  shape(2,0) = z;
5315  shape(2,1) = z;
5316  shape(2,2) = 1. - x - y;
5317 
5318  shape(3,0) = -y;
5319  shape(3,1) = x;
5320  shape(3,2) = 0.;
5321 
5322  shape(4,0) = -z;
5323  shape(4,1) = 0.;
5324  shape(4,2) = x;
5325 
5326  shape(5,0) = 0.;
5327  shape(5,1) = -z;
5328  shape(5,2) = y;
5329 }
5330 
5332  DenseMatrix &curl_shape)
5333 const
5334 {
5335  curl_shape(0,0) = 0.;
5336  curl_shape(0,1) = -2.;
5337  curl_shape(0,2) = 2.;
5338 
5339  curl_shape(1,0) = 2.;
5340  curl_shape(1,1) = 0.;
5341  curl_shape(1,2) = -2.;
5342 
5343  curl_shape(2,0) = -2.;
5344  curl_shape(2,1) = 2.;
5345  curl_shape(2,2) = 0.;
5346 
5347  curl_shape(3,0) = 0.;
5348  curl_shape(3,1) = 0.;
5349  curl_shape(3,2) = 2.;
5350 
5351  curl_shape(4,0) = 0.;
5352  curl_shape(4,1) = -2.;
5353  curl_shape(4,2) = 0.;
5354 
5355  curl_shape(5,0) = 2.;
5356  curl_shape(5,1) = 0.;
5357  curl_shape(5,2) = 0.;
5358 }
5359 
5360 const double Nedelec1TetFiniteElement::tk[6][3] =
5361 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
5362 
5365 {
5366  int k, j;
5367 #ifdef MFEM_THREAD_SAFE
5369 #endif
5370 
5371 #ifdef MFEM_DEBUG
5372  for (k = 0; k < 6; k++)
5373  {
5375  for (j = 0; j < 6; j++)
5376  {
5377  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5378  vshape(j,2)*tk[k][2] );
5379  if (j == k) { d -= 1.0; }
5380  if (fabs(d) > 1.0e-12)
5381  {
5382  mfem::err << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
5383  " k = " << k << ", j = " << j << ", d = " << d << endl;
5384  mfem_error();
5385  }
5386  }
5387  }
5388 #endif
5389 
5390  IntegrationPoint ip;
5391  ip.x = ip.y = ip.z = 0.0;
5392  Trans.SetIntPoint (&ip);
5393  // Trans must be linear
5394  const DenseMatrix &J = Trans.Jacobian();
5395  double vk[3];
5396  Vector xk (vk, 3);
5397 
5398  for (k = 0; k < 6; k++)
5399  {
5400  Trans.Transform (Nodes.IntPoint (k), xk);
5401  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5402  CalcVShape (ip, vshape);
5403  // vk = J tk
5404  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5405  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5406  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5407  for (j = 0; j < 6; j++)
5408  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5409  vshape(j,2)*vk[2])) < 1.0e-12)
5410  {
5411  I(k,j) = 0.0;
5412  }
5413  }
5414 }
5415 
5418  Vector &dofs) const
5419 {
5420  double vk[3];
5421  Vector xk (vk, 3);
5422 
5423  for (int k = 0; k < 6; k++)
5424  {
5425  Trans.SetIntPoint (&Nodes.IntPoint (k));
5426  const DenseMatrix &J = Trans.Jacobian();
5427 
5428  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5429  // xk^t J tk
5430  dofs(k) =
5431  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5432  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5433  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5434  }
5435 }
5436 
5438  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
5439 {
5440  // not real nodes ...
5441  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
5442  Nodes.IntPoint(0).x = 0.5;
5443  Nodes.IntPoint(0).y = 0.5;
5444  Nodes.IntPoint(0).z = 0.0;
5445 
5446  Nodes.IntPoint(1).x = 0.5;
5447  Nodes.IntPoint(1).y = 0.0;
5448  Nodes.IntPoint(1).z = 0.5;
5449 
5450  Nodes.IntPoint(2).x = 1.0;
5451  Nodes.IntPoint(2).y = 0.5;
5452  Nodes.IntPoint(2).z = 0.5;
5453 
5454  Nodes.IntPoint(3).x = 0.5;
5455  Nodes.IntPoint(3).y = 1.0;
5456  Nodes.IntPoint(3).z = 0.5;
5457 
5458  Nodes.IntPoint(4).x = 0.0;
5459  Nodes.IntPoint(4).y = 0.5;
5460  Nodes.IntPoint(4).z = 0.5;
5461 
5462  Nodes.IntPoint(5).x = 0.5;
5463  Nodes.IntPoint(5).y = 0.5;
5464  Nodes.IntPoint(5).z = 1.0;
5465 }
5466 
5468  DenseMatrix &shape) const
5469 {
5470  double x = ip.x, y = ip.y, z = ip.z;
5471  // z = 0
5472  shape(0,0) = 0.;
5473  shape(0,1) = 0.;
5474  shape(0,2) = z - 1.;
5475  // y = 0
5476  shape(1,0) = 0.;
5477  shape(1,1) = y - 1.;
5478  shape(1,2) = 0.;
5479  // x = 1
5480  shape(2,0) = x;
5481  shape(2,1) = 0.;
5482  shape(2,2) = 0.;
5483  // y = 1
5484  shape(3,0) = 0.;
5485  shape(3,1) = y;
5486  shape(3,2) = 0.;
5487  // x = 0
5488  shape(4,0) = x - 1.;
5489  shape(4,1) = 0.;
5490  shape(4,2) = 0.;
5491  // z = 1
5492  shape(5,0) = 0.;
5493  shape(5,1) = 0.;
5494  shape(5,2) = z;
5495 }
5496 
5498  Vector &divshape) const
5499 {
5500  divshape(0) = 1.;
5501  divshape(1) = 1.;
5502  divshape(2) = 1.;
5503  divshape(3) = 1.;
5504  divshape(4) = 1.;
5505  divshape(5) = 1.;
5506 }
5507 
5508 const double RT0HexFiniteElement::nk[6][3] =
5509 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
5510 
5513 {
5514  int k, j;
5515 #ifdef MFEM_THREAD_SAFE
5517  DenseMatrix Jinv(Dim);
5518 #endif
5519 
5520 #ifdef MFEM_DEBUG
5521  for (k = 0; k < 6; k++)
5522  {
5524  for (j = 0; j < 6; j++)
5525  {
5526  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5527  vshape(j,2)*nk[k][2] );
5528  if (j == k) { d -= 1.0; }
5529  if (fabs(d) > 1.0e-12)
5530  {
5531  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5532  " k = " << k << ", j = " << j << ", d = " << d << endl;
5533  mfem_error();
5534  }
5535  }
5536  }
5537 #endif
5538 
5539  IntegrationPoint ip;
5540  ip.x = ip.y = ip.z = 0.0;
5541  Trans.SetIntPoint (&ip);
5542  // Trans must be linear
5543  // set Jinv = |J| J^{-t} = adj(J)^t
5544  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5545  double vk[3];
5546  Vector xk (vk, 3);
5547 
5548  for (k = 0; k < 6; k++)
5549  {
5550  Trans.Transform (Nodes.IntPoint (k), xk);
5551  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5552  CalcVShape (ip, vshape);
5553  // vk = |J| J^{-t} nk
5554  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5555  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5556  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5557  for (j = 0; j < 6; j++)
5558  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5559  vshape(j,2)*vk[2])) < 1.0e-12)
5560  {
5561  I(k,j) = 0.0;
5562  }
5563  }
5564 }
5565 
5568  Vector &dofs) const
5569 {
5570  double vk[3];
5571  Vector xk (vk, 3);
5572 #ifdef MFEM_THREAD_SAFE
5573  DenseMatrix Jinv(Dim);
5574 #endif
5575 
5576  for (int k = 0; k < 6; k++)
5577  {
5578  Trans.SetIntPoint (&Nodes.IntPoint (k));
5579  // set Jinv = |J| J^{-t} = adj(J)^t
5580  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5581 
5582  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5583  // xk^t |J| J^{-t} nk
5584  dofs(k) =
5585  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5586  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5587  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5588  }
5589 }
5590 
5592  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
5593 {
5594  // z = 0
5595  Nodes.IntPoint(2).x = 1./3.;
5596  Nodes.IntPoint(2).y = 1./3.;
5597  Nodes.IntPoint(2).z = 0.0;
5598  Nodes.IntPoint(3).x = 2./3.;
5599  Nodes.IntPoint(3).y = 1./3.;
5600  Nodes.IntPoint(3).z = 0.0;
5601  Nodes.IntPoint(0).x = 1./3.;
5602  Nodes.IntPoint(0).y = 2./3.;
5603  Nodes.IntPoint(0).z = 0.0;
5604  Nodes.IntPoint(1).x = 2./3.;
5605  Nodes.IntPoint(1).y = 2./3.;
5606  Nodes.IntPoint(1).z = 0.0;
5607  // y = 0
5608  Nodes.IntPoint(4).x = 1./3.;
5609  Nodes.IntPoint(4).y = 0.0;
5610  Nodes.IntPoint(4).z = 1./3.;
5611  Nodes.IntPoint(5).x = 2./3.;
5612  Nodes.IntPoint(5).y = 0.0;
5613  Nodes.IntPoint(5).z = 1./3.;
5614  Nodes.IntPoint(6).x = 1./3.;
5615  Nodes.IntPoint(6).y = 0.0;
5616  Nodes.IntPoint(6).z = 2./3.;
5617  Nodes.IntPoint(7).x = 2./3.;
5618  Nodes.IntPoint(7).y = 0.0;
5619  Nodes.IntPoint(7).z = 2./3.;
5620  // x = 1
5621  Nodes.IntPoint(8).x = 1.0;
5622  Nodes.IntPoint(8).y = 1./3.;
5623  Nodes.IntPoint(8).z = 1./3.;
5624  Nodes.IntPoint(9).x = 1.0;
5625  Nodes.IntPoint(9).y = 2./3.;
5626  Nodes.IntPoint(9).z = 1./3.;
5627  Nodes.IntPoint(10).x = 1.0;
5628  Nodes.IntPoint(10).y = 1./3.;
5629  Nodes.IntPoint(10).z = 2./3.;
5630  Nodes.IntPoint(11).x = 1.0;
5631  Nodes.IntPoint(11).y = 2./3.;
5632  Nodes.IntPoint(11).z = 2./3.;
5633  // y = 1
5634  Nodes.IntPoint(13).x = 1./3.;
5635  Nodes.IntPoint(13).y = 1.0;
5636  Nodes.IntPoint(13).z = 1./3.;
5637  Nodes.IntPoint(12).x = 2./3.;
5638  Nodes.IntPoint(12).y = 1.0;
5639  Nodes.IntPoint(12).z = 1./3.;
5640  Nodes.IntPoint(15).x = 1./3.;
5641  Nodes.IntPoint(15).y = 1.0;
5642  Nodes.IntPoint(15).z = 2./3.;
5643  Nodes.IntPoint(14).x = 2./3.;
5644  Nodes.IntPoint(14).y = 1.0;
5645  Nodes.IntPoint(14).z = 2./3.;
5646  // x = 0
5647  Nodes.IntPoint(17).x = 0.0;
5648  Nodes.IntPoint(17).y = 1./3.;
5649  Nodes.IntPoint(17).z = 1./3.;
5650  Nodes.IntPoint(16).x = 0.0;
5651  Nodes.IntPoint(16).y = 2./3.;
5652  Nodes.IntPoint(16).z = 1./3.;
5653  Nodes.IntPoint(19).x = 0.0;
5654  Nodes.IntPoint(19).y = 1./3.;
5655  Nodes.IntPoint(19).z = 2./3.;
5656  Nodes.IntPoint(18).x = 0.0;
5657  Nodes.IntPoint(18).y = 2./3.;
5658  Nodes.IntPoint(18).z = 2./3.;
5659  // z = 1
5660  Nodes.IntPoint(20).x = 1./3.;
5661  Nodes.IntPoint(20).y = 1./3.;
5662  Nodes.IntPoint(20).z = 1.0;
5663  Nodes.IntPoint(21).x = 2./3.;
5664  Nodes.IntPoint(21).y = 1./3.;
5665  Nodes.IntPoint(21).z = 1.0;
5666  Nodes.IntPoint(22).x = 1./3.;
5667  Nodes.IntPoint(22).y = 2./3.;
5668  Nodes.IntPoint(22).z = 1.0;
5669  Nodes.IntPoint(23).x = 2./3.;
5670  Nodes.IntPoint(23).y = 2./3.;
5671  Nodes.IntPoint(23).z = 1.0;
5672  // x = 0.5 (interior)
5673  Nodes.IntPoint(24).x = 0.5;
5674  Nodes.IntPoint(24).y = 1./3.;
5675  Nodes.IntPoint(24).z = 1./3.;
5676  Nodes.IntPoint(25).x = 0.5;
5677  Nodes.IntPoint(25).y = 1./3.;
5678  Nodes.IntPoint(25).z = 2./3.;
5679  Nodes.IntPoint(26).x = 0.5;
5680  Nodes.IntPoint(26).y = 2./3.;
5681  Nodes.IntPoint(26).z = 1./3.;
5682  Nodes.IntPoint(27).x = 0.5;
5683  Nodes.IntPoint(27).y = 2./3.;
5684  Nodes.IntPoint(27).z = 2./3.;
5685  // y = 0.5 (interior)
5686  Nodes.IntPoint(28).x = 1./3.;
5687  Nodes.IntPoint(28).y = 0.5;
5688  Nodes.IntPoint(28).z = 1./3.;
5689  Nodes.IntPoint(29).x = 1./3.;
5690  Nodes.IntPoint(29).y = 0.5;
5691  Nodes.IntPoint(29).z = 2./3.;
5692  Nodes.IntPoint(30).x = 2./3.;
5693  Nodes.IntPoint(30).y = 0.5;
5694  Nodes.IntPoint(30).z = 1./3.;
5695  Nodes.IntPoint(31).x = 2./3.;
5696  Nodes.IntPoint(31).y = 0.5;
5697  Nodes.IntPoint(31).z = 2./3.;
5698  // z = 0.5 (interior)
5699  Nodes.IntPoint(32).x = 1./3.;
5700  Nodes.IntPoint(32).y = 1./3.;
5701  Nodes.IntPoint(32).z = 0.5;
5702  Nodes.IntPoint(33).x = 1./3.;
5703  Nodes.IntPoint(33).y = 2./3.;
5704  Nodes.IntPoint(33).z = 0.5;
5705  Nodes.IntPoint(34).x = 2./3.;
5706  Nodes.IntPoint(34).y = 1./3.;
5707  Nodes.IntPoint(34).z = 0.5;
5708  Nodes.IntPoint(35).x = 2./3.;
5709  Nodes.IntPoint(35).y = 2./3.;
5710  Nodes.IntPoint(35).z = 0.5;
5711 }
5712 
5714  DenseMatrix &shape) const
5715 {
5716  double x = ip.x, y = ip.y, z = ip.z;
5717  // z = 0
5718  shape(2,0) = 0.;
5719  shape(2,1) = 0.;
5720  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5721  shape(3,0) = 0.;
5722  shape(3,1) = 0.;
5723  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5724  shape(0,0) = 0.;
5725  shape(0,1) = 0.;
5726  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5727  shape(1,0) = 0.;
5728  shape(1,1) = 0.;
5729  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5730  // y = 0
5731  shape(4,0) = 0.;
5732  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5733  shape(4,2) = 0.;
5734  shape(5,0) = 0.;
5735  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5736  shape(5,2) = 0.;
5737  shape(6,0) = 0.;
5738  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5739  shape(6,2) = 0.;
5740  shape(7,0) = 0.;
5741  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5742  shape(7,2) = 0.;
5743  // x = 1
5744  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5745  shape(8,1) = 0.;
5746  shape(8,2) = 0.;
5747  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5748  shape(9,1) = 0.;
5749  shape(9,2) = 0.;
5750  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5751  shape(10,1) = 0.;
5752  shape(10,2) = 0.;
5753  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5754  shape(11,1) = 0.;
5755  shape(11,2) = 0.;
5756  // y = 1
5757  shape(13,0) = 0.;
5758  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5759  shape(13,2) = 0.;
5760  shape(12,0) = 0.;
5761  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5762  shape(12,2) = 0.;
5763  shape(15,0) = 0.;
5764  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5765  shape(15,2) = 0.;
5766  shape(14,0) = 0.;
5767  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5768  shape(14,2) = 0.;
5769  // x = 0
5770  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5771  shape(17,1) = 0.;
5772  shape(17,2) = 0.;
5773  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5774  shape(16,1) = 0.;
5775  shape(16,2) = 0.;
5776  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5777  shape(19,1) = 0.;
5778  shape(19,2) = 0.;
5779  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5780  shape(18,1) = 0.;
5781  shape(18,2) = 0.;
5782  // z = 1
5783  shape(20,0) = 0.;
5784  shape(20,1) = 0.;
5785  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5786  shape(21,0) = 0.;
5787  shape(21,1) = 0.;
5788  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5789  shape(22,0) = 0.;
5790  shape(22,1) = 0.;
5791  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5792  shape(23,0) = 0.;
5793  shape(23,1) = 0.;
5794  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5795  // x = 0.5 (interior)
5796  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5797  shape(24,1) = 0.;
5798  shape(24,2) = 0.;
5799  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5800  shape(25,1) = 0.;
5801  shape(25,2) = 0.;
5802  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5803  shape(26,1) = 0.;
5804  shape(26,2) = 0.;
5805  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5806  shape(27,1) = 0.;
5807  shape(27,2) = 0.;
5808  // y = 0.5 (interior)
5809  shape(28,0) = 0.;
5810  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5811  shape(28,2) = 0.;
5812  shape(29,0) = 0.;
5813  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5814  shape(29,2) = 0.;
5815  shape(30,0) = 0.;
5816  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5817  shape(30,2) = 0.;
5818  shape(31,0) = 0.;
5819  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5820  shape(31,2) = 0.;
5821  // z = 0.5 (interior)
5822  shape(32,0) = 0.;
5823  shape(32,1) = 0.;
5824  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5825  shape(33,0) = 0.;
5826  shape(33,1) = 0.;
5827  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5828  shape(34,0) = 0.;
5829  shape(34,1) = 0.;
5830  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5831  shape(35,0) = 0.;
5832  shape(35,1) = 0.;
5833  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5834 }
5835 
5837  Vector &divshape) const
5838 {
5839  double x = ip.x, y = ip.y, z = ip.z;
5840  // z = 0
5841  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5842  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5843  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5844  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5845  // y = 0
5846  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5847  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5848  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5849  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5850  // x = 1
5851  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5852  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5853  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5854  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5855  // y = 1
5856  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5857  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5858  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5859  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5860  // x = 0
5861  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5862  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5863  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5864  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5865  // z = 1
5866  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5867  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5868  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5869  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5870  // x = 0.5 (interior)
5871  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5872  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5873  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5874  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5875  // y = 0.5 (interior)
5876  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5877  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5878  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5879  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5880  // z = 0.5 (interior)
5881  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5882  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5883  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5884  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5885 }
5886 
5887 const double RT1HexFiniteElement::nk[36][3] =
5888 {
5889  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
5890  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
5891  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5892  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5893  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
5894  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
5895  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5896  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5897  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
5898 };
5899 
5902 {
5903  int k, j;
5904 #ifdef MFEM_THREAD_SAFE
5906  DenseMatrix Jinv(Dim);
5907 #endif
5908 
5909 #ifdef MFEM_DEBUG
5910  for (k = 0; k < 36; k++)
5911  {
5913  for (j = 0; j < 36; j++)
5914  {
5915  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5916  vshape(j,2)*nk[k][2] );
5917  if (j == k) { d -= 1.0; }
5918  if (fabs(d) > 1.0e-12)
5919  {
5920  mfem::err << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5921  " k = " << k << ", j = " << j << ", d = " << d << endl;
5922  mfem_error();
5923  }
5924  }
5925  }
5926 #endif
5927 
5928  IntegrationPoint ip;
5929  ip.x = ip.y = ip.z = 0.0;
5930  Trans.SetIntPoint (&ip);
5931  // Trans must be linear
5932  // set Jinv = |J| J^{-t} = adj(J)^t
5933  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5934  double vk[3];
5935  Vector xk (vk, 3);
5936 
5937  for (k = 0; k < 36; k++)
5938  {
5939  Trans.Transform (Nodes.IntPoint (k), xk);
5940  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5941  CalcVShape (ip, vshape);
5942  // vk = |J| J^{-t} nk
5943  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5944  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5945  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5946  for (j = 0; j < 36; j++)
5947  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5948  vshape(j,2)*vk[2])) < 1.0e-12)
5949  {
5950  I(k,j) = 0.0;
5951  }
5952  }
5953 }
5954 
5957  Vector &dofs) const
5958 {
5959  double vk[3];
5960  Vector xk (vk, 3);
5961 #ifdef MFEM_THREAD_SAFE
5962  DenseMatrix Jinv(Dim);
5963 #endif
5964 
5965  for (int k = 0; k < 36; k++)
5966  {
5967  Trans.SetIntPoint (&Nodes.IntPoint (k));
5968  // set Jinv = |J| J^{-t} = adj(J)^t
5969  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5970 
5971  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5972  // xk^t |J| J^{-t} nk
5973  dofs(k) =
5974  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5975  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5976  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5977  }
5978 }
5979 
5981  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
5982 {
5983  // not real nodes ...
5984  Nodes.IntPoint(0).x = 0.33333333333333333333;
5985  Nodes.IntPoint(0).y = 0.33333333333333333333;
5986  Nodes.IntPoint(0).z = 0.33333333333333333333;
5987 
5988  Nodes.IntPoint(1).x = 0.0;
5989  Nodes.IntPoint(1).y = 0.33333333333333333333;
5990  Nodes.IntPoint(1).z = 0.33333333333333333333;
5991 
5992  Nodes.IntPoint(2).x = 0.33333333333333333333;
5993  Nodes.IntPoint(2).y = 0.0;
5994  Nodes.IntPoint(2).z = 0.33333333333333333333;
5995 
5996  Nodes.IntPoint(3).x = 0.33333333333333333333;
5997  Nodes.IntPoint(3).y = 0.33333333333333333333;
5998  Nodes.IntPoint(3).z = 0.0;
5999 }
6000 
6002  DenseMatrix &shape) const
6003 {
6004  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
6005 
6006  shape(0,0) = x2;
6007  shape(0,1) = y2;
6008  shape(0,2) = z2;
6009 
6010  shape(1,0) = x2 - 2.0;
6011  shape(1,1) = y2;
6012  shape(1,2) = z2;
6013 
6014  shape(2,0) = x2;
6015  shape(2,1) = y2 - 2.0;
6016  shape(2,2) = z2;
6017 
6018  shape(3,0) = x2;
6019  shape(3,1) = y2;
6020  shape(3,2) = z2 - 2.0;
6021 }
6022 
6024  Vector &divshape) const
6025 {
6026  divshape(0) = 6.0;
6027  divshape(1) = 6.0;
6028  divshape(2) = 6.0;
6029  divshape(3) = 6.0;
6030 }
6031 
6032 const double RT0TetFiniteElement::nk[4][3] =
6033 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
6034 
6037 {
6038  int k, j;
6039 #ifdef MFEM_THREAD_SAFE
6041  DenseMatrix Jinv(Dim);
6042 #endif
6043 
6044 #ifdef MFEM_DEBUG
6045  for (k = 0; k < 4; k++)
6046  {
6048  for (j = 0; j < 4; j++)
6049  {
6050  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
6051  vshape(j,2)*nk[k][2] );
6052  if (j == k) { d -= 1.0; }
6053  if (fabs(d) > 1.0e-12)
6054  {
6055  mfem::err << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
6056  " k = " << k << ", j = " << j << ", d = " << d << endl;
6057  mfem_error();
6058  }
6059  }
6060  }
6061 #endif
6062 
6063  IntegrationPoint ip;
6064  ip.x = ip.y = ip.z = 0.0;
6065  Trans.SetIntPoint (&ip);
6066  // Trans must be linear
6067  // set Jinv = |J| J^{-t} = adj(J)^t
6068  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6069  double vk[3];
6070  Vector xk (vk, 3);
6071 
6072  for (k = 0; k < 4; k++)
6073  {
6074  Trans.Transform (Nodes.IntPoint (k), xk);
6075  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
6076  CalcVShape (ip, vshape);
6077  // vk = |J| J^{-t} nk
6078  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
6079  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
6080  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
6081  for (j = 0; j < 4; j++)
6082  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
6083  vshape(j,2)*vk[2])) < 1.0e-12)
6084  {
6085  I(k,j) = 0.0;
6086  }
6087  }
6088 }
6089 
6092  Vector &dofs) const
6093 {
6094  double vk[3];
6095  Vector xk (vk, 3);
6096 #ifdef MFEM_THREAD_SAFE
6097  DenseMatrix Jinv(Dim);
6098 #endif
6099 
6100  for (int k = 0; k < 4; k++)
6101  {
6102  Trans.SetIntPoint (&Nodes.IntPoint (k));
6103  // set Jinv = |J| J^{-t} = adj(J)^t
6104  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6105 
6106  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6107  // xk^t |J| J^{-t} nk
6108  dofs(k) =
6109  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6110  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6111  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6112  }
6113 }
6114 
6116  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
6117 {
6118  Nodes.IntPoint(0).x = 0.5;
6119  Nodes.IntPoint(0).y = 0.5;
6120  Nodes.IntPoint(0).z = 0.0;
6121 
6122  Nodes.IntPoint(1).x = 0.5;
6123  Nodes.IntPoint(1).y = 0.0;
6124  Nodes.IntPoint(1).z = 0.5;
6125 
6126  Nodes.IntPoint(2).x = 1.0;
6127  Nodes.IntPoint(2).y = 0.5;
6128  Nodes.IntPoint(2).z = 0.5;
6129 
6130  Nodes.IntPoint(3).x = 0.5;
6131  Nodes.IntPoint(3).y = 1.0;
6132  Nodes.IntPoint(3).z = 0.5;
6133 
6134  Nodes.IntPoint(4).x = 0.0;
6135  Nodes.IntPoint(4).y = 0.5;
6136  Nodes.IntPoint(4).z = 0.5;
6137 
6138  Nodes.IntPoint(5).x = 0.5;
6139  Nodes.IntPoint(5).y = 0.5;
6140  Nodes.IntPoint(5).z = 1.0;
6141 }
6142 
6144  Vector &shape) const
6145 {
6146  double x = 2. * ip.x - 1.;
6147  double y = 2. * ip.y - 1.;
6148  double z = 2. * ip.z - 1.;
6149  double f5 = x * x - y * y;
6150  double f6 = y * y - z * z;
6151 
6152  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
6153  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
6154  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
6155  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
6156  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
6157  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
6158 }
6159 
6161  DenseMatrix &dshape) const
6162 {
6163  const double a = 2./3.;
6164 
6165  double xt = a * (1. - 2. * ip.x);
6166  double yt = a * (1. - 2. * ip.y);
6167  double zt = a * (1. - 2. * ip.z);
6168 
6169  dshape(0,0) = xt;
6170  dshape(0,1) = yt;
6171  dshape(0,2) = -1. - 2. * zt;
6172 
6173  dshape(1,0) = xt;
6174  dshape(1,1) = -1. - 2. * yt;
6175  dshape(1,2) = zt;
6176 
6177  dshape(2,0) = 1. - 2. * xt;
6178  dshape(2,1) = yt;
6179  dshape(2,2) = zt;
6180 
6181  dshape(3,0) = xt;
6182  dshape(3,1) = 1. - 2. * yt;
6183  dshape(3,2) = zt;
6184 
6185  dshape(4,0) = -1. - 2. * xt;
6186  dshape(4,1) = yt;
6187  dshape(4,2) = zt;
6188 
6189  dshape(5,0) = xt;
6190  dshape(5,1) = yt;
6191  dshape(5,2) = 1. - 2. * zt;
6192 }
6193 
6194 
6195 Poly_1D::Basis::Basis(const int p, const double *nodes, EvalType etype)
6196  : etype(etype)
6197 {
6198  switch (etype)
6199  {
6200  case ChangeOfBasis:
6201  {
6202  x.SetSize(p + 1);
6203  w.SetSize(p + 1);
6204  DenseMatrix A(p + 1);
6205  for (int i = 0; i <= p; i++)
6206  {
6207  CalcBasis(p, nodes[i], A.GetColumn(i));
6208  }
6209  Ai.Factor(A);
6210  // mfem::out << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
6211  break;
6212  }
6213  case Barycentric:
6214  {
6215  x.SetSize(p + 1);
6216  w.SetSize(p + 1);
6217  x = nodes;
6218  w = 1.0;
6219  for (int i = 0; i <= p; i++)
6220  {
6221  for (int j = 0; j < i; j++)
6222  {
6223  double xij = x(i) - x(j);
6224  w(i) *= xij;
6225  w(j) *= -xij;
6226  }
6227  }
6228  for (int i = 0; i <= p; i++)
6229  {
6230  w(i) = 1.0/w(i);
6231  }
6232 
6233 #ifdef MFEM_DEBUG
6234  // Make sure the nodes are increasing
6235  for (int i = 0; i < p; i++)
6236  {
6237  if (x(i) >= x(i+1))
6238  {
6239  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
6240  }
6241  }
6242 #endif
6243  break;
6244  }
6245  case Positive:
6246  x.SetDataAndSize(NULL, p + 1); // use x to store (p + 1)
6247  break;
6248 
6249  default: break;
6250  }
6251 }
6252 
6253 void Poly_1D::Basis::Eval(const double y, Vector &u) const
6254 {
6255  switch (etype)
6256  {
6257  case ChangeOfBasis:
6258  {
6259  CalcBasis(Ai.Width() - 1, y, x);
6260  Ai.Mult(x, u);
6261  break;
6262  }
6263  case Barycentric:
6264  {
6265  int i, k, p = x.Size() - 1;
6266  double l, lk;
6267 
6268  if (p == 0)
6269  {
6270  u(0) = 1.0;
6271  return;
6272  }
6273 
6274  lk = 1.0;
6275  for (k = 0; k < p; k++)
6276  {
6277  if (y >= (x(k) + x(k+1))/2)
6278  {
6279  lk *= y - x(k);
6280  }
6281  else
6282  {
6283  for (i = k+1; i <= p; i++)
6284  {
6285  lk *= y - x(i);
6286  }
6287  break;
6288  }
6289  }
6290  l = lk * (y - x(k));
6291 
6292  for (i = 0; i < k; i++)
6293  {
6294  u(i) = l * w(i) / (y - x(i));
6295  }
6296  u(k) = lk * w(k);
6297  for (i++; i <= p; i++)
6298  {
6299  u(i) = l * w(i) / (y - x(i));
6300  }
6301  break;
6302  }
6303  case Positive:
6304  CalcBernstein(x.Size() - 1, y, u);
6305  break;
6306 
6307  default: break;
6308  }
6309 }
6310 
6311 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
6312 {
6313  switch (etype)
6314  {
6315  case ChangeOfBasis:
6316  {
6317  CalcBasis(Ai.Width() - 1, y, x, w);
6318  Ai.Mult(x, u);
6319  Ai.Mult(w, d);
6320  break;
6321  }
6322  case Barycentric:
6323  {
6324  int i, k, p = x.Size() - 1;
6325  double l, lp, lk, sk, si;
6326 
6327  if (p == 0)
6328  {
6329  u(0) = 1.0;
6330  d(0) = 0.0;
6331  return;
6332  }
6333 
6334  lk = 1.0;
6335  for (k = 0; k < p; k++)
6336  {
6337  if (y >= (x(k) + x(k+1))/2)
6338  {
6339  lk *= y - x(k);
6340  }
6341  else
6342  {
6343  for (i = k+1; i <= p; i++)
6344  {
6345  lk *= y - x(i);
6346  }
6347  break;
6348  }
6349  }
6350  l = lk * (y - x(k));
6351 
6352  sk = 0.0;
6353  for (i = 0; i < k; i++)
6354  {
6355  si = 1.0/(y - x(i));
6356  sk += si;
6357  u(i) = l * si * w(i);
6358  }
6359  u(k) = lk * w(k);
6360  for (i++; i <= p; i++)
6361  {
6362  si = 1.0/(y - x(i));
6363  sk += si;
6364  u(i) = l * si * w(i);
6365  }
6366  lp = l * sk + lk;
6367 
6368  for (i = 0; i < k; i++)
6369  {
6370  d(i) = (lp * w(i) - u(i))/(y - x(i));
6371  }
6372  d(k) = sk * u(k);
6373  for (i++; i <= p; i++)
6374  {
6375  d(i) = (lp * w(i) - u(i))/(y - x(i));
6376  }
6377  break;
6378  }
6379  case Positive:
6380  CalcBernstein(x.Size() - 1, y, u, d);
6381  break;
6382 
6383  default: break;
6384  }
6385 }
6386 
6387 const int *Poly_1D::Binom(const int p)
6388 {
6389  if (binom.NumCols() <= p)
6390  {
6391  binom.SetSize(p + 1, p + 1);
6392  for (int i = 0; i <= p; i++)
6393  {
6394  binom(i,0) = binom(i,i) = 1;
6395  for (int j = 1; j < i; j++)
6396  {
6397  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
6398  }
6399  }
6400  }
6401  return binom[p];
6402 }
6403 
6404 void Poly_1D::ChebyshevPoints(const int p, double *x)
6405 {
6406  for (int i = 0; i <= p; i++)
6407  {
6408  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
6409  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
6410  x[i] = s*s;
6411  }
6412 }
6413 
6414 void Poly_1D::CalcMono(const int p, const double x, double *u)
6415 {
6416  double xn;
6417  u[0] = xn = 1.;
6418  for (int n = 1; n <= p; n++)
6419  {
6420  u[n] = (xn *= x);
6421  }
6422 }
6423 
6424 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
6425 {
6426  double xn;
6427  u[0] = xn = 1.;
6428  d[0] = 0.;
6429  for (int n = 1; n <= p; n++)
6430  {
6431  d[n] = n * xn;
6432  u[n] = (xn *= x);
6433  }
6434 }
6435 
6436 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6437  double *u)
6438 {
6439  if (p == 0)
6440  {
6441  u[0] = 1.;
6442  }
6443  else
6444  {
6445  int i;
6446  const int *b = Binom(p);
6447  double z = x;
6448 
6449  for (i = 1; i < p; i++)
6450  {
6451  u[i] = b[i]*z;
6452  z *= x;
6453  }
6454  u[p] = z;
6455  z = y;
6456  for (i--; i > 0; i--)
6457  {
6458  u[i] *= z;
6459  z *= y;
6460  }
6461  u[0] = z;
6462  }
6463 }
6464 
6465 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6466  double *u, double *d)
6467 {
6468  if (p == 0)
6469  {
6470  u[0] = 1.;
6471  d[0] = 0.;
6472  }
6473  else
6474  {
6475  int i;
6476  const int *b = Binom(p);
6477  const double xpy = x + y, ptx = p*x;
6478  double z = 1.;
6479 
6480  for (i = 1; i < p; i++)
6481  {
6482  d[i] = b[i]*z*(i*xpy - ptx);
6483  z *= x;
6484  u[i] = b[i]*z;
6485  }
6486  d[p] = p*z;
6487  u[p] = z*x;
6488  z = 1.;
6489  for (i--; i > 0; i--)
6490  {
6491  d[i] *= z;
6492  z *= y;
6493  u[i] *= z;
6494  }
6495  d[0] = -p*z;
6496  u[0] = z*y;
6497  }
6498 }
6499 
6500 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
6501  double *d)
6502 {
6503  if (p == 0)
6504  {
6505  d[0] = 0.;
6506  }
6507  else
6508  {
6509  int i;
6510  const int *b = Binom(p);
6511  const double xpy = x + y, ptx = p*x;
6512  double z = 1.;
6513 
6514  for (i = 1; i < p; i++)
6515  {
6516  d[i] = b[i]*z*(i*xpy - ptx);
6517  z *= x;
6518  }
6519  d[p] = p*z;
6520  z = 1.;
6521  for (i--; i > 0; i--)
6522  {
6523  d[i] *= z;
6524  z *= y;
6525  }
6526  d[0] = -p*z;
6527  }
6528 }
6529 
6530 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
6531 {
6532  // use the recursive definition for [-1,1]:
6533  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6534  double z;
6535  u[0] = 1.;
6536  if (p == 0) { return; }
6537  u[1] = z = 2.*x - 1.;
6538  for (int n = 1; n < p; n++)
6539  {
6540  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6541  }
6542 }
6543 
6544 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
6545 {
6546  // use the recursive definition for [-1,1]:
6547  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6548  // for the derivative use, z in [-1,1]:
6549  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
6550  double z;
6551  u[0] = 1.;
6552  d[0] = 0.;
6553  if (p == 0) { return; }
6554  u[1] = z = 2.*x - 1.;
6555  d[1] = 2.;
6556  for (int n = 1; n < p; n++)
6557  {
6558  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6559  d[n+1] = (4*n + 2)*u[n] + d[n-1];
6560  }
6561 }
6562 
6563 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
6564 {
6565  // recursive definition, z in [-1,1]
6566  // T_0(z) = 1, T_1(z) = z
6567  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6568  double z;
6569  u[0] = 1.;
6570  if (p == 0) { return; }
6571  u[1] = z = 2.*x - 1.;
6572  for (int n = 1; n < p; n++)
6573  {
6574  u[n+1] = 2*z*u[n] - u[n-1];
6575  }
6576 }
6577 
6578 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
6579 {
6580  // recursive definition, z in [-1,1]
6581  // T_0(z) = 1, T_1(z) = z
6582  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6583  // T'_n(z) = n*U_{n-1}(z)
6584  // U_0(z) = 1 U_1(z) = 2*z
6585  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
6586  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
6587  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
6588  double z;
6589  u[0] = 1.;
6590  d[0] = 0.;
6591  if (p == 0) { return; }
6592  u[1] = z = 2.*x - 1.;
6593  d[1] = 2.;
6594  for (int n = 1; n < p; n++)
6595  {
6596  u[n+1] = 2*z*u[n] - u[n-1];
6597  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
6598  }
6599 }
6600 
6601 const double *Poly_1D::GetPoints(const int p, const int btype)
6602 {
6603  BasisType::Check(btype);
6604  const int qtype = BasisType::GetQuadrature1D(btype);
6605 
6606  if (qtype == Quadrature1D::Invalid) { return NULL; }
6607 
6608  if (points_container.find(btype) == points_container.end())
6609  {
6610  points_container[btype] = new Array<double*>;
6611  }
6612  Array<double*> &pts = *points_container[btype];
6613  if (pts.Size() <= p)
6614  {
6615  pts.SetSize(p + 1, NULL);
6616  }
6617  if (pts[p] == NULL)
6618  {
6619  pts[p] = new double[p + 1];
6620  quad_func.GivePolyPoints(p+1, pts[p], qtype);
6621  }
6622  return pts[p];
6623 }
6624 
6625 Poly_1D::Basis &Poly_1D::GetBasis(const int p, const int btype)
6626 {
6627  BasisType::Check(btype);
6628 
6629  if ( bases_container.find(btype) == bases_container.end() )
6630  {
6631  // we haven't been asked for basis or points of this type yet
6632  bases_container[btype] = new Array<Basis*>;
6633  }
6634  Array<Basis*> &bases = *bases_container[btype];
6635  if (bases.Size() <= p)
6636  {
6637  bases.SetSize(p + 1, NULL);
6638  }
6639  if (bases[p] == NULL)
6640  {
6641  EvalType etype = (btype == BasisType::Positive) ? Positive : Barycentric;
6642  bases[p] = new Basis(p, GetPoints(p, btype), etype);
6643  }
6644  return *bases[p];
6645 }
6646 
6648 {
6649  for (PointsMap::iterator it = points_container.begin();
6650  it != points_container.end() ; ++it)
6651  {
6652  Array<double*>& pts = *it->second;
6653  for ( int i = 0 ; i < pts.Size() ; ++i )
6654  {
6655  delete [] pts[i];
6656  }
6657  delete it->second;
6658  }
6659 
6660  for (BasisMap::iterator it = bases_container.begin();
6661  it != bases_container.end() ; ++it)
6662  {
6663  Array<Basis*>& bases = *it->second;
6664  for ( int i = 0 ; i < bases.Size() ; ++i )
6665  {
6666  delete bases[i];
6667  }
6668  delete it->second;
6669  }
6670 }
6671 
6673 Array2D<int> Poly_1D::binom;
6674 
6675 
6676 TensorBasisElement::TensorBasisElement(const int dims, const int p,
6677  const int btype, const DofMapType dmtype)
6678  : b_type(btype),
6679  basis1d(poly1d.GetBasis(p, b_type))
6680 {
6681  if (dmtype == H1_DOF_MAP)
6682  {
6683  switch (dims)
6684  {
6685  case 1:
6686  {
6687  dof_map.SetSize(p + 1);
6688  dof_map[0] = 0;
6689  dof_map[p] = 1;
6690  for (int i = 1; i < p; i++)
6691  {
6692  dof_map[i] = i+1;
6693  }
6694  break;
6695  }
6696  case 2:
6697  {
6698  const int p1 = p + 1;
6699  dof_map.SetSize(p1*p1);
6700 
6701  // vertices
6702  dof_map[0 + 0*p1] = 0;
6703  dof_map[p + 0*p1] = 1;
6704  dof_map[p + p*p1] = 2;
6705  dof_map[0 + p*p1] = 3;
6706 
6707  // edges
6708  int o = 4;
6709  for (int i = 1; i < p; i++)
6710  {
6711  dof_map[i + 0*p1] = o++;
6712  }
6713  for (int i = 1; i < p; i++)
6714  {
6715  dof_map[p + i*p1] = o++;
6716  }
6717  for (int i = 1; i < p; i++)
6718  {
6719  dof_map[(p-i) + p*p1] = o++;
6720  }
6721  for (int i = 1; i < p; i++)
6722  {
6723  dof_map[0 + (p-i)*p1] = o++;
6724  }
6725 
6726  // interior
6727  for (int j = 1; j < p; j++)
6728  {
6729  for (int i = 1; i < p; i++)
6730  {
6731  dof_map[i + j*p1] = o++;
6732  }
6733  }
6734  break;
6735  }
6736  case 3:
6737  {
6738  const int p1 = p + 1;
6739  dof_map.SetSize(p1*p1*p1);
6740 
6741  // vertices
6742  dof_map[0 + (0 + 0*p1)*p1] = 0;
6743  dof_map[p + (0 + 0*p1)*p1] = 1;
6744  dof_map[p + (p + 0*p1)*p1] = 2;
6745  dof_map[0 + (p + 0*p1)*p1] = 3;
6746  dof_map[0 + (0 + p*p1)*p1] = 4;
6747  dof_map[p + (0 + p*p1)*p1] = 5;
6748  dof_map[p + (p + p*p1)*p1] = 6;
6749  dof_map[0 + (p + p*p1)*p1] = 7;
6750 
6751  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
6752  int o = 8;
6753  for (int i = 1; i < p; i++)
6754  {
6755  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
6756  }
6757  for (int i = 1; i < p; i++)
6758  {
6759  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
6760  }
6761  for (int i = 1; i < p; i++)
6762  {
6763  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
6764  }
6765  for (int i = 1; i < p; i++)
6766  {
6767  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
6768  }
6769  for (int i = 1; i < p; i++)
6770  {
6771  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
6772  }
6773  for (int i = 1; i < p; i++)
6774  {
6775  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
6776  }
6777  for (int i = 1; i < p; i++)
6778  {
6779  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
6780  }
6781  for (int i = 1; i < p; i++)
6782  {
6783  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
6784  }
6785  for (int i = 1; i < p; i++)
6786  {
6787  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
6788  }
6789  for (int i = 1; i < p; i++)
6790  {
6791  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
6792  }
6793  for (int i = 1; i < p; i++)
6794  {
6795  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
6796  }
6797  for (int i = 1; i < p; i++)
6798  {
6799  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
6800  }
6801 
6802  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
6803  for (int j = 1; j < p; j++)
6804  {
6805  for (int i = 1; i < p; i++)
6806  {
6807  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
6808  }
6809  }
6810  for (int j = 1; j < p; j++)
6811  {
6812  for (int i = 1; i < p; i++)
6813  {
6814  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
6815  }
6816  }
6817  for (int j = 1; j < p; j++)
6818  {
6819  for (int i = 1; i < p; i++)
6820  {
6821  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
6822  }
6823  }
6824  for (int j = 1; j < p; j++)
6825  {
6826  for (int i = 1; i < p; i++)
6827  {
6828  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
6829  }
6830  }
6831  for (int j = 1; j < p; j++)
6832  {
6833  for (int i = 1; i < p; i++)
6834  {
6835  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
6836  }
6837  }
6838  for (int j = 1; j < p; j++)
6839  {
6840  for (int i = 1; i < p; i++)
6841  {
6842  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
6843  }
6844  }
6845 
6846  // interior
6847  for (int k = 1; k < p; k++)
6848  {
6849  for (int j = 1; j < p; j++)
6850  {
6851  for (int i = 1; i < p; i++)
6852  {
6853  dof_map[i + (j + k*p1)*p1] = o++;
6854  }
6855  }
6856  }
6857  break;
6858  }
6859  default:
6860  MFEM_ABORT("invalid dimension: " << dims);
6861  break;
6862  }
6863  }
6864  else if (dmtype == L2_DOF_MAP)
6865  {
6866  // leave dof_map empty, indicating that the dofs are ordered
6867  // lexicographically, i.e. the dof_map is identity
6868  }
6869  else
6870  {
6871  MFEM_ABORT("invalid DofMapType: " << dmtype);
6872  }
6873 }
6874 
6875 
6877  const int p,
6878  const int btype,
6879  const DofMapType dmtype)
6880  : NodalFiniteElement(dims, GetTensorProductGeometry(dims), Pow(p + 1, dims),
6881  p, dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
6882  TensorBasisElement(dims, p, VerifyNodal(btype), dmtype) { }
6883 
6884 
6886  const int dims, const int p, const DofMapType dmtype)
6887  : PositiveFiniteElement(dims, GetTensorProductGeometry(dims),
6888  Pow(p + 1, dims), p,
6889  dims > 1 ? FunctionSpace::Qk : FunctionSpace::Pk),
6890  TensorBasisElement(dims, p, BasisType::Positive, dmtype) { }
6891 
6892 
6893 H1_SegmentElement::H1_SegmentElement(const int p, const int btype)
6894  : NodalTensorFiniteElement(1, p, VerifyClosed(btype), H1_DOF_MAP)
6895 {
6896  const double *cp = poly1d.ClosedPoints(p, b_type);
6897 
6898 #ifndef MFEM_THREAD_SAFE
6899  shape_x.SetSize(p+1);
6900  dshape_x.SetSize(p+1);
6901 #endif
6902 
6903  Nodes.IntPoint(0).x = cp[0];
6904  Nodes.IntPoint(1).x = cp[p];
6905  for (int i = 1; i < p; i++)
6906  {
6907  Nodes.IntPoint(i+1).x = cp[i];
6908  }
6909 }
6910 
6912  Vector &shape) const
6913 {
6914  const int p = Order;
6915 
6916 #ifdef MFEM_THREAD_SAFE
6917  Vector shape_x(p+1);
6918 #endif
6919 
6920  basis1d.Eval(ip.x, shape_x);
6921 
6922  shape(0) = shape_x(0);
6923  shape(1) = shape_x(p);
6924  for (int i = 1; i < p; i++)
6925  {
6926  shape(i+1) = shape_x(i);
6927  }
6928 }
6929 
6931  DenseMatrix &dshape) const
6932 {
6933  const int p = Order;
6934 
6935 #ifdef MFEM_THREAD_SAFE
6936  Vector shape_x(p+1), dshape_x(p+1);
6937 #endif
6938 
6939  basis1d.Eval(ip.x, shape_x, dshape_x);
6940 
6941  dshape(0,0) = dshape_x(0);
6942  dshape(1,0) = dshape_x(p);
6943  for (int i = 1; i < p; i++)
6944  {
6945  dshape(i+1,0) = dshape_x(i);
6946  }
6947 }
6948 
6949 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
6950 {
6951  const int p = Order;
6952  const double *cp = poly1d.ClosedPoints(p, b_type);
6953 
6954  switch (vertex)
6955  {
6956  case 0:
6957  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
6958  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
6959  for (int i = 1; i < p; i++)
6960  {
6961  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6962  }
6963  break;
6964 
6965  case 1:
6966  dofs(0) = poly1d.CalcDelta(p, cp[0]);
6967  dofs(1) = poly1d.CalcDelta(p, cp[p]);
6968  for (int i = 1; i < p; i++)
6969  {
6970  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
6971  }
6972  break;
6973  }
6974 }
6975 
6976 
6978  : NodalTensorFiniteElement(2, p, VerifyClosed(btype), H1_DOF_MAP)
6979 {
6980  const double *cp = poly1d.ClosedPoints(p, b_type);
6981 
6982 #ifndef MFEM_THREAD_SAFE
6983  const int p1 = p + 1;
6984 
6985  shape_x.SetSize(p1);
6986  shape_y.SetSize(p1);
6987  dshape_x.SetSize(p1);
6988  dshape_y.SetSize(p1);
6989 #endif
6990 
6991  int o = 0;
6992  for (int j = 0; j <= p; j++)
6993  {
6994  for (int i = 0; i <= p; i++)
6995  {
6996  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
6997  }
6998  }
6999 }
7000 
7002  Vector &shape) const
7003 {
7004  const int p = Order;
7005 
7006 #ifdef MFEM_THREAD_SAFE
7007  Vector shape_x(p+1), shape_y(p+1);
7008 #endif
7009 
7010  basis1d.Eval(ip.x, shape_x);
7011  basis1d.Eval(ip.y, shape_y);
7012 
7013  for (int o = 0, j = 0; j <= p; j++)
7014  for (int i = 0; i <= p; i++)
7015  {
7016  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7017  }
7018 }
7019 
7021  DenseMatrix &dshape) const
7022 {
7023  const int p = Order;
7024 
7025 #ifdef MFEM_THREAD_SAFE
7026  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7027 #endif
7028 
7029  basis1d.Eval(ip.x, shape_x, dshape_x);
7030  basis1d.Eval(ip.y, shape_y, dshape_y);
7031 
7032  for (int o = 0, j = 0; j <= p; j++)
7033  {
7034  for (int i = 0; i <= p; i++)
7035  {
7036  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7037  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7038  }
7039  }
7040 }
7041 
7042 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
7043 {
7044  const int p = Order;
7045  const double *cp = poly1d.ClosedPoints(p, b_type);
7046 
7047 #ifdef MFEM_THREAD_SAFE
7048  Vector shape_x(p+1), shape_y(p+1);
7049 #endif
7050 
7051  for (int i = 0; i <= p; i++)
7052  {
7053  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7054  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7055  }
7056 
7057  switch (vertex)
7058  {
7059  case 0:
7060  for (int o = 0, j = 0; j <= p; j++)
7061  for (int i = 0; i <= p; i++)
7062  {
7063  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
7064  }
7065  break;
7066  case 1:
7067  for (int o = 0, j = 0; j <= p; j++)
7068  for (int i = 0; i <= p; i++)
7069  {
7070  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
7071  }
7072  break;
7073  case 2:
7074  for (int o = 0, j = 0; j <= p; j++)
7075  for (int i = 0; i <= p; i++)
7076  {
7077  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
7078  }
7079  break;
7080  case 3:
7081  for (int o = 0, 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);
7085  }
7086  break;
7087  }
7088 }
7089 
7090 
7091 H1_HexahedronElement::H1_HexahedronElement(const int p, const int btype)
7092  : NodalTensorFiniteElement(3, p, VerifyClosed(btype), H1_DOF_MAP)
7093 {
7094  const double *cp = poly1d.ClosedPoints(p, b_type);
7095 
7096 #ifndef MFEM_THREAD_SAFE
7097  const int p1 = p + 1;
7098 
7099  shape_x.SetSize(p1);
7100  shape_y.SetSize(p1);
7101  shape_z.SetSize(p1);
7102  dshape_x.SetSize(p1);
7103  dshape_y.SetSize(p1);
7104  dshape_z.SetSize(p1);
7105 #endif
7106 
7107  int o = 0;
7108  for (int k = 0; k <= p; k++)
7109  for (int j = 0; j <= p; j++)
7110  for (int i = 0; i <= p; i++)
7111  {
7112  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
7113  }
7114 }
7115 
7117  Vector &shape) const
7118 {
7119  const int p = Order;
7120 
7121 #ifdef MFEM_THREAD_SAFE
7122  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7123 #endif
7124 
7125  basis1d.Eval(ip.x, shape_x);
7126  basis1d.Eval(ip.y, shape_y);
7127  basis1d.Eval(ip.z, shape_z);
7128 
7129  for (int o = 0, k = 0; k <= p; k++)
7130  for (int j = 0; j <= p; j++)
7131  for (int i = 0; i <= p; i++)
7132  {
7133  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7134  }
7135 }
7136 
7138  DenseMatrix &dshape) const
7139 {
7140  const int p = Order;
7141 
7142 #ifdef MFEM_THREAD_SAFE
7143  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7144  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7145 #endif
7146 
7147  basis1d.Eval(ip.x, shape_x, dshape_x);
7148  basis1d.Eval(ip.y, shape_y, dshape_y);
7149  basis1d.Eval(ip.z, shape_z, dshape_z);
7150 
7151  for (int o = 0, k = 0; k <= p; k++)
7152  for (int j = 0; j <= p; j++)
7153  for (int i = 0; i <= p; i++)
7154  {
7155  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7156  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7157  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7158  }
7159 }
7160 
7161 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7162 {
7163  const int p = Order;
7164  const double *cp = poly1d.ClosedPoints(p,b_type);
7165 
7166 #ifdef MFEM_THREAD_SAFE
7167  Vector shape_x(p+1), shape_y(p+1);
7168 #endif
7169 
7170  for (int i = 0; i <= p; i++)
7171  {
7172  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7173  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7174  }
7175 
7176  switch (vertex)
7177  {
7178  case 0:
7179  for (int o = 0, k = 0; k <= p; k++)
7180  for (int j = 0; j <= p; j++)
7181  for (int i = 0; i <= p; i++)
7182  {
7183  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
7184  }
7185  break;
7186  case 1:
7187  for (int o = 0, k = 0; k <= p; k++)
7188  for (int j = 0; j <= p; j++)
7189  for (int i = 0; i <= p; i++)
7190  {
7191  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
7192  }
7193  break;
7194  case 2:
7195  for (int o = 0, k = 0; k <= p; k++)
7196  for (int j = 0; j <= p; j++)
7197  for (int i = 0; i <= p; i++)
7198  {
7199  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
7200  }
7201  break;
7202  case 3:
7203  for (int o = 0, k = 0; k <= p; k++)
7204  for (int j = 0; j <= p; j++)
7205  for (int i = 0; i <= p; i++)
7206  {
7207  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
7208  }
7209  break;
7210  case 4:
7211  for (int o = 0, k = 0; k <= p; k++)
7212  for (int j = 0; j <= p; j++)
7213  for (int i = 0; i <= p; i++)
7214  {
7215  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
7216  }
7217  break;
7218  case 5:
7219  for (int o = 0, k = 0; k <= p; k++)
7220  for (int j = 0; j <= p; j++)
7221  for (int i = 0; i <= p; i++)
7222  {
7223  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
7224  }
7225  break;
7226  case 6:
7227  for (int o = 0, k = 0; k <= p; k++)
7228  for (int j = 0; j <= p; j++)
7229  for (int i = 0; i <= p; i++)
7230  {
7231  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
7232  }
7233  break;
7234  case 7:
7235  for (int o = 0, k = 0; k <= p; k++)
7236  for (int j = 0; j <= p; j++)
7237  for (int i = 0; i <= p; i++)
7238  {
7239  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
7240  }
7241  break;
7242  }
7243 }
7244 
7245 
7247  : PositiveTensorFiniteElement(1, p, H1_DOF_MAP)
7248 {
7249 #ifndef MFEM_THREAD_SAFE
7250  // thread private versions; see class header.
7251  shape_x.SetSize(p+1);
7252  dshape_x.SetSize(p+1);
7253 #endif
7254 
7255  // Endpoints need to be first in the list, so reorder them.
7256  Nodes.IntPoint(0).x = 0.0;
7257  Nodes.IntPoint(1).x = 1.0;
7258  for (int i = 1; i < p; i++)
7259  {
7260  Nodes.IntPoint(i+1).x = double(i)/p;
7261  }
7262 }
7263 
7265  Vector &shape) const
7266 {
7267  const int p = Order;
7268 
7269 #ifdef MFEM_THREAD_SAFE
7270  Vector shape_x(p+1);
7271 #endif
7272 
7273  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7274 
7275  // Endpoints need to be first in the list, so reorder them.
7276  shape(0) = shape_x(0);
7277  shape(1) = shape_x(p);
7278  for (int i = 1; i < p; i++)
7279  {
7280  shape(i+1) = shape_x(i);
7281  }
7282 }
7283 
7285  DenseMatrix &dshape) const
7286 {
7287  const int p = Order;
7288 
7289 #ifdef MFEM_THREAD_SAFE
7290  Vector shape_x(p+1), dshape_x(p+1);
7291 #endif
7292 
7293  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7294 
7295  // Endpoints need to be first in the list, so reorder them.
7296  dshape(0,0) = dshape_x(0);
7297  dshape(1,0) = dshape_x(p);
7298  for (int i = 1; i < p; i++)
7299  {
7300  dshape(i+1,0) = dshape_x(i);
7301  }
7302 }
7303 
7304 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7305 {
7306  dofs = 0.0;
7307  dofs[vertex] = 1.0;
7308 }
7309 
7310 
7312  : PositiveTensorFiniteElement(2, p, H1_DOF_MAP)
7313 {
7314 #ifndef MFEM_THREAD_SAFE
7315  const int p1 = p + 1;
7316 
7317  shape_x.SetSize(p1);
7318  shape_y.SetSize(p1);
7319  dshape_x.SetSize(p1);
7320  dshape_y.SetSize(p1);
7321 #endif
7322 
7323  int o = 0;
7324  for (int j = 0; j <= p; j++)
7325  for (int i = 0; i <= p; i++)
7326  {
7327  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
7328  }
7329 }
7330 
7332  Vector &shape) const
7333 {
7334  const int p = Order;
7335 
7336 #ifdef MFEM_THREAD_SAFE
7337  Vector shape_x(p+1), shape_y(p+1);
7338 #endif
7339 
7340  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7341  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7342 
7343  // Reorder so that vertices are at the beginning of the list
7344  for (int o = 0, j = 0; j <= p; j++)
7345  for (int i = 0; i <= p; i++)
7346  {
7347  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7348  }
7349 }
7350 
7352  DenseMatrix &dshape) const
7353 {
7354  const int p = Order;
7355 
7356 #ifdef MFEM_THREAD_SAFE
7357  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7358 #endif
7359 
7360  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7361  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7362 
7363  // Reorder so that vertices are at the beginning of the list
7364  for (int o = 0, j = 0; j <= p; j++)
7365  for (int i = 0; i <= p; i++)
7366  {
7367  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7368  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7369  }
7370 }
7371 
7373 {
7374  dofs = 0.0;
7375  dofs[vertex] = 1.0;
7376 }
7377 
7378 
7380  : PositiveTensorFiniteElement(3, p, H1_DOF_MAP)
7381 {
7382 #ifndef MFEM_THREAD_SAFE
7383  const int p1 = p + 1;
7384 
7385  shape_x.SetSize(p1);
7386  shape_y.SetSize(p1);
7387  shape_z.SetSize(p1);
7388  dshape_x.SetSize(p1);
7389  dshape_y.SetSize(p1);
7390  dshape_z.SetSize(p1);
7391 #endif
7392 
7393  int o = 0;
7394  for (int k = 0; k <= p; k++)
7395  for (int j = 0; j <= p; j++)
7396  for (int i = 0; i <= p; i++)
7397  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
7398  double(k)/p);
7399 }
7400 
7402  Vector &shape) const
7403 {
7404  const int p = Order;
7405 
7406 #ifdef MFEM_THREAD_SAFE
7407  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7408 #endif
7409 
7410  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7411  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7412  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
7413 
7414  for (int o = 0, k = 0; k <= p; k++)
7415  for (int j = 0; j <= p; j++)
7416  for (int i = 0; i <= p; i++)
7417  {
7418  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7419  }
7420 }
7421 
7423  DenseMatrix &dshape) const
7424 {
7425  const int p = Order;
7426 
7427 #ifdef MFEM_THREAD_SAFE
7428  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7429  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7430 #endif
7431 
7432  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7433  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7434  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
7435 
7436  for (int o = 0, k = 0; k <= p; k++)
7437  for (int j = 0; j <= p; j++)
7438  for (int i = 0; i <= p; i++)
7439  {
7440  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7441  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7442  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7443  }
7444 }
7445 
7446 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7447 {
7448  dofs = 0.0;
7449  dofs[vertex] = 1.0;
7450 }
7451 
7452 
7453 H1_TriangleElement::H1_TriangleElement(const int p, const int btype)
7454  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7455  FunctionSpace::Pk)
7456 {
7457  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
7458 
7459 #ifndef MFEM_THREAD_SAFE
7460  shape_x.SetSize(p + 1);
7461  shape_y.SetSize(p + 1);
7462  shape_l.SetSize(p + 1);
7463  dshape_x.SetSize(p + 1);
7464  dshape_y.SetSize(p + 1);
7465  dshape_l.SetSize(p + 1);
7466  u.SetSize(Dof);
7467  du.SetSize(Dof, Dim);
7468 #else
7469  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7470 #endif
7471 
7472  // vertices
7473  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
7474  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
7475  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
7476 
7477  // edges
7478  int o = 3;
7479  for (int i = 1; i < p; i++)
7480  {
7481  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
7482  }
7483  for (int i = 1; i < p; i++)
7484  {
7485  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
7486  }
7487  for (int i = 1; i < p; i++)
7488  {
7489  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
7490  }
7491 
7492  // interior
7493  for (int j = 1; j < p; j++)
7494  for (int i = 1; i + j < p; i++)
7495  {
7496  const double w = cp[i] + cp[j] + cp[p-i-j];
7497  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
7498  }
7499 
7500  DenseMatrix T(Dof);
7501  for (int k = 0; k < Dof; k++)
7502  {
7503  IntegrationPoint &ip = Nodes.IntPoint(k);
7504  poly1d.CalcBasis(p, ip.x, shape_x);
7505  poly1d.CalcBasis(p, ip.y, shape_y);
7506  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7507 
7508  o = 0;
7509  for (int j = 0; j <= p; j++)
7510  for (int i = 0; i + j <= p; i++)
7511  {
7512  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7513  }
7514  }
7515 
7516  Ti.Factor(T);
7517  // mfem::out << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
7518 }
7519 
7521  Vector &shape) const
7522 {
7523  const int p = Order;
7524 
7525 #ifdef MFEM_THREAD_SAFE
7526  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
7527 #endif
7528 
7529  poly1d.CalcBasis(p, ip.x, shape_x);
7530  poly1d.CalcBasis(p, ip.y, shape_y);
7531  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7532 
7533  for (int o = 0, j = 0; j <= p; j++)
7534  for (int i = 0; i + j <= p; i++)
7535  {
7536  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7537  }
7538 
7539  Ti.Mult(u, shape);
7540 }
7541 
7543  DenseMatrix &dshape) const
7544 {
7545  const int p = Order;
7546 
7547 #ifdef MFEM_THREAD_SAFE
7548  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7549  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
7550  DenseMatrix du(Dof, Dim);
7551 #endif
7552 
7553  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7554  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7555  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
7556 
7557  for (int o = 0, j = 0; j <= p; j++)
7558  for (int i = 0; i + j <= p; i++)
7559  {
7560  int k = p - i - j;
7561  du(o,0) = ((dshape_x(i)* shape_l(k)) -
7562  ( shape_x(i)*dshape_l(k)))*shape_y(j);
7563  du(o,1) = ((dshape_y(j)* shape_l(k)) -
7564  ( shape_y(j)*dshape_l(k)))*shape_x(i);
7565  o++;
7566  }
7567 
7568  Ti.Mult(du, dshape);
7569 }
7570 
7571 
7573  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
7574  p, FunctionSpace::Pk)
7575 {
7576  const double *cp = poly1d.ClosedPoints(p, VerifyNodal(VerifyClosed(btype)));
7577 
7578 #ifndef MFEM_THREAD_SAFE
7579  shape_x.SetSize(p + 1);
7580  shape_y.SetSize(p + 1);
7581  shape_z.SetSize(p + 1);
7582  shape_l.SetSize(p + 1);
7583  dshape_x.SetSize(p + 1);
7584  dshape_y.SetSize(p + 1);
7585  dshape_z.SetSize(p + 1);
7586  dshape_l.SetSize(p + 1);
7587  u.SetSize(Dof);
7588  du.SetSize(Dof, Dim);
7589 #else
7590  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7591 #endif
7592 
7593  // vertices
7594  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
7595  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
7596  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
7597  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
7598 
7599  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7600  int o = 4;
7601  for (int i = 1; i < p; i++) // (0,1)
7602  {
7603  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
7604  }
7605  for (int i = 1; i < p; i++) // (0,2)
7606  {
7607  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
7608  }
7609  for (int i = 1; i < p; i++) // (0,3)
7610  {
7611  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
7612  }
7613  for (int i = 1; i < p; i++) // (1,2)
7614  {
7615  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
7616  }
7617  for (int i = 1; i < p; i++) // (1,3)
7618  {
7619  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
7620  }
7621  for (int i = 1; i < p; i++) // (2,3)
7622  {
7623  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
7624  }
7625 
7626  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7627  for (int j = 1; j < p; j++)
7628  for (int i = 1; i + j < p; i++) // (1,2,3)
7629  {
7630  double w = cp[i] + cp[j] + cp[p-i-j];
7631  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
7632  }
7633  for (int j = 1; j < p; j++)
7634  for (int i = 1; i + j < p; i++) // (0,3,2)
7635  {
7636  double w = cp[i] + cp[j] + cp[p-i-j];
7637  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
7638  }
7639  for (int j = 1; j < p; j++)
7640  for (int i = 1; i + j < p; i++) // (0,1,3)
7641  {
7642  double w = cp[i] + cp[j] + cp[p-i-j];
7643  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
7644  }
7645  for (int j = 1; j < p; j++)
7646  for (int i = 1; i + j < p; i++) // (0,2,1)
7647  {
7648  double w = cp[i] + cp[j] + cp[p-i-j];
7649  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
7650  }
7651 
7652  // interior
7653  for (int k = 1; k < p; k++)
7654  for (int j = 1; j + k < p; j++)
7655  for (int i = 1; i + j + k < p; i++)
7656  {
7657  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
7658  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
7659  }
7660 
7661  DenseMatrix T(Dof);
7662  for (int m = 0; m < Dof; m++)
7663  {
7664  IntegrationPoint &ip = Nodes.IntPoint(m);
7665  poly1d.CalcBasis(p, ip.x, shape_x);
7666  poly1d.CalcBasis(p, ip.y, shape_y);
7667  poly1d.CalcBasis(p, ip.z, shape_z);
7668  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7669 
7670  o = 0;
7671  for (int k = 0; k <= p; k++)
7672  for (int j = 0; j + k <= p; j++)
7673  for (int i = 0; i + j + k <= p; i++)
7674  {
7675  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7676  }
7677  }
7678 
7679  Ti.Factor(T);
7680  // mfem::out << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
7681 }
7682 
7684  Vector &shape) const
7685 {
7686  const int p = Order;
7687 
7688 #ifdef MFEM_THREAD_SAFE
7689  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7690  Vector u(Dof);
7691 #endif
7692 
7693  poly1d.CalcBasis(p, ip.x, shape_x);
7694  poly1d.CalcBasis(p, ip.y, shape_y);
7695  poly1d.CalcBasis(p, ip.z, shape_z);
7696  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7697 
7698  for (int o = 0, k = 0; k <= p; k++)
7699  for (int j = 0; j + k <= p; j++)
7700  for (int i = 0; i + j + k <= p; i++)
7701  {
7702  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7703  }
7704 
7705  Ti.Mult(u, shape);
7706 }
7707 
7709  DenseMatrix &dshape) const
7710 {
7711  const int p = Order;
7712 
7713 #ifdef MFEM_THREAD_SAFE
7714  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7715  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
7716  DenseMatrix du(Dof, Dim);
7717 #endif
7718 
7719  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7720  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7721  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
7722  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
7723 
7724  for (int o = 0, k = 0; k <= p; k++)
7725  for (int j = 0; j + k <= p; j++)
7726  for (int i = 0; i + j + k <= p; i++)
7727  {
7728  int l = p - i - j - k;
7729  du(o,0) = ((dshape_x(i)* shape_l(l)) -
7730  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
7731  du(o,1) = ((dshape_y(j)* shape_l(l)) -
7732  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
7733  du(o,2) = ((dshape_z(k)* shape_l(l)) -
7734  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
7735  o++;
7736  }
7737 
7738  Ti.Mult(du, dshape);
7739 }
7740 
7741 
7743  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7744  FunctionSpace::Pk)
7745 {
7746 #ifndef MFEM_THREAD_SAFE
7747  m_shape.SetSize(Dof);
7748  dshape_1d.SetSize(p + 1);
7749  m_dshape.SetSize(Dof, Dim);
7750 #endif
7751  dof_map.SetSize(Dof);
7752 
7753  struct Index
7754  {
7755  int p2p3;
7756  Index(int p) { p2p3 = 2*p + 3; }
7757  int operator()(int i, int j) { return ((p2p3-j)*j)/2+i; }
7758  };
7759  Index idx(p);
7760 
7761  // vertices
7762  dof_map[idx(0,0)] = 0;
7763  Nodes.IntPoint(0).Set2(0., 0.);
7764  dof_map[idx(p,0)] = 1;
7765  Nodes.IntPoint(1).Set2(1., 0.);
7766  dof_map[idx(0,p)] = 2;
7767  Nodes.IntPoint(2).Set2(0., 1.);
7768 
7769  // edges
7770  int o = 3;
7771  for (int i = 1; i < p; i++)
7772  {
7773  dof_map[idx(i,0)] = o;
7774  Nodes.IntPoint(o++).Set2(double(i)/p, 0.);
7775  }
7776  for (int i = 1; i < p; i++)
7777  {
7778  dof_map[idx(p-i,i)] = o;
7779  Nodes.IntPoint(o++).Set2(double(p-i)/p, double(i)/p);
7780  }
7781  for (int i = 1; i < p; i++)
7782  {
7783  dof_map[idx(0,p-i)] = o;
7784  Nodes.IntPoint(o++).Set2(0., double(p-i)/p);
7785  }
7786 
7787  // interior
7788  for (int j = 1; j < p; j++)
7789  for (int i = 1; i + j < p; i++)
7790  {
7791  dof_map[idx(i,j)] = o;
7792  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
7793  }
7794 }
7795 
7796 // static method
7798  const int p, const double l1, const double l2, double *shape)
7799 {
7800  const double l3 = 1. - l1 - l2;
7801 
7802  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
7803  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
7804  // Another expression is given by the terms of the expansion:
7805  // (l1 + l2 + l3)^p =
7806  // \sum_{j=0}^p \binom{p}{j} l2^j
7807  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
7808  const int *bp = Poly_1D::Binom(p);
7809  double z = 1.;
7810  for (int o = 0, j = 0; j <= p; j++)
7811  {
7812  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape[o]);
7813  double s = bp[j]*z;
7814  for (int i = 0; i <= p - j; i++)
7815  {
7816  shape[o++] *= s;
7817  }
7818  z *= l2;
7819  }
7820 }
7821 
7822 // static method
7824  const int p, const double l1, const double l2,
7825  double *dshape_1d, double *dshape)
7826 {
7827  const int dof = ((p + 1)*(p + 2))/2;
7828  const double l3 = 1. - l1 - l2;
7829 
7830  const int *bp = Poly_1D::Binom(p);
7831  double z = 1.;
7832  for (int o = 0, j = 0; j <= p; j++)
7833  {
7834  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
7835  double s = bp[j]*z;
7836  for (int i = 0; i <= p - j; i++)
7837  {
7838  dshape[o++] = s*dshape_1d[i];
7839  }
7840  z *= l2;
7841  }
7842  z = 1.;
7843  for (int i = 0; i <= p; i++)
7844  {
7845  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
7846  double s = bp[i]*z;
7847  for (int o = i, j = 0; j <= p - i; j++)
7848  {
7849  dshape[dof + o] = s*dshape_1d[j];
7850  o += p + 1 - j;
7851  }
7852  z *= l1;
7853  }
7854 }
7855 
7857  Vector &shape) const
7858 {
7859 #ifdef MFEM_THREAD_SAFE
7860  Vector m_shape(Dof);
7861 #endif
7862  CalcShape(Order, ip.x, ip.y, m_shape.GetData());
7863  for (int i = 0; i < Dof; i++)
7864  {
7865  shape(dof_map[i]) = m_shape(i);
7866  }
7867 }
7868 
7870  DenseMatrix &dshape) const
7871 {
7872 #ifdef MFEM_THREAD_SAFE
7873  Vector dshape_1d(Order + 1);
7875 #endif
7876  CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(), m_dshape.Data());
7877  for (int d = 0; d < 2; d++)
7878  {
7879  for (int i = 0; i < Dof; i++)
7880  {
7881  dshape(dof_map[i],d) = m_dshape(i,d);
7882  }
7883  }
7884 }
7885 
7886 
7888  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
7889  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
7890 {
7891 #ifndef MFEM_THREAD_SAFE
7892  m_shape.SetSize(Dof);
7893  dshape_1d.SetSize(p + 1);
7894  m_dshape.SetSize(Dof, Dim);
7895 #endif
7896  dof_map.SetSize(Dof);
7897 
7898  struct Index
7899  {
7900  int p, dof;
7901  int tri(int k) { return (k*(k + 1))/2; }
7902  int tet(int k) { return (k*(k + 1)*(k + 2))/6; }
7903  Index(int p_) { p = p_; dof = tet(p + 1); }
7904  int operator()(int i, int j, int k)
7905  { return dof - tet(p - k) - tri(p + 1 - k - j) + i; }
7906  };
7907  Index idx(p);
7908 
7909  // vertices
7910  dof_map[idx(0,0,0)] = 0;
7911  Nodes.IntPoint(0).Set3(0., 0., 0.);
7912  dof_map[idx(p,0,0)] = 1;
7913  Nodes.IntPoint(1).Set3(1., 0., 0.);
7914  dof_map[idx(0,p,0)] = 2;
7915  Nodes.IntPoint(2).Set3(0., 1., 0.);
7916  dof_map[idx(0,0,p)] = 3;
7917  Nodes.IntPoint(3).Set3(0., 0., 1.);
7918 
7919  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7920  int o = 4;
7921  for (int i = 1; i < p; i++) // (0,1)
7922  {
7923  dof_map[idx(i,0,0)] = o;
7924  Nodes.IntPoint(o++).Set3(double(i)/p, 0., 0.);
7925  }
7926  for (int i = 1; i < p; i++) // (0,2)
7927  {
7928  dof_map[idx(0,i,0)] = o;
7929  Nodes.IntPoint(o++).Set3(0., double(i)/p, 0.);
7930  }
7931  for (int i = 1; i < p; i++) // (0,3)
7932  {
7933  dof_map[idx(0,0,i)] = o;
7934  Nodes.IntPoint(o++).Set3(0., 0., double(i)/p);
7935  }
7936  for (int i = 1; i < p; i++) // (1,2)
7937  {
7938  dof_map[idx(p-i,i,0)] = o;
7939  Nodes.IntPoint(o++).Set3(double(p-i)/p, double(i)/p, 0.);
7940  }
7941  for (int i = 1; i < p; i++) // (1,3)
7942  {
7943  dof_map[idx(p-i,0,i)] = o;
7944  Nodes.IntPoint(o++).Set3(double(p-i)/p, 0., double(i)/p);
7945  }
7946  for (int i = 1; i < p; i++) // (2,3)
7947  {
7948  dof_map[idx(0,p-i,i)] = o;
7949  Nodes.IntPoint(o++).Set3(0., double(p-i)/p, double(i)/p);
7950  }
7951 
7952  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7953  for (int j = 1; j < p; j++)
7954  for (int i = 1; i + j < p; i++) // (1,2,3)
7955  {
7956  dof_map[idx(p-i-j,i,j)] = o;
7957  Nodes.IntPoint(o++).Set3(double(p-i-j)/p, double(i)/p, double(j)/p);
7958  }
7959  for (int j = 1; j < p; j++)
7960  for (int i = 1; i + j < p; i++) // (0,3,2)
7961  {
7962  dof_map[idx(0,j,i)] = o;
7963  Nodes.IntPoint(o++).Set3(0., double(j)/p, double(i)/p);
7964  }
7965  for (int j = 1; j < p; j++)
7966  for (int i = 1; i + j < p; i++) // (0,1,3)
7967  {
7968  dof_map[idx(i,0,j)] = o;
7969  Nodes.IntPoint(o++).Set3(double(i)/p, 0., double(j)/p);
7970  }
7971  for (int j = 1; j < p; j++)
7972  for (int i = 1; i + j < p; i++) // (0,2,1)
7973  {
7974  dof_map[idx(j,i,0)] = o;
7975  Nodes.IntPoint(o++).Set3(double(j)/p, double(i)/p, 0.);
7976  }
7977 
7978  // interior
7979  for (int k = 1; k < p; k++)
7980  for (int j = 1; j + k < p; j++)
7981  for (int i = 1; i + j + k < p; i++)
7982  {
7983  dof_map[idx(i,j,k)] = o;
7984  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
7985  }
7986 }
7987 
7988 // static method
7990  const int p, const double l1, const double l2, const double l3,
7991  double *shape)
7992 {
7993  const double l4 = 1. - l1 - l2 - l3;
7994 
7995  // The basis functions are the terms in the expansion:
7996  // (l1 + l2 + l3 + l4)^p =
7997  // \sum_{k=0}^p \binom{p}{k} l3^k
7998  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
7999  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8000  const int *bp = Poly_1D::Binom(p);
8001  double l3k = 1.;
8002  for (int o = 0, k = 0; k <= p; k++)
8003  {
8004  const int *bpk = Poly_1D::Binom(p - k);
8005  const double ek = bp[k]*l3k;
8006  double l2j = 1.;
8007  for (int j = 0; j <= p - k; j++)
8008  {
8009  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape[o]);
8010  double ekj = ek*bpk[j]*l2j;
8011  for (int i = 0; i <= p - k - j; i++)
8012  {
8013  shape[o++] *= ekj;
8014  }
8015  l2j *= l2;
8016  }
8017  l3k *= l3;
8018  }
8019 }
8020 
8021 // static method
8023  const int p, const double l1, const double l2, const double l3,
8024  double *dshape_1d, double *dshape)
8025 {
8026  const int dof = ((p + 1)*(p + 2)*(p + 3))/6;
8027  const double l4 = 1. - l1 - l2 - l3;
8028 
8029  // For the x derivatives, differentiate the terms of the expression:
8030  // \sum_{k=0}^p \binom{p}{k} l3^k
8031  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8032  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8033  const int *bp = Poly_1D::Binom(p);
8034  double l3k = 1.;
8035  for (int o = 0, k = 0; k <= p; k++)
8036  {
8037  const int *bpk = Poly_1D::Binom(p - k);
8038  const double ek = bp[k]*l3k;
8039  double l2j = 1.;
8040  for (int j = 0; j <= p - k; j++)
8041  {
8042  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
8043  double ekj = ek*bpk[j]*l2j;
8044  for (int i = 0; i <= p - k - j; i++)
8045  {
8046  dshape[o++] = dshape_1d[i]*ekj;
8047  }
8048  l2j *= l2;
8049  }
8050  l3k *= l3;
8051  }
8052  // For the y derivatives, differentiate the terms of the expression:
8053  // \sum_{k=0}^p \binom{p}{k} l3^k
8054  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
8055  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
8056  l3k = 1.;
8057  for (int ok = 0, k = 0; k <= p; k++)
8058  {
8059  const int *bpk = Poly_1D::Binom(p - k);
8060  const double ek = bp[k]*l3k;
8061  double l1i = 1.;
8062  for (int i = 0; i <= p - k; i++)
8063  {
8064  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
8065  double eki = ek*bpk[i]*l1i;
8066  int o = ok + i;
8067  for (int j = 0; j <= p - k - i; j++)
8068  {
8069  dshape[dof + o] = dshape_1d[j]*eki;
8070  o += p - k - j + 1;
8071  }
8072  l1i *= l1;
8073  }
8074  l3k *= l3;
8075  ok += ((p - k + 2)*(p - k + 1))/2;
8076  }
8077  // For the z derivatives, differentiate the terms of the expression:
8078  // \sum_{j=0}^p \binom{p}{j} l2^j
8079  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
8080  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
8081  double l2j = 1.;
8082  for (int j = 0; j <= p; j++)
8083  {
8084  const int *bpj = Poly_1D::Binom(p - j);
8085  const double ej = bp[j]*l2j;
8086  double l1i = 1.;
8087  for (int i = 0; i <= p - j; i++)
8088  {
8089  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
8090  double eji = ej*bpj[i]*l1i;
8091  int m = ((p + 2)*(p + 1))/2;
8092  int n = ((p - j + 2)*(p - j + 1))/2;
8093  for (int o = i, k = 0; k <= p - j - i; k++)
8094  {
8095  // m = ((p - k + 2)*(p - k + 1))/2;
8096  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
8097  o += m;
8098  dshape[2*dof + o - n] = dshape_1d[k]*eji;
8099  m -= p - k + 1;
8100  n -= p - k - j + 1;
8101  }
8102  l1i *= l1;
8103  }
8104  l2j *= l2;
8105  }
8106 }
8107 
8109  Vector &shape) const
8110 {
8111 #ifdef MFEM_THREAD_SAFE
8112  Vector m_shape(Dof);
8113 #endif
8114  CalcShape(Order, ip.x, ip.y, ip.z, m_shape.GetData());
8115  for (int i = 0; i < Dof; i++)
8116  {
8117  shape(dof_map[i]) = m_shape(i);
8118  }
8119 }
8120 
8122  DenseMatrix &dshape) const
8123 {
8124 #ifdef MFEM_THREAD_SAFE
8125  Vector dshape_1d(Order + 1);
8127 #endif
8128  CalcDShape(Order, ip.x, ip.y, ip.z, dshape_1d.GetData(), m_dshape.Data());
8129  for (int d = 0; d < 3; d++)
8130  {
8131  for (int i = 0; i < Dof; i++)
8132  {
8133  dshape(dof_map[i],d) = m_dshape(i,d);
8134  }
8135  }
8136 }
8137 
8138 
8139 L2_SegmentElement::L2_SegmentElement(const int p, const int btype)
8140  : NodalTensorFiniteElement(1, p, VerifyOpen(btype), L2_DOF_MAP)
8141 {
8142  const double *op = poly1d.OpenPoints(p, btype);
8143 
8144 #ifndef MFEM_THREAD_SAFE
8145  shape_x.SetSize(p + 1);
8146  dshape_x.SetDataAndSize(NULL, p + 1);
8147 #endif
8148 
8149  for (int i = 0; i <= p; i++)
8150  {
8151  Nodes.IntPoint(i).x = op[i];
8152  }
8153 }
8154 
8156  Vector &shape) const
8157 {
8158  basis1d.Eval(ip.x, shape);
8159 }
8160 
8162  DenseMatrix &dshape) const
8163 {
8164 #ifdef MFEM_THREAD_SAFE
8165  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8166 #else
8167  dshape_x.SetData(dshape.Data());
8168 #endif
8169  basis1d.Eval(ip.x, shape_x, dshape_x);
8170 }
8171 
8172 void L2_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8173 {
8174  const int p = Order;
8175  const double *op = poly1d.OpenPoints(p, b_type);
8176 
8177  switch (vertex)
8178  {
8179  case 0:
8180  for (int i = 0; i <= p; i++)
8181  {
8182  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8183  }
8184  break;
8185 
8186  case 1:
8187  for (int i = 0; i <= p; i++)
8188  {
8189  dofs(i) = poly1d.CalcDelta(p,op[i]);
8190  }
8191  break;
8192  }
8193 }
8194 
8195 
8197  : PositiveTensorFiniteElement(1, p, L2_DOF_MAP)
8198 {
8199 #ifndef MFEM_THREAD_SAFE
8200  shape_x.SetSize(p + 1);
8201  dshape_x.SetDataAndSize(NULL, p + 1);
8202 #endif
8203 
8204  if (p == 0)
8205  {
8206  Nodes.IntPoint(0).x = 0.5;
8207  }
8208  else
8209  {
8210  for (int i = 0; i <= p; i++)
8211  {
8212  Nodes.IntPoint(i).x = double(i)/p;
8213  }
8214  }
8215 }
8216 
8218  Vector &shape) const
8219 {
8220  Poly_1D::CalcBernstein(Order, ip.x, shape);
8221 }
8222 
8224  DenseMatrix &dshape) const
8225 {
8226 #ifdef MFEM_THREAD_SAFE
8227  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8228 #else
8229  dshape_x.SetData(dshape.Data());
8230 #endif
8231  Poly_1D::CalcBernstein(Order, ip.x, shape_x, dshape_x);
8232 }
8233 
8234 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8235 {
8236  dofs = 0.0;
8237  dofs[vertex*Order] = 1.0;
8238 }
8239 
8240 
8242  : NodalTensorFiniteElement(2, p, VerifyOpen(btype), L2_DOF_MAP)
8243 {
8244  const double *op = poly1d.OpenPoints(p, b_type);
8245 
8246 #ifndef MFEM_THREAD_SAFE
8247  shape_x.SetSize(p + 1);
8248  shape_y.SetSize(p + 1);
8249  dshape_x.SetSize(p + 1);
8250  dshape_y.SetSize(p + 1);
8251 #endif
8252 
8253  for (int o = 0, j = 0; j <= p; j++)
8254  for (int i = 0; i <= p; i++)
8255  {
8256  Nodes.IntPoint(o++).Set2(op[i], op[j]);
8257  }
8258 }
8259 
8261  Vector &shape) const
8262 {
8263  const int p = Order;
8264 
8265 #ifdef MFEM_THREAD_SAFE
8266  Vector shape_x(p+1), shape_y(p+1);
8267 #endif
8268 
8269  basis1d.Eval(ip.x, shape_x);
8270  basis1d.Eval(ip.y, shape_y);
8271 
8272  for (int o = 0, j = 0; j <= p; j++)
8273  for (int i = 0; i <= p; i++)
8274  {
8275  shape(o++) = shape_x(i)*shape_y(j);
8276  }
8277 }
8278 
8280  DenseMatrix &dshape) const
8281 {
8282  const int p = Order;
8283 
8284 #ifdef MFEM_THREAD_SAFE
8285  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8286 #endif
8287 
8288  basis1d.Eval(ip.x, shape_x, dshape_x);
8289  basis1d.Eval(ip.y, shape_y, dshape_y);
8290 
8291  for (int o = 0, j = 0; j <= p; j++)
8292  for (int i = 0; i <= p; i++)
8293  {
8294  dshape(o,0) = dshape_x(i)* shape_y(j);
8295  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8296  }
8297 }
8298 
8299 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
8300 {
8301  const int p = Order;
8302  const double *op = poly1d.OpenPoints(p, b_type);
8303 
8304 #ifdef MFEM_THREAD_SAFE
8305  Vector shape_x(p+1), shape_y(p+1);
8306 #endif
8307 
8308  for (int i = 0; i <= p; i++)
8309  {
8310  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8311  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8312  }
8313 
8314  switch (vertex)
8315  {
8316  case 0:
8317  for (int o = 0, j = 0; j <= p; j++)
8318  for (int i = 0; i <= p; i++)
8319  {
8320  dofs[o++] = shape_x(i)*shape_x(j);
8321  }
8322  break;
8323  case 1:
8324  for (int o = 0, j = 0; j <= p; j++)
8325  for (int i = 0; i <= p; i++)
8326  {
8327  dofs[o++] = shape_y(i)*shape_x(j);
8328  }
8329  break;
8330  case 2:
8331  for (int o = 0, j = 0; j <= p; j++)
8332  for (int i = 0; i <= p; i++)
8333  {
8334  dofs[o++] = shape_y(i)*shape_y(j);
8335  }
8336  break;
8337  case 3:
8338  for (int o = 0, j = 0; j <= p; j++)
8339  for (int i = 0; i <= p; i++)
8340  {
8341  dofs[o++] = shape_x(i)*shape_y(j);
8342  }
8343  break;
8344  }
8345 }
8346 
8347 
8349  : PositiveTensorFiniteElement(2, p, L2_DOF_MAP)
8350 {
8351 #ifndef MFEM_THREAD_SAFE
8352  shape_x.SetSize(p + 1);
8353  shape_y.SetSize(p + 1);
8354  dshape_x.SetSize(p + 1);
8355  dshape_y.SetSize(p + 1);
8356 #endif
8357 
8358  if (p == 0)
8359  {
8360  Nodes.IntPoint(0).Set2(0.5, 0.5);
8361  }
8362  else
8363  {
8364  for (int o = 0, j = 0; j <= p; j++)
8365  for (int i = 0; i <= p; i++)
8366  {
8367  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8368  }
8369  }
8370 }
8371 
8373  Vector &shape) const
8374 {
8375  const int p = Order;
8376 
8377 #ifdef MFEM_THREAD_SAFE
8378  Vector shape_x(p+1), shape_y(p+1);
8379 #endif
8380 
8381  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8382  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8383 
8384  for (int o = 0, j = 0; j <= p; j++)
8385  for (int i = 0; i <= p; i++)
8386  {
8387  shape(o++) = shape_x(i)*shape_y(j);
8388  }
8389 }
8390 
8392  DenseMatrix &dshape) const
8393 {
8394  const int p = Order;
8395 
8396 #ifdef MFEM_THREAD_SAFE
8397  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8398 #endif
8399 
8400  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8401  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8402 
8403  for (int o = 0, j = 0; j <= p; j++)
8404  for (int i = 0; i <= p; i++)
8405  {
8406  dshape(o,0) = dshape_x(i)* shape_y(j);
8407  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8408  }
8409 }
8410 
8412 {
8413  const int p = Order;
8414 
8415  dofs = 0.0;
8416  switch (vertex)
8417  {
8418  case 0: dofs[0] = 1.0; break;
8419  case 1: dofs[p] = 1.0; break;
8420  case 2: dofs[p*(p + 2)] = 1.0; break;
8421  case 3: dofs[p*(p + 1)] = 1.0; break;
8422  }
8423 }
8424 
8425 
8426 L2_HexahedronElement::L2_HexahedronElement(const int p, const int btype)
8427  : NodalTensorFiniteElement(3, p, VerifyOpen(btype), L2_DOF_MAP)
8428 {
8429  const double *op = poly1d.OpenPoints(p, btype);
8430 
8431 #ifndef MFEM_THREAD_SAFE
8432  shape_x.SetSize(p + 1);
8433  shape_y.SetSize(p + 1);
8434  shape_z.SetSize(p + 1);
8435  dshape_x.SetSize(p + 1);
8436  dshape_y.SetSize(p + 1);
8437  dshape_z.SetSize(p + 1);
8438 #endif
8439 
8440  for (int o = 0, k = 0; k <= p; k++)
8441  for (int j = 0; j <= p; j++)
8442  for (int i = 0; i <= p; i++)
8443  {
8444  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
8445  }
8446 }
8447 
8449  Vector &shape) const
8450 {
8451  const int p = Order;
8452 
8453 #ifdef MFEM_THREAD_SAFE
8454  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8455 #endif
8456 
8457  basis1d.Eval(ip.x, shape_x);
8458  basis1d.Eval(ip.y, shape_y);
8459  basis1d.Eval(ip.z, shape_z);
8460 
8461  for (int o = 0, k = 0; k <= p; k++)
8462  for (int j = 0; j <= p; j++)
8463  for (int i = 0; i <= p; i++)
8464  {
8465  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8466  }
8467 }
8468 
8470  DenseMatrix &dshape) const
8471 {
8472  const int p = Order;
8473 
8474 #ifdef MFEM_THREAD_SAFE
8475  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8476  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8477 #endif
8478 
8479  basis1d.Eval(ip.x, shape_x, dshape_x);
8480  basis1d.Eval(ip.y, shape_y, dshape_y);
8481  basis1d.Eval(ip.z, shape_z, dshape_z);
8482 
8483  for (int o = 0, k = 0; k <= p; k++)
8484  for (int j = 0; j <= p; j++)
8485  for (int i = 0; i <= p; i++)
8486  {
8487  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8488  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8489  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8490  }
8491 }
8492 
8493 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8494 {
8495  const int p = Order;
8496  const double *op = poly1d.OpenPoints(p, b_type);
8497 
8498 #ifdef MFEM_THREAD_SAFE
8499  Vector shape_x(p+1), shape_y(p+1);
8500 #endif
8501 
8502  for (int i = 0; i <= p; i++)
8503  {
8504  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8505  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8506  }
8507 
8508  switch (vertex)
8509  {
8510  case 0:
8511  for (int o = 0, k = 0; k <= p; k++)
8512  for (int j = 0; j <= p; j++)
8513  for (int i = 0; i <= p; i++)
8514  {
8515  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
8516  }
8517  break;
8518  case 1:
8519  for (int o = 0, k = 0; k <= p; k++)
8520  for (int j = 0; j <= p; j++)
8521  for (int i = 0; i <= p; i++)
8522  {
8523  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
8524  }
8525  break;
8526  case 2:
8527  for (int o = 0, k = 0; k <= p; k++)
8528  for (int j = 0; j <= p; j++)
8529  for (int i = 0; i <= p; i++)
8530  {
8531  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
8532  }
8533  break;
8534  case 3:
8535  for (int o = 0, k = 0; k <= p; k++)
8536  for (int j = 0; j <= p; j++)
8537  for (int i = 0; i <= p; i++)
8538  {
8539  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
8540  }
8541  break;
8542  case 4:
8543  for (int o = 0, k = 0; k <= p; k++)
8544  for (int j = 0; j <= p; j++)
8545  for (int i = 0; i <= p; i++)
8546  {
8547  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
8548  }
8549  break;
8550  case 5:
8551  for (int o = 0, k = 0; k <= p; k++)
8552  for (int j = 0; j <= p; j++)
8553  for (int i = 0; i <= p; i++)
8554  {
8555  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
8556  }
8557  break;
8558  case 6:
8559  for (int o = 0, k = 0; k <= p; k++)
8560  for (int j = 0; j <= p; j++)
8561  for (int i = 0; i <= p; i++)
8562  {
8563  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
8564  }
8565  break;
8566  case 7:
8567  for (int o = 0, k = 0; k <= p; k++)
8568  for (int j = 0; j <= p; j++)
8569  for (int i = 0; i <= p; i++)
8570  {
8571  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
8572  }
8573  break;
8574  }
8575 }
8576 
8577 
8579  : PositiveTensorFiniteElement(3, p, L2_DOF_MAP)
8580 {
8581 #ifndef MFEM_THREAD_SAFE
8582  shape_x.SetSize(p + 1);
8583  shape_y.SetSize(p + 1);
8584  shape_z.SetSize(p + 1);
8585  dshape_x.SetSize(p + 1);
8586  dshape_y.SetSize(p + 1);
8587  dshape_z.SetSize(p + 1);
8588 #endif
8589 
8590  if (p == 0)
8591  {
8592  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
8593  }
8594  else
8595  {
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  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8601  }
8602  }
8603 }
8604 
8606  Vector &shape) const
8607 {
8608  const int p = Order;
8609 
8610 #ifdef MFEM_THREAD_SAFE
8611  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8612 #endif
8613 
8614  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8615  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8616  Poly_1D::CalcBernstein(p, ip.z, shape_z);
8617 
8618  for (int o = 0, k = 0; k <= p; k++)
8619  for (int j = 0; j <= p; j++)
8620  for (int i = 0; i <= p; i++)
8621  {
8622  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8623  }
8624 }
8625 
8627  DenseMatrix &dshape) const
8628 {
8629  const int p = Order;
8630 
8631 #ifdef MFEM_THREAD_SAFE
8632  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8633  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8634 #endif
8635 
8636  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8637  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8638  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
8639 
8640  for (int o = 0, k = 0; k <= p; k++)
8641  for (int j = 0; j <= p; j++)
8642  for (int i = 0; i <= p; i++)
8643  {
8644  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8645  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8646  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8647  }
8648 }
8649 
8650 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8651 {
8652  const int p = Order;
8653 
8654  dofs = 0.0;
8655  switch (vertex)
8656  {
8657  case 0: dofs[0] = 1.0; break;
8658  case 1: dofs[p] = 1.0; break;
8659  case 2: dofs[p*(p + 2)] = 1.0; break;
8660  case 3: dofs[p*(p + 1)] = 1.0; break;
8661  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
8662  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
8663  case 6: dofs[Dof - 1] = 1.0; break;
8664  case 7: dofs[Dof - p - 1] = 1.0; break;
8665  }
8666 }
8667 
8668 
8669 L2_TriangleElement::L2_TriangleElement(const int p, const int btype)
8670  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8671  FunctionSpace::Pk)
8672 {
8673  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
8674 
8675 #ifndef MFEM_THREAD_SAFE
8676  shape_x.SetSize(p + 1);
8677  shape_y.SetSize(p + 1);
8678  shape_l.SetSize(p + 1);
8679  dshape_x.SetSize(p + 1);
8680  dshape_y.SetSize(p + 1);
8681  dshape_l.SetSize(p + 1);
8682  u.SetSize(Dof);
8683  du.SetSize(Dof, Dim);
8684 #else
8685  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8686 #endif
8687 
8688  for (int o = 0, j = 0; j <= p; j++)
8689  for (int i = 0; i + j <= p; i++)
8690  {
8691  double w = op[i] + op[j] + op[p-i-j];
8692  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
8693  }
8694 
8695  DenseMatrix T(Dof);
8696  for (int k = 0; k < Dof; k++)
8697  {
8698  IntegrationPoint &ip = Nodes.IntPoint(k);
8699  poly1d.CalcBasis(p, ip.x, shape_x);
8700  poly1d.CalcBasis(p, ip.y, shape_y);
8701  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8702 
8703  for (int o = 0, j = 0; j <= p; j++)
8704  for (int i = 0; i + j <= p; i++)
8705  {
8706  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8707  }
8708  }
8709 
8710  Ti.Factor(T);
8711  // mfem::out << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
8712 }
8713 
8715  Vector &shape) const
8716 {
8717  const int p = Order;
8718 
8719 #ifdef MFEM_THREAD_SAFE
8720  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
8721 #endif
8722 
8723  poly1d.CalcBasis(p, ip.x, shape_x);
8724  poly1d.CalcBasis(p, ip.y, shape_y);
8725  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8726 
8727  for (int o = 0, j = 0; j <= p; j++)
8728  for (int i = 0; i + j <= p; i++)
8729  {
8730  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8731  }
8732 
8733  Ti.Mult(u, shape);
8734 }
8735 
8737  DenseMatrix &dshape) const
8738 {
8739  const int p = Order;
8740 
8741 #ifdef MFEM_THREAD_SAFE
8742  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8743  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8744  DenseMatrix du(Dof, Dim);
8745 #endif
8746 
8747  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8748  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8749  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
8750 
8751  for (int o = 0, j = 0; j <= p; j++)
8752  for (int i = 0; i + j <= p; i++)
8753  {
8754  int k = p - i - j;
8755  du(o,0) = ((dshape_x(i)* shape_l(k)) -
8756  ( shape_x(i)*dshape_l(k)))*shape_y(j);
8757  du(o,1) = ((dshape_y(j)* shape_l(k)) -
8758  ( shape_y(j)*dshape_l(k)))*shape_x(i);
8759  o++;
8760  }
8761 
8762  Ti.Mult(du, dshape);
8763 }
8764 
8765 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8766 {
8767  switch (vertex)
8768  {
8769  case 0:
8770  for (int i = 0; i < Dof; i++)
8771  {
8772  const IntegrationPoint &ip = Nodes.IntPoint(i);
8773  dofs[i] = pow(1.0 - ip.x - ip.y, Order);
8774  }
8775  break;
8776  case 1:
8777  for (int i = 0; i < Dof; i++)
8778  {
8779  const IntegrationPoint &ip = Nodes.IntPoint(i);
8780  dofs[i] = pow(ip.x, Order);
8781  }
8782  break;
8783  case 2:
8784  for (int i = 0; i < Dof; i++)
8785  {
8786  const IntegrationPoint &ip = Nodes.IntPoint(i);
8787  dofs[i] = pow(ip.y, Order);
8788  }
8789  break;
8790  }
8791 }
8792 
8793 
8795  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8796  FunctionSpace::Pk)
8797 {
8798 #ifndef MFEM_THREAD_SAFE
8799  dshape_1d.SetSize(p + 1);
8800 #endif
8801 
8802  if (p == 0)
8803  {
8804  Nodes.IntPoint(0).Set2(1./3, 1./3);
8805  }
8806  else
8807  {
8808  for (int o = 0, j = 0; j <= p; j++)
8809  for (int i = 0; i + j <= p; i++)
8810  {
8811  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8812  }
8813  }
8814 }
8815 
8817  Vector &shape) const
8818 {
8819  H1Pos_TriangleElement::CalcShape(Order, ip.x, ip.y, shape.GetData());
8820 }
8821 
8823  DenseMatrix &dshape) const
8824 {
8825 #ifdef MFEM_THREAD_SAFE
8826  Vector dshape_1d(Order + 1);
8827 #endif
8828 
8829  H1Pos_TriangleElement::CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(),
8830  dshape.Data());
8831 }
8832 
8833 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8834 {
8835  dofs = 0.0;
8836  switch (vertex)
8837  {
8838  case 0: dofs[0] = 1.0; break;
8839  case 1: dofs[Order] = 1.0; break;
8840  case 2: dofs[Dof-1] = 1.0; break;
8841  }
8842 }
8843 
8844 
8846  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
8847  p, FunctionSpace::Pk)
8848 {
8849  const double *op = poly1d.OpenPoints(p, VerifyNodal(VerifyOpen(btype)));
8850 
8851 #ifndef MFEM_THREAD_SAFE
8852  shape_x.SetSize(p + 1);
8853  shape_y.SetSize(p + 1);
8854  shape_z.SetSize(p + 1);
8855  shape_l.SetSize(p + 1);
8856  dshape_x.SetSize(p + 1);
8857  dshape_y.SetSize(p + 1);
8858  dshape_z.SetSize(p + 1);
8859  dshape_l.SetSize(p + 1);
8860  u.SetSize(Dof);
8861  du.SetSize(Dof, Dim);
8862 #else
8863  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8864 #endif
8865 
8866  for (int o = 0, k = 0; k <= p; k++)
8867  for (int j = 0; j + k <= p; j++)
8868  for (int i = 0; i + j + k <= p; i++)
8869  {
8870  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
8871  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
8872  }
8873 
8874  DenseMatrix T(Dof);
8875  for (int m = 0; m < Dof; m++)
8876  {
8877  IntegrationPoint &ip = Nodes.IntPoint(m);
8878  poly1d.CalcBasis(p, ip.x, shape_x);
8879  poly1d.CalcBasis(p, ip.y, shape_y);
8880  poly1d.CalcBasis(p, ip.z, shape_z);
8881  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8882 
8883  for (int o = 0, k = 0; k <= p; k++)
8884  for (int j = 0; j + k <= p; j++)
8885  for (int i = 0; i + j + k <= p; i++)
8886  {
8887  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8888  }
8889  }
8890 
8891  Ti.Factor(T);
8892  // mfem::out << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8893 }
8894 
8896  Vector &shape) const
8897 {
8898  const int p = Order;
8899 
8900 #ifdef MFEM_THREAD_SAFE
8901  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8902  Vector u(Dof);
8903 #endif
8904 
8905  poly1d.CalcBasis(p, ip.x, shape_x);
8906  poly1d.CalcBasis(p, ip.y, shape_y);
8907  poly1d.CalcBasis(p, ip.z, shape_z);
8908  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8909 
8910  for (int o = 0, k = 0; k <= p; k++)
8911  for (int j = 0; j + k <= p; j++)
8912  for (int i = 0; i + j + k <= p; i++)
8913  {
8914  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8915  }
8916 
8917  Ti.Mult(u, shape);
8918 }
8919 
8921  DenseMatrix &dshape) const
8922 {
8923  const int p = Order;
8924 
8925 #ifdef MFEM_THREAD_SAFE
8926  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8927  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8928  DenseMatrix du(Dof, Dim);
8929 #endif
8930 
8931  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8932  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8933  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
8934  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
8935 
8936  for (int o = 0, k = 0; k <= p; k++)
8937  for (int j = 0; j + k <= p; j++)
8938  for (int i = 0; i + j + k <= p; i++)
8939  {
8940  int l = p - i - j - k;
8941  du(o,0) = ((dshape_x(i)* shape_l(l)) -
8942  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
8943  du(o,1) = ((dshape_y(j)* shape_l(l)) -
8944  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
8945  du(o,2) = ((dshape_z(k)* shape_l(l)) -
8946  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
8947  o++;
8948  }
8949 
8950  Ti.Mult(du, dshape);
8951 }
8952 
8953 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8954 {
8955  switch (vertex)
8956  {
8957  case 0:
8958  for (int i = 0; i < Dof; i++)
8959  {
8960  const IntegrationPoint &ip = Nodes.IntPoint(i);
8961  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, Order);
8962  }
8963  break;
8964  case 1:
8965  for (int i = 0; i < Dof; i++)
8966  {
8967  const IntegrationPoint &ip = Nodes.IntPoint(i);
8968  dofs[i] = pow(ip.x, Order);
8969  }
8970  break;
8971  case 2:
8972  for (int i = 0; i < Dof; i++)
8973  {
8974  const IntegrationPoint &ip = Nodes.IntPoint(i);
8975  dofs[i] = pow(ip.y, Order);
8976  }
8977  case 3:
8978  for (int i = 0; i < Dof; i++)
8979  {
8980  const IntegrationPoint &ip = Nodes.IntPoint(i);
8981  dofs[i] = pow(ip.z, Order);
8982  }
8983  break;
8984  }
8985 }
8986 
8987 
8989  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
8990  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
8991 {
8992 #ifndef MFEM_THREAD_SAFE
8993  dshape_1d.SetSize(p + 1);
8994 #endif
8995 
8996  if (p == 0)
8997  {
8998  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
8999  }
9000  else
9001  {
9002  for (int o = 0, k = 0; k <= p; k++)
9003  for (int j = 0; j + k <= p; j++)
9004  for (int i = 0; i + j + k <= p; i++)
9005  {
9006  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
9007  }
9008  }
9009 }
9010 
9012  Vector &shape) const
9013 {
9015  shape.GetData());
9016 }
9017 
9019  DenseMatrix &dshape) const
9020 {
9021 #ifdef MFEM_THREAD_SAFE
9022  Vector dshape_1d(Order + 1);
9023 #endif
9024 
9026  dshape_1d.GetData(), dshape.Data());
9027 }
9028 
9029 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
9030 {
9031  dofs = 0.0;
9032  switch (vertex)
9033  {
9034  case 0: dofs[0] = 1.0; break;
9035  case 1: dofs[Order] = 1.0; break;
9036  case 2: dofs[(Order*(Order+3))/2] = 1.0; break;
9037  case 3: dofs[Dof-1] = 1.0; break;
9038  }
9039 }
9040 
9041 
9042 const double RT_QuadrilateralElement::nk[8] =
9043 { 0., -1., 1., 0., 0., 1., -1., 0. };
9044 
9046  const int cb_type,
9047  const int ob_type)
9048  : VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p + 1,
9049  H_DIV, FunctionSpace::Qk),
9050  cbasis1d(poly1d.GetBasis(p + 1, VerifyClosed(cb_type))),
9051  obasis1d(poly1d.GetBasis(p, VerifyOpen(ob_type))),
9052  dof_map(Dof), dof2nk(Dof)
9053 {
9054  const double *cp = poly1d.ClosedPoints(p + 1, cb_type);
9055  const double *op = poly1d.OpenPoints(p, ob_type);
9056  const int dof2 = Dof/2;
9057 
9058 #ifndef MFEM_THREAD_SAFE
9059  shape_cx.SetSize(p + 2);
9060  shape_ox.SetSize(p + 1);
9061  shape_cy.SetSize(p + 2);
9062  shape_oy.SetSize(p + 1);
9063  dshape_cx.SetSize(p + 2);
9064  dshape_cy.SetSize(p + 2);
9065 #endif
9066 
9067  // edges
9068  int o = 0;
9069  for (int i = 0; i <= p; i++) // (0,1)
9070  {
9071  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
9072  }
9073  for (int i = 0; i <= p; i++) // (1,2)
9074  {
9075  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
9076  }
9077  for (int i = 0; i <= p; i++) // (2,3)
9078  {
9079  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
9080  }
9081  for (int i = 0; i <= p; i++) // (3,0)
9082  {
9083  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
9084  }
9085 
9086  // interior
9087  for (int j = 0; j <= p; j++) // x-components
9088  for (int i = 1; i <= p; i++)
9089  {
9090  dof_map[0*dof2 + i + j*(p + 2)] = o++;
9091  }
9092  for (int j = 1; j <= p; j++) // y-components
9093  for (int i = 0; i <= p; i++)
9094  {
9095  dof_map[1*dof2 + i + j*(p + 1)] = o++;
9096  }
9097 
9098  // dof orientations
9099  // x-components
9100  for (int j = 0; j <= p; j++)
9101  for (int i = 0; i <= p/2; i++)
9102  {
9103  int idx = 0*dof2 + i + j*(p + 2);
9104  dof_map[idx] = -1 - dof_map[idx];
9105  }
9106  if (p%2 == 1)
9107  for (int j = p/2 + 1; j <= p; j++)
9108  {
9109  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
9110  dof_map[idx] = -1 - dof_map[idx];
9111  }
9112  // y-components
9113  for (int j = 0; j <= p/2; j++)
9114  for (int i = 0; i <= p; i++)
9115  {
9116  int idx = 1*dof2 + i + j*(p + 1);
9117  dof_map[idx] = -1 - dof_map[idx];
9118  }
9119  if (p%2 == 1)
9120  for (int i = 0; i <= p/2; i++)
9121  {
9122  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
9123  dof_map[idx] = -1 - dof_map[idx];
9124  }
9125 
9126  o = 0;
9127  for (int j = 0; j <= p; j++)
9128  for (int i = 0; i <= p + 1; i++)
9129  {
9130  int idx;
9131  if ((idx = dof_map[o++]) < 0)
9132  {
9133  idx = -1 - idx;
9134  dof2nk[idx] = 3;
9135  }
9136  else
9137  {
9138  dof2nk[idx] = 1;
9139  }
9140  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
9141  }
9142  for (int j = 0; j <= p + 1; j++)
9143  for (int i = 0; i <= p; i++)
9144  {
9145  int idx;
9146  if ((idx = dof_map[o++]) < 0)
9147  {
9148  idx = -1 - idx;
9149  dof2nk[idx] = 0;
9150  }
9151  else
9152  {
9153  dof2nk[idx] = 2;
9154  }
9155  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
9156  }
9157 }
9158 
9160  DenseMatrix &shape) const
9161 {
9162  const int pp1 = Order;
9163 
9164 #ifdef MFEM_THREAD_SAFE
9165  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9166 #endif
9167 
9168  cbasis1d.Eval(ip.x, shape_cx);
9169  obasis1d.Eval(ip.x, shape_ox);
9170  cbasis1d.Eval(ip.y, shape_cy);
9171  obasis1d.Eval(ip.y, shape_oy);
9172 
9173  int o = 0;
9174  for (int j = 0; j < pp1; j++)
9175  for (int i = 0; i <= pp1; i++)
9176  {
9177  int idx, s;
9178  if ((idx = dof_map[o++]) < 0)
9179  {
9180  idx = -1 - idx, s = -1;
9181  }
9182  else
9183  {
9184  s = +1;
9185  }
9186  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
9187  shape(idx,1) = 0.;
9188  }
9189  for (int j = 0; j <= pp1; j++)
9190  for (int i = 0; i < pp1; i++)
9191  {
9192  int idx, s;
9193  if ((idx = dof_map[o++]) < 0)
9194  {
9195  idx = -1 - idx, s = -1;
9196  }
9197  else
9198  {
9199  s = +1;
9200  }
9201  shape(idx,0) = 0.;
9202  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
9203  }
9204 }
9205 
9207  Vector &divshape) const
9208 {
9209  const int pp1 = Order;
9210 
9211 #ifdef MFEM_THREAD_SAFE
9212  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9213  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
9214 #endif
9215 
9216  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9217  obasis1d.Eval(ip.x, shape_ox);
9218  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9219  obasis1d.Eval(ip.y, shape_oy);
9220 
9221  int o = 0;
9222  for (int j = 0; j < pp1; j++)
9223  for (int i = 0; i <= pp1; i++)
9224  {
9225  int idx, s;
9226  if ((idx = dof_map[o++]) < 0)
9227  {
9228  idx = -1 - idx, s = -1;
9229  }
9230  else
9231  {
9232  s = +1;
9233  }
9234  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
9235  }
9236  for (int j = 0; j <= pp1; j++)
9237  for (int i = 0; i < pp1; i++)
9238  {
9239  int idx, s;
9240  if ((idx = dof_map[o++]) < 0)
9241  {
9242  idx = -1 - idx, s = -1;
9243  }
9244  else
9245  {
9246  s = +1;
9247  }
9248  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
9249  }
9250 }
9251 
9252 
9253 const double RT_HexahedronElement::nk[18] =
9254 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
9255 
9257  const int cb_type,
9258  const int ob_type)
9259  : VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 1)*(p + 2), p + 1,
9260  H_DIV, FunctionSpace::Qk),
9261  cbasis1d(poly1d.GetBasis(p + 1, VerifyClosed(cb_type))),
9262  obasis1d(poly1d.GetBasis(p, VerifyOpen(ob_type))),
9263  dof_map(Dof), dof2nk(Dof)
9264 {
9265  const double *cp = poly1d.ClosedPoints(p + 1, cb_type);
9266  const double *op = poly1d.OpenPoints(p, ob_type);
9267  const int dof3 = Dof/3;
9268 
9269 #ifndef MFEM_THREAD_SAFE
9270  shape_cx.SetSize(p + 2);
9271  shape_ox.SetSize(p + 1);
9272  shape_cy.SetSize(p + 2);
9273  shape_oy.SetSize(p + 1);
9274  shape_cz.SetSize(p + 2);
9275  shape_oz.SetSize(p + 1);
9276  dshape_cx.SetSize(p + 2);
9277  dshape_cy.SetSize(p + 2);
9278  dshape_cz.SetSize(p + 2);
9279 #endif
9280 
9281  // faces
9282  int o = 0;
9283  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
9284  for (int i = 0; i <= p; i++)
9285  {
9286  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
9287  }
9288  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
9289  for (int i = 0; i <= p; i++)
9290  {
9291  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
9292  }
9293  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
9294  for (int i = 0; i <= p; i++)
9295  {
9296  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
9297  }
9298  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
9299  for (int i = 0; i <= p; i++)
9300  {
9301  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
9302  }
9303  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
9304  for (int i = 0; i <= p; i++)
9305  {
9306  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
9307  }
9308  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
9309  for (int i = 0; i <= p; i++)
9310  {
9311  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
9312  }
9313 
9314  // interior
9315  // x-components
9316  for (int k = 0; k <= p; k++)
9317  for (int j = 0; j <= p; j++)
9318  for (int i = 1; i <= p; i++)
9319  {
9320  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
9321  }
9322  // y-components
9323  for (int k = 0; k <= p; k++)
9324  for (int j = 1; j <= p; j++)
9325  for (int i = 0; i <= p; i++)
9326  {
9327  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
9328  }
9329  // z-components
9330  for (int k = 1; k <= p; k++)
9331  for (int j = 0; j <= p; j++)
9332  for (int i = 0; i <= p; i++)
9333  {
9334  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
9335  }
9336 
9337  // dof orientations
9338  // for odd p, do not change the orientations in the mid-planes
9339  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
9340  // respectively.
9341  // x-components
9342  for (int k = 0; k <= p; k++)
9343  for (int j = 0; j <= p; j++)
9344  for (int i = 0; i <= p/2; i++)
9345  {
9346  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
9347  dof_map[idx] = -1 - dof_map[idx];
9348  }
9349  // y-components
9350  for (int k = 0; k <= p; k++)
9351  for (int j = 0; j <= p/2; j++)
9352  for (int i = 0; i <= p; i++)
9353  {
9354  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
9355  dof_map[idx] = -1 - dof_map[idx];
9356  }
9357  // z-components
9358  for (int k = 0; k <= p/2; k++)
9359  for (int j = 0; j <= p; j++)
9360  for (int i = 0; i <= p; i++)
9361  {
9362  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
9363  dof_map[idx] = -1 - dof_map[idx];
9364  }
9365 
9366  o = 0;
9367  // x-components
9368  for (int k = 0; k <= p; k++)
9369  for (int j = 0; j <= p; j++)
9370  for (int i = 0; i <= p + 1; i++)
9371  {
9372  int idx;
9373  if ((idx = dof_map[o++]) < 0)
9374  {
9375  idx = -1 - idx;
9376  dof2nk[idx] = 4;
9377  }
9378  else
9379  {
9380  dof2nk[idx] = 2;
9381  }
9382  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
9383  }
9384  // y-components
9385  for (int k = 0; k <= p; k++)
9386  for (int j = 0; j <= p + 1; j++)
9387  for (int i = 0; i <= p; i++)
9388  {
9389  int idx;
9390  if ((idx = dof_map[o++]) < 0)
9391  {
9392  idx = -1 - idx;
9393  dof2nk[idx] = 1;
9394  }
9395  else
9396  {
9397  dof2nk[idx] = 3;
9398  }
9399  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
9400  }
9401  // z-components
9402  for (int k = 0; k <= p + 1; k++)
9403  for (int j = 0; j <= p; j++)
9404  for (int i = 0; i <= p; i++)
9405  {
9406  int idx;
9407  if ((idx = dof_map[o++]) < 0)
9408  {
9409  idx = -1 - idx;
9410  dof2nk[idx] = 0;
9411  }
9412  else
9413  {
9414  dof2nk[idx] = 5;
9415  }
9416  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
9417  }
9418 }
9419 
9421  DenseMatrix &shape) const
9422 {
9423  const int pp1 = Order;
9424 
9425 #ifdef MFEM_THREAD_SAFE
9426  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9427  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9428 #endif
9429 
9430  cbasis1d.Eval(ip.x, shape_cx);
9431  obasis1d.Eval(ip.x, shape_ox);
9432  cbasis1d.Eval(ip.y, shape_cy);
9433  obasis1d.Eval(ip.y, shape_oy);
9434  cbasis1d.Eval(ip.z, shape_cz);
9435  obasis1d.Eval(ip.z, shape_oz);
9436 
9437  int o = 0;
9438  // x-components
9439  for (int k = 0; k < pp1; k++)
9440  for (int j = 0; j < pp1; j++)
9441  for (int i = 0; i <= pp1; i++)
9442  {
9443  int idx, s;
9444  if ((idx = dof_map[o++]) < 0)
9445  {
9446  idx = -1 - idx, s = -1;
9447  }
9448  else
9449  {
9450  s = +1;
9451  }
9452  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
9453  shape(idx,1) = 0.;
9454  shape(idx,2) = 0.;
9455  }
9456  // y-components
9457  for (int k = 0; k < pp1; k++)
9458  for (int j = 0; j <= pp1; j++)
9459  for (int i = 0; i < pp1; i++)
9460  {
9461  int idx, s;
9462  if ((idx = dof_map[o++]) < 0)
9463  {
9464  idx = -1 - idx, s = -1;
9465  }
9466  else
9467  {
9468  s = +1;
9469  }
9470  shape(idx,0) = 0.;
9471  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
9472  shape(idx,2) = 0.;
9473  }
9474  // z-components
9475  for (int k = 0; k <= pp1; k++)
9476  for (int j = 0; j < pp1; j++)
9477  for (int i = 0; i < pp1; i++)
9478  {
9479  int idx, s;
9480  if ((idx = dof_map[o++]) < 0)
9481  {
9482  idx = -1 - idx, s = -1;
9483  }
9484  else
9485  {
9486  s = +1;
9487  }
9488  shape(idx,0) = 0.;
9489  shape(idx,1) = 0.;
9490  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
9491  }
9492 }
9493 
9495  Vector &divshape) const
9496 {
9497  const int pp1 = Order;
9498 
9499 #ifdef MFEM_THREAD_SAFE
9500  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9501  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9502  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
9503 #endif
9504 
9505  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9506  obasis1d.Eval(ip.x, shape_ox);
9507  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9508  obasis1d.Eval(ip.y, shape_oy);
9509  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
9510  obasis1d.Eval(ip.z, shape_oz);
9511 
9512  int o = 0;
9513  // x-components
9514  for (int k = 0; k < pp1; k++)
9515  for (int j = 0; j < pp1; j++)
9516  for (int i = 0; i <= pp1; i++)
9517  {
9518  int idx, s;
9519  if ((idx = dof_map[o++]) < 0)
9520  {
9521  idx = -1 - idx, s = -1;
9522  }
9523  else
9524  {
9525  s = +1;
9526  }
9527  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
9528  }
9529  // y-components
9530  for (int k = 0; k < pp1; k++)
9531  for (int j = 0; j <= pp1; j++)
9532  for (int i = 0; i < pp1; i++)
9533  {
9534  int idx, s;
9535  if ((idx = dof_map[o++]) < 0)
9536  {
9537  idx = -1 - idx, s = -1;
9538  }
9539  else
9540  {
9541  s = +1;
9542  }
9543  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
9544  }
9545  // z-components
9546  for (int k = 0; k <= pp1; k++)
9547  for (int j = 0; j < pp1; j++)
9548  for (int i = 0; i < pp1; i++)
9549  {
9550  int idx, s;
9551  if ((idx = dof_map[o++]) < 0)
9552  {
9553  idx = -1 - idx, s = -1;
9554  }
9555  else
9556  {
9557  s = +1;
9558  }
9559  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
9560  }
9561 }
9562 
9563 
9564 const double RT_TriangleElement::nk[6] =
9565 { 0., -1., 1., 1., -1., 0. };
9566 
9567 const double RT_TriangleElement::c = 1./3.;
9568 
9570  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
9571  H_DIV, FunctionSpace::Pk),
9572  dof2nk(Dof)
9573 {
9574  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9575  const double *bop = poly1d.OpenPoints(p);
9576 
9577 #ifndef MFEM_THREAD_SAFE
9578  shape_x.SetSize(p + 1);
9579  shape_y.SetSize(p + 1);
9580  shape_l.SetSize(p + 1);
9581  dshape_x.SetSize(p + 1);
9582  dshape_y.SetSize(p + 1);
9583  dshape_l.SetSize(p + 1);
9584  u.SetSize(Dof, Dim);
9585  divu.SetSize(Dof);
9586 #else
9587  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9588 #endif
9589 
9590  // edges
9591  int o = 0;
9592  for (int i = 0; i <= p; i++) // (0,1)
9593  {
9594  Nodes.IntPoint(o).Set2(bop[i], 0.);
9595  dof2nk[o++] = 0;
9596  }
9597  for (int i = 0; i <= p; i++) // (1,2)
9598  {
9599  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
9600  dof2nk[o++] = 1;
9601  }
9602  for (int i = 0; i <= p; i++) // (2,0)
9603  {
9604  Nodes.IntPoint(o).Set2(0., bop[p-i]);
9605  dof2nk[o++] = 2;
9606  }
9607 
9608  // interior
9609  for (int j = 0; j < p; j++)
9610  for (int i = 0; i + j < p; i++)
9611  {
9612  double w = iop[i] + iop[j] + iop[p-1-i-j];
9613  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9614  dof2nk[o++] = 0;
9615  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9616  dof2nk[o++] = 2;
9617  }
9618 
9619  DenseMatrix T(Dof);
9620  for (int k = 0; k < Dof; k++)
9621  {
9622  const IntegrationPoint &ip = Nodes.IntPoint(k);
9623  poly1d.CalcBasis(p, ip.x, shape_x);
9624  poly1d.CalcBasis(p, ip.y, shape_y);
9625  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9626  const double *n_k = nk + 2*dof2nk[k];
9627 
9628  o = 0;
9629  for (int j = 0; j <= p; j++)
9630  for (int i = 0; i + j <= p; i++)
9631  {
9632  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9633  T(o++, k) = s*n_k[0];
9634  T(o++, k) = s*n_k[1];
9635  }
9636  for (int i = 0; i <= p; i++)
9637  {
9638  double s = shape_x(i)*shape_y(p-i);
9639  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
9640  }
9641  }
9642 
9643  Ti.Factor(T);
9644  // mfem::out << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
9645 }
9646 
9648  DenseMatrix &shape) const
9649 {
9650  const int p = Order - 1;
9651 
9652 #ifdef MFEM_THREAD_SAFE
9653  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9654  DenseMatrix u(Dof, Dim);
9655 #endif
9656 
9657  poly1d.CalcBasis(p, ip.x, shape_x);
9658  poly1d.CalcBasis(p, ip.y, shape_y);
9659  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9660 
9661  int o = 0;
9662  for (int j = 0; j <= p; j++)
9663  for (int i = 0; i + j <= p; i++)
9664  {
9665  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9666  u(o,0) = s; u(o,1) = 0; o++;
9667  u(o,0) = 0; u(o,1) = s; o++;
9668  }
9669  for (int i = 0; i <= p; i++)
9670  {
9671  double s = shape_x(i)*shape_y(p-i);
9672  u(o,0) = (ip.x - c)*s;
9673  u(o,1) = (ip.y - c)*s;
9674  o++;
9675  }
9676 
9677  Ti.Mult(u, shape);
9678 }
9679 
9681  Vector &divshape) const
9682 {
9683  const int p = Order - 1;
9684 
9685 #ifdef MFEM_THREAD_SAFE
9686  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9687  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
9688  Vector divu(Dof);
9689 #endif
9690 
9691  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9692  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9693  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
9694 
9695  int o = 0;
9696  for (int j = 0; j <= p; j++)
9697  for (int i = 0; i + j <= p; i++)
9698  {
9699  int k = p - i - j;
9700  divu(o++) = (dshape_x(i)*shape_l(k) -
9701  shape_x(i)*dshape_l(k))*shape_y(j);
9702  divu(o++) = (dshape_y(j)*shape_l(k) -
9703  shape_y(j)*dshape_l(k))*shape_x(i);
9704  }
9705  for (int i = 0; i <= p; i++)
9706  {
9707  int j = p - i;
9708  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
9709  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
9710  }
9711 
9712  Ti.Mult(divu, divshape);
9713 }
9714 
9715 
9716 const double RT_TetrahedronElement::nk[12] =
9717 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
9718 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
9719 
9720 const double RT_TetrahedronElement::c = 1./4.;
9721 
9723  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
9724  p + 1, H_DIV, FunctionSpace::Pk),
9725  dof2nk(Dof)
9726 {
9727  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9728  const double *bop = poly1d.OpenPoints(p);
9729 
9730 #ifndef MFEM_THREAD_SAFE
9731  shape_x.SetSize(p + 1);
9732  shape_y.SetSize(p + 1);
9733  shape_z.SetSize(p + 1);
9734  shape_l.SetSize(p + 1);
9735  dshape_x.SetSize(p + 1);
9736  dshape_y.SetSize(p + 1);
9737  dshape_z.SetSize(p + 1);
9738  dshape_l.SetSize(p + 1);
9739  u.SetSize(Dof, Dim);
9740  divu.SetSize(Dof);
9741 #else
9742  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9743 #endif
9744 
9745  int o = 0;
9746  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
9747  // the constructor of H1_TetrahedronElement)
9748  for (int j = 0; j <= p; j++)
9749  for (int i = 0; i + j <= p; i++) // (1,2,3)
9750  {
9751  double w = bop[i] + bop[j] + bop[p-i-j];
9752  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
9753  dof2nk[o++] = 0;
9754  }
9755  for (int j = 0; j <= p; j++)
9756  for (int i = 0; i + j <= p; i++) // (0,3,2)
9757  {
9758  double w = bop[i] + bop[j] + bop[p-i-j];
9759  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
9760  dof2nk[o++] = 1;
9761  }
9762  for (int j = 0; j <= p; j++)
9763  for (int i = 0; i + j <= p; i++) // (0,1,3)
9764  {
9765  double w = bop[i] + bop[j] + bop[p-i-j];
9766  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
9767  dof2nk[o++] = 2;
9768  }
9769  for (int j = 0; j <= p; j++)
9770  for (int i = 0; i + j <= p; i++) // (0,2,1)
9771  {
9772  double w = bop[i] + bop[j] + bop[p-i-j];
9773  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
9774  dof2nk[o++] = 3;
9775  }
9776 
9777  // interior
9778  for (int k = 0; k < p; k++)
9779  for (int j = 0; j + k < p; j++)
9780  for (int i = 0; i + j + k < p; i++)
9781  {
9782  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
9783  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9784  dof2nk[o++] = 1;
9785  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9786  dof2nk[o++] = 2;
9787  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9788  dof2nk[o++] = 3;
9789  }
9790 
9791  DenseMatrix T(Dof);
9792  for (int m = 0; m < Dof; m++)
9793  {
9794  const IntegrationPoint &ip = Nodes.IntPoint(m);
9795  poly1d.CalcBasis(p, ip.x, shape_x);
9796  poly1d.CalcBasis(p, ip.y, shape_y);
9797  poly1d.CalcBasis(p, ip.z, shape_z);
9798  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9799  const double *nm = nk + 3*dof2nk[m];
9800 
9801  o = 0;
9802  for (int k = 0; k <= p; k++)
9803  for (int j = 0; j + k <= p; j++)
9804  for (int i = 0; i + j + k <= p; i++)
9805  {
9806  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9807  T(o++, m) = s * nm[0];
9808  T(o++, m) = s * nm[1];
9809  T(o++, m) = s * nm[2];
9810  }
9811  for (int j = 0; j <= p; j++)
9812  for (int i = 0; i + j <= p; i++)
9813  {
9814  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9815  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
9816  (ip.z - c)*nm[2]);
9817  }
9818  }
9819 
9820  Ti.Factor(T);
9821  // mfem::out << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
9822 }
9823 
9825  DenseMatrix &shape) const
9826 {
9827  const int p = Order - 1;
9828 
9829 #ifdef MFEM_THREAD_SAFE
9830  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9831  DenseMatrix u(Dof, Dim);
9832 #endif
9833 
9834  poly1d.CalcBasis(p, ip.x, shape_x);
9835  poly1d.CalcBasis(p, ip.y, shape_y);
9836  poly1d.CalcBasis(p, ip.z, shape_z);
9837  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9838 
9839  int o = 0;
9840  for (int k = 0; k <= p; k++)
9841  for (int j = 0; j + k <= p; j++)
9842  for (int i = 0; i + j + k <= p; i++)
9843  {
9844  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9845  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
9846  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
9847  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
9848  }
9849  for (int j = 0; j <= p; j++)
9850  for (int i = 0; i + j <= p; i++)
9851  {
9852  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9853  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
9854  o++;
9855  }
9856 
9857  Ti.Mult(u, shape);
9858 }
9859 
9861  Vector &divshape) const
9862 {
9863  const int p = Order - 1;
9864 
9865 #ifdef MFEM_THREAD_SAFE
9866  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9867  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
9868  Vector divu(Dof);
9869 #endif
9870 
9871  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9872  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9873  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
9874  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
9875 
9876  int o = 0;
9877  for (int k = 0; k <= p; k++)
9878  for (int j = 0; j + k <= p; j++)
9879  for (int i = 0; i + j + k <= p; i++)
9880  {
9881  int l = p - i - j - k;
9882  divu(o++) = (dshape_x(i)*shape_l(l) -
9883  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
9884  divu(o++) = (dshape_y(j)*shape_l(l) -
9885  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
9886  divu(o++) = (dshape_z(k)*shape_l(l) -
9887  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
9888  }
9889  for (int j = 0; j <= p; j++)
9890  for (int i = 0; i + j <= p; i++)
9891  {
9892  int k = p - i - j;
9893  divu(o++) =
9894  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
9895  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
9896  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
9897  }
9898 
9899  Ti.Mult(divu, divshape);
9900 }
9901 
9902 
9903 const double ND_HexahedronElement::tk[18] =
9904 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
9905 
9907  const int cb_type, const int ob_type)
9908  : VectorFiniteElement(3, Geometry::CUBE, 3*p*(p + 1)*(p + 1), p,
9909  H_CURL, FunctionSpace::Qk),
9910  cbasis1d(poly1d.GetBasis(p, VerifyClosed(cb_type))),
9911  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(ob_type))),
9912  dof_map(Dof), dof2tk(Dof)
9913 {
9914  const double *cp = poly1d.ClosedPoints(p, cb_type);
9915  const double *op = poly1d.OpenPoints(p - 1, ob_type);
9916  const int dof3 = Dof/3;
9917 
9918 #ifndef MFEM_THREAD_SAFE
9919  shape_cx.SetSize(p + 1);
9920  shape_ox.SetSize(p);
9921  shape_cy.SetSize(p + 1);
9922  shape_oy.SetSize(p);
9923  shape_cz.SetSize(p + 1);
9924  shape_oz.SetSize(p);
9925  dshape_cx.SetSize(p + 1);
9926  dshape_cy.SetSize(p + 1);
9927  dshape_cz.SetSize(p + 1);
9928 #endif
9929 
9930  // edges
9931  int o = 0;
9932  for (int i = 0; i < p; i++) // (0,1)
9933  {
9934  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
9935  }
9936  for (int i = 0; i < p; i++) // (1,2)
9937  {
9938  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
9939  }
9940  for (int i = 0; i < p; i++) // (3,2)
9941  {
9942  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
9943  }
9944  for (int i = 0; i < p; i++) // (0,3)
9945  {
9946  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
9947  }
9948  for (int i = 0; i < p; i++) // (4,5)
9949  {
9950  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
9951  }
9952  for (int i = 0; i < p; i++) // (5,6)
9953  {
9954  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
9955  }
9956  for (int i = 0; i < p; i++) // (7,6)
9957  {
9958  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
9959  }
9960  for (int i = 0; i < p; i++) // (4,7)
9961  {
9962  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
9963  }
9964  for (int i = 0; i < p; i++) // (0,4)
9965  {
9966  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
9967  }
9968  for (int i = 0; i < p; i++) // (1,5)
9969  {
9970  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
9971  }
9972  for (int i = 0; i < p; i++) // (2,6)
9973  {
9974  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
9975  }
9976  for (int i = 0; i < p; i++) // (3,7)
9977  {
9978  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
9979  }
9980 
9981  // faces
9982  // (3,2,1,0) -- bottom
9983  for (int j = 1; j < p; j++) // x - components
9984  for (int i = 0; i < p; i++)
9985  {
9986  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
9987  }
9988  for (int j = 0; j < p; j++) // y - components
9989  for (int i = 1; i < p; i++)
9990  {
9991  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
9992  }
9993  // (0,1,5,4) -- front
9994  for (int k = 1; k < p; k++) // x - components
9995  for (int i = 0; i < p; i++)
9996  {
9997  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
9998  }
9999  for (int k = 0; k < p; k++) // z - components
10000  for (int i = 1; i < p; i++ )
10001  {
10002  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
10003  }
10004  // (1,2,6,5) -- right
10005  for (int k = 1; k < p; k++) // y - components
10006  for (int j = 0; j < p; j++)
10007  {
10008  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
10009  }
10010  for (int k = 0; k < p; k++) // z - components
10011  for (int j = 1; j < p; j++)
10012  {
10013  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
10014  }
10015  // (2,3,7,6) -- back
10016  for (int k = 1; k < p; k++) // x - components
10017  for (int i = 0; i < p; i++)
10018  {
10019  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
10020  }
10021  for (int k = 0; k < p; k++) // z - components
10022  for (int i = 1; i < p; i++)
10023  {
10024  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
10025  }
10026  // (3,0,4,7) -- left
10027  for (int k = 1; k < p; k++) // y - components
10028  for (int j = 0; j < p; j++)
10029  {
10030  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
10031  }
10032  for (int k = 0; k < p; k++) // z - components
10033  for (int j = 1; j < p; j++)
10034  {
10035  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
10036  }
10037  // (4,5,6,7) -- top
10038  for (int j = 1; j < p; j++) // x - components
10039  for (int i = 0; i < p; i++)
10040  {
10041  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
10042  }
10043  for (int j = 0; j < p; j++) // y - components
10044  for (int i = 1; i < p; i++)
10045  {
10046  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
10047  }
10048 
10049  // interior
10050  // x-components
10051  for (int k = 1; k < p; k++)
10052  for (int j = 1; j < p; j++)
10053  for (int i = 0; i < p; i++)
10054  {
10055  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
10056  }
10057  // y-components
10058  for (int k = 1; k < p; k++)
10059  for (int j = 0; j < p; j++)
10060  for (int i = 1; i < p; i++)
10061  {
10062  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
10063  }
10064  // z-components
10065  for (int k = 0; k < p; k++)
10066  for (int j = 1; j < p; j++)
10067  for (int i = 1; i < p; i++)
10068  {
10069  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
10070  }
10071 
10072  // set dof2tk and Nodes
10073  o = 0;
10074  // x-components
10075  for (int k = 0; k <= p; k++)
10076  for (int j = 0; j <= p; j++)
10077  for (int i = 0; i < p; i++)
10078  {
10079  int idx;
10080  if ((idx = dof_map[o++]) < 0)
10081  {
10082  dof2tk[idx = -1 - idx] = 3;
10083  }
10084  else
10085  {
10086  dof2tk[idx] = 0;
10087  }
10088  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
10089  }
10090  // y-components
10091  for (int k = 0; k <= p; k++)
10092  for (int j = 0; j < p; j++)
10093  for (int i = 0; i <= p; i++)
10094  {
10095  int idx;
10096  if ((idx = dof_map[o++]) < 0)
10097  {
10098  dof2tk[idx = -1 - idx] = 4;
10099  }
10100  else
10101  {
10102  dof2tk[idx] = 1;
10103  }
10104  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
10105  }
10106  // z-components
10107  for (int k = 0; k < p; k++)
10108  for (int j = 0; j <= p; j++)
10109  for (int i = 0; i <= p; i++)
10110  {
10111  int idx;
10112  if ((idx = dof_map[o++]) < 0)
10113  {
10114  dof2tk[idx = -1 - idx] = 5;
10115  }
10116  else
10117  {
10118  dof2tk[idx] = 2;
10119  }
10120  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
10121  }
10122 }
10123 
10125  DenseMatrix &shape) const
10126 {
10127  const int p = Order;
10128 
10129 #ifdef MFEM_THREAD_SAFE
10130  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10131  Vector shape_cz(p + 1), shape_oz(p);
10132 #endif
10133 
10134  cbasis1d.Eval(ip.x, shape_cx);
10135  obasis1d.Eval(ip.x, shape_ox);
10136  cbasis1d.Eval(ip.y, shape_cy);
10137  obasis1d.Eval(ip.y, shape_oy);
10138  cbasis1d.Eval(ip.z, shape_cz);
10139  obasis1d.Eval(ip.z, shape_oz);
10140 
10141  int o = 0;
10142  // x-components
10143  for (int k = 0; k <= p; k++)
10144  for (int j = 0; j <= p; j++)
10145  for (int i = 0; i < p; i++)
10146  {
10147  int idx, s;
10148  if ((idx = dof_map[o++]) < 0)
10149  {
10150  idx = -1 - idx, s = -1;
10151  }
10152  else
10153  {
10154  s = +1;
10155  }
10156  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
10157  shape(idx,1) = 0.;
10158  shape(idx,2) = 0.;
10159  }
10160  // y-components
10161  for (int k = 0; k <= p; k++)
10162  for (int j = 0; j < p; j++)
10163  for (int i = 0; i <= p; i++)
10164  {
10165  int idx, s;
10166  if ((idx = dof_map[o++]) < 0)
10167  {
10168  idx = -1 - idx, s = -1;
10169  }
10170  else
10171  {
10172  s = +1;
10173  }
10174  shape(idx,0) = 0.;
10175  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
10176  shape(idx,2) = 0.;
10177  }
10178  // z-components
10179  for (int k = 0; k < p; k++)
10180  for (int j = 0; j <= p; j++)
10181  for (int i = 0; i <= p; i++)
10182  {
10183  int idx, s;
10184  if ((idx = dof_map[o++]) < 0)
10185  {
10186  idx = -1 - idx, s = -1;
10187  }
10188  else
10189  {
10190  s = +1;
10191  }
10192  shape(idx,0) = 0.;
10193  shape(idx,1) = 0.;
10194  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
10195  }
10196 }
10197 
10199  DenseMatrix &curl_shape) const
10200 {
10201  const int p = Order;
10202 
10203 #ifdef MFEM_THREAD_SAFE
10204  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10205  Vector shape_cz(p + 1), shape_oz(p);
10206  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
10207 #endif
10208 
10209  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10210  obasis1d.Eval(ip.x, shape_ox);
10211  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10212  obasis1d.Eval(ip.y, shape_oy);
10213  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
10214  obasis1d.Eval(ip.z, shape_oz);
10215 
10216  int o = 0;
10217  // x-components
10218  for (int k = 0; k <= p; k++)
10219  for (int j = 0; j <= p; j++)
10220  for (int i = 0; i < p; i++)
10221  {
10222  int idx, s;
10223  if ((idx = dof_map[o++]) < 0)
10224  {
10225  idx = -1 - idx, s = -1;
10226  }
10227  else
10228  {
10229  s = +1;
10230  }
10231  curl_shape(idx,0) = 0.;
10232  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
10233  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
10234  }
10235  // y-components
10236  for (int k = 0; k <= p; k++)
10237  for (int j = 0; j < p; j++)
10238  for (int i = 0; i <= p; i++)
10239  {
10240  int idx, s;
10241  if ((idx = dof_map[o++]) < 0)
10242  {
10243  idx = -1 - idx, s = -1;
10244  }
10245  else
10246  {
10247  s = +1;
10248  }
10249  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
10250  curl_shape(idx,1) = 0.;
10251  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
10252  }
10253  // z-components
10254  for (int k = 0; k < p; k++)
10255  for (int j = 0; j <= p; j++)
10256  for (int i = 0; i <= p; i++)
10257  {
10258  int idx, s;
10259  if ((idx = dof_map[o++]) < 0)
10260  {
10261  idx = -1 - idx, s = -1;
10262  }
10263  else
10264  {
10265  s = +1;
10266  }
10267  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
10268  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
10269  curl_shape(idx,2) = 0.;
10270  }
10271 }
10272 
10273 
10274 const double ND_QuadrilateralElement::tk[8] =
10275 { 1.,0., 0.,1., -1.,0., 0.,-1. };
10276 
10278  const int cb_type,
10279  const int ob_type)
10280  : VectorFiniteElement(2, Geometry::SQUARE, 2*p*(p + 1), p,
10281  H_CURL, FunctionSpace::Qk),
10282  cbasis1d(poly1d.GetBasis(p, VerifyClosed(cb_type))),
10283  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(ob_type))),
10284  dof_map(Dof), dof2tk(Dof)
10285 {
10286  const double *cp = poly1d.ClosedPoints(p, cb_type);
10287  const double *op = poly1d.OpenPoints(p - 1, ob_type);
10288  const int dof2 = Dof/2;
10289 
10290 #ifndef MFEM_THREAD_SAFE
10291  shape_cx.SetSize(p + 1);
10292  shape_ox.SetSize(p);
10293  shape_cy.SetSize(p + 1);
10294  shape_oy.SetSize(p);
10295  dshape_cx.SetSize(p + 1);
10296  dshape_cy.SetSize(p + 1);
10297 #endif
10298 
10299  // edges
10300  int o = 0;
10301  for (int i = 0; i < p; i++) // (0,1)
10302  {
10303  dof_map[0*dof2 + i + 0*p] = o++;
10304  }
10305  for (int j = 0; j < p; j++) // (1,2)
10306  {
10307  dof_map[1*dof2 + p + j*(p + 1)] = o++;
10308  }
10309  for (int i = 0; i < p; i++) // (2,3)
10310  {
10311  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
10312  }
10313  for (int j = 0; j < p; j++) // (3,0)
10314  {
10315  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
10316  }
10317 
10318  // interior
10319  // x-components
10320  for (int j = 1; j < p; j++)
10321  for (int i = 0; i < p; i++)
10322  {
10323  dof_map[0*dof2 + i + j*p] = o++;
10324  }
10325  // y-components
10326  for (int j = 0; j < p; j++)
10327  for (int i = 1; i < p; i++)
10328  {
10329  dof_map[1*dof2 + i + j*(p + 1)] = o++;
10330  }
10331 
10332  // set dof2tk and Nodes
10333  o = 0;
10334  // x-components
10335  for (int j = 0; j <= p; j++)
10336  for (int i = 0; i < p; i++)
10337  {
10338  int idx;
10339  if ((idx = dof_map[o++]) < 0)
10340  {
10341  dof2tk[idx = -1 - idx] = 2;
10342  }
10343  else
10344  {
10345  dof2tk[idx] = 0;
10346  }
10347  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
10348  }
10349  // y-components
10350  for (int j = 0; j < p; j++)
10351  for (int i = 0; i <= p; i++)
10352  {
10353  int idx;
10354  if ((idx = dof_map[o++]) < 0)
10355  {
10356  dof2tk[idx = -1 - idx] = 3;
10357  }
10358  else
10359  {
10360  dof2tk[idx] = 1;
10361  }
10362  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
10363  }
10364 }
10365 
10367  DenseMatrix &shape) const
10368 {
10369  const int p = Order;
10370 
10371 #ifdef MFEM_THREAD_SAFE
10372  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10373 #endif
10374 
10375  cbasis1d.Eval(ip.x, shape_cx);
10376  obasis1d.Eval(ip.x, shape_ox);
10377  cbasis1d.Eval(ip.y, shape_cy);
10378  obasis1d.Eval(ip.y, shape_oy);
10379 
10380  int o = 0;
10381  // x-components
10382  for (int j = 0; j <= p; j++)
10383  for (int i = 0; i < p; i++)
10384  {
10385  int idx, s;
10386  if ((idx = dof_map[o++]) < 0)
10387  {
10388  idx = -1 - idx, s = -1;
10389  }
10390  else
10391  {
10392  s = +1;
10393  }
10394  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
10395  shape(idx,1) = 0.;
10396  }
10397  // y-components
10398  for (int j = 0; j < p; j++)
10399  for (int i = 0; i <= p; i++)
10400  {
10401  int idx, s;
10402  if ((idx = dof_map[o++]) < 0)
10403  {
10404  idx = -1 - idx, s = -1;
10405  }
10406  else
10407  {
10408  s = +1;
10409  }
10410  shape(idx,0) = 0.;
10411  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
10412  }
10413 }
10414 
10416  DenseMatrix &curl_shape) const
10417 {
10418  const int p = Order;
10419 
10420 #ifdef MFEM_THREAD_SAFE
10421  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10422  Vector dshape_cx(p + 1), dshape_cy(p + 1);
10423 #endif
10424 
10425  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10426  obasis1d.Eval(ip.x, shape_ox);
10427  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10428  obasis1d.Eval(ip.y, shape_oy);
10429 
10430  int o = 0;
10431  // x-components
10432  for (int j = 0; j <= p; j++)
10433  for (int i = 0; i < p; i++)
10434  {
10435  int idx, s;
10436  if ((idx = dof_map[o++]) < 0)
10437  {
10438  idx = -1 - idx, s = -1;
10439  }
10440  else
10441  {
10442  s = +1;
10443  }
10444  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
10445  }
10446  // y-components
10447  for (int j = 0; j < p; j++)
10448  for (int i = 0; i <= p; i++)
10449  {
10450  int idx, s;
10451  if ((idx = dof_map[o++]) < 0)
10452  {
10453  idx = -1 - idx, s = -1;
10454  }
10455  else
10456  {
10457  s = +1;
10458  }
10459  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
10460  }
10461 }
10462 
10463 
10464 const double ND_TetrahedronElement::tk[18] =
10465 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
10466 
10467 const double ND_TetrahedronElement::c = 1./4.;
10468 
10470  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
10471  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
10472 {
10473  const double *eop = poly1d.OpenPoints(p - 1);
10474  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10475  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
10476 
10477  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
10478 
10479 #ifndef MFEM_THREAD_SAFE
10480  shape_x.SetSize(p);
10481  shape_y.SetSize(p);
10482  shape_z.SetSize(p);
10483  shape_l.SetSize(p);
10484  dshape_x.SetSize(p);
10485  dshape_y.SetSize(p);
10486  dshape_z.SetSize(p);
10487  dshape_l.SetSize(p);
10488  u.SetSize(Dof, Dim);
10489 #else
10490  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10491 #endif
10492 
10493  int o = 0;
10494  // edges
10495  for (int i = 0; i < p; i++) // (0,1)
10496  {
10497  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
10498  dof2tk[o++] = 0;
10499  }
10500  for (int i = 0; i < p; i++) // (0,2)
10501  {
10502  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
10503  dof2tk[o++] = 1;
10504  }
10505  for (int i = 0; i < p; i++) // (0,3)
10506  {
10507  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
10508  dof2tk[o++] = 2;
10509  }
10510  for (int i = 0; i < p; i++) // (1,2)
10511  {
10512  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
10513  dof2tk[o++] = 3;
10514  }
10515  for (int i = 0; i < p; i++) // (1,3)
10516  {
10517  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
10518  dof2tk[o++] = 4;
10519  }
10520  for (int i = 0; i < p; i++) // (2,3)
10521  {
10522  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
10523  dof2tk[o++] = 5;
10524  }
10525 
10526  // faces
10527  for (int j = 0; j <= pm2; j++) // (1,2,3)
10528  for (int i = 0; i + j <= pm2; i++)
10529  {
10530  double w = fop[i] + fop[j] + fop[pm2-i-j];
10531  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10532  dof2tk[o++] = 3;
10533  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10534  dof2tk[o++] = 4;
10535  }
10536  for (int j = 0; j <= pm2; j++) // (0,3,2)
10537  for (int i = 0; i + j <= pm2; i++)
10538  {
10539  double w = fop[i] + fop[j] + fop[pm2-i-j];
10540  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10541  dof2tk[o++] = 2;
10542  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10543  dof2tk[o++] = 1;
10544  }
10545  for (int j = 0; j <= pm2; j++) // (0,1,3)
10546  for (int i = 0; i + j <= pm2; i++)
10547  {
10548  double w = fop[i] + fop[j] + fop[pm2-i-j];
10549  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10550  dof2tk[o++] = 0;
10551  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10552  dof2tk[o++] = 2;
10553  }
10554  for (int j = 0; j <= pm2; j++) // (0,2,1)
10555  for (int i = 0; i + j <= pm2; i++)
10556  {
10557  double w = fop[i] + fop[j] + fop[pm2-i-j];
10558  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10559  dof2tk[o++] = 1;
10560  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10561  dof2tk[o++] = 0;
10562  }
10563 
10564  // interior
10565  for (int k = 0; k <= pm3; k++)
10566  for (int j = 0; j + k <= pm3; j++)
10567  for (int i = 0; i + j + k <= pm3; i++)
10568  {
10569  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
10570  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10571  dof2tk[o++] = 0;
10572  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10573  dof2tk[o++] = 1;
10574  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10575  dof2tk[o++] = 2;
10576  }
10577 
10578  DenseMatrix T(Dof);
10579  for (int m = 0; m < Dof; m++)
10580  {
10581  const IntegrationPoint &ip = Nodes.IntPoint(m);
10582  const double *tm = tk + 3*dof2tk[m];
10583  o = 0;
10584 
10585  poly1d.CalcBasis(pm1, ip.x, shape_x);
10586  poly1d.CalcBasis(pm1, ip.y, shape_y);
10587  poly1d.CalcBasis(pm1, ip.z, shape_z);
10588  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10589 
10590  for (int k = 0; k <= pm1; k++)
10591  for (int j = 0; j + k <= pm1; j++)
10592  for (int i = 0; i + j + k <= pm1; i++)
10593  {
10594  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10595  T(o++, m) = s * tm[0];
10596  T(o++, m) = s * tm[1];
10597  T(o++, m) = s * tm[2];
10598  }
10599  for (int k = 0; k <= pm1; k++)
10600  for (int j = 0; j + k <= pm1; j++)
10601  {
10602  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10603  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10604  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
10605  }
10606  for (int k = 0; k <= pm1; k++)
10607  {
10608  T(o++, m) =
10609  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
10610  }
10611  }
10612 
10613  Ti.Factor(T);
10614  // mfem::out << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
10615 }
10616 
10618  DenseMatrix &shape) const
10619 {
10620  const int pm1 = Order - 1;
10621 
10622 #ifdef MFEM_THREAD_SAFE
10623  const int p = Order;
10624  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10625  DenseMatrix u(Dof, Dim);
10626 #endif
10627 
10628  poly1d.CalcBasis(pm1, ip.x, shape_x);
10629  poly1d.CalcBasis(pm1, ip.y, shape_y);
10630  poly1d.CalcBasis(pm1, ip.z, shape_z);
10631  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10632 
10633  int n = 0;
10634  for (int k = 0; k <= pm1; k++)
10635  for (int j = 0; j + k <= pm1; j++)
10636  for (int i = 0; i + j + k <= pm1; i++)
10637  {
10638  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10639  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
10640  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
10641  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
10642  }
10643  for (int k = 0; k <= pm1; k++)
10644  for (int j = 0; j + k <= pm1; j++)
10645  {
10646  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10647  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
10648  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
10649  }
10650  for (int k = 0; k <= pm1; k++)
10651  {
10652  double s = shape_y(pm1-k)*shape_z(k);
10653  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
10654  }
10655 
10656  Ti.Mult(u, shape);
10657 }
10658 
10660  DenseMatrix &curl_shape) const
10661 {
10662  const int pm1 = Order - 1;
10663 
10664 #ifdef MFEM_THREAD_SAFE
10665  const int p = Order;
10666  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10667  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
10668  DenseMatrix u(Dof, Dim);
10669 #endif
10670 
10671  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10672  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10673  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
10674  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10675 
10676  int n = 0;
10677  for (int k = 0; k <= pm1; k++)
10678  for (int j = 0; j + k <= pm1; j++)
10679  for (int i = 0; i + j + k <= pm1; i++)
10680  {
10681  int l = pm1-i-j-k;
10682  const double dx = (dshape_x(i)*shape_l(l) -
10683  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
10684  const double dy = (dshape_y(j)*shape_l(l) -
10685  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
10686  const double dz = (dshape_z(k)*shape_l(l) -
10687  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
10688 
10689  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
10690  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
10691  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
10692  }
10693  for (int k = 0; k <= pm1; k++)
10694  for (int j = 0; j + k <= pm1; j++)
10695  {
10696  int i = pm1 - j - k;
10697  // s = shape_x(i)*shape_y(j)*shape_z(k);
10698  // curl of s*(ip.y - c, -(ip.x - c), 0):
10699  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
10700  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
10701  u(n,2) =
10702  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
10703  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
10704  n++;
10705  // curl of s*(ip.z - c, 0, -(ip.x - c)):
10706  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
10707  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
10708  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
10709  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
10710  n++;
10711  }
10712  for (int k = 0; k <= pm1; k++)
10713  {
10714  int j = pm1 - k;
10715  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
10716  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
10717  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
10718  u(n,1) = 0.;
10719  u(n,2) = 0.; n++;
10720  }
10721 
10722  Ti.Mult(u, curl_shape);
10723 }
10724 
10725 
10726 const double ND_TriangleElement::tk[8] =
10727 { 1.,0., -1.,1., 0.,-1., 0.,1. };
10728 
10729 const double ND_TriangleElement::c = 1./3.;
10730 
10732  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
10733  H_CURL, FunctionSpace::Pk),
10734  dof2tk(Dof)
10735 {
10736  const double *eop = poly1d.OpenPoints(p - 1);
10737  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10738 
10739  const int pm1 = p - 1, pm2 = p - 2;
10740 
10741 #ifndef MFEM_THREAD_SAFE
10742  shape_x.SetSize(p);
10743  shape_y.SetSize(p);
10744  shape_l.SetSize(p);
10745  dshape_x.SetSize(p);
10746  dshape_y.SetSize(p);
10747  dshape_l.SetSize(p);
10748  u.SetSize(Dof, Dim);
10749  curlu.SetSize(Dof);
10750 #else
10751  Vector shape_x(p), shape_y(p), shape_l(p);
10752 #endif
10753 
10754  int n = 0;
10755  // edges
10756  for (int i = 0; i < p; i++) // (0,1)
10757  {
10758  Nodes.IntPoint(n).Set2(eop[i], 0.);
10759  dof2tk[n++] = 0;
10760  }
10761  for (int i = 0; i < p; i++) // (1,2)
10762  {
10763  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
10764  dof2tk[n++] = 1;
10765  }
10766  for (int i = 0; i < p; i++) // (2,0)
10767  {
10768  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
10769  dof2tk[n++] = 2;
10770  }
10771 
10772  // interior
10773  for (int j = 0; j <= pm2; j++)
10774  for (int i = 0; i + j <= pm2; i++)
10775  {
10776  double w = iop[i] + iop[j] + iop[pm2-i-j];
10777  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10778  dof2tk[n++] = 0;
10779  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10780  dof2tk[n++] = 3;
10781  }
10782 
10783  DenseMatrix T(Dof);
10784  for (int m = 0; m < Dof; m++)
10785  {
10786  const IntegrationPoint &ip = Nodes.IntPoint(m);
10787  const double *tm = tk + 2*dof2tk[m];
10788  n = 0;
10789 
10790  poly1d.CalcBasis(pm1, ip.x, shape_x);
10791  poly1d.CalcBasis(pm1, ip.y, shape_y);
10792  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10793 
10794  for (int j = 0; j <= pm1; j++)
10795  for (int i = 0; i + j <= pm1; i++)
10796  {
10797  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10798  T(n++, m) = s * tm[0];
10799  T(n++, m) = s * tm[1];
10800  }
10801  for (int j = 0; j <= pm1; j++)
10802  {
10803  T(n++, m) =
10804  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10805  }
10806  }
10807 
10808  Ti.Factor(T);
10809  // mfem::out << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
10810 }
10811 
10813  DenseMatrix &shape) const
10814 {
10815  const int pm1 = Order - 1;
10816 
10817 #ifdef MFEM_THREAD_SAFE
10818  const int p = Order;
10819  Vector shape_x(p), shape_y(p), shape_l(p);
10820  DenseMatrix u(Dof, Dim);
10821 #endif
10822 
10823  poly1d.CalcBasis(pm1, ip.x, shape_x);
10824  poly1d.CalcBasis(pm1, ip.y, shape_y);
10825  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10826 
10827  int n = 0;
10828  for (int j = 0; j <= pm1; j++)
10829  for (int i = 0; i + j <= pm1; i++)
10830  {
10831  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10832  u(n,0) = s; u(n,1) = 0; n++;
10833  u(n,0) = 0; u(n,1) = s; n++;
10834  }
10835  for (int j = 0; j <= pm1; j++)
10836  {
10837  double s = shape_x(pm1-j)*shape_y(j);
10838  u(n,0) = s*(ip.y - c);
10839  u(n,1) = -s*(ip.x - c);
10840  n++;
10841  }
10842 
10843  Ti.Mult(u, shape);
10844 }
10845 
10847  DenseMatrix &curl_shape) const
10848 {
10849  const int pm1 = Order - 1;
10850 
10851 #ifdef MFEM_THREAD_SAFE
10852  const int p = Order;
10853  Vector shape_x(p), shape_y(p), shape_l(p);
10854  Vector dshape_x(p), dshape_y(p), dshape_l(p);
10855  Vector curlu(Dof);
10856 #endif
10857 
10858  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10859  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10860  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
10861 
10862  int n = 0;
10863  for (int j = 0; j <= pm1; j++)
10864  for (int i = 0; i + j <= pm1; i++)
10865  {
10866  int l = pm1-i-j;
10867  const double dx = (dshape_x(i)*shape_l(l) -
10868  shape_x(i)*dshape_l(l)) * shape_y(j);
10869  const double dy = (dshape_y(j)*shape_l(l) -
10870  shape_y(j)*dshape_l(l)) * shape_x(i);
10871 
10872  curlu(n++) = -dy;
10873  curlu(n++) = dx;
10874  }
10875 
10876  for (int j = 0; j <= pm1; j++)
10877  {
10878  int i = pm1 - j;
10879  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
10880  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
10881  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
10882  }
10883 
10884  Vector curl2d(curl_shape.Data(),Dof);
10885  Ti.Mult(curlu, curl2d);
10886 }
10887 
10888 
10889 const double ND_SegmentElement::tk[1] = { 1. };
10890 
10891 ND_SegmentElement::ND_SegmentElement(const int p, const int ob_type)
10892  : VectorFiniteElement(1, Geometry::SEGMENT, p, p - 1,
10893  H_CURL, FunctionSpace::Pk),
10894  obasis1d(poly1d.GetBasis(p - 1, VerifyOpen(ob_type))),
10895  dof2tk(Dof)
10896 {
10897  const double *op = poly1d.OpenPoints(p - 1, ob_type);
10898 
10899  // set dof2tk and Nodes
10900  for (int i = 0; i < p; i++)
10901  {
10902  dof2tk[i] = 0;
10903  Nodes.IntPoint(i).x = op[i];
10904  }
10905 }
10906 
10908  DenseMatrix &shape) const
10909 {
10910  Vector vshape(shape.Data(), Dof);
10911 
10912  obasis1d.Eval(ip.x, vshape);
10913 }
10914 
10916 {
10917  Order = kv[0]->GetOrder();
10918  Dof = Order + 1;
10919 
10920  weights.SetSize(Dof);
10921  shape_x.SetSize(Dof);
10922 }
10923 
10925  Vector &shape) const
10926 {
10927  kv[0]->CalcShape(shape, ijk[0], ip.x);
10928 
10929  double sum = 0.0;
10930  for (int i = 0; i <= Order; i++)
10931  {
10932  sum += (shape(i) *= weights(i));
10933  }
10934 
10935  shape /= sum;
10936 }
10937 
10939  DenseMatrix &dshape) const
10940 {
10941  Vector grad(dshape.Data(), Dof);
10942 
10943  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
10944  kv[0]->CalcDShape(grad, ijk[0], ip.x);
10945 
10946  double sum = 0.0, dsum = 0.0;
10947  for (int i = 0; i <= Order; i++)
10948  {
10949  sum += (shape_x(i) *= weights(i));
10950  dsum += ( grad(i) *= weights(i));
10951  }
10952 
10953  sum = 1.0/sum;
10954  add(sum, grad, -dsum*sum*sum, shape_x, grad);
10955 }
10956 
10958 {
10959  Orders[0] = kv[0]->GetOrder();
10960  Orders[1] = kv[1]->GetOrder();
10961  shape_x.SetSize(Orders[0]+1);
10962  shape_y.SetSize(Orders[1]+1);
10963  dshape_x.SetSize(Orders[0]+1);
10964  dshape_y.SetSize(Orders[1]+1);
10965 
10966  Order = max(Orders[0], Orders[1]);
10967  Dof = (Orders[0] + 1)*(Orders[1] + 1);
10968  u.SetSize(Dof);
10969  weights.SetSize(Dof);
10970 }
10971 
10973  Vector &shape) const
10974 {
10975  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
10976  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
10977 
10978  double sum = 0.0;
10979  for (int o = 0, j = 0; j <= Orders[1]; j++)
10980  {
10981  const double sy = shape_y(j);
10982  for (int i = 0; i <= Orders[0]; i++, o++)
10983  {
10984  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
10985  }
10986  }
10987 
10988  shape /= sum;
10989 }
10990 
10992  DenseMatrix &dshape) const
10993 {
10994  double sum, dsum[2];
10995 
10996  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
10997  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
10998 
10999  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
11000  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
11001 
11002  sum = dsum[0] = dsum[1] = 0.0;
11003  for (int o = 0, j = 0; j <= Orders[1]; j++)
11004  {
11005  const double sy = shape_y(j), dsy = dshape_y(j);
11006  for (int i = 0; i <= Orders[0]; i++, o++)
11007  {
11008  sum += ( u(o) = shape_x(i)*sy*weights(o) );
11009 
11010  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
11011  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
11012  }
11013  }
11014 
11015  sum = 1.0/sum;
11016  dsum[0] *= sum*sum;
11017  dsum[1] *= sum*sum;
11018 
11019  for (int o = 0; o < Dof; o++)
11020  {
11021  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11022  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11023  }
11024 }
11025 
11026 //---------------------------------------------------------------------
11028 {
11029  Orders[0] = kv[0]->GetOrder();
11030  Orders[1] = kv[1]->GetOrder();
11031  Orders[2] = kv[2]->GetOrder();
11032  shape_x.SetSize(Orders[0]+1);
11033  shape_y.SetSize(Orders[1]+1);
11034  shape_z.SetSize(Orders[2]+1);
11035 
11036  dshape_x.SetSize(Orders[0]+1);
11037  dshape_y.SetSize(Orders[1]+1);
11038  dshape_z.SetSize(Orders[2]+1);
11039 
11040  Order = max(max(Orders[0], Orders[1]), Orders[2]);
11041  Dof = (Orders[0] + 1)*(Orders[1] + 1)*(Orders[2] + 1);
11042  u.SetSize(Dof);
11043  weights.SetSize(Dof);
11044 }
11045 
11047  Vector &shape) const
11048 {
11049  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
11050  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
11051  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
11052 
11053  double sum = 0.0;
11054  for (int o = 0, k = 0; k <= Orders[2]; k++)
11055  {
11056  const double sz = shape_z(k);
11057  for (int j = 0; j <= Orders[1]; j++)
11058  {
11059  const double sy_sz = shape_y(j)*sz;
11060  for (int i = 0; i <= Orders[0]; i++, o++)
11061  {
11062  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
11063  }
11064  }
11065  }
11066 
11067  shape /= sum;
11068 }
11069 
11071  DenseMatrix &dshape) const
11072 {
11073  double sum, dsum[3];
11074 
11075  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
11076  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
11077  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
11078 
11079  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
11080  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
11081  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
11082 
11083  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
11084  for (int o = 0, k = 0; k <= Orders[2]; k++)
11085  {
11086  const double sz = shape_z(k), dsz = dshape_z(k);
11087  for (int j = 0; j <= Orders[1]; j++)
11088  {
11089  const double sy_sz = shape_y(j)* sz;
11090  const double dsy_sz = dshape_y(j)* sz;
11091  const double sy_dsz = shape_y(j)*dsz;
11092  for (int i = 0; i <= Orders[0]; i++, o++)
11093  {
11094  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
11095 
11096  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
11097  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
11098  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
11099  }
11100  }
11101  }
11102 
11103  sum = 1.0/sum;
11104  dsum[0] *= sum*sum;
11105  dsum[1] *= sum*sum;
11106  dsum[2] *= sum*sum;
11107 
11108  for (int o = 0; o < Dof; o++)
11109  {
11110  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11111  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11112  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
11113  }
11114 }
11115 
11116 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:232
Abstract class for Finite Elements.
Definition: fe.hpp:140
RefinedLinear3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:4291
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1404
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:8260
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:3356
ND_SegmentElement(const int p, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:10891
int Size() const
Logical size of the array.
Definition: array.hpp:133
const DenseMatrix & AdjugateJacobian()
Definition: eltrans.hpp:72
For scalar fields; preserves point values.
Definition: fe.hpp:180
DenseMatrix curlshape_J
Definition: fe.hpp:565
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:6090
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:211
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7304
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:2928
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:3869
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:1152
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:83
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8650
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:10991
Linear3DFiniteElement()
Construct a linear FE on tetrahedron.
Definition: fe.cpp:2327
static int Check(int b_type)
If the input does not represents a valid BasisType, abort with an error; otherwise return the input...
Definition: fe.hpp:44
static double CalcDelta(const int p, const double x)
Definition: fe.hpp:1622
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:3110
No derivatives implemented.
Definition: fe.hpp:195
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8411
void ProjectMatrixCoefficient_RT(const double *nk, const Array< int > &d2n, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:590
int NumCols() const
Definition: array.hpp:311
void ProjectMatrixCoefficient_ND(const double *tk, const Array< int > &d2t, MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:766
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:9824
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:40
RefinedBiLinear2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4523
NodalTensorFiniteElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:6876
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:1722
void LocalInterpolation_RT(const VectorFiniteElement &cfe, const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:860
L2Pos_TriangleElement(const int p)
Definition: fe.cpp:8794
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:7246
Basis(const int p, const double *nodes, EvalType etype=Barycentric)
Create a nodal or positive (Bernstein) basis.
Definition: fe.cpp:6195
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:171
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:5135
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:124
Array< const KnotVector * > kv
Definition: fe.hpp:2533
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:2565
void CalcPhysDivShape(ElementTransformation &Trans, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in physical space at the po...
Definition: fe.cpp:61
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2344
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8833
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:2882
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3162
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:1518
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:7284
PositiveTensorFiniteElement(const int dims, const int p, const DofMapType dmtype)
Definition: fe.cpp:6885
void GivePolyPoints(const int np, double *pts, const int type)
Definition: intrules.cpp:596
L2Pos_TetrahedronElement(const int p)
Definition: fe.cpp:8988
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:334
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:547
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:328
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:9206
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:5197
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:3652
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1073
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:295
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:1542
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1900
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:1811
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:2647
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:478
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
evaluate derivatives of shape function - constant 0
Definition: fe.cpp:2298
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:962
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6949
virtual void Eval(DenseMatrix &K, ElementTransformation &T, const IntegrationPoint &ip)=0
H1Pos_TetrahedronElement(const int p)
Definition: fe.cpp:7887
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:10924
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:8279
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
Definition: densemat.cpp:315
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:52
LagrangeHexFiniteElement(int degree)
Definition: fe.cpp:3921
TensorBasisElement(const int dims, const int p, const int btype, const DofMapType dmtype)
Definition: fe.cpp:6676
L2_SegmentElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:8139
int GetOrder() const
Returns the order of the finite element. In the case of anisotropic orders, returns the maximum order...
Definition: fe.hpp:221
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:2660
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:3775
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:4083
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:3727
int Size() const
Returns the size of the vector.
Definition: vector.hpp:120
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:397
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:10938
static int GetQuadrature1D(int b_type)
Get the corresponding Quadrature1D constant, when that makes sense; otherwise return Quadrature1D::In...
Definition: fe.hpp:60
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:9680
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:5363
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:692
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:2313
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:10915
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:1971
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:111
const DenseMatrix & InverseJacobian()
Definition: eltrans.hpp:75
RefinedTriLinear3DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4670
DenseMatrix vshape
Definition: fe.hpp:153
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:3908
Quadratic3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:2383
int GetMapType() const
Definition: fe.hpp:237
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:8155
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:5713
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:5900
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:4160
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:2759
const IntegrationPoint & GetIntPoint()
Definition: eltrans.hpp:54
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8953
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
Nodal interpolation.
Definition: fe.cpp:201
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:2023
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:9018
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:2590
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:2582
const IntegrationPoint & GetCenter(int GeomType)
Return the center of the given Geometry::Type, GeomType.
Definition: geom.hpp:62
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:8217
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:7001
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:730
H1Pos_HexahedronElement(const int p)
Definition: fe.cpp:7379
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:155
double * GetData() const
Return a pointer to the beginning of the Vector data.
Definition: vector.hpp:129
static void CalcShape(const int p, const double x, const double y, const double z, double *shape)
Definition: fe.cpp:7989
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:8895
Implements CalcDivShape methods.
Definition: fe.hpp:197
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
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:7351
Linear2DFiniteElement()
Construct a linear FE on triangle.
Definition: fe.cpp:976
const double * ClosedPoints(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.hpp:1590
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:2440
Possible basis types. Note that not all elements can use all BasisType(s).
Definition: fe.hpp:27
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:6035
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:260
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4859
H1_HexahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7091
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:10812
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:943
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:2043
void CalcPhysCurlShape(ElementTransformation &Trans, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in physical space at the point de...
Definition: fe.cpp:75
L2Pos_HexahedronElement(const int p)
Definition: fe.cpp:8578
ND_TriangleElement(const int p)
Definition: fe.cpp:10731
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:9860
static void CalcDShape(const int p, const double x, const double y, const double z, double *dshape_1d, double *dshape)
Definition: fe.cpp:8022
static void CalcBasis(const int p, const double x, double *u)
Definition: fe.hpp:1606
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
evaluate shape function - constant 1
Definition: fe.cpp:2292
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:2071
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:6436
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:105
const double * GetPoints(const int p, const int btype)
Get the coordinates of the points of the given BasisType, btype.
Definition: fe.cpp:6601
H1Pos_TriangleElement(const int p)
Definition: fe.cpp:7742
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:3364
Cubic3DFiniteElement()
Construct a cubic FE on tetrahedron.
Definition: fe.cpp:2118
Linear1DFiniteElement()
Construct a linear FE on interval.
Definition: fe.cpp:955
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4232
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:6023
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:1591
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:4193
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:163
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:1209
static void CalcShape(const int p, const double x, const double y, double *shape)
Definition: fe.cpp:7797
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:2613
void SetSize(int m, int n)
Definition: array.hpp:308
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2211
Geometry Geometries
Definition: geom.cpp:760
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:235
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:3670
Implements CalcCurlShape methods.
Definition: fe.hpp:198
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:219
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:3114
int Dof
Number of degrees of freedom.
Definition: fe.hpp:148
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:8161
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1169
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1180
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1428
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:4121
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7161
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7372
ND_HexahedronElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:9906
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:1695
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:8736
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:7520
Poly_1D::Basis & basis1d
Definition: fe.hpp:1653
For scalar fields; preserves volume integrals.
Definition: fe.hpp:181
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4148
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
Definition: error.cpp:146
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:3303
static void ChebyshevPoints(const int p, double *x)
Definition: fe.cpp:6404
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
Definition: densemat.cpp:3803
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:6160
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 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:6001
int GetSpaceDim() const
Get the dimension of the target (physical) space.
Definition: eltrans.hpp:93
ND_TetrahedronElement(const int p)
Definition: fe.cpp:10469
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:8822
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
H1_QuadrilateralElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:6977
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:949
int GeomType
Geometry::Type of the reference element.
Definition: fe.hpp:143
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:1986
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:642
const IntegrationRule & GetNodes() const
Definition: fe.hpp:270
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5250
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1250
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8493
static int VerifyOpen(int b_type)
Definition: fe.hpp:423
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:2418
L2Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:8348
const int * ijk
Definition: fe.hpp:2534
P0SegmentFiniteElement(int Ord=0)
Definition: fe.cpp:2553
static void CalcDShape(const int p, const double x, const double y, double *dshape_1d, double *dshape)
Definition: fe.cpp:7823
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:2905
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:11046
DenseMatrix curlshape
Definition: fe.hpp:565
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
Definition: densemat.cpp:3825
H1_SegmentElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:6893
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:9420
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:5301
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:189
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:8714
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:9159
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:1850
L2_QuadrilateralElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:8241
void SetData(double *d)
Definition: vector.hpp:94
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:3562
Basis & GetBasis(const int p, const int btype)
Get a Poly_1D::Basis object of the given degree and BasisType, btype.
Definition: fe.cpp:6625
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1025
void GetColumn(int c, Vector &col) const
Definition: densemat.cpp:2312
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2353
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:9494
const double * OpenPoints(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.hpp:1587
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:7683
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1274
void ScalarLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const ScalarFiniteElement &fine_fe) const
&quot;Interpolation&quot; defined through local L2-projection.
Definition: fe.cpp:235
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:1352
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:839
L2_TetrahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:8845
static const int MaxDim
Definition: geom.hpp:35
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:8816
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3150
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:11070
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:1366
int GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:214
DenseMatrix m_dshape
Definition: fe.hpp:1859
int Dim
Dimension of reference space.
Definition: fe.hpp:143
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:10415
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:8372
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:63
IntegrationRule Nodes
Definition: fe.hpp:151
Array< int > dof_map
Definition: fe.hpp:1652
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1236
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:8605
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:7264
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7446
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3614
int Orders[Geometry::MaxDim]
Anisotropic orders.
Definition: fe.hpp:150
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:10846
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:2774
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4546
void LocalInterpolation_ND(const VectorFiniteElement &cfe, const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:899
ND_QuadrilateralElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:10277
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:2671
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:559
DenseMatrix Jinv
Definition: fe.hpp:564
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8172
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:217
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:7708
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:1120
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:5331
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:9011
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:179
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:569
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:987
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4716
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:4413
static const int * Binom(const int p)
Get a pointer to an array containing the binomial coefficients &quot;p choose k&quot; for k=0,...,p for the given p.
Definition: fe.cpp:6387
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:3464
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:54
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:1055
H1_TetrahedronElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7572
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:11027
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:8920
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:10124
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2838
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:101
FiniteElement(int D, int G, int Do, int O, int F=FunctionSpace::Pk)
Definition: fe.cpp:25
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1477
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2498
Quad1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:1161
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:7401
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:100
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:1109
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1016
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:68
H1Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:7311
H1_TriangleElement(const int p, const int btype=BasisType::GaussLobatto)
Definition: fe.cpp:7453
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:969
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8765
virtual void ProjectMatrixCoefficient(MatrixCoefficient &mc, ElementTransformation &T, Vector &dofs) const
Definition: fe.cpp:136
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:7422
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:8223
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:2319
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:8626
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:570
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:7116
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:1144
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:3278
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:10617
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:3038
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:10366
static int VerifyClosed(int b_type)
Definition: fe.hpp:417
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:426
int DerivRangeType
Definition: fe.hpp:143
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:2786
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:8234
RefinedLinear2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:4167
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5955
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:276
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4129
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:3857
Array< int > dof_map
Definition: fe.hpp:1861
RT_TetrahedronElement(const int p)
Definition: fe.cpp:9722
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Return the local interpolation matrix I (Dof x Dof) where the fine element is the image of the base g...
Definition: fe.cpp:5511
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:4062
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:6930
BiQuad2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:1381
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:2373
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:3075
P0TriangleFiniteElement()
Construct P0 triangle finite element.
Definition: fe.cpp:2285
static int VerifyNodal(int b_type)
Definition: fe.hpp:428
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:2559
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
RT_TriangleElement(const int p)
Definition: fe.cpp:9569
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:6911
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:10907
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:10198
void Eval(const double x, Vector &u) const
Definition: fe.cpp:6253
L2Pos_SegmentElement(const int p)
Definition: fe.cpp:8196
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:4326
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5566
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:3631
Vector data type.
Definition: vector.hpp:48
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:5497
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:168
static void CalcBernstein(const int p, const double x, double *u)
Definition: fe.hpp:1638
virtual void Transform(const IntegrationPoint &, Vector &)=0
virtual void SetOrder() const
Update the NURBSFiniteElement according to the currently set knot vectors.
Definition: fe.cpp:10957
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:7331
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:8469
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1302
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:9647
Quad2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:1219
Describes the space on each element.
Definition: fe.hpp:122
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2514
Bernstein polynomials.
Definition: fe.hpp:35
virtual void GetTransferMatrix(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
Return interpolation matrix, I, which maps dofs from a coarse element, fe, to the fine dofs on this f...
Definition: fe.cpp:117
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5416
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:8391
RT_HexahedronElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:9256
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:10659
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:3914
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:1620
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:995
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:2183
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:2624
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:7042
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:5467
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:3682
RT_QuadrilateralElement(const int p, const int cb_type=BasisType::GaussLobatto, const int ob_type=BasisType::GaussLegendre)
Definition: fe.cpp:9045
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4597
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:10972
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:749
int GetRangeType() const
Definition: fe.hpp:233
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:1098
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:353
int Order
Order/degree of the shape functions.
Definition: fe.hpp:148
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2980
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
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:7137
L2_HexahedronElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:8426
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:7020
static void CalcDBinomTerms(const int p, const double x, const double y, double *d)
Definition: fe.cpp:6500
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:5080
TriLinear3DFiniteElement()
Construct a tri-linear FE on cube.
Definition: fe.cpp:2462
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:142
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:1199
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:8448
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4184
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:3643
L2_TriangleElement(const int p, const int btype=BasisType::GaussLegendre)
Definition: fe.cpp:8669
BiLinear2DFiniteElement()
Construct a bilinear FE on quadrilateral.
Definition: fe.cpp:1003
Poly_1D poly1d
Definition: fe.cpp:6672
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:6143
Lagrange1DFiniteElement(int degree)
Definition: fe.cpp:3695
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2723
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:5836
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:9029
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8299
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:1065
const int ir_order
Definition: ex1.cpp:44
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:7542
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:665
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:458