MFEM  v3.3
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
fe.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Finite Element classes
13 
14 #include "fe.hpp"
15 #include "../mesh/nurbs.hpp"
16 #include "bilininteg.hpp"
17 #include <cmath>
18 
19 namespace mfem
20 {
21 
22 using namespace std;
23 
24 FiniteElement::FiniteElement(int D, int G, int Do, int O, int F)
25  : Nodes(Do)
26 {
27  Dim = D ; GeomType = G ; Dof = Do ; Order = O ; FuncSpace = F;
28  RangeType = SCALAR;
29  MapType = VALUE;
30  DerivType = NONE;
33 #ifndef MFEM_THREAD_SAFE
35 #endif
36 }
37 
39  const IntegrationPoint &ip, DenseMatrix &shape) const
40 {
41  mfem_error ("FiniteElement::CalcVShape (ip, ...)\n"
42  " is not implemented for this class!");
43 }
44 
47 {
48  mfem_error ("FiniteElement::CalcVShape (trans, ...)\n"
49  " is not implemented for this class!");
50 }
51 
53  const IntegrationPoint &ip, Vector &divshape) const
54 {
55  mfem_error ("FiniteElement::CalcDivShape (ip, ...)\n"
56  " is not implemented for this class!");
57 }
58 
60  ElementTransformation &Trans, Vector &div_shape) const
61 {
62  CalcDivShape(Trans.GetIntPoint(), div_shape);
63  div_shape *= (1.0 / Trans.Weight());
64 }
65 
67  DenseMatrix &curl_shape) const
68 {
69  mfem_error ("FiniteElement::CalcCurlShape (ip, ...)\n"
70  " is not implemented for this class!");
71 }
72 
74  DenseMatrix &curl_shape) const
75 {
76  switch (Dim)
77  {
78  case 3:
79  {
80 #ifdef MFEM_THREAD_SAFE
82 #endif
84  MultABt(vshape, Trans.Jacobian(), curl_shape);
85  curl_shape *= (1.0 / Trans.Weight());
86  break;
87  }
88  case 2:
89  // This is valid for both 2x2 and 3x2 Jacobians
90  CalcCurlShape(Trans.GetIntPoint(), curl_shape);
91  curl_shape *= (1.0 / Trans.Weight());
92  break;
93  default:
94  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
95  }
96 }
97 
98 void FiniteElement::GetFaceDofs(int face, int **dofs, int *ndofs) const
99 {
100  mfem_error ("FiniteElement::GetFaceDofs (...)");
101 }
102 
104  DenseMatrix &h) const
105 {
106  mfem_error ("FiniteElement::CalcHessian (...) is not overloaded !");
107 }
108 
110  DenseMatrix &I) const
111 {
112  mfem_error ("GetLocalInterpolation (...) is not overloaded !");
113 }
114 
116  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
117 {
118  mfem_error ("FiniteElement::Project (...) is not overloaded !");
119 }
120 
123 {
124  mfem_error ("FiniteElement::Project (...) (vector) is not overloaded !");
125 }
126 
127 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
128 {
129  mfem_error("FiniteElement::ProjectDelta(...) is not implemented for "
130  "this element!");
131 }
132 
135 {
136  mfem_error("FiniteElement::Project(...) (fe version) is not implemented "
137  "for this element!");
138 }
139 
142  DenseMatrix &grad) const
143 {
144  mfem_error("FiniteElement::ProjectGrad(...) is not implemented for "
145  "this element!");
146 }
147 
150  DenseMatrix &curl) const
151 {
152  mfem_error("FiniteElement::ProjectCurl(...) is not implemented for "
153  "this element!");
154 }
155 
158  DenseMatrix &div) const
159 {
160  mfem_error("FiniteElement::ProjectDiv(...) is not implemented for "
161  "this element!");
162 }
163 
165  Vector &shape) const
166 {
167  CalcShape(Trans.GetIntPoint(), shape);
168  if (MapType == INTEGRAL)
169  {
170  shape /= Trans.Weight();
171  }
172 }
173 
175  DenseMatrix &dshape) const
176 {
177  MFEM_ASSERT(MapType == VALUE, "");
178 #ifdef MFEM_THREAD_SAFE
180 #endif
181  CalcDShape(Trans.GetIntPoint(), vshape);
182  Mult(vshape, Trans.InverseJacobian(), dshape);
183 }
184 
187  const NodalFiniteElement &fine_fe) const
188 {
189  double v[3];
190  Vector vv (v, Dim);
191  IntegrationPoint f_ip;
192 
193 #ifdef MFEM_THREAD_SAFE
194  Vector c_shape(Dof);
195 #endif
196 
197  MFEM_ASSERT(MapType == fine_fe.GetMapType(), "");
198 
199  for (int i = 0; i < fine_fe.Dof; i++)
200  {
201  Trans.Transform (fine_fe.Nodes.IntPoint (i), vv);
202  f_ip.Set(v, Dim);
203  CalcShape (f_ip, c_shape);
204  for (int j = 0; j < Dof; j++)
205  if (fabs (I (i,j) = c_shape (j)) < 1.0e-12)
206  {
207  I (i,j) = 0.0;
208  }
209  }
210  if (MapType == INTEGRAL)
211  {
212  // assuming Trans is linear; this should be ok for all refinement types
214  I *= Trans.Weight();
215  }
216 }
217 
220  DenseMatrix &curl) const
221 {
222  MFEM_ASSERT(GetMapType() == FiniteElement::INTEGRAL, "");
223 
224  DenseMatrix curl_shape(fe.GetDof(), 1);
225 
226  curl.SetSize(Dof, fe.GetDof());
227  for (int i = 0; i < Dof; i++)
228  {
229  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
230  for (int j = 0; j < fe.GetDof(); j++)
231  {
232  curl(i,j) = curl_shape(j,0);
233  }
234  }
235 }
236 
238  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
239 {
240  for (int i = 0; i < Dof; i++)
241  {
242  const IntegrationPoint &ip = Nodes.IntPoint(i);
243  // some coefficients expect that Trans.IntPoint is the same
244  // as the second argument of Eval
245  Trans.SetIntPoint(&ip);
246  dofs(i) = coeff.Eval (Trans, ip);
247  if (MapType == INTEGRAL)
248  {
249  dofs(i) *= Trans.Weight();
250  }
251  }
252 }
253 
256 {
257  MFEM_ASSERT(vc.GetVDim() <= 3, "");
258 
259  double v[3];
260  Vector x (v, vc.GetVDim());
261 
262  for (int i = 0; i < Dof; i++)
263  {
264  const IntegrationPoint &ip = Nodes.IntPoint(i);
265  Trans.SetIntPoint(&ip);
266  vc.Eval (x, Trans, ip);
267  if (MapType == INTEGRAL)
268  {
269  x *= Trans.Weight();
270  }
271  for (int j = 0; j < x.Size(); j++)
272  {
273  dofs(Dof*j+i) = v[j];
274  }
275  }
276 }
277 
280 {
281  if (fe.GetRangeType() == SCALAR)
282  {
283  MFEM_ASSERT(MapType == fe.GetMapType(), "");
284 
285  Vector shape(fe.GetDof());
286 
287  I.SetSize(Dof, fe.GetDof());
288  for (int k = 0; k < Dof; k++)
289  {
290  fe.CalcShape(Nodes.IntPoint(k), shape);
291  for (int j = 0; j < shape.Size(); j++)
292  {
293  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
294  }
295  }
296  }
297  else
298  {
299  DenseMatrix vshape(fe.GetDof(), Dim);
300 
301  I.SetSize(Dim*Dof, fe.GetDof());
302  for (int k = 0; k < Dof; k++)
303  {
304  Trans.SetIntPoint(&Nodes.IntPoint(k));
305  fe.CalcVShape(Trans, vshape);
306  if (MapType == INTEGRAL)
307  {
308  vshape *= Trans.Weight();
309  }
310  for (int j = 0; j < vshape.Height(); j++)
311  for (int d = 0; d < vshape.Width(); d++)
312  {
313  I(k+d*Dof,j) = vshape(j,d);
314  }
315  }
316  }
317 }
318 
321  DenseMatrix &grad) const
322 {
323  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
324  MFEM_ASSERT(Trans.GetSpaceDim() == Dim, "")
325 
326  DenseMatrix dshape(fe.GetDof(), Dim), grad_k(fe.GetDof(), Dim), Jinv(Dim);
327 
328  grad.SetSize(Dim*Dof, fe.GetDof());
329  for (int k = 0; k < Dof; k++)
330  {
331  const IntegrationPoint &ip = Nodes.IntPoint(k);
332  fe.CalcDShape(ip, dshape);
333  Trans.SetIntPoint(&ip);
334  CalcInverse(Trans.Jacobian(), Jinv);
335  Mult(dshape, Jinv, grad_k);
336  if (MapType == INTEGRAL)
337  {
338  grad_k *= Trans.Weight();
339  }
340  for (int j = 0; j < grad_k.Height(); j++)
341  for (int d = 0; d < Dim; d++)
342  {
343  grad(k+d*Dof,j) = grad_k(j,d);
344  }
345  }
346 }
347 
350  DenseMatrix &div) const
351 {
352  double detJ;
353  Vector div_shape(fe.GetDof());
354 
355  div.SetSize(Dof, fe.GetDof());
356  for (int k = 0; k < Dof; k++)
357  {
358  const IntegrationPoint &ip = Nodes.IntPoint(k);
359  fe.CalcDivShape(ip, div_shape);
360  if (MapType == VALUE)
361  {
362  Trans.SetIntPoint(&ip);
363  detJ = Trans.Weight();
364  for (int j = 0; j < div_shape.Size(); j++)
365  {
366  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
367  }
368  }
369  else
370  {
371  for (int j = 0; j < div_shape.Size(); j++)
372  {
373  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
374  }
375  }
376  }
377 }
378 
381  const PositiveFiniteElement &fine_fe) const
382 {
383  // General interpolation, defined based on L2 projection
384 
385  double v[3];
386  Vector vv (v, Dim);
387  IntegrationPoint f_ip;
388 
389  const int fs = fine_fe.GetDof(), cs = this->GetDof();
390  I.SetSize(fs, cs);
391  Vector fine_shape(fs), coarse_shape(cs);
392  DenseMatrix fine_mass(fs), fine_coarse_mass(fs, cs); // initialized with 0
393  const int ir_order = GetOrder() + fine_fe.GetOrder();
394  const IntegrationRule &ir = IntRules.Get(fine_fe.GetGeomType(), ir_order);
395 
396  for (int i = 0; i < ir.GetNPoints(); i++)
397  {
398  const IntegrationPoint &ip = ir.IntPoint(i);
399  fine_fe.CalcShape(ip, fine_shape);
400  Trans.Transform(ip, vv);
401  f_ip.Set(v, Dim);
402  this->CalcShape(f_ip, coarse_shape);
403 
404  AddMult_a_VVt(ip.weight, fine_shape, fine_mass);
405  AddMult_a_VWt(ip.weight, fine_shape, coarse_shape, fine_coarse_mass);
406  }
407 
408  DenseMatrixInverse fine_mass_inv(fine_mass);
409  fine_mass_inv.Mult(fine_coarse_mass, I);
410 
411  if (MapType == INTEGRAL)
412  {
413  // assuming Trans is linear; this should be ok for all refinement types
415  I *= Trans.Weight();
416  }
417 }
418 
420  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
421 {
422  for (int i = 0; i < Dof; i++)
423  {
424  const IntegrationPoint &ip = Nodes.IntPoint(i);
425  Trans.SetIntPoint(&ip);
426  dofs(i) = coeff.Eval(Trans, ip);
427  }
428 }
429 
432 {
433  const NodalFiniteElement *nfe =
434  dynamic_cast<const NodalFiniteElement *>(&fe);
435 
436  if (nfe && Dof == nfe->GetDof())
437  {
438  nfe->Project(*this, Trans, I);
439  I.Invert();
440  }
441  else
442  {
443  // local L2 projection
444  DenseMatrix pos_mass, mixed_mass;
445  MassIntegrator mass_integ;
446 
447  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
448  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
449 
450  DenseMatrixInverse pos_mass_inv(pos_mass);
451  I.SetSize(Dof, fe.GetDof());
452  pos_mass_inv.Mult(mixed_mass, I);
453  }
454 }
455 
456 
457 void VectorFiniteElement::CalcShape (
458  const IntegrationPoint &ip, Vector &shape ) const
459 {
460  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
461  " VectorFiniteElements!");
462 }
463 
464 void VectorFiniteElement::CalcDShape (
465  const IntegrationPoint &ip, DenseMatrix &dshape ) const
466 {
467  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
468  " VectorFiniteElements!");
469 }
470 
472 {
473  switch (MapType)
474  {
475  case H_DIV:
476  DerivType = DIV;
479  break;
480  case H_CURL:
481  switch (Dim)
482  {
483  case 3: // curl: 3D H_CURL -> 3D H_DIV
484  DerivType = CURL;
487  break;
488  case 2:
489  // curl: 2D H_CURL -> INTEGRAL
490  DerivType = CURL;
493  break;
494  case 1:
495  DerivType = NONE;
498  break;
499  default:
500  MFEM_ABORT("Invalid dimension, Dim = " << Dim);
501  }
502  break;
503  default:
504  MFEM_ABORT("Invalid MapType = " << MapType);
505  }
506 }
507 
509  ElementTransformation &Trans, DenseMatrix &shape) const
510 {
511  MFEM_ASSERT(MapType == H_DIV, "");
512 #ifdef MFEM_THREAD_SAFE
514 #endif
515  CalcVShape(Trans.GetIntPoint(), vshape);
516  MultABt(vshape, Trans.Jacobian(), shape);
517  shape *= (1.0 / Trans.Weight());
518 }
519 
521  ElementTransformation &Trans, DenseMatrix &shape) const
522 {
523  MFEM_ASSERT(MapType == H_CURL, "");
524 #ifdef MFEM_THREAD_SAFE
526 #endif
527  CalcVShape(Trans.GetIntPoint(), vshape);
528  Mult(vshape, Trans.InverseJacobian(), shape);
529 }
530 
532  const double *nk, const Array<int> &d2n,
534 {
535  double vk[3];
536  const int sdim = Trans.GetSpaceDim();
537  MFEM_ASSERT(vc.GetVDim() == sdim, "");
538  Vector xk(vk, sdim);
539  const bool square_J = (Dim == sdim);
540 
541  for (int k = 0; k < Dof; k++)
542  {
543  Trans.SetIntPoint(&Nodes.IntPoint(k));
544  vc.Eval(xk, Trans, Nodes.IntPoint(k));
545  // dof_k = nk^t adj(J) xk
546  dofs(k) = Trans.AdjugateJacobian().InnerProduct(vk, nk + d2n[k]*Dim);
547  if (!square_J) { dofs(k) /= Trans.Weight(); }
548  }
549 }
550 
552  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
554 {
555  if (fe.GetRangeType() == SCALAR)
556  {
557  double vk[3];
558  Vector shape(fe.GetDof());
559  int sdim = Trans.GetSpaceDim();
560 
561  I.SetSize(Dof, sdim*fe.GetDof());
562  for (int k = 0; k < Dof; k++)
563  {
564  const IntegrationPoint &ip = Nodes.IntPoint(k);
565 
566  fe.CalcShape(ip, shape);
567  Trans.SetIntPoint(&ip);
568  Trans.AdjugateJacobian().MultTranspose(nk + d2n[k]*Dim, vk);
569  if (fe.GetMapType() == INTEGRAL)
570  {
571  double w = 1.0/Trans.Weight();
572  for (int d = 0; d < Dim; d++)
573  {
574  vk[d] *= w;
575  }
576  }
577 
578  for (int j = 0; j < shape.Size(); j++)
579  {
580  double s = shape(j);
581  if (fabs(s) < 1e-12)
582  {
583  s = 0.0;
584  }
585  for (int d = 0; d < sdim; d++)
586  {
587  I(k,j+d*shape.Size()) = s*vk[d];
588  }
589  }
590  }
591  }
592  else
593  {
594  mfem_error("VectorFiniteElement::Project_RT (fe version)");
595  }
596 }
597 
599  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
601 {
602  if (Dim != 2)
603  {
604  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
605  }
606 
607  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
608  Vector grad_k(fe.GetDof());
609  double tk[2];
610 
611  grad.SetSize(Dof, fe.GetDof());
612  for (int k = 0; k < Dof; k++)
613  {
614  fe.CalcDShape(Nodes.IntPoint(k), dshape);
615  tk[0] = nk[d2n[k]*Dim+1];
616  tk[1] = -nk[d2n[k]*Dim];
617  dshape.Mult(tk, grad_k);
618  for (int j = 0; j < grad_k.Size(); j++)
619  {
620  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
621  }
622  }
623 }
624 
626  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
628 {
629 #ifdef MFEM_THREAD_SAFE
632  DenseMatrix J(Dim, Dim);
633 #else
634  curlshape.SetSize(fe.GetDof(), Dim);
635  curlshape_J.SetSize(fe.GetDof(), Dim);
636  J.SetSize(Dim, Dim);
637 #endif
638 
639  Vector curl_k(fe.GetDof());
640 
641  curl.SetSize(Dof, fe.GetDof());
642  for (int k = 0; k < Dof; k++)
643  {
644  const IntegrationPoint &ip = Nodes.IntPoint(k);
645 
646  // calculate J^t * J / |J|
647  Trans.SetIntPoint(&ip);
648  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
649  J *= 1.0 / Trans.Weight();
650 
651  // transform curl of shapes (rows) by J^t * J / |J|
652  fe.CalcCurlShape(ip, curlshape);
654 
655  curlshape_J.Mult(tk + d2t[k]*Dim, curl_k);
656  for (int j = 0; j < curl_k.Size(); j++)
657  {
658  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
659  }
660  }
661 }
662 
664  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
666 {
667  DenseMatrix curl_shape(fe.GetDof(), Dim);
668  Vector curl_k(fe.GetDof());
669 
670  curl.SetSize(Dof, fe.GetDof());
671  for (int k = 0; k < Dof; k++)
672  {
673  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
674  curl_shape.Mult(nk + d2n[k]*Dim, curl_k);
675  for (int j = 0; j < curl_k.Size(); j++)
676  {
677  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
678  }
679  }
680 }
681 
683  const double *tk, const Array<int> &d2t,
685 {
686  double vk[3];
687  Vector xk(vk, vc.GetVDim());
688 
689  for (int k = 0; k < Dof; k++)
690  {
691  Trans.SetIntPoint(&Nodes.IntPoint(k));
692 
693  vc.Eval(xk, Trans, Nodes.IntPoint(k));
694  // dof_k = xk^t J tk
695  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*Dim, vk);
696  }
697 }
698 
700  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
702 {
703  if (fe.GetRangeType() == SCALAR)
704  {
705  int sdim = Trans.GetSpaceDim();
706  double vk[3];
707  Vector shape(fe.GetDof());
708 
709  I.SetSize(Dof, sdim*fe.GetDof());
710  for (int k = 0; k < Dof; k++)
711  {
712  const IntegrationPoint &ip = Nodes.IntPoint(k);
713 
714  fe.CalcShape(ip, shape);
715  Trans.SetIntPoint(&ip);
716  Trans.Jacobian().Mult(tk + d2t[k]*Dim, vk);
717  if (fe.GetMapType() == INTEGRAL)
718  {
719  double w = 1.0/Trans.Weight();
720  for (int d = 0; d < sdim; d++)
721  {
722  vk[d] *= w;
723  }
724  }
725 
726  for (int j = 0; j < shape.Size(); j++)
727  {
728  double s = shape(j);
729  if (fabs(s) < 1e-12)
730  {
731  s = 0.0;
732  }
733  for (int d = 0; d < sdim; d++)
734  {
735  I(k, j + d*shape.Size()) = s*vk[d];
736  }
737  }
738  }
739  }
740  else
741  {
742  mfem_error("VectorFiniteElement::Project_ND (fe version)");
743  }
744 }
745 
747  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
749 {
750  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
751 
752  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
753  Vector grad_k(fe.GetDof());
754 
755  grad.SetSize(Dof, fe.GetDof());
756  for (int k = 0; k < Dof; k++)
757  {
758  fe.CalcDShape(Nodes.IntPoint(k), dshape);
759  dshape.Mult(tk + d2t[k]*Dim, grad_k);
760  for (int j = 0; j < grad_k.Size(); j++)
761  {
762  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
763  }
764  }
765 }
766 
768  const double *nk, const Array<int> &d2n, ElementTransformation &Trans,
769  DenseMatrix &I) const
770 {
771  double vk[3];
772  Vector xk(vk, Dim);
773  IntegrationPoint ip;
774 #ifdef MFEM_THREAD_SAFE
776 #endif
777 
778  // assuming Trans is linear; this should be ok for all refinement types
780  const DenseMatrix &adjJ = Trans.AdjugateJacobian();
781  for (int k = 0; k < Dof; k++)
782  {
783  Trans.Transform(Nodes.IntPoint(k), xk);
784  ip.Set3(vk);
785  CalcVShape(ip, vshape);
786  // xk = |J| J^{-t} n_k
787  adjJ.MultTranspose(nk + d2n[k]*Dim, vk);
788  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,Dof
789  for (int j = 0; j < Dof; j++)
790  {
791  double Ikj = 0.;
792  for (int i = 0; i < Dim; i++)
793  {
794  Ikj += vshape(j, i) * vk[i];
795  }
796  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
797  }
798  }
799 }
800 
802  const double *tk, const Array<int> &d2t, ElementTransformation &Trans,
803  DenseMatrix &I) const
804 {
805  double vk[3];
806  Vector xk(vk, Dim);
807  IntegrationPoint ip;
808 #ifdef MFEM_THREAD_SAFE
810 #endif
811 
812  // assuming Trans is linear; this should be ok for all refinement types
814  const DenseMatrix &J = Trans.Jacobian();
815  for (int k = 0; k < Dof; k++)
816  {
817  Trans.Transform(Nodes.IntPoint(k), xk);
818  ip.Set3(vk);
819  CalcVShape(ip, vshape);
820  // xk = J t_k
821  J.Mult(tk + d2t[k]*Dim, vk);
822  // I_k = vshape_k.J.t_k, k=1,...,Dof
823  for (int j = 0; j < Dof; j++)
824  {
825  double Ikj = 0.;
826  for (int i = 0; i < Dim; i++)
827  {
828  Ikj += vshape(j, i) * vk[i];
829  }
830  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
831  }
832  }
833 }
834 
835 
837  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
838 {
839  Nodes.IntPoint(0).x = 0.0;
840 }
841 
843  Vector &shape) const
844 {
845  shape(0) = 1.;
846 }
847 
849  DenseMatrix &dshape) const
850 {
851  // dshape is (1 x 0) - nothing to compute
852 }
853 
855  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
856 {
857  Nodes.IntPoint(0).x = 0.0;
858  Nodes.IntPoint(1).x = 1.0;
859 }
860 
862  Vector &shape) const
863 {
864  shape(0) = 1. - ip.x;
865  shape(1) = ip.x;
866 }
867 
869  DenseMatrix &dshape) const
870 {
871  dshape(0,0) = -1.;
872  dshape(1,0) = 1.;
873 }
874 
876  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
877 {
878  Nodes.IntPoint(0).x = 0.0;
879  Nodes.IntPoint(0).y = 0.0;
880  Nodes.IntPoint(1).x = 1.0;
881  Nodes.IntPoint(1).y = 0.0;
882  Nodes.IntPoint(2).x = 0.0;
883  Nodes.IntPoint(2).y = 1.0;
884 }
885 
887  Vector &shape) const
888 {
889  shape(0) = 1. - ip.x - ip.y;
890  shape(1) = ip.x;
891  shape(2) = ip.y;
892 }
893 
895  DenseMatrix &dshape) const
896 {
897  dshape(0,0) = -1.; dshape(0,1) = -1.;
898  dshape(1,0) = 1.; dshape(1,1) = 0.;
899  dshape(2,0) = 0.; dshape(2,1) = 1.;
900 }
901 
903  : NodalFiniteElement(2, Geometry::SQUARE , 4, 1, FunctionSpace::Qk)
904 {
905  Nodes.IntPoint(0).x = 0.0;
906  Nodes.IntPoint(0).y = 0.0;
907  Nodes.IntPoint(1).x = 1.0;
908  Nodes.IntPoint(1).y = 0.0;
909  Nodes.IntPoint(2).x = 1.0;
910  Nodes.IntPoint(2).y = 1.0;
911  Nodes.IntPoint(3).x = 0.0;
912  Nodes.IntPoint(3).y = 1.0;
913 }
914 
916  Vector &shape) const
917 {
918  shape(0) = (1. - ip.x) * (1. - ip.y) ;
919  shape(1) = ip.x * (1. - ip.y) ;
920  shape(2) = ip.x * ip.y ;
921  shape(3) = (1. - ip.x) * ip.y ;
922 }
923 
925  DenseMatrix &dshape) const
926 {
927  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
928  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
929  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
930  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
931 }
932 
934  const IntegrationPoint &ip, DenseMatrix &h) const
935 {
936  h(0,0) = 0.; h(0,1) = 1.; h(0,2) = 0.;
937  h(1,0) = 0.; h(1,1) = -1.; h(1,2) = 0.;
938  h(2,0) = 0.; h(2,1) = 1.; h(2,2) = 0.;
939  h(3,0) = 0.; h(3,1) = -1.; h(3,2) = 0.;
940 }
941 
942 
944  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
945 {
946  Nodes.IntPoint(0).x = 1./6.;
947  Nodes.IntPoint(0).y = 1./6.;
948  Nodes.IntPoint(1).x = 2./3.;
949  Nodes.IntPoint(1).y = 1./6.;
950  Nodes.IntPoint(2).x = 1./6.;
951  Nodes.IntPoint(2).y = 2./3.;
952 }
953 
955  Vector &shape) const
956 {
957  const double x = ip.x, y = ip.y;
958 
959  shape(0) = 5./3. - 2. * (x + y);
960  shape(1) = 2. * (x - 1./6.);
961  shape(2) = 2. * (y - 1./6.);
962 }
963 
965  DenseMatrix &dshape) const
966 {
967  dshape(0,0) = -2.; dshape(0,1) = -2.;
968  dshape(1,0) = 2.; dshape(1,1) = 0.;
969  dshape(2,0) = 0.; dshape(2,1) = 2.;
970 }
971 
973 {
974  dofs(vertex) = 2./3.;
975  dofs((vertex+1)%3) = 1./6.;
976  dofs((vertex+2)%3) = 1./6.;
977 }
978 
979 
980 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
981 const double GaussBiLinear2DFiniteElement::p[] =
982 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
983 
985  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
986 {
987  Nodes.IntPoint(0).x = p[0];
988  Nodes.IntPoint(0).y = p[0];
989  Nodes.IntPoint(1).x = p[1];
990  Nodes.IntPoint(1).y = p[0];
991  Nodes.IntPoint(2).x = p[1];
992  Nodes.IntPoint(2).y = p[1];
993  Nodes.IntPoint(3).x = p[0];
994  Nodes.IntPoint(3).y = p[1];
995 }
996 
998  Vector &shape) const
999 {
1000  const double x = ip.x, y = ip.y;
1001 
1002  shape(0) = 3. * (p[1] - x) * (p[1] - y);
1003  shape(1) = 3. * (x - p[0]) * (p[1] - y);
1004  shape(2) = 3. * (x - p[0]) * (y - p[0]);
1005  shape(3) = 3. * (p[1] - x) * (y - p[0]);
1006 }
1007 
1009  DenseMatrix &dshape) const
1010 {
1011  const double x = ip.x, y = ip.y;
1012 
1013  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
1014  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
1015  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
1016  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
1017 }
1018 
1020 {
1021 #if 1
1022  dofs(vertex) = p[1]*p[1];
1023  dofs((vertex+1)%4) = p[0]*p[1];
1024  dofs((vertex+2)%4) = p[0]*p[0];
1025  dofs((vertex+3)%4) = p[0]*p[1];
1026 #else
1027  dofs = 1.0;
1028 #endif
1029 }
1030 
1031 
1033  : NodalFiniteElement(2, Geometry::SQUARE , 3, 1, FunctionSpace::Qk)
1034 {
1035  Nodes.IntPoint(0).x = 0.0;
1036  Nodes.IntPoint(0).y = 0.0;
1037  Nodes.IntPoint(1).x = 1.0;
1038  Nodes.IntPoint(1).y = 0.0;
1039  Nodes.IntPoint(2).x = 0.0;
1040  Nodes.IntPoint(2).y = 1.0;
1041 }
1042 
1044  Vector &shape) const
1045 {
1046  shape(0) = 1. - ip.x - ip.y;
1047  shape(1) = ip.x;
1048  shape(2) = ip.y;
1049 }
1050 
1052  DenseMatrix &dshape) const
1053 {
1054  dshape(0,0) = -1.; dshape(0,1) = -1.;
1055  dshape(1,0) = 1.; dshape(1,1) = 0.;
1056  dshape(2,0) = 0.; dshape(2,1) = 1.;
1057 }
1058 
1059 
1061  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
1062 {
1063  Nodes.IntPoint(0).x = 0.0;
1064  Nodes.IntPoint(1).x = 1.0;
1065  Nodes.IntPoint(2).x = 0.5;
1066 }
1067 
1069  Vector &shape) const
1070 {
1071  double x = ip.x;
1072  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
1073 
1074  shape(0) = l1 * (-l3);
1075  shape(1) = l2 * l3;
1076  shape(2) = 4. * l1 * l2;
1077 }
1078 
1080  DenseMatrix &dshape) const
1081 {
1082  double x = ip.x;
1083 
1084  dshape(0,0) = 4. * x - 3.;
1085  dshape(1,0) = 4. * x - 1.;
1086  dshape(2,0) = 4. - 8. * x;
1087 }
1088 
1089 
1091  : PositiveFiniteElement(1, Geometry::SEGMENT, 3, 2)
1092 {
1093  Nodes.IntPoint(0).x = 0.0;
1094  Nodes.IntPoint(1).x = 1.0;
1095  Nodes.IntPoint(2).x = 0.5;
1096 }
1097 
1099  Vector &shape) const
1100 {
1101  const double x = ip.x, x1 = 1. - x;
1102 
1103  shape(0) = x1 * x1;
1104  shape(1) = x * x;
1105  shape(2) = 2. * x * x1;
1106 }
1107 
1109  DenseMatrix &dshape) const
1110 {
1111  const double x = ip.x;
1112 
1113  dshape(0,0) = 2. * x - 2.;
1114  dshape(1,0) = 2. * x;
1115  dshape(2,0) = 2. - 4. * x;
1116 }
1117 
1119  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1120 {
1121  Nodes.IntPoint(0).x = 0.0;
1122  Nodes.IntPoint(0).y = 0.0;
1123  Nodes.IntPoint(1).x = 1.0;
1124  Nodes.IntPoint(1).y = 0.0;
1125  Nodes.IntPoint(2).x = 0.0;
1126  Nodes.IntPoint(2).y = 1.0;
1127  Nodes.IntPoint(3).x = 0.5;
1128  Nodes.IntPoint(3).y = 0.0;
1129  Nodes.IntPoint(4).x = 0.5;
1130  Nodes.IntPoint(4).y = 0.5;
1131  Nodes.IntPoint(5).x = 0.0;
1132  Nodes.IntPoint(5).y = 0.5;
1133 }
1134 
1136  Vector &shape) const
1137 {
1138  double x = ip.x, y = ip.y;
1139  double l1 = 1.-x-y, l2 = x, l3 = y;
1140 
1141  shape(0) = l1 * (2. * l1 - 1.);
1142  shape(1) = l2 * (2. * l2 - 1.);
1143  shape(2) = l3 * (2. * l3 - 1.);
1144  shape(3) = 4. * l1 * l2;
1145  shape(4) = 4. * l2 * l3;
1146  shape(5) = 4. * l3 * l1;
1147 }
1148 
1150  DenseMatrix &dshape) const
1151 {
1152  double x = ip.x, y = ip.y;
1153 
1154  dshape(0,0) =
1155  dshape(0,1) = 4. * (x + y) - 3.;
1156 
1157  dshape(1,0) = 4. * x - 1.;
1158  dshape(1,1) = 0.;
1159 
1160  dshape(2,0) = 0.;
1161  dshape(2,1) = 4. * y - 1.;
1162 
1163  dshape(3,0) = -4. * (2. * x + y - 1.);
1164  dshape(3,1) = -4. * x;
1165 
1166  dshape(4,0) = 4. * y;
1167  dshape(4,1) = 4. * x;
1168 
1169  dshape(5,0) = -4. * y;
1170  dshape(5,1) = -4. * (x + 2. * y - 1.);
1171 }
1172 
1174  DenseMatrix &h) const
1175 {
1176  h(0,0) = 4.;
1177  h(0,1) = 4.;
1178  h(0,2) = 4.;
1179 
1180  h(1,0) = 4.;
1181  h(1,1) = 0.;
1182  h(1,2) = 0.;
1183 
1184  h(2,0) = 0.;
1185  h(2,1) = 0.;
1186  h(2,2) = 4.;
1187 
1188  h(3,0) = -8.;
1189  h(3,1) = -4.;
1190  h(3,2) = 0.;
1191 
1192  h(4,0) = 0.;
1193  h(4,1) = 4.;
1194  h(4,2) = 0.;
1195 
1196  h(5,0) = 0.;
1197  h(5,1) = -4.;
1198  h(5,2) = -8.;
1199 }
1200 
1201 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1202 {
1203 #if 0
1204  dofs = 1.;
1205 #else
1206  dofs = 0.;
1207  dofs(vertex) = 1.;
1208  switch (vertex)
1209  {
1210  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1211  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1212  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1213  }
1214 #endif
1215 }
1216 
1217 
1218 const double GaussQuad2DFiniteElement::p[] =
1219 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1220 
1222  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1223 {
1224  Nodes.IntPoint(0).x = p[0];
1225  Nodes.IntPoint(0).y = p[0];
1226  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1227  Nodes.IntPoint(1).y = p[0];
1228  Nodes.IntPoint(2).x = p[0];
1229  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1230  Nodes.IntPoint(3).x = p[1];
1231  Nodes.IntPoint(3).y = p[1];
1232  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1233  Nodes.IntPoint(4).y = p[1];
1234  Nodes.IntPoint(5).x = p[1];
1235  Nodes.IntPoint(5).y = 1. - 2. * p[1];
1236 
1237  for (int i = 0; i < 6; i++)
1238  {
1239  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
1240  A(0,i) = 1.;
1241  A(1,i) = x;
1242  A(2,i) = y;
1243  A(3,i) = x * x;
1244  A(4,i) = x * y;
1245  A(5,i) = y * y;
1246  }
1247 
1248  A.Invert();
1249 }
1250 
1252  Vector &shape) const
1253 {
1254  const double x = ip.x, y = ip.y;
1255  pol(0) = 1.;
1256  pol(1) = x;
1257  pol(2) = y;
1258  pol(3) = x * x;
1259  pol(4) = x * y;
1260  pol(5) = y * y;
1261 
1262  A.Mult(pol, shape);
1263 }
1264 
1266  DenseMatrix &dshape) const
1267 {
1268  const double x = ip.x, y = ip.y;
1269  D(0,0) = 0.; D(0,1) = 0.;
1270  D(1,0) = 1.; D(1,1) = 0.;
1271  D(2,0) = 0.; D(2,1) = 1.;
1272  D(3,0) = 2. * x; D(3,1) = 0.;
1273  D(4,0) = y; D(4,1) = x;
1274  D(5,0) = 0.; D(5,1) = 2. * y;
1275 
1276  Mult(A, D, dshape);
1277 }
1278 
1279 
1281  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1282 {
1283  Nodes.IntPoint(0).x = 0.0;
1284  Nodes.IntPoint(0).y = 0.0;
1285  Nodes.IntPoint(1).x = 1.0;
1286  Nodes.IntPoint(1).y = 0.0;
1287  Nodes.IntPoint(2).x = 1.0;
1288  Nodes.IntPoint(2).y = 1.0;
1289  Nodes.IntPoint(3).x = 0.0;
1290  Nodes.IntPoint(3).y = 1.0;
1291  Nodes.IntPoint(4).x = 0.5;
1292  Nodes.IntPoint(4).y = 0.0;
1293  Nodes.IntPoint(5).x = 1.0;
1294  Nodes.IntPoint(5).y = 0.5;
1295  Nodes.IntPoint(6).x = 0.5;
1296  Nodes.IntPoint(6).y = 1.0;
1297  Nodes.IntPoint(7).x = 0.0;
1298  Nodes.IntPoint(7).y = 0.5;
1299  Nodes.IntPoint(8).x = 0.5;
1300  Nodes.IntPoint(8).y = 0.5;
1301 }
1302 
1304  Vector &shape) const
1305 {
1306  double x = ip.x, y = ip.y;
1307  double l1x, l2x, l3x, l1y, l2y, l3y;
1308 
1309  l1x = (x - 1.) * (2. * x - 1);
1310  l2x = 4. * x * (1. - x);
1311  l3x = x * (2. * x - 1.);
1312  l1y = (y - 1.) * (2. * y - 1);
1313  l2y = 4. * y * (1. - y);
1314  l3y = y * (2. * y - 1.);
1315 
1316  shape(0) = l1x * l1y;
1317  shape(4) = l2x * l1y;
1318  shape(1) = l3x * l1y;
1319  shape(7) = l1x * l2y;
1320  shape(8) = l2x * l2y;
1321  shape(5) = l3x * l2y;
1322  shape(3) = l1x * l3y;
1323  shape(6) = l2x * l3y;
1324  shape(2) = l3x * l3y;
1325 }
1326 
1328  DenseMatrix &dshape) const
1329 {
1330  double x = ip.x, y = ip.y;
1331  double l1x, l2x, l3x, l1y, l2y, l3y;
1332  double d1x, d2x, d3x, d1y, d2y, d3y;
1333 
1334  l1x = (x - 1.) * (2. * x - 1);
1335  l2x = 4. * x * (1. - x);
1336  l3x = x * (2. * x - 1.);
1337  l1y = (y - 1.) * (2. * y - 1);
1338  l2y = 4. * y * (1. - y);
1339  l3y = y * (2. * y - 1.);
1340 
1341  d1x = 4. * x - 3.;
1342  d2x = 4. - 8. * x;
1343  d3x = 4. * x - 1.;
1344  d1y = 4. * y - 3.;
1345  d2y = 4. - 8. * y;
1346  d3y = 4. * y - 1.;
1347 
1348  dshape(0,0) = d1x * l1y;
1349  dshape(0,1) = l1x * d1y;
1350 
1351  dshape(4,0) = d2x * l1y;
1352  dshape(4,1) = l2x * d1y;
1353 
1354  dshape(1,0) = d3x * l1y;
1355  dshape(1,1) = l3x * d1y;
1356 
1357  dshape(7,0) = d1x * l2y;
1358  dshape(7,1) = l1x * d2y;
1359 
1360  dshape(8,0) = d2x * l2y;
1361  dshape(8,1) = l2x * d2y;
1362 
1363  dshape(5,0) = d3x * l2y;
1364  dshape(5,1) = l3x * d2y;
1365 
1366  dshape(3,0) = d1x * l3y;
1367  dshape(3,1) = l1x * d3y;
1368 
1369  dshape(6,0) = d2x * l3y;
1370  dshape(6,1) = l2x * d3y;
1371 
1372  dshape(2,0) = d3x * l3y;
1373  dshape(2,1) = l3x * d3y;
1374 }
1375 
1376 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1377 {
1378 #if 0
1379  dofs = 1.;
1380 #else
1381  dofs = 0.;
1382  dofs(vertex) = 1.;
1383  switch (vertex)
1384  {
1385  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
1386  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
1387  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
1388  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
1389  }
1390  dofs(8) = 1./16.;
1391 #endif
1392 }
1393 
1395  : PositiveFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1396 {
1397  Nodes.IntPoint(0).x = 0.0;
1398  Nodes.IntPoint(0).y = 0.0;
1399  Nodes.IntPoint(1).x = 1.0;
1400  Nodes.IntPoint(1).y = 0.0;
1401  Nodes.IntPoint(2).x = 1.0;
1402  Nodes.IntPoint(2).y = 1.0;
1403  Nodes.IntPoint(3).x = 0.0;
1404  Nodes.IntPoint(3).y = 1.0;
1405  Nodes.IntPoint(4).x = 0.5;
1406  Nodes.IntPoint(4).y = 0.0;
1407  Nodes.IntPoint(5).x = 1.0;
1408  Nodes.IntPoint(5).y = 0.5;
1409  Nodes.IntPoint(6).x = 0.5;
1410  Nodes.IntPoint(6).y = 1.0;
1411  Nodes.IntPoint(7).x = 0.0;
1412  Nodes.IntPoint(7).y = 0.5;
1413  Nodes.IntPoint(8).x = 0.5;
1414  Nodes.IntPoint(8).y = 0.5;
1415 }
1416 
1418  Vector &shape) const
1419 {
1420  double x = ip.x, y = ip.y;
1421  double l1x, l2x, l3x, l1y, l2y, l3y;
1422 
1423  l1x = (1. - x) * (1. - x);
1424  l2x = 2. * x * (1. - x);
1425  l3x = x * x;
1426  l1y = (1. - y) * (1. - y);
1427  l2y = 2. * y * (1. - y);
1428  l3y = y * y;
1429 
1430  shape(0) = l1x * l1y;
1431  shape(4) = l2x * l1y;
1432  shape(1) = l3x * l1y;
1433  shape(7) = l1x * l2y;
1434  shape(8) = l2x * l2y;
1435  shape(5) = l3x * l2y;
1436  shape(3) = l1x * l3y;
1437  shape(6) = l2x * l3y;
1438  shape(2) = l3x * l3y;
1439 }
1440 
1442  DenseMatrix &dshape) const
1443 {
1444  double x = ip.x, y = ip.y;
1445  double l1x, l2x, l3x, l1y, l2y, l3y;
1446  double d1x, d2x, d3x, d1y, d2y, d3y;
1447 
1448  l1x = (1. - x) * (1. - x);
1449  l2x = 2. * x * (1. - x);
1450  l3x = x * x;
1451  l1y = (1. - y) * (1. - y);
1452  l2y = 2. * y * (1. - y);
1453  l3y = y * y;
1454 
1455  d1x = 2. * x - 2.;
1456  d2x = 2. - 4. * x;
1457  d3x = 2. * x;
1458  d1y = 2. * y - 2.;
1459  d2y = 2. - 4. * y;
1460  d3y = 2. * y;
1461 
1462  dshape(0,0) = d1x * l1y;
1463  dshape(0,1) = l1x * d1y;
1464 
1465  dshape(4,0) = d2x * l1y;
1466  dshape(4,1) = l2x * d1y;
1467 
1468  dshape(1,0) = d3x * l1y;
1469  dshape(1,1) = l3x * d1y;
1470 
1471  dshape(7,0) = d1x * l2y;
1472  dshape(7,1) = l1x * d2y;
1473 
1474  dshape(8,0) = d2x * l2y;
1475  dshape(8,1) = l2x * d2y;
1476 
1477  dshape(5,0) = d3x * l2y;
1478  dshape(5,1) = l3x * d2y;
1479 
1480  dshape(3,0) = d1x * l3y;
1481  dshape(3,1) = l1x * d3y;
1482 
1483  dshape(6,0) = d2x * l3y;
1484  dshape(6,1) = l2x * d3y;
1485 
1486  dshape(2,0) = d3x * l3y;
1487  dshape(2,1) = l3x * d3y;
1488 }
1489 
1492 {
1493  double s[9];
1494  IntegrationPoint tr_ip;
1495  Vector xx(&tr_ip.x, 2), shape(s, 9);
1496 
1497  for (int i = 0; i < 9; i++)
1498  {
1499  Trans.Transform(Nodes.IntPoint(i), xx);
1500  CalcShape(tr_ip, shape);
1501  for (int j = 0; j < 9; j++)
1502  if (fabs(I(i,j) = s[j]) < 1.0e-12)
1503  {
1504  I(i,j) = 0.0;
1505  }
1506  }
1507  for (int i = 0; i < 9; i++)
1508  {
1509  double *d = &I(0,i);
1510  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1511  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1512  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1513  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1514  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1515  0.25 * (d[0] + d[1] + d[2] + d[3]);
1516  }
1517 }
1518 
1520  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
1521 {
1522  double *d = dofs;
1523 
1524  for (int i = 0; i < 9; i++)
1525  {
1526  const IntegrationPoint &ip = Nodes.IntPoint(i);
1527  Trans.SetIntPoint(&ip);
1528  d[i] = coeff.Eval(Trans, ip);
1529  }
1530  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1531  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1532  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1533  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1534  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1535  0.25 * (d[0] + d[1] + d[2] + d[3]);
1536 }
1537 
1540  Vector &dofs) const
1541 {
1542  double v[3];
1543  Vector x (v, vc.GetVDim());
1544 
1545  for (int i = 0; i < 9; i++)
1546  {
1547  const IntegrationPoint &ip = Nodes.IntPoint(i);
1548  Trans.SetIntPoint(&ip);
1549  vc.Eval (x, Trans, ip);
1550  for (int j = 0; j < x.Size(); j++)
1551  {
1552  dofs(9*j+i) = v[j];
1553  }
1554  }
1555  for (int j = 0; j < x.Size(); j++)
1556  {
1557  double *d = &dofs(9*j);
1558 
1559  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1560  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1561  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1562  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1563  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1564  0.25 * (d[0] + d[1] + d[2] + d[3]);
1565  }
1566 }
1567 
1568 
1570  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1571 {
1572  const double p1 = 0.5*(1.-sqrt(3./5.));
1573 
1574  Nodes.IntPoint(0).x = p1;
1575  Nodes.IntPoint(0).y = p1;
1576  Nodes.IntPoint(4).x = 0.5;
1577  Nodes.IntPoint(4).y = p1;
1578  Nodes.IntPoint(1).x = 1.-p1;
1579  Nodes.IntPoint(1).y = p1;
1580  Nodes.IntPoint(7).x = p1;
1581  Nodes.IntPoint(7).y = 0.5;
1582  Nodes.IntPoint(8).x = 0.5;
1583  Nodes.IntPoint(8).y = 0.5;
1584  Nodes.IntPoint(5).x = 1.-p1;
1585  Nodes.IntPoint(5).y = 0.5;
1586  Nodes.IntPoint(3).x = p1;
1587  Nodes.IntPoint(3).y = 1.-p1;
1588  Nodes.IntPoint(6).x = 0.5;
1589  Nodes.IntPoint(6).y = 1.-p1;
1590  Nodes.IntPoint(2).x = 1.-p1;
1591  Nodes.IntPoint(2).y = 1.-p1;
1592 }
1593 
1595  Vector &shape) const
1596 {
1597  const double a = sqrt(5./3.);
1598  const double p1 = 0.5*(1.-sqrt(3./5.));
1599 
1600  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1601  double l1x, l2x, l3x, l1y, l2y, l3y;
1602 
1603  l1x = (x - 1.) * (2. * x - 1);
1604  l2x = 4. * x * (1. - x);
1605  l3x = x * (2. * x - 1.);
1606  l1y = (y - 1.) * (2. * y - 1);
1607  l2y = 4. * y * (1. - y);
1608  l3y = y * (2. * y - 1.);
1609 
1610  shape(0) = l1x * l1y;
1611  shape(4) = l2x * l1y;
1612  shape(1) = l3x * l1y;
1613  shape(7) = l1x * l2y;
1614  shape(8) = l2x * l2y;
1615  shape(5) = l3x * l2y;
1616  shape(3) = l1x * l3y;
1617  shape(6) = l2x * l3y;
1618  shape(2) = l3x * l3y;
1619 }
1620 
1622  DenseMatrix &dshape) const
1623 {
1624  const double a = sqrt(5./3.);
1625  const double p1 = 0.5*(1.-sqrt(3./5.));
1626 
1627  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1628  double l1x, l2x, l3x, l1y, l2y, l3y;
1629  double d1x, d2x, d3x, d1y, d2y, d3y;
1630 
1631  l1x = (x - 1.) * (2. * x - 1);
1632  l2x = 4. * x * (1. - x);
1633  l3x = x * (2. * x - 1.);
1634  l1y = (y - 1.) * (2. * y - 1);
1635  l2y = 4. * y * (1. - y);
1636  l3y = y * (2. * y - 1.);
1637 
1638  d1x = a * (4. * x - 3.);
1639  d2x = a * (4. - 8. * x);
1640  d3x = a * (4. * x - 1.);
1641  d1y = a * (4. * y - 3.);
1642  d2y = a * (4. - 8. * y);
1643  d3y = a * (4. * y - 1.);
1644 
1645  dshape(0,0) = d1x * l1y;
1646  dshape(0,1) = l1x * d1y;
1647 
1648  dshape(4,0) = d2x * l1y;
1649  dshape(4,1) = l2x * d1y;
1650 
1651  dshape(1,0) = d3x * l1y;
1652  dshape(1,1) = l3x * d1y;
1653 
1654  dshape(7,0) = d1x * l2y;
1655  dshape(7,1) = l1x * d2y;
1656 
1657  dshape(8,0) = d2x * l2y;
1658  dshape(8,1) = l2x * d2y;
1659 
1660  dshape(5,0) = d3x * l2y;
1661  dshape(5,1) = l3x * d2y;
1662 
1663  dshape(3,0) = d1x * l3y;
1664  dshape(3,1) = l1x * d3y;
1665 
1666  dshape(6,0) = d2x * l3y;
1667  dshape(6,1) = l2x * d3y;
1668 
1669  dshape(2,0) = d3x * l3y;
1670  dshape(2,1) = l3x * d3y;
1671 }
1672 
1674  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
1675 {
1676  Nodes.IntPoint(0).x = 0.;
1677  Nodes.IntPoint(0).y = 0.;
1678  Nodes.IntPoint(1).x = 1.;
1679  Nodes.IntPoint(1).y = 0.;
1680  Nodes.IntPoint(2).x = 1.;
1681  Nodes.IntPoint(2).y = 1.;
1682  Nodes.IntPoint(3).x = 0.;
1683  Nodes.IntPoint(3).y = 1.;
1684  Nodes.IntPoint(4).x = 1./3.;
1685  Nodes.IntPoint(4).y = 0.;
1686  Nodes.IntPoint(5).x = 2./3.;
1687  Nodes.IntPoint(5).y = 0.;
1688  Nodes.IntPoint(6).x = 1.;
1689  Nodes.IntPoint(6).y = 1./3.;
1690  Nodes.IntPoint(7).x = 1.;
1691  Nodes.IntPoint(7).y = 2./3.;
1692  Nodes.IntPoint(8).x = 2./3.;
1693  Nodes.IntPoint(8).y = 1.;
1694  Nodes.IntPoint(9).x = 1./3.;
1695  Nodes.IntPoint(9).y = 1.;
1696  Nodes.IntPoint(10).x = 0.;
1697  Nodes.IntPoint(10).y = 2./3.;
1698  Nodes.IntPoint(11).x = 0.;
1699  Nodes.IntPoint(11).y = 1./3.;
1700  Nodes.IntPoint(12).x = 1./3.;
1701  Nodes.IntPoint(12).y = 1./3.;
1702  Nodes.IntPoint(13).x = 2./3.;
1703  Nodes.IntPoint(13).y = 1./3.;
1704  Nodes.IntPoint(14).x = 1./3.;
1705  Nodes.IntPoint(14).y = 2./3.;
1706  Nodes.IntPoint(15).x = 2./3.;
1707  Nodes.IntPoint(15).y = 2./3.;
1708 }
1709 
1711  const IntegrationPoint &ip, Vector &shape) const
1712 {
1713  double x = ip.x, y = ip.y;
1714 
1715  double w1x, w2x, w3x, w1y, w2y, w3y;
1716  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1717 
1718  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1719  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1720 
1721  l0x = (- 4.5) * w1x * w2x * w3x;
1722  l1x = ( 13.5) * x * w2x * w3x;
1723  l2x = (-13.5) * x * w1x * w3x;
1724  l3x = ( 4.5) * x * w1x * w2x;
1725 
1726  l0y = (- 4.5) * w1y * w2y * w3y;
1727  l1y = ( 13.5) * y * w2y * w3y;
1728  l2y = (-13.5) * y * w1y * w3y;
1729  l3y = ( 4.5) * y * w1y * w2y;
1730 
1731  shape(0) = l0x * l0y;
1732  shape(1) = l3x * l0y;
1733  shape(2) = l3x * l3y;
1734  shape(3) = l0x * l3y;
1735  shape(4) = l1x * l0y;
1736  shape(5) = l2x * l0y;
1737  shape(6) = l3x * l1y;
1738  shape(7) = l3x * l2y;
1739  shape(8) = l2x * l3y;
1740  shape(9) = l1x * l3y;
1741  shape(10) = l0x * l2y;
1742  shape(11) = l0x * l1y;
1743  shape(12) = l1x * l1y;
1744  shape(13) = l2x * l1y;
1745  shape(14) = l1x * l2y;
1746  shape(15) = l2x * l2y;
1747 }
1748 
1750  const IntegrationPoint &ip, DenseMatrix &dshape) const
1751 {
1752  double x = ip.x, y = ip.y;
1753 
1754  double w1x, w2x, w3x, w1y, w2y, w3y;
1755  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1756  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1757 
1758  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1759  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1760 
1761  l0x = (- 4.5) * w1x * w2x * w3x;
1762  l1x = ( 13.5) * x * w2x * w3x;
1763  l2x = (-13.5) * x * w1x * w3x;
1764  l3x = ( 4.5) * x * w1x * w2x;
1765 
1766  l0y = (- 4.5) * w1y * w2y * w3y;
1767  l1y = ( 13.5) * y * w2y * w3y;
1768  l2y = (-13.5) * y * w1y * w3y;
1769  l3y = ( 4.5) * y * w1y * w2y;
1770 
1771  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1772  d1x = 9. + (-45. + 40.5 * x) * x;
1773  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1774  d3x = 1. + (- 9. + 13.5 * x) * x;
1775 
1776  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1777  d1y = 9. + (-45. + 40.5 * y) * y;
1778  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1779  d3y = 1. + (- 9. + 13.5 * y) * y;
1780 
1781  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
1782  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
1783  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
1784  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
1785  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
1786  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
1787  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
1788  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
1789  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
1790  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
1791  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
1792  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
1793  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
1794  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
1795  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
1796  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
1797 }
1798 
1800  const IntegrationPoint &ip, DenseMatrix &h) const
1801 {
1802  double x = ip.x, y = ip.y;
1803 
1804  double w1x, w2x, w3x, w1y, w2y, w3y;
1805  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1806  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1807  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
1808 
1809  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1810  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1811 
1812  l0x = (- 4.5) * w1x * w2x * w3x;
1813  l1x = ( 13.5) * x * w2x * w3x;
1814  l2x = (-13.5) * x * w1x * w3x;
1815  l3x = ( 4.5) * x * w1x * w2x;
1816 
1817  l0y = (- 4.5) * w1y * w2y * w3y;
1818  l1y = ( 13.5) * y * w2y * w3y;
1819  l2y = (-13.5) * y * w1y * w3y;
1820  l3y = ( 4.5) * y * w1y * w2y;
1821 
1822  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1823  d1x = 9. + (-45. + 40.5 * x) * x;
1824  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1825  d3x = 1. + (- 9. + 13.5 * x) * x;
1826 
1827  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1828  d1y = 9. + (-45. + 40.5 * y) * y;
1829  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1830  d3y = 1. + (- 9. + 13.5 * y) * y;
1831 
1832  h0x = -27. * x + 18.;
1833  h1x = 81. * x - 45.;
1834  h2x = -81. * x + 36.;
1835  h3x = 27. * x - 9.;
1836 
1837  h0y = -27. * y + 18.;
1838  h1y = 81. * y - 45.;
1839  h2y = -81. * y + 36.;
1840  h3y = 27. * y - 9.;
1841 
1842  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
1843  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
1844  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
1845  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
1846  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
1847  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
1848  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
1849  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
1850  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
1851  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
1852  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
1853  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
1854  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
1855  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
1856  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
1857  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
1858 }
1859 
1860 
1862  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
1863 {
1864  Nodes.IntPoint(0).x = 0.0;
1865  Nodes.IntPoint(1).x = 1.0;
1866  Nodes.IntPoint(2).x = 0.33333333333333333333;
1867  Nodes.IntPoint(3).x = 0.66666666666666666667;
1868 }
1869 
1871  Vector &shape) const
1872 {
1873  double x = ip.x;
1874  double l1 = x,
1875  l2 = (1.0-x),
1876  l3 = (0.33333333333333333333-x),
1877  l4 = (0.66666666666666666667-x);
1878 
1879  shape(0) = 4.5 * l2 * l3 * l4;
1880  shape(1) = 4.5 * l1 * l3 * l4;
1881  shape(2) = 13.5 * l1 * l2 * l4;
1882  shape(3) = -13.5 * l1 * l2 * l3;
1883 }
1884 
1886  DenseMatrix &dshape) const
1887 {
1888  double x = ip.x;
1889 
1890  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
1891  dshape(1,0) = 1. - x * (9. - 13.5 * x);
1892  dshape(2,0) = 9. - x * (45. - 40.5 * x);
1893  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
1894 }
1895 
1896 
1898  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
1899 {
1900  Nodes.IntPoint(0).x = 0.0;
1901  Nodes.IntPoint(0).y = 0.0;
1902  Nodes.IntPoint(1).x = 1.0;
1903  Nodes.IntPoint(1).y = 0.0;
1904  Nodes.IntPoint(2).x = 0.0;
1905  Nodes.IntPoint(2).y = 1.0;
1906  Nodes.IntPoint(3).x = 0.33333333333333333333;
1907  Nodes.IntPoint(3).y = 0.0;
1908  Nodes.IntPoint(4).x = 0.66666666666666666667;
1909  Nodes.IntPoint(4).y = 0.0;
1910  Nodes.IntPoint(5).x = 0.66666666666666666667;
1911  Nodes.IntPoint(5).y = 0.33333333333333333333;
1912  Nodes.IntPoint(6).x = 0.33333333333333333333;
1913  Nodes.IntPoint(6).y = 0.66666666666666666667;
1914  Nodes.IntPoint(7).x = 0.0;
1915  Nodes.IntPoint(7).y = 0.66666666666666666667;
1916  Nodes.IntPoint(8).x = 0.0;
1917  Nodes.IntPoint(8).y = 0.33333333333333333333;
1918  Nodes.IntPoint(9).x = 0.33333333333333333333;
1919  Nodes.IntPoint(9).y = 0.33333333333333333333;
1920 }
1921 
1923  Vector &shape) const
1924 {
1925  double x = ip.x, y = ip.y;
1926  double l1 = (-1. + x + y),
1927  lx = (-1. + 3.*x),
1928  ly = (-1. + 3.*y);
1929 
1930  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
1931  shape(1) = 0.5*x*(lx - 1.)*lx;
1932  shape(2) = 0.5*y*(-1. + ly)*ly;
1933  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
1934  shape(4) = -4.5*x*lx*l1;
1935  shape(5) = 4.5*x*lx*y;
1936  shape(6) = 4.5*x*y*ly;
1937  shape(7) = -4.5*y*l1*ly;
1938  shape(8) = 4.5*y*l1*(1. + 3.*l1);
1939  shape(9) = -27.*x*y*l1;
1940 }
1941 
1943  DenseMatrix &dshape) const
1944 {
1945  double x = ip.x, y = ip.y;
1946 
1947  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
1948  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
1949  dshape(2,0) = 0.;
1950  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
1951  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
1952  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
1953  dshape(6,0) = 4.5*y*(-1. + 3.*y);
1954  dshape(7,0) = 4.5*(1. - 3.*y)*y;
1955  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
1956  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
1957 
1958  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
1959  dshape(1,1) = 0.;
1960  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
1961  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
1962  dshape(4,1) = 4.5*(1. - 3.*x)*x;
1963  dshape(5,1) = 4.5*x*(-1. + 3.*x);
1964  dshape(6,1) = 4.5*x*(-1. + 6.*y);
1965  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
1966  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
1967  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
1968 }
1969 
1971  DenseMatrix &h) const
1972 {
1973  double x = ip.x, y = ip.y;
1974 
1975  h(0,0) = 18.-27.*(x+y);
1976  h(0,1) = 18.-27.*(x+y);
1977  h(0,2) = 18.-27.*(x+y);
1978 
1979  h(1,0) = -9.+27.*x;
1980  h(1,1) = 0.;
1981  h(1,2) = 0.;
1982 
1983  h(2,0) = 0.;
1984  h(2,1) = 0.;
1985  h(2,2) = -9.+27.*y;
1986 
1987  h(3,0) = -45.+81.*x+54.*y;
1988  h(3,1) = -22.5+54.*x+27.*y;
1989  h(3,2) = 27.*x;
1990 
1991  h(4,0) = 36.-81.*x-27.*y;
1992  h(4,1) = 4.5-27.*x;
1993  h(4,2) = 0.;
1994 
1995  h(5,0) = 27.*y;
1996  h(5,1) = -4.5+27.*x;
1997  h(5,2) = 0.;
1998 
1999  h(6,0) = 0.;
2000  h(6,1) = -4.5+27.*y;
2001  h(6,2) = 27.*x;
2002 
2003  h(7,0) = 0.;
2004  h(7,1) = 4.5-27.*y;
2005  h(7,2) = 36.-27.*x-81.*y;
2006 
2007  h(8,0) = 27.*y;
2008  h(8,1) = -22.5+27.*x+54.*y;
2009  h(8,2) = -45.+54.*x+81.*y;
2010 
2011  h(9,0) = -54.*y;
2012  h(9,1) = 27.-54.*(x+y);
2013  h(9,2) = -54.*x;
2014 }
2015 
2016 
2018  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
2019 {
2020  Nodes.IntPoint(0).x = 0;
2021  Nodes.IntPoint(0).y = 0;
2022  Nodes.IntPoint(0).z = 0;
2023  Nodes.IntPoint(1).x = 1.;
2024  Nodes.IntPoint(1).y = 0;
2025  Nodes.IntPoint(1).z = 0;
2026  Nodes.IntPoint(2).x = 0;
2027  Nodes.IntPoint(2).y = 1.;
2028  Nodes.IntPoint(2).z = 0;
2029  Nodes.IntPoint(3).x = 0;
2030  Nodes.IntPoint(3).y = 0;
2031  Nodes.IntPoint(3).z = 1.;
2032  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
2033  Nodes.IntPoint(4).y = 0;
2034  Nodes.IntPoint(4).z = 0;
2035  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
2036  Nodes.IntPoint(5).y = 0;
2037  Nodes.IntPoint(5).z = 0;
2038  Nodes.IntPoint(6).x = 0;
2039  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
2040  Nodes.IntPoint(6).z = 0;
2041  Nodes.IntPoint(7).x = 0;
2042  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
2043  Nodes.IntPoint(7).z = 0;
2044  Nodes.IntPoint(8).x = 0;
2045  Nodes.IntPoint(8).y = 0;
2046  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
2047  Nodes.IntPoint(9).x = 0;
2048  Nodes.IntPoint(9).y = 0;
2049  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
2050  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
2051  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
2052  Nodes.IntPoint(10).z = 0;
2053  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
2054  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
2055  Nodes.IntPoint(11).z = 0;
2056  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
2057  Nodes.IntPoint(12).y = 0;
2058  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
2059  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
2060  Nodes.IntPoint(13).y = 0;
2061  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
2062  Nodes.IntPoint(14).x = 0;
2063  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
2064  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
2065  Nodes.IntPoint(15).x = 0;
2066  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
2067  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
2068  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
2069  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
2070  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
2071  Nodes.IntPoint(17).x = 0;
2072  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
2073  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
2074  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
2075  Nodes.IntPoint(18).y = 0;
2076  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
2077  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
2078  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
2079  Nodes.IntPoint(19).z = 0;
2080 }
2081 
2083  Vector &shape) const
2084 {
2085  double x = ip.x, y = ip.y, z = ip.z;
2086 
2087  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
2088  (-1 + 3*x + 3*y + 3*z))/2.;
2089  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2090  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
2091  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
2092  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2093  shape(19) = -27*x*y*(-1 + x + y + z);
2094  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
2095  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
2096  shape(11) = (9*x*y*(-1 + 3*y))/2.;
2097  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
2098  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
2099  shape(18) = -27*x*z*(-1 + x + y + z);
2100  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
2101  shape(17) = -27*y*z*(-1 + x + y + z);
2102  shape(16) = 27*x*y*z;
2103  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
2104  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
2105  shape(13) = (9*x*z*(-1 + 3*z))/2.;
2106  shape(15) = (9*y*z*(-1 + 3*z))/2.;
2107  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
2108 }
2109 
2111  DenseMatrix &dshape) const
2112 {
2113  double x = ip.x, y = ip.y, z = ip.z;
2114 
2115  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2116  x*(-4 + 6*y + 6*z)))/2.;
2117  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2118  x*(-4 + 6*y + 6*z)))/2.;
2119  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2120  x*(-4 + 6*y + 6*z)))/2.;
2121  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
2122  2*x*(-5 + 6*y + 6*z)))/2.;
2123  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2124  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2125  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
2126  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
2127  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
2128  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
2129  dshape(1,1) = 0;
2130  dshape(1,2) = 0;
2131  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2132  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
2133  x*(-5 + 12*y + 6*z)))/2.;
2134  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2135  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
2136  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
2137  dshape(19,2) = -27*x*y;
2138  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
2139  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
2140  dshape(10,2) = 0;
2141  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
2142  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
2143  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
2144  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
2145  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
2146  dshape(11,2) = 0;
2147  dshape(2,0) = 0;
2148  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
2149  dshape(2,2) = 0;
2150  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2151  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2152  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
2153  x*(-5 + 6*y + 12*z)))/2.;
2154  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
2155  dshape(18,1) = -27*x*z;
2156  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
2157  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
2158  dshape(12,1) = 0;
2159  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
2160  dshape(17,0) = -27*y*z;
2161  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
2162  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
2163  dshape(16,0) = 27*y*z;
2164  dshape(16,1) = 27*x*z;
2165  dshape(16,2) = 27*x*y;
2166  dshape(14,0) = 0;
2167  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
2168  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
2169  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
2170  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
2171  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
2172  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
2173  dshape(13,1) = 0;
2174  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
2175  dshape(15,0) = 0;
2176  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
2177  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
2178  dshape(3,0) = 0;
2179  dshape(3,1) = 0;
2180  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
2181 }
2182 
2183 
2185  : NodalFiniteElement(2, Geometry::TRIANGLE , 1, 0)
2186 {
2187  Nodes.IntPoint(0).x = 0.333333333333333333;
2188  Nodes.IntPoint(0).y = 0.333333333333333333;
2189 }
2190 
2192  Vector &shape) const
2193 {
2194  shape(0) = 1.0;
2195 }
2196 
2198  DenseMatrix &dshape) const
2199 {
2200  dshape(0,0) = 0.0;
2201  dshape(0,1) = 0.0;
2202 }
2203 
2204 
2206  : NodalFiniteElement(2, Geometry::SQUARE , 1, 0, FunctionSpace::Qk)
2207 {
2208  Nodes.IntPoint(0).x = 0.5;
2209  Nodes.IntPoint(0).y = 0.5;
2210 }
2211 
2213  Vector &shape) const
2214 {
2215  shape(0) = 1.0;
2216 }
2217 
2219  DenseMatrix &dshape) const
2220 {
2221  dshape(0,0) = 0.0;
2222  dshape(0,1) = 0.0;
2223 }
2224 
2225 
2227  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
2228 {
2229  Nodes.IntPoint(0).x = 0.0;
2230  Nodes.IntPoint(0).y = 0.0;
2231  Nodes.IntPoint(0).z = 0.0;
2232  Nodes.IntPoint(1).x = 1.0;
2233  Nodes.IntPoint(1).y = 0.0;
2234  Nodes.IntPoint(1).z = 0.0;
2235  Nodes.IntPoint(2).x = 0.0;
2236  Nodes.IntPoint(2).y = 1.0;
2237  Nodes.IntPoint(2).z = 0.0;
2238  Nodes.IntPoint(3).x = 0.0;
2239  Nodes.IntPoint(3).y = 0.0;
2240  Nodes.IntPoint(3).z = 1.0;
2241 }
2242 
2244  Vector &shape) const
2245 {
2246  shape(0) = 1. - ip.x - ip.y - ip.z;
2247  shape(1) = ip.x;
2248  shape(2) = ip.y;
2249  shape(3) = ip.z;
2250 }
2251 
2253  DenseMatrix &dshape) const
2254 {
2255  if (dshape.Height() == 4)
2256  {
2257  double *A = &dshape(0,0);
2258  A[0] = -1.; A[4] = -1.; A[8] = -1.;
2259  A[1] = 1.; A[5] = 0.; A[9] = 0.;
2260  A[2] = 0.; A[6] = 1.; A[10] = 0.;
2261  A[3] = 0.; A[7] = 0.; A[11] = 1.;
2262  }
2263  else
2264  {
2265  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
2266  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
2267  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
2268  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
2269  }
2270 }
2271 
2272 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
2273 const
2274 {
2275  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
2276 
2277  *ndofs = 3;
2278  *dofs = face_dofs[face];
2279 }
2280 
2281 
2283  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
2284 {
2285  Nodes.IntPoint(0).x = 0.0;
2286  Nodes.IntPoint(0).y = 0.0;
2287  Nodes.IntPoint(0).z = 0.0;
2288  Nodes.IntPoint(1).x = 1.0;
2289  Nodes.IntPoint(1).y = 0.0;
2290  Nodes.IntPoint(1).z = 0.0;
2291  Nodes.IntPoint(2).x = 0.0;
2292  Nodes.IntPoint(2).y = 1.0;
2293  Nodes.IntPoint(2).z = 0.0;
2294  Nodes.IntPoint(3).x = 0.0;
2295  Nodes.IntPoint(3).y = 0.0;
2296  Nodes.IntPoint(3).z = 1.0;
2297  Nodes.IntPoint(4).x = 0.5;
2298  Nodes.IntPoint(4).y = 0.0;
2299  Nodes.IntPoint(4).z = 0.0;
2300  Nodes.IntPoint(5).x = 0.0;
2301  Nodes.IntPoint(5).y = 0.5;
2302  Nodes.IntPoint(5).z = 0.0;
2303  Nodes.IntPoint(6).x = 0.0;
2304  Nodes.IntPoint(6).y = 0.0;
2305  Nodes.IntPoint(6).z = 0.5;
2306  Nodes.IntPoint(7).x = 0.5;
2307  Nodes.IntPoint(7).y = 0.5;
2308  Nodes.IntPoint(7).z = 0.0;
2309  Nodes.IntPoint(8).x = 0.5;
2310  Nodes.IntPoint(8).y = 0.0;
2311  Nodes.IntPoint(8).z = 0.5;
2312  Nodes.IntPoint(9).x = 0.0;
2313  Nodes.IntPoint(9).y = 0.5;
2314  Nodes.IntPoint(9).z = 0.5;
2315 }
2316 
2318  Vector &shape) const
2319 {
2320  double L0, L1, L2, L3;
2321 
2322  L0 = 1. - ip.x - ip.y - ip.z;
2323  L1 = ip.x;
2324  L2 = ip.y;
2325  L3 = ip.z;
2326 
2327  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
2328  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
2329  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
2330  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
2331  shape(4) = 4.0 * L0 * L1;
2332  shape(5) = 4.0 * L0 * L2;
2333  shape(6) = 4.0 * L0 * L3;
2334  shape(7) = 4.0 * L1 * L2;
2335  shape(8) = 4.0 * L1 * L3;
2336  shape(9) = 4.0 * L2 * L3;
2337 }
2338 
2340  DenseMatrix &dshape) const
2341 {
2342  double x, y, z, L0;
2343 
2344  x = ip.x;
2345  y = ip.y;
2346  z = ip.z;
2347  L0 = 1.0 - x - y - z;
2348 
2349  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
2350  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
2351  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
2352  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
2353  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
2354  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
2355  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
2356  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
2357  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
2358  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
2359 }
2360 
2362  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
2363 {
2364  Nodes.IntPoint(0).x = 0.0;
2365  Nodes.IntPoint(0).y = 0.0;
2366  Nodes.IntPoint(0).z = 0.0;
2367 
2368  Nodes.IntPoint(1).x = 1.0;
2369  Nodes.IntPoint(1).y = 0.0;
2370  Nodes.IntPoint(1).z = 0.0;
2371 
2372  Nodes.IntPoint(2).x = 1.0;
2373  Nodes.IntPoint(2).y = 1.0;
2374  Nodes.IntPoint(2).z = 0.0;
2375 
2376  Nodes.IntPoint(3).x = 0.0;
2377  Nodes.IntPoint(3).y = 1.0;
2378  Nodes.IntPoint(3).z = 0.0;
2379 
2380  Nodes.IntPoint(4).x = 0.0;
2381  Nodes.IntPoint(4).y = 0.0;
2382  Nodes.IntPoint(4).z = 1.0;
2383 
2384  Nodes.IntPoint(5).x = 1.0;
2385  Nodes.IntPoint(5).y = 0.0;
2386  Nodes.IntPoint(5).z = 1.0;
2387 
2388  Nodes.IntPoint(6).x = 1.0;
2389  Nodes.IntPoint(6).y = 1.0;
2390  Nodes.IntPoint(6).z = 1.0;
2391 
2392  Nodes.IntPoint(7).x = 0.0;
2393  Nodes.IntPoint(7).y = 1.0;
2394  Nodes.IntPoint(7).z = 1.0;
2395 }
2396 
2398  Vector &shape) const
2399 {
2400  double x = ip.x, y = ip.y, z = ip.z;
2401  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2402 
2403  shape(0) = ox * oy * oz;
2404  shape(1) = x * oy * oz;
2405  shape(2) = x * y * oz;
2406  shape(3) = ox * y * oz;
2407  shape(4) = ox * oy * z;
2408  shape(5) = x * oy * z;
2409  shape(6) = x * y * z;
2410  shape(7) = ox * y * z;
2411 }
2412 
2414  DenseMatrix &dshape) const
2415 {
2416  double x = ip.x, y = ip.y, z = ip.z;
2417  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2418 
2419  dshape(0,0) = - oy * oz;
2420  dshape(0,1) = - ox * oz;
2421  dshape(0,2) = - ox * oy;
2422 
2423  dshape(1,0) = oy * oz;
2424  dshape(1,1) = - x * oz;
2425  dshape(1,2) = - x * oy;
2426 
2427  dshape(2,0) = y * oz;
2428  dshape(2,1) = x * oz;
2429  dshape(2,2) = - x * y;
2430 
2431  dshape(3,0) = - y * oz;
2432  dshape(3,1) = ox * oz;
2433  dshape(3,2) = - ox * y;
2434 
2435  dshape(4,0) = - oy * z;
2436  dshape(4,1) = - ox * z;
2437  dshape(4,2) = ox * oy;
2438 
2439  dshape(5,0) = oy * z;
2440  dshape(5,1) = - x * z;
2441  dshape(5,2) = x * oy;
2442 
2443  dshape(6,0) = y * z;
2444  dshape(6,1) = x * z;
2445  dshape(6,2) = x * y;
2446 
2447  dshape(7,0) = - y * z;
2448  dshape(7,1) = ox * z;
2449  dshape(7,2) = ox * y;
2450 }
2451 
2453  : NodalFiniteElement(1, Geometry::SEGMENT , 1, Ord) // defaul Ord = 0
2454 {
2455  Nodes.IntPoint(0).x = 0.5;
2456 }
2457 
2459  Vector &shape) const
2460 {
2461  shape(0) = 1.0;
2462 }
2463 
2465  DenseMatrix &dshape) const
2466 {
2467  dshape(0,0) = 0.0;
2468 }
2469 
2471  : NodalFiniteElement(2, Geometry::TRIANGLE , 3, 1)
2472 {
2473  Nodes.IntPoint(0).x = 0.5;
2474  Nodes.IntPoint(0).y = 0.0;
2475  Nodes.IntPoint(1).x = 0.5;
2476  Nodes.IntPoint(1).y = 0.5;
2477  Nodes.IntPoint(2).x = 0.0;
2478  Nodes.IntPoint(2).y = 0.5;
2479 }
2480 
2482  Vector &shape) const
2483 {
2484  shape(0) = 1.0 - 2.0 * ip.y;
2485  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
2486  shape(2) = 1.0 - 2.0 * ip.x;
2487 }
2488 
2490  DenseMatrix &dshape) const
2491 {
2492  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
2493  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
2494  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
2495 }
2496 
2498 // the FunctionSpace should be rotated (45 degrees) Q_1
2499 // i.e. the span of { 1, x, y, x^2 - y^2 }
2500  : NodalFiniteElement(2, Geometry::SQUARE , 4, 2, FunctionSpace::Qk)
2501 {
2502  Nodes.IntPoint(0).x = 0.5;
2503  Nodes.IntPoint(0).y = 0.0;
2504  Nodes.IntPoint(1).x = 1.0;
2505  Nodes.IntPoint(1).y = 0.5;
2506  Nodes.IntPoint(2).x = 0.5;
2507  Nodes.IntPoint(2).y = 1.0;
2508  Nodes.IntPoint(3).x = 0.0;
2509  Nodes.IntPoint(3).y = 0.5;
2510 }
2511 
2513  Vector &shape) const
2514 {
2515  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
2516 
2517  shape(0) = l2 * l3;
2518  shape(1) = l1 * l3;
2519  shape(2) = l1 * l4;
2520  shape(3) = l2 * l4;
2521 }
2522 
2524  DenseMatrix &dshape) const
2525 {
2526  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
2527 
2528  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
2529  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
2530  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
2531  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
2532 }
2533 
2534 
2536  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
2537 {
2538  Nodes.IntPoint(0).x = 0.5;
2539  Nodes.IntPoint(0).y = 0.0;
2540  Nodes.IntPoint(1).x = 0.5;
2541  Nodes.IntPoint(1).y = 0.5;
2542  Nodes.IntPoint(2).x = 0.0;
2543  Nodes.IntPoint(2).y = 0.5;
2544 }
2545 
2547  DenseMatrix &shape) const
2548 {
2549  double x = ip.x, y = ip.y;
2550 
2551  shape(0,0) = x;
2552  shape(0,1) = y - 1.;
2553  shape(1,0) = x;
2554  shape(1,1) = y;
2555  shape(2,0) = x - 1.;
2556  shape(2,1) = y;
2557 }
2558 
2560  Vector &divshape) const
2561 {
2562  divshape(0) = 2.;
2563  divshape(1) = 2.;
2564  divshape(2) = 2.;
2565 }
2566 
2567 const double RT0TriangleFiniteElement::nk[3][2] =
2568 { {0, -1}, {1, 1}, {-1, 0} };
2569 
2572 {
2573  int k, j;
2574 #ifdef MFEM_THREAD_SAFE
2576  DenseMatrix Jinv(Dim);
2577 #endif
2578 
2579 #ifdef MFEM_DEBUG
2580  for (k = 0; k < 3; k++)
2581  {
2583  for (j = 0; j < 3; j++)
2584  {
2585  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2586  if (j == k) { d -= 1.0; }
2587  if (fabs(d) > 1.0e-12)
2588  {
2589  cerr << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
2590  " k = " << k << ", j = " << j << ", d = " << d << endl;
2591  mfem_error();
2592  }
2593  }
2594  }
2595 #endif
2596 
2597  IntegrationPoint ip;
2598  ip.x = ip.y = 0.0;
2599  Trans.SetIntPoint (&ip);
2600  // Trans must be linear
2601  // set Jinv = |J| J^{-t} = adj(J)^t
2602  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2603  double vk[2];
2604  Vector xk (vk, 2);
2605 
2606  for (k = 0; k < 3; k++)
2607  {
2608  Trans.Transform (Nodes.IntPoint (k), xk);
2609  ip.x = vk[0]; ip.y = vk[1];
2610  CalcVShape (ip, vshape);
2611  // vk = |J| J^{-t} nk
2612  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2613  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2614  for (j = 0; j < 3; j++)
2615  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2616  {
2617  I(k,j) = 0.0;
2618  }
2619  }
2620 }
2621 
2624  Vector &dofs) const
2625 {
2626  double vk[2];
2627  Vector xk (vk, 2);
2628 #ifdef MFEM_THREAD_SAFE
2629  DenseMatrix Jinv(Dim);
2630 #endif
2631 
2632  for (int k = 0; k < 3; k++)
2633  {
2634  Trans.SetIntPoint (&Nodes.IntPoint (k));
2635  // set Jinv = |J| J^{-t} = adj(J)^t
2636  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2637 
2638  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2639  // xk^t |J| J^{-t} nk
2640  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2641  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2642  }
2643 }
2644 
2646  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
2647 {
2648  Nodes.IntPoint(0).x = 0.5;
2649  Nodes.IntPoint(0).y = 0.0;
2650  Nodes.IntPoint(1).x = 1.0;
2651  Nodes.IntPoint(1).y = 0.5;
2652  Nodes.IntPoint(2).x = 0.5;
2653  Nodes.IntPoint(2).y = 1.0;
2654  Nodes.IntPoint(3).x = 0.0;
2655  Nodes.IntPoint(3).y = 0.5;
2656 }
2657 
2659  DenseMatrix &shape) const
2660 {
2661  double x = ip.x, y = ip.y;
2662 
2663  shape(0,0) = 0;
2664  shape(0,1) = y - 1.;
2665  shape(1,0) = x;
2666  shape(1,1) = 0;
2667  shape(2,0) = 0;
2668  shape(2,1) = y;
2669  shape(3,0) = x - 1.;
2670  shape(3,1) = 0;
2671 }
2672 
2674  Vector &divshape) const
2675 {
2676  divshape(0) = 1.;
2677  divshape(1) = 1.;
2678  divshape(2) = 1.;
2679  divshape(3) = 1.;
2680 }
2681 
2682 const double RT0QuadFiniteElement::nk[4][2] =
2683 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
2684 
2687 {
2688  int k, j;
2689 #ifdef MFEM_THREAD_SAFE
2691  DenseMatrix Jinv(Dim);
2692 #endif
2693 
2694 #ifdef MFEM_DEBUG
2695  for (k = 0; k < 4; k++)
2696  {
2698  for (j = 0; j < 4; j++)
2699  {
2700  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2701  if (j == k) { d -= 1.0; }
2702  if (fabs(d) > 1.0e-12)
2703  {
2704  cerr << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
2705  " k = " << k << ", j = " << j << ", d = " << d << endl;
2706  mfem_error();
2707  }
2708  }
2709  }
2710 #endif
2711 
2712  IntegrationPoint ip;
2713  ip.x = ip.y = 0.0;
2714  Trans.SetIntPoint (&ip);
2715  // Trans must be linear (more to have embedding?)
2716  // set Jinv = |J| J^{-t} = adj(J)^t
2717  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2718  double vk[2];
2719  Vector xk (vk, 2);
2720 
2721  for (k = 0; k < 4; k++)
2722  {
2723  Trans.Transform (Nodes.IntPoint (k), xk);
2724  ip.x = vk[0]; ip.y = vk[1];
2725  CalcVShape (ip, vshape);
2726  // vk = |J| J^{-t} nk
2727  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2728  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2729  for (j = 0; j < 4; j++)
2730  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2731  {
2732  I(k,j) = 0.0;
2733  }
2734  }
2735 }
2736 
2739  Vector &dofs) const
2740 {
2741  double vk[2];
2742  Vector xk (vk, 2);
2743 #ifdef MFEM_THREAD_SAFE
2744  DenseMatrix Jinv(Dim);
2745 #endif
2746 
2747  for (int k = 0; k < 4; k++)
2748  {
2749  Trans.SetIntPoint (&Nodes.IntPoint (k));
2750  // set Jinv = |J| J^{-t} = adj(J)^t
2751  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2752 
2753  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2754  // xk^t |J| J^{-t} nk
2755  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2756  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2757  }
2758 }
2759 
2761  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
2762 {
2763  Nodes.IntPoint(0).x = 0.33333333333333333333;
2764  Nodes.IntPoint(0).y = 0.0;
2765  Nodes.IntPoint(1).x = 0.66666666666666666667;
2766  Nodes.IntPoint(1).y = 0.0;
2767  Nodes.IntPoint(2).x = 0.66666666666666666667;
2768  Nodes.IntPoint(2).y = 0.33333333333333333333;
2769  Nodes.IntPoint(3).x = 0.33333333333333333333;
2770  Nodes.IntPoint(3).y = 0.66666666666666666667;
2771  Nodes.IntPoint(4).x = 0.0;
2772  Nodes.IntPoint(4).y = 0.66666666666666666667;
2773  Nodes.IntPoint(5).x = 0.0;
2774  Nodes.IntPoint(5).y = 0.33333333333333333333;
2775  Nodes.IntPoint(6).x = 0.33333333333333333333;
2776  Nodes.IntPoint(6).y = 0.33333333333333333333;
2777  Nodes.IntPoint(7).x = 0.33333333333333333333;
2778  Nodes.IntPoint(7).y = 0.33333333333333333333;
2779 }
2780 
2782  DenseMatrix &shape) const
2783 {
2784  double x = ip.x, y = ip.y;
2785 
2786  shape(0,0) = -2 * x * (-1 + x + 2 * y);
2787  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
2788  shape(1,0) = 2 * x * (x - y);
2789  shape(1,1) = 2 * (x - y) * (-1 + y);
2790  shape(2,0) = 2 * x * (-1 + 2 * x + y);
2791  shape(2,1) = 2 * y * (-1 + 2 * x + y);
2792  shape(3,0) = 2 * x * (-1 + x + 2 * y);
2793  shape(3,1) = 2 * y * (-1 + x + 2 * y);
2794  shape(4,0) = -2 * (-1 + x) * (x - y);
2795  shape(4,1) = 2 * y * (-x + y);
2796  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
2797  shape(5,1) = -2 * y * (-1 + 2 * x + y);
2798  shape(6,0) = -3 * x * (-2 + 2 * x + y);
2799  shape(6,1) = -3 * y * (-1 + 2 * x + y);
2800  shape(7,0) = -3 * x * (-1 + x + 2 * y);
2801  shape(7,1) = -3 * y * (-2 + x + 2 * y);
2802 }
2803 
2805  Vector &divshape) const
2806 {
2807  double x = ip.x, y = ip.y;
2808 
2809  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
2810  divshape(1) = 2 + 6 * x - 6 * y;
2811  divshape(2) = -4 + 12 * x + 6 * y;
2812  divshape(3) = -4 + 6 * x + 12 * y;
2813  divshape(4) = 2 - 6 * x + 6 * y;
2814  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
2815  divshape(6) = -9 * (-1 + 2 * x + y);
2816  divshape(7) = -9 * (-1 + x + 2 * y);
2817 }
2818 
2819 const double RT1TriangleFiniteElement::nk[8][2] =
2820 {
2821  { 0,-1}, { 0,-1},
2822  { 1, 1}, { 1, 1},
2823  {-1, 0}, {-1, 0},
2824  { 1, 0}, { 0, 1}
2825 };
2826 
2829 {
2830  int k, j;
2831 #ifdef MFEM_THREAD_SAFE
2833  DenseMatrix Jinv(Dim);
2834 #endif
2835 
2836 #ifdef MFEM_DEBUG
2837  for (k = 0; k < 8; k++)
2838  {
2840  for (j = 0; j < 8; j++)
2841  {
2842  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2843  if (j == k) { d -= 1.0; }
2844  if (fabs(d) > 1.0e-12)
2845  {
2846  cerr << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
2847  " k = " << k << ", j = " << j << ", d = " << d << endl;
2848  mfem_error();
2849  }
2850  }
2851  }
2852 #endif
2853 
2854  IntegrationPoint ip;
2855  ip.x = ip.y = 0.0;
2856  Trans.SetIntPoint (&ip);
2857  // Trans must be linear (more to have embedding?)
2858  // set Jinv = |J| J^{-t} = adj(J)^t
2859  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2860  double vk[2];
2861  Vector xk (vk, 2);
2862 
2863  for (k = 0; k < 8; k++)
2864  {
2865  Trans.Transform (Nodes.IntPoint (k), xk);
2866  ip.x = vk[0]; ip.y = vk[1];
2867  CalcVShape (ip, vshape);
2868  // vk = |J| J^{-t} nk
2869  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2870  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2871  for (j = 0; j < 8; j++)
2872  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2873  {
2874  I(k,j) = 0.0;
2875  }
2876  }
2877 }
2878 
2881 {
2882  double vk[2];
2883  Vector xk (vk, 2);
2884 #ifdef MFEM_THREAD_SAFE
2885  DenseMatrix Jinv(Dim);
2886 #endif
2887 
2888  for (int k = 0; k < 8; k++)
2889  {
2890  Trans.SetIntPoint (&Nodes.IntPoint (k));
2891  // set Jinv = |J| J^{-t} = adj(J)^t
2892  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2893 
2894  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2895  // xk^t |J| J^{-t} nk
2896  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2897  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2898  dofs(k) *= 0.5;
2899  }
2900 }
2901 
2903  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
2904 {
2905  // y = 0
2906  Nodes.IntPoint(0).x = 1./3.;
2907  Nodes.IntPoint(0).y = 0.0;
2908  Nodes.IntPoint(1).x = 2./3.;
2909  Nodes.IntPoint(1).y = 0.0;
2910  // x = 1
2911  Nodes.IntPoint(2).x = 1.0;
2912  Nodes.IntPoint(2).y = 1./3.;
2913  Nodes.IntPoint(3).x = 1.0;
2914  Nodes.IntPoint(3).y = 2./3.;
2915  // y = 1
2916  Nodes.IntPoint(4).x = 2./3.;
2917  Nodes.IntPoint(4).y = 1.0;
2918  Nodes.IntPoint(5).x = 1./3.;
2919  Nodes.IntPoint(5).y = 1.0;
2920  // x = 0
2921  Nodes.IntPoint(6).x = 0.0;
2922  Nodes.IntPoint(6).y = 2./3.;
2923  Nodes.IntPoint(7).x = 0.0;
2924  Nodes.IntPoint(7).y = 1./3.;
2925  // x = 0.5 (interior)
2926  Nodes.IntPoint(8).x = 0.5;
2927  Nodes.IntPoint(8).y = 1./3.;
2928  Nodes.IntPoint(9).x = 0.5;
2929  Nodes.IntPoint(9).y = 2./3.;
2930  // y = 0.5 (interior)
2931  Nodes.IntPoint(10).x = 1./3.;
2932  Nodes.IntPoint(10).y = 0.5;
2933  Nodes.IntPoint(11).x = 2./3.;
2934  Nodes.IntPoint(11).y = 0.5;
2935 }
2936 
2938  DenseMatrix &shape) const
2939 {
2940  double x = ip.x, y = ip.y;
2941 
2942  // y = 0
2943  shape(0,0) = 0;
2944  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
2945  shape(1,0) = 0;
2946  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
2947  // x = 1
2948  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
2949  shape(2,1) = 0;
2950  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
2951  shape(3,1) = 0;
2952  // y = 1
2953  shape(4,0) = 0;
2954  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
2955  shape(5,0) = 0;
2956  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
2957  // x = 0
2958  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
2959  shape(6,1) = 0;
2960  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
2961  shape(7,1) = 0;
2962  // x = 0.5 (interior)
2963  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
2964  shape(8,1) = 0;
2965  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
2966  shape(9,1) = 0;
2967  // y = 0.5 (interior)
2968  shape(10,0) = 0;
2969  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
2970  shape(11,0) = 0;
2971  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
2972 }
2973 
2975  Vector &divshape) const
2976 {
2977  double x = ip.x, y = ip.y;
2978 
2979  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
2980  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
2981  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
2982  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
2983  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
2984  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
2985  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
2986  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
2987  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
2988  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
2989  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
2990  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
2991 }
2992 
2993 const double RT1QuadFiniteElement::nk[12][2] =
2994 {
2995  // y = 0
2996  {0,-1}, {0,-1},
2997  // X = 1
2998  {1, 0}, {1, 0},
2999  // y = 1
3000  {0, 1}, {0, 1},
3001  // x = 0
3002  {-1,0}, {-1,0},
3003  // x = 0.5 (interior)
3004  {1, 0}, {1, 0},
3005  // y = 0.5 (interior)
3006  {0, 1}, {0, 1}
3007 };
3008 
3011 {
3012  int k, j;
3013 #ifdef MFEM_THREAD_SAFE
3015  DenseMatrix Jinv(Dim);
3016 #endif
3017 
3018 #ifdef MFEM_DEBUG
3019  for (k = 0; k < 12; k++)
3020  {
3022  for (j = 0; j < 12; j++)
3023  {
3024  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3025  if (j == k) { d -= 1.0; }
3026  if (fabs(d) > 1.0e-12)
3027  {
3028  cerr << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
3029  " k = " << k << ", j = " << j << ", d = " << d << endl;
3030  mfem_error();
3031  }
3032  }
3033  }
3034 #endif
3035 
3036  IntegrationPoint ip;
3037  ip.x = ip.y = 0.0;
3038  Trans.SetIntPoint (&ip);
3039  // Trans must be linear (more to have embedding?)
3040  // set Jinv = |J| J^{-t} = adj(J)^t
3041  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3042  double vk[2];
3043  Vector xk (vk, 2);
3044 
3045  for (k = 0; k < 12; k++)
3046  {
3047  Trans.Transform (Nodes.IntPoint (k), xk);
3048  ip.x = vk[0]; ip.y = vk[1];
3049  CalcVShape (ip, vshape);
3050  // vk = |J| J^{-t} nk
3051  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3052  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3053  for (j = 0; j < 12; j++)
3054  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3055  {
3056  I(k,j) = 0.0;
3057  }
3058  }
3059 }
3060 
3063 {
3064  double vk[2];
3065  Vector xk (vk, 2);
3066 #ifdef MFEM_THREAD_SAFE
3067  DenseMatrix Jinv(Dim);
3068 #endif
3069 
3070  for (int k = 0; k < 12; k++)
3071  {
3072  Trans.SetIntPoint (&Nodes.IntPoint (k));
3073  // set Jinv = |J| J^{-t} = adj(J)^t
3074  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3075 
3076  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3077  // xk^t |J| J^{-t} nk
3078  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3079  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3080  }
3081 }
3082 
3083 const double RT2TriangleFiniteElement::M[15][15] =
3084 {
3085  {
3086  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
3087  0, 24.442740046346700787, -16.647580015448900262, -12.,
3088  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
3089  12., 30.590320061795601049, 15.295160030897800524
3090  },
3091  {
3092  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
3093  -15., 10.5
3094  },
3095  {
3096  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
3097  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
3098  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
3099  12., -6.5903200617956010489, -3.2951600308978005244
3100  },
3101  {
3102  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
3103  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
3104  0, -3.2951600308978005244
3105  },
3106  {
3107  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
3108  36., 10.5
3109  },
3110  {
3111  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
3112  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
3113  0, 15.295160030897800524
3114  },
3115  {
3116  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
3117  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
3118  -0.76209992275549868892, 4.1189500386222506555, -12.,
3119  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
3120  12.
3121  },
3122  {
3123  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
3124  -15., -15.
3125  },
3126  {
3127  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
3128  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
3129  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
3130  30.590320061795601049, 12.
3131  },
3132  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
3133  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
3134  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
3135  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
3136  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
3137  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
3138 };
3139 
3141  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
3142 {
3143  const double p = 0.11270166537925831148;
3144 
3145  Nodes.IntPoint(0).x = p;
3146  Nodes.IntPoint(0).y = 0.0;
3147  Nodes.IntPoint(1).x = 0.5;
3148  Nodes.IntPoint(1).y = 0.0;
3149  Nodes.IntPoint(2).x = 1.-p;
3150  Nodes.IntPoint(2).y = 0.0;
3151  Nodes.IntPoint(3).x = 1.-p;
3152  Nodes.IntPoint(3).y = p;
3153  Nodes.IntPoint(4).x = 0.5;
3154  Nodes.IntPoint(4).y = 0.5;
3155  Nodes.IntPoint(5).x = p;
3156  Nodes.IntPoint(5).y = 1.-p;
3157  Nodes.IntPoint(6).x = 0.0;
3158  Nodes.IntPoint(6).y = 1.-p;
3159  Nodes.IntPoint(7).x = 0.0;
3160  Nodes.IntPoint(7).y = 0.5;
3161  Nodes.IntPoint(8).x = 0.0;
3162  Nodes.IntPoint(8).y = p;
3163  Nodes.IntPoint(9).x = 0.25;
3164  Nodes.IntPoint(9).y = 0.25;
3165  Nodes.IntPoint(10).x = 0.25;
3166  Nodes.IntPoint(10).y = 0.25;
3167  Nodes.IntPoint(11).x = 0.5;
3168  Nodes.IntPoint(11).y = 0.25;
3169  Nodes.IntPoint(12).x = 0.5;
3170  Nodes.IntPoint(12).y = 0.25;
3171  Nodes.IntPoint(13).x = 0.25;
3172  Nodes.IntPoint(13).y = 0.5;
3173  Nodes.IntPoint(14).x = 0.25;
3174  Nodes.IntPoint(14).y = 0.5;
3175 }
3176 
3178  DenseMatrix &shape) const
3179 {
3180  double x = ip.x, y = ip.y;
3181 
3182  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
3183  x*x*y, x*y*y
3184  };
3185  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
3186  x*x*y, x*y*y, y*y*y
3187  };
3188 
3189  for (int i = 0; i < 15; i++)
3190  {
3191  double cx = 0.0, cy = 0.0;
3192  for (int j = 0; j < 15; j++)
3193  {
3194  cx += M[i][j] * Bx[j];
3195  cy += M[i][j] * By[j];
3196  }
3197  shape(i,0) = cx;
3198  shape(i,1) = cy;
3199  }
3200 }
3201 
3203  Vector &divshape) const
3204 {
3205  double x = ip.x, y = ip.y;
3206 
3207  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
3208  4.*x*x, 4.*x*y, 4.*y*y
3209  };
3210 
3211  for (int i = 0; i < 15; i++)
3212  {
3213  double div = 0.0;
3214  for (int j = 0; j < 15; j++)
3215  {
3216  div += M[i][j] * DivB[j];
3217  }
3218  divshape(i) = div;
3219  }
3220 }
3221 
3222 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
3223 
3224 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
3225 
3227  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
3228 {
3229  // y = 0 (pt[0])
3230  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
3231  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
3232  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
3233  // x = 1 (pt[3])
3234  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
3235  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
3236  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
3237  // y = 1 (pt[3])
3238  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
3239  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
3240  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
3241  // x = 0 (pt[0])
3242  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
3243  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
3244  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
3245  // x = pt[1] (interior)
3246  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
3247  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
3248  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
3249  // x = pt[2] (interior)
3250  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
3251  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
3252  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
3253  // y = pt[1] (interior)
3254  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
3255  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
3256  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
3257  // y = pt[2] (interior)
3258  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
3259  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
3260  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
3261 }
3262 
3264  DenseMatrix &shape) const
3265 {
3266  double x = ip.x, y = ip.y;
3267 
3268  double ax0 = pt[0] - x;
3269  double ax1 = pt[1] - x;
3270  double ax2 = pt[2] - x;
3271  double ax3 = pt[3] - x;
3272 
3273  double by0 = dpt[0] - y;
3274  double by1 = dpt[1] - y;
3275  double by2 = dpt[2] - y;
3276 
3277  double ay0 = pt[0] - y;
3278  double ay1 = pt[1] - y;
3279  double ay2 = pt[2] - y;
3280  double ay3 = pt[3] - y;
3281 
3282  double bx0 = dpt[0] - x;
3283  double bx1 = dpt[1] - x;
3284  double bx2 = dpt[2] - x;
3285 
3286  double A01 = pt[0] - pt[1];
3287  double A02 = pt[0] - pt[2];
3288  double A12 = pt[1] - pt[2];
3289  double A03 = pt[0] - pt[3];
3290  double A13 = pt[1] - pt[3];
3291  double A23 = pt[2] - pt[3];
3292 
3293  double B01 = dpt[0] - dpt[1];
3294  double B02 = dpt[0] - dpt[2];
3295  double B12 = dpt[1] - dpt[2];
3296 
3297  double tx0 = (bx1*bx2)/(B01*B02);
3298  double tx1 = -(bx0*bx2)/(B01*B12);
3299  double tx2 = (bx0*bx1)/(B02*B12);
3300 
3301  double ty0 = (by1*by2)/(B01*B02);
3302  double ty1 = -(by0*by2)/(B01*B12);
3303  double ty2 = (by0*by1)/(B02*B12);
3304 
3305  // y = 0 (p[0])
3306  shape(0, 0) = 0;
3307  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
3308  shape(1, 0) = 0;
3309  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
3310  shape(2, 0) = 0;
3311  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
3312  // x = 1 (p[3])
3313  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
3314  shape(3, 1) = 0;
3315  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
3316  shape(4, 1) = 0;
3317  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
3318  shape(5, 1) = 0;
3319  // y = 1 (p[3])
3320  shape(6, 0) = 0;
3321  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
3322  shape(7, 0) = 0;
3323  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
3324  shape(8, 0) = 0;
3325  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
3326  // x = 0 (p[0])
3327  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
3328  shape(9, 1) = 0;
3329  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
3330  shape(10, 1) = 0;
3331  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
3332  shape(11, 1) = 0;
3333  // x = p[1] (interior)
3334  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
3335  shape(12, 1) = 0;
3336  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
3337  shape(13, 1) = 0;
3338  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
3339  shape(14, 1) = 0;
3340  // x = p[2] (interior)
3341  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
3342  shape(15, 1) = 0;
3343  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
3344  shape(16, 1) = 0;
3345  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
3346  shape(17, 1) = 0;
3347  // y = p[1] (interior)
3348  shape(18, 0) = 0;
3349  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
3350  shape(19, 0) = 0;
3351  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
3352  shape(20, 0) = 0;
3353  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
3354  // y = p[2] (interior)
3355  shape(21, 0) = 0;
3356  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
3357  shape(22, 0) = 0;
3358  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
3359  shape(23, 0) = 0;
3360  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
3361 }
3362 
3364  Vector &divshape) const
3365 {
3366  double x = ip.x, y = ip.y;
3367 
3368  double a01 = pt[0]*pt[1];
3369  double a02 = pt[0]*pt[2];
3370  double a12 = pt[1]*pt[2];
3371  double a03 = pt[0]*pt[3];
3372  double a13 = pt[1]*pt[3];
3373  double a23 = pt[2]*pt[3];
3374 
3375  double bx0 = dpt[0] - x;
3376  double bx1 = dpt[1] - x;
3377  double bx2 = dpt[2] - x;
3378 
3379  double by0 = dpt[0] - y;
3380  double by1 = dpt[1] - y;
3381  double by2 = dpt[2] - y;
3382 
3383  double A01 = pt[0] - pt[1];
3384  double A02 = pt[0] - pt[2];
3385  double A12 = pt[1] - pt[2];
3386  double A03 = pt[0] - pt[3];
3387  double A13 = pt[1] - pt[3];
3388  double A23 = pt[2] - pt[3];
3389 
3390  double A012 = pt[0] + pt[1] + pt[2];
3391  double A013 = pt[0] + pt[1] + pt[3];
3392  double A023 = pt[0] + pt[2] + pt[3];
3393  double A123 = pt[1] + pt[2] + pt[3];
3394 
3395  double B01 = dpt[0] - dpt[1];
3396  double B02 = dpt[0] - dpt[2];
3397  double B12 = dpt[1] - dpt[2];
3398 
3399  double tx0 = (bx1*bx2)/(B01*B02);
3400  double tx1 = -(bx0*bx2)/(B01*B12);
3401  double tx2 = (bx0*bx1)/(B02*B12);
3402 
3403  double ty0 = (by1*by2)/(B01*B02);
3404  double ty1 = -(by0*by2)/(B01*B12);
3405  double ty2 = (by0*by1)/(B02*B12);
3406 
3407  // y = 0 (p[0])
3408  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
3409  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
3410  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
3411  // x = 1 (p[3])
3412  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
3413  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
3414  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
3415  // y = 1 (p[3])
3416  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
3417  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
3418  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
3419  // x = 0 (p[0])
3420  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
3421  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
3422  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
3423  // x = p[1] (interior)
3424  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
3425  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
3426  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
3427  // x = p[2] (interior)
3428  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
3429  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
3430  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
3431  // y = p[1] (interior)
3432  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
3433  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
3434  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
3435  // y = p[2] (interior)
3436  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
3437  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
3438  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
3439 }
3440 
3441 const double RT2QuadFiniteElement::nk[24][2] =
3442 {
3443  // y = 0
3444  {0,-1}, {0,-1}, {0,-1},
3445  // x = 1
3446  {1, 0}, {1, 0}, {1, 0},
3447  // y = 1
3448  {0, 1}, {0, 1}, {0, 1},
3449  // x = 0
3450  {-1,0}, {-1,0}, {-1,0},
3451  // x = p[1] (interior)
3452  {1, 0}, {1, 0}, {1, 0},
3453  // x = p[2] (interior)
3454  {1, 0}, {1, 0}, {1, 0},
3455  // y = p[1] (interior)
3456  {0, 1}, {0, 1}, {0, 1},
3457  // y = p[1] (interior)
3458  {0, 1}, {0, 1}, {0, 1}
3459 };
3460 
3463 {
3464  int k, j;
3465 #ifdef MFEM_THREAD_SAFE
3467  DenseMatrix Jinv(Dim);
3468 #endif
3469 
3470 #ifdef MFEM_DEBUG
3471  for (k = 0; k < 24; k++)
3472  {
3474  for (j = 0; j < 24; j++)
3475  {
3476  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3477  if (j == k) { d -= 1.0; }
3478  if (fabs(d) > 1.0e-12)
3479  {
3480  cerr << "RT2QuadFiniteElement::GetLocalInterpolation (...)\n"
3481  " k = " << k << ", j = " << j << ", d = " << d << endl;
3482  mfem_error();
3483  }
3484  }
3485  }
3486 #endif
3487 
3488  IntegrationPoint ip;
3489  ip.x = ip.y = 0.0;
3490  Trans.SetIntPoint (&ip);
3491  // Trans must be linear (more to have embedding?)
3492  // set Jinv = |J| J^{-t} = adj(J)^t
3493  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3494  double vk[2];
3495  Vector xk (vk, 2);
3496 
3497  for (k = 0; k < 24; k++)
3498  {
3499  Trans.Transform (Nodes.IntPoint (k), xk);
3500  ip.x = vk[0]; ip.y = vk[1];
3501  CalcVShape (ip, vshape);
3502  // vk = |J| J^{-t} nk
3503  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3504  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3505  for (j = 0; j < 24; j++)
3506  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3507  {
3508  I(k,j) = 0.0;
3509  }
3510  }
3511 }
3512 
3515 {
3516  double vk[2];
3517  Vector xk (vk, 2);
3518 #ifdef MFEM_THREAD_SAFE
3519  DenseMatrix Jinv(Dim);
3520 #endif
3521 
3522  for (int k = 0; k < 24; k++)
3523  {
3524  Trans.SetIntPoint (&Nodes.IntPoint (k));
3525  // set Jinv = |J| J^{-t} = adj(J)^t
3526  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3527 
3528  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3529  // xk^t |J| J^{-t} nk
3530  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3531  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3532  }
3533 }
3534 
3536  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
3537 {
3538  Nodes.IntPoint(0).x = 0.33333333333333333333;
3539  Nodes.IntPoint(1).x = 0.66666666666666666667;
3540 }
3541 
3543  Vector &shape) const
3544 {
3545  double x = ip.x;
3546 
3547  shape(0) = 2. - 3. * x;
3548  shape(1) = 3. * x - 1.;
3549 }
3550 
3552  DenseMatrix &dshape) const
3553 {
3554  dshape(0,0) = -3.;
3555  dshape(1,0) = 3.;
3556 }
3557 
3558 
3560  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
3561 {
3562  const double p = 0.11270166537925831148;
3563 
3564  Nodes.IntPoint(0).x = p;
3565  Nodes.IntPoint(1).x = 0.5;
3566  Nodes.IntPoint(2).x = 1.-p;
3567 }
3568 
3570  Vector &shape) const
3571 {
3572  const double p = 0.11270166537925831148;
3573  const double w = 1./((1-2*p)*(1-2*p));
3574  double x = ip.x;
3575 
3576  shape(0) = (2*x-1)*(x-1+p)*w;
3577  shape(1) = 4*(x-1+p)*(p-x)*w;
3578  shape(2) = (2*x-1)*(x-p)*w;
3579 }
3580 
3582  DenseMatrix &dshape) const
3583 {
3584  const double p = 0.11270166537925831148;
3585  const double w = 1./((1-2*p)*(1-2*p));
3586  double x = ip.x;
3587 
3588  dshape(0,0) = (-3+4*x+2*p)*w;
3589  dshape(1,0) = (4-8*x)*w;
3590  dshape(2,0) = (-1+4*x-2*p)*w;
3591 }
3592 
3593 
3595  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
3596 {
3597  int i, m = degree;
3598 
3599  Nodes.IntPoint(0).x = 0.0;
3600  Nodes.IntPoint(1).x = 1.0;
3601  for (i = 1; i < m; i++)
3602  {
3603  Nodes.IntPoint(i+1).x = double(i) / m;
3604  }
3605 
3606  rwk.SetSize(degree+1);
3607 #ifndef MFEM_THREAD_SAFE
3608  rxxk.SetSize(degree+1);
3609 #endif
3610 
3611  rwk(0) = 1.0;
3612  for (i = 1; i <= m; i++)
3613  {
3614  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
3615  }
3616  for (i = 0; i < m/2+1; i++)
3617  {
3618  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
3619  }
3620  for (i = m-1; i >= 0; i -= 2)
3621  {
3622  rwk(i) = -rwk(i);
3623  }
3624 }
3625 
3627  Vector &shape) const
3628 {
3629  double w, wk, x = ip.x;
3630  int i, k, m = GetOrder();
3631 
3632 #ifdef MFEM_THREAD_SAFE
3633  Vector rxxk(m+1);
3634 #endif
3635 
3636  k = (int) floor ( m * x + 0.5 );
3637  wk = 1.0;
3638  for (i = 0; i <= m; i++)
3639  if (i != k)
3640  {
3641  wk *= ( rxxk(i) = x - (double)(i) / m );
3642  }
3643  w = wk * ( rxxk(k) = x - (double)(k) / m );
3644 
3645  if (k != 0)
3646  {
3647  shape(0) = w * rwk(0) / rxxk(0);
3648  }
3649  else
3650  {
3651  shape(0) = wk * rwk(0);
3652  }
3653  if (k != m)
3654  {
3655  shape(1) = w * rwk(m) / rxxk(m);
3656  }
3657  else
3658  {
3659  shape(1) = wk * rwk(k);
3660  }
3661  for (i = 1; i < m; i++)
3662  if (i != k)
3663  {
3664  shape(i+1) = w * rwk(i) / rxxk(i);
3665  }
3666  else
3667  {
3668  shape(k+1) = wk * rwk(k);
3669  }
3670 }
3671 
3673  DenseMatrix &dshape) const
3674 {
3675  double s, srx, w, wk, x = ip.x;
3676  int i, k, m = GetOrder();
3677 
3678 #ifdef MFEM_THREAD_SAFE
3679  Vector rxxk(m+1);
3680 #endif
3681 
3682  k = (int) floor ( m * x + 0.5 );
3683  wk = 1.0;
3684  for (i = 0; i <= m; i++)
3685  if (i != k)
3686  {
3687  wk *= ( rxxk(i) = x - (double)(i) / m );
3688  }
3689  w = wk * ( rxxk(k) = x - (double)(k) / m );
3690 
3691  for (i = 0; i <= m; i++)
3692  {
3693  rxxk(i) = 1.0 / rxxk(i);
3694  }
3695  srx = 0.0;
3696  for (i = 0; i <= m; i++)
3697  if (i != k)
3698  {
3699  srx += rxxk(i);
3700  }
3701  s = w * srx + wk;
3702 
3703  if (k != 0)
3704  {
3705  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
3706  }
3707  else
3708  {
3709  dshape(0,0) = wk * srx * rwk(0);
3710  }
3711  if (k != m)
3712  {
3713  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
3714  }
3715  else
3716  {
3717  dshape(1,0) = wk * srx * rwk(k);
3718  }
3719  for (i = 1; i < m; i++)
3720  if (i != k)
3721  {
3722  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
3723  }
3724  else
3725  {
3726  dshape(k+1,0) = wk * srx * rwk(k);
3727  }
3728 }
3729 
3730 
3732  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
3733 {
3734  Nodes.IntPoint(0).x = 0.33333333333333333333;
3735  Nodes.IntPoint(0).y = 0.33333333333333333333;
3736  Nodes.IntPoint(0).z = 0.33333333333333333333;
3737 
3738  Nodes.IntPoint(1).x = 0.0;
3739  Nodes.IntPoint(1).y = 0.33333333333333333333;
3740  Nodes.IntPoint(1).z = 0.33333333333333333333;
3741 
3742  Nodes.IntPoint(2).x = 0.33333333333333333333;
3743  Nodes.IntPoint(2).y = 0.0;
3744  Nodes.IntPoint(2).z = 0.33333333333333333333;
3745 
3746  Nodes.IntPoint(3).x = 0.33333333333333333333;
3747  Nodes.IntPoint(3).y = 0.33333333333333333333;
3748  Nodes.IntPoint(3).z = 0.0;
3749 
3750 }
3751 
3753  Vector &shape) const
3754 {
3755  double L0, L1, L2, L3;
3756 
3757  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
3758  shape(0) = 1.0 - 3.0 * L0;
3759  shape(1) = 1.0 - 3.0 * L1;
3760  shape(2) = 1.0 - 3.0 * L2;
3761  shape(3) = 1.0 - 3.0 * L3;
3762 }
3763 
3765  DenseMatrix &dshape) const
3766 {
3767  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
3768  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
3769  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
3770  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
3771 }
3772 
3773 
3775  : NodalFiniteElement(3, Geometry::TETRAHEDRON , 1, 0)
3776 {
3777  Nodes.IntPoint(0).x = 0.25;
3778  Nodes.IntPoint(0).y = 0.25;
3779  Nodes.IntPoint(0).z = 0.25;
3780 }
3781 
3783  Vector &shape) const
3784 {
3785  shape(0) = 1.0;
3786 }
3787 
3789  DenseMatrix &dshape) const
3790 {
3791  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3792 }
3793 
3794 
3796  : NodalFiniteElement(3, Geometry::CUBE, 1, 0, FunctionSpace::Qk)
3797 {
3798  Nodes.IntPoint(0).x = 0.5;
3799  Nodes.IntPoint(0).y = 0.5;
3800  Nodes.IntPoint(0).z = 0.5;
3801 }
3802 
3804  Vector &shape) const
3805 {
3806  shape(0) = 1.0;
3807 }
3808 
3810  DenseMatrix &dshape) const
3811 {
3812  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3813 }
3814 
3815 
3817  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
3818  degree, FunctionSpace::Qk)
3819 {
3820  if (degree == 2)
3821  {
3822  I = new int[Dof];
3823  J = new int[Dof];
3824  K = new int[Dof];
3825  // nodes
3826  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3827  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3828  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3829  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3830  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3831  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3832  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3833  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3834  // edges
3835  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3836  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
3837  I[10] = 2; J[10] = 1; K[10] = 0;
3838  I[11] = 0; J[11] = 2; K[11] = 0;
3839  I[12] = 2; J[12] = 0; K[12] = 1;
3840  I[13] = 1; J[13] = 2; K[13] = 1;
3841  I[14] = 2; J[14] = 1; K[14] = 1;
3842  I[15] = 0; J[15] = 2; K[15] = 1;
3843  I[16] = 0; J[16] = 0; K[16] = 2;
3844  I[17] = 1; J[17] = 0; K[17] = 2;
3845  I[18] = 1; J[18] = 1; K[18] = 2;
3846  I[19] = 0; J[19] = 1; K[19] = 2;
3847  // faces
3848  I[20] = 2; J[20] = 2; K[20] = 0;
3849  I[21] = 2; J[21] = 0; K[21] = 2;
3850  I[22] = 1; J[22] = 2; K[22] = 2;
3851  I[23] = 2; J[23] = 1; K[23] = 2;
3852  I[24] = 0; J[24] = 2; K[24] = 2;
3853  I[25] = 2; J[25] = 2; K[25] = 1;
3854  // element
3855  I[26] = 2; J[26] = 2; K[26] = 2;
3856  }
3857  else if (degree == 3)
3858  {
3859  I = new int[Dof];
3860  J = new int[Dof];
3861  K = new int[Dof];
3862  // nodes
3863  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3864  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3865  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3866  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3867  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3868  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3869  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3870  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3871  // edges
3872  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3873  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
3874  I[10] = 1; J[10] = 2; K[10] = 0;
3875  I[11] = 1; J[11] = 3; K[11] = 0;
3876  I[12] = 2; J[12] = 1; K[12] = 0;
3877  I[13] = 3; J[13] = 1; K[13] = 0;
3878  I[14] = 0; J[14] = 2; K[14] = 0;
3879  I[15] = 0; J[15] = 3; K[15] = 0;
3880  I[16] = 2; J[16] = 0; K[16] = 1;
3881  I[17] = 3; J[17] = 0; K[17] = 1;
3882  I[18] = 1; J[18] = 2; K[18] = 1;
3883  I[19] = 1; J[19] = 3; K[19] = 1;
3884  I[20] = 2; J[20] = 1; K[20] = 1;
3885  I[21] = 3; J[21] = 1; K[21] = 1;
3886  I[22] = 0; J[22] = 2; K[22] = 1;
3887  I[23] = 0; J[23] = 3; K[23] = 1;
3888  I[24] = 0; J[24] = 0; K[24] = 2;
3889  I[25] = 0; J[25] = 0; K[25] = 3;
3890  I[26] = 1; J[26] = 0; K[26] = 2;
3891  I[27] = 1; J[27] = 0; K[27] = 3;
3892  I[28] = 1; J[28] = 1; K[28] = 2;
3893  I[29] = 1; J[29] = 1; K[29] = 3;
3894  I[30] = 0; J[30] = 1; K[30] = 2;
3895  I[31] = 0; J[31] = 1; K[31] = 3;
3896  // faces
3897  I[32] = 2; J[32] = 3; K[32] = 0;
3898  I[33] = 3; J[33] = 3; K[33] = 0;
3899  I[34] = 2; J[34] = 2; K[34] = 0;
3900  I[35] = 3; J[35] = 2; K[35] = 0;
3901  I[36] = 2; J[36] = 0; K[36] = 2;
3902  I[37] = 3; J[37] = 0; K[37] = 2;
3903  I[38] = 2; J[38] = 0; K[38] = 3;
3904  I[39] = 3; J[39] = 0; K[39] = 3;
3905  I[40] = 1; J[40] = 2; K[40] = 2;
3906  I[41] = 1; J[41] = 3; K[41] = 2;
3907  I[42] = 1; J[42] = 2; K[42] = 3;
3908  I[43] = 1; J[43] = 3; K[43] = 3;
3909  I[44] = 3; J[44] = 1; K[44] = 2;
3910  I[45] = 2; J[45] = 1; K[45] = 2;
3911  I[46] = 3; J[46] = 1; K[46] = 3;
3912  I[47] = 2; J[47] = 1; K[47] = 3;
3913  I[48] = 0; J[48] = 3; K[48] = 2;
3914  I[49] = 0; J[49] = 2; K[49] = 2;
3915  I[50] = 0; J[50] = 3; K[50] = 3;
3916  I[51] = 0; J[51] = 2; K[51] = 3;
3917  I[52] = 2; J[52] = 2; K[52] = 1;
3918  I[53] = 3; J[53] = 2; K[53] = 1;
3919  I[54] = 2; J[54] = 3; K[54] = 1;
3920  I[55] = 3; J[55] = 3; K[55] = 1;
3921  // element
3922  I[56] = 2; J[56] = 2; K[56] = 2;
3923  I[57] = 3; J[57] = 2; K[57] = 2;
3924  I[58] = 3; J[58] = 3; K[58] = 2;
3925  I[59] = 2; J[59] = 3; K[59] = 2;
3926  I[60] = 2; J[60] = 2; K[60] = 3;
3927  I[61] = 3; J[61] = 2; K[61] = 3;
3928  I[62] = 3; J[62] = 3; K[62] = 3;
3929  I[63] = 2; J[63] = 3; K[63] = 3;
3930  }
3931  else
3932  {
3933  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
3934  }
3935 
3936  fe1d = new Lagrange1DFiniteElement(degree);
3937  dof1d = fe1d -> GetDof();
3938 
3939 #ifndef MFEM_THREAD_SAFE
3940  shape1dx.SetSize(dof1d);
3941  shape1dy.SetSize(dof1d);
3942  shape1dz.SetSize(dof1d);
3943 
3944  dshape1dx.SetSize(dof1d,1);
3945  dshape1dy.SetSize(dof1d,1);
3946  dshape1dz.SetSize(dof1d,1);
3947 #endif
3948 
3949  for (int n = 0; n < Dof; n++)
3950  {
3951  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
3952  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
3953  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
3954  }
3955 }
3956 
3958  Vector &shape) const
3959 {
3960  IntegrationPoint ipy, ipz;
3961  ipy.x = ip.y;
3962  ipz.x = ip.z;
3963 
3964 #ifdef MFEM_THREAD_SAFE
3965  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
3966 #endif
3967 
3968  fe1d -> CalcShape(ip, shape1dx);
3969  fe1d -> CalcShape(ipy, shape1dy);
3970  fe1d -> CalcShape(ipz, shape1dz);
3971 
3972  for (int n = 0; n < Dof; n++)
3973  {
3974  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
3975  }
3976 }
3977 
3979  DenseMatrix &dshape) const
3980 {
3981  IntegrationPoint ipy, ipz;
3982  ipy.x = ip.y;
3983  ipz.x = ip.z;
3984 
3985 #ifdef MFEM_THREAD_SAFE
3986  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
3987  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
3988 #endif
3989 
3990  fe1d -> CalcShape(ip, shape1dx);
3991  fe1d -> CalcShape(ipy, shape1dy);
3992  fe1d -> CalcShape(ipz, shape1dz);
3993 
3994  fe1d -> CalcDShape(ip, dshape1dx);
3995  fe1d -> CalcDShape(ipy, dshape1dy);
3996  fe1d -> CalcDShape(ipz, dshape1dz);
3997 
3998  for (int n = 0; n < Dof; n++)
3999  {
4000  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
4001  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
4002  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
4003  }
4004 }
4005 
4007 {
4008  delete fe1d;
4009 
4010  delete [] I;
4011  delete [] J;
4012  delete [] K;
4013 }
4014 
4015 
4017  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
4018 {
4019  Nodes.IntPoint(0).x = 0.0;
4020  Nodes.IntPoint(1).x = 1.0;
4021  Nodes.IntPoint(2).x = 0.5;
4022 }
4023 
4025  Vector &shape) const
4026 {
4027  double x = ip.x;
4028 
4029  if (x <= 0.5)
4030  {
4031  shape(0) = 1.0 - 2.0 * x;
4032  shape(1) = 0.0;
4033  shape(2) = 2.0 * x;
4034  }
4035  else
4036  {
4037  shape(0) = 0.0;
4038  shape(1) = 2.0 * x - 1.0;
4039  shape(2) = 2.0 - 2.0 * x;
4040  }
4041 }
4042 
4044  DenseMatrix &dshape) const
4045 {
4046  double x = ip.x;
4047 
4048  if (x <= 0.5)
4049  {
4050  dshape(0,0) = - 2.0;
4051  dshape(1,0) = 0.0;
4052  dshape(2,0) = 2.0;
4053  }
4054  else
4055  {
4056  dshape(0,0) = 0.0;
4057  dshape(1,0) = 2.0;
4058  dshape(2,0) = - 2.0;
4059  }
4060 }
4061 
4063  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
4064 {
4065  Nodes.IntPoint(0).x = 0.0;
4066  Nodes.IntPoint(0).y = 0.0;
4067  Nodes.IntPoint(1).x = 1.0;
4068  Nodes.IntPoint(1).y = 0.0;
4069  Nodes.IntPoint(2).x = 0.0;
4070  Nodes.IntPoint(2).y = 1.0;
4071  Nodes.IntPoint(3).x = 0.5;
4072  Nodes.IntPoint(3).y = 0.0;
4073  Nodes.IntPoint(4).x = 0.5;
4074  Nodes.IntPoint(4).y = 0.5;
4075  Nodes.IntPoint(5).x = 0.0;
4076  Nodes.IntPoint(5).y = 0.5;
4077 }
4078 
4080  Vector &shape) const
4081 {
4082  int i;
4083 
4084  double L0, L1, L2;
4085  L0 = 2.0 * ( 1. - ip.x - ip.y );
4086  L1 = 2.0 * ( ip.x );
4087  L2 = 2.0 * ( ip.y );
4088 
4089  // The reference triangle is split in 4 triangles as follows:
4090  //
4091  // T0 - 0,3,5
4092  // T1 - 1,3,4
4093  // T2 - 2,4,5
4094  // T3 - 3,4,5
4095 
4096  for (i = 0; i < 6; i++)
4097  {
4098  shape(i) = 0.0;
4099  }
4100 
4101  if (L0 >= 1.0) // T0
4102  {
4103  shape(0) = L0 - 1.0;
4104  shape(3) = L1;
4105  shape(5) = L2;
4106  }
4107  else if (L1 >= 1.0) // T1
4108  {
4109  shape(3) = L0;
4110  shape(1) = L1 - 1.0;
4111  shape(4) = L2;
4112  }
4113  else if (L2 >= 1.0) // T2
4114  {
4115  shape(5) = L0;
4116  shape(4) = L1;
4117  shape(2) = L2 - 1.0;
4118  }
4119  else // T3
4120  {
4121  shape(3) = 1.0 - L2;
4122  shape(4) = 1.0 - L0;
4123  shape(5) = 1.0 - L1;
4124  }
4125 }
4126 
4128  DenseMatrix &dshape) const
4129 {
4130  int i,j;
4131 
4132  double L0, L1, L2;
4133  L0 = 2.0 * ( 1. - ip.x - ip.y );
4134  L1 = 2.0 * ( ip.x );
4135  L2 = 2.0 * ( ip.y );
4136 
4137  double DL0[2], DL1[2], DL2[2];
4138  DL0[0] = -2.0; DL0[1] = -2.0;
4139  DL1[0] = 2.0; DL1[1] = 0.0;
4140  DL2[0] = 0.0; DL2[1] = 2.0;
4141 
4142  for (i = 0; i < 6; i++)
4143  for (j = 0; j < 2; j++)
4144  {
4145  dshape(i,j) = 0.0;
4146  }
4147 
4148  if (L0 >= 1.0) // T0
4149  {
4150  for (j = 0; j < 2; j++)
4151  {
4152  dshape(0,j) = DL0[j];
4153  dshape(3,j) = DL1[j];
4154  dshape(5,j) = DL2[j];
4155  }
4156  }
4157  else if (L1 >= 1.0) // T1
4158  {
4159  for (j = 0; j < 2; j++)
4160  {
4161  dshape(3,j) = DL0[j];
4162  dshape(1,j) = DL1[j];
4163  dshape(4,j) = DL2[j];
4164  }
4165  }
4166  else if (L2 >= 1.0) // T2
4167  {
4168  for (j = 0; j < 2; j++)
4169  {
4170  dshape(5,j) = DL0[j];
4171  dshape(4,j) = DL1[j];
4172  dshape(2,j) = DL2[j];
4173  }
4174  }
4175  else // T3
4176  {
4177  for (j = 0; j < 2; j++)
4178  {
4179  dshape(3,j) = - DL2[j];
4180  dshape(4,j) = - DL0[j];
4181  dshape(5,j) = - DL1[j];
4182  }
4183  }
4184 }
4185 
4187  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
4188 {
4189  Nodes.IntPoint(0).x = 0.0;
4190  Nodes.IntPoint(0).y = 0.0;
4191  Nodes.IntPoint(0).z = 0.0;
4192  Nodes.IntPoint(1).x = 1.0;
4193  Nodes.IntPoint(1).y = 0.0;
4194  Nodes.IntPoint(1).z = 0.0;
4195  Nodes.IntPoint(2).x = 0.0;
4196  Nodes.IntPoint(2).y = 1.0;
4197  Nodes.IntPoint(2).z = 0.0;
4198  Nodes.IntPoint(3).x = 0.0;
4199  Nodes.IntPoint(3).y = 0.0;
4200  Nodes.IntPoint(3).z = 1.0;
4201  Nodes.IntPoint(4).x = 0.5;
4202  Nodes.IntPoint(4).y = 0.0;
4203  Nodes.IntPoint(4).z = 0.0;
4204  Nodes.IntPoint(5).x = 0.0;
4205  Nodes.IntPoint(5).y = 0.5;
4206  Nodes.IntPoint(5).z = 0.0;
4207  Nodes.IntPoint(6).x = 0.0;
4208  Nodes.IntPoint(6).y = 0.0;
4209  Nodes.IntPoint(6).z = 0.5;
4210  Nodes.IntPoint(7).x = 0.5;
4211  Nodes.IntPoint(7).y = 0.5;
4212  Nodes.IntPoint(7).z = 0.0;
4213  Nodes.IntPoint(8).x = 0.5;
4214  Nodes.IntPoint(8).y = 0.0;
4215  Nodes.IntPoint(8).z = 0.5;
4216  Nodes.IntPoint(9).x = 0.0;
4217  Nodes.IntPoint(9).y = 0.5;
4218  Nodes.IntPoint(9).z = 0.5;
4219 }
4220 
4222  Vector &shape) const
4223 {
4224  int i;
4225 
4226  double L0, L1, L2, L3, L4, L5;
4227  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4228  L1 = 2.0 * ( ip.x );
4229  L2 = 2.0 * ( ip.y );
4230  L3 = 2.0 * ( ip.z );
4231  L4 = 2.0 * ( ip.x + ip.y );
4232  L5 = 2.0 * ( ip.y + ip.z );
4233 
4234  // The reference tetrahedron is split in 8 tetrahedra as follows:
4235  //
4236  // T0 - 0,4,5,6
4237  // T1 - 1,4,7,8
4238  // T2 - 2,5,7,9
4239  // T3 - 3,6,8,9
4240  // T4 - 4,5,6,8
4241  // T5 - 4,5,7,8
4242  // T6 - 5,6,8,9
4243  // T7 - 5,7,8,9
4244 
4245  for (i = 0; i < 10; i++)
4246  {
4247  shape(i) = 0.0;
4248  }
4249 
4250  if (L0 >= 1.0) // T0
4251  {
4252  shape(0) = L0 - 1.0;
4253  shape(4) = L1;
4254  shape(5) = L2;
4255  shape(6) = L3;
4256  }
4257  else if (L1 >= 1.0) // T1
4258  {
4259  shape(4) = L0;
4260  shape(1) = L1 - 1.0;
4261  shape(7) = L2;
4262  shape(8) = L3;
4263  }
4264  else if (L2 >= 1.0) // T2
4265  {
4266  shape(5) = L0;
4267  shape(7) = L1;
4268  shape(2) = L2 - 1.0;
4269  shape(9) = L3;
4270  }
4271  else if (L3 >= 1.0) // T3
4272  {
4273  shape(6) = L0;
4274  shape(8) = L1;
4275  shape(9) = L2;
4276  shape(3) = L3 - 1.0;
4277  }
4278  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4279  {
4280  shape(4) = 1.0 - L5;
4281  shape(5) = L2;
4282  shape(6) = 1.0 - L4;
4283  shape(8) = 1.0 - L0;
4284  }
4285  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4286  {
4287  shape(4) = 1.0 - L5;
4288  shape(5) = 1.0 - L1;
4289  shape(7) = L4 - 1.0;
4290  shape(8) = L3;
4291  }
4292  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4293  {
4294  shape(5) = 1.0 - L3;
4295  shape(6) = 1.0 - L4;
4296  shape(8) = L1;
4297  shape(9) = L5 - 1.0;
4298  }
4299  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4300  {
4301  shape(5) = L0;
4302  shape(7) = L4 - 1.0;
4303  shape(8) = 1.0 - L2;
4304  shape(9) = L5 - 1.0;
4305  }
4306 }
4307 
4309  DenseMatrix &dshape) const
4310 {
4311  int i,j;
4312 
4313  double L0, L1, L2, L3, L4, L5;
4314  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4315  L1 = 2.0 * ( ip.x );
4316  L2 = 2.0 * ( ip.y );
4317  L3 = 2.0 * ( ip.z );
4318  L4 = 2.0 * ( ip.x + ip.y );
4319  L5 = 2.0 * ( ip.y + ip.z );
4320 
4321  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
4322  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
4323  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
4324  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
4325  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
4326  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
4327  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
4328 
4329  for (i = 0; i < 10; i++)
4330  for (j = 0; j < 3; j++)
4331  {
4332  dshape(i,j) = 0.0;
4333  }
4334 
4335  if (L0 >= 1.0) // T0
4336  {
4337  for (j = 0; j < 3; j++)
4338  {
4339  dshape(0,j) = DL0[j];
4340  dshape(4,j) = DL1[j];
4341  dshape(5,j) = DL2[j];
4342  dshape(6,j) = DL3[j];
4343  }
4344  }
4345  else if (L1 >= 1.0) // T1
4346  {
4347  for (j = 0; j < 3; j++)
4348  {
4349  dshape(4,j) = DL0[j];
4350  dshape(1,j) = DL1[j];
4351  dshape(7,j) = DL2[j];
4352  dshape(8,j) = DL3[j];
4353  }
4354  }
4355  else if (L2 >= 1.0) // T2
4356  {
4357  for (j = 0; j < 3; j++)
4358  {
4359  dshape(5,j) = DL0[j];
4360  dshape(7,j) = DL1[j];
4361  dshape(2,j) = DL2[j];
4362  dshape(9,j) = DL3[j];
4363  }
4364  }
4365  else if (L3 >= 1.0) // T3
4366  {
4367  for (j = 0; j < 3; j++)
4368  {
4369  dshape(6,j) = DL0[j];
4370  dshape(8,j) = DL1[j];
4371  dshape(9,j) = DL2[j];
4372  dshape(3,j) = DL3[j];
4373  }
4374  }
4375  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4376  {
4377  for (j = 0; j < 3; j++)
4378  {
4379  dshape(4,j) = - DL5[j];
4380  dshape(5,j) = DL2[j];
4381  dshape(6,j) = - DL4[j];
4382  dshape(8,j) = - DL0[j];
4383  }
4384  }
4385  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4386  {
4387  for (j = 0; j < 3; j++)
4388  {
4389  dshape(4,j) = - DL5[j];
4390  dshape(5,j) = - DL1[j];
4391  dshape(7,j) = DL4[j];
4392  dshape(8,j) = DL3[j];
4393  }
4394  }
4395  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4396  {
4397  for (j = 0; j < 3; j++)
4398  {
4399  dshape(5,j) = - DL3[j];
4400  dshape(6,j) = - DL4[j];
4401  dshape(8,j) = DL1[j];
4402  dshape(9,j) = DL5[j];
4403  }
4404  }
4405  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4406  {
4407  for (j = 0; j < 3; j++)
4408  {
4409  dshape(5,j) = DL0[j];
4410  dshape(7,j) = DL4[j];
4411  dshape(8,j) = - DL2[j];
4412  dshape(9,j) = DL5[j];
4413  }
4414  }
4415 }
4416 
4417 
4419  : NodalFiniteElement(2, Geometry::SQUARE , 9, 1, FunctionSpace::rQk)
4420 {
4421  Nodes.IntPoint(0).x = 0.0;
4422  Nodes.IntPoint(0).y = 0.0;
4423  Nodes.IntPoint(1).x = 1.0;
4424  Nodes.IntPoint(1).y = 0.0;
4425  Nodes.IntPoint(2).x = 1.0;
4426  Nodes.IntPoint(2).y = 1.0;
4427  Nodes.IntPoint(3).x = 0.0;
4428  Nodes.IntPoint(3).y = 1.0;
4429  Nodes.IntPoint(4).x = 0.5;
4430  Nodes.IntPoint(4).y = 0.0;
4431  Nodes.IntPoint(5).x = 1.0;
4432  Nodes.IntPoint(5).y = 0.5;
4433  Nodes.IntPoint(6).x = 0.5;
4434  Nodes.IntPoint(6).y = 1.0;
4435  Nodes.IntPoint(7).x = 0.0;
4436  Nodes.IntPoint(7).y = 0.5;
4437  Nodes.IntPoint(8).x = 0.5;
4438  Nodes.IntPoint(8).y = 0.5;
4439 }
4440 
4442  Vector &shape) const
4443 {
4444  int i;
4445  double x = ip.x, y = ip.y;
4446  double Lx, Ly;
4447  Lx = 2.0 * ( 1. - x );
4448  Ly = 2.0 * ( 1. - y );
4449 
4450  // The reference square is split in 4 squares as follows:
4451  //
4452  // T0 - 0,4,7,8
4453  // T1 - 1,4,5,8
4454  // T2 - 2,5,6,8
4455  // T3 - 3,6,7,8
4456 
4457  for (i = 0; i < 9; i++)
4458  {
4459  shape(i) = 0.0;
4460  }
4461 
4462  if ((x <= 0.5) && (y <= 0.5)) // T0
4463  {
4464  shape(0) = (Lx - 1.0) * (Ly - 1.0);
4465  shape(4) = (2.0 - Lx) * (Ly - 1.0);
4466  shape(8) = (2.0 - Lx) * (2.0 - Ly);
4467  shape(7) = (Lx - 1.0) * (2.0 - Ly);
4468  }
4469  else if ((x >= 0.5) && (y <= 0.5)) // T1
4470  {
4471  shape(4) = Lx * (Ly - 1.0);
4472  shape(1) = (1.0 - Lx) * (Ly - 1.0);
4473  shape(5) = (1.0 - Lx) * (2.0 - Ly);
4474  shape(8) = Lx * (2.0 - Ly);
4475  }
4476  else if ((x >= 0.5) && (y >= 0.5)) // T2
4477  {
4478  shape(8) = Lx * Ly ;
4479  shape(5) = (1.0 - Lx) * Ly ;
4480  shape(2) = (1.0 - Lx) * (1.0 - Ly);
4481  shape(6) = Lx * (1.0 - Ly);
4482  }
4483  else if ((x <= 0.5) && (y >= 0.5)) // T3
4484  {
4485  shape(7) = (Lx - 1.0) * Ly ;
4486  shape(8) = (2.0 - Lx) * Ly ;
4487  shape(6) = (2.0 - Lx) * (1.0 - Ly);
4488  shape(3) = (Lx - 1.0) * (1.0 - Ly);
4489  }
4490 }
4491 
4493  DenseMatrix &dshape) const
4494 {
4495  int i,j;
4496  double x = ip.x, y = ip.y;
4497  double Lx, Ly;
4498  Lx = 2.0 * ( 1. - x );
4499  Ly = 2.0 * ( 1. - y );
4500 
4501  for (i = 0; i < 9; i++)
4502  for (j = 0; j < 2; j++)
4503  {
4504  dshape(i,j) = 0.0;
4505  }
4506 
4507  if ((x <= 0.5) && (y <= 0.5)) // T0
4508  {
4509  dshape(0,0) = 2.0 * (1.0 - Ly);
4510  dshape(0,1) = 2.0 * (1.0 - Lx);
4511 
4512  dshape(4,0) = 2.0 * (Ly - 1.0);
4513  dshape(4,1) = -2.0 * (2.0 - Lx);
4514 
4515  dshape(8,0) = 2.0 * (2.0 - Ly);
4516  dshape(8,1) = 2.0 * (2.0 - Lx);
4517 
4518  dshape(7,0) = -2.0 * (2.0 - Ly);
4519  dshape(7,0) = 2.0 * (Lx - 1.0);
4520  }
4521  else if ((x >= 0.5) && (y <= 0.5)) // T1
4522  {
4523  dshape(4,0) = -2.0 * (Ly - 1.0);
4524  dshape(4,1) = -2.0 * Lx;
4525 
4526  dshape(1,0) = 2.0 * (Ly - 1.0);
4527  dshape(1,1) = -2.0 * (1.0 - Lx);
4528 
4529  dshape(5,0) = 2.0 * (2.0 - Ly);
4530  dshape(5,1) = 2.0 * (1.0 - Lx);
4531 
4532  dshape(8,0) = -2.0 * (2.0 - Ly);
4533  dshape(8,1) = 2.0 * Lx;
4534  }
4535  else if ((x >= 0.5) && (y >= 0.5)) // T2
4536  {
4537  dshape(8,0) = -2.0 * Ly;
4538  dshape(8,1) = -2.0 * Lx;
4539 
4540  dshape(5,0) = 2.0 * Ly;
4541  dshape(5,1) = -2.0 * (1.0 - Lx);
4542 
4543  dshape(2,0) = 2.0 * (1.0 - Ly);
4544  dshape(2,1) = 2.0 * (1.0 - Lx);
4545 
4546  dshape(6,0) = -2.0 * (1.0 - Ly);
4547  dshape(6,1) = 2.0 * Lx;
4548  }
4549  else if ((x <= 0.5) && (y >= 0.5)) // T3
4550  {
4551  dshape(7,0) = -2.0 * Ly;
4552  dshape(7,1) = -2.0 * (Lx - 1.0);
4553 
4554  dshape(8,0) = 2.0 * Ly ;
4555  dshape(8,1) = -2.0 * (2.0 - Lx);
4556 
4557  dshape(6,0) = 2.0 * (1.0 - Ly);
4558  dshape(6,1) = 2.0 * (2.0 - Lx);
4559 
4560  dshape(3,0) = -2.0 * (1.0 - Ly);
4561  dshape(3,1) = 2.0 * (Lx - 1.0);
4562  }
4563 }
4564 
4566  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
4567 {
4568  double I[27];
4569  double J[27];
4570  double K[27];
4571  // nodes
4572  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
4573  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
4574  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
4575  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
4576  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
4577  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
4578  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
4579  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
4580  // edges
4581  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
4582  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
4583  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
4584  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
4585  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
4586  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
4587  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
4588  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
4589  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
4590  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
4591  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
4592  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
4593  // faces
4594  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
4595  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
4596  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
4597  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
4598  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
4599  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
4600  // element
4601  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
4602 
4603  for (int n = 0; n < 27; n++)
4604  {
4605  Nodes.IntPoint(n).x = I[n];
4606  Nodes.IntPoint(n).y = J[n];
4607  Nodes.IntPoint(n).z = K[n];
4608  }
4609 }
4610 
4612  Vector &shape) const
4613 {
4614  int i, N[8];
4615  double Lx, Ly, Lz;
4616  double x = ip.x, y = ip.y, z = ip.z;
4617 
4618  for (i = 0; i < 27; i++)
4619  {
4620  shape(i) = 0.0;
4621  }
4622 
4623  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4624  {
4625  Lx = 1.0 - 2.0 * x;
4626  Ly = 1.0 - 2.0 * y;
4627  Lz = 1.0 - 2.0 * z;
4628 
4629  N[0] = 0;
4630  N[1] = 8;
4631  N[2] = 20;
4632  N[3] = 11;
4633  N[4] = 16;
4634  N[5] = 21;
4635  N[6] = 26;
4636  N[7] = 24;
4637  }
4638  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4639  {
4640  Lx = 2.0 - 2.0 * x;
4641  Ly = 1.0 - 2.0 * y;
4642  Lz = 1.0 - 2.0 * z;
4643 
4644  N[0] = 8;
4645  N[1] = 1;
4646  N[2] = 9;
4647  N[3] = 20;
4648  N[4] = 21;
4649  N[5] = 17;
4650  N[6] = 22;
4651  N[7] = 26;
4652  }
4653  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4654  {
4655  Lx = 2.0 - 2.0 * x;
4656  Ly = 2.0 - 2.0 * y;
4657  Lz = 1.0 - 2.0 * z;
4658 
4659  N[0] = 20;
4660  N[1] = 9;
4661  N[2] = 2;
4662  N[3] = 10;
4663  N[4] = 26;
4664  N[5] = 22;
4665  N[6] = 18;
4666  N[7] = 23;
4667  }
4668  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4669  {
4670  Lx = 1.0 - 2.0 * x;
4671  Ly = 2.0 - 2.0 * y;
4672  Lz = 1.0 - 2.0 * z;
4673 
4674  N[0] = 11;
4675  N[1] = 20;
4676  N[2] = 10;
4677  N[3] = 3;
4678  N[4] = 24;
4679  N[5] = 26;
4680  N[6] = 23;
4681  N[7] = 19;
4682  }
4683  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4684  {
4685  Lx = 1.0 - 2.0 * x;
4686  Ly = 1.0 - 2.0 * y;
4687  Lz = 2.0 - 2.0 * z;
4688 
4689  N[0] = 16;
4690  N[1] = 21;
4691  N[2] = 26;
4692  N[3] = 24;
4693  N[4] = 4;
4694  N[5] = 12;
4695  N[6] = 25;
4696  N[7] = 15;
4697  }
4698  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4699  {
4700  Lx = 2.0 - 2.0 * x;
4701  Ly = 1.0 - 2.0 * y;
4702  Lz = 2.0 - 2.0 * z;
4703 
4704  N[0] = 21;
4705  N[1] = 17;
4706  N[2] = 22;
4707  N[3] = 26;
4708  N[4] = 12;
4709  N[5] = 5;
4710  N[6] = 13;
4711  N[7] = 25;
4712  }
4713  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4714  {
4715  Lx = 2.0 - 2.0 * x;
4716  Ly = 2.0 - 2.0 * y;
4717  Lz = 2.0 - 2.0 * z;
4718 
4719  N[0] = 26;
4720  N[1] = 22;
4721  N[2] = 18;
4722  N[3] = 23;
4723  N[4] = 25;
4724  N[5] = 13;
4725  N[6] = 6;
4726  N[7] = 14;
4727  }
4728  else // T7
4729  {
4730  Lx = 1.0 - 2.0 * x;
4731  Ly = 2.0 - 2.0 * y;
4732  Lz = 2.0 - 2.0 * z;
4733 
4734  N[0] = 24;
4735  N[1] = 26;
4736  N[2] = 23;
4737  N[3] = 19;
4738  N[4] = 15;
4739  N[5] = 25;
4740  N[6] = 14;
4741  N[7] = 7;
4742  }
4743 
4744  shape(N[0]) = Lx * Ly * Lz;
4745  shape(N[1]) = (1 - Lx) * Ly * Lz;
4746  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
4747  shape(N[3]) = Lx * (1 - Ly) * Lz;
4748  shape(N[4]) = Lx * Ly * (1 - Lz);
4749  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
4750  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
4751  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
4752 }
4753 
4755  DenseMatrix &dshape) const
4756 {
4757  int i, j, N[8];
4758  double Lx, Ly, Lz;
4759  double x = ip.x, y = ip.y, z = ip.z;
4760 
4761  for (i = 0; i < 27; i++)
4762  for (j = 0; j < 3; j++)
4763  {
4764  dshape(i,j) = 0.0;
4765  }
4766 
4767  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4768  {
4769  Lx = 1.0 - 2.0 * x;
4770  Ly = 1.0 - 2.0 * y;
4771  Lz = 1.0 - 2.0 * z;
4772 
4773  N[0] = 0;
4774  N[1] = 8;
4775  N[2] = 20;
4776  N[3] = 11;
4777  N[4] = 16;
4778  N[5] = 21;
4779  N[6] = 26;
4780  N[7] = 24;
4781  }
4782  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4783  {
4784  Lx = 2.0 - 2.0 * x;
4785  Ly = 1.0 - 2.0 * y;
4786  Lz = 1.0 - 2.0 * z;
4787 
4788  N[0] = 8;
4789  N[1] = 1;
4790  N[2] = 9;
4791  N[3] = 20;
4792  N[4] = 21;
4793  N[5] = 17;
4794  N[6] = 22;
4795  N[7] = 26;
4796  }
4797  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4798  {
4799  Lx = 2.0 - 2.0 * x;
4800  Ly = 2.0 - 2.0 * y;
4801  Lz = 1.0 - 2.0 * z;
4802 
4803  N[0] = 20;
4804  N[1] = 9;
4805  N[2] = 2;
4806  N[3] = 10;
4807  N[4] = 26;
4808  N[5] = 22;
4809  N[6] = 18;
4810  N[7] = 23;
4811  }
4812  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4813  {
4814  Lx = 1.0 - 2.0 * x;
4815  Ly = 2.0 - 2.0 * y;
4816  Lz = 1.0 - 2.0 * z;
4817 
4818  N[0] = 11;
4819  N[1] = 20;
4820  N[2] = 10;
4821  N[3] = 3;
4822  N[4] = 24;
4823  N[5] = 26;
4824  N[6] = 23;
4825  N[7] = 19;
4826  }
4827  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4828  {
4829  Lx = 1.0 - 2.0 * x;
4830  Ly = 1.0 - 2.0 * y;
4831  Lz = 2.0 - 2.0 * z;
4832 
4833  N[0] = 16;
4834  N[1] = 21;
4835  N[2] = 26;
4836  N[3] = 24;
4837  N[4] = 4;
4838  N[5] = 12;
4839  N[6] = 25;
4840  N[7] = 15;
4841  }
4842  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4843  {
4844  Lx = 2.0 - 2.0 * x;
4845  Ly = 1.0 - 2.0 * y;
4846  Lz = 2.0 - 2.0 * z;
4847 
4848  N[0] = 21;
4849  N[1] = 17;
4850  N[2] = 22;
4851  N[3] = 26;
4852  N[4] = 12;
4853  N[5] = 5;
4854  N[6] = 13;
4855  N[7] = 25;
4856  }
4857  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4858  {
4859  Lx = 2.0 - 2.0 * x;
4860  Ly = 2.0 - 2.0 * y;
4861  Lz = 2.0 - 2.0 * z;
4862 
4863  N[0] = 26;
4864  N[1] = 22;
4865  N[2] = 18;
4866  N[3] = 23;
4867  N[4] = 25;
4868  N[5] = 13;
4869  N[6] = 6;
4870  N[7] = 14;
4871  }
4872  else // T7
4873  {
4874  Lx = 1.0 - 2.0 * x;
4875  Ly = 2.0 - 2.0 * y;
4876  Lz = 2.0 - 2.0 * z;
4877 
4878  N[0] = 24;
4879  N[1] = 26;
4880  N[2] = 23;
4881  N[3] = 19;
4882  N[4] = 15;
4883  N[5] = 25;
4884  N[6] = 14;
4885  N[7] = 7;
4886  }
4887 
4888  dshape(N[0],0) = -2.0 * Ly * Lz ;
4889  dshape(N[0],1) = -2.0 * Lx * Lz ;
4890  dshape(N[0],2) = -2.0 * Lx * Ly ;
4891 
4892  dshape(N[1],0) = 2.0 * Ly * Lz ;
4893  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
4894  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
4895 
4896  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
4897  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
4898  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
4899 
4900  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
4901  dshape(N[3],1) = 2.0 * Lx * Lz ;
4902  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
4903 
4904  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
4905  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
4906  dshape(N[4],2) = 2.0 * Lx * Ly ;
4907 
4908  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
4909  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
4910  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
4911 
4912  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
4913  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
4914  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
4915 
4916  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
4917  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
4918  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
4919 }
4920 
4921 
4923  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
4924 {
4925  // not real nodes ...
4926  Nodes.IntPoint(0).x = 0.5;
4927  Nodes.IntPoint(0).y = 0.0;
4928  Nodes.IntPoint(0).z = 0.0;
4929 
4930  Nodes.IntPoint(1).x = 1.0;
4931  Nodes.IntPoint(1).y = 0.5;
4932  Nodes.IntPoint(1).z = 0.0;
4933 
4934  Nodes.IntPoint(2).x = 0.5;
4935  Nodes.IntPoint(2).y = 1.0;
4936  Nodes.IntPoint(2).z = 0.0;
4937 
4938  Nodes.IntPoint(3).x = 0.0;
4939  Nodes.IntPoint(3).y = 0.5;
4940  Nodes.IntPoint(3).z = 0.0;
4941 
4942  Nodes.IntPoint(4).x = 0.5;
4943  Nodes.IntPoint(4).y = 0.0;
4944  Nodes.IntPoint(4).z = 1.0;
4945 
4946  Nodes.IntPoint(5).x = 1.0;
4947  Nodes.IntPoint(5).y = 0.5;
4948  Nodes.IntPoint(5).z = 1.0;
4949 
4950  Nodes.IntPoint(6).x = 0.5;
4951  Nodes.IntPoint(6).y = 1.0;
4952  Nodes.IntPoint(6).z = 1.0;
4953 
4954  Nodes.IntPoint(7).x = 0.0;
4955  Nodes.IntPoint(7).y = 0.5;
4956  Nodes.IntPoint(7).z = 1.0;
4957 
4958  Nodes.IntPoint(8).x = 0.0;
4959  Nodes.IntPoint(8).y = 0.0;
4960  Nodes.IntPoint(8).z = 0.5;
4961 
4962  Nodes.IntPoint(9).x = 1.0;
4963  Nodes.IntPoint(9).y = 0.0;
4964  Nodes.IntPoint(9).z = 0.5;
4965 
4966  Nodes.IntPoint(10).x= 1.0;
4967  Nodes.IntPoint(10).y= 1.0;
4968  Nodes.IntPoint(10).z= 0.5;
4969 
4970  Nodes.IntPoint(11).x= 0.0;
4971  Nodes.IntPoint(11).y= 1.0;
4972  Nodes.IntPoint(11).z= 0.5;
4973 }
4974 
4976  DenseMatrix &shape) const
4977 {
4978  double x = ip.x, y = ip.y, z = ip.z;
4979 
4980  shape(0,0) = (1. - y) * (1. - z);
4981  shape(0,1) = 0.;
4982  shape(0,2) = 0.;
4983 
4984  shape(2,0) = y * (1. - z);
4985  shape(2,1) = 0.;
4986  shape(2,2) = 0.;
4987 
4988  shape(4,0) = z * (1. - y);
4989  shape(4,1) = 0.;
4990  shape(4,2) = 0.;
4991 
4992  shape(6,0) = y * z;
4993  shape(6,1) = 0.;
4994  shape(6,2) = 0.;
4995 
4996  shape(1,0) = 0.;
4997  shape(1,1) = x * (1. - z);
4998  shape(1,2) = 0.;
4999 
5000  shape(3,0) = 0.;
5001  shape(3,1) = (1. - x) * (1. - z);
5002  shape(3,2) = 0.;
5003 
5004  shape(5,0) = 0.;
5005  shape(5,1) = x * z;
5006  shape(5,2) = 0.;
5007 
5008  shape(7,0) = 0.;
5009  shape(7,1) = (1. - x) * z;
5010  shape(7,2) = 0.;
5011 
5012  shape(8,0) = 0.;
5013  shape(8,1) = 0.;
5014  shape(8,2) = (1. - x) * (1. - y);
5015 
5016  shape(9,0) = 0.;
5017  shape(9,1) = 0.;
5018  shape(9,2) = x * (1. - y);
5019 
5020  shape(10,0) = 0.;
5021  shape(10,1) = 0.;
5022  shape(10,2) = x * y;
5023 
5024  shape(11,0) = 0.;
5025  shape(11,1) = 0.;
5026  shape(11,2) = y * (1. - x);
5027 
5028 }
5029 
5031  DenseMatrix &curl_shape)
5032 const
5033 {
5034  double x = ip.x, y = ip.y, z = ip.z;
5035 
5036  curl_shape(0,0) = 0.;
5037  curl_shape(0,1) = y - 1.;
5038  curl_shape(0,2) = 1. - z;
5039 
5040  curl_shape(2,0) = 0.;
5041  curl_shape(2,1) = -y;
5042  curl_shape(2,2) = z - 1.;
5043 
5044  curl_shape(4,0) = 0;
5045  curl_shape(4,1) = 1. - y;
5046  curl_shape(4,2) = z;
5047 
5048  curl_shape(6,0) = 0.;
5049  curl_shape(6,1) = y;
5050  curl_shape(6,2) = -z;
5051 
5052  curl_shape(1,0) = x;
5053  curl_shape(1,1) = 0.;
5054  curl_shape(1,2) = 1. - z;
5055 
5056  curl_shape(3,0) = 1. - x;
5057  curl_shape(3,1) = 0.;
5058  curl_shape(3,2) = z - 1.;
5059 
5060  curl_shape(5,0) = -x;
5061  curl_shape(5,1) = 0.;
5062  curl_shape(5,2) = z;
5063 
5064  curl_shape(7,0) = x - 1.;
5065  curl_shape(7,1) = 0.;
5066  curl_shape(7,2) = -z;
5067 
5068  curl_shape(8,0) = x - 1.;
5069  curl_shape(8,1) = 1. - y;
5070  curl_shape(8,2) = 0.;
5071 
5072  curl_shape(9,0) = -x;
5073  curl_shape(9,1) = y - 1.;
5074  curl_shape(9,2) = 0;
5075 
5076  curl_shape(10,0) = x;
5077  curl_shape(10,1) = -y;
5078  curl_shape(10,2) = 0.;
5079 
5080  curl_shape(11,0) = 1. - x;
5081  curl_shape(11,1) = y;
5082  curl_shape(11,2) = 0.;
5083 }
5084 
5085 const double Nedelec1HexFiniteElement::tk[12][3] =
5086 {
5087  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5088  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
5089  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
5090 };
5091 
5094 {
5095  int k, j;
5096 #ifdef MFEM_THREAD_SAFE
5098 #endif
5099 
5100 #ifdef MFEM_DEBUG
5101  for (k = 0; k < 12; k++)
5102  {
5104  for (j = 0; j < 12; j++)
5105  {
5106  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5107  vshape(j,2)*tk[k][2] );
5108  if (j == k) { d -= 1.0; }
5109  if (fabs(d) > 1.0e-12)
5110  {
5111  cerr << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
5112  " k = " << k << ", j = " << j << ", d = " << d << endl;
5113  mfem_error();
5114  }
5115  }
5116  }
5117 #endif
5118 
5119  IntegrationPoint ip;
5120  ip.x = ip.y = ip.z = 0.0;
5121  Trans.SetIntPoint (&ip);
5122  // Trans must be linear (more to have embedding?)
5123  const DenseMatrix &J = Trans.Jacobian();
5124  double vk[3];
5125  Vector xk (vk, 3);
5126 
5127  for (k = 0; k < 12; k++)
5128  {
5129  Trans.Transform (Nodes.IntPoint (k), xk);
5130  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5131  CalcVShape (ip, vshape);
5132  // vk = J tk
5133  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5134  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5135  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5136  for (j = 0; j < 12; j++)
5137  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5138  vshape(j,2)*vk[2])) < 1.0e-12)
5139  {
5140  I(k,j) = 0.0;
5141  }
5142  }
5143 }
5144 
5147  Vector &dofs) const
5148 {
5149  double vk[3];
5150  Vector xk (vk, 3);
5151 
5152  for (int k = 0; k < 12; k++)
5153  {
5154  Trans.SetIntPoint (&Nodes.IntPoint (k));
5155  const DenseMatrix &J = Trans.Jacobian();
5156 
5157  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5158  // xk^t J tk
5159  dofs(k) =
5160  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5161  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5162  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5163  }
5164 }
5165 
5166 
5168  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
5169 {
5170  // not real nodes ...
5171  Nodes.IntPoint(0).x = 0.5;
5172  Nodes.IntPoint(0).y = 0.0;
5173  Nodes.IntPoint(0).z = 0.0;
5174 
5175  Nodes.IntPoint(1).x = 0.0;
5176  Nodes.IntPoint(1).y = 0.5;
5177  Nodes.IntPoint(1).z = 0.0;
5178 
5179  Nodes.IntPoint(2).x = 0.0;
5180  Nodes.IntPoint(2).y = 0.0;
5181  Nodes.IntPoint(2).z = 0.5;
5182 
5183  Nodes.IntPoint(3).x = 0.5;
5184  Nodes.IntPoint(3).y = 0.5;
5185  Nodes.IntPoint(3).z = 0.0;
5186 
5187  Nodes.IntPoint(4).x = 0.5;
5188  Nodes.IntPoint(4).y = 0.0;
5189  Nodes.IntPoint(4).z = 0.5;
5190 
5191  Nodes.IntPoint(5).x = 0.0;
5192  Nodes.IntPoint(5).y = 0.5;
5193  Nodes.IntPoint(5).z = 0.5;
5194 }
5195 
5197  DenseMatrix &shape) const
5198 {
5199  double x = ip.x, y = ip.y, z = ip.z;
5200 
5201  shape(0,0) = 1. - y - z;
5202  shape(0,1) = x;
5203  shape(0,2) = x;
5204 
5205  shape(1,0) = y;
5206  shape(1,1) = 1. - x - z;
5207  shape(1,2) = y;
5208 
5209  shape(2,0) = z;
5210  shape(2,1) = z;
5211  shape(2,2) = 1. - x - y;
5212 
5213  shape(3,0) = -y;
5214  shape(3,1) = x;
5215  shape(3,2) = 0.;
5216 
5217  shape(4,0) = -z;
5218  shape(4,1) = 0.;
5219  shape(4,2) = x;
5220 
5221  shape(5,0) = 0.;
5222  shape(5,1) = -z;
5223  shape(5,2) = y;
5224 }
5225 
5227  DenseMatrix &curl_shape)
5228 const
5229 {
5230  curl_shape(0,0) = 0.;
5231  curl_shape(0,1) = -2.;
5232  curl_shape(0,2) = 2.;
5233 
5234  curl_shape(1,0) = 2.;
5235  curl_shape(1,1) = 0.;
5236  curl_shape(1,2) = -2.;
5237 
5238  curl_shape(2,0) = -2.;
5239  curl_shape(2,1) = 2.;
5240  curl_shape(2,2) = 0.;
5241 
5242  curl_shape(3,0) = 0.;
5243  curl_shape(3,1) = 0.;
5244  curl_shape(3,2) = 2.;
5245 
5246  curl_shape(4,0) = 0.;
5247  curl_shape(4,1) = -2.;
5248  curl_shape(4,2) = 0.;
5249 
5250  curl_shape(5,0) = 2.;
5251  curl_shape(5,1) = 0.;
5252  curl_shape(5,2) = 0.;
5253 }
5254 
5255 const double Nedelec1TetFiniteElement::tk[6][3] =
5256 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
5257 
5260 {
5261  int k, j;
5262 #ifdef MFEM_THREAD_SAFE
5264 #endif
5265 
5266 #ifdef MFEM_DEBUG
5267  for (k = 0; k < 6; k++)
5268  {
5270  for (j = 0; j < 6; j++)
5271  {
5272  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5273  vshape(j,2)*tk[k][2] );
5274  if (j == k) { d -= 1.0; }
5275  if (fabs(d) > 1.0e-12)
5276  {
5277  cerr << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
5278  " k = " << k << ", j = " << j << ", d = " << d << endl;
5279  mfem_error();
5280  }
5281  }
5282  }
5283 #endif
5284 
5285  IntegrationPoint ip;
5286  ip.x = ip.y = ip.z = 0.0;
5287  Trans.SetIntPoint (&ip);
5288  // Trans must be linear
5289  const DenseMatrix &J = Trans.Jacobian();
5290  double vk[3];
5291  Vector xk (vk, 3);
5292 
5293  for (k = 0; k < 6; k++)
5294  {
5295  Trans.Transform (Nodes.IntPoint (k), xk);
5296  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5297  CalcVShape (ip, vshape);
5298  // vk = J tk
5299  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5300  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5301  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5302  for (j = 0; j < 6; j++)
5303  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5304  vshape(j,2)*vk[2])) < 1.0e-12)
5305  {
5306  I(k,j) = 0.0;
5307  }
5308  }
5309 }
5310 
5313  Vector &dofs) const
5314 {
5315  double vk[3];
5316  Vector xk (vk, 3);
5317 
5318  for (int k = 0; k < 6; k++)
5319  {
5320  Trans.SetIntPoint (&Nodes.IntPoint (k));
5321  const DenseMatrix &J = Trans.Jacobian();
5322 
5323  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5324  // xk^t J tk
5325  dofs(k) =
5326  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5327  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5328  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5329  }
5330 }
5331 
5333  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
5334 {
5335  // not real nodes ...
5336  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
5337  Nodes.IntPoint(0).x = 0.5;
5338  Nodes.IntPoint(0).y = 0.5;
5339  Nodes.IntPoint(0).z = 0.0;
5340 
5341  Nodes.IntPoint(1).x = 0.5;
5342  Nodes.IntPoint(1).y = 0.0;
5343  Nodes.IntPoint(1).z = 0.5;
5344 
5345  Nodes.IntPoint(2).x = 1.0;
5346  Nodes.IntPoint(2).y = 0.5;
5347  Nodes.IntPoint(2).z = 0.5;
5348 
5349  Nodes.IntPoint(3).x = 0.5;
5350  Nodes.IntPoint(3).y = 1.0;
5351  Nodes.IntPoint(3).z = 0.5;
5352 
5353  Nodes.IntPoint(4).x = 0.0;
5354  Nodes.IntPoint(4).y = 0.5;
5355  Nodes.IntPoint(4).z = 0.5;
5356 
5357  Nodes.IntPoint(5).x = 0.5;
5358  Nodes.IntPoint(5).y = 0.5;
5359  Nodes.IntPoint(5).z = 1.0;
5360 }
5361 
5363  DenseMatrix &shape) const
5364 {
5365  double x = ip.x, y = ip.y, z = ip.z;
5366  // z = 0
5367  shape(0,0) = 0.;
5368  shape(0,1) = 0.;
5369  shape(0,2) = z - 1.;
5370  // y = 0
5371  shape(1,0) = 0.;
5372  shape(1,1) = y - 1.;
5373  shape(1,2) = 0.;
5374  // x = 1
5375  shape(2,0) = x;
5376  shape(2,1) = 0.;
5377  shape(2,2) = 0.;
5378  // y = 1
5379  shape(3,0) = 0.;
5380  shape(3,1) = y;
5381  shape(3,2) = 0.;
5382  // x = 0
5383  shape(4,0) = x - 1.;
5384  shape(4,1) = 0.;
5385  shape(4,2) = 0.;
5386  // z = 1
5387  shape(5,0) = 0.;
5388  shape(5,1) = 0.;
5389  shape(5,2) = z;
5390 }
5391 
5393  Vector &divshape) const
5394 {
5395  divshape(0) = 1.;
5396  divshape(1) = 1.;
5397  divshape(2) = 1.;
5398  divshape(3) = 1.;
5399  divshape(4) = 1.;
5400  divshape(5) = 1.;
5401 }
5402 
5403 const double RT0HexFiniteElement::nk[6][3] =
5404 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
5405 
5408 {
5409  int k, j;
5410 #ifdef MFEM_THREAD_SAFE
5412  DenseMatrix Jinv(Dim);
5413 #endif
5414 
5415 #ifdef MFEM_DEBUG
5416  for (k = 0; k < 6; k++)
5417  {
5419  for (j = 0; j < 6; j++)
5420  {
5421  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5422  vshape(j,2)*nk[k][2] );
5423  if (j == k) { d -= 1.0; }
5424  if (fabs(d) > 1.0e-12)
5425  {
5426  cerr << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5427  " k = " << k << ", j = " << j << ", d = " << d << endl;
5428  mfem_error();
5429  }
5430  }
5431  }
5432 #endif
5433 
5434  IntegrationPoint ip;
5435  ip.x = ip.y = ip.z = 0.0;
5436  Trans.SetIntPoint (&ip);
5437  // Trans must be linear
5438  // set Jinv = |J| J^{-t} = adj(J)^t
5439  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5440  double vk[3];
5441  Vector xk (vk, 3);
5442 
5443  for (k = 0; k < 6; k++)
5444  {
5445  Trans.Transform (Nodes.IntPoint (k), xk);
5446  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5447  CalcVShape (ip, vshape);
5448  // vk = |J| J^{-t} nk
5449  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5450  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5451  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5452  for (j = 0; j < 6; j++)
5453  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5454  vshape(j,2)*vk[2])) < 1.0e-12)
5455  {
5456  I(k,j) = 0.0;
5457  }
5458  }
5459 }
5460 
5463  Vector &dofs) const
5464 {
5465  double vk[3];
5466  Vector xk (vk, 3);
5467 #ifdef MFEM_THREAD_SAFE
5468  DenseMatrix Jinv(Dim);
5469 #endif
5470 
5471  for (int k = 0; k < 6; k++)
5472  {
5473  Trans.SetIntPoint (&Nodes.IntPoint (k));
5474  // set Jinv = |J| J^{-t} = adj(J)^t
5475  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5476 
5477  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5478  // xk^t |J| J^{-t} nk
5479  dofs(k) =
5480  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5481  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5482  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5483  }
5484 }
5485 
5487  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
5488 {
5489  // z = 0
5490  Nodes.IntPoint(2).x = 1./3.;
5491  Nodes.IntPoint(2).y = 1./3.;
5492  Nodes.IntPoint(2).z = 0.0;
5493  Nodes.IntPoint(3).x = 2./3.;
5494  Nodes.IntPoint(3).y = 1./3.;
5495  Nodes.IntPoint(3).z = 0.0;
5496  Nodes.IntPoint(0).x = 1./3.;
5497  Nodes.IntPoint(0).y = 2./3.;
5498  Nodes.IntPoint(0).z = 0.0;
5499  Nodes.IntPoint(1).x = 2./3.;
5500  Nodes.IntPoint(1).y = 2./3.;
5501  Nodes.IntPoint(1).z = 0.0;
5502  // y = 0
5503  Nodes.IntPoint(4).x = 1./3.;
5504  Nodes.IntPoint(4).y = 0.0;
5505  Nodes.IntPoint(4).z = 1./3.;
5506  Nodes.IntPoint(5).x = 2./3.;
5507  Nodes.IntPoint(5).y = 0.0;
5508  Nodes.IntPoint(5).z = 1./3.;
5509  Nodes.IntPoint(6).x = 1./3.;
5510  Nodes.IntPoint(6).y = 0.0;
5511  Nodes.IntPoint(6).z = 2./3.;
5512  Nodes.IntPoint(7).x = 2./3.;
5513  Nodes.IntPoint(7).y = 0.0;
5514  Nodes.IntPoint(7).z = 2./3.;
5515  // x = 1
5516  Nodes.IntPoint(8).x = 1.0;
5517  Nodes.IntPoint(8).y = 1./3.;
5518  Nodes.IntPoint(8).z = 1./3.;
5519  Nodes.IntPoint(9).x = 1.0;
5520  Nodes.IntPoint(9).y = 2./3.;
5521  Nodes.IntPoint(9).z = 1./3.;
5522  Nodes.IntPoint(10).x = 1.0;
5523  Nodes.IntPoint(10).y = 1./3.;
5524  Nodes.IntPoint(10).z = 2./3.;
5525  Nodes.IntPoint(11).x = 1.0;
5526  Nodes.IntPoint(11).y = 2./3.;
5527  Nodes.IntPoint(11).z = 2./3.;
5528  // y = 1
5529  Nodes.IntPoint(13).x = 1./3.;
5530  Nodes.IntPoint(13).y = 1.0;
5531  Nodes.IntPoint(13).z = 1./3.;
5532  Nodes.IntPoint(12).x = 2./3.;
5533  Nodes.IntPoint(12).y = 1.0;
5534  Nodes.IntPoint(12).z = 1./3.;
5535  Nodes.IntPoint(15).x = 1./3.;
5536  Nodes.IntPoint(15).y = 1.0;
5537  Nodes.IntPoint(15).z = 2./3.;
5538  Nodes.IntPoint(14).x = 2./3.;
5539  Nodes.IntPoint(14).y = 1.0;
5540  Nodes.IntPoint(14).z = 2./3.;
5541  // x = 0
5542  Nodes.IntPoint(17).x = 0.0;
5543  Nodes.IntPoint(17).y = 1./3.;
5544  Nodes.IntPoint(17).z = 1./3.;
5545  Nodes.IntPoint(16).x = 0.0;
5546  Nodes.IntPoint(16).y = 2./3.;
5547  Nodes.IntPoint(16).z = 1./3.;
5548  Nodes.IntPoint(19).x = 0.0;
5549  Nodes.IntPoint(19).y = 1./3.;
5550  Nodes.IntPoint(19).z = 2./3.;
5551  Nodes.IntPoint(18).x = 0.0;
5552  Nodes.IntPoint(18).y = 2./3.;
5553  Nodes.IntPoint(18).z = 2./3.;
5554  // z = 1
5555  Nodes.IntPoint(20).x = 1./3.;
5556  Nodes.IntPoint(20).y = 1./3.;
5557  Nodes.IntPoint(20).z = 1.0;
5558  Nodes.IntPoint(21).x = 2./3.;
5559  Nodes.IntPoint(21).y = 1./3.;
5560  Nodes.IntPoint(21).z = 1.0;
5561  Nodes.IntPoint(22).x = 1./3.;
5562  Nodes.IntPoint(22).y = 2./3.;
5563  Nodes.IntPoint(22).z = 1.0;
5564  Nodes.IntPoint(23).x = 2./3.;
5565  Nodes.IntPoint(23).y = 2./3.;
5566  Nodes.IntPoint(23).z = 1.0;
5567  // x = 0.5 (interior)
5568  Nodes.IntPoint(24).x = 0.5;
5569  Nodes.IntPoint(24).y = 1./3.;
5570  Nodes.IntPoint(24).z = 1./3.;
5571  Nodes.IntPoint(25).x = 0.5;
5572  Nodes.IntPoint(25).y = 1./3.;
5573  Nodes.IntPoint(25).z = 2./3.;
5574  Nodes.IntPoint(26).x = 0.5;
5575  Nodes.IntPoint(26).y = 2./3.;
5576  Nodes.IntPoint(26).z = 1./3.;
5577  Nodes.IntPoint(27).x = 0.5;
5578  Nodes.IntPoint(27).y = 2./3.;
5579  Nodes.IntPoint(27).z = 2./3.;
5580  // y = 0.5 (interior)
5581  Nodes.IntPoint(28).x = 1./3.;
5582  Nodes.IntPoint(28).y = 0.5;
5583  Nodes.IntPoint(28).z = 1./3.;
5584  Nodes.IntPoint(29).x = 1./3.;
5585  Nodes.IntPoint(29).y = 0.5;
5586  Nodes.IntPoint(29).z = 2./3.;
5587  Nodes.IntPoint(30).x = 2./3.;
5588  Nodes.IntPoint(30).y = 0.5;
5589  Nodes.IntPoint(30).z = 1./3.;
5590  Nodes.IntPoint(31).x = 2./3.;
5591  Nodes.IntPoint(31).y = 0.5;
5592  Nodes.IntPoint(31).z = 2./3.;
5593  // z = 0.5 (interior)
5594  Nodes.IntPoint(32).x = 1./3.;
5595  Nodes.IntPoint(32).y = 1./3.;
5596  Nodes.IntPoint(32).z = 0.5;
5597  Nodes.IntPoint(33).x = 1./3.;
5598  Nodes.IntPoint(33).y = 2./3.;
5599  Nodes.IntPoint(33).z = 0.5;
5600  Nodes.IntPoint(34).x = 2./3.;
5601  Nodes.IntPoint(34).y = 1./3.;
5602  Nodes.IntPoint(34).z = 0.5;
5603  Nodes.IntPoint(35).x = 2./3.;
5604  Nodes.IntPoint(35).y = 2./3.;
5605  Nodes.IntPoint(35).z = 0.5;
5606 }
5607 
5609  DenseMatrix &shape) const
5610 {
5611  double x = ip.x, y = ip.y, z = ip.z;
5612  // z = 0
5613  shape(2,0) = 0.;
5614  shape(2,1) = 0.;
5615  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5616  shape(3,0) = 0.;
5617  shape(3,1) = 0.;
5618  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5619  shape(0,0) = 0.;
5620  shape(0,1) = 0.;
5621  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5622  shape(1,0) = 0.;
5623  shape(1,1) = 0.;
5624  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5625  // y = 0
5626  shape(4,0) = 0.;
5627  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5628  shape(4,2) = 0.;
5629  shape(5,0) = 0.;
5630  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5631  shape(5,2) = 0.;
5632  shape(6,0) = 0.;
5633  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5634  shape(6,2) = 0.;
5635  shape(7,0) = 0.;
5636  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5637  shape(7,2) = 0.;
5638  // x = 1
5639  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5640  shape(8,1) = 0.;
5641  shape(8,2) = 0.;
5642  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5643  shape(9,1) = 0.;
5644  shape(9,2) = 0.;
5645  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5646  shape(10,1) = 0.;
5647  shape(10,2) = 0.;
5648  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5649  shape(11,1) = 0.;
5650  shape(11,2) = 0.;
5651  // y = 1
5652  shape(13,0) = 0.;
5653  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5654  shape(13,2) = 0.;
5655  shape(12,0) = 0.;
5656  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5657  shape(12,2) = 0.;
5658  shape(15,0) = 0.;
5659  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5660  shape(15,2) = 0.;
5661  shape(14,0) = 0.;
5662  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5663  shape(14,2) = 0.;
5664  // x = 0
5665  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5666  shape(17,1) = 0.;
5667  shape(17,2) = 0.;
5668  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5669  shape(16,1) = 0.;
5670  shape(16,2) = 0.;
5671  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5672  shape(19,1) = 0.;
5673  shape(19,2) = 0.;
5674  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5675  shape(18,1) = 0.;
5676  shape(18,2) = 0.;
5677  // z = 1
5678  shape(20,0) = 0.;
5679  shape(20,1) = 0.;
5680  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5681  shape(21,0) = 0.;
5682  shape(21,1) = 0.;
5683  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5684  shape(22,0) = 0.;
5685  shape(22,1) = 0.;
5686  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5687  shape(23,0) = 0.;
5688  shape(23,1) = 0.;
5689  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5690  // x = 0.5 (interior)
5691  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5692  shape(24,1) = 0.;
5693  shape(24,2) = 0.;
5694  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5695  shape(25,1) = 0.;
5696  shape(25,2) = 0.;
5697  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5698  shape(26,1) = 0.;
5699  shape(26,2) = 0.;
5700  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5701  shape(27,1) = 0.;
5702  shape(27,2) = 0.;
5703  // y = 0.5 (interior)
5704  shape(28,0) = 0.;
5705  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5706  shape(28,2) = 0.;
5707  shape(29,0) = 0.;
5708  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5709  shape(29,2) = 0.;
5710  shape(30,0) = 0.;
5711  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5712  shape(30,2) = 0.;
5713  shape(31,0) = 0.;
5714  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5715  shape(31,2) = 0.;
5716  // z = 0.5 (interior)
5717  shape(32,0) = 0.;
5718  shape(32,1) = 0.;
5719  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5720  shape(33,0) = 0.;
5721  shape(33,1) = 0.;
5722  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5723  shape(34,0) = 0.;
5724  shape(34,1) = 0.;
5725  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5726  shape(35,0) = 0.;
5727  shape(35,1) = 0.;
5728  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5729 }
5730 
5732  Vector &divshape) const
5733 {
5734  double x = ip.x, y = ip.y, z = ip.z;
5735  // z = 0
5736  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5737  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5738  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5739  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5740  // y = 0
5741  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5742  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5743  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5744  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5745  // x = 1
5746  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5747  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5748  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5749  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5750  // y = 1
5751  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5752  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5753  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5754  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5755  // x = 0
5756  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5757  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5758  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5759  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5760  // z = 1
5761  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5762  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5763  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5764  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5765  // x = 0.5 (interior)
5766  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5767  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5768  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5769  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5770  // y = 0.5 (interior)
5771  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5772  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5773  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5774  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5775  // z = 0.5 (interior)
5776  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5777  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5778  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5779  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5780 }
5781 
5782 const double RT1HexFiniteElement::nk[36][3] =
5783 {
5784  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
5785  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
5786  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5787  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5788  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
5789  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
5790  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5791  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5792  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
5793 };
5794 
5797 {
5798  int k, j;
5799 #ifdef MFEM_THREAD_SAFE
5801  DenseMatrix Jinv(Dim);
5802 #endif
5803 
5804 #ifdef MFEM_DEBUG
5805  for (k = 0; k < 36; k++)
5806  {
5808  for (j = 0; j < 36; j++)
5809  {
5810  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5811  vshape(j,2)*nk[k][2] );
5812  if (j == k) { d -= 1.0; }
5813  if (fabs(d) > 1.0e-12)
5814  {
5815  cerr << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5816  " k = " << k << ", j = " << j << ", d = " << d << endl;
5817  mfem_error();
5818  }
5819  }
5820  }
5821 #endif
5822 
5823  IntegrationPoint ip;
5824  ip.x = ip.y = ip.z = 0.0;
5825  Trans.SetIntPoint (&ip);
5826  // Trans must be linear
5827  // set Jinv = |J| J^{-t} = adj(J)^t
5828  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5829  double vk[3];
5830  Vector xk (vk, 3);
5831 
5832  for (k = 0; k < 36; k++)
5833  {
5834  Trans.Transform (Nodes.IntPoint (k), xk);
5835  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5836  CalcVShape (ip, vshape);
5837  // vk = |J| J^{-t} nk
5838  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5839  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5840  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5841  for (j = 0; j < 36; j++)
5842  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5843  vshape(j,2)*vk[2])) < 1.0e-12)
5844  {
5845  I(k,j) = 0.0;
5846  }
5847  }
5848 }
5849 
5852  Vector &dofs) const
5853 {
5854  double vk[3];
5855  Vector xk (vk, 3);
5856 #ifdef MFEM_THREAD_SAFE
5857  DenseMatrix Jinv(Dim);
5858 #endif
5859 
5860  for (int k = 0; k < 36; k++)
5861  {
5862  Trans.SetIntPoint (&Nodes.IntPoint (k));
5863  // set Jinv = |J| J^{-t} = adj(J)^t
5864  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5865 
5866  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5867  // xk^t |J| J^{-t} nk
5868  dofs(k) =
5869  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5870  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5871  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5872  }
5873 }
5874 
5876  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
5877 {
5878  // not real nodes ...
5879  Nodes.IntPoint(0).x = 0.33333333333333333333;
5880  Nodes.IntPoint(0).y = 0.33333333333333333333;
5881  Nodes.IntPoint(0).z = 0.33333333333333333333;
5882 
5883  Nodes.IntPoint(1).x = 0.0;
5884  Nodes.IntPoint(1).y = 0.33333333333333333333;
5885  Nodes.IntPoint(1).z = 0.33333333333333333333;
5886 
5887  Nodes.IntPoint(2).x = 0.33333333333333333333;
5888  Nodes.IntPoint(2).y = 0.0;
5889  Nodes.IntPoint(2).z = 0.33333333333333333333;
5890 
5891  Nodes.IntPoint(3).x = 0.33333333333333333333;
5892  Nodes.IntPoint(3).y = 0.33333333333333333333;
5893  Nodes.IntPoint(3).z = 0.0;
5894 }
5895 
5897  DenseMatrix &shape) const
5898 {
5899  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
5900 
5901  shape(0,0) = x2;
5902  shape(0,1) = y2;
5903  shape(0,2) = z2;
5904 
5905  shape(1,0) = x2 - 2.0;
5906  shape(1,1) = y2;
5907  shape(1,2) = z2;
5908 
5909  shape(2,0) = x2;
5910  shape(2,1) = y2 - 2.0;
5911  shape(2,2) = z2;
5912 
5913  shape(3,0) = x2;
5914  shape(3,1) = y2;
5915  shape(3,2) = z2 - 2.0;
5916 }
5917 
5919  Vector &divshape) const
5920 {
5921  divshape(0) = 6.0;
5922  divshape(1) = 6.0;
5923  divshape(2) = 6.0;
5924  divshape(3) = 6.0;
5925 }
5926 
5927 const double RT0TetFiniteElement::nk[4][3] =
5928 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
5929 
5932 {
5933  int k, j;
5934 #ifdef MFEM_THREAD_SAFE
5936  DenseMatrix Jinv(Dim);
5937 #endif
5938 
5939 #ifdef MFEM_DEBUG
5940  for (k = 0; k < 4; k++)
5941  {
5943  for (j = 0; j < 4; j++)
5944  {
5945  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5946  vshape(j,2)*nk[k][2] );
5947  if (j == k) { d -= 1.0; }
5948  if (fabs(d) > 1.0e-12)
5949  {
5950  cerr << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
5951  " k = " << k << ", j = " << j << ", d = " << d << endl;
5952  mfem_error();
5953  }
5954  }
5955  }
5956 #endif
5957 
5958  IntegrationPoint ip;
5959  ip.x = ip.y = ip.z = 0.0;
5960  Trans.SetIntPoint (&ip);
5961  // Trans must be linear
5962  // set Jinv = |J| J^{-t} = adj(J)^t
5963  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5964  double vk[3];
5965  Vector xk (vk, 3);
5966 
5967  for (k = 0; k < 4; k++)
5968  {
5969  Trans.Transform (Nodes.IntPoint (k), xk);
5970  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5971  CalcVShape (ip, vshape);
5972  // vk = |J| J^{-t} nk
5973  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5974  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5975  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5976  for (j = 0; j < 4; j++)
5977  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5978  vshape(j,2)*vk[2])) < 1.0e-12)
5979  {
5980  I(k,j) = 0.0;
5981  }
5982  }
5983 }
5984 
5987  Vector &dofs) const
5988 {
5989  double vk[3];
5990  Vector xk (vk, 3);
5991 #ifdef MFEM_THREAD_SAFE
5992  DenseMatrix Jinv(Dim);
5993 #endif
5994 
5995  for (int k = 0; k < 4; k++)
5996  {
5997  Trans.SetIntPoint (&Nodes.IntPoint (k));
5998  // set Jinv = |J| J^{-t} = adj(J)^t
5999  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
6000 
6001  vc.Eval (xk, Trans, Nodes.IntPoint (k));
6002  // xk^t |J| J^{-t} nk
6003  dofs(k) =
6004  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
6005  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
6006  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
6007  }
6008 }
6009 
6011  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
6012 {
6013  Nodes.IntPoint(0).x = 0.5;
6014  Nodes.IntPoint(0).y = 0.5;
6015  Nodes.IntPoint(0).z = 0.0;
6016 
6017  Nodes.IntPoint(1).x = 0.5;
6018  Nodes.IntPoint(1).y = 0.0;
6019  Nodes.IntPoint(1).z = 0.5;
6020 
6021  Nodes.IntPoint(2).x = 1.0;
6022  Nodes.IntPoint(2).y = 0.5;
6023  Nodes.IntPoint(2).z = 0.5;
6024 
6025  Nodes.IntPoint(3).x = 0.5;
6026  Nodes.IntPoint(3).y = 1.0;
6027  Nodes.IntPoint(3).z = 0.5;
6028 
6029  Nodes.IntPoint(4).x = 0.0;
6030  Nodes.IntPoint(4).y = 0.5;
6031  Nodes.IntPoint(4).z = 0.5;
6032 
6033  Nodes.IntPoint(5).x = 0.5;
6034  Nodes.IntPoint(5).y = 0.5;
6035  Nodes.IntPoint(5).z = 1.0;
6036 }
6037 
6039  Vector &shape) const
6040 {
6041  double x = 2. * ip.x - 1.;
6042  double y = 2. * ip.y - 1.;
6043  double z = 2. * ip.z - 1.;
6044  double f5 = x * x - y * y;
6045  double f6 = y * y - z * z;
6046 
6047  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
6048  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
6049  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
6050  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
6051  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
6052  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
6053 }
6054 
6056  DenseMatrix &dshape) const
6057 {
6058  const double a = 2./3.;
6059 
6060  double xt = a * (1. - 2. * ip.x);
6061  double yt = a * (1. - 2. * ip.y);
6062  double zt = a * (1. - 2. * ip.z);
6063 
6064  dshape(0,0) = xt;
6065  dshape(0,1) = yt;
6066  dshape(0,2) = -1. - 2. * zt;
6067 
6068  dshape(1,0) = xt;
6069  dshape(1,1) = -1. - 2. * yt;
6070  dshape(1,2) = zt;
6071 
6072  dshape(2,0) = 1. - 2. * xt;
6073  dshape(2,1) = yt;
6074  dshape(2,2) = zt;
6075 
6076  dshape(3,0) = xt;
6077  dshape(3,1) = 1. - 2. * yt;
6078  dshape(3,2) = zt;
6079 
6080  dshape(4,0) = -1. - 2. * xt;
6081  dshape(4,1) = yt;
6082  dshape(4,2) = zt;
6083 
6084  dshape(5,0) = xt;
6085  dshape(5,1) = yt;
6086  dshape(5,2) = 1. - 2. * zt;
6087 }
6088 
6089 
6090 Poly_1D::Basis::Basis(const int p, const double *nodes, int _mode)
6091  : x(p + 1), w(p + 1)
6092 {
6093  mode = _mode;
6094  if (mode == 0)
6095  {
6096  DenseMatrix A(p + 1);
6097  for (int i = 0; i <= p; i++)
6098  {
6099  CalcBasis(p, nodes[i], x);
6100  for (int j = 0; j <= p; j++)
6101  {
6102  A(j, i) = x(j);
6103  }
6104  }
6105 
6106  Ai.Factor(A);
6107  // cout << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
6108  }
6109  else
6110  {
6111  x = nodes;
6112  w = 1.0;
6113  for (int i = 0; i <= p; i++)
6114  {
6115  for (int j = 0; j < i; j++)
6116  {
6117  double xij = x(i) - x(j);
6118  w(i) *= xij;
6119  w(j) *= -xij;
6120  }
6121  }
6122  for (int i = 0; i <= p; i++)
6123  {
6124  w(i) = 1.0/w(i);
6125  }
6126 
6127 #ifdef MFEM_DEBUG
6128  // Make sure the nodes are increasing
6129  for (int i = 0; i < p; i++)
6130  {
6131  if (x(i) >= x(i+1))
6132  {
6133  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
6134  }
6135  }
6136 #endif
6137  }
6138 }
6139 
6140 void Poly_1D::Basis::Eval(const double y, Vector &u) const
6141 {
6142  if (mode == 0)
6143  {
6144  CalcBasis(Ai.Width() - 1, y, x);
6145  Ai.Mult(x, u);
6146  }
6147  else
6148  {
6149  int i, k, p = x.Size() - 1;
6150  double l, lk;
6151 
6152  if (p == 0)
6153  {
6154  u(0) = 1.0;
6155  return;
6156  }
6157 
6158  lk = 1.0;
6159  for (k = 0; k < p; k++)
6160  {
6161  if (y >= (x(k) + x(k+1))/2)
6162  {
6163  lk *= y - x(k);
6164  }
6165  else
6166  {
6167  for (i = k+1; i <= p; i++)
6168  {
6169  lk *= y - x(i);
6170  }
6171  break;
6172  }
6173  }
6174  l = lk * (y - x(k));
6175 
6176  for (i = 0; i < k; i++)
6177  {
6178  u(i) = l * w(i) / (y - x(i));
6179  }
6180  u(k) = lk * w(k);
6181  for (i++; i <= p; i++)
6182  {
6183  u(i) = l * w(i) / (y - x(i));
6184  }
6185  }
6186 }
6187 
6188 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
6189 {
6190  if (mode == 0)
6191  {
6192  CalcBasis(Ai.Width() - 1, y, x, w);
6193  Ai.Mult(x, u);
6194  Ai.Mult(w, d);
6195  }
6196  else
6197  {
6198  int i, k, p = x.Size() - 1;
6199  double l, lp, lk, sk, si;
6200 
6201  if (p == 0)
6202  {
6203  u(0) = 1.0;
6204  d(0) = 0.0;
6205  return;
6206  }
6207 
6208  lk = 1.0;
6209  for (k = 0; k < p; k++)
6210  {
6211  if (y >= (x(k) + x(k+1))/2)
6212  {
6213  lk *= y - x(k);
6214  }
6215  else
6216  {
6217  for (i = k+1; i <= p; i++)
6218  {
6219  lk *= y - x(i);
6220  }
6221  break;
6222  }
6223  }
6224  l = lk * (y - x(k));
6225 
6226  sk = 0.0;
6227  for (i = 0; i < k; i++)
6228  {
6229  si = 1.0/(y - x(i));
6230  sk += si;
6231  u(i) = l * si * w(i);
6232  }
6233  u(k) = lk * w(k);
6234  for (i++; i <= p; i++)
6235  {
6236  si = 1.0/(y - x(i));
6237  sk += si;
6238  u(i) = l * si * w(i);
6239  }
6240  lp = l * sk + lk;
6241 
6242  for (i = 0; i < k; i++)
6243  {
6244  d(i) = (lp * w(i) - u(i))/(y - x(i));
6245  }
6246  d(k) = sk * u(k);
6247  for (i++; i <= p; i++)
6248  {
6249  d(i) = (lp * w(i) - u(i))/(y - x(i));
6250  }
6251  }
6252 }
6253 
6254 const int *Poly_1D::Binom(const int p)
6255 {
6256  if (binom.NumCols() <= p)
6257  {
6258  binom.SetSize(p + 1, p + 1);
6259  for (int i = 0; i <= p; i++)
6260  {
6261  binom(i,0) = binom(i,i) = 1;
6262  for (int j = 1; j < i; j++)
6263  {
6264  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
6265  }
6266  }
6267  }
6268  return binom[p];
6269 }
6270 
6271 void Poly_1D::ChebyshevPoints(const int p, double *x)
6272 {
6273  for (int i = 0; i <= p; i++)
6274  {
6275  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
6276  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
6277  x[i] = s*s;
6278  }
6279 }
6280 
6281 void Poly_1D::CalcMono(const int p, const double x, double *u)
6282 {
6283  double xn;
6284  u[0] = xn = 1.;
6285  for (int n = 1; n <= p; n++)
6286  {
6287  u[n] = (xn *= x);
6288  }
6289 }
6290 
6291 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
6292 {
6293  double xn;
6294  u[0] = xn = 1.;
6295  d[0] = 0.;
6296  for (int n = 1; n <= p; n++)
6297  {
6298  d[n] = n * xn;
6299  u[n] = (xn *= x);
6300  }
6301 }
6302 
6303 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6304  double *u)
6305 {
6306  if (p == 0)
6307  {
6308  u[0] = 1.;
6309  }
6310  else
6311  {
6312  int i;
6313  const int *b = Binom(p);
6314  double z = x;
6315 
6316  for (i = 1; i < p; i++)
6317  {
6318  u[i] = b[i]*z;
6319  z *= x;
6320  }
6321  u[p] = z;
6322  z = y;
6323  for (i--; i > 0; i--)
6324  {
6325  u[i] *= z;
6326  z *= y;
6327  }
6328  u[0] = z;
6329  }
6330 }
6331 
6332 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6333  double *u, double *d)
6334 {
6335  if (p == 0)
6336  {
6337  u[0] = 1.;
6338  d[0] = 0.;
6339  }
6340  else
6341  {
6342  int i;
6343  const int *b = Binom(p);
6344  const double xpy = x + y, ptx = p*x;
6345  double z = 1.;
6346 
6347  for (i = 1; i < p; i++)
6348  {
6349  d[i] = b[i]*z*(i*xpy - ptx);
6350  z *= x;
6351  u[i] = b[i]*z;
6352  }
6353  d[p] = p*z;
6354  u[p] = z*x;
6355  z = 1.;
6356  for (i--; i > 0; i--)
6357  {
6358  d[i] *= z;
6359  z *= y;
6360  u[i] *= z;
6361  }
6362  d[0] = -p*z;
6363  u[0] = z*y;
6364  }
6365 }
6366 
6367 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
6368  double *d)
6369 {
6370  if (p == 0)
6371  {
6372  d[0] = 0.;
6373  }
6374  else
6375  {
6376  int i;
6377  const int *b = Binom(p);
6378  const double xpy = x + y, ptx = p*x;
6379  double z = 1.;
6380 
6381  for (i = 1; i < p; i++)
6382  {
6383  d[i] = b[i]*z*(i*xpy - ptx);
6384  z *= x;
6385  }
6386  d[p] = p*z;
6387  z = 1.;
6388  for (i--; i > 0; i--)
6389  {
6390  d[i] *= z;
6391  z *= y;
6392  }
6393  d[0] = -p*z;
6394  }
6395 }
6396 
6397 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
6398 {
6399  // use the recursive definition for [-1,1]:
6400  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6401  double z;
6402  u[0] = 1.;
6403  if (p == 0) { return; }
6404  u[1] = z = 2.*x - 1.;
6405  for (int n = 1; n < p; n++)
6406  {
6407  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6408  }
6409 }
6410 
6411 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
6412 {
6413  // use the recursive definition for [-1,1]:
6414  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6415  // for the derivative use, z in [-1,1]:
6416  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
6417  double z;
6418  u[0] = 1.;
6419  d[0] = 0.;
6420  if (p == 0) { return; }
6421  u[1] = z = 2.*x - 1.;
6422  d[1] = 2.;
6423  for (int n = 1; n < p; n++)
6424  {
6425  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6426  d[n+1] = (4*n + 2)*u[n] + d[n-1];
6427  }
6428 }
6429 
6430 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
6431 {
6432  // recursive definition, z in [-1,1]
6433  // T_0(z) = 1, T_1(z) = z
6434  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6435  double z;
6436  u[0] = 1.;
6437  if (p == 0) { return; }
6438  u[1] = z = 2.*x - 1.;
6439  for (int n = 1; n < p; n++)
6440  {
6441  u[n+1] = 2*z*u[n] - u[n-1];
6442  }
6443 }
6444 
6445 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
6446 {
6447  // recursive definition, z in [-1,1]
6448  // T_0(z) = 1, T_1(z) = z
6449  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6450  // T'_n(z) = n*U_{n-1}(z)
6451  // U_0(z) = 1 U_1(z) = 2*z
6452  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
6453  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
6454  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
6455  double z;
6456  u[0] = 1.;
6457  d[0] = 0.;
6458  if (p == 0) { return; }
6459  u[1] = z = 2.*x - 1.;
6460  d[1] = 2.;
6461  for (int n = 1; n < p; n++)
6462  {
6463  u[n+1] = 2*z*u[n] - u[n-1];
6464  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
6465  }
6466 }
6467 
6468 const double *Poly_1D::GetPoints(const int p, const int type)
6469 {
6470  MFEM_ASSERT(type != Quadrature1D::Invalid, "invalid point type");
6471 
6472  if (points_container.find(type) == points_container.end())
6473  {
6474  points_container[type] = new Array<double*>;
6475  }
6476  Array<double*> &pts = *points_container[type];
6477  if (pts.Size() <= p)
6478  {
6479  pts.SetSize(p + 1, NULL);
6480  }
6481  if (pts[p] == NULL)
6482  {
6483  pts[p] = new double[p + 1];
6484  quad_func.GivePolyPoints(p+1, pts[p], type);
6485  }
6486  return pts[p];
6487 }
6488 
6489 Poly_1D::Basis &Poly_1D::GetBasis(const int p, const int type)
6490 {
6491  MFEM_ASSERT(type != Quadrature1D::Invalid, "invalid point type");
6492 
6493  if ( bases_container.find(type) == bases_container.end() )
6494  {
6495  // we haven't been asked for basis or points of this type yet
6496  bases_container[type] = new Array<Basis*>;
6497  }
6498  Array<Basis*> &bases = *bases_container[type];
6499  if (bases.Size() <= p)
6500  {
6501  bases.SetSize(p + 1, NULL);
6502  }
6503  if (bases[p] == NULL)
6504  {
6505  bases[p] = new Basis(p, GetPoints(p, type));
6506  }
6507  return *bases[p];
6508 }
6509 
6511 {
6512  for (std::map<int, Array<double*>*>::iterator it = points_container.begin();
6513  it != points_container.end() ; ++it)
6514  {
6515  Array<double*>& pts = *it->second;
6516  for ( int i = 0 ; i < pts.Size() ; ++i )
6517  {
6518  delete [] pts[i];
6519  }
6520  delete it->second;
6521  }
6522 
6523  for (std::map<int, Array<Basis*>*>::iterator it = bases_container.begin();
6524  it != bases_container.end() ; ++it )
6525  {
6526  Array<Basis*>& bases = *it->second;
6527  for ( int i = 0 ; i < bases.Size() ; ++i )
6528  {
6529  delete bases[i];
6530  }
6531  delete it->second;
6532  }
6533 }
6534 
6536 Array2D<int> Poly_1D::binom;
6537 
6538 
6539 H1_SegmentElement::H1_SegmentElement(const int p, const int type)
6540  : NodalFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
6541  pt_type(VerifyClosed(type)),
6542  basis1d(poly1d.ClosedBasis(p, pt_type)),
6543  dof_map(Dof)
6544 {
6545  const double *cp = poly1d.ClosedPoints(p, pt_type);
6546 
6547 #ifndef MFEM_THREAD_SAFE
6548  shape_x.SetSize(p+1);
6549  dshape_x.SetSize(p+1);
6550 #endif
6551 
6552  Nodes.IntPoint(0).x = cp[0];
6553  Nodes.IntPoint(1).x = cp[p];
6554  dof_map[0] = 0;
6555  dof_map[p] = 1;
6556  for (int i = 1; i < p; i++)
6557  {
6558  Nodes.IntPoint(i+1).x = cp[i];
6559  dof_map[i] = i+1;
6560  }
6561 }
6562 
6564  Vector &shape) const
6565 {
6566  const int p = Order;
6567 
6568 #ifdef MFEM_THREAD_SAFE
6569  Vector shape_x(p+1);
6570 #endif
6571 
6572  basis1d.Eval(ip.x, shape_x);
6573 
6574  shape(0) = shape_x(0);
6575  shape(1) = shape_x(p);
6576  for (int i = 1; i < p; i++)
6577  {
6578  shape(i+1) = shape_x(i);
6579  }
6580 }
6581 
6583  DenseMatrix &dshape) const
6584 {
6585  const int p = Order;
6586 
6587 #ifdef MFEM_THREAD_SAFE
6588  Vector shape_x(p+1), dshape_x(p+1);
6589 #endif
6590 
6591  basis1d.Eval(ip.x, shape_x, dshape_x);
6592 
6593  dshape(0,0) = dshape_x(0);
6594  dshape(1,0) = dshape_x(p);
6595  for (int i = 1; i < p; i++)
6596  {
6597  dshape(i+1,0) = dshape_x(i);
6598  }
6599 }
6600 
6601 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
6602 {
6603  const int p = Order;
6604  const double *cp = poly1d.ClosedPoints(p, pt_type);
6605 
6606  switch (vertex)
6607  {
6608  case 0:
6609  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
6610  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
6611  for (int i = 1; i < p; i++)
6612  {
6613  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6614  }
6615  break;
6616 
6617  case 1:
6618  dofs(0) = poly1d.CalcDelta(p, cp[0]);
6619  dofs(1) = poly1d.CalcDelta(p, cp[p]);
6620  for (int i = 1; i < p; i++)
6621  {
6622  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
6623  }
6624  break;
6625  }
6626 }
6627 
6628 
6630  : NodalFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
6631  FunctionSpace::Qk),
6632  pt_type(VerifyClosed(type)),
6633  basis1d(poly1d.ClosedBasis(p, pt_type)),
6634  dof_map((p + 1)*(p + 1))
6635 {
6636  const double *cp = poly1d.ClosedPoints(p, pt_type);
6637 
6638  const int p1 = p + 1;
6639 
6640 #ifndef MFEM_THREAD_SAFE
6641  shape_x.SetSize(p1);
6642  shape_y.SetSize(p1);
6643  dshape_x.SetSize(p1);
6644  dshape_y.SetSize(p1);
6645 #endif
6646 
6647  // vertices
6648  dof_map[0 + 0*p1] = 0;
6649  dof_map[p + 0*p1] = 1;
6650  dof_map[p + p*p1] = 2;
6651  dof_map[0 + p*p1] = 3;
6652 
6653  // edges
6654  int o = 4;
6655  for (int i = 1; i < p; i++)
6656  {
6657  dof_map[i + 0*p1] = o++;
6658  }
6659  for (int i = 1; i < p; i++)
6660  {
6661  dof_map[p + i*p1] = o++;
6662  }
6663  for (int i = 1; i < p; i++)
6664  {
6665  dof_map[(p-i) + p*p1] = o++;
6666  }
6667  for (int i = 1; i < p; i++)
6668  {
6669  dof_map[0 + (p-i)*p1] = o++;
6670  }
6671 
6672  // interior
6673  for (int j = 1; j < p; j++)
6674  for (int i = 1; i < p; i++)
6675  {
6676  dof_map[i + j*p1] = o++;
6677  }
6678 
6679  o = 0;
6680  for (int j = 0; j <= p; j++)
6681  {
6682  for (int i = 0; i <= p; i++)
6683  {
6684  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
6685  }
6686  }
6687 }
6688 
6690  Vector &shape) const
6691 {
6692  const int p = Order;
6693 
6694 #ifdef MFEM_THREAD_SAFE
6695  Vector shape_x(p+1), shape_y(p+1);
6696 #endif
6697 
6698  basis1d.Eval(ip.x, shape_x);
6699  basis1d.Eval(ip.y, shape_y);
6700 
6701  for (int o = 0, j = 0; j <= p; j++)
6702  for (int i = 0; i <= p; i++)
6703  {
6704  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
6705  }
6706 }
6707 
6709  DenseMatrix &dshape) const
6710 {
6711  const int p = Order;
6712 
6713 #ifdef MFEM_THREAD_SAFE
6714  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
6715 #endif
6716 
6717  basis1d.Eval(ip.x, shape_x, dshape_x);
6718  basis1d.Eval(ip.y, shape_y, dshape_y);
6719 
6720  for (int o = 0, j = 0; j <= p; j++)
6721  {
6722  for (int i = 0; i <= p; i++)
6723  {
6724  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
6725  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
6726  }
6727  }
6728 }
6729 
6730 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
6731 {
6732  const int p = Order;
6733  const double *cp = poly1d.ClosedPoints(p, pt_type);
6734 
6735 #ifdef MFEM_THREAD_SAFE
6736  Vector shape_x(p+1), shape_y(p+1);
6737 #endif
6738 
6739  for (int i = 0; i <= p; i++)
6740  {
6741  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6742  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
6743  }
6744 
6745  switch (vertex)
6746  {
6747  case 0:
6748  for (int o = 0, j = 0; j <= p; j++)
6749  for (int i = 0; i <= p; i++)
6750  {
6751  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
6752  }
6753  break;
6754  case 1:
6755  for (int o = 0, j = 0; j <= p; j++)
6756  for (int i = 0; i <= p; i++)
6757  {
6758  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
6759  }
6760  break;
6761  case 2:
6762  for (int o = 0, j = 0; j <= p; j++)
6763  for (int i = 0; i <= p; i++)
6764  {
6765  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
6766  }
6767  break;
6768  case 3:
6769  for (int o = 0, j = 0; j <= p; j++)
6770  for (int i = 0; i <= p; i++)
6771  {
6772  dofs(dof_map[o++]) = shape_x(i)*shape_y(j);
6773  }
6774  break;
6775  }
6776 }
6777 
6778 
6780  : NodalFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
6781  FunctionSpace::Qk),
6782  pt_type(VerifyClosed(type)),
6783  basis1d(poly1d.ClosedBasis(p, pt_type)),
6784  dof_map((p + 1)*(p + 1)*(p + 1))
6785 {
6786  const double *cp = poly1d.ClosedPoints(p, pt_type);
6787 
6788  const int p1 = p + 1;
6789 
6790 #ifndef MFEM_THREAD_SAFE
6791  shape_x.SetSize(p1);
6792  shape_y.SetSize(p1);
6793  shape_z.SetSize(p1);
6794  dshape_x.SetSize(p1);
6795  dshape_y.SetSize(p1);
6796  dshape_z.SetSize(p1);
6797 #endif
6798 
6799  // vertices
6800  dof_map[0 + (0 + 0*p1)*p1] = 0;
6801  dof_map[p + (0 + 0*p1)*p1] = 1;
6802  dof_map[p + (p + 0*p1)*p1] = 2;
6803  dof_map[0 + (p + 0*p1)*p1] = 3;
6804  dof_map[0 + (0 + p*p1)*p1] = 4;
6805  dof_map[p + (0 + p*p1)*p1] = 5;
6806  dof_map[p + (p + p*p1)*p1] = 6;
6807  dof_map[0 + (p + p*p1)*p1] = 7;
6808 
6809  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
6810  int o = 8;
6811  for (int i = 1; i < p; i++)
6812  {
6813  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
6814  }
6815  for (int i = 1; i < p; i++)
6816  {
6817  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
6818  }
6819  for (int i = 1; i < p; i++)
6820  {
6821  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
6822  }
6823  for (int i = 1; i < p; i++)
6824  {
6825  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
6826  }
6827  for (int i = 1; i < p; i++)
6828  {
6829  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
6830  }
6831  for (int i = 1; i < p; i++)
6832  {
6833  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
6834  }
6835  for (int i = 1; i < p; i++)
6836  {
6837  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
6838  }
6839  for (int i = 1; i < p; i++)
6840  {
6841  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
6842  }
6843  for (int i = 1; i < p; i++)
6844  {
6845  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
6846  }
6847  for (int i = 1; i < p; i++)
6848  {
6849  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
6850  }
6851  for (int i = 1; i < p; i++)
6852  {
6853  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
6854  }
6855  for (int i = 1; i < p; i++)
6856  {
6857  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
6858  }
6859 
6860  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
6861  for (int j = 1; j < p; j++)
6862  for (int i = 1; i < p; i++)
6863  {
6864  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
6865  }
6866  for (int j = 1; j < p; j++)
6867  for (int i = 1; i < p; i++)
6868  {
6869  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
6870  }
6871  for (int j = 1; j < p; j++)
6872  for (int i = 1; i < p; i++)
6873  {
6874  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
6875  }
6876  for (int j = 1; j < p; j++)
6877  for (int i = 1; i < p; i++)
6878  {
6879  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
6880  }
6881  for (int j = 1; j < p; j++)
6882  for (int i = 1; i < p; i++)
6883  {
6884  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
6885  }
6886  for (int j = 1; j < p; j++)
6887  for (int i = 1; i < p; i++)
6888  {
6889  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
6890  }
6891 
6892  // interior
6893  for (int k = 1; k < p; k++)
6894  for (int j = 1; j < p; j++)
6895  for (int i = 1; i < p; i++)
6896  {
6897  dof_map[i + (j + k*p1)*p1] = o++;
6898  }
6899 
6900  o = 0;
6901  for (int k = 0; k <= p; k++)
6902  for (int j = 0; j <= p; j++)
6903  for (int i = 0; i <= p; i++)
6904  {
6905  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
6906  }
6907 }
6908 
6910  Vector &shape) const
6911 {
6912  const int p = Order;
6913 
6914 #ifdef MFEM_THREAD_SAFE
6915  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
6916 #endif
6917 
6918  basis1d.Eval(ip.x, shape_x);
6919  basis1d.Eval(ip.y, shape_y);
6920  basis1d.Eval(ip.z, shape_z);
6921 
6922  for (int o = 0, k = 0; k <= p; k++)
6923  for (int j = 0; j <= p; j++)
6924  for (int i = 0; i <= p; i++)
6925  {
6926  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
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), shape_y(p+1), shape_z(p+1);
6937  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
6938 #endif
6939 
6940  basis1d.Eval(ip.x, shape_x, dshape_x);
6941  basis1d.Eval(ip.y, shape_y, dshape_y);
6942  basis1d.Eval(ip.z, shape_z, dshape_z);
6943 
6944  for (int o = 0, k = 0; k <= p; k++)
6945  for (int j = 0; j <= p; j++)
6946  for (int i = 0; i <= p; i++)
6947  {
6948  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
6949  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
6950  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
6951  }
6952 }
6953 
6954 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
6955 {
6956  const int p = Order;
6957  const double *cp = poly1d.ClosedPoints(p,pt_type);
6958 
6959 #ifdef MFEM_THREAD_SAFE
6960  Vector shape_x(p+1), shape_y(p+1);
6961 #endif
6962 
6963  for (int i = 0; i <= p; i++)
6964  {
6965  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6966  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
6967  }
6968 
6969  switch (vertex)
6970  {
6971  case 0:
6972  for (int o = 0, k = 0; k <= p; k++)
6973  for (int j = 0; j <= p; j++)
6974  for (int i = 0; i <= p; i++)
6975  {
6976  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
6977  }
6978  break;
6979  case 1:
6980  for (int o = 0, k = 0; k <= p; k++)
6981  for (int j = 0; j <= p; j++)
6982  for (int i = 0; i <= p; i++)
6983  {
6984  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
6985  }
6986  break;
6987  case 2:
6988  for (int o = 0, k = 0; k <= p; k++)
6989  for (int j = 0; j <= p; j++)
6990  for (int i = 0; i <= p; i++)
6991  {
6992  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
6993  }
6994  break;
6995  case 3:
6996  for (int o = 0, k = 0; k <= p; k++)
6997  for (int j = 0; j <= p; j++)
6998  for (int i = 0; i <= p; i++)
6999  {
7000  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
7001  }
7002  break;
7003  case 4:
7004  for (int o = 0, k = 0; k <= p; k++)
7005  for (int j = 0; j <= p; j++)
7006  for (int i = 0; i <= p; i++)
7007  {
7008  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
7009  }
7010  break;
7011  case 5:
7012  for (int o = 0, k = 0; k <= p; k++)
7013  for (int j = 0; j <= p; j++)
7014  for (int i = 0; i <= p; i++)
7015  {
7016  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
7017  }
7018  break;
7019  case 6:
7020  for (int o = 0, k = 0; k <= p; k++)
7021  for (int j = 0; j <= p; j++)
7022  for (int i = 0; i <= p; i++)
7023  {
7024  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
7025  }
7026  break;
7027  case 7:
7028  for (int o = 0, k = 0; k <= p; k++)
7029  for (int j = 0; j <= p; j++)
7030  for (int i = 0; i <= p; i++)
7031  {
7032  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
7033  }
7034  break;
7035  }
7036 }
7037 
7038 
7040  : PositiveFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
7041  dof_map(Dof)
7042 {
7043 #ifndef MFEM_THREAD_SAFE
7044  // thread private versions; see class header.
7045  shape_x.SetSize(p+1);
7046  dshape_x.SetSize(p+1);
7047 #endif
7048 
7049  // Endpoints need to be first in the list, so reorder them.
7050  Nodes.IntPoint(0).x = 0.0;
7051  Nodes.IntPoint(1).x = 1.0;
7052  dof_map[0] = 0;
7053  dof_map[p] = 1;
7054  for (int i = 1; i < p; i++)
7055  {
7056  Nodes.IntPoint(i+1).x = double(i)/p;
7057  dof_map[i] = i+1;
7058  }
7059 }
7060 
7062  Vector &shape) const
7063 {
7064  const int p = Order;
7065 
7066 #ifdef MFEM_THREAD_SAFE
7067  Vector shape_x(p+1);
7068 #endif
7069 
7070  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7071 
7072  // Endpoints need to be first in the list, so reorder them.
7073  shape(0) = shape_x(0);
7074  shape(1) = shape_x(p);
7075  for (int i = 1; i < p; i++)
7076  {
7077  shape(i+1) = shape_x(i);
7078  }
7079 }
7080 
7082  DenseMatrix &dshape) const
7083 {
7084  const int p = Order;
7085 
7086 #ifdef MFEM_THREAD_SAFE
7087  Vector shape_x(p+1), dshape_x(p+1);
7088 #endif
7089 
7090  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7091 
7092  // Endpoints need to be first in the list, so reorder them.
7093  dshape(0,0) = dshape_x(0);
7094  dshape(1,0) = dshape_x(p);
7095  for (int i = 1; i < p; i++)
7096  {
7097  dshape(i+1,0) = dshape_x(i);
7098  }
7099 }
7100 
7101 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7102 {
7103  dofs = 0.0;
7104  dofs[vertex] = 1.0;
7105 }
7106 
7107 
7109  : PositiveFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
7110  FunctionSpace::Qk),
7111  dof_map((p + 1)*(p + 1))
7112 {
7113  const int p1 = p + 1;
7114 
7115 #ifndef MFEM_THREAD_SAFE
7116  shape_x.SetSize(p1);
7117  shape_y.SetSize(p1);
7118  dshape_x.SetSize(p1);
7119  dshape_y.SetSize(p1);
7120 #endif
7121 
7122  // vertices must be the first ones in the list of DOF's for
7123  // this element. So we need to reorder the points.
7124  dof_map[0 + 0*p1] = 0;
7125  dof_map[p + 0*p1] = 1;
7126  dof_map[p + p*p1] = 2;
7127  dof_map[0 + p*p1] = 3;
7128 
7129  // edges
7130  int o = 4;
7131  for (int i = 1; i < p; i++)
7132  {
7133  dof_map[i + 0*p1] = o++;
7134  }
7135  for (int i = 1; i < p; i++)
7136  {
7137  dof_map[p + i*p1] = o++;
7138  }
7139  for (int i = 1; i < p; i++)
7140  {
7141  dof_map[(p-i) + p*p1] = o++;
7142  }
7143  for (int i = 1; i < p; i++)
7144  {
7145  dof_map[0 + (p-i)*p1] = o++;
7146  }
7147 
7148  // interior
7149  for (int j = 1; j < p; j++)
7150  for (int i = 1; i < p; i++)
7151  {
7152  dof_map[i + j*p1] = o++;
7153  }
7154 
7155  o = 0;
7156  for (int j = 0; j <= p; j++)
7157  for (int i = 0; i <= p; i++)
7158  {
7159  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
7160  }
7161 }
7162 
7164  Vector &shape) const
7165 {
7166  const int p = Order;
7167 
7168 #ifdef MFEM_THREAD_SAFE
7169  Vector shape_x(p+1), shape_y(p+1);
7170 #endif
7171 
7172  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7173  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7174 
7175  // Reorder so that vertices are at the beginning of the list
7176  for (int o = 0, j = 0; j <= p; j++)
7177  for (int i = 0; i <= p; i++)
7178  {
7179  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7180  }
7181 }
7182 
7184  DenseMatrix &dshape) const
7185 {
7186  const int p = Order;
7187 
7188 #ifdef MFEM_THREAD_SAFE
7189  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7190 #endif
7191 
7192  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7193  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7194 
7195  // Reorder so that vertices are at the beginning of the list
7196  for (int o = 0, j = 0; j <= p; j++)
7197  for (int i = 0; i <= p; i++)
7198  {
7199  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7200  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7201  }
7202 }
7203 
7205 {
7206  dofs = 0.0;
7207  dofs[vertex] = 1.0;
7208 }
7209 
7210 
7212  : PositiveFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
7213  FunctionSpace::Qk),
7214  dof_map((p + 1)*(p + 1)*(p + 1))
7215 {
7216  const int p1 = p + 1;
7217 
7218 #ifndef MFEM_THREAD_SAFE
7219  shape_x.SetSize(p1);
7220  shape_y.SetSize(p1);
7221  shape_z.SetSize(p1);
7222  dshape_x.SetSize(p1);
7223  dshape_y.SetSize(p1);
7224  dshape_z.SetSize(p1);
7225 #endif
7226 
7227  // vertices must be the first ones in the list of DOF's for
7228  // this element. So we need to reorder the points.
7229  dof_map[0 + (0 + 0*p1)*p1] = 0;
7230  dof_map[p + (0 + 0*p1)*p1] = 1;
7231  dof_map[p + (p + 0*p1)*p1] = 2;
7232  dof_map[0 + (p + 0*p1)*p1] = 3;
7233  dof_map[0 + (0 + p*p1)*p1] = 4;
7234  dof_map[p + (0 + p*p1)*p1] = 5;
7235  dof_map[p + (p + p*p1)*p1] = 6;
7236  dof_map[0 + (p + p*p1)*p1] = 7;
7237 
7238  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
7239  int o = 8;
7240  for (int i = 1; i < p; i++)
7241  {
7242  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
7243  }
7244  for (int i = 1; i < p; i++)
7245  {
7246  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
7247  }
7248  for (int i = 1; i < p; i++)
7249  {
7250  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
7251  }
7252  for (int i = 1; i < p; i++)
7253  {
7254  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
7255  }
7256  for (int i = 1; i < p; i++)
7257  {
7258  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
7259  }
7260  for (int i = 1; i < p; i++)
7261  {
7262  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
7263  }
7264  for (int i = 1; i < p; i++)
7265  {
7266  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
7267  }
7268  for (int i = 1; i < p; i++)
7269  {
7270  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
7271  }
7272  for (int i = 1; i < p; i++)
7273  {
7274  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
7275  }
7276  for (int i = 1; i < p; i++)
7277  {
7278  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
7279  }
7280  for (int i = 1; i < p; i++)
7281  {
7282  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
7283  }
7284  for (int i = 1; i < p; i++)
7285  {
7286  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
7287  }
7288 
7289  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7290  for (int j = 1; j < p; j++)
7291  for (int i = 1; i < p; i++)
7292  {
7293  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
7294  }
7295  for (int j = 1; j < p; j++)
7296  for (int i = 1; i < p; i++)
7297  {
7298  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
7299  }
7300  for (int j = 1; j < p; j++)
7301  for (int i = 1; i < p; i++)
7302  {
7303  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
7304  }
7305  for (int j = 1; j < p; j++)
7306  for (int i = 1; i < p; i++)
7307  {
7308  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
7309  }
7310  for (int j = 1; j < p; j++)
7311  for (int i = 1; i < p; i++)
7312  {
7313  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
7314  }
7315  for (int j = 1; j < p; j++)
7316  for (int i = 1; i < p; i++)
7317  {
7318  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
7319  }
7320 
7321  // interior
7322  for (int k = 1; k < p; k++)
7323  for (int j = 1; j < p; j++)
7324  for (int i = 1; i < p; i++)
7325  {
7326  dof_map[i + (j + k*p1)*p1] = o++;
7327  }
7328 
7329  o = 0;
7330  for (int k = 0; k <= p; k++)
7331  for (int j = 0; j <= p; j++)
7332  for (int i = 0; i <= p; i++)
7333  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
7334  double(k)/p);
7335 }
7336 
7338  Vector &shape) const
7339 {
7340  const int p = Order;
7341 
7342 #ifdef MFEM_THREAD_SAFE
7343  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7344 #endif
7345 
7346  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7347  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7348  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
7349 
7350  for (int o = 0, k = 0; k <= p; k++)
7351  for (int j = 0; j <= p; j++)
7352  for (int i = 0; i <= p; i++)
7353  {
7354  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7355  }
7356 }
7357 
7359  DenseMatrix &dshape) const
7360 {
7361  const int p = Order;
7362 
7363 #ifdef MFEM_THREAD_SAFE
7364  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7365  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7366 #endif
7367 
7368  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7369  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7370  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
7371 
7372  for (int o = 0, k = 0; k <= p; k++)
7373  for (int j = 0; j <= p; j++)
7374  for (int i = 0; i <= p; i++)
7375  {
7376  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7377  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7378  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7379  }
7380 }
7381 
7382 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7383 {
7384  dofs = 0.0;
7385  dofs[vertex] = 1.0;
7386 }
7387 
7388 
7389 H1_TriangleElement::H1_TriangleElement(const int p, const int type)
7390  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7391  FunctionSpace::Pk)
7392 {
7393  const double *cp = poly1d.ClosedPoints(p, VerifyClosed(type));
7394 
7395 #ifndef MFEM_THREAD_SAFE
7396  shape_x.SetSize(p + 1);
7397  shape_y.SetSize(p + 1);
7398  shape_l.SetSize(p + 1);
7399  dshape_x.SetSize(p + 1);
7400  dshape_y.SetSize(p + 1);
7401  dshape_l.SetSize(p + 1);
7402  u.SetSize(Dof);
7403  du.SetSize(Dof, Dim);
7404 #else
7405  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7406 #endif
7407 
7408  // vertices
7409  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
7410  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
7411  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
7412 
7413  // edges
7414  int o = 3;
7415  for (int i = 1; i < p; i++)
7416  {
7417  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
7418  }
7419  for (int i = 1; i < p; i++)
7420  {
7421  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
7422  }
7423  for (int i = 1; i < p; i++)
7424  {
7425  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
7426  }
7427 
7428  // interior
7429  for (int j = 1; j < p; j++)
7430  for (int i = 1; i + j < p; i++)
7431  {
7432  const double w = cp[i] + cp[j] + cp[p-i-j];
7433  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
7434  }
7435 
7436  DenseMatrix T(Dof);
7437  for (int k = 0; k < Dof; k++)
7438  {
7439  IntegrationPoint &ip = Nodes.IntPoint(k);
7440  poly1d.CalcBasis(p, ip.x, shape_x);
7441  poly1d.CalcBasis(p, ip.y, shape_y);
7442  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7443 
7444  o = 0;
7445  for (int j = 0; j <= p; j++)
7446  for (int i = 0; i + j <= p; i++)
7447  {
7448  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7449  }
7450  }
7451 
7452  Ti.Factor(T);
7453  // cout << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
7454 }
7455 
7457  Vector &shape) const
7458 {
7459  const int p = Order;
7460 
7461 #ifdef MFEM_THREAD_SAFE
7462  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
7463 #endif
7464 
7465  poly1d.CalcBasis(p, ip.x, shape_x);
7466  poly1d.CalcBasis(p, ip.y, shape_y);
7467  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7468 
7469  for (int o = 0, j = 0; j <= p; j++)
7470  for (int i = 0; i + j <= p; i++)
7471  {
7472  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7473  }
7474 
7475  Ti.Mult(u, shape);
7476 }
7477 
7479  DenseMatrix &dshape) const
7480 {
7481  const int p = Order;
7482 
7483 #ifdef MFEM_THREAD_SAFE
7484  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7485  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
7486  DenseMatrix du(Dof, Dim);
7487 #endif
7488 
7489  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7490  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7491  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
7492 
7493  for (int o = 0, j = 0; j <= p; j++)
7494  for (int i = 0; i + j <= p; i++)
7495  {
7496  int k = p - i - j;
7497  du(o,0) = ((dshape_x(i)* shape_l(k)) -
7498  ( shape_x(i)*dshape_l(k)))*shape_y(j);
7499  du(o,1) = ((dshape_y(j)* shape_l(k)) -
7500  ( shape_y(j)*dshape_l(k)))*shape_x(i);
7501  o++;
7502  }
7503 
7504  Ti.Mult(du, dshape);
7505 }
7506 
7507 
7509  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
7510  p, FunctionSpace::Pk)
7511 {
7512  const double *cp = poly1d.ClosedPoints(p, VerifyClosed(type));
7513 
7514 #ifndef MFEM_THREAD_SAFE
7515  shape_x.SetSize(p + 1);
7516  shape_y.SetSize(p + 1);
7517  shape_z.SetSize(p + 1);
7518  shape_l.SetSize(p + 1);
7519  dshape_x.SetSize(p + 1);
7520  dshape_y.SetSize(p + 1);
7521  dshape_z.SetSize(p + 1);
7522  dshape_l.SetSize(p + 1);
7523  u.SetSize(Dof);
7524  du.SetSize(Dof, Dim);
7525 #else
7526  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7527 #endif
7528 
7529  // vertices
7530  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
7531  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
7532  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
7533  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
7534 
7535  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7536  int o = 4;
7537  for (int i = 1; i < p; i++) // (0,1)
7538  {
7539  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
7540  }
7541  for (int i = 1; i < p; i++) // (0,2)
7542  {
7543  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
7544  }
7545  for (int i = 1; i < p; i++) // (0,3)
7546  {
7547  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
7548  }
7549  for (int i = 1; i < p; i++) // (1,2)
7550  {
7551  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
7552  }
7553  for (int i = 1; i < p; i++) // (1,3)
7554  {
7555  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
7556  }
7557  for (int i = 1; i < p; i++) // (2,3)
7558  {
7559  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
7560  }
7561 
7562  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7563  for (int j = 1; j < p; j++)
7564  for (int i = 1; i + j < p; i++) // (1,2,3)
7565  {
7566  double w = cp[i] + cp[j] + cp[p-i-j];
7567  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
7568  }
7569  for (int j = 1; j < p; j++)
7570  for (int i = 1; i + j < p; i++) // (0,3,2)
7571  {
7572  double w = cp[i] + cp[j] + cp[p-i-j];
7573  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
7574  }
7575  for (int j = 1; j < p; j++)
7576  for (int i = 1; i + j < p; i++) // (0,1,3)
7577  {
7578  double w = cp[i] + cp[j] + cp[p-i-j];
7579  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
7580  }
7581  for (int j = 1; j < p; j++)
7582  for (int i = 1; i + j < p; i++) // (0,2,1)
7583  {
7584  double w = cp[i] + cp[j] + cp[p-i-j];
7585  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
7586  }
7587 
7588  // interior
7589  for (int k = 1; k < p; k++)
7590  for (int j = 1; j + k < p; j++)
7591  for (int i = 1; i + j + k < p; i++)
7592  {
7593  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
7594  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
7595  }
7596 
7597  DenseMatrix T(Dof);
7598  for (int m = 0; m < Dof; m++)
7599  {
7600  IntegrationPoint &ip = Nodes.IntPoint(m);
7601  poly1d.CalcBasis(p, ip.x, shape_x);
7602  poly1d.CalcBasis(p, ip.y, shape_y);
7603  poly1d.CalcBasis(p, ip.z, shape_z);
7604  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7605 
7606  o = 0;
7607  for (int k = 0; k <= p; k++)
7608  for (int j = 0; j + k <= p; j++)
7609  for (int i = 0; i + j + k <= p; i++)
7610  {
7611  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7612  }
7613  }
7614 
7615  Ti.Factor(T);
7616  // cout << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
7617 }
7618 
7620  Vector &shape) const
7621 {
7622  const int p = Order;
7623 
7624 #ifdef MFEM_THREAD_SAFE
7625  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7626  Vector u(Dof);
7627 #endif
7628 
7629  poly1d.CalcBasis(p, ip.x, shape_x);
7630  poly1d.CalcBasis(p, ip.y, shape_y);
7631  poly1d.CalcBasis(p, ip.z, shape_z);
7632  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7633 
7634  for (int o = 0, k = 0; k <= p; k++)
7635  for (int j = 0; j + k <= p; j++)
7636  for (int i = 0; i + j + k <= p; i++)
7637  {
7638  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7639  }
7640 
7641  Ti.Mult(u, shape);
7642 }
7643 
7645  DenseMatrix &dshape) const
7646 {
7647  const int p = Order;
7648 
7649 #ifdef MFEM_THREAD_SAFE
7650  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7651  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
7652  DenseMatrix du(Dof, Dim);
7653 #endif
7654 
7655  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7656  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7657  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
7658  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
7659 
7660  for (int o = 0, k = 0; k <= p; k++)
7661  for (int j = 0; j + k <= p; j++)
7662  for (int i = 0; i + j + k <= p; i++)
7663  {
7664  int l = p - i - j - k;
7665  du(o,0) = ((dshape_x(i)* shape_l(l)) -
7666  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
7667  du(o,1) = ((dshape_y(j)* shape_l(l)) -
7668  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
7669  du(o,2) = ((dshape_z(k)* shape_l(l)) -
7670  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
7671  o++;
7672  }
7673 
7674  Ti.Mult(du, dshape);
7675 }
7676 
7677 
7679  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7680  FunctionSpace::Pk)
7681 {
7682 #ifndef MFEM_THREAD_SAFE
7683  m_shape.SetSize(Dof);
7684  dshape_1d.SetSize(p + 1);
7685  m_dshape.SetSize(Dof, Dim);
7686 #endif
7687  dof_map.SetSize(Dof);
7688 
7689  struct Index
7690  {
7691  int p2p3;
7692  Index(int p) { p2p3 = 2*p + 3; }
7693  int operator()(int i, int j) { return ((p2p3-j)*j)/2+i; }
7694  };
7695  Index idx(p);
7696 
7697  // vertices
7698  dof_map[idx(0,0)] = 0;
7699  Nodes.IntPoint(0).Set2(0., 0.);
7700  dof_map[idx(p,0)] = 1;
7701  Nodes.IntPoint(1).Set2(1., 0.);
7702  dof_map[idx(0,p)] = 2;
7703  Nodes.IntPoint(2).Set2(0., 1.);
7704 
7705  // edges
7706  int o = 3;
7707  for (int i = 1; i < p; i++)
7708  {
7709  dof_map[idx(i,0)] = o;
7710  Nodes.IntPoint(o++).Set2(double(i)/p, 0.);
7711  }
7712  for (int i = 1; i < p; i++)
7713  {
7714  dof_map[idx(p-i,i)] = o;
7715  Nodes.IntPoint(o++).Set2(double(p-i)/p, double(i)/p);
7716  }
7717  for (int i = 1; i < p; i++)
7718  {
7719  dof_map[idx(0,p-i)] = o;
7720  Nodes.IntPoint(o++).Set2(0., double(p-i)/p);
7721  }
7722 
7723  // interior
7724  for (int j = 1; j < p; j++)
7725  for (int i = 1; i + j < p; i++)
7726  {
7727  dof_map[idx(i,j)] = o;
7728  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
7729  }
7730 }
7731 
7732 // static method
7734  const int p, const double l1, const double l2, double *shape)
7735 {
7736  const double l3 = 1. - l1 - l2;
7737 
7738  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
7739  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
7740  // Another expression is given by the terms of the expansion:
7741  // (l1 + l2 + l3)^p =
7742  // \sum_{j=0}^p \binom{p}{j} l2^j
7743  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
7744  const int *bp = Poly_1D::Binom(p);
7745  double z = 1.;
7746  for (int o = 0, j = 0; j <= p; j++)
7747  {
7748  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape[o]);
7749  double s = bp[j]*z;
7750  for (int i = 0; i <= p - j; i++)
7751  {
7752  shape[o++] *= s;
7753  }
7754  z *= l2;
7755  }
7756 }
7757 
7758 // static method
7760  const int p, const double l1, const double l2,
7761  double *dshape_1d, double *dshape)
7762 {
7763  const int dof = ((p + 1)*(p + 2))/2;
7764  const double l3 = 1. - l1 - l2;
7765 
7766  const int *bp = Poly_1D::Binom(p);
7767  double z = 1.;
7768  for (int o = 0, j = 0; j <= p; j++)
7769  {
7770  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
7771  double s = bp[j]*z;
7772  for (int i = 0; i <= p - j; i++)
7773  {
7774  dshape[o++] = s*dshape_1d[i];
7775  }
7776  z *= l2;
7777  }
7778  z = 1.;
7779  for (int i = 0; i <= p; i++)
7780  {
7781  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
7782  double s = bp[i]*z;
7783  for (int o = i, j = 0; j <= p - i; j++)
7784  {
7785  dshape[dof + o] = s*dshape_1d[j];
7786  o += p + 1 - j;
7787  }
7788  z *= l1;
7789  }
7790 }
7791 
7793  Vector &shape) const
7794 {
7795 #ifdef MFEM_THREAD_SAFE
7796  Vector m_shape(Dof);
7797 #endif
7798  CalcShape(Order, ip.x, ip.y, m_shape.GetData());
7799  for (int i = 0; i < Dof; i++)
7800  {
7801  shape(dof_map[i]) = m_shape(i);
7802  }
7803 }
7804 
7806  DenseMatrix &dshape) const
7807 {
7808 #ifdef MFEM_THREAD_SAFE
7809  Vector dshape_1d(Order + 1);
7811 #endif
7812  CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(), m_dshape.Data());
7813  for (int d = 0; d < 2; d++)
7814  {
7815  for (int i = 0; i < Dof; i++)
7816  {
7817  dshape(dof_map[i],d) = m_dshape(i,d);
7818  }
7819  }
7820 }
7821 
7822 
7824  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
7825  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
7826 {
7827 #ifndef MFEM_THREAD_SAFE
7828  m_shape.SetSize(Dof);
7829  dshape_1d.SetSize(p + 1);
7830  m_dshape.SetSize(Dof, Dim);
7831 #endif
7832  dof_map.SetSize(Dof);
7833 
7834  struct Index
7835  {
7836  int p, dof;
7837  int tri(int k) { return (k*(k + 1))/2; }
7838  int tet(int k) { return (k*(k + 1)*(k + 2))/6; }
7839  Index(int p_) { p = p_; dof = tet(p + 1); }
7840  int operator()(int i, int j, int k)
7841  { return dof - tet(p - k) - tri(p + 1 - k - j) + i; }
7842  };
7843  Index idx(p);
7844 
7845  // vertices
7846  dof_map[idx(0,0,0)] = 0;
7847  Nodes.IntPoint(0).Set3(0., 0., 0.);
7848  dof_map[idx(p,0,0)] = 1;
7849  Nodes.IntPoint(1).Set3(1., 0., 0.);
7850  dof_map[idx(0,p,0)] = 2;
7851  Nodes.IntPoint(2).Set3(0., 1., 0.);
7852  dof_map[idx(0,0,p)] = 3;
7853  Nodes.IntPoint(3).Set3(0., 0., 1.);
7854 
7855  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7856  int o = 4;
7857  for (int i = 1; i < p; i++) // (0,1)
7858  {
7859  dof_map[idx(i,0,0)] = o;
7860  Nodes.IntPoint(o++).Set3(double(i)/p, 0., 0.);
7861  }
7862  for (int i = 1; i < p; i++) // (0,2)
7863  {
7864  dof_map[idx(0,i,0)] = o;
7865  Nodes.IntPoint(o++).Set3(0., double(i)/p, 0.);
7866  }
7867  for (int i = 1; i < p; i++) // (0,3)
7868  {
7869  dof_map[idx(0,0,i)] = o;
7870  Nodes.IntPoint(o++).Set3(0., 0., double(i)/p);
7871  }
7872  for (int i = 1; i < p; i++) // (1,2)
7873  {
7874  dof_map[idx(p-i,i,0)] = o;
7875  Nodes.IntPoint(o++).Set3(double(p-i)/p, double(i)/p, 0.);
7876  }
7877  for (int i = 1; i < p; i++) // (1,3)
7878  {
7879  dof_map[idx(p-i,0,i)] = o;
7880  Nodes.IntPoint(o++).Set3(double(p-i)/p, 0., double(i)/p);
7881  }
7882  for (int i = 1; i < p; i++) // (2,3)
7883  {
7884  dof_map[idx(0,p-i,i)] = o;
7885  Nodes.IntPoint(o++).Set3(0., double(p-i)/p, double(i)/p);
7886  }
7887 
7888  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7889  for (int j = 1; j < p; j++)
7890  for (int i = 1; i + j < p; i++) // (1,2,3)
7891  {
7892  dof_map[idx(p-i-j,i,j)] = o;
7893  Nodes.IntPoint(o++).Set3(double(p-i-j)/p, double(i)/p, double(j)/p);
7894  }
7895  for (int j = 1; j < p; j++)
7896  for (int i = 1; i + j < p; i++) // (0,3,2)
7897  {
7898  dof_map[idx(0,j,i)] = o;
7899  Nodes.IntPoint(o++).Set3(0., double(j)/p, double(i)/p);
7900  }
7901  for (int j = 1; j < p; j++)
7902  for (int i = 1; i + j < p; i++) // (0,1,3)
7903  {
7904  dof_map[idx(i,0,j)] = o;
7905  Nodes.IntPoint(o++).Set3(double(i)/p, 0., double(j)/p);
7906  }
7907  for (int j = 1; j < p; j++)
7908  for (int i = 1; i + j < p; i++) // (0,2,1)
7909  {
7910  dof_map[idx(j,i,0)] = o;
7911  Nodes.IntPoint(o++).Set3(double(j)/p, double(i)/p, 0.);
7912  }
7913 
7914  // interior
7915  for (int k = 1; k < p; k++)
7916  for (int j = 1; j + k < p; j++)
7917  for (int i = 1; i + j + k < p; i++)
7918  {
7919  dof_map[idx(i,j,k)] = o;
7920  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
7921  }
7922 }
7923 
7924 // static method
7926  const int p, const double l1, const double l2, const double l3,
7927  double *shape)
7928 {
7929  const double l4 = 1. - l1 - l2 - l3;
7930 
7931  // The basis functions are the terms in the expansion:
7932  // (l1 + l2 + l3 + l4)^p =
7933  // \sum_{k=0}^p \binom{p}{k} l3^k
7934  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
7935  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
7936  const int *bp = Poly_1D::Binom(p);
7937  double l3k = 1.;
7938  for (int o = 0, k = 0; k <= p; k++)
7939  {
7940  const int *bpk = Poly_1D::Binom(p - k);
7941  const double ek = bp[k]*l3k;
7942  double l2j = 1.;
7943  for (int j = 0; j <= p - k; j++)
7944  {
7945  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape[o]);
7946  double ekj = ek*bpk[j]*l2j;
7947  for (int i = 0; i <= p - k - j; i++)
7948  {
7949  shape[o++] *= ekj;
7950  }
7951  l2j *= l2;
7952  }
7953  l3k *= l3;
7954  }
7955 }
7956 
7957 // static method
7959  const int p, const double l1, const double l2, const double l3,
7960  double *dshape_1d, double *dshape)
7961 {
7962  const int dof = ((p + 1)*(p + 2)*(p + 3))/6;
7963  const double l4 = 1. - l1 - l2 - l3;
7964 
7965  // For the x derivatives, differentiate the terms of the expression:
7966  // \sum_{k=0}^p \binom{p}{k} l3^k
7967  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
7968  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
7969  const int *bp = Poly_1D::Binom(p);
7970  double l3k = 1.;
7971  for (int o = 0, k = 0; k <= p; k++)
7972  {
7973  const int *bpk = Poly_1D::Binom(p - k);
7974  const double ek = bp[k]*l3k;
7975  double l2j = 1.;
7976  for (int j = 0; j <= p - k; j++)
7977  {
7978  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
7979  double ekj = ek*bpk[j]*l2j;
7980  for (int i = 0; i <= p - k - j; i++)
7981  {
7982  dshape[o++] = dshape_1d[i]*ekj;
7983  }
7984  l2j *= l2;
7985  }
7986  l3k *= l3;
7987  }
7988  // For the y derivatives, differentiate the terms of the expression:
7989  // \sum_{k=0}^p \binom{p}{k} l3^k
7990  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
7991  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
7992  l3k = 1.;
7993  for (int ok = 0, k = 0; k <= p; k++)
7994  {
7995  const int *bpk = Poly_1D::Binom(p - k);
7996  const double ek = bp[k]*l3k;
7997  double l1i = 1.;
7998  for (int i = 0; i <= p - k; i++)
7999  {
8000  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
8001  double eki = ek*bpk[i]*l1i;
8002  int o = ok + i;
8003  for (int j = 0; j <= p - k - i; j++)
8004  {
8005  dshape[dof + o] = dshape_1d[j]*eki;
8006  o += p - k - j + 1;
8007  }
8008  l1i *= l1;
8009  }
8010  l3k *= l3;
8011  ok += ((p - k + 2)*(p - k + 1))/2;
8012  }
8013  // For the z derivatives, differentiate the terms of the expression:
8014  // \sum_{j=0}^p \binom{p}{j} l2^j
8015  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
8016  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
8017  double l2j = 1.;
8018  for (int j = 0; j <= p; j++)
8019  {
8020  const int *bpj = Poly_1D::Binom(p - j);
8021  const double ej = bp[j]*l2j;
8022  double l1i = 1.;
8023  for (int i = 0; i <= p - j; i++)
8024  {
8025  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
8026  double eji = ej*bpj[i]*l1i;
8027  int m = ((p + 2)*(p + 1))/2;
8028  int n = ((p - j + 2)*(p - j + 1))/2;
8029  for (int o = i, k = 0; k <= p - j - i; k++)
8030  {
8031  // m = ((p - k + 2)*(p - k + 1))/2;
8032  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
8033  o += m;
8034  dshape[2*dof + o - n] = dshape_1d[k]*eji;
8035  m -= p - k + 1;
8036  n -= p - k - j + 1;
8037  }
8038  l1i *= l1;
8039  }
8040  l2j *= l2;
8041  }
8042 }
8043 
8045  Vector &shape) const
8046 {
8047 #ifdef MFEM_THREAD_SAFE
8048  Vector m_shape(Dof);
8049 #endif
8050  CalcShape(Order, ip.x, ip.y, ip.z, m_shape.GetData());
8051  for (int i = 0; i < Dof; i++)
8052  {
8053  shape(dof_map[i]) = m_shape(i);
8054  }
8055 }
8056 
8058  DenseMatrix &dshape) const
8059 {
8060 #ifdef MFEM_THREAD_SAFE
8061  Vector dshape_1d(Order + 1);
8063 #endif
8064  CalcDShape(Order, ip.x, ip.y, ip.z, dshape_1d.GetData(), m_dshape.Data());
8065  for (int d = 0; d < 3; d++)
8066  {
8067  for (int i = 0; i < Dof; i++)
8068  {
8069  dshape(dof_map[i],d) = m_dshape(i,d);
8070  }
8071  }
8072 }
8073 
8074 
8075 L2_SegmentElement::L2_SegmentElement(const int p, const int type)
8076  : NodalFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
8077  type(VerifyOpen(type)),
8078  basis1d(poly1d.OpenBasis(p, type))
8079 {
8080  const double *op = poly1d.OpenPoints(p, type);
8081 
8082 #ifndef MFEM_THREAD_SAFE
8083  shape_x.SetSize(p + 1);
8084  dshape_x.SetDataAndSize(NULL, p + 1);
8085 #endif
8086 
8087  for (int i = 0; i <= p; i++)
8088  {
8089  Nodes.IntPoint(i).x = op[i];
8090  }
8091 }
8092 
8094  Vector &shape) const
8095 {
8096  basis1d.Eval(ip.x, shape);
8097 }
8098 
8100  DenseMatrix &dshape) const
8101 {
8102 #ifdef MFEM_THREAD_SAFE
8103  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
8104 #else
8105  dshape_x.SetData(dshape.Data());
8106 #endif
8107  basis1d.Eval(ip.x, shape_x, dshape_x);
8108 }
8109 
8110 void L2_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8111 {
8112  const int p = Order;
8113  const double *op = poly1d.OpenPoints(p,type);
8114 
8115  switch (vertex)
8116  {
8117  case 0:
8118  for (int i = 0; i <= p; i++)
8119  {
8120  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8121  }
8122  break;
8123 
8124  case 1:
8125  for (int i = 0; i <= p; i++)
8126  {
8127  dofs(i) = poly1d.CalcDelta(p,op[i]);
8128  }
8129  break;
8130  }
8131 }
8132 
8133 
8135  : PositiveFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk)
8136 {
8137 #ifndef MFEM_THREAD_SAFE
8138  shape_x.SetSize(p + 1);
8139  dshape_x.SetDataAndSize(NULL, p + 1);
8140 #endif
8141 
8142  if (p == 0)
8143  {
8144  Nodes.IntPoint(0).x = 0.5;
8145  }
8146  else
8147  {
8148  for (int i = 0; i <= p; i++)
8149  {
8150  Nodes.IntPoint(i).x = double(i)/p;
8151  }
8152  }
8153 }
8154 
8156  Vector &shape) const
8157 {
8158  Poly_1D::CalcBernstein(Order, 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  Poly_1D::CalcBernstein(Order, ip.x, shape_x, dshape_x);
8170 }
8171 
8172 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
8173 {
8174  dofs = 0.0;
8175  dofs[vertex*Order] = 1.0;
8176 }
8177 
8178 
8180  : NodalFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
8181  FunctionSpace::Qk),
8182  type(VerifyOpen(_type)),
8183  basis1d(poly1d.OpenBasis(p, type))
8184 {
8185  const double *op = poly1d.OpenPoints(p, type);
8186 
8187 #ifndef MFEM_THREAD_SAFE
8188  shape_x.SetSize(p + 1);
8189  shape_y.SetSize(p + 1);
8190  dshape_x.SetSize(p + 1);
8191  dshape_y.SetSize(p + 1);
8192 #endif
8193 
8194  for (int o = 0, j = 0; j <= p; j++)
8195  for (int i = 0; i <= p; i++)
8196  {
8197  Nodes.IntPoint(o++).Set2(op[i], op[j]);
8198  }
8199 }
8200 
8202  Vector &shape) const
8203 {
8204  const int p = Order;
8205 
8206 #ifdef MFEM_THREAD_SAFE
8207  Vector shape_x(p+1), shape_y(p+1);
8208 #endif
8209 
8210  basis1d.Eval(ip.x, shape_x);
8211  basis1d.Eval(ip.y, shape_y);
8212 
8213  for (int o = 0, j = 0; j <= p; j++)
8214  for (int i = 0; i <= p; i++)
8215  {
8216  shape(o++) = shape_x(i)*shape_y(j);
8217  }
8218 }
8219 
8221  DenseMatrix &dshape) const
8222 {
8223  const int p = Order;
8224 
8225 #ifdef MFEM_THREAD_SAFE
8226  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8227 #endif
8228 
8229  basis1d.Eval(ip.x, shape_x, dshape_x);
8230  basis1d.Eval(ip.y, shape_y, dshape_y);
8231 
8232  for (int o = 0, j = 0; j <= p; j++)
8233  for (int i = 0; i <= p; i++)
8234  {
8235  dshape(o,0) = dshape_x(i)* shape_y(j);
8236  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8237  }
8238 }
8239 
8240 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
8241 {
8242  const int p = Order;
8243  const double *op = poly1d.OpenPoints(p, type);
8244 
8245 #ifdef MFEM_THREAD_SAFE
8246  Vector shape_x(p+1), shape_y(p+1);
8247 #endif
8248 
8249  for (int i = 0; i <= p; i++)
8250  {
8251  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8252  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8253  }
8254 
8255  switch (vertex)
8256  {
8257  case 0:
8258  for (int o = 0, j = 0; j <= p; j++)
8259  for (int i = 0; i <= p; i++)
8260  {
8261  dofs[o++] = shape_x(i)*shape_x(j);
8262  }
8263  break;
8264  case 1:
8265  for (int o = 0, j = 0; j <= p; j++)
8266  for (int i = 0; i <= p; i++)
8267  {
8268  dofs[o++] = shape_y(i)*shape_x(j);
8269  }
8270  break;
8271  case 2:
8272  for (int o = 0, j = 0; j <= p; j++)
8273  for (int i = 0; i <= p; i++)
8274  {
8275  dofs[o++] = shape_y(i)*shape_y(j);
8276  }
8277  break;
8278  case 3:
8279  for (int o = 0, j = 0; j <= p; j++)
8280  for (int i = 0; i <= p; i++)
8281  {
8282  dofs[o++] = shape_x(i)*shape_y(j);
8283  }
8284  break;
8285  }
8286 }
8287 
8288 
8290  : PositiveFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
8291  FunctionSpace::Qk)
8292 {
8293 #ifndef MFEM_THREAD_SAFE
8294  shape_x.SetSize(p + 1);
8295  shape_y.SetSize(p + 1);
8296  dshape_x.SetSize(p + 1);
8297  dshape_y.SetSize(p + 1);
8298 #endif
8299 
8300  if (p == 0)
8301  {
8302  Nodes.IntPoint(0).Set2(0.5, 0.5);
8303  }
8304  else
8305  {
8306  for (int o = 0, j = 0; j <= p; j++)
8307  for (int i = 0; i <= p; i++)
8308  {
8309  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8310  }
8311  }
8312 }
8313 
8315  Vector &shape) const
8316 {
8317  const int p = Order;
8318 
8319 #ifdef MFEM_THREAD_SAFE
8320  Vector shape_x(p+1), shape_y(p+1);
8321 #endif
8322 
8323  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8324  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8325 
8326  for (int o = 0, j = 0; j <= p; j++)
8327  for (int i = 0; i <= p; i++)
8328  {
8329  shape(o++) = shape_x(i)*shape_y(j);
8330  }
8331 }
8332 
8334  DenseMatrix &dshape) const
8335 {
8336  const int p = Order;
8337 
8338 #ifdef MFEM_THREAD_SAFE
8339  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8340 #endif
8341 
8342  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8343  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8344 
8345  for (int o = 0, j = 0; j <= p; j++)
8346  for (int i = 0; i <= p; i++)
8347  {
8348  dshape(o,0) = dshape_x(i)* shape_y(j);
8349  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8350  }
8351 }
8352 
8354 {
8355  const int p = Order;
8356 
8357  dofs = 0.0;
8358  switch (vertex)
8359  {
8360  case 0: dofs[0] = 1.0; break;
8361  case 1: dofs[p] = 1.0; break;
8362  case 2: dofs[p*(p + 2)] = 1.0; break;
8363  case 3: dofs[p*(p + 1)] = 1.0; break;
8364  }
8365 }
8366 
8367 
8368 L2_HexahedronElement::L2_HexahedronElement(const int p, const int _type)
8369  : NodalFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
8370  FunctionSpace::Qk),
8371  type(VerifyOpen(_type)),
8372  basis1d(poly1d.OpenBasis(p, type))
8373 {
8374  const double *op = poly1d.OpenPoints(p, type);
8375 
8376 #ifndef MFEM_THREAD_SAFE
8377  shape_x.SetSize(p + 1);
8378  shape_y.SetSize(p + 1);
8379  shape_z.SetSize(p + 1);
8380  dshape_x.SetSize(p + 1);
8381  dshape_y.SetSize(p + 1);
8382  dshape_z.SetSize(p + 1);
8383 #endif
8384 
8385  for (int o = 0, k = 0; k <= p; k++)
8386  for (int j = 0; j <= p; j++)
8387  for (int i = 0; i <= p; i++)
8388  {
8389  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
8390  }
8391 }
8392 
8394  Vector &shape) const
8395 {
8396  const int p = Order;
8397 
8398 #ifdef MFEM_THREAD_SAFE
8399  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8400 #endif
8401 
8402  basis1d.Eval(ip.x, shape_x);
8403  basis1d.Eval(ip.y, shape_y);
8404  basis1d.Eval(ip.z, shape_z);
8405 
8406  for (int o = 0, k = 0; k <= p; k++)
8407  for (int j = 0; j <= p; j++)
8408  for (int i = 0; i <= p; i++)
8409  {
8410  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8411  }
8412 }
8413 
8415  DenseMatrix &dshape) const
8416 {
8417  const int p = Order;
8418 
8419 #ifdef MFEM_THREAD_SAFE
8420  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8421  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8422 #endif
8423 
8424  basis1d.Eval(ip.x, shape_x, dshape_x);
8425  basis1d.Eval(ip.y, shape_y, dshape_y);
8426  basis1d.Eval(ip.z, shape_z, dshape_z);
8427 
8428  for (int o = 0, k = 0; k <= p; k++)
8429  for (int j = 0; j <= p; j++)
8430  for (int i = 0; i <= p; i++)
8431  {
8432  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8433  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8434  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8435  }
8436 }
8437 
8438 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8439 {
8440  const int p = Order;
8441  const double *op = poly1d.OpenPoints(p, type);
8442 
8443 #ifdef MFEM_THREAD_SAFE
8444  Vector shape_x(p+1), shape_y(p+1);
8445 #endif
8446 
8447  for (int i = 0; i <= p; i++)
8448  {
8449  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8450  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8451  }
8452 
8453  switch (vertex)
8454  {
8455  case 0:
8456  for (int o = 0, k = 0; k <= p; k++)
8457  for (int j = 0; j <= p; j++)
8458  for (int i = 0; i <= p; i++)
8459  {
8460  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
8461  }
8462  break;
8463  case 1:
8464  for (int o = 0, k = 0; k <= p; k++)
8465  for (int j = 0; j <= p; j++)
8466  for (int i = 0; i <= p; i++)
8467  {
8468  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
8469  }
8470  break;
8471  case 2:
8472  for (int o = 0, k = 0; k <= p; k++)
8473  for (int j = 0; j <= p; j++)
8474  for (int i = 0; i <= p; i++)
8475  {
8476  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
8477  }
8478  break;
8479  case 3:
8480  for (int o = 0, k = 0; k <= p; k++)
8481  for (int j = 0; j <= p; j++)
8482  for (int i = 0; i <= p; i++)
8483  {
8484  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
8485  }
8486  break;
8487  case 4:
8488  for (int o = 0, k = 0; k <= p; k++)
8489  for (int j = 0; j <= p; j++)
8490  for (int i = 0; i <= p; i++)
8491  {
8492  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
8493  }
8494  break;
8495  case 5:
8496  for (int o = 0, k = 0; k <= p; k++)
8497  for (int j = 0; j <= p; j++)
8498  for (int i = 0; i <= p; i++)
8499  {
8500  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
8501  }
8502  break;
8503  case 6:
8504  for (int o = 0, k = 0; k <= p; k++)
8505  for (int j = 0; j <= p; j++)
8506  for (int i = 0; i <= p; i++)
8507  {
8508  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
8509  }
8510  break;
8511  case 7:
8512  for (int o = 0, k = 0; k <= p; k++)
8513  for (int j = 0; j <= p; j++)
8514  for (int i = 0; i <= p; i++)
8515  {
8516  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
8517  }
8518  break;
8519  }
8520 }
8521 
8522 
8524  : PositiveFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
8525  FunctionSpace::Qk)
8526 {
8527 #ifndef MFEM_THREAD_SAFE
8528  shape_x.SetSize(p + 1);
8529  shape_y.SetSize(p + 1);
8530  shape_z.SetSize(p + 1);
8531  dshape_x.SetSize(p + 1);
8532  dshape_y.SetSize(p + 1);
8533  dshape_z.SetSize(p + 1);
8534 #endif
8535 
8536  if (p == 0)
8537  {
8538  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
8539  }
8540  else
8541  {
8542  for (int o = 0, k = 0; k <= p; k++)
8543  for (int j = 0; j <= p; j++)
8544  for (int i = 0; i <= p; i++)
8545  {
8546  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8547  }
8548  }
8549 }
8550 
8552  Vector &shape) const
8553 {
8554  const int p = Order;
8555 
8556 #ifdef MFEM_THREAD_SAFE
8557  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8558 #endif
8559 
8560  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8561  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8562  Poly_1D::CalcBernstein(p, ip.z, shape_z);
8563 
8564  for (int o = 0, k = 0; k <= p; k++)
8565  for (int j = 0; j <= p; j++)
8566  for (int i = 0; i <= p; i++)
8567  {
8568  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8569  }
8570 }
8571 
8573  DenseMatrix &dshape) const
8574 {
8575  const int p = Order;
8576 
8577 #ifdef MFEM_THREAD_SAFE
8578  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8579  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8580 #endif
8581 
8582  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8583  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8584  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
8585 
8586  for (int o = 0, k = 0; k <= p; k++)
8587  for (int j = 0; j <= p; j++)
8588  for (int i = 0; i <= p; i++)
8589  {
8590  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8591  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8592  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8593  }
8594 }
8595 
8596 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8597 {
8598  const int p = Order;
8599 
8600  dofs = 0.0;
8601  switch (vertex)
8602  {
8603  case 0: dofs[0] = 1.0; break;
8604  case 1: dofs[p] = 1.0; break;
8605  case 2: dofs[p*(p + 2)] = 1.0; break;
8606  case 3: dofs[p*(p + 1)] = 1.0; break;
8607  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
8608  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
8609  case 6: dofs[Dof - 1] = 1.0; break;
8610  case 7: dofs[Dof - p - 1] = 1.0; break;
8611  }
8612 }
8613 
8614 
8615 L2_TriangleElement::L2_TriangleElement(const int p, const int type)
8616  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8617  FunctionSpace::Pk)
8618 {
8619  const double *op = poly1d.OpenPoints(p, VerifyOpen(type));
8620 
8621 #ifndef MFEM_THREAD_SAFE
8622  shape_x.SetSize(p + 1);
8623  shape_y.SetSize(p + 1);
8624  shape_l.SetSize(p + 1);
8625  dshape_x.SetSize(p + 1);
8626  dshape_y.SetSize(p + 1);
8627  dshape_l.SetSize(p + 1);
8628  u.SetSize(Dof);
8629  du.SetSize(Dof, Dim);
8630 #else
8631  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8632 #endif
8633 
8634  for (int o = 0, j = 0; j <= p; j++)
8635  for (int i = 0; i + j <= p; i++)
8636  {
8637  double w = op[i] + op[j] + op[p-i-j];
8638  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
8639  }
8640 
8641  DenseMatrix T(Dof);
8642  for (int k = 0; k < Dof; k++)
8643  {
8644  IntegrationPoint &ip = Nodes.IntPoint(k);
8645  poly1d.CalcBasis(p, ip.x, shape_x);
8646  poly1d.CalcBasis(p, ip.y, shape_y);
8647  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8648 
8649  for (int o = 0, j = 0; j <= p; j++)
8650  for (int i = 0; i + j <= p; i++)
8651  {
8652  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8653  }
8654  }
8655 
8656  Ti.Factor(T);
8657  // cout << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
8658 }
8659 
8661  Vector &shape) const
8662 {
8663  const int p = Order;
8664 
8665 #ifdef MFEM_THREAD_SAFE
8666  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
8667 #endif
8668 
8669  poly1d.CalcBasis(p, ip.x, shape_x);
8670  poly1d.CalcBasis(p, ip.y, shape_y);
8671  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8672 
8673  for (int o = 0, j = 0; j <= p; j++)
8674  for (int i = 0; i + j <= p; i++)
8675  {
8676  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8677  }
8678 
8679  Ti.Mult(u, shape);
8680 }
8681 
8683  DenseMatrix &dshape) const
8684 {
8685  const int p = Order;
8686 
8687 #ifdef MFEM_THREAD_SAFE
8688  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8689  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8690  DenseMatrix du(Dof, Dim);
8691 #endif
8692 
8693  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8694  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8695  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
8696 
8697  for (int o = 0, j = 0; j <= p; j++)
8698  for (int i = 0; i + j <= p; i++)
8699  {
8700  int k = p - i - j;
8701  du(o,0) = ((dshape_x(i)* shape_l(k)) -
8702  ( shape_x(i)*dshape_l(k)))*shape_y(j);
8703  du(o,1) = ((dshape_y(j)* shape_l(k)) -
8704  ( shape_y(j)*dshape_l(k)))*shape_x(i);
8705  o++;
8706  }
8707 
8708  Ti.Mult(du, dshape);
8709 }
8710 
8711 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8712 {
8713  switch (vertex)
8714  {
8715  case 0:
8716  for (int i = 0; i < Dof; i++)
8717  {
8718  const IntegrationPoint &ip = Nodes.IntPoint(i);
8719  dofs[i] = pow(1.0 - ip.x - ip.y, Order);
8720  }
8721  break;
8722  case 1:
8723  for (int i = 0; i < Dof; i++)
8724  {
8725  const IntegrationPoint &ip = Nodes.IntPoint(i);
8726  dofs[i] = pow(ip.x, Order);
8727  }
8728  break;
8729  case 2:
8730  for (int i = 0; i < Dof; i++)
8731  {
8732  const IntegrationPoint &ip = Nodes.IntPoint(i);
8733  dofs[i] = pow(ip.y, Order);
8734  }
8735  break;
8736  }
8737 }
8738 
8739 
8741  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8742  FunctionSpace::Pk)
8743 {
8744 #ifndef MFEM_THREAD_SAFE
8745  dshape_1d.SetSize(p + 1);
8746 #endif
8747 
8748  if (p == 0)
8749  {
8750  Nodes.IntPoint(0).Set2(1./3, 1./3);
8751  }
8752  else
8753  {
8754  for (int o = 0, j = 0; j <= p; j++)
8755  for (int i = 0; i + j <= p; i++)
8756  {
8757  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8758  }
8759  }
8760 }
8761 
8763  Vector &shape) const
8764 {
8765  H1Pos_TriangleElement::CalcShape(Order, ip.x, ip.y, shape.GetData());
8766 }
8767 
8769  DenseMatrix &dshape) const
8770 {
8771 #ifdef MFEM_THREAD_SAFE
8772  Vector dshape_1d(Order + 1);
8773 #endif
8774 
8775  H1Pos_TriangleElement::CalcDShape(Order, ip.x, ip.y, dshape_1d.GetData(),
8776  dshape.Data());
8777 }
8778 
8779 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8780 {
8781  dofs = 0.0;
8782  switch (vertex)
8783  {
8784  case 0: dofs[0] = 1.0; break;
8785  case 1: dofs[Order] = 1.0; break;
8786  case 2: dofs[Dof-1] = 1.0; break;
8787  }
8788 }
8789 
8790 
8792  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
8793  p, FunctionSpace::Pk)
8794 {
8795  const double *op = poly1d.OpenPoints(p, VerifyOpen(type));
8796 
8797 #ifndef MFEM_THREAD_SAFE
8798  shape_x.SetSize(p + 1);
8799  shape_y.SetSize(p + 1);
8800  shape_z.SetSize(p + 1);
8801  shape_l.SetSize(p + 1);
8802  dshape_x.SetSize(p + 1);
8803  dshape_y.SetSize(p + 1);
8804  dshape_z.SetSize(p + 1);
8805  dshape_l.SetSize(p + 1);
8806  u.SetSize(Dof);
8807  du.SetSize(Dof, Dim);
8808 #else
8809  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8810 #endif
8811 
8812  for (int o = 0, k = 0; k <= p; k++)
8813  for (int j = 0; j + k <= p; j++)
8814  for (int i = 0; i + j + k <= p; i++)
8815  {
8816  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
8817  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
8818  }
8819 
8820  DenseMatrix T(Dof);
8821  for (int m = 0; m < Dof; m++)
8822  {
8823  IntegrationPoint &ip = Nodes.IntPoint(m);
8824  poly1d.CalcBasis(p, ip.x, shape_x);
8825  poly1d.CalcBasis(p, ip.y, shape_y);
8826  poly1d.CalcBasis(p, ip.z, shape_z);
8827  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8828 
8829  for (int o = 0, k = 0; k <= p; k++)
8830  for (int j = 0; j + k <= p; j++)
8831  for (int i = 0; i + j + k <= p; i++)
8832  {
8833  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8834  }
8835  }
8836 
8837  Ti.Factor(T);
8838  // cout << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8839 }
8840 
8842  Vector &shape) const
8843 {
8844  const int p = Order;
8845 
8846 #ifdef MFEM_THREAD_SAFE
8847  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8848  Vector u(Dof);
8849 #endif
8850 
8851  poly1d.CalcBasis(p, ip.x, shape_x);
8852  poly1d.CalcBasis(p, ip.y, shape_y);
8853  poly1d.CalcBasis(p, ip.z, shape_z);
8854  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8855 
8856  for (int o = 0, k = 0; k <= p; k++)
8857  for (int j = 0; j + k <= p; j++)
8858  for (int i = 0; i + j + k <= p; i++)
8859  {
8860  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8861  }
8862 
8863  Ti.Mult(u, shape);
8864 }
8865 
8867  DenseMatrix &dshape) const
8868 {
8869  const int p = Order;
8870 
8871 #ifdef MFEM_THREAD_SAFE
8872  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8873  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8874  DenseMatrix du(Dof, Dim);
8875 #endif
8876 
8877  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8878  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8879  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
8880  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
8881 
8882  for (int o = 0, k = 0; k <= p; k++)
8883  for (int j = 0; j + k <= p; j++)
8884  for (int i = 0; i + j + k <= p; i++)
8885  {
8886  int l = p - i - j - k;
8887  du(o,0) = ((dshape_x(i)* shape_l(l)) -
8888  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
8889  du(o,1) = ((dshape_y(j)* shape_l(l)) -
8890  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
8891  du(o,2) = ((dshape_z(k)* shape_l(l)) -
8892  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
8893  o++;
8894  }
8895 
8896  Ti.Mult(du, dshape);
8897 }
8898 
8899 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8900 {
8901  switch (vertex)
8902  {
8903  case 0:
8904  for (int i = 0; i < Dof; i++)
8905  {
8906  const IntegrationPoint &ip = Nodes.IntPoint(i);
8907  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, Order);
8908  }
8909  break;
8910  case 1:
8911  for (int i = 0; i < Dof; i++)
8912  {
8913  const IntegrationPoint &ip = Nodes.IntPoint(i);
8914  dofs[i] = pow(ip.x, Order);
8915  }
8916  break;
8917  case 2:
8918  for (int i = 0; i < Dof; i++)
8919  {
8920  const IntegrationPoint &ip = Nodes.IntPoint(i);
8921  dofs[i] = pow(ip.y, Order);
8922  }
8923  case 3:
8924  for (int i = 0; i < Dof; i++)
8925  {
8926  const IntegrationPoint &ip = Nodes.IntPoint(i);
8927  dofs[i] = pow(ip.z, Order);
8928  }
8929  break;
8930  }
8931 }
8932 
8933 
8935  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
8936  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
8937 {
8938 #ifndef MFEM_THREAD_SAFE
8939  dshape_1d.SetSize(p + 1);
8940 #endif
8941 
8942  if (p == 0)
8943  {
8944  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
8945  }
8946  else
8947  {
8948  for (int o = 0, k = 0; k <= p; k++)
8949  for (int j = 0; j + k <= p; j++)
8950  for (int i = 0; i + j + k <= p; i++)
8951  {
8952  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8953  }
8954  }
8955 }
8956 
8958  Vector &shape) const
8959 {
8961  shape.GetData());
8962 }
8963 
8965  DenseMatrix &dshape) const
8966 {
8967 #ifdef MFEM_THREAD_SAFE
8968  Vector dshape_1d(Order + 1);
8969 #endif
8970 
8972  dshape_1d.GetData(), dshape.Data());
8973 }
8974 
8975 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8976 {
8977  dofs = 0.0;
8978  switch (vertex)
8979  {
8980  case 0: dofs[0] = 1.0; break;
8981  case 1: dofs[Order] = 1.0; break;
8982  case 2: dofs[(Order*(Order+3))/2] = 1.0; break;
8983  case 3: dofs[Dof-1] = 1.0; break;
8984  }
8985 }
8986 
8987 
8988 const double RT_QuadrilateralElement::nk[8] =
8989 { 0., -1., 1., 0., 0., 1., -1., 0. };
8990 
8992  const int cp_type,
8993  const int op_type)
8994  : VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p + 1,
8995  H_DIV, FunctionSpace::Qk),
8996  cbasis1d(poly1d.ClosedBasis(p + 1, VerifyClosed(cp_type))),
8997  obasis1d(poly1d.OpenBasis(p, VerifyOpen(op_type))),
8998  dof_map(Dof), dof2nk(Dof)
8999 {
9000  const double *cp = poly1d.ClosedPoints(p + 1, cp_type);
9001  const double *op = poly1d.OpenPoints(p, op_type);
9002  const int dof2 = Dof/2;
9003 
9004 #ifndef MFEM_THREAD_SAFE
9005  shape_cx.SetSize(p + 2);
9006  shape_ox.SetSize(p + 1);
9007  shape_cy.SetSize(p + 2);
9008  shape_oy.SetSize(p + 1);
9009  dshape_cx.SetSize(p + 2);
9010  dshape_cy.SetSize(p + 2);
9011 #endif
9012 
9013  // edges
9014  int o = 0;
9015  for (int i = 0; i <= p; i++) // (0,1)
9016  {
9017  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
9018  }
9019  for (int i = 0; i <= p; i++) // (1,2)
9020  {
9021  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
9022  }
9023  for (int i = 0; i <= p; i++) // (2,3)
9024  {
9025  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
9026  }
9027  for (int i = 0; i <= p; i++) // (3,0)
9028  {
9029  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
9030  }
9031 
9032  // interior
9033  for (int j = 0; j <= p; j++) // x-components
9034  for (int i = 1; i <= p; i++)
9035  {
9036  dof_map[0*dof2 + i + j*(p + 2)] = o++;
9037  }
9038  for (int j = 1; j <= p; j++) // y-components
9039  for (int i = 0; i <= p; i++)
9040  {
9041  dof_map[1*dof2 + i + j*(p + 1)] = o++;
9042  }
9043 
9044  // dof orientations
9045  // x-components
9046  for (int j = 0; j <= p; j++)
9047  for (int i = 0; i <= p/2; i++)
9048  {
9049  int idx = 0*dof2 + i + j*(p + 2);
9050  dof_map[idx] = -1 - dof_map[idx];
9051  }
9052  if (p%2 == 1)
9053  for (int j = p/2 + 1; j <= p; j++)
9054  {
9055  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
9056  dof_map[idx] = -1 - dof_map[idx];
9057  }
9058  // y-components
9059  for (int j = 0; j <= p/2; j++)
9060  for (int i = 0; i <= p; i++)
9061  {
9062  int idx = 1*dof2 + i + j*(p + 1);
9063  dof_map[idx] = -1 - dof_map[idx];
9064  }
9065  if (p%2 == 1)
9066  for (int i = 0; i <= p/2; i++)
9067  {
9068  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
9069  dof_map[idx] = -1 - dof_map[idx];
9070  }
9071 
9072  o = 0;
9073  for (int j = 0; j <= p; j++)
9074  for (int i = 0; i <= p + 1; i++)
9075  {
9076  int idx;
9077  if ((idx = dof_map[o++]) < 0)
9078  {
9079  idx = -1 - idx;
9080  dof2nk[idx] = 3;
9081  }
9082  else
9083  {
9084  dof2nk[idx] = 1;
9085  }
9086  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
9087  }
9088  for (int j = 0; j <= p + 1; j++)
9089  for (int i = 0; i <= p; i++)
9090  {
9091  int idx;
9092  if ((idx = dof_map[o++]) < 0)
9093  {
9094  idx = -1 - idx;
9095  dof2nk[idx] = 0;
9096  }
9097  else
9098  {
9099  dof2nk[idx] = 2;
9100  }
9101  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
9102  }
9103 }
9104 
9106  DenseMatrix &shape) const
9107 {
9108  const int pp1 = Order;
9109 
9110 #ifdef MFEM_THREAD_SAFE
9111  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9112 #endif
9113 
9114  cbasis1d.Eval(ip.x, shape_cx);
9115  obasis1d.Eval(ip.x, shape_ox);
9116  cbasis1d.Eval(ip.y, shape_cy);
9117  obasis1d.Eval(ip.y, shape_oy);
9118 
9119  int o = 0;
9120  for (int j = 0; j < pp1; j++)
9121  for (int i = 0; i <= pp1; i++)
9122  {
9123  int idx, s;
9124  if ((idx = dof_map[o++]) < 0)
9125  {
9126  idx = -1 - idx, s = -1;
9127  }
9128  else
9129  {
9130  s = +1;
9131  }
9132  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
9133  shape(idx,1) = 0.;
9134  }
9135  for (int j = 0; j <= pp1; j++)
9136  for (int i = 0; i < pp1; i++)
9137  {
9138  int idx, s;
9139  if ((idx = dof_map[o++]) < 0)
9140  {
9141  idx = -1 - idx, s = -1;
9142  }
9143  else
9144  {
9145  s = +1;
9146  }
9147  shape(idx,0) = 0.;
9148  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
9149  }
9150 }
9151 
9153  Vector &divshape) const
9154 {
9155  const int pp1 = Order;
9156 
9157 #ifdef MFEM_THREAD_SAFE
9158  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9159  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
9160 #endif
9161 
9162  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9163  obasis1d.Eval(ip.x, shape_ox);
9164  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9165  obasis1d.Eval(ip.y, shape_oy);
9166 
9167  int o = 0;
9168  for (int j = 0; j < pp1; j++)
9169  for (int i = 0; i <= pp1; i++)
9170  {
9171  int idx, s;
9172  if ((idx = dof_map[o++]) < 0)
9173  {
9174  idx = -1 - idx, s = -1;
9175  }
9176  else
9177  {
9178  s = +1;
9179  }
9180  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
9181  }
9182  for (int j = 0; j <= pp1; j++)
9183  for (int i = 0; i < pp1; i++)
9184  {
9185  int idx, s;
9186  if ((idx = dof_map[o++]) < 0)
9187  {
9188  idx = -1 - idx, s = -1;
9189  }
9190  else
9191  {
9192  s = +1;
9193  }
9194  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
9195  }
9196 }
9197 
9198 
9199 const double RT_HexahedronElement::nk[18] =
9200 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
9201 
9203  const int cp_type,
9204  const int op_type)
9205  : VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 1)*(p + 2), p + 1,
9206  H_DIV, FunctionSpace::Qk),
9207  cbasis1d(poly1d.ClosedBasis(p + 1, VerifyClosed(cp_type))),
9208  obasis1d(poly1d.OpenBasis(p, VerifyOpen(op_type))),
9209  dof_map(Dof), dof2nk(Dof)
9210 {
9211  const double *cp = poly1d.ClosedPoints(p + 1, cp_type);
9212  const double *op = poly1d.OpenPoints(p, op_type);
9213  const int dof3 = Dof/3;
9214 
9215 #ifndef MFEM_THREAD_SAFE
9216  shape_cx.SetSize(p + 2);
9217  shape_ox.SetSize(p + 1);
9218  shape_cy.SetSize(p + 2);
9219  shape_oy.SetSize(p + 1);
9220  shape_cz.SetSize(p + 2);
9221  shape_oz.SetSize(p + 1);
9222  dshape_cx.SetSize(p + 2);
9223  dshape_cy.SetSize(p + 2);
9224  dshape_cz.SetSize(p + 2);
9225 #endif
9226 
9227  // faces
9228  int o = 0;
9229  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
9230  for (int i = 0; i <= p; i++)
9231  {
9232  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
9233  }
9234  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
9235  for (int i = 0; i <= p; i++)
9236  {
9237  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
9238  }
9239  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
9240  for (int i = 0; i <= p; i++)
9241  {
9242  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
9243  }
9244  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
9245  for (int i = 0; i <= p; i++)
9246  {
9247  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
9248  }
9249  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
9250  for (int i = 0; i <= p; i++)
9251  {
9252  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
9253  }
9254  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
9255  for (int i = 0; i <= p; i++)
9256  {
9257  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
9258  }
9259 
9260  // interior
9261  // x-components
9262  for (int k = 0; k <= p; k++)
9263  for (int j = 0; j <= p; j++)
9264  for (int i = 1; i <= p; i++)
9265  {
9266  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
9267  }
9268  // y-components
9269  for (int k = 0; k <= p; k++)
9270  for (int j = 1; j <= p; j++)
9271  for (int i = 0; i <= p; i++)
9272  {
9273  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
9274  }
9275  // z-components
9276  for (int k = 1; k <= p; k++)
9277  for (int j = 0; j <= p; j++)
9278  for (int i = 0; i <= p; i++)
9279  {
9280  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
9281  }
9282 
9283  // dof orientations
9284  // for odd p, do not change the orientations in the mid-planes
9285  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
9286  // respectively.
9287  // x-components
9288  for (int k = 0; k <= p; k++)
9289  for (int j = 0; j <= p; j++)
9290  for (int i = 0; i <= p/2; i++)
9291  {
9292  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
9293  dof_map[idx] = -1 - dof_map[idx];
9294  }
9295  // y-components
9296  for (int k = 0; k <= p; k++)
9297  for (int j = 0; j <= p/2; j++)
9298  for (int i = 0; i <= p; i++)
9299  {
9300  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
9301  dof_map[idx] = -1 - dof_map[idx];
9302  }
9303  // z-components
9304  for (int k = 0; k <= p/2; k++)
9305  for (int j = 0; j <= p; j++)
9306  for (int i = 0; i <= p; i++)
9307  {
9308  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
9309  dof_map[idx] = -1 - dof_map[idx];
9310  }
9311 
9312  o = 0;
9313  // x-components
9314  for (int k = 0; k <= p; k++)
9315  for (int j = 0; j <= p; j++)
9316  for (int i = 0; i <= p + 1; i++)
9317  {
9318  int idx;
9319  if ((idx = dof_map[o++]) < 0)
9320  {
9321  idx = -1 - idx;
9322  dof2nk[idx] = 4;
9323  }
9324  else
9325  {
9326  dof2nk[idx] = 2;
9327  }
9328  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
9329  }
9330  // y-components
9331  for (int k = 0; k <= p; k++)
9332  for (int j = 0; j <= p + 1; j++)
9333  for (int i = 0; i <= p; i++)
9334  {
9335  int idx;
9336  if ((idx = dof_map[o++]) < 0)
9337  {
9338  idx = -1 - idx;
9339  dof2nk[idx] = 1;
9340  }
9341  else
9342  {
9343  dof2nk[idx] = 3;
9344  }
9345  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
9346  }
9347  // z-components
9348  for (int k = 0; k <= p + 1; k++)
9349  for (int j = 0; j <= p; j++)
9350  for (int i = 0; i <= p; i++)
9351  {
9352  int idx;
9353  if ((idx = dof_map[o++]) < 0)
9354  {
9355  idx = -1 - idx;
9356  dof2nk[idx] = 0;
9357  }
9358  else
9359  {
9360  dof2nk[idx] = 5;
9361  }
9362  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
9363  }
9364 }
9365 
9367  DenseMatrix &shape) const
9368 {
9369  const int pp1 = Order;
9370 
9371 #ifdef MFEM_THREAD_SAFE
9372  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9373  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9374 #endif
9375 
9376  cbasis1d.Eval(ip.x, shape_cx);
9377  obasis1d.Eval(ip.x, shape_ox);
9378  cbasis1d.Eval(ip.y, shape_cy);
9379  obasis1d.Eval(ip.y, shape_oy);
9380  cbasis1d.Eval(ip.z, shape_cz);
9381  obasis1d.Eval(ip.z, shape_oz);
9382 
9383  int o = 0;
9384  // x-components
9385  for (int k = 0; k < pp1; k++)
9386  for (int j = 0; j < pp1; j++)
9387  for (int i = 0; i <= pp1; i++)
9388  {
9389  int idx, s;
9390  if ((idx = dof_map[o++]) < 0)
9391  {
9392  idx = -1 - idx, s = -1;
9393  }
9394  else
9395  {
9396  s = +1;
9397  }
9398  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
9399  shape(idx,1) = 0.;
9400  shape(idx,2) = 0.;
9401  }
9402  // y-components
9403  for (int k = 0; k < pp1; k++)
9404  for (int j = 0; j <= pp1; j++)
9405  for (int i = 0; i < pp1; i++)
9406  {
9407  int idx, s;
9408  if ((idx = dof_map[o++]) < 0)
9409  {
9410  idx = -1 - idx, s = -1;
9411  }
9412  else
9413  {
9414  s = +1;
9415  }
9416  shape(idx,0) = 0.;
9417  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
9418  shape(idx,2) = 0.;
9419  }
9420  // z-components
9421  for (int k = 0; k <= pp1; k++)
9422  for (int j = 0; j < pp1; j++)
9423  for (int i = 0; i < pp1; i++)
9424  {
9425  int idx, s;
9426  if ((idx = dof_map[o++]) < 0)
9427  {
9428  idx = -1 - idx, s = -1;
9429  }
9430  else
9431  {
9432  s = +1;
9433  }
9434  shape(idx,0) = 0.;
9435  shape(idx,1) = 0.;
9436  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
9437  }
9438 }
9439 
9441  Vector &divshape) const
9442 {
9443  const int pp1 = Order;
9444 
9445 #ifdef MFEM_THREAD_SAFE
9446  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9447  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9448  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
9449 #endif
9450 
9451  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9452  obasis1d.Eval(ip.x, shape_ox);
9453  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9454  obasis1d.Eval(ip.y, shape_oy);
9455  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
9456  obasis1d.Eval(ip.z, shape_oz);
9457 
9458  int o = 0;
9459  // x-components
9460  for (int k = 0; k < pp1; k++)
9461  for (int j = 0; j < pp1; j++)
9462  for (int i = 0; i <= pp1; i++)
9463  {
9464  int idx, s;
9465  if ((idx = dof_map[o++]) < 0)
9466  {
9467  idx = -1 - idx, s = -1;
9468  }
9469  else
9470  {
9471  s = +1;
9472  }
9473  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
9474  }
9475  // y-components
9476  for (int k = 0; k < pp1; k++)
9477  for (int j = 0; j <= pp1; j++)
9478  for (int i = 0; i < pp1; i++)
9479  {
9480  int idx, s;
9481  if ((idx = dof_map[o++]) < 0)
9482  {
9483  idx = -1 - idx, s = -1;
9484  }
9485  else
9486  {
9487  s = +1;
9488  }
9489  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
9490  }
9491  // z-components
9492  for (int k = 0; k <= pp1; k++)
9493  for (int j = 0; j < pp1; j++)
9494  for (int i = 0; i < pp1; i++)
9495  {
9496  int idx, s;
9497  if ((idx = dof_map[o++]) < 0)
9498  {
9499  idx = -1 - idx, s = -1;
9500  }
9501  else
9502  {
9503  s = +1;
9504  }
9505  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
9506  }
9507 }
9508 
9509 
9510 const double RT_TriangleElement::nk[6] =
9511 { 0., -1., 1., 1., -1., 0. };
9512 
9513 const double RT_TriangleElement::c = 1./3.;
9514 
9516  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
9517  H_DIV, FunctionSpace::Pk),
9518  dof2nk(Dof)
9519 {
9520  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9521  const double *bop = poly1d.OpenPoints(p);
9522 
9523 #ifndef MFEM_THREAD_SAFE
9524  shape_x.SetSize(p + 1);
9525  shape_y.SetSize(p + 1);
9526  shape_l.SetSize(p + 1);
9527  dshape_x.SetSize(p + 1);
9528  dshape_y.SetSize(p + 1);
9529  dshape_l.SetSize(p + 1);
9530  u.SetSize(Dof, Dim);
9531  divu.SetSize(Dof);
9532 #else
9533  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9534 #endif
9535 
9536  // edges
9537  int o = 0;
9538  for (int i = 0; i <= p; i++) // (0,1)
9539  {
9540  Nodes.IntPoint(o).Set2(bop[i], 0.);
9541  dof2nk[o++] = 0;
9542  }
9543  for (int i = 0; i <= p; i++) // (1,2)
9544  {
9545  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
9546  dof2nk[o++] = 1;
9547  }
9548  for (int i = 0; i <= p; i++) // (2,0)
9549  {
9550  Nodes.IntPoint(o).Set2(0., bop[p-i]);
9551  dof2nk[o++] = 2;
9552  }
9553 
9554  // interior
9555  for (int j = 0; j < p; j++)
9556  for (int i = 0; i + j < p; i++)
9557  {
9558  double w = iop[i] + iop[j] + iop[p-1-i-j];
9559  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9560  dof2nk[o++] = 0;
9561  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9562  dof2nk[o++] = 2;
9563  }
9564 
9565  DenseMatrix T(Dof);
9566  for (int k = 0; k < Dof; k++)
9567  {
9568  const IntegrationPoint &ip = Nodes.IntPoint(k);
9569  poly1d.CalcBasis(p, ip.x, shape_x);
9570  poly1d.CalcBasis(p, ip.y, shape_y);
9571  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9572  const double *n_k = nk + 2*dof2nk[k];
9573 
9574  o = 0;
9575  for (int j = 0; j <= p; j++)
9576  for (int i = 0; i + j <= p; i++)
9577  {
9578  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9579  T(o++, k) = s*n_k[0];
9580  T(o++, k) = s*n_k[1];
9581  }
9582  for (int i = 0; i <= p; i++)
9583  {
9584  double s = shape_x(i)*shape_y(p-i);
9585  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
9586  }
9587  }
9588 
9589  Ti.Factor(T);
9590  // cout << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
9591 }
9592 
9594  DenseMatrix &shape) const
9595 {
9596  const int p = Order - 1;
9597 
9598 #ifdef MFEM_THREAD_SAFE
9599  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9600  DenseMatrix u(Dof, Dim);
9601 #endif
9602 
9603  poly1d.CalcBasis(p, ip.x, shape_x);
9604  poly1d.CalcBasis(p, ip.y, shape_y);
9605  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9606 
9607  int o = 0;
9608  for (int j = 0; j <= p; j++)
9609  for (int i = 0; i + j <= p; i++)
9610  {
9611  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9612  u(o,0) = s; u(o,1) = 0; o++;
9613  u(o,0) = 0; u(o,1) = s; o++;
9614  }
9615  for (int i = 0; i <= p; i++)
9616  {
9617  double s = shape_x(i)*shape_y(p-i);
9618  u(o,0) = (ip.x - c)*s;
9619  u(o,1) = (ip.y - c)*s;
9620  o++;
9621  }
9622 
9623  Ti.Mult(u, shape);
9624 }
9625 
9627  Vector &divshape) const
9628 {
9629  const int p = Order - 1;
9630 
9631 #ifdef MFEM_THREAD_SAFE
9632  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9633  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
9634  Vector divu(Dof);
9635 #endif
9636 
9637  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9638  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9639  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
9640 
9641  int o = 0;
9642  for (int j = 0; j <= p; j++)
9643  for (int i = 0; i + j <= p; i++)
9644  {
9645  int k = p - i - j;
9646  divu(o++) = (dshape_x(i)*shape_l(k) -
9647  shape_x(i)*dshape_l(k))*shape_y(j);
9648  divu(o++) = (dshape_y(j)*shape_l(k) -
9649  shape_y(j)*dshape_l(k))*shape_x(i);
9650  }
9651  for (int i = 0; i <= p; i++)
9652  {
9653  int j = p - i;
9654  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
9655  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
9656  }
9657 
9658  Ti.Mult(divu, divshape);
9659 }
9660 
9661 
9662 const double RT_TetrahedronElement::nk[12] =
9663 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
9664 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
9665 
9666 const double RT_TetrahedronElement::c = 1./4.;
9667 
9669  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
9670  p + 1, H_DIV, FunctionSpace::Pk),
9671  dof2nk(Dof)
9672 {
9673  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9674  const double *bop = poly1d.OpenPoints(p);
9675 
9676 #ifndef MFEM_THREAD_SAFE
9677  shape_x.SetSize(p + 1);
9678  shape_y.SetSize(p + 1);
9679  shape_z.SetSize(p + 1);
9680  shape_l.SetSize(p + 1);
9681  dshape_x.SetSize(p + 1);
9682  dshape_y.SetSize(p + 1);
9683  dshape_z.SetSize(p + 1);
9684  dshape_l.SetSize(p + 1);
9685  u.SetSize(Dof, Dim);
9686  divu.SetSize(Dof);
9687 #else
9688  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9689 #endif
9690 
9691  int o = 0;
9692  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
9693  // the constructor of H1_TetrahedronElement)
9694  for (int j = 0; j <= p; j++)
9695  for (int i = 0; i + j <= p; i++) // (1,2,3)
9696  {
9697  double w = bop[i] + bop[j] + bop[p-i-j];
9698  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
9699  dof2nk[o++] = 0;
9700  }
9701  for (int j = 0; j <= p; j++)
9702  for (int i = 0; i + j <= p; i++) // (0,3,2)
9703  {
9704  double w = bop[i] + bop[j] + bop[p-i-j];
9705  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
9706  dof2nk[o++] = 1;
9707  }
9708  for (int j = 0; j <= p; j++)
9709  for (int i = 0; i + j <= p; i++) // (0,1,3)
9710  {
9711  double w = bop[i] + bop[j] + bop[p-i-j];
9712  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
9713  dof2nk[o++] = 2;
9714  }
9715  for (int j = 0; j <= p; j++)
9716  for (int i = 0; i + j <= p; i++) // (0,2,1)
9717  {
9718  double w = bop[i] + bop[j] + bop[p-i-j];
9719  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
9720  dof2nk[o++] = 3;
9721  }
9722 
9723  // interior
9724  for (int k = 0; k < p; k++)
9725  for (int j = 0; j + k < p; j++)
9726  for (int i = 0; i + j + k < p; i++)
9727  {
9728  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
9729  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9730  dof2nk[o++] = 1;
9731  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9732  dof2nk[o++] = 2;
9733  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9734  dof2nk[o++] = 3;
9735  }
9736 
9737  DenseMatrix T(Dof);
9738  for (int m = 0; m < Dof; m++)
9739  {
9740  const IntegrationPoint &ip = Nodes.IntPoint(m);
9741  poly1d.CalcBasis(p, ip.x, shape_x);
9742  poly1d.CalcBasis(p, ip.y, shape_y);
9743  poly1d.CalcBasis(p, ip.z, shape_z);
9744  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9745  const double *nm = nk + 3*dof2nk[m];
9746 
9747  o = 0;
9748  for (int k = 0; k <= p; k++)
9749  for (int j = 0; j + k <= p; j++)
9750  for (int i = 0; i + j + k <= p; i++)
9751  {
9752  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9753  T(o++, m) = s * nm[0];
9754  T(o++, m) = s * nm[1];
9755  T(o++, m) = s * nm[2];
9756  }
9757  for (int j = 0; j <= p; j++)
9758  for (int i = 0; i + j <= p; i++)
9759  {
9760  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9761  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
9762  (ip.z - c)*nm[2]);
9763  }
9764  }
9765 
9766  Ti.Factor(T);
9767  // cout << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
9768 }
9769 
9771  DenseMatrix &shape) const
9772 {
9773  const int p = Order - 1;
9774 
9775 #ifdef MFEM_THREAD_SAFE
9776  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9777  DenseMatrix u(Dof, Dim);
9778 #endif
9779 
9780  poly1d.CalcBasis(p, ip.x, shape_x);
9781  poly1d.CalcBasis(p, ip.y, shape_y);
9782  poly1d.CalcBasis(p, ip.z, shape_z);
9783  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9784 
9785  int o = 0;
9786  for (int k = 0; k <= p; k++)
9787  for (int j = 0; j + k <= p; j++)
9788  for (int i = 0; i + j + k <= p; i++)
9789  {
9790  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9791  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
9792  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
9793  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
9794  }
9795  for (int j = 0; j <= p; j++)
9796  for (int i = 0; i + j <= p; i++)
9797  {
9798  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9799  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
9800  o++;
9801  }
9802 
9803  Ti.Mult(u, shape);
9804 }
9805 
9807  Vector &divshape) const
9808 {
9809  const int p = Order - 1;
9810 
9811 #ifdef MFEM_THREAD_SAFE
9812  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9813  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
9814  Vector divu(Dof);
9815 #endif
9816 
9817  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9818  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9819  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
9820  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
9821 
9822  int o = 0;
9823  for (int k = 0; k <= p; k++)
9824  for (int j = 0; j + k <= p; j++)
9825  for (int i = 0; i + j + k <= p; i++)
9826  {
9827  int l = p - i - j - k;
9828  divu(o++) = (dshape_x(i)*shape_l(l) -
9829  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
9830  divu(o++) = (dshape_y(j)*shape_l(l) -
9831  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
9832  divu(o++) = (dshape_z(k)*shape_l(l) -
9833  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
9834  }
9835  for (int j = 0; j <= p; j++)
9836  for (int i = 0; i + j <= p; i++)
9837  {
9838  int k = p - i - j;
9839  divu(o++) =
9840  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
9841  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
9842  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
9843  }
9844 
9845  Ti.Mult(divu, divshape);
9846 }
9847 
9848 
9849 const double ND_HexahedronElement::tk[18] =
9850 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
9851 
9853  const int cp_type, const int op_type)
9854  : VectorFiniteElement(3, Geometry::CUBE, 3*p*(p + 1)*(p + 1), p,
9855  H_CURL, FunctionSpace::Qk),
9856  cbasis1d(poly1d.ClosedBasis(p, VerifyClosed(cp_type))),
9857  obasis1d(poly1d.OpenBasis(p - 1, VerifyOpen(op_type))),
9858  dof_map(Dof), dof2tk(Dof)
9859 {
9860  const double *cp = poly1d.ClosedPoints(p, cp_type);
9861  const double *op = poly1d.OpenPoints(p - 1, op_type);
9862  const int dof3 = Dof/3;
9863 
9864 #ifndef MFEM_THREAD_SAFE
9865  shape_cx.SetSize(p + 1);
9866  shape_ox.SetSize(p);
9867  shape_cy.SetSize(p + 1);
9868  shape_oy.SetSize(p);
9869  shape_cz.SetSize(p + 1);
9870  shape_oz.SetSize(p);
9871  dshape_cx.SetSize(p + 1);
9872  dshape_cy.SetSize(p + 1);
9873  dshape_cz.SetSize(p + 1);
9874 #endif
9875 
9876  // edges
9877  int o = 0;
9878  for (int i = 0; i < p; i++) // (0,1)
9879  {
9880  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
9881  }
9882  for (int i = 0; i < p; i++) // (1,2)
9883  {
9884  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
9885  }
9886  for (int i = 0; i < p; i++) // (3,2)
9887  {
9888  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
9889  }
9890  for (int i = 0; i < p; i++) // (0,3)
9891  {
9892  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
9893  }
9894  for (int i = 0; i < p; i++) // (4,5)
9895  {
9896  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
9897  }
9898  for (int i = 0; i < p; i++) // (5,6)
9899  {
9900  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
9901  }
9902  for (int i = 0; i < p; i++) // (7,6)
9903  {
9904  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
9905  }
9906  for (int i = 0; i < p; i++) // (4,7)
9907  {
9908  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
9909  }
9910  for (int i = 0; i < p; i++) // (0,4)
9911  {
9912  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
9913  }
9914  for (int i = 0; i < p; i++) // (1,5)
9915  {
9916  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
9917  }
9918  for (int i = 0; i < p; i++) // (2,6)
9919  {
9920  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
9921  }
9922  for (int i = 0; i < p; i++) // (3,7)
9923  {
9924  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
9925  }
9926 
9927  // faces
9928  // (3,2,1,0) -- bottom
9929  for (int j = 1; j < p; j++) // x - components
9930  for (int i = 0; i < p; i++)
9931  {
9932  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
9933  }
9934  for (int j = 0; j < p; j++) // y - components
9935  for (int i = 1; i < p; i++)
9936  {
9937  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
9938  }
9939  // (0,1,5,4) -- front
9940  for (int k = 1; k < p; k++) // x - components
9941  for (int i = 0; i < p; i++)
9942  {
9943  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
9944  }
9945  for (int k = 0; k < p; k++) // z - components
9946  for (int i = 1; i < p; i++ )
9947  {
9948  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
9949  }
9950  // (1,2,6,5) -- right
9951  for (int k = 1; k < p; k++) // y - components
9952  for (int j = 0; j < p; j++)
9953  {
9954  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
9955  }
9956  for (int k = 0; k < p; k++) // z - components
9957  for (int j = 1; j < p; j++)
9958  {
9959  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
9960  }
9961  // (2,3,7,6) -- back
9962  for (int k = 1; k < p; k++) // x - components
9963  for (int i = 0; i < p; i++)
9964  {
9965  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
9966  }
9967  for (int k = 0; k < p; k++) // z - components
9968  for (int i = 1; i < p; i++)
9969  {
9970  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
9971  }
9972  // (3,0,4,7) -- left
9973  for (int k = 1; k < p; k++) // y - components
9974  for (int j = 0; j < p; j++)
9975  {
9976  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
9977  }
9978  for (int k = 0; k < p; k++) // z - components
9979  for (int j = 1; j < p; j++)
9980  {
9981  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
9982  }
9983  // (4,5,6,7) -- top
9984  for (int j = 1; j < p; j++) // x - components
9985  for (int i = 0; i < p; i++)
9986  {
9987  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
9988  }
9989  for (int j = 0; j < p; j++) // y - components
9990  for (int i = 1; i < p; i++)
9991  {
9992  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
9993  }
9994 
9995  // interior
9996  // x-components
9997  for (int k = 1; k < p; k++)
9998  for (int j = 1; j < p; j++)
9999  for (int i = 0; i < p; i++)
10000  {
10001  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
10002  }
10003  // y-components
10004  for (int k = 1; k < p; k++)
10005  for (int j = 0; j < p; j++)
10006  for (int i = 1; i < p; i++)
10007  {
10008  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
10009  }
10010  // z-components
10011  for (int k = 0; k < p; k++)
10012  for (int j = 1; j < p; j++)
10013  for (int i = 1; i < p; i++)
10014  {
10015  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
10016  }
10017 
10018  // set dof2tk and Nodes
10019  o = 0;
10020  // x-components
10021  for (int k = 0; k <= p; k++)
10022  for (int j = 0; j <= p; j++)
10023  for (int i = 0; i < p; i++)
10024  {
10025  int idx;
10026  if ((idx = dof_map[o++]) < 0)
10027  {
10028  dof2tk[idx = -1 - idx] = 3;
10029  }
10030  else
10031  {
10032  dof2tk[idx] = 0;
10033  }
10034  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
10035  }
10036  // y-components
10037  for (int k = 0; k <= p; k++)
10038  for (int j = 0; j < p; j++)
10039  for (int i = 0; i <= p; i++)
10040  {
10041  int idx;
10042  if ((idx = dof_map[o++]) < 0)
10043  {
10044  dof2tk[idx = -1 - idx] = 4;
10045  }
10046  else
10047  {
10048  dof2tk[idx] = 1;
10049  }
10050  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
10051  }
10052  // z-components
10053  for (int k = 0; k < p; k++)
10054  for (int j = 0; j <= p; j++)
10055  for (int i = 0; i <= p; i++)
10056  {
10057  int idx;
10058  if ((idx = dof_map[o++]) < 0)
10059  {
10060  dof2tk[idx = -1 - idx] = 5;
10061  }
10062  else
10063  {
10064  dof2tk[idx] = 2;
10065  }
10066  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
10067  }
10068 }
10069 
10071  DenseMatrix &shape) const
10072 {
10073  const int p = Order;
10074 
10075 #ifdef MFEM_THREAD_SAFE
10076  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10077  Vector shape_cz(p + 1), shape_oz(p);
10078 #endif
10079 
10080  cbasis1d.Eval(ip.x, shape_cx);
10081  obasis1d.Eval(ip.x, shape_ox);
10082  cbasis1d.Eval(ip.y, shape_cy);
10083  obasis1d.Eval(ip.y, shape_oy);
10084  cbasis1d.Eval(ip.z, shape_cz);
10085  obasis1d.Eval(ip.z, shape_oz);
10086 
10087  int o = 0;
10088  // x-components
10089  for (int k = 0; k <= p; k++)
10090  for (int j = 0; j <= p; j++)
10091  for (int i = 0; i < p; i++)
10092  {
10093  int idx, s;
10094  if ((idx = dof_map[o++]) < 0)
10095  {
10096  idx = -1 - idx, s = -1;
10097  }
10098  else
10099  {
10100  s = +1;
10101  }
10102  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
10103  shape(idx,1) = 0.;
10104  shape(idx,2) = 0.;
10105  }
10106  // y-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, s;
10112  if ((idx = dof_map[o++]) < 0)
10113  {
10114  idx = -1 - idx, s = -1;
10115  }
10116  else
10117  {
10118  s = +1;
10119  }
10120  shape(idx,0) = 0.;
10121  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
10122  shape(idx,2) = 0.;
10123  }
10124  // z-components
10125  for (int k = 0; k < p; k++)
10126  for (int j = 0; j <= p; j++)
10127  for (int i = 0; i <= p; i++)
10128  {
10129  int idx, s;
10130  if ((idx = dof_map[o++]) < 0)
10131  {
10132  idx = -1 - idx, s = -1;
10133  }
10134  else
10135  {
10136  s = +1;
10137  }
10138  shape(idx,0) = 0.;
10139  shape(idx,1) = 0.;
10140  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
10141  }
10142 }
10143 
10145  DenseMatrix &curl_shape) const
10146 {
10147  const int p = Order;
10148 
10149 #ifdef MFEM_THREAD_SAFE
10150  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10151  Vector shape_cz(p + 1), shape_oz(p);
10152  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
10153 #endif
10154 
10155  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10156  obasis1d.Eval(ip.x, shape_ox);
10157  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10158  obasis1d.Eval(ip.y, shape_oy);
10159  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
10160  obasis1d.Eval(ip.z, shape_oz);
10161 
10162  int o = 0;
10163  // x-components
10164  for (int k = 0; k <= p; k++)
10165  for (int j = 0; j <= p; j++)
10166  for (int i = 0; i < p; i++)
10167  {
10168  int idx, s;
10169  if ((idx = dof_map[o++]) < 0)
10170  {
10171  idx = -1 - idx, s = -1;
10172  }
10173  else
10174  {
10175  s = +1;
10176  }
10177  curl_shape(idx,0) = 0.;
10178  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
10179  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
10180  }
10181  // y-components
10182  for (int k = 0; k <= p; k++)
10183  for (int j = 0; j < p; j++)
10184  for (int i = 0; i <= p; i++)
10185  {
10186  int idx, s;
10187  if ((idx = dof_map[o++]) < 0)
10188  {
10189  idx = -1 - idx, s = -1;
10190  }
10191  else
10192  {
10193  s = +1;
10194  }
10195  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
10196  curl_shape(idx,1) = 0.;
10197  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
10198  }
10199  // z-components
10200  for (int k = 0; k < p; k++)
10201  for (int j = 0; j <= p; j++)
10202  for (int i = 0; i <= p; i++)
10203  {
10204  int idx, s;
10205  if ((idx = dof_map[o++]) < 0)
10206  {
10207  idx = -1 - idx, s = -1;
10208  }
10209  else
10210  {
10211  s = +1;
10212  }
10213  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
10214  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
10215  curl_shape(idx,2) = 0.;
10216  }
10217 }
10218 
10219 
10220 const double ND_QuadrilateralElement::tk[8] =
10221 { 1.,0., 0.,1., -1.,0., 0.,-1. };
10222 
10224  const int cp_type,
10225  const int op_type)
10226  : VectorFiniteElement(2, Geometry::SQUARE, 2*p*(p + 1), p,
10227  H_CURL, FunctionSpace::Qk),
10228  cbasis1d(poly1d.ClosedBasis(p, VerifyClosed(cp_type))),
10229  obasis1d(poly1d.OpenBasis(p - 1, VerifyOpen(op_type))),
10230  dof_map(Dof), dof2tk(Dof)
10231 {
10232  const double *cp = poly1d.ClosedPoints(p, cp_type);
10233  const double *op = poly1d.OpenPoints(p - 1, op_type);
10234  const int dof2 = Dof/2;
10235 
10236 #ifndef MFEM_THREAD_SAFE
10237  shape_cx.SetSize(p + 1);
10238  shape_ox.SetSize(p);
10239  shape_cy.SetSize(p + 1);
10240  shape_oy.SetSize(p);
10241  dshape_cx.SetSize(p + 1);
10242  dshape_cy.SetSize(p + 1);
10243 #endif
10244 
10245  // edges
10246  int o = 0;
10247  for (int i = 0; i < p; i++) // (0,1)
10248  {
10249  dof_map[0*dof2 + i + 0*p] = o++;
10250  }
10251  for (int j = 0; j < p; j++) // (1,2)
10252  {
10253  dof_map[1*dof2 + p + j*(p + 1)] = o++;
10254  }
10255  for (int i = 0; i < p; i++) // (2,3)
10256  {
10257  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
10258  }
10259  for (int j = 0; j < p; j++) // (3,0)
10260  {
10261  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
10262  }
10263 
10264  // interior
10265  // x-components
10266  for (int j = 1; j < p; j++)
10267  for (int i = 0; i < p; i++)
10268  {
10269  dof_map[0*dof2 + i + j*p] = o++;
10270  }
10271  // y-components
10272  for (int j = 0; j < p; j++)
10273  for (int i = 1; i < p; i++)
10274  {
10275  dof_map[1*dof2 + i + j*(p + 1)] = o++;
10276  }
10277 
10278  // set dof2tk and Nodes
10279  o = 0;
10280  // x-components
10281  for (int j = 0; j <= p; j++)
10282  for (int i = 0; i < p; i++)
10283  {
10284  int idx;
10285  if ((idx = dof_map[o++]) < 0)
10286  {
10287  dof2tk[idx = -1 - idx] = 2;
10288  }
10289  else
10290  {
10291  dof2tk[idx] = 0;
10292  }
10293  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
10294  }
10295  // y-components
10296  for (int j = 0; j < p; j++)
10297  for (int i = 0; i <= p; i++)
10298  {
10299  int idx;
10300  if ((idx = dof_map[o++]) < 0)
10301  {
10302  dof2tk[idx = -1 - idx] = 3;
10303  }
10304  else
10305  {
10306  dof2tk[idx] = 1;
10307  }
10308  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
10309  }
10310 }
10311 
10313  DenseMatrix &shape) const
10314 {
10315  const int p = Order;
10316 
10317 #ifdef MFEM_THREAD_SAFE
10318  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10319 #endif
10320 
10321  cbasis1d.Eval(ip.x, shape_cx);
10322  obasis1d.Eval(ip.x, shape_ox);
10323  cbasis1d.Eval(ip.y, shape_cy);
10324  obasis1d.Eval(ip.y, shape_oy);
10325 
10326  int o = 0;
10327  // x-components
10328  for (int j = 0; j <= p; j++)
10329  for (int i = 0; i < p; i++)
10330  {
10331  int idx, s;
10332  if ((idx = dof_map[o++]) < 0)
10333  {
10334  idx = -1 - idx, s = -1;
10335  }
10336  else
10337  {
10338  s = +1;
10339  }
10340  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
10341  shape(idx,1) = 0.;
10342  }
10343  // y-components
10344  for (int j = 0; j < p; j++)
10345  for (int i = 0; i <= p; i++)
10346  {
10347  int idx, s;
10348  if ((idx = dof_map[o++]) < 0)
10349  {
10350  idx = -1 - idx, s = -1;
10351  }
10352  else
10353  {
10354  s = +1;
10355  }
10356  shape(idx,0) = 0.;
10357  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
10358  }
10359 }
10360 
10362  DenseMatrix &curl_shape) const
10363 {
10364  const int p = Order;
10365 
10366 #ifdef MFEM_THREAD_SAFE
10367  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10368  Vector dshape_cx(p + 1), dshape_cy(p + 1);
10369 #endif
10370 
10371  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10372  obasis1d.Eval(ip.x, shape_ox);
10373  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10374  obasis1d.Eval(ip.y, shape_oy);
10375 
10376  int o = 0;
10377  // x-components
10378  for (int j = 0; j <= p; j++)
10379  for (int i = 0; i < p; i++)
10380  {
10381  int idx, s;
10382  if ((idx = dof_map[o++]) < 0)
10383  {
10384  idx = -1 - idx, s = -1;
10385  }
10386  else
10387  {
10388  s = +1;
10389  }
10390  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
10391  }
10392  // y-components
10393  for (int j = 0; j < p; j++)
10394  for (int i = 0; i <= p; i++)
10395  {
10396  int idx, s;
10397  if ((idx = dof_map[o++]) < 0)
10398  {
10399  idx = -1 - idx, s = -1;
10400  }
10401  else
10402  {
10403  s = +1;
10404  }
10405  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
10406  }
10407 }
10408 
10409 
10410 const double ND_TetrahedronElement::tk[18] =
10411 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
10412 
10413 const double ND_TetrahedronElement::c = 1./4.;
10414 
10416  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
10417  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
10418 {
10419  const double *eop = poly1d.OpenPoints(p - 1);
10420  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10421  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
10422 
10423  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
10424 
10425 #ifndef MFEM_THREAD_SAFE
10426  shape_x.SetSize(p);
10427  shape_y.SetSize(p);
10428  shape_z.SetSize(p);
10429  shape_l.SetSize(p);
10430  dshape_x.SetSize(p);
10431  dshape_y.SetSize(p);
10432  dshape_z.SetSize(p);
10433  dshape_l.SetSize(p);
10434  u.SetSize(Dof, Dim);
10435 #else
10436  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10437 #endif
10438 
10439  int o = 0;
10440  // edges
10441  for (int i = 0; i < p; i++) // (0,1)
10442  {
10443  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
10444  dof2tk[o++] = 0;
10445  }
10446  for (int i = 0; i < p; i++) // (0,2)
10447  {
10448  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
10449  dof2tk[o++] = 1;
10450  }
10451  for (int i = 0; i < p; i++) // (0,3)
10452  {
10453  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
10454  dof2tk[o++] = 2;
10455  }
10456  for (int i = 0; i < p; i++) // (1,2)
10457  {
10458  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
10459  dof2tk[o++] = 3;
10460  }
10461  for (int i = 0; i < p; i++) // (1,3)
10462  {
10463  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
10464  dof2tk[o++] = 4;
10465  }
10466  for (int i = 0; i < p; i++) // (2,3)
10467  {
10468  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
10469  dof2tk[o++] = 5;
10470  }
10471 
10472  // faces
10473  for (int j = 0; j <= pm2; j++) // (1,2,3)
10474  for (int i = 0; i + j <= pm2; i++)
10475  {
10476  double w = fop[i] + fop[j] + fop[pm2-i-j];
10477  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10478  dof2tk[o++] = 3;
10479  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10480  dof2tk[o++] = 4;
10481  }
10482  for (int j = 0; j <= pm2; j++) // (0,3,2)
10483  for (int i = 0; i + j <= pm2; i++)
10484  {
10485  double w = fop[i] + fop[j] + fop[pm2-i-j];
10486  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10487  dof2tk[o++] = 2;
10488  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10489  dof2tk[o++] = 1;
10490  }
10491  for (int j = 0; j <= pm2; j++) // (0,1,3)
10492  for (int i = 0; i + j <= pm2; i++)
10493  {
10494  double w = fop[i] + fop[j] + fop[pm2-i-j];
10495  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10496  dof2tk[o++] = 0;
10497  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10498  dof2tk[o++] = 2;
10499  }
10500  for (int j = 0; j <= pm2; j++) // (0,2,1)
10501  for (int i = 0; i + j <= pm2; i++)
10502  {
10503  double w = fop[i] + fop[j] + fop[pm2-i-j];
10504  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10505  dof2tk[o++] = 1;
10506  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10507  dof2tk[o++] = 0;
10508  }
10509 
10510  // interior
10511  for (int k = 0; k <= pm3; k++)
10512  for (int j = 0; j + k <= pm3; j++)
10513  for (int i = 0; i + j + k <= pm3; i++)
10514  {
10515  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
10516  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10517  dof2tk[o++] = 0;
10518  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10519  dof2tk[o++] = 1;
10520  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10521  dof2tk[o++] = 2;
10522  }
10523 
10524  DenseMatrix T(Dof);
10525  for (int m = 0; m < Dof; m++)
10526  {
10527  const IntegrationPoint &ip = Nodes.IntPoint(m);
10528  const double *tm = tk + 3*dof2tk[m];
10529  o = 0;
10530 
10531  poly1d.CalcBasis(pm1, ip.x, shape_x);
10532  poly1d.CalcBasis(pm1, ip.y, shape_y);
10533  poly1d.CalcBasis(pm1, ip.z, shape_z);
10534  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10535 
10536  for (int k = 0; k <= pm1; k++)
10537  for (int j = 0; j + k <= pm1; j++)
10538  for (int i = 0; i + j + k <= pm1; i++)
10539  {
10540  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10541  T(o++, m) = s * tm[0];
10542  T(o++, m) = s * tm[1];
10543  T(o++, m) = s * tm[2];
10544  }
10545  for (int k = 0; k <= pm1; k++)
10546  for (int j = 0; j + k <= pm1; j++)
10547  {
10548  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10549  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10550  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
10551  }
10552  for (int k = 0; k <= pm1; k++)
10553  {
10554  T(o++, m) =
10555  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
10556  }
10557  }
10558 
10559  Ti.Factor(T);
10560  // cout << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
10561 }
10562 
10564  DenseMatrix &shape) const
10565 {
10566  const int pm1 = Order - 1;
10567 
10568 #ifdef MFEM_THREAD_SAFE
10569  const int p = Order;
10570  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10571  DenseMatrix u(Dof, Dim);
10572 #endif
10573 
10574  poly1d.CalcBasis(pm1, ip.x, shape_x);
10575  poly1d.CalcBasis(pm1, ip.y, shape_y);
10576  poly1d.CalcBasis(pm1, ip.z, shape_z);
10577  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10578 
10579  int n = 0;
10580  for (int k = 0; k <= pm1; k++)
10581  for (int j = 0; j + k <= pm1; j++)
10582  for (int i = 0; i + j + k <= pm1; i++)
10583  {
10584  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10585  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
10586  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
10587  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
10588  }
10589  for (int k = 0; k <= pm1; k++)
10590  for (int j = 0; j + k <= pm1; j++)
10591  {
10592  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10593  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
10594  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
10595  }
10596  for (int k = 0; k <= pm1; k++)
10597  {
10598  double s = shape_y(pm1-k)*shape_z(k);
10599  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
10600  }
10601 
10602  Ti.Mult(u, shape);
10603 }
10604 
10606  DenseMatrix &curl_shape) const
10607 {
10608  const int pm1 = Order - 1;
10609 
10610 #ifdef MFEM_THREAD_SAFE
10611  const int p = Order;
10612  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10613  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
10614  DenseMatrix u(Dof, Dim);
10615 #endif
10616 
10617  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10618  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10619  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
10620  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10621 
10622  int n = 0;
10623  for (int k = 0; k <= pm1; k++)
10624  for (int j = 0; j + k <= pm1; j++)
10625  for (int i = 0; i + j + k <= pm1; i++)
10626  {
10627  int l = pm1-i-j-k;
10628  const double dx = (dshape_x(i)*shape_l(l) -
10629  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
10630  const double dy = (dshape_y(j)*shape_l(l) -
10631  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
10632  const double dz = (dshape_z(k)*shape_l(l) -
10633  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
10634 
10635  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
10636  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
10637  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
10638  }
10639  for (int k = 0; k <= pm1; k++)
10640  for (int j = 0; j + k <= pm1; j++)
10641  {
10642  int i = pm1 - j - k;
10643  // s = shape_x(i)*shape_y(j)*shape_z(k);
10644  // curl of s*(ip.y - c, -(ip.x - c), 0):
10645  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
10646  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
10647  u(n,2) =
10648  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
10649  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
10650  n++;
10651  // curl of s*(ip.z - c, 0, -(ip.x - c)):
10652  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
10653  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
10654  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
10655  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
10656  n++;
10657  }
10658  for (int k = 0; k <= pm1; k++)
10659  {
10660  int j = pm1 - k;
10661  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
10662  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
10663  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
10664  u(n,1) = 0.;
10665  u(n,2) = 0.; n++;
10666  }
10667 
10668  Ti.Mult(u, curl_shape);
10669 }
10670 
10671 
10672 const double ND_TriangleElement::tk[8] =
10673 { 1.,0., -1.,1., 0.,-1., 0.,1. };
10674 
10675 const double ND_TriangleElement::c = 1./3.;
10676 
10678  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
10679  H_CURL, FunctionSpace::Pk),
10680  dof2tk(Dof)
10681 {
10682  const double *eop = poly1d.OpenPoints(p - 1);
10683  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10684 
10685  const int pm1 = p - 1, pm2 = p - 2;
10686 
10687 #ifndef MFEM_THREAD_SAFE
10688  shape_x.SetSize(p);
10689  shape_y.SetSize(p);
10690  shape_l.SetSize(p);
10691  dshape_x.SetSize(p);
10692  dshape_y.SetSize(p);
10693  dshape_l.SetSize(p);
10694  u.SetSize(Dof, Dim);
10695  curlu.SetSize(Dof);
10696 #else
10697  Vector shape_x(p), shape_y(p), shape_l(p);
10698 #endif
10699 
10700  int n = 0;
10701  // edges
10702  for (int i = 0; i < p; i++) // (0,1)
10703  {
10704  Nodes.IntPoint(n).Set2(eop[i], 0.);
10705  dof2tk[n++] = 0;
10706  }
10707  for (int i = 0; i < p; i++) // (1,2)
10708  {
10709  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
10710  dof2tk[n++] = 1;
10711  }
10712  for (int i = 0; i < p; i++) // (2,0)
10713  {
10714  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
10715  dof2tk[n++] = 2;
10716  }
10717 
10718  // interior
10719  for (int j = 0; j <= pm2; j++)
10720  for (int i = 0; i + j <= pm2; i++)
10721  {
10722  double w = iop[i] + iop[j] + iop[pm2-i-j];
10723  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10724  dof2tk[n++] = 0;
10725  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10726  dof2tk[n++] = 3;
10727  }
10728 
10729  DenseMatrix T(Dof);
10730  for (int m = 0; m < Dof; m++)
10731  {
10732  const IntegrationPoint &ip = Nodes.IntPoint(m);
10733  const double *tm = tk + 2*dof2tk[m];
10734  n = 0;
10735 
10736  poly1d.CalcBasis(pm1, ip.x, shape_x);
10737  poly1d.CalcBasis(pm1, ip.y, shape_y);
10738  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10739 
10740  for (int j = 0; j <= pm1; j++)
10741  for (int i = 0; i + j <= pm1; i++)
10742  {
10743  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10744  T(n++, m) = s * tm[0];
10745  T(n++, m) = s * tm[1];
10746  }
10747  for (int j = 0; j <= pm1; j++)
10748  {
10749  T(n++, m) =
10750  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10751  }
10752  }
10753 
10754  Ti.Factor(T);
10755  // cout << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
10756 }
10757 
10759  DenseMatrix &shape) const
10760 {
10761  const int pm1 = Order - 1;
10762 
10763 #ifdef MFEM_THREAD_SAFE
10764  const int p = Order;
10765  Vector shape_x(p), shape_y(p), shape_l(p);
10766  DenseMatrix u(Dof, Dim);
10767 #endif
10768 
10769  poly1d.CalcBasis(pm1, ip.x, shape_x);
10770  poly1d.CalcBasis(pm1, ip.y, shape_y);
10771  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10772 
10773  int n = 0;
10774  for (int j = 0; j <= pm1; j++)
10775  for (int i = 0; i + j <= pm1; i++)
10776  {
10777  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10778  u(n,0) = s; u(n,1) = 0; n++;
10779  u(n,0) = 0; u(n,1) = s; n++;
10780  }
10781  for (int j = 0; j <= pm1; j++)
10782  {
10783  double s = shape_x(pm1-j)*shape_y(j);
10784  u(n,0) = s*(ip.y - c);
10785  u(n,1) = -s*(ip.x - c);
10786  n++;
10787  }
10788 
10789  Ti.Mult(u, shape);
10790 }
10791 
10793  DenseMatrix &curl_shape) const
10794 {
10795  const int pm1 = Order - 1;
10796 
10797 #ifdef MFEM_THREAD_SAFE
10798  const int p = Order;
10799  Vector shape_x(p), shape_y(p), shape_l(p);
10800  Vector dshape_x(p), dshape_y(p), dshape_l(p);
10801  Vector curlu(Dof);
10802 #endif
10803 
10804  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10805  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10806  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
10807 
10808  int n = 0;
10809  for (int j = 0; j <= pm1; j++)
10810  for (int i = 0; i + j <= pm1; i++)
10811  {
10812  int l = pm1-i-j;
10813  const double dx = (dshape_x(i)*shape_l(l) -
10814  shape_x(i)*dshape_l(l)) * shape_y(j);
10815  const double dy = (dshape_y(j)*shape_l(l) -
10816  shape_y(j)*dshape_l(l)) * shape_x(i);
10817 
10818  curlu(n++) = -dy;
10819  curlu(n++) = dx;
10820  }
10821 
10822  for (int j = 0; j <= pm1; j++)
10823  {
10824  int i = pm1 - j;
10825  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
10826  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
10827  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
10828  }
10829 
10830  Vector curl2d(curl_shape.Data(),Dof);
10831  Ti.Mult(curlu, curl2d);
10832 }
10833 
10834 
10835 const double ND_SegmentElement::tk[1] = { 1. };
10836 
10837 ND_SegmentElement::ND_SegmentElement(const int p, const int op_type)
10838  : VectorFiniteElement(1, Geometry::SEGMENT, p, p - 1,
10839  H_CURL, FunctionSpace::Pk),
10840  obasis1d(poly1d.OpenBasis(p - 1, VerifyOpen(op_type))),
10841  dof2tk(Dof)
10842 {
10843  const double *op = poly1d.OpenPoints(p - 1, op_type);
10844 
10845  // set dof2tk and Nodes
10846  for (int i = 0; i < p; i++)
10847  {
10848  dof2tk[i] = 0;
10849  Nodes.IntPoint(i).x = op[i];
10850  }
10851 }
10852 
10854  DenseMatrix &shape) const
10855 {
10856  Vector vshape(shape.Data(), Dof);
10857 
10858  obasis1d.Eval(ip.x, vshape);
10859 }
10860 
10861 
10863  Vector &shape) const
10864 {
10865  kv[0]->CalcShape(shape, ijk[0], ip.x);
10866 
10867  double sum = 0.0;
10868  for (int i = 0; i <= Order; i++)
10869  {
10870  sum += (shape(i) *= weights(i));
10871  }
10872 
10873  shape /= sum;
10874 }
10875 
10877  DenseMatrix &dshape) const
10878 {
10879  Vector grad(dshape.Data(), Dof);
10880 
10881  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
10882  kv[0]->CalcDShape(grad, ijk[0], ip.x);
10883 
10884  double sum = 0.0, dsum = 0.0;
10885  for (int i = 0; i <= Order; i++)
10886  {
10887  sum += (shape_x(i) *= weights(i));
10888  dsum += ( grad(i) *= weights(i));
10889  }
10890 
10891  sum = 1.0/sum;
10892  add(sum, grad, -dsum*sum*sum, shape_x, grad);
10893 }
10894 
10896  Vector &shape) const
10897 {
10898  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
10899  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
10900 
10901  double sum = 0.0;
10902  for (int o = 0, j = 0; j <= Order; j++)
10903  {
10904  const double sy = shape_y(j);
10905  for (int i = 0; i <= Order; i++, o++)
10906  {
10907  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
10908  }
10909  }
10910 
10911  shape /= sum;
10912 }
10913 
10915  DenseMatrix &dshape) const
10916 {
10917  double sum, dsum[2];
10918 
10919  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
10920  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
10921 
10922  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
10923  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
10924 
10925  sum = dsum[0] = dsum[1] = 0.0;
10926  for (int o = 0, j = 0; j <= Order; j++)
10927  {
10928  const double sy = shape_y(j), dsy = dshape_y(j);
10929  for (int i = 0; i <= Order; i++, o++)
10930  {
10931  sum += ( u(o) = shape_x(i)*sy*weights(o) );
10932 
10933  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
10934  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
10935  }
10936  }
10937 
10938  sum = 1.0/sum;
10939  dsum[0] *= sum*sum;
10940  dsum[1] *= sum*sum;
10941 
10942  for (int o = 0; o < Dof; o++)
10943  {
10944  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
10945  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
10946  }
10947 }
10948 
10950  Vector &shape) const
10951 {
10952  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
10953  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
10954  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
10955 
10956  double sum = 0.0;
10957  for (int o = 0, k = 0; k <= Order; k++)
10958  {
10959  const double sz = shape_z(k);
10960  for (int j = 0; j <= Order; j++)
10961  {
10962  const double sy_sz = shape_y(j)*sz;
10963  for (int i = 0; i <= Order; i++, o++)
10964  {
10965  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
10966  }
10967  }
10968  }
10969 
10970  shape /= sum;
10971 }
10972 
10974  DenseMatrix &dshape) const
10975 {
10976  double sum, dsum[3];
10977 
10978  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
10979  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
10980  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
10981 
10982  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
10983  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
10984  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
10985 
10986  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
10987  for (int o = 0, k = 0; k <= Order; k++)
10988  {
10989  const double sz = shape_z(k), dsz = dshape_z(k);
10990  for (int j = 0; j <= Order; j++)
10991  {
10992  const double sy_sz = shape_y(j)* sz;
10993  const double dsy_sz = dshape_y(j)* sz;
10994  const double sy_dsz = shape_y(j)*dsz;
10995  for (int i = 0; i <= Order; i++, o++)
10996  {
10997  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
10998 
10999  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
11000  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
11001  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
11002  }
11003  }
11004  }
11005 
11006  sum = 1.0/sum;
11007  dsum[0] *= sum*sum;
11008  dsum[1] *= sum*sum;
11009  dsum[2] *= sum*sum;
11010 
11011  for (int o = 0; o < Dof; o++)
11012  {
11013  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
11014  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
11015  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
11016  }
11017 }
11018 
11019 }
int GetNPoints() const
Returns the number of the points in the integration rule.
Definition: intrules.hpp:222
Abstract class for Finite Elements.
Definition: fe.hpp:46
RefinedLinear3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:4186
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1303
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:8201
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:3216
int Size() const
Logical size of the array.
Definition: array.hpp:109
const DenseMatrix & AdjugateJacobian()
Definition: eltrans.hpp:69
DenseMatrix curlshape_J
Definition: fe.hpp:401
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5985
int GetDim() const
Returns the reference space dimension for the finite element.
Definition: fe.hpp:115
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7101
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2827
L2_SegmentElement(const int p, const int type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8075
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:3764
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:1051
Class for an integration rule - an Array of IntegrationPoint.
Definition: intrules.hpp:83
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8596
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:10914
Linear3DFiniteElement()
Construct a linear FE on tetrahedron.
Definition: fe.cpp:2226
static double CalcDelta(const int p, const double x)
Definition: fe.hpp:1428
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:3009
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8353
int NumCols() const
Definition: array.hpp:285
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:9770
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Evaluate the values of all shape functions of a vector finite element in reference space at the given...
Definition: fe.cpp:38
RefinedBiLinear2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4418
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:1621
L2Pos_TriangleElement(const int p)
Definition: fe.cpp:8740
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:7039
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:156
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:5030
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:115
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:2464
void CalcPhysDivShape(ElementTransformation &Trans, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in physical space at the po...
Definition: fe.cpp:59
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2243
const double * OpenPoints(const int p, const int type=Quadrature1D::GaussLegendre)
Definition: fe.hpp:1389
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8779
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:2781
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3061
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:1417
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:7081
void GivePolyPoints(const int np, double *pts, const int type)
Definition: intrules.cpp:596
L2Pos_TetrahedronElement(const int p)
Definition: fe.cpp:8934
Array< KnotVector * > kv
Definition: fe.hpp:2233
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:508
L2_TriangleElement(const int p, const int type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8615
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:310
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:9152
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5092
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:3551
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:972
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:237
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1441
void LocalInterpolation_ND(const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:801
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1799
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:1710
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:2546
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:468
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
evaluate derivatives of shape function - constant 0
Definition: fe.cpp:2197
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:861
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6601
H1Pos_TetrahedronElement(const int p)
Definition: fe.cpp:7823
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:10862
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:8220
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
Definition: densemat.cpp:271
void SetIntPoint(const IntegrationPoint *ip)
Definition: eltrans.hpp:51
LagrangeHexFiniteElement(int degree)
Definition: fe.cpp:3816
int GetOrder() const
Returns the order of the finite element.
Definition: fe.hpp:124
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:2559
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:3672
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:3978
Data type dense matrix using column-major storage.
Definition: densemat.hpp:22
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:3626
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:319
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:10876
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:9626
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5258
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:625
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:2212
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:1870
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:109
const DenseMatrix & InverseJacobian()
Definition: eltrans.hpp:72
RefinedTriLinear3DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4565
DenseMatrix vshape
Definition: fe.hpp:57
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:3803
Quadratic3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:2282
int GetMapType() const
Definition: fe.hpp:133
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:8093
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:5608
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5795
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:3979
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:2658
const IntegrationPoint & GetIntPoint()
Definition: eltrans.hpp:53
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8899
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:1922
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:8964
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:2489
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:2481
const IntegrationPoint & GetCenter(int GeomType)
Definition: geom.hpp:57
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 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:6689
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:663
H1Pos_HexahedronElement(const int p)
Definition: fe.cpp:7211
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:140
double * GetData() const
Definition: vector.hpp:114
static void CalcShape(const int p, const double x, const double y, const double z, double *shape)
Definition: fe.cpp:7925
H1_SegmentElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:6539
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:8841
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:933
H1_TetrahedronElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:7508
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:7183
Linear2DFiniteElement()
Construct a linear FE on triangle.
Definition: fe.cpp:875
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:2339
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5930
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:264
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4754
L2_QuadrilateralElement(const int p, const int _type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8179
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:10758
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:842
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:1942
void CalcPhysCurlShape(ElementTransformation &Trans, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in physical space at the point de...
Definition: fe.cpp:73
L2Pos_HexahedronElement(const int p)
Definition: fe.cpp:8523
ND_TriangleElement(const int p)
Definition: fe.cpp:10677
RT_QuadrilateralElement(const int p, const int cp_type=Quadrature1D::GaussLobatto, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8991
const double * GetPoints(const int p, const int type)
Get the coordinates of the points of the given Quadrature1D type.
Definition: fe.cpp:6468
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:9806
Implements CalcDivShape methods.
Definition: fe.hpp:101
static void CalcDShape(const int p, const double x, const double y, const double z, double *dshape_1d, double *dshape)
Definition: fe.cpp:7958
static void CalcBasis(const int p, const double x, double *u)
Definition: fe.hpp:1412
H1_HexahedronElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:6779
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
evaluate shape function - constant 1
Definition: fe.cpp:2191
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1970
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:6303
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:103
H1Pos_TriangleElement(const int p)
Definition: fe.cpp:7678
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:3263
static int VerifyOpen(int pt_type)
Definition: fe.hpp:287
Cubic3DFiniteElement()
Construct a cubic FE on tetrahedron.
Definition: fe.cpp:2017
Linear1DFiniteElement()
Construct a linear FE on interval.
Definition: fe.cpp:854
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4127
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:5918
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1490
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:4012
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp: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:1108
static void CalcShape(const int p, const double x, const double y, double *shape)
Definition: fe.cpp:7733
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:2512
void SetSize(int m, int n)
Definition: array.hpp:282
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:2110
Geometry Geometries
Definition: geom.cpp:544
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:225
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:3569
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:193
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:2974
int Dof
Number of degrees of freedom.
Definition: fe.hpp:49
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:8099
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1068
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1079
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1327
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:4016
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6954
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7204
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:1594
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:8682
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:7456
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4043
void LocalInterpolation_RT(const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:767
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:3202
static void ChebyshevPoints(const int p, double *x)
Definition: fe.cpp:6271
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
Definition: densemat.cpp:3639
const DenseMatrix & Jacobian()
Definition: eltrans.hpp:64
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:6055
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:3788
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:5896
ND_TetrahedronElement(const int p)
Definition: fe.cpp:10415
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:8768
int DerivMapType
Definition: fe.hpp:49
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:848
For scalar fields; preserves point values.
Definition: fe.hpp:84
int GeomType
Geometry::Type of the reference element.
Definition: fe.hpp:49
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:1885
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:566
const IntegrationRule & GetNodes() const
Definition: fe.hpp:166
For scalar fields; preserves volume integrals.
Definition: fe.hpp:85
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5145
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1149
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8438
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:2317
L2Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:8289
P0SegmentFiniteElement(int Ord=0)
Definition: fe.cpp:2452
static void CalcDShape(const int p, const double x, const double y, double *dshape_1d, double *dshape)
Definition: fe.cpp:7759
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:2804
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:10949
Implements CalcCurlShape methods.
Definition: fe.hpp:102
DenseMatrix curlshape
Definition: fe.hpp:401
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
Definition: densemat.cpp:3661
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:9366
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:5196
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:174
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:8660
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:9105
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:1749
void SetData(double *d)
Definition: vector.hpp:80
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:3461
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:924
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2252
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:9440
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:7619
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1173
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:1251
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:746
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:8762
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3010
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:10973
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:1265
int GetGeomType() const
Returns the Geometry::Type of the reference element.
Definition: fe.hpp:118
DenseMatrix m_dshape
Definition: fe.hpp:1617
int Dim
Dimension of reference space.
Definition: fe.hpp:49
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:10361
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:8314
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:63
IntegrationRule Nodes
Definition: fe.hpp:55
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1135
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:8551
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:7061
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7382
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3513
double * Data() const
Returns the matrix data array.
Definition: densemat.hpp:88
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:10792
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:2673
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4441
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2570
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:520
DenseMatrix Jinv
Definition: fe.hpp:400
No derivatives implemented.
Definition: fe.hpp:99
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8110
int GetDof() const
Returns the number of degrees of freedom in the finite element.
Definition: fe.hpp:121
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:7644
Base class Coefficient that may optionally depend on time.
Definition: coefficient.hpp:31
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1019
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:5226
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:8957
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:164
void mfem_error(const char *msg)
Definition: error.cpp:106
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:349
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:886
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4611
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:4308
static const int * Binom(const int p)
Get a poiner to an array containing the binomial coefficients &quot;p choose k&quot; for k=0,...,p for the given p.
Definition: fe.cpp:6254
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:3363
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Evaluate the divergence of all shape functions of a vector finite element in reference space at the g...
Definition: fe.cpp:52
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:954
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:8866
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:10070
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2737
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:87
FiniteElement(int D, int G, int Do, int O, int F=FunctionSpace::Pk)
Definition: fe.cpp:24
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1376
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2397
ND_HexahedronElement(const int p, const int cp_type=Quadrature1D::GaussLobatto, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:9852
Quad1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:1060
RT_HexahedronElement(const int p, const int cp_type=Quadrature1D::GaussLobatto, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:9202
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:7337
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:98
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:1008
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:915
Basis & ClosedBasis(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.hpp:1406
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Evaluate the curl of all shape functions of a vector finite element in reference space at the given p...
Definition: fe.cpp:66
H1Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:7108
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:868
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8711
Basis & GetBasis(const int p, const int type)
Get a Poly_1D::Basis object of the given degree and Quadrature1D type.
Definition: fe.cpp:6489
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:7358
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 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:2218
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:8572
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:531
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:6909
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:1043
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:3177
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:10563
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:2937
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:10312
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:348
static int VerifyClosed(int pt_type)
Definition: fe.hpp:280
int DerivRangeType
Definition: fe.hpp:49
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2685
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:764
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8172
RefinedLinear2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:4062
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const NodalFiniteElement &fine_fe) const
Definition: fe.cpp:185
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5850
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:218
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4024
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:3752
Array< int > dof_map
Definition: fe.hpp:1619
RT_TetrahedronElement(const int p)
Definition: fe.cpp:9668
ND_QuadrilateralElement(const int p, const int cp_type=Quadrature1D::GaussLobatto, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:10223
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5406
L2_TetrahedronElement(const int p, const int type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8791
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:3957
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:6582
BiQuad2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:1280
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:2272
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:2974
P0TriangleFiniteElement()
Construct P0 triangle finite element.
Definition: fe.cpp:2184
const double * ClosedPoints(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.hpp:1392
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:2458
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
RT_TriangleElement(const int p)
Definition: fe.cpp:9515
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:6563
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:10853
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:10144
void Eval(const double x, Vector &u) const
Definition: fe.cpp:6140
L2Pos_SegmentElement(const int p)
Definition: fe.cpp:8134
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:4221
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5461
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:3491
Vector data type.
Definition: vector.hpp:36
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:5392
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:142
static void CalcBernstein(const int p, const double x, double *u)
Definition: fe.hpp:1444
virtual void Transform(const IntegrationPoint &, Vector &)=0
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Evaluate the values of all shape functions of a scalar finite element in reference space at the given...
Definition: fe.cpp:7163
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:8414
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1201
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:9593
Quad2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:1118
virtual int GetSpaceDim()=0
Describes the space on each element.
Definition: fe.hpp:29
H1_QuadrilateralElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:6629
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2413
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5311
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:8333
void PositiveLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const PositiveFiniteElement &fine_fe) const
Definition: fe.cpp:379
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:10605
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:3809
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:1519
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:894
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:2082
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:2523
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:82
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6730
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:5362
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:3581
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4492
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:10895
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:682
int GetRangeType() const
Definition: fe.hpp:129
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:997
IntegrationRules IntRules(0, Quadrature1D::GaussLegendre)
A global object with all integration rules (defined in intrules.cpp)
Definition: intrules.hpp:343
int Order
Order/degree of the shape functions.
Definition: fe.hpp:49
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2879
H1_TriangleElement(const int p, const int type=Quadrature1D::GaussLobatto)
Definition: fe.cpp:7389
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:3782
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
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:6708
Basis(const int p, const double *nodes, const int _mode=1)
Definition: fe.cpp:6090
static void CalcDBinomTerms(const int p, const double x, const double y, double *d)
Definition: fe.cpp:6367
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:4975
TriLinear3DFiniteElement()
Construct a tri-linear FE on cube.
Definition: fe.cpp:2361
ND_SegmentElement(const int p, const int op_type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:10837
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:127
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
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:8393
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4079
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:3542
BiLinear2DFiniteElement()
Construct a bilinear FE on quadrilateral.
Definition: fe.cpp:902
L2_HexahedronElement(const int p, const int _type=Quadrature1D::GaussLegendre)
Definition: fe.cpp:8368
Poly_1D poly1d
Definition: fe.cpp:6535
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:6038
Lagrange1DFiniteElement(int degree)
Definition: fe.cpp:3594
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2622
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:5731
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8975
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8240
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:964
const int ir_order
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Evaluate the gradients of all shape functions of a scalar finite element in reference space at the gi...
Definition: fe.cpp:7478
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:598
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:419