MFEM  v3.1
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 "fem.hpp"
15 #include <cmath>
16 
17 namespace mfem
18 {
19 
20 using namespace std;
21 
22 FiniteElement::FiniteElement(int D, int G, int Do, int O, int F)
23  : Nodes(Do)
24 {
25  Dim = D ; GeomType = G ; Dof = Do ; Order = O ; FuncSpace = F;
26  RangeType = SCALAR;
27  MapType = VALUE;
28 }
29 
31  const IntegrationPoint &ip, DenseMatrix &shape) const
32 {
33  mfem_error ("FiniteElement::CalcVShape (...)\n"
34  " is not implemented for this class!");
35 }
36 
38  ElementTransformation &Trans, DenseMatrix &shape) const
39 {
40  mfem_error ("FiniteElement::CalcVShape 2 (...)\n"
41  " is not implemented for this class!");
42 }
43 
45  const IntegrationPoint &ip, Vector &divshape) const
46 {
47  mfem_error ("FiniteElement::CalcDivShape (...)\n"
48  " is not implemented for this class!");
49 }
50 
52  DenseMatrix &curl_shape) const
53 {
54  mfem_error ("FiniteElement::CalcCurlShape (...)\n"
55  " is not implemented for this class!");
56 }
57 
58 void FiniteElement::GetFaceDofs(int face, int **dofs, int *ndofs) const
59 {
60  mfem_error ("FiniteElement::GetFaceDofs (...)");
61 }
62 
64  DenseMatrix &h) const
65 {
66  mfem_error ("FiniteElement::CalcHessian (...) is not overloaded !");
67 }
68 
70  DenseMatrix &I) const
71 {
72  mfem_error ("GetLocalInterpolation (...) is not overloaded !");
73 }
74 
76  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
77 {
78  mfem_error ("FiniteElement::Project (...) is not overloaded !");
79 }
80 
82  VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
83 {
84  mfem_error ("FiniteElement::Project (...) (vector) is not overloaded !");
85 }
86 
87 void FiniteElement::ProjectDelta(int vertex, Vector &dofs) const
88 {
89  mfem_error("FiniteElement::ProjectDelta(...) is not implemented for "
90  "this element!");
91 }
92 
94  const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
95 {
96  mfem_error("FiniteElement::Project(...) (fe version) is not implemented "
97  "for this element!");
98 }
99 
101  const FiniteElement &fe, ElementTransformation &Trans,
102  DenseMatrix &grad) const
103 {
104  mfem_error("FiniteElement::ProjectGrad(...) is not implemented for "
105  "this element!");
106 }
107 
109  const FiniteElement &fe, ElementTransformation &Trans,
110  DenseMatrix &curl) const
111 {
112  mfem_error("FiniteElement::ProjectCurl(...) is not implemented for "
113  "this element!");
114 }
115 
117  const FiniteElement &fe, ElementTransformation &Trans,
118  DenseMatrix &div) const
119 {
120  mfem_error("FiniteElement::ProjectDiv(...) is not implemented for "
121  "this element!");
122 }
123 
124 
127  const NodalFiniteElement &fine_fe) const
128 {
129  double v[3];
130  Vector vv (v, Dim);
131  IntegrationPoint f_ip;
132 
133 #ifdef MFEM_THREAD_SAFE
134  Vector c_shape(Dof);
135 #endif
136 
137  MFEM_ASSERT(MapType == fine_fe.GetMapType(), "");
138 
139  for (int i = 0; i < fine_fe.Dof; i++)
140  {
141  Trans.Transform (fine_fe.Nodes.IntPoint (i), vv);
142  f_ip.Set(v, Dim);
143  CalcShape (f_ip, c_shape);
144  for (int j = 0; j < Dof; j++)
145  if (fabs (I (i,j) = c_shape (j)) < 1.0e-12)
146  {
147  I (i,j) = 0.0;
148  }
149  }
150  if (MapType == INTEGRAL)
151  {
152  // assuming Trans is linear; this should be ok for all refinement types
154  I *= Trans.Weight();
155  }
156 }
157 
159  const FiniteElement &fe, ElementTransformation &Trans,
160  DenseMatrix &curl) const
161 {
162  MFEM_ASSERT(GetMapType() == FiniteElement::INTEGRAL, "");
163 
164  DenseMatrix curl_shape(fe.GetDof(), 1);
165 
166  curl.SetSize(Dof, fe.GetDof());
167  for (int i = 0; i < Dof; i++)
168  {
169  fe.CalcCurlShape(Nodes.IntPoint(i), curl_shape);
170  for (int j = 0; j < fe.GetDof(); j++)
171  {
172  curl(i,j) = curl_shape(j,0);
173  }
174  }
175 }
176 
178  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
179 {
180  for (int i = 0; i < Dof; i++)
181  {
182  const IntegrationPoint &ip = Nodes.IntPoint(i);
183  // some coefficients expect that Trans.IntPoint is the same
184  // as the second argument of Eval
185  Trans.SetIntPoint(&ip);
186  dofs(i) = coeff.Eval (Trans, ip);
187  if (MapType == INTEGRAL)
188  {
189  dofs(i) *= Trans.Weight();
190  }
191  }
192 }
193 
195  VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
196 {
197  MFEM_ASSERT(vc.GetVDim() <= 3, "");
198 
199  double v[3];
200  Vector x (v, vc.GetVDim());
201 
202  for (int i = 0; i < Dof; i++)
203  {
204  const IntegrationPoint &ip = Nodes.IntPoint(i);
205  Trans.SetIntPoint(&ip);
206  vc.Eval (x, Trans, ip);
207  if (MapType == INTEGRAL)
208  {
209  x *= Trans.Weight();
210  }
211  for (int j = 0; j < x.Size(); j++)
212  {
213  dofs(Dof*j+i) = v[j];
214  }
215  }
216 }
217 
219  const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
220 {
221  if (fe.GetRangeType() == SCALAR)
222  {
223  MFEM_ASSERT(MapType == fe.GetMapType(), "");
224 
225  Vector shape(fe.GetDof());
226 
227  I.SetSize(Dof, fe.GetDof());
228  for (int k = 0; k < Dof; k++)
229  {
230  fe.CalcShape(Nodes.IntPoint(k), shape);
231  for (int j = 0; j < shape.Size(); j++)
232  {
233  I(k,j) = (fabs(shape(j)) < 1e-12) ? 0.0 : shape(j);
234  }
235  }
236  }
237  else
238  {
239  DenseMatrix vshape(fe.GetDof(), Dim);
240 
241  I.SetSize(Dim*Dof, fe.GetDof());
242  for (int k = 0; k < Dof; k++)
243  {
244  Trans.SetIntPoint(&Nodes.IntPoint(k));
245  fe.CalcVShape(Trans, vshape);
246  if (MapType == INTEGRAL)
247  {
248  vshape *= Trans.Weight();
249  }
250  for (int j = 0; j < vshape.Height(); j++)
251  for (int d = 0; d < vshape.Width(); d++)
252  {
253  I(k+d*Dof,j) = vshape(j,d);
254  }
255  }
256  }
257 }
258 
260  const FiniteElement &fe, ElementTransformation &Trans,
261  DenseMatrix &grad) const
262 {
263  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
264  MFEM_ASSERT(Trans.GetSpaceDim() == Dim, "")
265 
266  DenseMatrix dshape(fe.GetDof(), Dim), grad_k(fe.GetDof(), Dim), Jinv(Dim);
267 
268  grad.SetSize(Dim*Dof, fe.GetDof());
269  for (int k = 0; k < Dof; k++)
270  {
271  const IntegrationPoint &ip = Nodes.IntPoint(k);
272  fe.CalcDShape(ip, dshape);
273  Trans.SetIntPoint(&ip);
274  CalcInverse(Trans.Jacobian(), Jinv);
275  Mult(dshape, Jinv, grad_k);
276  if (MapType == INTEGRAL)
277  {
278  grad_k *= Trans.Weight();
279  }
280  for (int j = 0; j < grad_k.Height(); j++)
281  for (int d = 0; d < Dim; d++)
282  {
283  grad(k+d*Dof,j) = grad_k(j,d);
284  }
285  }
286 }
287 
289  const FiniteElement &fe, ElementTransformation &Trans,
290  DenseMatrix &div) const
291 {
292  double detJ;
293  Vector div_shape(fe.GetDof());
294 
295  div.SetSize(Dof, fe.GetDof());
296  for (int k = 0; k < Dof; k++)
297  {
298  const IntegrationPoint &ip = Nodes.IntPoint(k);
299  fe.CalcDivShape(ip, div_shape);
300  if (MapType == VALUE)
301  {
302  Trans.SetIntPoint(&ip);
303  detJ = Trans.Weight();
304  for (int j = 0; j < div_shape.Size(); j++)
305  {
306  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j)/detJ;
307  }
308  }
309  else
310  {
311  for (int j = 0; j < div_shape.Size(); j++)
312  {
313  div(k,j) = (fabs(div_shape(j)) < 1e-12) ? 0.0 : div_shape(j);
314  }
315  }
316  }
317 }
318 
319 
321  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
322 {
323  for (int i = 0; i < Dof; i++)
324  {
325  const IntegrationPoint &ip = Nodes.IntPoint(i);
326  Trans.SetIntPoint(&ip);
327  dofs(i) = coeff.Eval(Trans, ip);
328  }
329 }
330 
332  const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &I) const
333 {
334  const NodalFiniteElement *nfe =
335  dynamic_cast<const NodalFiniteElement *>(&fe);
336 
337  if (nfe && Dof == nfe->GetDof())
338  {
339  nfe->Project(*this, Trans, I);
340  I.Invert();
341  }
342  else
343  {
344  // local L2 projection
345  DenseMatrix pos_mass, mixed_mass;
346  MassIntegrator mass_integ;
347 
348  mass_integ.AssembleElementMatrix(*this, Trans, pos_mass);
349  mass_integ.AssembleElementMatrix2(fe, *this, Trans, mixed_mass);
350 
351  DenseMatrixInverse pos_mass_inv(pos_mass);
352  I.SetSize(Dof, fe.GetDof());
353  pos_mass_inv.Mult(mixed_mass, I);
354  }
355 }
356 
357 
358 void VectorFiniteElement::CalcShape (
359  const IntegrationPoint &ip, Vector &shape ) const
360 {
361  mfem_error ("Error: Cannot use scalar CalcShape(...) function with\n"
362  " VectorFiniteElements!");
363 }
364 
365 void VectorFiniteElement::CalcDShape (
366  const IntegrationPoint &ip, DenseMatrix &dshape ) const
367 {
368  mfem_error ("Error: Cannot use scalar CalcDShape(...) function with\n"
369  " VectorFiniteElements!");
370 }
371 
373  ElementTransformation &Trans, DenseMatrix &shape) const
374 {
375 #ifdef MFEM_THREAD_SAFE
377 #endif
378  CalcVShape(Trans.GetIntPoint(), vshape);
379 
380  MultABt(vshape, Trans.Jacobian(), shape);
381 
382  shape *= (1.0 / Trans.Weight());
383 }
384 
386  ElementTransformation &Trans, DenseMatrix &shape) const
387 {
388  const DenseMatrix &J = Trans.Jacobian();
389 
390 #ifdef MFEM_THREAD_SAFE
392  DenseMatrix Jinv(J.Width(), J.Height());
393 #else
394  Jinv.SetSize(J.Width(), J.Height());
395 #endif
396 
397  CalcInverse(J, Jinv);
398 
399  CalcVShape(Trans.GetIntPoint(), vshape);
400 
401  Mult(vshape, Jinv, shape);
402 }
403 
405  const double *nk, const Array<int> &d2n,
406  VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
407 {
408  double vk[3];
409  Vector xk(vk, vc.GetVDim());
410 #ifdef MFEM_THREAD_SAFE
411  DenseMatrix Jinv(Dim, vc.GetVDim());
412 #else
413  Jinv.SetSize(Dim, vc.GetVDim());
414 #endif
415  const bool square_J = (Jinv.Height() == Jinv.Width());
416 
417  for (int k = 0; k < Dof; k++)
418  {
419  Trans.SetIntPoint(&Nodes.IntPoint(k));
420  // set Jinv = |J| J^{-1} = adj(J), when J is square
421  // set Jinv = adj(J^t.J).J^t, otherwise
422  CalcAdjugate(Trans.Jacobian(), Jinv);
423 
424  vc.Eval(xk, Trans, Nodes.IntPoint(k));
425  // dof_k = nk^t adj(J) xk
426  dofs(k) = Jinv.InnerProduct(vk, nk + d2n[k]*Dim);
427  if (!square_J) { dofs(k) /= Trans.Weight(); }
428  }
429 }
430 
432  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
433  ElementTransformation &Trans, DenseMatrix &I) const
434 {
435  if (fe.GetRangeType() == SCALAR)
436  {
437  double vk[3];
438  Vector shape(fe.GetDof());
439  int sdim = Trans.GetSpaceDim();
440 #ifdef MFEM_THREAD_SAFE
441  DenseMatrix Jinv(Dim, sdim);
442 #endif
443 
444  I.SetSize(Dof, sdim*fe.GetDof());
445  for (int k = 0; k < Dof; k++)
446  {
447  const IntegrationPoint &ip = Nodes.IntPoint(k);
448 
449  fe.CalcShape(ip, shape);
450  Trans.SetIntPoint(&ip);
451  CalcAdjugate(Trans.Jacobian(), Jinv);
452  Jinv.MultTranspose(nk + d2n[k]*Dim, vk);
453  if (fe.GetMapType() == INTEGRAL)
454  {
455  double w = 1.0/Trans.Weight();
456  for (int d = 0; d < Dim; d++)
457  {
458  vk[d] *= w;
459  }
460  }
461 
462  for (int j = 0; j < shape.Size(); j++)
463  {
464  double s = shape(j);
465  if (fabs(s) < 1e-12)
466  {
467  s = 0.0;
468  }
469  for (int d = 0; d < sdim; d++)
470  {
471  I(k,j+d*shape.Size()) = s*vk[d];
472  }
473  }
474  }
475  }
476  else
477  {
478  mfem_error("VectorFiniteElement::Project_RT (fe version)");
479  }
480 }
481 
483  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
484  ElementTransformation &Trans, DenseMatrix &grad) const
485 {
486  if (Dim != 2)
487  {
488  mfem_error("VectorFiniteElement::ProjectGrad_RT works only in 2D!");
489  }
490 
491  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
492  Vector grad_k(fe.GetDof());
493  double tk[2];
494 
495  grad.SetSize(Dof, fe.GetDof());
496  for (int k = 0; k < Dof; k++)
497  {
498  fe.CalcDShape(Nodes.IntPoint(k), dshape);
499  tk[0] = nk[d2n[k]*Dim+1];
500  tk[1] = -nk[d2n[k]*Dim];
501  dshape.Mult(tk, grad_k);
502  for (int j = 0; j < grad_k.Size(); j++)
503  {
504  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
505  }
506  }
507 }
508 
510  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
511  ElementTransformation &Trans, DenseMatrix &curl) const
512 {
513 #ifdef MFEM_THREAD_SAFE
516  DenseMatrix J(Dim, Dim);
517 #else
518  curlshape.SetSize(fe.GetDof(), Dim);
519  curlshape_J.SetSize(fe.GetDof(), Dim);
520  J.SetSize(Dim, Dim);
521 #endif
522 
523  Vector curl_k(fe.GetDof());
524 
525  curl.SetSize(Dof, fe.GetDof());
526  for (int k = 0; k < Dof; k++)
527  {
528  const IntegrationPoint &ip = Nodes.IntPoint(k);
529 
530  // calculate J^t * J / |J|
531  Trans.SetIntPoint(&ip);
532  MultAtB(Trans.Jacobian(), Trans.Jacobian(), J);
533  J *= 1.0 / Trans.Weight();
534 
535  // transform curl of shapes (rows) by J^t * J / |J|
536  fe.CalcCurlShape(ip, curlshape);
538 
539  curlshape_J.Mult(tk + d2t[k]*Dim, curl_k);
540  for (int j = 0; j < curl_k.Size(); j++)
541  {
542  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
543  }
544  }
545 }
546 
548  const double *nk, const Array<int> &d2n, const FiniteElement &fe,
549  ElementTransformation &Trans, DenseMatrix &curl) const
550 {
551  DenseMatrix curl_shape(fe.GetDof(), Dim);
552  Vector curl_k(fe.GetDof());
553 
554  curl.SetSize(Dof, fe.GetDof());
555  for (int k = 0; k < Dof; k++)
556  {
557  fe.CalcCurlShape(Nodes.IntPoint(k), curl_shape);
558  curl_shape.Mult(nk + d2n[k]*Dim, curl_k);
559  for (int j = 0; j < curl_k.Size(); j++)
560  {
561  curl(k,j) = (fabs(curl_k(j)) < 1e-12) ? 0.0 : curl_k(j);
562  }
563  }
564 }
565 
567  const double *tk, const Array<int> &d2t,
568  VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
569 {
570  double vk[3];
571  Vector xk(vk, vc.GetVDim());
572 
573  for (int k = 0; k < Dof; k++)
574  {
575  Trans.SetIntPoint(&Nodes.IntPoint(k));
576 
577  vc.Eval(xk, Trans, Nodes.IntPoint(k));
578  // dof_k = xk^t J tk
579  dofs(k) = Trans.Jacobian().InnerProduct(tk + d2t[k]*Dim, vk);
580  }
581 }
582 
584  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
585  ElementTransformation &Trans, DenseMatrix &I) const
586 {
587  if (fe.GetRangeType() == SCALAR)
588  {
589  int sdim = Trans.GetSpaceDim();
590  double vk[3];
591  Vector shape(fe.GetDof());
592 
593  I.SetSize(Dof, sdim*fe.GetDof());
594  for (int k = 0; k < Dof; k++)
595  {
596  const IntegrationPoint &ip = Nodes.IntPoint(k);
597 
598  fe.CalcShape(ip, shape);
599  Trans.SetIntPoint(&ip);
600  Trans.Jacobian().Mult(tk + d2t[k]*Dim, vk);
601  if (fe.GetMapType() == INTEGRAL)
602  {
603  double w = 1.0/Trans.Weight();
604  for (int d = 0; d < sdim; d++)
605  {
606  vk[d] *= w;
607  }
608  }
609 
610  for (int j = 0; j < shape.Size(); j++)
611  {
612  double s = shape(j);
613  if (fabs(s) < 1e-12)
614  {
615  s = 0.0;
616  }
617  for (int d = 0; d < sdim; d++)
618  {
619  I(k, j + d*shape.Size()) = s*vk[d];
620  }
621  }
622  }
623  }
624  else
625  {
626  mfem_error("VectorFiniteElement::Project_ND (fe version)");
627  }
628 }
629 
631  const double *tk, const Array<int> &d2t, const FiniteElement &fe,
632  ElementTransformation &Trans, DenseMatrix &grad) const
633 {
634  MFEM_ASSERT(fe.GetMapType() == VALUE, "");
635 
636  DenseMatrix dshape(fe.GetDof(), fe.GetDim());
637  Vector grad_k(fe.GetDof());
638 
639  grad.SetSize(Dof, fe.GetDof());
640  for (int k = 0; k < Dof; k++)
641  {
642  fe.CalcDShape(Nodes.IntPoint(k), dshape);
643  dshape.Mult(tk + d2t[k]*Dim, grad_k);
644  for (int j = 0; j < grad_k.Size(); j++)
645  {
646  grad(k,j) = (fabs(grad_k(j)) < 1e-12) ? 0.0 : grad_k(j);
647  }
648  }
649 }
650 
652  const double *nk, const Array<int> &d2n, ElementTransformation &Trans,
653  DenseMatrix &I) const
654 {
655  double vk[3];
656  Vector xk(vk, Dim);
657  IntegrationPoint ip;
658 #ifdef MFEM_THREAD_SAFE
661 #endif
662 
663  // assuming Trans is linear; this should be ok for all refinement types
665  // set Jinv = |J| J^{-t} = adj(J)^t
667  for (int k = 0; k < Dof; k++)
668  {
669  Trans.Transform(Nodes.IntPoint(k), xk);
670  ip.Set3(vk);
671  CalcVShape(ip, vshape);
672  // xk = |J| J^{-t} n_k
673  Jinv.Mult(nk + d2n[k]*Dim, vk);
674  // I_k = vshape_k.adj(J)^t.n_k, k=1,...,Dof
675  for (int j = 0; j < Dof; j++)
676  {
677  double Ikj = 0.;
678  for (int i = 0; i < Dim; i++)
679  {
680  Ikj += vshape(j, i) * vk[i];
681  }
682  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
683  }
684  }
685 }
686 
688  const double *tk, const Array<int> &d2t, ElementTransformation &Trans,
689  DenseMatrix &I) const
690 {
691  double vk[3];
692  Vector xk(vk, Dim);
693  IntegrationPoint ip;
694 #ifdef MFEM_THREAD_SAFE
696 #endif
697 
698  // assuming Trans is linear; this should be ok for all refinement types
700  const DenseMatrix &J = Trans.Jacobian();
701  for (int k = 0; k < Dof; k++)
702  {
703  Trans.Transform(Nodes.IntPoint(k), xk);
704  ip.Set3(vk);
705  CalcVShape(ip, vshape);
706  // xk = J t_k
707  J.Mult(tk + d2t[k]*Dim, vk);
708  // I_k = vshape_k.J.t_k, k=1,...,Dof
709  for (int j = 0; j < Dof; j++)
710  {
711  double Ikj = 0.;
712  for (int i = 0; i < Dim; i++)
713  {
714  Ikj += vshape(j, i) * vk[i];
715  }
716  I(k, j) = (fabs(Ikj) < 1e-12) ? 0.0 : Ikj;
717  }
718  }
719 }
720 
721 
723  : NodalFiniteElement(0, Geometry::POINT, 1, 0)
724 {
725  Nodes.IntPoint(0).x = 0.0;
726 }
727 
729  Vector &shape) const
730 {
731  shape(0) = 1.;
732 }
733 
735  DenseMatrix &dshape) const
736 {
737  // doesn't make sense
738 }
739 
741  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
742 {
743  Nodes.IntPoint(0).x = 0.0;
744  Nodes.IntPoint(1).x = 1.0;
745 }
746 
748  Vector &shape) const
749 {
750  shape(0) = 1. - ip.x;
751  shape(1) = ip.x;
752 }
753 
755  DenseMatrix &dshape) const
756 {
757  dshape(0,0) = -1.;
758  dshape(1,0) = 1.;
759 }
760 
762  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1)
763 {
764  Nodes.IntPoint(0).x = 0.0;
765  Nodes.IntPoint(0).y = 0.0;
766  Nodes.IntPoint(1).x = 1.0;
767  Nodes.IntPoint(1).y = 0.0;
768  Nodes.IntPoint(2).x = 0.0;
769  Nodes.IntPoint(2).y = 1.0;
770 }
771 
773  Vector &shape) const
774 {
775  shape(0) = 1. - ip.x - ip.y;
776  shape(1) = ip.x;
777  shape(2) = ip.y;
778 }
779 
781  DenseMatrix &dshape) const
782 {
783  dshape(0,0) = -1.; dshape(0,1) = -1.;
784  dshape(1,0) = 1.; dshape(1,1) = 0.;
785  dshape(2,0) = 0.; dshape(2,1) = 1.;
786 }
787 
789  : NodalFiniteElement(2, Geometry::SQUARE , 4, 1, FunctionSpace::Qk)
790 {
791  Nodes.IntPoint(0).x = 0.0;
792  Nodes.IntPoint(0).y = 0.0;
793  Nodes.IntPoint(1).x = 1.0;
794  Nodes.IntPoint(1).y = 0.0;
795  Nodes.IntPoint(2).x = 1.0;
796  Nodes.IntPoint(2).y = 1.0;
797  Nodes.IntPoint(3).x = 0.0;
798  Nodes.IntPoint(3).y = 1.0;
799 }
800 
802  Vector &shape) const
803 {
804  shape(0) = (1. - ip.x) * (1. - ip.y) ;
805  shape(1) = ip.x * (1. - ip.y) ;
806  shape(2) = ip.x * ip.y ;
807  shape(3) = (1. - ip.x) * ip.y ;
808 }
809 
811  DenseMatrix &dshape) const
812 {
813  dshape(0,0) = -1. + ip.y; dshape(0,1) = -1. + ip.x ;
814  dshape(1,0) = 1. - ip.y; dshape(1,1) = -ip.x ;
815  dshape(2,0) = ip.y ; dshape(2,1) = ip.x ;
816  dshape(3,0) = -ip.y ; dshape(3,1) = 1. - ip.x ;
817 }
818 
820  const IntegrationPoint &ip, DenseMatrix &h) const
821 {
822  h( 0,0) = 0.; h( 0,1) = 1.; h( 0,2) = 0.;
823  h( 1,0) = 0.; h( 1,1) = -1.; h( 1,2) = 0.;
824  h( 2,0) = 0.; h( 2,1) = 1.; h( 2,2) = 0.;
825  h( 3,0) = 0.; h( 3,1) = -1.; h( 3,2) = 0.;
826 }
827 
828 
830  : NodalFiniteElement(2, Geometry::TRIANGLE, 3, 1, FunctionSpace::Pk)
831 {
832  Nodes.IntPoint(0).x = 1./6.;
833  Nodes.IntPoint(0).y = 1./6.;
834  Nodes.IntPoint(1).x = 2./3.;
835  Nodes.IntPoint(1).y = 1./6.;
836  Nodes.IntPoint(2).x = 1./6.;
837  Nodes.IntPoint(2).y = 2./3.;
838 }
839 
841  Vector &shape) const
842 {
843  const double x = ip.x, y = ip.y;
844 
845  shape(0) = 5./3. - 2. * (x + y);
846  shape(1) = 2. * (x - 1./6.);
847  shape(2) = 2. * (y - 1./6.);
848 }
849 
851  DenseMatrix &dshape) const
852 {
853  dshape(0,0) = -2.; dshape(0,1) = -2.;
854  dshape(1,0) = 2.; dshape(1,1) = 0.;
855  dshape(2,0) = 0.; dshape(2,1) = 2.;
856 }
857 
859 {
860  dofs(vertex) = 2./3.;
861  dofs((vertex+1)%3) = 1./6.;
862  dofs((vertex+2)%3) = 1./6.;
863 }
864 
865 
866 // 0.5-0.5/sqrt(3) and 0.5+0.5/sqrt(3)
867 const double GaussBiLinear2DFiniteElement::p[] =
868 { 0.2113248654051871177454256, 0.7886751345948128822545744 };
869 
871  : NodalFiniteElement(2, Geometry::SQUARE, 4, 1, FunctionSpace::Qk)
872 {
873  Nodes.IntPoint(0).x = p[0];
874  Nodes.IntPoint(0).y = p[0];
875  Nodes.IntPoint(1).x = p[1];
876  Nodes.IntPoint(1).y = p[0];
877  Nodes.IntPoint(2).x = p[1];
878  Nodes.IntPoint(2).y = p[1];
879  Nodes.IntPoint(3).x = p[0];
880  Nodes.IntPoint(3).y = p[1];
881 }
882 
884  Vector &shape) const
885 {
886  const double x = ip.x, y = ip.y;
887 
888  shape(0) = 3. * (p[1] - x) * (p[1] - y);
889  shape(1) = 3. * (x - p[0]) * (p[1] - y);
890  shape(2) = 3. * (x - p[0]) * (y - p[0]);
891  shape(3) = 3. * (p[1] - x) * (y - p[0]);
892 }
893 
895  DenseMatrix &dshape) const
896 {
897  const double x = ip.x, y = ip.y;
898 
899  dshape(0,0) = 3. * (y - p[1]); dshape(0,1) = 3. * (x - p[1]);
900  dshape(1,0) = 3. * (p[1] - y); dshape(1,1) = 3. * (p[0] - x);
901  dshape(2,0) = 3. * (y - p[0]); dshape(2,1) = 3. * (x - p[0]);
902  dshape(3,0) = 3. * (p[0] - y); dshape(3,1) = 3. * (p[1] - x);
903 }
904 
906 {
907 #if 1
908  dofs(vertex) = p[1]*p[1];
909  dofs((vertex+1)%4) = p[0]*p[1];
910  dofs((vertex+2)%4) = p[0]*p[0];
911  dofs((vertex+3)%4) = p[0]*p[1];
912 #else
913  dofs = 1.0;
914 #endif
915 }
916 
917 
919  : NodalFiniteElement(2, Geometry::SQUARE , 3, 1, FunctionSpace::Qk)
920 {
921  Nodes.IntPoint(0).x = 0.0;
922  Nodes.IntPoint(0).y = 0.0;
923  Nodes.IntPoint(1).x = 1.0;
924  Nodes.IntPoint(1).y = 0.0;
925  Nodes.IntPoint(2).x = 0.0;
926  Nodes.IntPoint(2).y = 1.0;
927 }
928 
930  Vector &shape) const
931 {
932  shape(0) = 1. - ip.x - ip.y;
933  shape(1) = ip.x;
934  shape(2) = ip.y;
935 }
936 
938  DenseMatrix &dshape) const
939 {
940  dshape(0,0) = -1.; dshape(0,1) = -1.;
941  dshape(1,0) = 1.; dshape(1,1) = 0.;
942  dshape(2,0) = 0.; dshape(2,1) = 1.;
943 }
944 
945 
947  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
948 {
949  Nodes.IntPoint(0).x = 0.0;
950  Nodes.IntPoint(1).x = 1.0;
951  Nodes.IntPoint(2).x = 0.5;
952 }
953 
955  Vector &shape) const
956 {
957  double x = ip.x;
958  double l1 = 1.0 - x, l2 = x, l3 = 2. * x - 1.;
959 
960  shape(0) = l1 * (-l3);
961  shape(1) = l2 * l3;
962  shape(2) = 4. * l1 * l2;
963 }
964 
966  DenseMatrix &dshape) const
967 {
968  double x = ip.x;
969 
970  dshape(0,0) = 4. * x - 3.;
971  dshape(1,0) = 4. * x - 1.;
972  dshape(2,0) = 4. - 8. * x;
973 }
974 
975 
977  : FiniteElement(1, Geometry::SEGMENT, 3, 2)
978 {
979  Nodes.IntPoint(0).x = 0.0;
980  Nodes.IntPoint(1).x = 1.0;
981  Nodes.IntPoint(2).x = 0.5;
982 }
983 
985  Vector &shape) const
986 {
987  const double x = ip.x, x1 = 1. - x;
988 
989  shape(0) = x1 * x1;
990  shape(1) = x * x;
991  shape(2) = 2. * x * x1;
992 }
993 
995  DenseMatrix &dshape) const
996 {
997  const double x = ip.x;
998 
999  dshape(0,0) = 2. * x - 2.;
1000  dshape(1,0) = 2. * x;
1001  dshape(2,0) = 2. - 4. * x;
1002 }
1003 
1005  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2)
1006 {
1007  Nodes.IntPoint(0).x = 0.0;
1008  Nodes.IntPoint(0).y = 0.0;
1009  Nodes.IntPoint(1).x = 1.0;
1010  Nodes.IntPoint(1).y = 0.0;
1011  Nodes.IntPoint(2).x = 0.0;
1012  Nodes.IntPoint(2).y = 1.0;
1013  Nodes.IntPoint(3).x = 0.5;
1014  Nodes.IntPoint(3).y = 0.0;
1015  Nodes.IntPoint(4).x = 0.5;
1016  Nodes.IntPoint(4).y = 0.5;
1017  Nodes.IntPoint(5).x = 0.0;
1018  Nodes.IntPoint(5).y = 0.5;
1019 }
1020 
1022  Vector &shape) const
1023 {
1024  double x = ip.x, y = ip.y;
1025  double l1 = 1.-x-y, l2 = x, l3 = y;
1026 
1027  shape(0) = l1 * (2. * l1 - 1.);
1028  shape(1) = l2 * (2. * l2 - 1.);
1029  shape(2) = l3 * (2. * l3 - 1.);
1030  shape(3) = 4. * l1 * l2;
1031  shape(4) = 4. * l2 * l3;
1032  shape(5) = 4. * l3 * l1;
1033 }
1034 
1036  DenseMatrix &dshape) const
1037 {
1038  double x = ip.x, y = ip.y;
1039 
1040  dshape(0,0) =
1041  dshape(0,1) = 4. * (x + y) - 3.;
1042 
1043  dshape(1,0) = 4. * x - 1.;
1044  dshape(1,1) = 0.;
1045 
1046  dshape(2,0) = 0.;
1047  dshape(2,1) = 4. * y - 1.;
1048 
1049  dshape(3,0) = -4. * (2. * x + y - 1.);
1050  dshape(3,1) = -4. * x;
1051 
1052  dshape(4,0) = 4. * y;
1053  dshape(4,1) = 4. * x;
1054 
1055  dshape(5,0) = -4. * y;
1056  dshape(5,1) = -4. * (x + 2. * y - 1.);
1057 }
1058 
1060  DenseMatrix &h) const
1061 {
1062  h(0,0) = 4.;
1063  h(0,1) = 4.;
1064  h(0,2) = 4.;
1065 
1066  h(1,0) = 4.;
1067  h(1,1) = 0.;
1068  h(1,2) = 0.;
1069 
1070  h(2,0) = 0.;
1071  h(2,1) = 0.;
1072  h(2,2) = 4.;
1073 
1074  h(3,0) = -8.;
1075  h(3,1) = -4.;
1076  h(3,2) = 0.;
1077 
1078  h(4,0) = 0.;
1079  h(4,1) = 4.;
1080  h(4,2) = 0.;
1081 
1082  h(5,0) = 0.;
1083  h(5,1) = -4.;
1084  h(5,2) = -8.;
1085 }
1086 
1087 void Quad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1088 {
1089 #if 0
1090  dofs = 1.;
1091 #else
1092  dofs = 0.;
1093  dofs(vertex) = 1.;
1094  switch (vertex)
1095  {
1096  case 0: dofs(3) = 0.25; dofs(5) = 0.25; break;
1097  case 1: dofs(3) = 0.25; dofs(4) = 0.25; break;
1098  case 2: dofs(4) = 0.25; dofs(5) = 0.25; break;
1099  }
1100 #endif
1101 }
1102 
1103 
1104 const double GaussQuad2DFiniteElement::p[] =
1105 { 0.0915762135097707434595714634022015, 0.445948490915964886318329253883051 };
1106 
1108  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 2), A(6), D(6,2), pol(6)
1109 {
1110  Nodes.IntPoint(0).x = p[0];
1111  Nodes.IntPoint(0).y = p[0];
1112  Nodes.IntPoint(1).x = 1. - 2. * p[0];
1113  Nodes.IntPoint(1).y = p[0];
1114  Nodes.IntPoint(2).x = p[0];
1115  Nodes.IntPoint(2).y = 1. - 2. * p[0];
1116  Nodes.IntPoint(3).x = p[1];
1117  Nodes.IntPoint(3).y = p[1];
1118  Nodes.IntPoint(4).x = 1. - 2. * p[1];
1119  Nodes.IntPoint(4).y = p[1];
1120  Nodes.IntPoint(5).x = p[1];
1121  Nodes.IntPoint(5).y = 1. - 2. * p[1];
1122 
1123  for (int i = 0; i < 6; i++)
1124  {
1125  const double x = Nodes.IntPoint(i).x, y = Nodes.IntPoint(i).y;
1126  A(0,i) = 1.;
1127  A(1,i) = x;
1128  A(2,i) = y;
1129  A(3,i) = x * x;
1130  A(4,i) = x * y;
1131  A(5,i) = y * y;
1132  }
1133 
1134  A.Invert();
1135 }
1136 
1138  Vector &shape) const
1139 {
1140  const double x = ip.x, y = ip.y;
1141  pol(0) = 1.;
1142  pol(1) = x;
1143  pol(2) = y;
1144  pol(3) = x * x;
1145  pol(4) = x * y;
1146  pol(5) = y * y;
1147 
1148  A.Mult(pol, shape);
1149 }
1150 
1152  DenseMatrix &dshape) const
1153 {
1154  const double x = ip.x, y = ip.y;
1155  D(0,0) = 0.; D(0,1) = 0.;
1156  D(1,0) = 1.; D(1,1) = 0.;
1157  D(2,0) = 0.; D(2,1) = 1.;
1158  D(3,0) = 2. * x; D(3,1) = 0.;
1159  D(4,0) = y; D(4,1) = x;
1160  D(5,0) = 0.; D(5,1) = 2. * y;
1161 
1162  Mult(A, D, dshape);
1163 }
1164 
1165 
1167  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1168 {
1169  Nodes.IntPoint(0).x = 0.0;
1170  Nodes.IntPoint(0).y = 0.0;
1171  Nodes.IntPoint(1).x = 1.0;
1172  Nodes.IntPoint(1).y = 0.0;
1173  Nodes.IntPoint(2).x = 1.0;
1174  Nodes.IntPoint(2).y = 1.0;
1175  Nodes.IntPoint(3).x = 0.0;
1176  Nodes.IntPoint(3).y = 1.0;
1177  Nodes.IntPoint(4).x = 0.5;
1178  Nodes.IntPoint(4).y = 0.0;
1179  Nodes.IntPoint(5).x = 1.0;
1180  Nodes.IntPoint(5).y = 0.5;
1181  Nodes.IntPoint(6).x = 0.5;
1182  Nodes.IntPoint(6).y = 1.0;
1183  Nodes.IntPoint(7).x = 0.0;
1184  Nodes.IntPoint(7).y = 0.5;
1185  Nodes.IntPoint(8).x = 0.5;
1186  Nodes.IntPoint(8).y = 0.5;
1187 }
1188 
1190  Vector &shape) const
1191 {
1192  double x = ip.x, y = ip.y;
1193  double l1x, l2x, l3x, l1y, l2y, l3y;
1194 
1195  l1x = (x - 1.) * (2. * x - 1);
1196  l2x = 4. * x * (1. - x);
1197  l3x = x * (2. * x - 1.);
1198  l1y = (y - 1.) * (2. * y - 1);
1199  l2y = 4. * y * (1. - y);
1200  l3y = y * (2. * y - 1.);
1201 
1202  shape(0) = l1x * l1y;
1203  shape(4) = l2x * l1y;
1204  shape(1) = l3x * l1y;
1205  shape(7) = l1x * l2y;
1206  shape(8) = l2x * l2y;
1207  shape(5) = l3x * l2y;
1208  shape(3) = l1x * l3y;
1209  shape(6) = l2x * l3y;
1210  shape(2) = l3x * l3y;
1211 }
1212 
1214  DenseMatrix &dshape) const
1215 {
1216  double x = ip.x, y = ip.y;
1217  double l1x, l2x, l3x, l1y, l2y, l3y;
1218  double d1x, d2x, d3x, d1y, d2y, d3y;
1219 
1220  l1x = (x - 1.) * (2. * x - 1);
1221  l2x = 4. * x * (1. - x);
1222  l3x = x * (2. * x - 1.);
1223  l1y = (y - 1.) * (2. * y - 1);
1224  l2y = 4. * y * (1. - y);
1225  l3y = y * (2. * y - 1.);
1226 
1227  d1x = 4. * x - 3.;
1228  d2x = 4. - 8. * x;
1229  d3x = 4. * x - 1.;
1230  d1y = 4. * y - 3.;
1231  d2y = 4. - 8. * y;
1232  d3y = 4. * y - 1.;
1233 
1234  dshape(0,0) = d1x * l1y;
1235  dshape(0,1) = l1x * d1y;
1236 
1237  dshape(4,0) = d2x * l1y;
1238  dshape(4,1) = l2x * d1y;
1239 
1240  dshape(1,0) = d3x * l1y;
1241  dshape(1,1) = l3x * d1y;
1242 
1243  dshape(7,0) = d1x * l2y;
1244  dshape(7,1) = l1x * d2y;
1245 
1246  dshape(8,0) = d2x * l2y;
1247  dshape(8,1) = l2x * d2y;
1248 
1249  dshape(5,0) = d3x * l2y;
1250  dshape(5,1) = l3x * d2y;
1251 
1252  dshape(3,0) = d1x * l3y;
1253  dshape(3,1) = l1x * d3y;
1254 
1255  dshape(6,0) = d2x * l3y;
1256  dshape(6,1) = l2x * d3y;
1257 
1258  dshape(2,0) = d3x * l3y;
1259  dshape(2,1) = l3x * d3y;
1260 }
1261 
1262 void BiQuad2DFiniteElement::ProjectDelta(int vertex, Vector &dofs) const
1263 {
1264 #if 0
1265  dofs = 1.;
1266 #else
1267  dofs = 0.;
1268  dofs(vertex) = 1.;
1269  switch (vertex)
1270  {
1271  case 0: dofs(4) = 0.25; dofs(7) = 0.25; break;
1272  case 1: dofs(4) = 0.25; dofs(5) = 0.25; break;
1273  case 2: dofs(5) = 0.25; dofs(6) = 0.25; break;
1274  case 3: dofs(6) = 0.25; dofs(7) = 0.25; break;
1275  }
1276  dofs(8) = 1./16.;
1277 #endif
1278 }
1279 
1281  : FiniteElement(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 = (1. - x) * (1. - x);
1310  l2x = 2. * x * (1. - x);
1311  l3x = x * x;
1312  l1y = (1. - y) * (1. - y);
1313  l2y = 2. * y * (1. - y);
1314  l3y = y * y;
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 = (1. - x) * (1. - x);
1335  l2x = 2. * x * (1. - x);
1336  l3x = x * x;
1337  l1y = (1. - y) * (1. - y);
1338  l2y = 2. * y * (1. - y);
1339  l3y = y * y;
1340 
1341  d1x = 2. * x - 2.;
1342  d2x = 2. - 4. * x;
1343  d3x = 2. * x;
1344  d1y = 2. * y - 2.;
1345  d2y = 2. - 4. * y;
1346  d3y = 2. * y;
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 
1377  ElementTransformation &Trans, DenseMatrix &I) const
1378 {
1379  double s[9];
1380  IntegrationPoint tr_ip;
1381  Vector xx(&tr_ip.x, 2), shape(s, 9);
1382 
1383  for (int i = 0; i < 9; i++)
1384  {
1385  Trans.Transform(Nodes.IntPoint(i), xx);
1386  CalcShape(tr_ip, shape);
1387  for (int j = 0; j < 9; j++)
1388  if (fabs(I(i,j) = s[j]) < 1.0e-12)
1389  {
1390  I(i,j) = 0.0;
1391  }
1392  }
1393  for (int i = 0; i < 9; i++)
1394  {
1395  double *d = &I(0,i);
1396  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1397  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1398  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1399  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1400  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1401  0.25 * (d[0] + d[1] + d[2] + d[3]);
1402  }
1403 }
1404 
1406  Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
1407 {
1408  double *d = dofs;
1409 
1410  for (int i = 0; i < 9; i++)
1411  {
1412  const IntegrationPoint &ip = Nodes.IntPoint(i);
1413  Trans.SetIntPoint(&ip);
1414  d[i] = coeff.Eval(Trans, ip);
1415  }
1416  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1417  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1418  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1419  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1420  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1421  0.25 * (d[0] + d[1] + d[2] + d[3]);
1422 }
1423 
1426  Vector &dofs) const
1427 {
1428  double v[3];
1429  Vector x (v, vc.GetVDim());
1430 
1431  for (int i = 0; i < 9; i++)
1432  {
1433  const IntegrationPoint &ip = Nodes.IntPoint(i);
1434  Trans.SetIntPoint(&ip);
1435  vc.Eval (x, Trans, ip);
1436  for (int j = 0; j < x.Size(); j++)
1437  {
1438  dofs(9*j+i) = v[j];
1439  }
1440  }
1441  for (int j = 0; j < x.Size(); j++)
1442  {
1443  double *d = &dofs(9*j);
1444 
1445  d[4] = 2. * d[4] - 0.5 * (d[0] + d[1]);
1446  d[5] = 2. * d[5] - 0.5 * (d[1] + d[2]);
1447  d[6] = 2. * d[6] - 0.5 * (d[2] + d[3]);
1448  d[7] = 2. * d[7] - 0.5 * (d[3] + d[0]);
1449  d[8] = 4. * d[8] - 0.5 * (d[4] + d[5] + d[6] + d[7]) -
1450  0.25 * (d[0] + d[1] + d[2] + d[3]);
1451  }
1452 }
1453 
1454 
1456  : NodalFiniteElement(2, Geometry::SQUARE, 9, 2, FunctionSpace::Qk)
1457 {
1458  const double p1 = 0.5*(1.-sqrt(3./5.));
1459 
1460  Nodes.IntPoint(0).x = p1;
1461  Nodes.IntPoint(0).y = p1;
1462  Nodes.IntPoint(4).x = 0.5;
1463  Nodes.IntPoint(4).y = p1;
1464  Nodes.IntPoint(1).x = 1.-p1;
1465  Nodes.IntPoint(1).y = p1;
1466  Nodes.IntPoint(7).x = p1;
1467  Nodes.IntPoint(7).y = 0.5;
1468  Nodes.IntPoint(8).x = 0.5;
1469  Nodes.IntPoint(8).y = 0.5;
1470  Nodes.IntPoint(5).x = 1.-p1;
1471  Nodes.IntPoint(5).y = 0.5;
1472  Nodes.IntPoint(3).x = p1;
1473  Nodes.IntPoint(3).y = 1.-p1;
1474  Nodes.IntPoint(6).x = 0.5;
1475  Nodes.IntPoint(6).y = 1.-p1;
1476  Nodes.IntPoint(2).x = 1.-p1;
1477  Nodes.IntPoint(2).y = 1.-p1;
1478 }
1479 
1481  Vector &shape) const
1482 {
1483  const double a = sqrt(5./3.);
1484  const double p1 = 0.5*(1.-sqrt(3./5.));
1485 
1486  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1487  double l1x, l2x, l3x, l1y, l2y, l3y;
1488 
1489  l1x = (x - 1.) * (2. * x - 1);
1490  l2x = 4. * x * (1. - x);
1491  l3x = x * (2. * x - 1.);
1492  l1y = (y - 1.) * (2. * y - 1);
1493  l2y = 4. * y * (1. - y);
1494  l3y = y * (2. * y - 1.);
1495 
1496  shape(0) = l1x * l1y;
1497  shape(4) = l2x * l1y;
1498  shape(1) = l3x * l1y;
1499  shape(7) = l1x * l2y;
1500  shape(8) = l2x * l2y;
1501  shape(5) = l3x * l2y;
1502  shape(3) = l1x * l3y;
1503  shape(6) = l2x * l3y;
1504  shape(2) = l3x * l3y;
1505 }
1506 
1508  DenseMatrix &dshape) const
1509 {
1510  const double a = sqrt(5./3.);
1511  const double p1 = 0.5*(1.-sqrt(3./5.));
1512 
1513  double x = a*(ip.x-p1), y = a*(ip.y-p1);
1514  double l1x, l2x, l3x, l1y, l2y, l3y;
1515  double d1x, d2x, d3x, d1y, d2y, d3y;
1516 
1517  l1x = (x - 1.) * (2. * x - 1);
1518  l2x = 4. * x * (1. - x);
1519  l3x = x * (2. * x - 1.);
1520  l1y = (y - 1.) * (2. * y - 1);
1521  l2y = 4. * y * (1. - y);
1522  l3y = y * (2. * y - 1.);
1523 
1524  d1x = a * (4. * x - 3.);
1525  d2x = a * (4. - 8. * x);
1526  d3x = a * (4. * x - 1.);
1527  d1y = a * (4. * y - 3.);
1528  d2y = a * (4. - 8. * y);
1529  d3y = a * (4. * y - 1.);
1530 
1531  dshape(0,0) = d1x * l1y;
1532  dshape(0,1) = l1x * d1y;
1533 
1534  dshape(4,0) = d2x * l1y;
1535  dshape(4,1) = l2x * d1y;
1536 
1537  dshape(1,0) = d3x * l1y;
1538  dshape(1,1) = l3x * d1y;
1539 
1540  dshape(7,0) = d1x * l2y;
1541  dshape(7,1) = l1x * d2y;
1542 
1543  dshape(8,0) = d2x * l2y;
1544  dshape(8,1) = l2x * d2y;
1545 
1546  dshape(5,0) = d3x * l2y;
1547  dshape(5,1) = l3x * d2y;
1548 
1549  dshape(3,0) = d1x * l3y;
1550  dshape(3,1) = l1x * d3y;
1551 
1552  dshape(6,0) = d2x * l3y;
1553  dshape(6,1) = l2x * d3y;
1554 
1555  dshape(2,0) = d3x * l3y;
1556  dshape(2,1) = l3x * d3y;
1557 }
1558 
1560  : NodalFiniteElement (2, Geometry::SQUARE, 16, 3, FunctionSpace::Qk)
1561 {
1562  Nodes.IntPoint(0).x = 0.;
1563  Nodes.IntPoint(0).y = 0.;
1564  Nodes.IntPoint(1).x = 1.;
1565  Nodes.IntPoint(1).y = 0.;
1566  Nodes.IntPoint(2).x = 1.;
1567  Nodes.IntPoint(2).y = 1.;
1568  Nodes.IntPoint(3).x = 0.;
1569  Nodes.IntPoint(3).y = 1.;
1570  Nodes.IntPoint(4).x = 1./3.;
1571  Nodes.IntPoint(4).y = 0.;
1572  Nodes.IntPoint(5).x = 2./3.;
1573  Nodes.IntPoint(5).y = 0.;
1574  Nodes.IntPoint(6).x = 1.;
1575  Nodes.IntPoint(6).y = 1./3.;
1576  Nodes.IntPoint(7).x = 1.;
1577  Nodes.IntPoint(7).y = 2./3.;
1578  Nodes.IntPoint(8).x = 2./3.;
1579  Nodes.IntPoint(8).y = 1.;
1580  Nodes.IntPoint(9).x = 1./3.;
1581  Nodes.IntPoint(9).y = 1.;
1582  Nodes.IntPoint(10).x = 0.;
1583  Nodes.IntPoint(10).y = 2./3.;
1584  Nodes.IntPoint(11).x = 0.;
1585  Nodes.IntPoint(11).y = 1./3.;
1586  Nodes.IntPoint(12).x = 1./3.;
1587  Nodes.IntPoint(12).y = 1./3.;
1588  Nodes.IntPoint(13).x = 2./3.;
1589  Nodes.IntPoint(13).y = 1./3.;
1590  Nodes.IntPoint(14).x = 1./3.;
1591  Nodes.IntPoint(14).y = 2./3.;
1592  Nodes.IntPoint(15).x = 2./3.;
1593  Nodes.IntPoint(15).y = 2./3.;
1594 }
1595 
1597  const IntegrationPoint &ip, Vector &shape) const
1598 {
1599  double x = ip.x, y = ip.y;
1600 
1601  double w1x, w2x, w3x, w1y, w2y, w3y;
1602  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1603 
1604  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1605  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1606 
1607  l0x = (- 4.5) * w1x * w2x * w3x;
1608  l1x = ( 13.5) * x * w2x * w3x;
1609  l2x = (-13.5) * x * w1x * w3x;
1610  l3x = ( 4.5) * x * w1x * w2x;
1611 
1612  l0y = (- 4.5) * w1y * w2y * w3y;
1613  l1y = ( 13.5) * y * w2y * w3y;
1614  l2y = (-13.5) * y * w1y * w3y;
1615  l3y = ( 4.5) * y * w1y * w2y;
1616 
1617  shape(0) = l0x * l0y;
1618  shape(1) = l3x * l0y;
1619  shape(2) = l3x * l3y;
1620  shape(3) = l0x * l3y;
1621  shape(4) = l1x * l0y;
1622  shape(5) = l2x * l0y;
1623  shape(6) = l3x * l1y;
1624  shape(7) = l3x * l2y;
1625  shape(8) = l2x * l3y;
1626  shape(9) = l1x * l3y;
1627  shape(10) = l0x * l2y;
1628  shape(11) = l0x * l1y;
1629  shape(12) = l1x * l1y;
1630  shape(13) = l2x * l1y;
1631  shape(14) = l1x * l2y;
1632  shape(15) = l2x * l2y;
1633 }
1634 
1636  const IntegrationPoint &ip, DenseMatrix &dshape) const
1637 {
1638  double x = ip.x, y = ip.y;
1639 
1640  double w1x, w2x, w3x, w1y, w2y, w3y;
1641  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1642  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1643 
1644  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1645  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1646 
1647  l0x = (- 4.5) * w1x * w2x * w3x;
1648  l1x = ( 13.5) * x * w2x * w3x;
1649  l2x = (-13.5) * x * w1x * w3x;
1650  l3x = ( 4.5) * x * w1x * w2x;
1651 
1652  l0y = (- 4.5) * w1y * w2y * w3y;
1653  l1y = ( 13.5) * y * w2y * w3y;
1654  l2y = (-13.5) * y * w1y * w3y;
1655  l3y = ( 4.5) * y * w1y * w2y;
1656 
1657  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1658  d1x = 9. + (-45. + 40.5 * x) * x;
1659  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1660  d3x = 1. + (- 9. + 13.5 * x) * x;
1661 
1662  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1663  d1y = 9. + (-45. + 40.5 * y) * y;
1664  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1665  d3y = 1. + (- 9. + 13.5 * y) * y;
1666 
1667  dshape( 0,0) = d0x * l0y; dshape( 0,1) = l0x * d0y;
1668  dshape( 1,0) = d3x * l0y; dshape( 1,1) = l3x * d0y;
1669  dshape( 2,0) = d3x * l3y; dshape( 2,1) = l3x * d3y;
1670  dshape( 3,0) = d0x * l3y; dshape( 3,1) = l0x * d3y;
1671  dshape( 4,0) = d1x * l0y; dshape( 4,1) = l1x * d0y;
1672  dshape( 5,0) = d2x * l0y; dshape( 5,1) = l2x * d0y;
1673  dshape( 6,0) = d3x * l1y; dshape( 6,1) = l3x * d1y;
1674  dshape( 7,0) = d3x * l2y; dshape( 7,1) = l3x * d2y;
1675  dshape( 8,0) = d2x * l3y; dshape( 8,1) = l2x * d3y;
1676  dshape( 9,0) = d1x * l3y; dshape( 9,1) = l1x * d3y;
1677  dshape(10,0) = d0x * l2y; dshape(10,1) = l0x * d2y;
1678  dshape(11,0) = d0x * l1y; dshape(11,1) = l0x * d1y;
1679  dshape(12,0) = d1x * l1y; dshape(12,1) = l1x * d1y;
1680  dshape(13,0) = d2x * l1y; dshape(13,1) = l2x * d1y;
1681  dshape(14,0) = d1x * l2y; dshape(14,1) = l1x * d2y;
1682  dshape(15,0) = d2x * l2y; dshape(15,1) = l2x * d2y;
1683 }
1684 
1686  const IntegrationPoint &ip, DenseMatrix &h) const
1687 {
1688  double x = ip.x, y = ip.y;
1689 
1690  double w1x, w2x, w3x, w1y, w2y, w3y;
1691  double l0x, l1x, l2x, l3x, l0y, l1y, l2y, l3y;
1692  double d0x, d1x, d2x, d3x, d0y, d1y, d2y, d3y;
1693  double h0x, h1x, h2x, h3x, h0y, h1y, h2y, h3y;
1694 
1695  w1x = x - 1./3.; w2x = x - 2./3.; w3x = x - 1.;
1696  w1y = y - 1./3.; w2y = y - 2./3.; w3y = y - 1.;
1697 
1698  l0x = (- 4.5) * w1x * w2x * w3x;
1699  l1x = ( 13.5) * x * w2x * w3x;
1700  l2x = (-13.5) * x * w1x * w3x;
1701  l3x = ( 4.5) * x * w1x * w2x;
1702 
1703  l0y = (- 4.5) * w1y * w2y * w3y;
1704  l1y = ( 13.5) * y * w2y * w3y;
1705  l2y = (-13.5) * y * w1y * w3y;
1706  l3y = ( 4.5) * y * w1y * w2y;
1707 
1708  d0x = -5.5 + ( 18. - 13.5 * x) * x;
1709  d1x = 9. + (-45. + 40.5 * x) * x;
1710  d2x = -4.5 + ( 36. - 40.5 * x) * x;
1711  d3x = 1. + (- 9. + 13.5 * x) * x;
1712 
1713  d0y = -5.5 + ( 18. - 13.5 * y) * y;
1714  d1y = 9. + (-45. + 40.5 * y) * y;
1715  d2y = -4.5 + ( 36. - 40.5 * y) * y;
1716  d3y = 1. + (- 9. + 13.5 * y) * y;
1717 
1718  h0x = -27. * x + 18.;
1719  h1x = 81. * x - 45.;
1720  h2x = -81. * x + 36.;
1721  h3x = 27. * x - 9.;
1722 
1723  h0y = -27. * y + 18.;
1724  h1y = 81. * y - 45.;
1725  h2y = -81. * y + 36.;
1726  h3y = 27. * y - 9.;
1727 
1728  h( 0,0) = h0x * l0y; h( 0,1) = d0x * d0y; h( 0,2) = l0x * h0y;
1729  h( 1,0) = h3x * l0y; h( 1,1) = d3x * d0y; h( 1,2) = l3x * h0y;
1730  h( 2,0) = h3x * l3y; h( 2,1) = d3x * d3y; h( 2,2) = l3x * h3y;
1731  h( 3,0) = h0x * l3y; h( 3,1) = d0x * d3y; h( 3,2) = l0x * h3y;
1732  h( 4,0) = h1x * l0y; h( 4,1) = d1x * d0y; h( 4,2) = l1x * h0y;
1733  h( 5,0) = h2x * l0y; h( 5,1) = d2x * d0y; h( 5,2) = l2x * h0y;
1734  h( 6,0) = h3x * l1y; h( 6,1) = d3x * d1y; h( 6,2) = l3x * h1y;
1735  h( 7,0) = h3x * l2y; h( 7,1) = d3x * d2y; h( 7,2) = l3x * h2y;
1736  h( 8,0) = h2x * l3y; h( 8,1) = d2x * d3y; h( 8,2) = l2x * h3y;
1737  h( 9,0) = h1x * l3y; h( 9,1) = d1x * d3y; h( 9,2) = l1x * h3y;
1738  h(10,0) = h0x * l2y; h(10,1) = d0x * d2y; h(10,2) = l0x * h2y;
1739  h(11,0) = h0x * l1y; h(11,1) = d0x * d1y; h(11,2) = l0x * h1y;
1740  h(12,0) = h1x * l1y; h(12,1) = d1x * d1y; h(12,2) = l1x * h1y;
1741  h(13,0) = h2x * l1y; h(13,1) = d2x * d1y; h(13,2) = l2x * h1y;
1742  h(14,0) = h1x * l2y; h(14,1) = d1x * d2y; h(14,2) = l1x * h2y;
1743  h(15,0) = h2x * l2y; h(15,1) = d2x * d2y; h(15,2) = l2x * h2y;
1744 }
1745 
1746 
1748  : NodalFiniteElement(1, Geometry::SEGMENT, 4, 3)
1749 {
1750  Nodes.IntPoint(0).x = 0.0;
1751  Nodes.IntPoint(1).x = 1.0;
1752  Nodes.IntPoint(2).x = 0.33333333333333333333;
1753  Nodes.IntPoint(3).x = 0.66666666666666666667;
1754 }
1755 
1757  Vector &shape) const
1758 {
1759  double x = ip.x;
1760  double l1 = x,
1761  l2 = (1.0-x),
1762  l3 = (0.33333333333333333333-x),
1763  l4 = (0.66666666666666666667-x);
1764 
1765  shape(0) = 4.5 * l2 * l3 * l4;
1766  shape(1) = 4.5 * l1 * l3 * l4;
1767  shape(2) = 13.5 * l1 * l2 * l4;
1768  shape(3) = -13.5 * l1 * l2 * l3;
1769 }
1770 
1772  DenseMatrix &dshape) const
1773 {
1774  double x = ip.x;
1775 
1776  dshape(0,0) = -5.5 + x * (18. - 13.5 * x);
1777  dshape(1,0) = 1. - x * (9. - 13.5 * x);
1778  dshape(2,0) = 9. - x * (45. - 40.5 * x);
1779  dshape(3,0) = -4.5 + x * (36. - 40.5 * x);
1780 }
1781 
1782 
1784  : NodalFiniteElement(2, Geometry::TRIANGLE, 10, 3)
1785 {
1786  Nodes.IntPoint(0).x = 0.0;
1787  Nodes.IntPoint(0).y = 0.0;
1788  Nodes.IntPoint(1).x = 1.0;
1789  Nodes.IntPoint(1).y = 0.0;
1790  Nodes.IntPoint(2).x = 0.0;
1791  Nodes.IntPoint(2).y = 1.0;
1792  Nodes.IntPoint(3).x = 0.33333333333333333333;
1793  Nodes.IntPoint(3).y = 0.0;
1794  Nodes.IntPoint(4).x = 0.66666666666666666667;
1795  Nodes.IntPoint(4).y = 0.0;
1796  Nodes.IntPoint(5).x = 0.66666666666666666667;
1797  Nodes.IntPoint(5).y = 0.33333333333333333333;
1798  Nodes.IntPoint(6).x = 0.33333333333333333333;
1799  Nodes.IntPoint(6).y = 0.66666666666666666667;
1800  Nodes.IntPoint(7).x = 0.0;
1801  Nodes.IntPoint(7).y = 0.66666666666666666667;
1802  Nodes.IntPoint(8).x = 0.0;
1803  Nodes.IntPoint(8).y = 0.33333333333333333333;
1804  Nodes.IntPoint(9).x = 0.33333333333333333333;
1805  Nodes.IntPoint(9).y = 0.33333333333333333333;
1806 }
1807 
1809  Vector &shape) const
1810 {
1811  double x = ip.x, y = ip.y;
1812  double l1 = (-1. + x + y),
1813  lx = (-1. + 3.*x),
1814  ly = (-1. + 3.*y);
1815 
1816  shape(0) = -0.5*l1*(3.*l1 + 1.)*(3.*l1 + 2.);
1817  shape(1) = 0.5*x*(lx - 1.)*lx;
1818  shape(2) = 0.5*y*(-1. + ly)*ly;
1819  shape(3) = 4.5*x*l1*(3.*l1 + 1.);
1820  shape(4) = -4.5*x*lx*l1;
1821  shape(5) = 4.5*x*lx*y;
1822  shape(6) = 4.5*x*y*ly;
1823  shape(7) = -4.5*y*l1*ly;
1824  shape(8) = 4.5*y*l1*(1. + 3.*l1);
1825  shape(9) = -27.*x*y*l1;
1826 }
1827 
1829  DenseMatrix &dshape) const
1830 {
1831  double x = ip.x, y = ip.y;
1832 
1833  dshape(0,0) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
1834  dshape(1,0) = 1. + 4.5*x*(-2. + 3.*x);
1835  dshape(2,0) = 0.;
1836  dshape(3,0) = 4.5*(2. + 9.*x*x - 5.*y + 3.*y*y + 2.*x*(-5. + 6.*y));
1837  dshape(4,0) = -4.5*(1. - 1.*y + x*(-8. + 9.*x + 6.*y));
1838  dshape(5,0) = 4.5*(-1. + 6.*x)*y;
1839  dshape(6,0) = 4.5*y*(-1. + 3.*y);
1840  dshape(7,0) = 4.5*(1. - 3.*y)*y;
1841  dshape(8,0) = 4.5*y*(-5. + 6.*x + 6.*y);
1842  dshape(9,0) = -27.*y*(-1. + 2.*x + y);
1843 
1844  dshape(0,1) = 0.5*(-11. + 36.*y - 9.*(x*(-4. + 3.*x) + 6.*x*y + 3.*y*y));
1845  dshape(1,1) = 0.;
1846  dshape(2,1) = 1. + 4.5*y*(-2. + 3.*y);
1847  dshape(3,1) = 4.5*x*(-5. + 6.*x + 6.*y);
1848  dshape(4,1) = 4.5*(1. - 3.*x)*x;
1849  dshape(5,1) = 4.5*x*(-1. + 3.*x);
1850  dshape(6,1) = 4.5*x*(-1. + 6.*y);
1851  dshape(7,1) = -4.5*(1. + x*(-1. + 6.*y) + y*(-8. + 9.*y));
1852  dshape(8,1) = 4.5*(2. + 3.*x*x + y*(-10. + 9.*y) + x*(-5. + 12.*y));
1853  dshape(9,1) = -27.*x*(-1. + x + 2.*y);
1854 }
1855 
1857  DenseMatrix &h) const
1858 {
1859  double x = ip.x, y = ip.y;
1860 
1861  h(0,0) = 18.-27.*(x+y);
1862  h(0,1) = 18.-27.*(x+y);
1863  h(0,2) = 18.-27.*(x+y);
1864 
1865  h(1,0) = -9.+27.*x;
1866  h(1,1) = 0.;
1867  h(1,2) = 0.;
1868 
1869  h(2,0) = 0.;
1870  h(2,1) = 0.;
1871  h(2,2) = -9.+27.*y;
1872 
1873  h(3,0) = -45.+81.*x+54.*y;
1874  h(3,1) = -22.5+54.*x+27.*y;
1875  h(3,2) = 27.*x;
1876 
1877  h(4,0) = 36.-81.*x-27.*y;
1878  h(4,1) = 4.5-27.*x;
1879  h(4,2) = 0.;
1880 
1881  h(5,0) = 27.*y;
1882  h(5,1) = -4.5+27.*x;
1883  h(5,2) = 0.;
1884 
1885  h(6,0) = 0.;
1886  h(6,1) = -4.5+27.*y;
1887  h(6,2) = 27.*x;
1888 
1889  h(7,0) = 0.;
1890  h(7,1) = 4.5-27.*y;
1891  h(7,2) = 36.-27.*x-81.*y;
1892 
1893  h(8,0) = 27.*y;
1894  h(8,1) = -22.5+27.*x+54.*y;
1895  h(8,2) = -45.+54.*x+81.*y;
1896 
1897  h(9,0) = -54.*y;
1898  h(9,1) = 27.-54.*(x+y);
1899  h(9,2) = -54.*x;
1900 }
1901 
1902 
1904  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 20, 3)
1905 {
1906  Nodes.IntPoint(0).x = 0;
1907  Nodes.IntPoint(0).y = 0;
1908  Nodes.IntPoint(0).z = 0;
1909  Nodes.IntPoint(1).x = 1.;
1910  Nodes.IntPoint(1).y = 0;
1911  Nodes.IntPoint(1).z = 0;
1912  Nodes.IntPoint(2).x = 0;
1913  Nodes.IntPoint(2).y = 1.;
1914  Nodes.IntPoint(2).z = 0;
1915  Nodes.IntPoint(3).x = 0;
1916  Nodes.IntPoint(3).y = 0;
1917  Nodes.IntPoint(3).z = 1.;
1918  Nodes.IntPoint(4).x = 0.3333333333333333333333333333;
1919  Nodes.IntPoint(4).y = 0;
1920  Nodes.IntPoint(4).z = 0;
1921  Nodes.IntPoint(5).x = 0.6666666666666666666666666667;
1922  Nodes.IntPoint(5).y = 0;
1923  Nodes.IntPoint(5).z = 0;
1924  Nodes.IntPoint(6).x = 0;
1925  Nodes.IntPoint(6).y = 0.3333333333333333333333333333;
1926  Nodes.IntPoint(6).z = 0;
1927  Nodes.IntPoint(7).x = 0;
1928  Nodes.IntPoint(7).y = 0.6666666666666666666666666667;
1929  Nodes.IntPoint(7).z = 0;
1930  Nodes.IntPoint(8).x = 0;
1931  Nodes.IntPoint(8).y = 0;
1932  Nodes.IntPoint(8).z = 0.3333333333333333333333333333;
1933  Nodes.IntPoint(9).x = 0;
1934  Nodes.IntPoint(9).y = 0;
1935  Nodes.IntPoint(9).z = 0.6666666666666666666666666667;
1936  Nodes.IntPoint(10).x = 0.6666666666666666666666666667;
1937  Nodes.IntPoint(10).y = 0.3333333333333333333333333333;
1938  Nodes.IntPoint(10).z = 0;
1939  Nodes.IntPoint(11).x = 0.3333333333333333333333333333;
1940  Nodes.IntPoint(11).y = 0.6666666666666666666666666667;
1941  Nodes.IntPoint(11).z = 0;
1942  Nodes.IntPoint(12).x = 0.6666666666666666666666666667;
1943  Nodes.IntPoint(12).y = 0;
1944  Nodes.IntPoint(12).z = 0.3333333333333333333333333333;
1945  Nodes.IntPoint(13).x = 0.3333333333333333333333333333;
1946  Nodes.IntPoint(13).y = 0;
1947  Nodes.IntPoint(13).z = 0.6666666666666666666666666667;
1948  Nodes.IntPoint(14).x = 0;
1949  Nodes.IntPoint(14).y = 0.6666666666666666666666666667;
1950  Nodes.IntPoint(14).z = 0.3333333333333333333333333333;
1951  Nodes.IntPoint(15).x = 0;
1952  Nodes.IntPoint(15).y = 0.3333333333333333333333333333;
1953  Nodes.IntPoint(15).z = 0.6666666666666666666666666667;
1954  Nodes.IntPoint(16).x = 0.3333333333333333333333333333;
1955  Nodes.IntPoint(16).y = 0.3333333333333333333333333333;
1956  Nodes.IntPoint(16).z = 0.3333333333333333333333333333;
1957  Nodes.IntPoint(17).x = 0;
1958  Nodes.IntPoint(17).y = 0.3333333333333333333333333333;
1959  Nodes.IntPoint(17).z = 0.3333333333333333333333333333;
1960  Nodes.IntPoint(18).x = 0.3333333333333333333333333333;
1961  Nodes.IntPoint(18).y = 0;
1962  Nodes.IntPoint(18).z = 0.3333333333333333333333333333;
1963  Nodes.IntPoint(19).x = 0.3333333333333333333333333333;
1964  Nodes.IntPoint(19).y = 0.3333333333333333333333333333;
1965  Nodes.IntPoint(19).z = 0;
1966 }
1967 
1969  Vector &shape) const
1970 {
1971  double x = ip.x, y = ip.y, z = ip.z;
1972 
1973  shape(0) = -((-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z)*
1974  (-1 + 3*x + 3*y + 3*z))/2.;
1975  shape(4) = (9*x*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
1976  shape(5) = (-9*x*(-1 + 3*x)*(-1 + x + y + z))/2.;
1977  shape(1) = (x*(2 + 9*(-1 + x)*x))/2.;
1978  shape(6) = (9*y*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
1979  shape(19) = -27*x*y*(-1 + x + y + z);
1980  shape(10) = (9*x*(-1 + 3*x)*y)/2.;
1981  shape(7) = (-9*y*(-1 + 3*y)*(-1 + x + y + z))/2.;
1982  shape(11) = (9*x*y*(-1 + 3*y))/2.;
1983  shape(2) = (y*(2 + 9*(-1 + y)*y))/2.;
1984  shape(8) = (9*z*(-1 + x + y + z)*(-2 + 3*x + 3*y + 3*z))/2.;
1985  shape(18) = -27*x*z*(-1 + x + y + z);
1986  shape(12) = (9*x*(-1 + 3*x)*z)/2.;
1987  shape(17) = -27*y*z*(-1 + x + y + z);
1988  shape(16) = 27*x*y*z;
1989  shape(14) = (9*y*(-1 + 3*y)*z)/2.;
1990  shape(9) = (-9*z*(-1 + x + y + z)*(-1 + 3*z))/2.;
1991  shape(13) = (9*x*z*(-1 + 3*z))/2.;
1992  shape(15) = (9*y*z*(-1 + 3*z))/2.;
1993  shape(3) = (z*(2 + 9*(-1 + z)*z))/2.;
1994 }
1995 
1997  DenseMatrix &dshape) const
1998 {
1999  double x = ip.x, y = ip.y, z = ip.z;
2000 
2001  dshape(0,0) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2002  x*(-4 + 6*y + 6*z)))/2.;
2003  dshape(0,1) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2004  x*(-4 + 6*y + 6*z)))/2.;
2005  dshape(0,2) = (-11 + 36*y + 36*z - 9*(3*pow(x,2) + 3*pow(y + z,2) +
2006  x*(-4 + 6*y + 6*z)))/2.;
2007  dshape(4,0) = (9*(9*pow(x,2) + (-1 + y + z)*(-2 + 3*y + 3*z) +
2008  2*x*(-5 + 6*y + 6*z)))/2.;
2009  dshape(4,1) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2010  dshape(4,2) = (9*x*(-5 + 6*x + 6*y + 6*z))/2.;
2011  dshape(5,0) = (-9*(1 - y - z + x*(-8 + 9*x + 6*y + 6*z)))/2.;
2012  dshape(5,1) = (9*(1 - 3*x)*x)/2.;
2013  dshape(5,2) = (9*(1 - 3*x)*x)/2.;
2014  dshape(1,0) = 1 + (9*x*(-2 + 3*x))/2.;
2015  dshape(1,1) = 0;
2016  dshape(1,2) = 0;
2017  dshape(6,0) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2018  dshape(6,1) = (9*(2 + 3*pow(x,2) - 10*y - 5*z + 3*(y + z)*(3*y + z) +
2019  x*(-5 + 12*y + 6*z)))/2.;
2020  dshape(6,2) = (9*y*(-5 + 6*x + 6*y + 6*z))/2.;
2021  dshape(19,0) = -27*y*(-1 + 2*x + y + z);
2022  dshape(19,1) = -27*x*(-1 + x + 2*y + z);
2023  dshape(19,2) = -27*x*y;
2024  dshape(10,0) = (9*(-1 + 6*x)*y)/2.;
2025  dshape(10,1) = (9*x*(-1 + 3*x))/2.;
2026  dshape(10,2) = 0;
2027  dshape(7,0) = (9*(1 - 3*y)*y)/2.;
2028  dshape(7,1) = (-9*(1 + x*(-1 + 6*y) - z + y*(-8 + 9*y + 6*z)))/2.;
2029  dshape(7,2) = (9*(1 - 3*y)*y)/2.;
2030  dshape(11,0) = (9*y*(-1 + 3*y))/2.;
2031  dshape(11,1) = (9*x*(-1 + 6*y))/2.;
2032  dshape(11,2) = 0;
2033  dshape(2,0) = 0;
2034  dshape(2,1) = 1 + (9*y*(-2 + 3*y))/2.;
2035  dshape(2,2) = 0;
2036  dshape(8,0) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2037  dshape(8,1) = (9*z*(-5 + 6*x + 6*y + 6*z))/2.;
2038  dshape(8,2) = (9*(2 + 3*pow(x,2) - 5*y - 10*z + 3*(y + z)*(y + 3*z) +
2039  x*(-5 + 6*y + 12*z)))/2.;
2040  dshape(18,0) = -27*z*(-1 + 2*x + y + z);
2041  dshape(18,1) = -27*x*z;
2042  dshape(18,2) = -27*x*(-1 + x + y + 2*z);
2043  dshape(12,0) = (9*(-1 + 6*x)*z)/2.;
2044  dshape(12,1) = 0;
2045  dshape(12,2) = (9*x*(-1 + 3*x))/2.;
2046  dshape(17,0) = -27*y*z;
2047  dshape(17,1) = -27*z*(-1 + x + 2*y + z);
2048  dshape(17,2) = -27*y*(-1 + x + y + 2*z);
2049  dshape(16,0) = 27*y*z;
2050  dshape(16,1) = 27*x*z;
2051  dshape(16,2) = 27*x*y;
2052  dshape(14,0) = 0;
2053  dshape(14,1) = (9*(-1 + 6*y)*z)/2.;
2054  dshape(14,2) = (9*y*(-1 + 3*y))/2.;
2055  dshape(9,0) = (9*(1 - 3*z)*z)/2.;
2056  dshape(9,1) = (9*(1 - 3*z)*z)/2.;
2057  dshape(9,2) = (9*(-1 + x + y + 8*z - 6*(x + y)*z - 9*pow(z,2)))/2.;
2058  dshape(13,0) = (9*z*(-1 + 3*z))/2.;
2059  dshape(13,1) = 0;
2060  dshape(13,2) = (9*x*(-1 + 6*z))/2.;
2061  dshape(15,0) = 0;
2062  dshape(15,1) = (9*z*(-1 + 3*z))/2.;
2063  dshape(15,2) = (9*y*(-1 + 6*z))/2.;
2064  dshape(3,0) = 0;
2065  dshape(3,1) = 0;
2066  dshape(3,2) = 1 + (9*z*(-2 + 3*z))/2.;
2067 }
2068 
2069 
2071  : NodalFiniteElement(2, Geometry::TRIANGLE , 1, 0)
2072 {
2073  Nodes.IntPoint(0).x = 0.333333333333333333;
2074  Nodes.IntPoint(0).y = 0.333333333333333333;
2075 }
2076 
2078  Vector &shape) const
2079 {
2080  shape(0) = 1.0;
2081 }
2082 
2084  DenseMatrix &dshape) const
2085 {
2086  dshape(0,0) = 0.0;
2087  dshape(0,1) = 0.0;
2088 }
2089 
2090 
2092  : NodalFiniteElement(2, Geometry::SQUARE , 1, 0, FunctionSpace::Qk)
2093 {
2094  Nodes.IntPoint(0).x = 0.5;
2095  Nodes.IntPoint(0).y = 0.5;
2096 }
2097 
2099  Vector &shape) const
2100 {
2101  shape(0) = 1.0;
2102 }
2103 
2105  DenseMatrix &dshape) const
2106 {
2107  dshape(0,0) = 0.0;
2108  dshape(0,1) = 0.0;
2109 }
2110 
2111 
2113  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
2114 {
2115  Nodes.IntPoint(0).x = 0.0;
2116  Nodes.IntPoint(0).y = 0.0;
2117  Nodes.IntPoint(0).z = 0.0;
2118  Nodes.IntPoint(1).x = 1.0;
2119  Nodes.IntPoint(1).y = 0.0;
2120  Nodes.IntPoint(1).z = 0.0;
2121  Nodes.IntPoint(2).x = 0.0;
2122  Nodes.IntPoint(2).y = 1.0;
2123  Nodes.IntPoint(2).z = 0.0;
2124  Nodes.IntPoint(3).x = 0.0;
2125  Nodes.IntPoint(3).y = 0.0;
2126  Nodes.IntPoint(3).z = 1.0;
2127 }
2128 
2130  Vector &shape) const
2131 {
2132  shape(0) = 1. - ip.x - ip.y - ip.z;
2133  shape(1) = ip.x;
2134  shape(2) = ip.y;
2135  shape(3) = ip.z;
2136 }
2137 
2139  DenseMatrix &dshape) const
2140 {
2141  if (dshape.Height() == 4)
2142  {
2143  double *A = &dshape(0,0);
2144  A[0] = -1.; A[4] = -1.; A[8] = -1.;
2145  A[1] = 1.; A[5] = 0.; A[9] = 0.;
2146  A[2] = 0.; A[6] = 1.; A[10] = 0.;
2147  A[3] = 0.; A[7] = 0.; A[11] = 1.;
2148  }
2149  else
2150  {
2151  dshape(0,0) = -1.; dshape(0,1) = -1.; dshape(0,2) = -1.;
2152  dshape(1,0) = 1.; dshape(1,1) = 0.; dshape(1,2) = 0.;
2153  dshape(2,0) = 0.; dshape(2,1) = 1.; dshape(2,2) = 0.;
2154  dshape(3,0) = 0.; dshape(3,1) = 0.; dshape(3,2) = 1.;
2155  }
2156 }
2157 
2158 void Linear3DFiniteElement::GetFaceDofs (int face, int **dofs, int *ndofs)
2159 const
2160 {
2161  static int face_dofs[4][3] = {{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}};
2162 
2163  *ndofs = 3;
2164  *dofs = face_dofs[face];
2165 }
2166 
2167 
2169  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 2)
2170 {
2171  Nodes.IntPoint(0).x = 0.0;
2172  Nodes.IntPoint(0).y = 0.0;
2173  Nodes.IntPoint(0).z = 0.0;
2174  Nodes.IntPoint(1).x = 1.0;
2175  Nodes.IntPoint(1).y = 0.0;
2176  Nodes.IntPoint(1).z = 0.0;
2177  Nodes.IntPoint(2).x = 0.0;
2178  Nodes.IntPoint(2).y = 1.0;
2179  Nodes.IntPoint(2).z = 0.0;
2180  Nodes.IntPoint(3).x = 0.0;
2181  Nodes.IntPoint(3).y = 0.0;
2182  Nodes.IntPoint(3).z = 1.0;
2183  Nodes.IntPoint(4).x = 0.5;
2184  Nodes.IntPoint(4).y = 0.0;
2185  Nodes.IntPoint(4).z = 0.0;
2186  Nodes.IntPoint(5).x = 0.0;
2187  Nodes.IntPoint(5).y = 0.5;
2188  Nodes.IntPoint(5).z = 0.0;
2189  Nodes.IntPoint(6).x = 0.0;
2190  Nodes.IntPoint(6).y = 0.0;
2191  Nodes.IntPoint(6).z = 0.5;
2192  Nodes.IntPoint(7).x = 0.5;
2193  Nodes.IntPoint(7).y = 0.5;
2194  Nodes.IntPoint(7).z = 0.0;
2195  Nodes.IntPoint(8).x = 0.5;
2196  Nodes.IntPoint(8).y = 0.0;
2197  Nodes.IntPoint(8).z = 0.5;
2198  Nodes.IntPoint(9).x = 0.0;
2199  Nodes.IntPoint(9).y = 0.5;
2200  Nodes.IntPoint(9).z = 0.5;
2201 }
2202 
2204  Vector &shape) const
2205 {
2206  double L0, L1, L2, L3;
2207 
2208  L0 = 1. - ip.x - ip.y - ip.z;
2209  L1 = ip.x;
2210  L2 = ip.y;
2211  L3 = ip.z;
2212 
2213  shape(0) = L0 * ( 2.0 * L0 - 1.0 );
2214  shape(1) = L1 * ( 2.0 * L1 - 1.0 );
2215  shape(2) = L2 * ( 2.0 * L2 - 1.0 );
2216  shape(3) = L3 * ( 2.0 * L3 - 1.0 );
2217  shape(4) = 4.0 * L0 * L1;
2218  shape(5) = 4.0 * L0 * L2;
2219  shape(6) = 4.0 * L0 * L3;
2220  shape(7) = 4.0 * L1 * L2;
2221  shape(8) = 4.0 * L1 * L3;
2222  shape(9) = 4.0 * L2 * L3;
2223 }
2224 
2226  DenseMatrix &dshape) const
2227 {
2228  double x, y, z, L0;
2229 
2230  x = ip.x;
2231  y = ip.y;
2232  z = ip.z;
2233  L0 = 1.0 - x - y - z;
2234 
2235  dshape(0,0) = dshape(0,1) = dshape(0,2) = 1.0 - 4.0 * L0;
2236  dshape(1,0) = -1.0 + 4.0 * x; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
2237  dshape(2,0) = 0.0; dshape(2,1) = -1.0 + 4.0 * y; dshape(2,2) = 0.0;
2238  dshape(3,0) = dshape(3,1) = 0.0; dshape(3,2) = -1.0 + 4.0 * z;
2239  dshape(4,0) = 4.0 * (L0 - x); dshape(4,1) = dshape(4,2) = -4.0 * x;
2240  dshape(5,0) = dshape(5,2) = -4.0 * y; dshape(5,1) = 4.0 * (L0 - y);
2241  dshape(6,0) = dshape(6,1) = -4.0 * z; dshape(6,2) = 4.0 * (L0 - z);
2242  dshape(7,0) = 4.0 * y; dshape(7,1) = 4.0 * x; dshape(7,2) = 0.0;
2243  dshape(8,0) = 4.0 * z; dshape(8,1) = 0.0; dshape(8,2) = 4.0 * x;
2244  dshape(9,0) = 0.0; dshape(9,1) = 4.0 * z; dshape(9,2) = 4.0 * y;
2245 }
2246 
2248  : NodalFiniteElement(3, Geometry::CUBE, 8, 1, FunctionSpace::Qk)
2249 {
2250  Nodes.IntPoint(0).x = 0.0;
2251  Nodes.IntPoint(0).y = 0.0;
2252  Nodes.IntPoint(0).z = 0.0;
2253 
2254  Nodes.IntPoint(1).x = 1.0;
2255  Nodes.IntPoint(1).y = 0.0;
2256  Nodes.IntPoint(1).z = 0.0;
2257 
2258  Nodes.IntPoint(2).x = 1.0;
2259  Nodes.IntPoint(2).y = 1.0;
2260  Nodes.IntPoint(2).z = 0.0;
2261 
2262  Nodes.IntPoint(3).x = 0.0;
2263  Nodes.IntPoint(3).y = 1.0;
2264  Nodes.IntPoint(3).z = 0.0;
2265 
2266  Nodes.IntPoint(4).x = 0.0;
2267  Nodes.IntPoint(4).y = 0.0;
2268  Nodes.IntPoint(4).z = 1.0;
2269 
2270  Nodes.IntPoint(5).x = 1.0;
2271  Nodes.IntPoint(5).y = 0.0;
2272  Nodes.IntPoint(5).z = 1.0;
2273 
2274  Nodes.IntPoint(6).x = 1.0;
2275  Nodes.IntPoint(6).y = 1.0;
2276  Nodes.IntPoint(6).z = 1.0;
2277 
2278  Nodes.IntPoint(7).x = 0.0;
2279  Nodes.IntPoint(7).y = 1.0;
2280  Nodes.IntPoint(7).z = 1.0;
2281 }
2282 
2284  Vector &shape) const
2285 {
2286  double x = ip.x, y = ip.y, z = ip.z;
2287  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2288 
2289  shape(0) = ox * oy * oz;
2290  shape(1) = x * oy * oz;
2291  shape(2) = x * y * oz;
2292  shape(3) = ox * y * oz;
2293  shape(4) = ox * oy * z;
2294  shape(5) = x * oy * z;
2295  shape(6) = x * y * z;
2296  shape(7) = ox * y * z;
2297 }
2298 
2300  DenseMatrix &dshape) const
2301 {
2302  double x = ip.x, y = ip.y, z = ip.z;
2303  double ox = 1.-x, oy = 1.-y, oz = 1.-z;
2304 
2305  dshape(0,0) = - oy * oz;
2306  dshape(0,1) = - ox * oz;
2307  dshape(0,2) = - ox * oy;
2308 
2309  dshape(1,0) = oy * oz;
2310  dshape(1,1) = - x * oz;
2311  dshape(1,2) = - x * oy;
2312 
2313  dshape(2,0) = y * oz;
2314  dshape(2,1) = x * oz;
2315  dshape(2,2) = - x * y;
2316 
2317  dshape(3,0) = - y * oz;
2318  dshape(3,1) = ox * oz;
2319  dshape(3,2) = - ox * y;
2320 
2321  dshape(4,0) = - oy * z;
2322  dshape(4,1) = - ox * z;
2323  dshape(4,2) = ox * oy;
2324 
2325  dshape(5,0) = oy * z;
2326  dshape(5,1) = - x * z;
2327  dshape(5,2) = x * oy;
2328 
2329  dshape(6,0) = y * z;
2330  dshape(6,1) = x * z;
2331  dshape(6,2) = x * y;
2332 
2333  dshape(7,0) = - y * z;
2334  dshape(7,1) = ox * z;
2335  dshape(7,2) = ox * y;
2336 }
2337 
2339  : NodalFiniteElement(1, Geometry::SEGMENT , 1, Ord) // defaul Ord = 0
2340 {
2341  Nodes.IntPoint(0).x = 0.5;
2342 }
2343 
2345  Vector &shape) const
2346 {
2347  shape(0) = 1.0;
2348 }
2349 
2351  DenseMatrix &dshape) const
2352 {
2353  dshape(0,0) = 0.0;
2354 }
2355 
2357  : NodalFiniteElement(2, Geometry::TRIANGLE , 3, 1)
2358 {
2359  Nodes.IntPoint(0).x = 0.5;
2360  Nodes.IntPoint(0).y = 0.0;
2361  Nodes.IntPoint(1).x = 0.5;
2362  Nodes.IntPoint(1).y = 0.5;
2363  Nodes.IntPoint(2).x = 0.0;
2364  Nodes.IntPoint(2).y = 0.5;
2365 }
2366 
2368  Vector &shape) const
2369 {
2370  shape(0) = 1.0 - 2.0 * ip.y;
2371  shape(1) = -1.0 + 2.0 * ( ip.x + ip.y );
2372  shape(2) = 1.0 - 2.0 * ip.x;
2373 }
2374 
2376  DenseMatrix &dshape) const
2377 {
2378  dshape(0,0) = 0.0; dshape(0,1) = -2.0;
2379  dshape(1,0) = 2.0; dshape(1,1) = 2.0;
2380  dshape(2,0) = -2.0; dshape(2,1) = 0.0;
2381 }
2382 
2384 // the FunctionSpace should be rotated (45 degrees) Q_1
2385 // i.e. the span of { 1, x, y, x^2 - y^2 }
2386  : NodalFiniteElement(2, Geometry::SQUARE , 4, 2, FunctionSpace::Qk)
2387 
2388 {
2389  Nodes.IntPoint(0).x = 0.5;
2390  Nodes.IntPoint(0).y = 0.0;
2391  Nodes.IntPoint(1).x = 1.0;
2392  Nodes.IntPoint(1).y = 0.5;
2393  Nodes.IntPoint(2).x = 0.5;
2394  Nodes.IntPoint(2).y = 1.0;
2395  Nodes.IntPoint(3).x = 0.0;
2396  Nodes.IntPoint(3).y = 0.5;
2397 }
2398 
2400  Vector &shape) const
2401 {
2402  const double l1 = ip.x+ip.y-0.5, l2 = 1.-l1, l3 = ip.x-ip.y+0.5, l4 = 1.-l3;
2403 
2404  shape(0) = l2 * l3;
2405  shape(1) = l1 * l3;
2406  shape(2) = l1 * l4;
2407  shape(3) = l2 * l4;
2408 }
2409 
2411  DenseMatrix &dshape) const
2412 {
2413  const double x2 = 2.*ip.x, y2 = 2.*ip.y;
2414 
2415  dshape(0,0) = 1. - x2; dshape(0,1) = -2. + y2;
2416  dshape(1,0) = x2; dshape(1,1) = 1. - y2;
2417  dshape(2,0) = 1. - x2; dshape(2,1) = y2;
2418  dshape(3,0) = -2. + x2; dshape(3,1) = 1. - y2;
2419 }
2420 
2421 
2423  : VectorFiniteElement(2, Geometry::TRIANGLE, 3, 1, H_DIV)
2424 {
2425  Nodes.IntPoint(0).x = 0.5;
2426  Nodes.IntPoint(0).y = 0.0;
2427  Nodes.IntPoint(1).x = 0.5;
2428  Nodes.IntPoint(1).y = 0.5;
2429  Nodes.IntPoint(2).x = 0.0;
2430  Nodes.IntPoint(2).y = 0.5;
2431 }
2432 
2434  DenseMatrix &shape) const
2435 {
2436  double x = ip.x, y = ip.y;
2437 
2438  shape(0,0) = x;
2439  shape(0,1) = y - 1.;
2440  shape(1,0) = x;
2441  shape(1,1) = y;
2442  shape(2,0) = x - 1.;
2443  shape(2,1) = y;
2444 }
2445 
2447  Vector &divshape) const
2448 {
2449  divshape(0) = 2.;
2450  divshape(1) = 2.;
2451  divshape(2) = 2.;
2452 }
2453 
2454 const double RT0TriangleFiniteElement::nk[3][2] =
2455 { {0, -1}, {1, 1}, {-1, 0} };
2456 
2458  ElementTransformation &Trans, DenseMatrix &I) const
2459 {
2460  int k, j;
2461 #ifdef MFEM_THREAD_SAFE
2463  DenseMatrix Jinv(Dim);
2464 #endif
2465 
2466 #ifdef MFEM_DEBUG
2467  for (k = 0; k < 3; k++)
2468  {
2470  for (j = 0; j < 3; j++)
2471  {
2472  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2473  if (j == k) { d -= 1.0; }
2474  if (fabs(d) > 1.0e-12)
2475  {
2476  cerr << "RT0TriangleFiniteElement::GetLocalInterpolation (...)\n"
2477  " k = " << k << ", j = " << j << ", d = " << d << endl;
2478  mfem_error();
2479  }
2480  }
2481  }
2482 #endif
2483 
2484  IntegrationPoint ip;
2485  ip.x = ip.y = 0.0;
2486  Trans.SetIntPoint (&ip);
2487  // Trans must be linear
2488  // set Jinv = |J| J^{-t} = adj(J)^t
2489  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2490  double vk[2];
2491  Vector xk (vk, 2);
2492 
2493  for (k = 0; k < 3; k++)
2494  {
2495  Trans.Transform (Nodes.IntPoint (k), xk);
2496  ip.x = vk[0]; ip.y = vk[1];
2497  CalcVShape (ip, vshape);
2498  // vk = |J| J^{-t} nk
2499  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2500  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2501  for (j = 0; j < 3; j++)
2502  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2503  {
2504  I(k,j) = 0.0;
2505  }
2506  }
2507 }
2508 
2511  Vector &dofs) const
2512 {
2513  double vk[2];
2514  Vector xk (vk, 2);
2515 #ifdef MFEM_THREAD_SAFE
2516  DenseMatrix Jinv(Dim);
2517 #endif
2518 
2519  for (int k = 0; k < 3; k++)
2520  {
2521  Trans.SetIntPoint (&Nodes.IntPoint (k));
2522  // set Jinv = |J| J^{-t} = adj(J)^t
2523  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2524 
2525  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2526  // xk^t |J| J^{-t} nk
2527  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2528  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2529  }
2530 }
2531 
2533  : VectorFiniteElement(2, Geometry::SQUARE, 4, 1, H_DIV, FunctionSpace::Qk)
2534 {
2535  Nodes.IntPoint(0).x = 0.5;
2536  Nodes.IntPoint(0).y = 0.0;
2537  Nodes.IntPoint(1).x = 1.0;
2538  Nodes.IntPoint(1).y = 0.5;
2539  Nodes.IntPoint(2).x = 0.5;
2540  Nodes.IntPoint(2).y = 1.0;
2541  Nodes.IntPoint(3).x = 0.0;
2542  Nodes.IntPoint(3).y = 0.5;
2543 }
2544 
2546  DenseMatrix &shape) const
2547 {
2548  double x = ip.x, y = ip.y;
2549 
2550  shape(0,0) = 0;
2551  shape(0,1) = y - 1.;
2552  shape(1,0) = x;
2553  shape(1,1) = 0;
2554  shape(2,0) = 0;
2555  shape(2,1) = y;
2556  shape(3,0) = x - 1.;
2557  shape(3,1) = 0;
2558 }
2559 
2561  Vector &divshape) const
2562 {
2563  divshape(0) = 1.;
2564  divshape(1) = 1.;
2565  divshape(2) = 1.;
2566  divshape(3) = 1.;
2567 }
2568 
2569 const double RT0QuadFiniteElement::nk[4][2] =
2570 { {0, -1}, {1, 0}, {0, 1}, {-1, 0} };
2571 
2573  ElementTransformation &Trans, DenseMatrix &I) const
2574 {
2575  int k, j;
2576 #ifdef MFEM_THREAD_SAFE
2578  DenseMatrix Jinv(Dim);
2579 #endif
2580 
2581 #ifdef MFEM_DEBUG
2582  for (k = 0; k < 4; k++)
2583  {
2585  for (j = 0; j < 4; j++)
2586  {
2587  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2588  if (j == k) { d -= 1.0; }
2589  if (fabs(d) > 1.0e-12)
2590  {
2591  cerr << "RT0QuadFiniteElement::GetLocalInterpolation (...)\n"
2592  " k = " << k << ", j = " << j << ", d = " << d << endl;
2593  mfem_error();
2594  }
2595  }
2596  }
2597 #endif
2598 
2599  IntegrationPoint ip;
2600  ip.x = ip.y = 0.0;
2601  Trans.SetIntPoint (&ip);
2602  // Trans must be linear (more to have embedding?)
2603  // set Jinv = |J| J^{-t} = adj(J)^t
2604  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2605  double vk[2];
2606  Vector xk (vk, 2);
2607 
2608  for (k = 0; k < 4; k++)
2609  {
2610  Trans.Transform (Nodes.IntPoint (k), xk);
2611  ip.x = vk[0]; ip.y = vk[1];
2612  CalcVShape (ip, vshape);
2613  // vk = |J| J^{-t} nk
2614  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2615  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2616  for (j = 0; j < 4; j++)
2617  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2618  {
2619  I(k,j) = 0.0;
2620  }
2621  }
2622 }
2623 
2626  Vector &dofs) const
2627 {
2628  double vk[2];
2629  Vector xk (vk, 2);
2630 #ifdef MFEM_THREAD_SAFE
2631  DenseMatrix Jinv(Dim);
2632 #endif
2633 
2634  for (int k = 0; k < 4; k++)
2635  {
2636  Trans.SetIntPoint (&Nodes.IntPoint (k));
2637  // set Jinv = |J| J^{-t} = adj(J)^t
2638  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2639 
2640  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2641  // xk^t |J| J^{-t} nk
2642  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2643  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2644  }
2645 }
2646 
2648  : VectorFiniteElement(2, Geometry::TRIANGLE, 8, 2, H_DIV)
2649 {
2650  Nodes.IntPoint(0).x = 0.33333333333333333333;
2651  Nodes.IntPoint(0).y = 0.0;
2652  Nodes.IntPoint(1).x = 0.66666666666666666667;
2653  Nodes.IntPoint(1).y = 0.0;
2654  Nodes.IntPoint(2).x = 0.66666666666666666667;
2655  Nodes.IntPoint(2).y = 0.33333333333333333333;
2656  Nodes.IntPoint(3).x = 0.33333333333333333333;
2657  Nodes.IntPoint(3).y = 0.66666666666666666667;
2658  Nodes.IntPoint(4).x = 0.0;
2659  Nodes.IntPoint(4).y = 0.66666666666666666667;
2660  Nodes.IntPoint(5).x = 0.0;
2661  Nodes.IntPoint(5).y = 0.33333333333333333333;
2662  Nodes.IntPoint(6).x = 0.33333333333333333333;
2663  Nodes.IntPoint(6).y = 0.33333333333333333333;
2664  Nodes.IntPoint(7).x = 0.33333333333333333333;
2665  Nodes.IntPoint(7).y = 0.33333333333333333333;
2666 }
2667 
2669  DenseMatrix &shape) const
2670 {
2671  double x = ip.x, y = ip.y;
2672 
2673  shape(0,0) = -2 * x * (-1 + x + 2 * y);
2674  shape(0,1) = -2 * (-1 + y) * (-1 + x + 2 * y);
2675  shape(1,0) = 2 * x * (x - y);
2676  shape(1,1) = 2 * (x - y) * (-1 + y);
2677  shape(2,0) = 2 * x * (-1 + 2 * x + y);
2678  shape(2,1) = 2 * y * (-1 + 2 * x + y);
2679  shape(3,0) = 2 * x * (-1 + x + 2 * y);
2680  shape(3,1) = 2 * y * (-1 + x + 2 * y);
2681  shape(4,0) = -2 * (-1 + x) * (x - y);
2682  shape(4,1) = 2 * y * (-x + y);
2683  shape(5,0) = -2 * (-1 + x) * (-1 + 2 * x + y);
2684  shape(5,1) = -2 * y * (-1 + 2 * x + y);
2685  shape(6,0) = -3 * x * (-2 + 2 * x + y);
2686  shape(6,1) = -3 * y * (-1 + 2 * x + y);
2687  shape(7,0) = -3 * x * (-1 + x + 2 * y);
2688  shape(7,1) = -3 * y * (-2 + x + 2 * y);
2689 }
2690 
2692  Vector &divshape) const
2693 {
2694  double x = ip.x, y = ip.y;
2695 
2696  divshape(0) = -2 * (-4 + 3 * x + 6 * y);
2697  divshape(1) = 2 + 6 * x - 6 * y;
2698  divshape(2) = -4 + 12 * x + 6 * y;
2699  divshape(3) = -4 + 6 * x + 12 * y;
2700  divshape(4) = 2 - 6 * x + 6 * y;
2701  divshape(5) = -2 * (-4 + 6 * x + 3 * y);
2702  divshape(6) = -9 * (-1 + 2 * x + y);
2703  divshape(7) = -9 * (-1 + x + 2 * y);
2704 }
2705 
2706 const double RT1TriangleFiniteElement::nk[8][2] =
2707 {
2708  { 0,-1}, { 0,-1},
2709  { 1, 1}, { 1, 1},
2710  {-1, 0}, {-1, 0},
2711  { 1, 0}, { 0, 1}
2712 };
2713 
2715  ElementTransformation &Trans, DenseMatrix &I) const
2716 {
2717  int k, j;
2718 #ifdef MFEM_THREAD_SAFE
2720  DenseMatrix Jinv(Dim);
2721 #endif
2722 
2723 #ifdef MFEM_DEBUG
2724  for (k = 0; k < 8; k++)
2725  {
2727  for (j = 0; j < 8; j++)
2728  {
2729  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2730  if (j == k) { d -= 1.0; }
2731  if (fabs(d) > 1.0e-12)
2732  {
2733  cerr << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
2734  " k = " << k << ", j = " << j << ", d = " << d << endl;
2735  mfem_error();
2736  }
2737  }
2738  }
2739 #endif
2740 
2741  IntegrationPoint ip;
2742  ip.x = ip.y = 0.0;
2743  Trans.SetIntPoint (&ip);
2744  // Trans must be linear (more to have embedding?)
2745  // set Jinv = |J| J^{-t} = adj(J)^t
2746  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2747  double vk[2];
2748  Vector xk (vk, 2);
2749 
2750  for (k = 0; k < 8; k++)
2751  {
2752  Trans.Transform (Nodes.IntPoint (k), xk);
2753  ip.x = vk[0]; ip.y = vk[1];
2754  CalcVShape (ip, vshape);
2755  // vk = |J| J^{-t} nk
2756  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2757  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2758  for (j = 0; j < 8; j++)
2759  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2760  {
2761  I(k,j) = 0.0;
2762  }
2763  }
2764 }
2765 
2767  VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
2768 {
2769  double vk[2];
2770  Vector xk (vk, 2);
2771 #ifdef MFEM_THREAD_SAFE
2772  DenseMatrix Jinv(Dim);
2773 #endif
2774 
2775  for (int k = 0; k < 8; k++)
2776  {
2777  Trans.SetIntPoint (&Nodes.IntPoint (k));
2778  // set Jinv = |J| J^{-t} = adj(J)^t
2779  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2780 
2781  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2782  // xk^t |J| J^{-t} nk
2783  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2784  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2785  dofs(k) *= 0.5;
2786  }
2787 }
2788 
2790  : VectorFiniteElement(2, Geometry::SQUARE, 12, 2, H_DIV, FunctionSpace::Qk)
2791 {
2792  // y = 0
2793  Nodes.IntPoint(0).x = 1./3.;
2794  Nodes.IntPoint(0).y = 0.0;
2795  Nodes.IntPoint(1).x = 2./3.;
2796  Nodes.IntPoint(1).y = 0.0;
2797  // x = 1
2798  Nodes.IntPoint(2).x = 1.0;
2799  Nodes.IntPoint(2).y = 1./3.;
2800  Nodes.IntPoint(3).x = 1.0;
2801  Nodes.IntPoint(3).y = 2./3.;
2802  // y = 1
2803  Nodes.IntPoint(4).x = 2./3.;
2804  Nodes.IntPoint(4).y = 1.0;
2805  Nodes.IntPoint(5).x = 1./3.;
2806  Nodes.IntPoint(5).y = 1.0;
2807  // x = 0
2808  Nodes.IntPoint(6).x = 0.0;
2809  Nodes.IntPoint(6).y = 2./3.;
2810  Nodes.IntPoint(7).x = 0.0;
2811  Nodes.IntPoint(7).y = 1./3.;
2812  // x = 0.5 (interior)
2813  Nodes.IntPoint(8).x = 0.5;
2814  Nodes.IntPoint(8).y = 1./3.;
2815  Nodes.IntPoint(9).x = 0.5;
2816  Nodes.IntPoint(9).y = 2./3.;
2817  // y = 0.5 (interior)
2818  Nodes.IntPoint(10).x = 1./3.;
2819  Nodes.IntPoint(10).y = 0.5;
2820  Nodes.IntPoint(11).x = 2./3.;
2821  Nodes.IntPoint(11).y = 0.5;
2822 }
2823 
2825  DenseMatrix &shape) const
2826 {
2827  double x = ip.x, y = ip.y;
2828 
2829  // y = 0
2830  shape(0,0) = 0;
2831  shape(0,1) = -( 1. - 3.*y + 2.*y*y)*( 2. - 3.*x);
2832  shape(1,0) = 0;
2833  shape(1,1) = -( 1. - 3.*y + 2.*y*y)*(-1. + 3.*x);
2834  // x = 1
2835  shape(2,0) = (-x + 2.*x*x)*( 2. - 3.*y);
2836  shape(2,1) = 0;
2837  shape(3,0) = (-x + 2.*x*x)*(-1. + 3.*y);
2838  shape(3,1) = 0;
2839  // y = 1
2840  shape(4,0) = 0;
2841  shape(4,1) = (-y + 2.*y*y)*(-1. + 3.*x);
2842  shape(5,0) = 0;
2843  shape(5,1) = (-y + 2.*y*y)*( 2. - 3.*x);
2844  // x = 0
2845  shape(6,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y);
2846  shape(6,1) = 0;
2847  shape(7,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y);
2848  shape(7,1) = 0;
2849  // x = 0.5 (interior)
2850  shape(8,0) = (4.*x - 4.*x*x)*( 2. - 3.*y);
2851  shape(8,1) = 0;
2852  shape(9,0) = (4.*x - 4.*x*x)*(-1. + 3.*y);
2853  shape(9,1) = 0;
2854  // y = 0.5 (interior)
2855  shape(10,0) = 0;
2856  shape(10,1) = (4.*y - 4.*y*y)*( 2. - 3.*x);
2857  shape(11,0) = 0;
2858  shape(11,1) = (4.*y - 4.*y*y)*(-1. + 3.*x);
2859 }
2860 
2862  Vector &divshape) const
2863 {
2864  double x = ip.x, y = ip.y;
2865 
2866  divshape(0) = -(-3. + 4.*y)*( 2. - 3.*x);
2867  divshape(1) = -(-3. + 4.*y)*(-1. + 3.*x);
2868  divshape(2) = (-1. + 4.*x)*( 2. - 3.*y);
2869  divshape(3) = (-1. + 4.*x)*(-1. + 3.*y);
2870  divshape(4) = (-1. + 4.*y)*(-1. + 3.*x);
2871  divshape(5) = (-1. + 4.*y)*( 2. - 3.*x);
2872  divshape(6) = -(-3. + 4.*x)*(-1. + 3.*y);
2873  divshape(7) = -(-3. + 4.*x)*( 2. - 3.*y);
2874  divshape(8) = ( 4. - 8.*x)*( 2. - 3.*y);
2875  divshape(9) = ( 4. - 8.*x)*(-1. + 3.*y);
2876  divshape(10) = ( 4. - 8.*y)*( 2. - 3.*x);
2877  divshape(11) = ( 4. - 8.*y)*(-1. + 3.*x);
2878 }
2879 
2880 const double RT1QuadFiniteElement::nk[12][2] =
2881 {
2882  // y = 0
2883  {0,-1}, {0,-1},
2884  // X = 1
2885  {1, 0}, {1, 0},
2886  // y = 1
2887  {0, 1}, {0, 1},
2888  // x = 0
2889  {-1,0}, {-1,0},
2890  // x = 0.5 (interior)
2891  {1, 0}, {1, 0},
2892  // y = 0.5 (interior)
2893  {0, 1}, {0, 1}
2894 };
2895 
2897  ElementTransformation &Trans, DenseMatrix &I) const
2898 {
2899  int k, j;
2900 #ifdef MFEM_THREAD_SAFE
2902  DenseMatrix Jinv(Dim);
2903 #endif
2904 
2905 #ifdef MFEM_DEBUG
2906  for (k = 0; k < 12; k++)
2907  {
2909  for (j = 0; j < 12; j++)
2910  {
2911  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
2912  if (j == k) { d -= 1.0; }
2913  if (fabs(d) > 1.0e-12)
2914  {
2915  cerr << "RT1QuadFiniteElement::GetLocalInterpolation (...)\n"
2916  " k = " << k << ", j = " << j << ", d = " << d << endl;
2917  mfem_error();
2918  }
2919  }
2920  }
2921 #endif
2922 
2923  IntegrationPoint ip;
2924  ip.x = ip.y = 0.0;
2925  Trans.SetIntPoint (&ip);
2926  // Trans must be linear (more to have embedding?)
2927  // set Jinv = |J| J^{-t} = adj(J)^t
2928  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2929  double vk[2];
2930  Vector xk (vk, 2);
2931 
2932  for (k = 0; k < 12; k++)
2933  {
2934  Trans.Transform (Nodes.IntPoint (k), xk);
2935  ip.x = vk[0]; ip.y = vk[1];
2936  CalcVShape (ip, vshape);
2937  // vk = |J| J^{-t} nk
2938  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
2939  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
2940  for (j = 0; j < 12; j++)
2941  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
2942  {
2943  I(k,j) = 0.0;
2944  }
2945  }
2946 }
2947 
2949  VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
2950 {
2951  double vk[2];
2952  Vector xk (vk, 2);
2953 #ifdef MFEM_THREAD_SAFE
2954  DenseMatrix Jinv(Dim);
2955 #endif
2956 
2957  for (int k = 0; k < 12; k++)
2958  {
2959  Trans.SetIntPoint (&Nodes.IntPoint (k));
2960  // set Jinv = |J| J^{-t} = adj(J)^t
2961  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
2962 
2963  vc.Eval (xk, Trans, Nodes.IntPoint (k));
2964  // xk^t |J| J^{-t} nk
2965  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
2966  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
2967  }
2968 }
2969 
2970 const double RT2TriangleFiniteElement::M[15][15] =
2971 {
2972  {
2973  0, -5.3237900077244501311, 5.3237900077244501311, 16.647580015448900262,
2974  0, 24.442740046346700787, -16.647580015448900262, -12.,
2975  -19.118950038622250656, -47.237900077244501311, 0, -34.414110069520051180,
2976  12., 30.590320061795601049, 15.295160030897800524
2977  },
2978  {
2979  0, 1.5, -1.5, -15., 0, 2.625, 15., 15., -4.125, 30., 0, -14.625, -15.,
2980  -15., 10.5
2981  },
2982  {
2983  0, -0.67620999227554986889, 0.67620999227554986889, 7.3524199845510997378,
2984  0, -3.4427400463467007866, -7.3524199845510997378, -12.,
2985  4.1189500386222506555, -0.76209992275549868892, 0, 7.4141100695200511800,
2986  12., -6.5903200617956010489, -3.2951600308978005244
2987  },
2988  {
2989  0, 0, 1.5, 0, 0, 1.5, -11.471370023173350393, 0, 2.4713700231733503933,
2990  -11.471370023173350393, 0, 2.4713700231733503933, 15.295160030897800524,
2991  0, -3.2951600308978005244
2992  },
2993  {
2994  0, 0, 4.875, 0, 0, 4.875, -16.875, 0, -16.875, -16.875, 0, -16.875, 10.5,
2995  36., 10.5
2996  },
2997  {
2998  0, 0, 1.5, 0, 0, 1.5, 2.4713700231733503933, 0, -11.471370023173350393,
2999  2.4713700231733503933, 0, -11.471370023173350393, -3.2951600308978005244,
3000  0, 15.295160030897800524
3001  },
3002  {
3003  -0.67620999227554986889, 0, -3.4427400463467007866, 0,
3004  7.3524199845510997378, 0.67620999227554986889, 7.4141100695200511800, 0,
3005  -0.76209992275549868892, 4.1189500386222506555, -12.,
3006  -7.3524199845510997378, -3.2951600308978005244, -6.5903200617956010489,
3007  12.
3008  },
3009  {
3010  1.5, 0, 2.625, 0, -15., -1.5, -14.625, 0, 30., -4.125, 15., 15., 10.5,
3011  -15., -15.
3012  },
3013  {
3014  -5.3237900077244501311, 0, 24.442740046346700787, 0, 16.647580015448900262,
3015  5.3237900077244501311, -34.414110069520051180, 0, -47.237900077244501311,
3016  -19.118950038622250656, -12., -16.647580015448900262, 15.295160030897800524,
3017  30.590320061795601049, 12.
3018  },
3019  { 0, 0, 18., 0, 0, 6., -42., 0, -30., -26., 0, -14., 24., 32., 8.},
3020  { 0, 0, 6., 0, 0, 18., -14., 0, -26., -30., 0, -42., 8., 32., 24.},
3021  { 0, 0, -6., 0, 0, -4., 30., 0, 4., 22., 0, 4., -24., -16., 0},
3022  { 0, 0, -4., 0, 0, -8., 20., 0, 8., 36., 0, 8., -16., -32., 0},
3023  { 0, 0, -8., 0, 0, -4., 8., 0, 36., 8., 0, 20., 0, -32., -16.},
3024  { 0, 0, -4., 0, 0, -6., 4., 0, 22., 4., 0, 30., 0, -16., -24.}
3025 };
3026 
3028  : VectorFiniteElement(2, Geometry::TRIANGLE, 15, 3, H_DIV)
3029 {
3030  const double p = 0.11270166537925831148;
3031 
3032  Nodes.IntPoint(0).x = p;
3033  Nodes.IntPoint(0).y = 0.0;
3034  Nodes.IntPoint(1).x = 0.5;
3035  Nodes.IntPoint(1).y = 0.0;
3036  Nodes.IntPoint(2).x = 1.-p;
3037  Nodes.IntPoint(2).y = 0.0;
3038  Nodes.IntPoint(3).x = 1.-p;
3039  Nodes.IntPoint(3).y = p;
3040  Nodes.IntPoint(4).x = 0.5;
3041  Nodes.IntPoint(4).y = 0.5;
3042  Nodes.IntPoint(5).x = p;
3043  Nodes.IntPoint(5).y = 1.-p;
3044  Nodes.IntPoint(6).x = 0.0;
3045  Nodes.IntPoint(6).y = 1.-p;
3046  Nodes.IntPoint(7).x = 0.0;
3047  Nodes.IntPoint(7).y = 0.5;
3048  Nodes.IntPoint(8).x = 0.0;
3049  Nodes.IntPoint(8).y = p;
3050  Nodes.IntPoint(9).x = 0.25;
3051  Nodes.IntPoint(9).y = 0.25;
3052  Nodes.IntPoint(10).x = 0.25;
3053  Nodes.IntPoint(10).y = 0.25;
3054  Nodes.IntPoint(11).x = 0.5;
3055  Nodes.IntPoint(11).y = 0.25;
3056  Nodes.IntPoint(12).x = 0.5;
3057  Nodes.IntPoint(12).y = 0.25;
3058  Nodes.IntPoint(13).x = 0.25;
3059  Nodes.IntPoint(13).y = 0.5;
3060  Nodes.IntPoint(14).x = 0.25;
3061  Nodes.IntPoint(14).y = 0.5;
3062 }
3063 
3065  DenseMatrix &shape) const
3066 {
3067  double x = ip.x, y = ip.y;
3068 
3069  double Bx[15] = {1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y, 0., x*x*x,
3070  x*x*y, x*y*y
3071  };
3072  double By[15] = {0., 1., 0., x, 0., y, 0., x*x, 0., x*y, 0., y*y,
3073  x*x*y, x*y*y, y*y*y
3074  };
3075 
3076  for (int i = 0; i < 15; i++)
3077  {
3078  double cx = 0.0, cy = 0.0;
3079  for (int j = 0; j < 15; j++)
3080  {
3081  cx += M[i][j] * Bx[j];
3082  cy += M[i][j] * By[j];
3083  }
3084  shape(i,0) = cx;
3085  shape(i,1) = cy;
3086  }
3087 }
3088 
3090  Vector &divshape) const
3091 {
3092  double x = ip.x, y = ip.y;
3093 
3094  double DivB[15] = {0., 0., 1., 0., 0., 1., 2.*x, 0., y, x, 0., 2.*y,
3095  4.*x*x, 4.*x*y, 4.*y*y
3096  };
3097 
3098  for (int i = 0; i < 15; i++)
3099  {
3100  double div = 0.0;
3101  for (int j = 0; j < 15; j++)
3102  {
3103  div += M[i][j] * DivB[j];
3104  }
3105  divshape(i) = div;
3106  }
3107 }
3108 
3109 const double RT2QuadFiniteElement::pt[4] = {0.,1./3.,2./3.,1.};
3110 
3111 const double RT2QuadFiniteElement::dpt[3] = {0.25,0.5,0.75};
3112 
3114  : VectorFiniteElement(2, Geometry::SQUARE, 24, 3, H_DIV, FunctionSpace::Qk)
3115 {
3116  // y = 0 (pt[0])
3117  Nodes.IntPoint(0).x = dpt[0]; Nodes.IntPoint(0).y = pt[0];
3118  Nodes.IntPoint(1).x = dpt[1]; Nodes.IntPoint(1).y = pt[0];
3119  Nodes.IntPoint(2).x = dpt[2]; Nodes.IntPoint(2).y = pt[0];
3120  // x = 1 (pt[3])
3121  Nodes.IntPoint(3).x = pt[3]; Nodes.IntPoint(3).y = dpt[0];
3122  Nodes.IntPoint(4).x = pt[3]; Nodes.IntPoint(4).y = dpt[1];
3123  Nodes.IntPoint(5).x = pt[3]; Nodes.IntPoint(5).y = dpt[2];
3124  // y = 1 (pt[3])
3125  Nodes.IntPoint(6).x = dpt[2]; Nodes.IntPoint(6).y = pt[3];
3126  Nodes.IntPoint(7).x = dpt[1]; Nodes.IntPoint(7).y = pt[3];
3127  Nodes.IntPoint(8).x = dpt[0]; Nodes.IntPoint(8).y = pt[3];
3128  // x = 0 (pt[0])
3129  Nodes.IntPoint(9).x = pt[0]; Nodes.IntPoint(9).y = dpt[2];
3130  Nodes.IntPoint(10).x = pt[0]; Nodes.IntPoint(10).y = dpt[1];
3131  Nodes.IntPoint(11).x = pt[0]; Nodes.IntPoint(11).y = dpt[0];
3132  // x = pt[1] (interior)
3133  Nodes.IntPoint(12).x = pt[1]; Nodes.IntPoint(12).y = dpt[0];
3134  Nodes.IntPoint(13).x = pt[1]; Nodes.IntPoint(13).y = dpt[1];
3135  Nodes.IntPoint(14).x = pt[1]; Nodes.IntPoint(14).y = dpt[2];
3136  // x = pt[2] (interior)
3137  Nodes.IntPoint(15).x = pt[2]; Nodes.IntPoint(15).y = dpt[0];
3138  Nodes.IntPoint(16).x = pt[2]; Nodes.IntPoint(16).y = dpt[1];
3139  Nodes.IntPoint(17).x = pt[2]; Nodes.IntPoint(17).y = dpt[2];
3140  // y = pt[1] (interior)
3141  Nodes.IntPoint(18).x = dpt[0]; Nodes.IntPoint(18).y = pt[1];
3142  Nodes.IntPoint(19).x = dpt[1]; Nodes.IntPoint(19).y = pt[1];
3143  Nodes.IntPoint(20).x = dpt[2]; Nodes.IntPoint(20).y = pt[1];
3144  // y = pt[2] (interior)
3145  Nodes.IntPoint(21).x = dpt[0]; Nodes.IntPoint(21).y = pt[2];
3146  Nodes.IntPoint(22).x = dpt[1]; Nodes.IntPoint(22).y = pt[2];
3147  Nodes.IntPoint(23).x = dpt[2]; Nodes.IntPoint(23).y = pt[2];
3148 }
3149 
3151  DenseMatrix &shape) const
3152 {
3153  double x = ip.x, y = ip.y;
3154 
3155  double ax0 = pt[0] - x;
3156  double ax1 = pt[1] - x;
3157  double ax2 = pt[2] - x;
3158  double ax3 = pt[3] - x;
3159 
3160  double by0 = dpt[0] - y;
3161  double by1 = dpt[1] - y;
3162  double by2 = dpt[2] - y;
3163 
3164  double ay0 = pt[0] - y;
3165  double ay1 = pt[1] - y;
3166  double ay2 = pt[2] - y;
3167  double ay3 = pt[3] - y;
3168 
3169  double bx0 = dpt[0] - x;
3170  double bx1 = dpt[1] - x;
3171  double bx2 = dpt[2] - x;
3172 
3173  double A01 = pt[0] - pt[1];
3174  double A02 = pt[0] - pt[2];
3175  double A12 = pt[1] - pt[2];
3176  double A03 = pt[0] - pt[3];
3177  double A13 = pt[1] - pt[3];
3178  double A23 = pt[2] - pt[3];
3179 
3180  double B01 = dpt[0] - dpt[1];
3181  double B02 = dpt[0] - dpt[2];
3182  double B12 = dpt[1] - dpt[2];
3183 
3184  double tx0 = (bx1*bx2)/(B01*B02);
3185  double tx1 = -(bx0*bx2)/(B01*B12);
3186  double tx2 = (bx0*bx1)/(B02*B12);
3187 
3188  double ty0 = (by1*by2)/(B01*B02);
3189  double ty1 = -(by0*by2)/(B01*B12);
3190  double ty2 = (by0*by1)/(B02*B12);
3191 
3192  // y = 0 (p[0])
3193  shape(0, 0) = 0;
3194  shape(0, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx0;
3195  shape(1, 0) = 0;
3196  shape(1, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx1;
3197  shape(2, 0) = 0;
3198  shape(2, 1) = (ay1*ay2*ay3)/(A01*A02*A03)*tx2;
3199  // x = 1 (p[3])
3200  shape(3, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty0;
3201  shape(3, 1) = 0;
3202  shape(4, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty1;
3203  shape(4, 1) = 0;
3204  shape(5, 0) = (ax0*ax1*ax2)/(A03*A13*A23)*ty2;
3205  shape(5, 1) = 0;
3206  // y = 1 (p[3])
3207  shape(6, 0) = 0;
3208  shape(6, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx2;
3209  shape(7, 0) = 0;
3210  shape(7, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx1;
3211  shape(8, 0) = 0;
3212  shape(8, 1) = (ay0*ay1*ay2)/(A03*A13*A23)*tx0;
3213  // x = 0 (p[0])
3214  shape(9, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty2;
3215  shape(9, 1) = 0;
3216  shape(10, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty1;
3217  shape(10, 1) = 0;
3218  shape(11, 0) = (ax1*ax2*ax3)/(A01*A02*A03)*ty0;
3219  shape(11, 1) = 0;
3220  // x = p[1] (interior)
3221  shape(12, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty0;
3222  shape(12, 1) = 0;
3223  shape(13, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty1;
3224  shape(13, 1) = 0;
3225  shape(14, 0) = (ax0*ax2*ax3)/(A01*A12*A13)*ty2;
3226  shape(14, 1) = 0;
3227  // x = p[2] (interior)
3228  shape(15, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty0;
3229  shape(15, 1) = 0;
3230  shape(16, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty1;
3231  shape(16, 1) = 0;
3232  shape(17, 0) = -(ax0*ax1*ax3)/(A02*A12*A23)*ty2;
3233  shape(17, 1) = 0;
3234  // y = p[1] (interior)
3235  shape(18, 0) = 0;
3236  shape(18, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx0;
3237  shape(19, 0) = 0;
3238  shape(19, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx1;
3239  shape(20, 0) = 0;
3240  shape(20, 1) = (ay0*ay2*ay3)/(A01*A12*A13)*tx2;
3241  // y = p[2] (interior)
3242  shape(21, 0) = 0;
3243  shape(21, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx0;
3244  shape(22, 0) = 0;
3245  shape(22, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx1;
3246  shape(23, 0) = 0;
3247  shape(23, 1) = -(ay0*ay1*ay3)/(A02*A12*A23)*tx2;
3248 }
3249 
3251  Vector &divshape) const
3252 {
3253  double x = ip.x, y = ip.y;
3254 
3255  double a01 = pt[0]*pt[1];
3256  double a02 = pt[0]*pt[2];
3257  double a12 = pt[1]*pt[2];
3258  double a03 = pt[0]*pt[3];
3259  double a13 = pt[1]*pt[3];
3260  double a23 = pt[2]*pt[3];
3261 
3262  double bx0 = dpt[0] - x;
3263  double bx1 = dpt[1] - x;
3264  double bx2 = dpt[2] - x;
3265 
3266  double by0 = dpt[0] - y;
3267  double by1 = dpt[1] - y;
3268  double by2 = dpt[2] - y;
3269 
3270  double A01 = pt[0] - pt[1];
3271  double A02 = pt[0] - pt[2];
3272  double A12 = pt[1] - pt[2];
3273  double A03 = pt[0] - pt[3];
3274  double A13 = pt[1] - pt[3];
3275  double A23 = pt[2] - pt[3];
3276 
3277  double A012 = pt[0] + pt[1] + pt[2];
3278  double A013 = pt[0] + pt[1] + pt[3];
3279  double A023 = pt[0] + pt[2] + pt[3];
3280  double A123 = pt[1] + pt[2] + pt[3];
3281 
3282  double B01 = dpt[0] - dpt[1];
3283  double B02 = dpt[0] - dpt[2];
3284  double B12 = dpt[1] - dpt[2];
3285 
3286  double tx0 = (bx1*bx2)/(B01*B02);
3287  double tx1 = -(bx0*bx2)/(B01*B12);
3288  double tx2 = (bx0*bx1)/(B02*B12);
3289 
3290  double ty0 = (by1*by2)/(B01*B02);
3291  double ty1 = -(by0*by2)/(B01*B12);
3292  double ty2 = (by0*by1)/(B02*B12);
3293 
3294  // y = 0 (p[0])
3295  divshape(0) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx0;
3296  divshape(1) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx1;
3297  divshape(2) = -(a12 + a13 + a23 - 2.*A123*y + 3.*y*y)/(A01*A02*A03)*tx2;
3298  // x = 1 (p[3])
3299  divshape(3) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty0;
3300  divshape(4) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty1;
3301  divshape(5) = -(a01 + a02 + a12 - 2.*A012*x + 3.*x*x)/(A03*A13*A23)*ty2;
3302  // y = 1 (p[3])
3303  divshape(6) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx2;
3304  divshape(7) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx1;
3305  divshape(8) = -(a01 + a02 + a12 - 2.*A012*y + 3.*y*y)/(A03*A13*A23)*tx0;
3306  // x = 0 (p[0])
3307  divshape(9) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty2;
3308  divshape(10) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty1;
3309  divshape(11) = -(a12 + a13 + a23 - 2.*A123*x + 3.*x*x)/(A01*A02*A03)*ty0;
3310  // x = p[1] (interior)
3311  divshape(12) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty0;
3312  divshape(13) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty1;
3313  divshape(14) = -(a02 + a03 + a23 - 2.*A023*x + 3.*x*x)/(A01*A12*A13)*ty2;
3314  // x = p[2] (interior)
3315  divshape(15) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty0;
3316  divshape(16) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty1;
3317  divshape(17) = (a01 + a03 + a13 - 2.*A013*x + 3.*x*x)/(A02*A12*A23)*ty2;
3318  // y = p[1] (interior)
3319  divshape(18) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx0;
3320  divshape(19) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx1;
3321  divshape(20) = -(a02 + a03 + a23 - 2.*A023*y + 3.*y*y)/(A01*A12*A13)*tx2;
3322  // y = p[2] (interior)
3323  divshape(21) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx0;
3324  divshape(22) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx1;
3325  divshape(23) = (a01 + a03 + a13 - 2.*A013*y + 3.*y*y)/(A02*A12*A23)*tx2;
3326 }
3327 
3328 const double RT2QuadFiniteElement::nk[24][2] =
3329 {
3330  // y = 0
3331  {0,-1}, {0,-1}, {0,-1},
3332  // x = 1
3333  {1, 0}, {1, 0}, {1, 0},
3334  // y = 1
3335  {0, 1}, {0, 1}, {0, 1},
3336  // x = 0
3337  {-1,0}, {-1,0}, {-1,0},
3338  // x = p[1] (interior)
3339  {1, 0}, {1, 0}, {1, 0},
3340  // x = p[2] (interior)
3341  {1, 0}, {1, 0}, {1, 0},
3342  // y = p[1] (interior)
3343  {0, 1}, {0, 1}, {0, 1},
3344  // y = p[1] (interior)
3345  {0, 1}, {0, 1}, {0, 1}
3346 };
3347 
3349  ElementTransformation &Trans, DenseMatrix &I) const
3350 {
3351  int k, j;
3352 #ifdef MFEM_THREAD_SAFE
3354  DenseMatrix Jinv(Dim);
3355 #endif
3356 
3357 #ifdef MFEM_DEBUG
3358  for (k = 0; k < 24; k++)
3359  {
3361  for (j = 0; j < 24; j++)
3362  {
3363  double d = vshape(j,0)*nk[k][0]+vshape(j,1)*nk[k][1];
3364  if (j == k) { d -= 1.0; }
3365  if (fabs(d) > 1.0e-12)
3366  {
3367  cerr << "RT2QuadFiniteElement::GetLocalInterpolation (...)\n"
3368  " k = " << k << ", j = " << j << ", d = " << d << endl;
3369  mfem_error();
3370  }
3371  }
3372  }
3373 #endif
3374 
3375  IntegrationPoint ip;
3376  ip.x = ip.y = 0.0;
3377  Trans.SetIntPoint (&ip);
3378  // Trans must be linear (more to have embedding?)
3379  // set Jinv = |J| J^{-t} = adj(J)^t
3380  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3381  double vk[2];
3382  Vector xk (vk, 2);
3383 
3384  for (k = 0; k < 24; k++)
3385  {
3386  Trans.Transform (Nodes.IntPoint (k), xk);
3387  ip.x = vk[0]; ip.y = vk[1];
3388  CalcVShape (ip, vshape);
3389  // vk = |J| J^{-t} nk
3390  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1];
3391  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1];
3392  for (j = 0; j < 24; j++)
3393  if (fabs (I(k,j) = vshape(j,0)*vk[0]+vshape(j,1)*vk[1]) < 1.0e-12)
3394  {
3395  I(k,j) = 0.0;
3396  }
3397  }
3398 }
3399 
3401  VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
3402 {
3403  double vk[2];
3404  Vector xk (vk, 2);
3405 #ifdef MFEM_THREAD_SAFE
3406  DenseMatrix Jinv(Dim);
3407 #endif
3408 
3409  for (int k = 0; k < 24; k++)
3410  {
3411  Trans.SetIntPoint (&Nodes.IntPoint (k));
3412  // set Jinv = |J| J^{-t} = adj(J)^t
3413  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
3414 
3415  vc.Eval (xk, Trans, Nodes.IntPoint (k));
3416  // xk^t |J| J^{-t} nk
3417  dofs(k) = (vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1] ) +
3418  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1] ));
3419  }
3420 }
3421 
3423  : NodalFiniteElement(1, Geometry::SEGMENT, 2, 1)
3424 {
3425  Nodes.IntPoint(0).x = 0.33333333333333333333;
3426  Nodes.IntPoint(1).x = 0.66666666666666666667;
3427 }
3428 
3430  Vector &shape) const
3431 {
3432  double x = ip.x;
3433 
3434  shape(0) = 2. - 3. * x;
3435  shape(1) = 3. * x - 1.;
3436 }
3437 
3439  DenseMatrix &dshape) const
3440 {
3441  dshape(0,0) = -3.;
3442  dshape(1,0) = 3.;
3443 }
3444 
3445 
3447  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 2)
3448 {
3449  const double p = 0.11270166537925831148;
3450 
3451  Nodes.IntPoint(0).x = p;
3452  Nodes.IntPoint(1).x = 0.5;
3453  Nodes.IntPoint(2).x = 1.-p;
3454 }
3455 
3457  Vector &shape) const
3458 {
3459  const double p = 0.11270166537925831148;
3460  const double w = 1./((1-2*p)*(1-2*p));
3461  double x = ip.x;
3462 
3463  shape(0) = (2*x-1)*(x-1+p)*w;
3464  shape(1) = 4*(x-1+p)*(p-x)*w;
3465  shape(2) = (2*x-1)*(x-p)*w;
3466 }
3467 
3469  DenseMatrix &dshape) const
3470 {
3471  const double p = 0.11270166537925831148;
3472  const double w = 1./((1-2*p)*(1-2*p));
3473  double x = ip.x;
3474 
3475  dshape(0,0) = (-3+4*x+2*p)*w;
3476  dshape(1,0) = (4-8*x)*w;
3477  dshape(2,0) = (-1+4*x-2*p)*w;
3478 }
3479 
3480 
3482  : NodalFiniteElement(1, Geometry::SEGMENT, degree+1, degree)
3483 {
3484  int i, m = degree;
3485 
3486  Nodes.IntPoint(0).x = 0.0;
3487  Nodes.IntPoint(1).x = 1.0;
3488  for (i = 1; i < m; i++)
3489  {
3490  Nodes.IntPoint(i+1).x = double(i) / m;
3491  }
3492 
3493  rwk.SetSize(degree+1);
3494 #ifndef MFEM_THREAD_SAFE
3495  rxxk.SetSize(degree+1);
3496 #endif
3497 
3498  rwk(0) = 1.0;
3499  for (i = 1; i <= m; i++)
3500  {
3501  rwk(i) = rwk(i-1) * ( (double)(m) / (double)(i) );
3502  }
3503  for (i = 0; i < m/2+1; i++)
3504  {
3505  rwk(m-i) = ( rwk(i) *= rwk(m-i) );
3506  }
3507  for (i = m-1; i >= 0; i -= 2)
3508  {
3509  rwk(i) = -rwk(i);
3510  }
3511 }
3512 
3514  Vector &shape) const
3515 {
3516  double w, wk, x = ip.x;
3517  int i, k, m = GetOrder();
3518 
3519 #ifdef MFEM_THREAD_SAFE
3520  Vector rxxk(m+1);
3521 #endif
3522 
3523  k = (int) floor ( m * x + 0.5 );
3524  wk = 1.0;
3525  for (i = 0; i <= m; i++)
3526  if (i != k)
3527  {
3528  wk *= ( rxxk(i) = x - (double)(i) / m );
3529  }
3530  w = wk * ( rxxk(k) = x - (double)(k) / m );
3531 
3532  if (k != 0)
3533  {
3534  shape(0) = w * rwk(0) / rxxk(0);
3535  }
3536  else
3537  {
3538  shape(0) = wk * rwk(0);
3539  }
3540  if (k != m)
3541  {
3542  shape(1) = w * rwk(m) / rxxk(m);
3543  }
3544  else
3545  {
3546  shape(1) = wk * rwk(k);
3547  }
3548  for (i = 1; i < m; i++)
3549  if (i != k)
3550  {
3551  shape(i+1) = w * rwk(i) / rxxk(i);
3552  }
3553  else
3554  {
3555  shape(k+1) = wk * rwk(k);
3556  }
3557 }
3558 
3560  DenseMatrix &dshape) const
3561 {
3562  double s, srx, w, wk, x = ip.x;
3563  int i, k, m = GetOrder();
3564 
3565 #ifdef MFEM_THREAD_SAFE
3566  Vector rxxk(m+1);
3567 #endif
3568 
3569  k = (int) floor ( m * x + 0.5 );
3570  wk = 1.0;
3571  for (i = 0; i <= m; i++)
3572  if (i != k)
3573  {
3574  wk *= ( rxxk(i) = x - (double)(i) / m );
3575  }
3576  w = wk * ( rxxk(k) = x - (double)(k) / m );
3577 
3578  for (i = 0; i <= m; i++)
3579  {
3580  rxxk(i) = 1.0 / rxxk(i);
3581  }
3582  srx = 0.0;
3583  for (i = 0; i <= m; i++)
3584  if (i != k)
3585  {
3586  srx += rxxk(i);
3587  }
3588  s = w * srx + wk;
3589 
3590  if (k != 0)
3591  {
3592  dshape(0,0) = (s - w * rxxk(0)) * rwk(0) * rxxk(0);
3593  }
3594  else
3595  {
3596  dshape(0,0) = wk * srx * rwk(0);
3597  }
3598  if (k != m)
3599  {
3600  dshape(1,0) = (s - w * rxxk(m)) * rwk(m) * rxxk(m);
3601  }
3602  else
3603  {
3604  dshape(1,0) = wk * srx * rwk(k);
3605  }
3606  for (i = 1; i < m; i++)
3607  if (i != k)
3608  {
3609  dshape(i+1,0) = (s - w * rxxk(i)) * rwk(i) * rxxk(i);
3610  }
3611  else
3612  {
3613  dshape(k+1,0) = wk * srx * rwk(k);
3614  }
3615 }
3616 
3617 
3619  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 4, 1)
3620 {
3621  Nodes.IntPoint(0).x = 0.33333333333333333333;
3622  Nodes.IntPoint(0).y = 0.33333333333333333333;
3623  Nodes.IntPoint(0).z = 0.33333333333333333333;
3624 
3625  Nodes.IntPoint(1).x = 0.0;
3626  Nodes.IntPoint(1).y = 0.33333333333333333333;
3627  Nodes.IntPoint(1).z = 0.33333333333333333333;
3628 
3629  Nodes.IntPoint(2).x = 0.33333333333333333333;
3630  Nodes.IntPoint(2).y = 0.0;
3631  Nodes.IntPoint(2).z = 0.33333333333333333333;
3632 
3633  Nodes.IntPoint(3).x = 0.33333333333333333333;
3634  Nodes.IntPoint(3).y = 0.33333333333333333333;
3635  Nodes.IntPoint(3).z = 0.0;
3636 
3637 }
3638 
3640  Vector &shape) const
3641 {
3642  double L0, L1, L2, L3;
3643 
3644  L1 = ip.x; L2 = ip.y; L3 = ip.z; L0 = 1.0 - L1 - L2 - L3;
3645  shape(0) = 1.0 - 3.0 * L0;
3646  shape(1) = 1.0 - 3.0 * L1;
3647  shape(2) = 1.0 - 3.0 * L2;
3648  shape(3) = 1.0 - 3.0 * L3;
3649 }
3650 
3652  DenseMatrix &dshape) const
3653 {
3654  dshape(0,0) = 3.0; dshape(0,1) = 3.0; dshape(0,2) = 3.0;
3655  dshape(1,0) = -3.0; dshape(1,1) = 0.0; dshape(1,2) = 0.0;
3656  dshape(2,0) = 0.0; dshape(2,1) = -3.0; dshape(2,2) = 0.0;
3657  dshape(3,0) = 0.0; dshape(3,1) = 0.0; dshape(3,2) = -3.0;
3658 }
3659 
3660 
3662  : NodalFiniteElement(3, Geometry::TETRAHEDRON , 1, 0)
3663 {
3664  Nodes.IntPoint(0).x = 0.25;
3665  Nodes.IntPoint(0).y = 0.25;
3666  Nodes.IntPoint(0).z = 0.25;
3667 }
3668 
3670  Vector &shape) const
3671 {
3672  shape(0) = 1.0;
3673 }
3674 
3676  DenseMatrix &dshape) const
3677 {
3678  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3679 }
3680 
3681 
3683  : NodalFiniteElement(3, Geometry::CUBE, 1, 0, FunctionSpace::Qk)
3684 {
3685  Nodes.IntPoint(0).x = 0.5;
3686  Nodes.IntPoint(0).y = 0.5;
3687  Nodes.IntPoint(0).z = 0.5;
3688 }
3689 
3691  Vector &shape) const
3692 {
3693  shape(0) = 1.0;
3694 }
3695 
3697  DenseMatrix &dshape) const
3698 {
3699  dshape(0,0) = 0.0; dshape(0,1) = 0.0; dshape(0,2) = 0.0;
3700 }
3701 
3702 
3704  : NodalFiniteElement(3, Geometry::CUBE, (degree+1)*(degree+1)*(degree+1),
3705  degree, FunctionSpace::Qk)
3706 {
3707  if (degree == 2)
3708  {
3709  I = new int[Dof];
3710  J = new int[Dof];
3711  K = new int[Dof];
3712  // nodes
3713  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3714  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3715  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3716  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3717  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3718  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3719  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3720  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3721  // edges
3722  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3723  I[ 9] = 1; J[ 9] = 2; K[ 9] = 0;
3724  I[10] = 2; J[10] = 1; K[10] = 0;
3725  I[11] = 0; J[11] = 2; K[11] = 0;
3726  I[12] = 2; J[12] = 0; K[12] = 1;
3727  I[13] = 1; J[13] = 2; K[13] = 1;
3728  I[14] = 2; J[14] = 1; K[14] = 1;
3729  I[15] = 0; J[15] = 2; K[15] = 1;
3730  I[16] = 0; J[16] = 0; K[16] = 2;
3731  I[17] = 1; J[17] = 0; K[17] = 2;
3732  I[18] = 1; J[18] = 1; K[18] = 2;
3733  I[19] = 0; J[19] = 1; K[19] = 2;
3734  // faces
3735  I[20] = 2; J[20] = 2; K[20] = 0;
3736  I[21] = 2; J[21] = 0; K[21] = 2;
3737  I[22] = 1; J[22] = 2; K[22] = 2;
3738  I[23] = 2; J[23] = 1; K[23] = 2;
3739  I[24] = 0; J[24] = 2; K[24] = 2;
3740  I[25] = 2; J[25] = 2; K[25] = 1;
3741  // element
3742  I[26] = 2; J[26] = 2; K[26] = 2;
3743  }
3744  else if (degree == 3)
3745  {
3746  I = new int[Dof];
3747  J = new int[Dof];
3748  K = new int[Dof];
3749  // nodes
3750  I[ 0] = 0; J[ 0] = 0; K[ 0] = 0;
3751  I[ 1] = 1; J[ 1] = 0; K[ 1] = 0;
3752  I[ 2] = 1; J[ 2] = 1; K[ 2] = 0;
3753  I[ 3] = 0; J[ 3] = 1; K[ 3] = 0;
3754  I[ 4] = 0; J[ 4] = 0; K[ 4] = 1;
3755  I[ 5] = 1; J[ 5] = 0; K[ 5] = 1;
3756  I[ 6] = 1; J[ 6] = 1; K[ 6] = 1;
3757  I[ 7] = 0; J[ 7] = 1; K[ 7] = 1;
3758  // edges
3759  I[ 8] = 2; J[ 8] = 0; K[ 8] = 0;
3760  I[ 9] = 3; J[ 9] = 0; K[ 9] = 0;
3761  I[10] = 1; J[10] = 2; K[10] = 0;
3762  I[11] = 1; J[11] = 3; K[11] = 0;
3763  I[12] = 2; J[12] = 1; K[12] = 0;
3764  I[13] = 3; J[13] = 1; K[13] = 0;
3765  I[14] = 0; J[14] = 2; K[14] = 0;
3766  I[15] = 0; J[15] = 3; K[15] = 0;
3767  I[16] = 2; J[16] = 0; K[16] = 1;
3768  I[17] = 3; J[17] = 0; K[17] = 1;
3769  I[18] = 1; J[18] = 2; K[18] = 1;
3770  I[19] = 1; J[19] = 3; K[19] = 1;
3771  I[20] = 2; J[20] = 1; K[20] = 1;
3772  I[21] = 3; J[21] = 1; K[21] = 1;
3773  I[22] = 0; J[22] = 2; K[22] = 1;
3774  I[23] = 0; J[23] = 3; K[23] = 1;
3775  I[24] = 0; J[24] = 0; K[24] = 2;
3776  I[25] = 0; J[25] = 0; K[25] = 3;
3777  I[26] = 1; J[26] = 0; K[26] = 2;
3778  I[27] = 1; J[27] = 0; K[27] = 3;
3779  I[28] = 1; J[28] = 1; K[28] = 2;
3780  I[29] = 1; J[29] = 1; K[29] = 3;
3781  I[30] = 0; J[30] = 1; K[30] = 2;
3782  I[31] = 0; J[31] = 1; K[31] = 3;
3783  // faces
3784  I[32] = 2; J[32] = 3; K[32] = 0;
3785  I[33] = 3; J[33] = 3; K[33] = 0;
3786  I[34] = 2; J[34] = 2; K[34] = 0;
3787  I[35] = 3; J[35] = 2; K[35] = 0;
3788  I[36] = 2; J[36] = 0; K[36] = 2;
3789  I[37] = 3; J[37] = 0; K[37] = 2;
3790  I[38] = 2; J[38] = 0; K[38] = 3;
3791  I[39] = 3; J[39] = 0; K[39] = 3;
3792  I[40] = 1; J[40] = 2; K[40] = 2;
3793  I[41] = 1; J[41] = 3; K[41] = 2;
3794  I[42] = 1; J[42] = 2; K[42] = 3;
3795  I[43] = 1; J[43] = 3; K[43] = 3;
3796  I[44] = 3; J[44] = 1; K[44] = 2;
3797  I[45] = 2; J[45] = 1; K[45] = 2;
3798  I[46] = 3; J[46] = 1; K[46] = 3;
3799  I[47] = 2; J[47] = 1; K[47] = 3;
3800  I[48] = 0; J[48] = 3; K[48] = 2;
3801  I[49] = 0; J[49] = 2; K[49] = 2;
3802  I[50] = 0; J[50] = 3; K[50] = 3;
3803  I[51] = 0; J[51] = 2; K[51] = 3;
3804  I[52] = 2; J[52] = 2; K[52] = 1;
3805  I[53] = 3; J[53] = 2; K[53] = 1;
3806  I[54] = 2; J[54] = 3; K[54] = 1;
3807  I[55] = 3; J[55] = 3; K[55] = 1;
3808  // element
3809  I[56] = 2; J[56] = 2; K[56] = 2;
3810  I[57] = 3; J[57] = 2; K[57] = 2;
3811  I[58] = 3; J[58] = 3; K[58] = 2;
3812  I[59] = 2; J[59] = 3; K[59] = 2;
3813  I[60] = 2; J[60] = 2; K[60] = 3;
3814  I[61] = 3; J[61] = 2; K[61] = 3;
3815  I[62] = 3; J[62] = 3; K[62] = 3;
3816  I[63] = 2; J[63] = 3; K[63] = 3;
3817  }
3818  else
3819  {
3820  mfem_error ("LagrangeHexFiniteElement::LagrangeHexFiniteElement");
3821  }
3822 
3823  fe1d = new Lagrange1DFiniteElement(degree);
3824  dof1d = fe1d -> GetDof();
3825 
3826 #ifndef MFEM_THREAD_SAFE
3827  shape1dx.SetSize(dof1d);
3828  shape1dy.SetSize(dof1d);
3829  shape1dz.SetSize(dof1d);
3830 
3831  dshape1dx.SetSize(dof1d,1);
3832  dshape1dy.SetSize(dof1d,1);
3833  dshape1dz.SetSize(dof1d,1);
3834 #endif
3835 
3836  for (int n = 0; n < Dof; n++)
3837  {
3838  Nodes.IntPoint(n).x = fe1d -> GetNodes().IntPoint(I[n]).x;
3839  Nodes.IntPoint(n).y = fe1d -> GetNodes().IntPoint(J[n]).x;
3840  Nodes.IntPoint(n).z = fe1d -> GetNodes().IntPoint(K[n]).x;
3841  }
3842 }
3843 
3845  Vector &shape) const
3846 {
3847  IntegrationPoint ipy, ipz;
3848  ipy.x = ip.y;
3849  ipz.x = ip.z;
3850 
3851 #ifdef MFEM_THREAD_SAFE
3852  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
3853 #endif
3854 
3855  fe1d -> CalcShape(ip, shape1dx);
3856  fe1d -> CalcShape(ipy, shape1dy);
3857  fe1d -> CalcShape(ipz, shape1dz);
3858 
3859  for (int n = 0; n < Dof; n++)
3860  {
3861  shape(n) = shape1dx(I[n]) * shape1dy(J[n]) * shape1dz(K[n]);
3862  }
3863 }
3864 
3866  DenseMatrix &dshape) const
3867 {
3868  IntegrationPoint ipy, ipz;
3869  ipy.x = ip.y;
3870  ipz.x = ip.z;
3871 
3872 #ifdef MFEM_THREAD_SAFE
3873  Vector shape1dx(dof1d), shape1dy(dof1d), shape1dz(dof1d);
3874  DenseMatrix dshape1dx(dof1d,1), dshape1dy(dof1d,1), dshape1dz(dof1d,1);
3875 #endif
3876 
3877  fe1d -> CalcShape(ip, shape1dx);
3878  fe1d -> CalcShape(ipy, shape1dy);
3879  fe1d -> CalcShape(ipz, shape1dz);
3880 
3881  fe1d -> CalcDShape(ip, dshape1dx);
3882  fe1d -> CalcDShape(ipy, dshape1dy);
3883  fe1d -> CalcDShape(ipz, dshape1dz);
3884 
3885  for (int n = 0; n < Dof; n++)
3886  {
3887  dshape(n,0) = dshape1dx(I[n],0) * shape1dy(J[n]) * shape1dz(K[n]);
3888  dshape(n,1) = shape1dx(I[n]) * dshape1dy(J[n],0) * shape1dz(K[n]);
3889  dshape(n,2) = shape1dx(I[n]) * shape1dy(J[n]) * dshape1dz(K[n],0);
3890  }
3891 }
3892 
3894 {
3895  delete fe1d;
3896 
3897  delete [] I;
3898  delete [] J;
3899  delete [] K;
3900 }
3901 
3902 
3904  : NodalFiniteElement(1, Geometry::SEGMENT, 3, 4)
3905 {
3906  Nodes.IntPoint(0).x = 0.0;
3907  Nodes.IntPoint(1).x = 1.0;
3908  Nodes.IntPoint(2).x = 0.5;
3909 }
3910 
3912  Vector &shape) const
3913 {
3914  double x = ip.x;
3915 
3916  if (x <= 0.5)
3917  {
3918  shape(0) = 1.0 - 2.0 * x;
3919  shape(1) = 0.0;
3920  shape(2) = 2.0 * x;
3921  }
3922  else
3923  {
3924  shape(0) = 0.0;
3925  shape(1) = 2.0 * x - 1.0;
3926  shape(2) = 2.0 - 2.0 * x;
3927  }
3928 }
3929 
3931  DenseMatrix &dshape) const
3932 {
3933  double x = ip.x;
3934 
3935  if (x <= 0.5)
3936  {
3937  dshape(0,0) = - 2.0;
3938  dshape(1,0) = 0.0;
3939  dshape(2,0) = 2.0;
3940  }
3941  else
3942  {
3943  dshape(0,0) = 0.0;
3944  dshape(1,0) = 2.0;
3945  dshape(2,0) = - 2.0;
3946  }
3947 }
3948 
3950  : NodalFiniteElement(2, Geometry::TRIANGLE, 6, 5)
3951 {
3952  Nodes.IntPoint(0).x = 0.0;
3953  Nodes.IntPoint(0).y = 0.0;
3954  Nodes.IntPoint(1).x = 1.0;
3955  Nodes.IntPoint(1).y = 0.0;
3956  Nodes.IntPoint(2).x = 0.0;
3957  Nodes.IntPoint(2).y = 1.0;
3958  Nodes.IntPoint(3).x = 0.5;
3959  Nodes.IntPoint(3).y = 0.0;
3960  Nodes.IntPoint(4).x = 0.5;
3961  Nodes.IntPoint(4).y = 0.5;
3962  Nodes.IntPoint(5).x = 0.0;
3963  Nodes.IntPoint(5).y = 0.5;
3964 }
3965 
3967  Vector &shape) const
3968 {
3969  int i;
3970 
3971  double L0, L1, L2;
3972  L0 = 2.0 * ( 1. - ip.x - ip.y );
3973  L1 = 2.0 * ( ip.x );
3974  L2 = 2.0 * ( ip.y );
3975 
3976  // The reference triangle is split in 4 triangles as follows:
3977  //
3978  // T0 - 0,3,5
3979  // T1 - 1,3,4
3980  // T2 - 2,4,5
3981  // T3 - 3,4,5
3982 
3983  for (i = 0; i < 6; i++)
3984  {
3985  shape(i) = 0.0;
3986  }
3987 
3988  if (L0 >= 1.0) // T0
3989  {
3990  shape(0) = L0 - 1.0;
3991  shape(3) = L1;
3992  shape(5) = L2;
3993  }
3994  else if (L1 >= 1.0) // T1
3995  {
3996  shape(3) = L0;
3997  shape(1) = L1 - 1.0;
3998  shape(4) = L2;
3999  }
4000  else if (L2 >= 1.0) // T2
4001  {
4002  shape(5) = L0;
4003  shape(4) = L1;
4004  shape(2) = L2 - 1.0;
4005  }
4006  else // T3
4007  {
4008  shape(3) = 1.0 - L2;
4009  shape(4) = 1.0 - L0;
4010  shape(5) = 1.0 - L1;
4011  }
4012 }
4013 
4015  DenseMatrix &dshape) const
4016 {
4017  int i,j;
4018 
4019  double L0, L1, L2;
4020  L0 = 2.0 * ( 1. - ip.x - ip.y );
4021  L1 = 2.0 * ( ip.x );
4022  L2 = 2.0 * ( ip.y );
4023 
4024  double DL0[2], DL1[2], DL2[2];
4025  DL0[0] = -2.0; DL0[1] = -2.0;
4026  DL1[0] = 2.0; DL1[1] = 0.0;
4027  DL2[0] = 0.0; DL2[1] = 2.0;
4028 
4029  for (i = 0; i < 6; i++)
4030  for (j = 0; j < 2; j++)
4031  {
4032  dshape(i,j) = 0.0;
4033  }
4034 
4035  if (L0 >= 1.0) // T0
4036  {
4037  for (j = 0; j < 2; j++)
4038  {
4039  dshape(0,j) = DL0[j];
4040  dshape(3,j) = DL1[j];
4041  dshape(5,j) = DL2[j];
4042  }
4043  }
4044  else if (L1 >= 1.0) // T1
4045  {
4046  for (j = 0; j < 2; j++)
4047  {
4048  dshape(3,j) = DL0[j];
4049  dshape(1,j) = DL1[j];
4050  dshape(4,j) = DL2[j];
4051  }
4052  }
4053  else if (L2 >= 1.0) // T2
4054  {
4055  for (j = 0; j < 2; j++)
4056  {
4057  dshape(5,j) = DL0[j];
4058  dshape(4,j) = DL1[j];
4059  dshape(2,j) = DL2[j];
4060  }
4061  }
4062  else // T3
4063  {
4064  for (j = 0; j < 2; j++)
4065  {
4066  dshape(3,j) = - DL2[j];
4067  dshape(4,j) = - DL0[j];
4068  dshape(5,j) = - DL1[j];
4069  }
4070  }
4071 }
4072 
4074  : NodalFiniteElement(3, Geometry::TETRAHEDRON, 10, 4)
4075 {
4076  Nodes.IntPoint(0).x = 0.0;
4077  Nodes.IntPoint(0).y = 0.0;
4078  Nodes.IntPoint(0).z = 0.0;
4079  Nodes.IntPoint(1).x = 1.0;
4080  Nodes.IntPoint(1).y = 0.0;
4081  Nodes.IntPoint(1).z = 0.0;
4082  Nodes.IntPoint(2).x = 0.0;
4083  Nodes.IntPoint(2).y = 1.0;
4084  Nodes.IntPoint(2).z = 0.0;
4085  Nodes.IntPoint(3).x = 0.0;
4086  Nodes.IntPoint(3).y = 0.0;
4087  Nodes.IntPoint(3).z = 1.0;
4088  Nodes.IntPoint(4).x = 0.5;
4089  Nodes.IntPoint(4).y = 0.0;
4090  Nodes.IntPoint(4).z = 0.0;
4091  Nodes.IntPoint(5).x = 0.0;
4092  Nodes.IntPoint(5).y = 0.5;
4093  Nodes.IntPoint(5).z = 0.0;
4094  Nodes.IntPoint(6).x = 0.0;
4095  Nodes.IntPoint(6).y = 0.0;
4096  Nodes.IntPoint(6).z = 0.5;
4097  Nodes.IntPoint(7).x = 0.5;
4098  Nodes.IntPoint(7).y = 0.5;
4099  Nodes.IntPoint(7).z = 0.0;
4100  Nodes.IntPoint(8).x = 0.5;
4101  Nodes.IntPoint(8).y = 0.0;
4102  Nodes.IntPoint(8).z = 0.5;
4103  Nodes.IntPoint(9).x = 0.0;
4104  Nodes.IntPoint(9).y = 0.5;
4105  Nodes.IntPoint(9).z = 0.5;
4106 }
4107 
4109  Vector &shape) const
4110 {
4111  int i;
4112 
4113  double L0, L1, L2, L3, L4, L5;
4114  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4115  L1 = 2.0 * ( ip.x );
4116  L2 = 2.0 * ( ip.y );
4117  L3 = 2.0 * ( ip.z );
4118  L4 = 2.0 * ( ip.x + ip.y );
4119  L5 = 2.0 * ( ip.y + ip.z );
4120 
4121  // The reference tetrahedron is split in 8 tetrahedra as follows:
4122  //
4123  // T0 - 0,4,5,6
4124  // T1 - 1,4,7,8
4125  // T2 - 2,5,7,9
4126  // T3 - 3,6,8,9
4127  // T4 - 4,5,6,8
4128  // T5 - 4,5,7,8
4129  // T6 - 5,6,8,9
4130  // T7 - 5,7,8,9
4131 
4132  for (i = 0; i < 10; i++)
4133  {
4134  shape(i) = 0.0;
4135  }
4136 
4137  if (L0 >= 1.0) // T0
4138  {
4139  shape(0) = L0 - 1.0;
4140  shape(4) = L1;
4141  shape(5) = L2;
4142  shape(6) = L3;
4143  }
4144  else if (L1 >= 1.0) // T1
4145  {
4146  shape(4) = L0;
4147  shape(1) = L1 - 1.0;
4148  shape(7) = L2;
4149  shape(8) = L3;
4150  }
4151  else if (L2 >= 1.0) // T2
4152  {
4153  shape(5) = L0;
4154  shape(7) = L1;
4155  shape(2) = L2 - 1.0;
4156  shape(9) = L3;
4157  }
4158  else if (L3 >= 1.0) // T3
4159  {
4160  shape(6) = L0;
4161  shape(8) = L1;
4162  shape(9) = L2;
4163  shape(3) = L3 - 1.0;
4164  }
4165  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4166  {
4167  shape(4) = 1.0 - L5;
4168  shape(5) = L2;
4169  shape(6) = 1.0 - L4;
4170  shape(8) = 1.0 - L0;
4171  }
4172  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4173  {
4174  shape(4) = 1.0 - L5;
4175  shape(5) = 1.0 - L1;
4176  shape(7) = L4 - 1.0;
4177  shape(8) = L3;
4178  }
4179  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4180  {
4181  shape(5) = 1.0 - L3;
4182  shape(6) = 1.0 - L4;
4183  shape(8) = L1;
4184  shape(9) = L5 - 1.0;
4185  }
4186  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4187  {
4188  shape(5) = L0;
4189  shape(7) = L4 - 1.0;
4190  shape(8) = 1.0 - L2;
4191  shape(9) = L5 - 1.0;
4192  }
4193 }
4194 
4196  DenseMatrix &dshape) const
4197 {
4198  int i,j;
4199 
4200  double L0, L1, L2, L3, L4, L5;
4201  L0 = 2.0 * ( 1. - ip.x - ip.y - ip.z );
4202  L1 = 2.0 * ( ip.x );
4203  L2 = 2.0 * ( ip.y );
4204  L3 = 2.0 * ( ip.z );
4205  L4 = 2.0 * ( ip.x + ip.y );
4206  L5 = 2.0 * ( ip.y + ip.z );
4207 
4208  double DL0[3], DL1[3], DL2[3], DL3[3], DL4[3], DL5[3];
4209  DL0[0] = -2.0; DL0[1] = -2.0; DL0[2] = -2.0;
4210  DL1[0] = 2.0; DL1[1] = 0.0; DL1[2] = 0.0;
4211  DL2[0] = 0.0; DL2[1] = 2.0; DL2[2] = 0.0;
4212  DL3[0] = 0.0; DL3[1] = 0.0; DL3[2] = 2.0;
4213  DL4[0] = 2.0; DL4[1] = 2.0; DL4[2] = 0.0;
4214  DL5[0] = 0.0; DL5[1] = 2.0; DL5[2] = 2.0;
4215 
4216  for (i = 0; i < 10; i++)
4217  for (j = 0; j < 3; j++)
4218  {
4219  dshape(i,j) = 0.0;
4220  }
4221 
4222  if (L0 >= 1.0) // T0
4223  {
4224  for (j = 0; j < 3; j++)
4225  {
4226  dshape(0,j) = DL0[j];
4227  dshape(4,j) = DL1[j];
4228  dshape(5,j) = DL2[j];
4229  dshape(6,j) = DL3[j];
4230  }
4231  }
4232  else if (L1 >= 1.0) // T1
4233  {
4234  for (j = 0; j < 3; j++)
4235  {
4236  dshape(4,j) = DL0[j];
4237  dshape(1,j) = DL1[j];
4238  dshape(7,j) = DL2[j];
4239  dshape(8,j) = DL3[j];
4240  }
4241  }
4242  else if (L2 >= 1.0) // T2
4243  {
4244  for (j = 0; j < 3; j++)
4245  {
4246  dshape(5,j) = DL0[j];
4247  dshape(7,j) = DL1[j];
4248  dshape(2,j) = DL2[j];
4249  dshape(9,j) = DL3[j];
4250  }
4251  }
4252  else if (L3 >= 1.0) // T3
4253  {
4254  for (j = 0; j < 3; j++)
4255  {
4256  dshape(6,j) = DL0[j];
4257  dshape(8,j) = DL1[j];
4258  dshape(9,j) = DL2[j];
4259  dshape(3,j) = DL3[j];
4260  }
4261  }
4262  else if ((L4 <= 1.0) && (L5 <= 1.0)) // T4
4263  {
4264  for (j = 0; j < 3; j++)
4265  {
4266  dshape(4,j) = - DL5[j];
4267  dshape(5,j) = DL2[j];
4268  dshape(6,j) = - DL4[j];
4269  dshape(8,j) = - DL0[j];
4270  }
4271  }
4272  else if ((L4 >= 1.0) && (L5 <= 1.0)) // T5
4273  {
4274  for (j = 0; j < 3; j++)
4275  {
4276  dshape(4,j) = - DL5[j];
4277  dshape(5,j) = - DL1[j];
4278  dshape(7,j) = DL4[j];
4279  dshape(8,j) = DL3[j];
4280  }
4281  }
4282  else if ((L4 <= 1.0) && (L5 >= 1.0)) // T6
4283  {
4284  for (j = 0; j < 3; j++)
4285  {
4286  dshape(5,j) = - DL3[j];
4287  dshape(6,j) = - DL4[j];
4288  dshape(8,j) = DL1[j];
4289  dshape(9,j) = DL5[j];
4290  }
4291  }
4292  else if ((L4 >= 1.0) && (L5 >= 1.0)) // T7
4293  {
4294  for (j = 0; j < 3; j++)
4295  {
4296  dshape(5,j) = DL0[j];
4297  dshape(7,j) = DL4[j];
4298  dshape(8,j) = - DL2[j];
4299  dshape(9,j) = DL5[j];
4300  }
4301  }
4302 }
4303 
4304 
4306  : NodalFiniteElement(2, Geometry::SQUARE , 9, 1, FunctionSpace::rQk)
4307 {
4308  Nodes.IntPoint(0).x = 0.0;
4309  Nodes.IntPoint(0).y = 0.0;
4310  Nodes.IntPoint(1).x = 1.0;
4311  Nodes.IntPoint(1).y = 0.0;
4312  Nodes.IntPoint(2).x = 1.0;
4313  Nodes.IntPoint(2).y = 1.0;
4314  Nodes.IntPoint(3).x = 0.0;
4315  Nodes.IntPoint(3).y = 1.0;
4316  Nodes.IntPoint(4).x = 0.5;
4317  Nodes.IntPoint(4).y = 0.0;
4318  Nodes.IntPoint(5).x = 1.0;
4319  Nodes.IntPoint(5).y = 0.5;
4320  Nodes.IntPoint(6).x = 0.5;
4321  Nodes.IntPoint(6).y = 1.0;
4322  Nodes.IntPoint(7).x = 0.0;
4323  Nodes.IntPoint(7).y = 0.5;
4324  Nodes.IntPoint(8).x = 0.5;
4325  Nodes.IntPoint(8).y = 0.5;
4326 }
4327 
4329  Vector &shape) const
4330 {
4331  int i;
4332  double x = ip.x, y = ip.y;
4333  double Lx, Ly;
4334  Lx = 2.0 * ( 1. - x );
4335  Ly = 2.0 * ( 1. - y );
4336 
4337  // The reference square is split in 4 squares as follows:
4338  //
4339  // T0 - 0,4,7,8
4340  // T1 - 1,4,5,8
4341  // T2 - 2,5,6,8
4342  // T3 - 3,6,7,8
4343 
4344  for (i = 0; i < 9; i++)
4345  {
4346  shape(i) = 0.0;
4347  }
4348 
4349  if ((x <= 0.5) && (y <= 0.5)) // T0
4350  {
4351  shape(0) = (Lx - 1.0) * (Ly - 1.0);
4352  shape(4) = (2.0 - Lx) * (Ly - 1.0);
4353  shape(8) = (2.0 - Lx) * (2.0 - Ly);
4354  shape(7) = (Lx - 1.0) * (2.0 - Ly);
4355  }
4356  else if ((x >= 0.5) && (y <= 0.5)) // T1
4357  {
4358  shape(4) = Lx * (Ly - 1.0);
4359  shape(1) = (1.0 - Lx) * (Ly - 1.0);
4360  shape(5) = (1.0 - Lx) * (2.0 - Ly);
4361  shape(8) = Lx * (2.0 - Ly);
4362  }
4363  else if ((x >= 0.5) && (y >= 0.5)) // T2
4364  {
4365  shape(8) = Lx * Ly ;
4366  shape(5) = (1.0 - Lx) * Ly ;
4367  shape(2) = (1.0 - Lx) * (1.0 - Ly);
4368  shape(6) = Lx * (1.0 - Ly);
4369  }
4370  else if ((x <= 0.5) && (y >= 0.5)) // T3
4371  {
4372  shape(7) = (Lx - 1.0) * Ly ;
4373  shape(8) = (2.0 - Lx) * Ly ;
4374  shape(6) = (2.0 - Lx) * (1.0 - Ly);
4375  shape(3) = (Lx - 1.0) * (1.0 - Ly);
4376  }
4377 }
4378 
4380  DenseMatrix &dshape) const
4381 {
4382  int i,j;
4383  double x = ip.x, y = ip.y;
4384  double Lx, Ly;
4385  Lx = 2.0 * ( 1. - x );
4386  Ly = 2.0 * ( 1. - y );
4387 
4388  for (i = 0; i < 9; i++)
4389  for (j = 0; j < 2; j++)
4390  {
4391  dshape(i,j) = 0.0;
4392  }
4393 
4394  if ((x <= 0.5) && (y <= 0.5)) // T0
4395  {
4396  dshape(0,0) = 2.0 * (1.0 - Ly);
4397  dshape(0,1) = 2.0 * (1.0 - Lx);
4398 
4399  dshape(4,0) = 2.0 * (Ly - 1.0);
4400  dshape(4,1) = -2.0 * (2.0 - Lx);
4401 
4402  dshape(8,0) = 2.0 * (2.0 - Ly);
4403  dshape(8,1) = 2.0 * (2.0 - Lx);
4404 
4405  dshape(7,0) = -2.0 * (2.0 - Ly);
4406  dshape(7,0) = 2.0 * (Lx - 1.0);
4407  }
4408  else if ((x >= 0.5) && (y <= 0.5)) // T1
4409  {
4410  dshape(4,0) = -2.0 * (Ly - 1.0);
4411  dshape(4,1) = -2.0 * Lx;
4412 
4413  dshape(1,0) = 2.0 * (Ly - 1.0);
4414  dshape(1,1) = -2.0 * (1.0 - Lx);
4415 
4416  dshape(5,0) = 2.0 * (2.0 - Ly);
4417  dshape(5,1) = 2.0 * (1.0 - Lx);
4418 
4419  dshape(8,0) = -2.0 * (2.0 - Ly);
4420  dshape(8,1) = 2.0 * Lx;
4421  }
4422  else if ((x >= 0.5) && (y >= 0.5)) // T2
4423  {
4424  dshape(8,0) = -2.0 * Ly;
4425  dshape(8,1) = -2.0 * Lx;
4426 
4427  dshape(5,0) = 2.0 * Ly;
4428  dshape(5,1) = -2.0 * (1.0 - Lx);
4429 
4430  dshape(2,0) = 2.0 * (1.0 - Ly);
4431  dshape(2,1) = 2.0 * (1.0 - Lx);
4432 
4433  dshape(6,0) = -2.0 * (1.0 - Ly);
4434  dshape(6,1) = 2.0 * Lx;
4435  }
4436  else if ((x <= 0.5) && (y >= 0.5)) // T3
4437  {
4438  dshape(7,0) = -2.0 * Ly;
4439  dshape(7,1) = -2.0 * (Lx - 1.0);
4440 
4441  dshape(8,0) = 2.0 * Ly ;
4442  dshape(8,1) = -2.0 * (2.0 - Lx);
4443 
4444  dshape(6,0) = 2.0 * (1.0 - Ly);
4445  dshape(6,1) = 2.0 * (2.0 - Lx);
4446 
4447  dshape(3,0) = -2.0 * (1.0 - Ly);
4448  dshape(3,1) = 2.0 * (Lx - 1.0);
4449  }
4450 }
4451 
4453  : NodalFiniteElement(3, Geometry::CUBE, 27, 2, FunctionSpace::rQk)
4454 {
4455  double I[27];
4456  double J[27];
4457  double K[27];
4458  // nodes
4459  I[ 0] = 0.0; J[ 0] = 0.0; K[ 0] = 0.0;
4460  I[ 1] = 1.0; J[ 1] = 0.0; K[ 1] = 0.0;
4461  I[ 2] = 1.0; J[ 2] = 1.0; K[ 2] = 0.0;
4462  I[ 3] = 0.0; J[ 3] = 1.0; K[ 3] = 0.0;
4463  I[ 4] = 0.0; J[ 4] = 0.0; K[ 4] = 1.0;
4464  I[ 5] = 1.0; J[ 5] = 0.0; K[ 5] = 1.0;
4465  I[ 6] = 1.0; J[ 6] = 1.0; K[ 6] = 1.0;
4466  I[ 7] = 0.0; J[ 7] = 1.0; K[ 7] = 1.0;
4467  // edges
4468  I[ 8] = 0.5; J[ 8] = 0.0; K[ 8] = 0.0;
4469  I[ 9] = 1.0; J[ 9] = 0.5; K[ 9] = 0.0;
4470  I[10] = 0.5; J[10] = 1.0; K[10] = 0.0;
4471  I[11] = 0.0; J[11] = 0.5; K[11] = 0.0;
4472  I[12] = 0.5; J[12] = 0.0; K[12] = 1.0;
4473  I[13] = 1.0; J[13] = 0.5; K[13] = 1.0;
4474  I[14] = 0.5; J[14] = 1.0; K[14] = 1.0;
4475  I[15] = 0.0; J[15] = 0.5; K[15] = 1.0;
4476  I[16] = 0.0; J[16] = 0.0; K[16] = 0.5;
4477  I[17] = 1.0; J[17] = 0.0; K[17] = 0.5;
4478  I[18] = 1.0; J[18] = 1.0; K[18] = 0.5;
4479  I[19] = 0.0; J[19] = 1.0; K[19] = 0.5;
4480  // faces
4481  I[20] = 0.5; J[20] = 0.5; K[20] = 0.0;
4482  I[21] = 0.5; J[21] = 0.0; K[21] = 0.5;
4483  I[22] = 1.0; J[22] = 0.5; K[22] = 0.5;
4484  I[23] = 0.5; J[23] = 1.0; K[23] = 0.5;
4485  I[24] = 0.0; J[24] = 0.5; K[24] = 0.5;
4486  I[25] = 0.5; J[25] = 0.5; K[25] = 1.0;
4487  // element
4488  I[26] = 0.5; J[26] = 0.5; K[26] = 0.5;
4489 
4490  for (int n = 0; n < 27; n++)
4491  {
4492  Nodes.IntPoint(n).x = I[n];
4493  Nodes.IntPoint(n).y = J[n];
4494  Nodes.IntPoint(n).z = K[n];
4495  }
4496 }
4497 
4499  Vector &shape) const
4500 {
4501  int i, N[8];
4502  double Lx, Ly, Lz;
4503  double x = ip.x, y = ip.y, z = ip.z;
4504 
4505  for (i = 0; i < 27; i++)
4506  {
4507  shape(i) = 0.0;
4508  }
4509 
4510  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4511  {
4512  Lx = 1.0 - 2.0 * x;
4513  Ly = 1.0 - 2.0 * y;
4514  Lz = 1.0 - 2.0 * z;
4515 
4516  N[0] = 0;
4517  N[1] = 8;
4518  N[2] = 20;
4519  N[3] = 11;
4520  N[4] = 16;
4521  N[5] = 21;
4522  N[6] = 26;
4523  N[7] = 24;
4524  }
4525  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4526  {
4527  Lx = 2.0 - 2.0 * x;
4528  Ly = 1.0 - 2.0 * y;
4529  Lz = 1.0 - 2.0 * z;
4530 
4531  N[0] = 8;
4532  N[1] = 1;
4533  N[2] = 9;
4534  N[3] = 20;
4535  N[4] = 21;
4536  N[5] = 17;
4537  N[6] = 22;
4538  N[7] = 26;
4539  }
4540  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4541  {
4542  Lx = 2.0 - 2.0 * x;
4543  Ly = 2.0 - 2.0 * y;
4544  Lz = 1.0 - 2.0 * z;
4545 
4546  N[0] = 20;
4547  N[1] = 9;
4548  N[2] = 2;
4549  N[3] = 10;
4550  N[4] = 26;
4551  N[5] = 22;
4552  N[6] = 18;
4553  N[7] = 23;
4554  }
4555  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4556  {
4557  Lx = 1.0 - 2.0 * x;
4558  Ly = 2.0 - 2.0 * y;
4559  Lz = 1.0 - 2.0 * z;
4560 
4561  N[0] = 11;
4562  N[1] = 20;
4563  N[2] = 10;
4564  N[3] = 3;
4565  N[4] = 24;
4566  N[5] = 26;
4567  N[6] = 23;
4568  N[7] = 19;
4569  }
4570  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4571  {
4572  Lx = 1.0 - 2.0 * x;
4573  Ly = 1.0 - 2.0 * y;
4574  Lz = 2.0 - 2.0 * z;
4575 
4576  N[0] = 16;
4577  N[1] = 21;
4578  N[2] = 26;
4579  N[3] = 24;
4580  N[4] = 4;
4581  N[5] = 12;
4582  N[6] = 25;
4583  N[7] = 15;
4584  }
4585  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4586  {
4587  Lx = 2.0 - 2.0 * x;
4588  Ly = 1.0 - 2.0 * y;
4589  Lz = 2.0 - 2.0 * z;
4590 
4591  N[0] = 21;
4592  N[1] = 17;
4593  N[2] = 22;
4594  N[3] = 26;
4595  N[4] = 12;
4596  N[5] = 5;
4597  N[6] = 13;
4598  N[7] = 25;
4599  }
4600  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4601  {
4602  Lx = 2.0 - 2.0 * x;
4603  Ly = 2.0 - 2.0 * y;
4604  Lz = 2.0 - 2.0 * z;
4605 
4606  N[0] = 26;
4607  N[1] = 22;
4608  N[2] = 18;
4609  N[3] = 23;
4610  N[4] = 25;
4611  N[5] = 13;
4612  N[6] = 6;
4613  N[7] = 14;
4614  }
4615  else // T7
4616  {
4617  Lx = 1.0 - 2.0 * x;
4618  Ly = 2.0 - 2.0 * y;
4619  Lz = 2.0 - 2.0 * z;
4620 
4621  N[0] = 24;
4622  N[1] = 26;
4623  N[2] = 23;
4624  N[3] = 19;
4625  N[4] = 15;
4626  N[5] = 25;
4627  N[6] = 14;
4628  N[7] = 7;
4629  }
4630 
4631  shape(N[0]) = Lx * Ly * Lz;
4632  shape(N[1]) = (1 - Lx) * Ly * Lz;
4633  shape(N[2]) = (1 - Lx) * (1 - Ly) * Lz;
4634  shape(N[3]) = Lx * (1 - Ly) * Lz;
4635  shape(N[4]) = Lx * Ly * (1 - Lz);
4636  shape(N[5]) = (1 - Lx) * Ly * (1 - Lz);
4637  shape(N[6]) = (1 - Lx) * (1 - Ly) * (1 - Lz);
4638  shape(N[7]) = Lx * (1 - Ly) * (1 - Lz);
4639 }
4640 
4642  DenseMatrix &dshape) const
4643 {
4644  int i, j, N[8];
4645  double Lx, Ly, Lz;
4646  double x = ip.x, y = ip.y, z = ip.z;
4647 
4648  for (i = 0; i < 27; i++)
4649  for (j = 0; j < 3; j++)
4650  {
4651  dshape(i,j) = 0.0;
4652  }
4653 
4654  if ((x <= 0.5) && (y <= 0.5) && (z <= 0.5)) // T0
4655  {
4656  Lx = 1.0 - 2.0 * x;
4657  Ly = 1.0 - 2.0 * y;
4658  Lz = 1.0 - 2.0 * z;
4659 
4660  N[0] = 0;
4661  N[1] = 8;
4662  N[2] = 20;
4663  N[3] = 11;
4664  N[4] = 16;
4665  N[5] = 21;
4666  N[6] = 26;
4667  N[7] = 24;
4668  }
4669  else if ((x >= 0.5) && (y <= 0.5) && (z <= 0.5)) // T1
4670  {
4671  Lx = 2.0 - 2.0 * x;
4672  Ly = 1.0 - 2.0 * y;
4673  Lz = 1.0 - 2.0 * z;
4674 
4675  N[0] = 8;
4676  N[1] = 1;
4677  N[2] = 9;
4678  N[3] = 20;
4679  N[4] = 21;
4680  N[5] = 17;
4681  N[6] = 22;
4682  N[7] = 26;
4683  }
4684  else if ((x <= 0.5) && (y >= 0.5) && (z <= 0.5)) // T2
4685  {
4686  Lx = 2.0 - 2.0 * x;
4687  Ly = 2.0 - 2.0 * y;
4688  Lz = 1.0 - 2.0 * z;
4689 
4690  N[0] = 20;
4691  N[1] = 9;
4692  N[2] = 2;
4693  N[3] = 10;
4694  N[4] = 26;
4695  N[5] = 22;
4696  N[6] = 18;
4697  N[7] = 23;
4698  }
4699  else if ((x >= 0.5) && (y >= 0.5) && (z <= 0.5)) // T3
4700  {
4701  Lx = 1.0 - 2.0 * x;
4702  Ly = 2.0 - 2.0 * y;
4703  Lz = 1.0 - 2.0 * z;
4704 
4705  N[0] = 11;
4706  N[1] = 20;
4707  N[2] = 10;
4708  N[3] = 3;
4709  N[4] = 24;
4710  N[5] = 26;
4711  N[6] = 23;
4712  N[7] = 19;
4713  }
4714  else if ((x <= 0.5) && (y <= 0.5) && (z >= 0.5)) // T4
4715  {
4716  Lx = 1.0 - 2.0 * x;
4717  Ly = 1.0 - 2.0 * y;
4718  Lz = 2.0 - 2.0 * z;
4719 
4720  N[0] = 16;
4721  N[1] = 21;
4722  N[2] = 26;
4723  N[3] = 24;
4724  N[4] = 4;
4725  N[5] = 12;
4726  N[6] = 25;
4727  N[7] = 15;
4728  }
4729  else if ((x >= 0.5) && (y <= 0.5) && (z >= 0.5)) // T5
4730  {
4731  Lx = 2.0 - 2.0 * x;
4732  Ly = 1.0 - 2.0 * y;
4733  Lz = 2.0 - 2.0 * z;
4734 
4735  N[0] = 21;
4736  N[1] = 17;
4737  N[2] = 22;
4738  N[3] = 26;
4739  N[4] = 12;
4740  N[5] = 5;
4741  N[6] = 13;
4742  N[7] = 25;
4743  }
4744  else if ((x <= 0.5) && (y >= 0.5) && (z >= 0.5)) // T6
4745  {
4746  Lx = 2.0 - 2.0 * x;
4747  Ly = 2.0 - 2.0 * y;
4748  Lz = 2.0 - 2.0 * z;
4749 
4750  N[0] = 26;
4751  N[1] = 22;
4752  N[2] = 18;
4753  N[3] = 23;
4754  N[4] = 25;
4755  N[5] = 13;
4756  N[6] = 6;
4757  N[7] = 14;
4758  }
4759  else // T7
4760  {
4761  Lx = 1.0 - 2.0 * x;
4762  Ly = 2.0 - 2.0 * y;
4763  Lz = 2.0 - 2.0 * z;
4764 
4765  N[0] = 24;
4766  N[1] = 26;
4767  N[2] = 23;
4768  N[3] = 19;
4769  N[4] = 15;
4770  N[5] = 25;
4771  N[6] = 14;
4772  N[7] = 7;
4773  }
4774 
4775  dshape(N[0],0) = -2.0 * Ly * Lz ;
4776  dshape(N[0],1) = -2.0 * Lx * Lz ;
4777  dshape(N[0],2) = -2.0 * Lx * Ly ;
4778 
4779  dshape(N[1],0) = 2.0 * Ly * Lz ;
4780  dshape(N[1],1) = -2.0 * (1 - Lx) * Lz ;
4781  dshape(N[1],2) = -2.0 * (1 - Lx) * Ly ;
4782 
4783  dshape(N[2],0) = 2.0 * (1 - Ly) * Lz ;
4784  dshape(N[2],1) = 2.0 * (1 - Lx) * Lz ;
4785  dshape(N[2],2) = -2.0 * (1 - Lx) * (1 - Ly);
4786 
4787  dshape(N[3],0) = -2.0 * (1 - Ly) * Lz ;
4788  dshape(N[3],1) = 2.0 * Lx * Lz ;
4789  dshape(N[3],2) = -2.0 * Lx * (1 - Ly);
4790 
4791  dshape(N[4],0) = -2.0 * Ly * (1 - Lz);
4792  dshape(N[4],1) = -2.0 * Lx * (1 - Lz);
4793  dshape(N[4],2) = 2.0 * Lx * Ly ;
4794 
4795  dshape(N[5],0) = 2.0 * Ly * (1 - Lz);
4796  dshape(N[5],1) = -2.0 * (1 - Lx) * (1 - Lz);
4797  dshape(N[5],2) = 2.0 * (1 - Lx) * Ly ;
4798 
4799  dshape(N[6],0) = 2.0 * (1 - Ly) * (1 - Lz);
4800  dshape(N[6],1) = 2.0 * (1 - Lx) * (1 - Lz);
4801  dshape(N[6],2) = 2.0 * (1 - Lx) * (1 - Ly);
4802 
4803  dshape(N[7],0) = -2.0 * (1 - Ly) * (1 - Lz);
4804  dshape(N[7],1) = 2.0 * Lx * (1 - Lz);
4805  dshape(N[7],2) = 2.0 * Lx * (1 - Ly);
4806 }
4807 
4808 
4810  : VectorFiniteElement(3, Geometry::CUBE, 12, 1, H_CURL, FunctionSpace::Qk)
4811 {
4812  // not real nodes ...
4813  Nodes.IntPoint(0).x = 0.5;
4814  Nodes.IntPoint(0).y = 0.0;
4815  Nodes.IntPoint(0).z = 0.0;
4816 
4817  Nodes.IntPoint(1).x = 1.0;
4818  Nodes.IntPoint(1).y = 0.5;
4819  Nodes.IntPoint(1).z = 0.0;
4820 
4821  Nodes.IntPoint(2).x = 0.5;
4822  Nodes.IntPoint(2).y = 1.0;
4823  Nodes.IntPoint(2).z = 0.0;
4824 
4825  Nodes.IntPoint(3).x = 0.0;
4826  Nodes.IntPoint(3).y = 0.5;
4827  Nodes.IntPoint(3).z = 0.0;
4828 
4829  Nodes.IntPoint(4).x = 0.5;
4830  Nodes.IntPoint(4).y = 0.0;
4831  Nodes.IntPoint(4).z = 1.0;
4832 
4833  Nodes.IntPoint(5).x = 1.0;
4834  Nodes.IntPoint(5).y = 0.5;
4835  Nodes.IntPoint(5).z = 1.0;
4836 
4837  Nodes.IntPoint(6).x = 0.5;
4838  Nodes.IntPoint(6).y = 1.0;
4839  Nodes.IntPoint(6).z = 1.0;
4840 
4841  Nodes.IntPoint(7).x = 0.0;
4842  Nodes.IntPoint(7).y = 0.5;
4843  Nodes.IntPoint(7).z = 1.0;
4844 
4845  Nodes.IntPoint(8).x = 0.0;
4846  Nodes.IntPoint(8).y = 0.0;
4847  Nodes.IntPoint(8).z = 0.5;
4848 
4849  Nodes.IntPoint(9).x = 1.0;
4850  Nodes.IntPoint(9).y = 0.0;
4851  Nodes.IntPoint(9).z = 0.5;
4852 
4853  Nodes.IntPoint(10).x= 1.0;
4854  Nodes.IntPoint(10).y= 1.0;
4855  Nodes.IntPoint(10).z= 0.5;
4856 
4857  Nodes.IntPoint(11).x= 0.0;
4858  Nodes.IntPoint(11).y= 1.0;
4859  Nodes.IntPoint(11).z= 0.5;
4860 }
4861 
4863  DenseMatrix &shape) const
4864 {
4865  double x = ip.x, y = ip.y, z = ip.z;
4866 
4867  shape(0,0) = (1. - y) * (1. - z);
4868  shape(0,1) = 0.;
4869  shape(0,2) = 0.;
4870 
4871  shape(2,0) = y * (1. - z);
4872  shape(2,1) = 0.;
4873  shape(2,2) = 0.;
4874 
4875  shape(4,0) = z * (1. - y);
4876  shape(4,1) = 0.;
4877  shape(4,2) = 0.;
4878 
4879  shape(6,0) = y * z;
4880  shape(6,1) = 0.;
4881  shape(6,2) = 0.;
4882 
4883  shape(1,0) = 0.;
4884  shape(1,1) = x * (1. - z);
4885  shape(1,2) = 0.;
4886 
4887  shape(3,0) = 0.;
4888  shape(3,1) = (1. - x) * (1. - z);
4889  shape(3,2) = 0.;
4890 
4891  shape(5,0) = 0.;
4892  shape(5,1) = x * z;
4893  shape(5,2) = 0.;
4894 
4895  shape(7,0) = 0.;
4896  shape(7,1) = (1. - x) * z;
4897  shape(7,2) = 0.;
4898 
4899  shape(8,0) = 0.;
4900  shape(8,1) = 0.;
4901  shape(8,2) = (1. - x) * (1. - y);
4902 
4903  shape(9,0) = 0.;
4904  shape(9,1) = 0.;
4905  shape(9,2) = x * (1. - y);
4906 
4907  shape(10,0) = 0.;
4908  shape(10,1) = 0.;
4909  shape(10,2) = x * y;
4910 
4911  shape(11,0) = 0.;
4912  shape(11,1) = 0.;
4913  shape(11,2) = y * (1. - x);
4914 
4915 }
4916 
4918  DenseMatrix &curl_shape)
4919 const
4920 {
4921  double x = ip.x, y = ip.y, z = ip.z;
4922 
4923  curl_shape(0,0) = 0.;
4924  curl_shape(0,1) = y - 1.;
4925  curl_shape(0,2) = 1. - z;
4926 
4927  curl_shape(2,0) = 0.;
4928  curl_shape(2,1) = -y;
4929  curl_shape(2,2) = z - 1.;
4930 
4931  curl_shape(4,0) = 0;
4932  curl_shape(4,1) = 1. - y;
4933  curl_shape(4,2) = z;
4934 
4935  curl_shape(6,0) = 0.;
4936  curl_shape(6,1) = y;
4937  curl_shape(6,2) = -z;
4938 
4939  curl_shape(1,0) = x;
4940  curl_shape(1,1) = 0.;
4941  curl_shape(1,2) = 1. - z;
4942 
4943  curl_shape(3,0) = 1. - x;
4944  curl_shape(3,1) = 0.;
4945  curl_shape(3,2) = z - 1.;
4946 
4947  curl_shape(5,0) = -x;
4948  curl_shape(5,1) = 0.;
4949  curl_shape(5,2) = z;
4950 
4951  curl_shape(7,0) = x - 1.;
4952  curl_shape(7,1) = 0.;
4953  curl_shape(7,2) = -z;
4954 
4955  curl_shape(8,0) = x - 1.;
4956  curl_shape(8,1) = 1. - y;
4957  curl_shape(8,2) = 0.;
4958 
4959  curl_shape(9,0) = -x;
4960  curl_shape(9,1) = y - 1.;
4961  curl_shape(9,2) = 0;
4962 
4963  curl_shape(10,0) = x;
4964  curl_shape(10,1) = -y;
4965  curl_shape(10,2) = 0.;
4966 
4967  curl_shape(11,0) = 1. - x;
4968  curl_shape(11,1) = y;
4969  curl_shape(11,2) = 0.;
4970 }
4971 
4972 const double Nedelec1HexFiniteElement::tk[12][3] =
4973 {
4974  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
4975  {1,0,0}, {0,1,0}, {1,0,0}, {0,1,0},
4976  {0,0,1}, {0,0,1}, {0,0,1}, {0,0,1}
4977 };
4978 
4980  ElementTransformation &Trans, DenseMatrix &I) const
4981 {
4982  int k, j;
4983 #ifdef MFEM_THREAD_SAFE
4985 #endif
4986 
4987 #ifdef MFEM_DEBUG
4988  for (k = 0; k < 12; k++)
4989  {
4991  for (j = 0; j < 12; j++)
4992  {
4993  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
4994  vshape(j,2)*tk[k][2] );
4995  if (j == k) { d -= 1.0; }
4996  if (fabs(d) > 1.0e-12)
4997  {
4998  cerr << "Nedelec1HexFiniteElement::GetLocalInterpolation (...)\n"
4999  " k = " << k << ", j = " << j << ", d = " << d << endl;
5000  mfem_error();
5001  }
5002  }
5003  }
5004 #endif
5005 
5006  IntegrationPoint ip;
5007  ip.x = ip.y = ip.z = 0.0;
5008  Trans.SetIntPoint (&ip);
5009  // Trans must be linear (more to have embedding?)
5010  const DenseMatrix &J = Trans.Jacobian();
5011  double vk[3];
5012  Vector xk (vk, 3);
5013 
5014  for (k = 0; k < 12; k++)
5015  {
5016  Trans.Transform (Nodes.IntPoint (k), xk);
5017  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5018  CalcVShape (ip, vshape);
5019  // vk = J tk
5020  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5021  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5022  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5023  for (j = 0; j < 12; j++)
5024  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5025  vshape(j,2)*vk[2])) < 1.0e-12)
5026  {
5027  I(k,j) = 0.0;
5028  }
5029  }
5030 }
5031 
5034  Vector &dofs) const
5035 {
5036  double vk[3];
5037  Vector xk (vk, 3);
5038 
5039  for (int k = 0; k < 12; k++)
5040  {
5041  Trans.SetIntPoint (&Nodes.IntPoint (k));
5042  const DenseMatrix &J = Trans.Jacobian();
5043 
5044  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5045  // xk^t J tk
5046  dofs(k) =
5047  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5048  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5049  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5050  }
5051 }
5052 
5053 
5055  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 6, 1, H_CURL)
5056 {
5057  // not real nodes ...
5058  Nodes.IntPoint(0).x = 0.5;
5059  Nodes.IntPoint(0).y = 0.0;
5060  Nodes.IntPoint(0).z = 0.0;
5061 
5062  Nodes.IntPoint(1).x = 0.0;
5063  Nodes.IntPoint(1).y = 0.5;
5064  Nodes.IntPoint(1).z = 0.0;
5065 
5066  Nodes.IntPoint(2).x = 0.0;
5067  Nodes.IntPoint(2).y = 0.0;
5068  Nodes.IntPoint(2).z = 0.5;
5069 
5070  Nodes.IntPoint(3).x = 0.5;
5071  Nodes.IntPoint(3).y = 0.5;
5072  Nodes.IntPoint(3).z = 0.0;
5073 
5074  Nodes.IntPoint(4).x = 0.5;
5075  Nodes.IntPoint(4).y = 0.0;
5076  Nodes.IntPoint(4).z = 0.5;
5077 
5078  Nodes.IntPoint(5).x = 0.0;
5079  Nodes.IntPoint(5).y = 0.5;
5080  Nodes.IntPoint(5).z = 0.5;
5081 }
5082 
5084  DenseMatrix &shape) const
5085 {
5086  double x = ip.x, y = ip.y, z = ip.z;
5087 
5088  shape(0,0) = 1. - y - z;
5089  shape(0,1) = x;
5090  shape(0,2) = x;
5091 
5092  shape(1,0) = y;
5093  shape(1,1) = 1. - x - z;
5094  shape(1,2) = y;
5095 
5096  shape(2,0) = z;
5097  shape(2,1) = z;
5098  shape(2,2) = 1. - x - y;
5099 
5100  shape(3,0) = -y;
5101  shape(3,1) = x;
5102  shape(3,2) = 0.;
5103 
5104  shape(4,0) = -z;
5105  shape(4,1) = 0.;
5106  shape(4,2) = x;
5107 
5108  shape(5,0) = 0.;
5109  shape(5,1) = -z;
5110  shape(5,2) = y;
5111 }
5112 
5114  DenseMatrix &curl_shape)
5115 const
5116 {
5117  curl_shape(0,0) = 0.;
5118  curl_shape(0,1) = -2.;
5119  curl_shape(0,2) = 2.;
5120 
5121  curl_shape(1,0) = 2.;
5122  curl_shape(1,1) = 0.;
5123  curl_shape(1,2) = -2.;
5124 
5125  curl_shape(2,0) = -2.;
5126  curl_shape(2,1) = 2.;
5127  curl_shape(2,2) = 0.;
5128 
5129  curl_shape(3,0) = 0.;
5130  curl_shape(3,1) = 0.;
5131  curl_shape(3,2) = 2.;
5132 
5133  curl_shape(4,0) = 0.;
5134  curl_shape(4,1) = -2.;
5135  curl_shape(4,2) = 0.;
5136 
5137  curl_shape(5,0) = 2.;
5138  curl_shape(5,1) = 0.;
5139  curl_shape(5,2) = 0.;
5140 }
5141 
5142 const double Nedelec1TetFiniteElement::tk[6][3] =
5143 {{1,0,0}, {0,1,0}, {0,0,1}, {-1,1,0}, {-1,0,1}, {0,-1,1}};
5144 
5146  ElementTransformation &Trans, DenseMatrix &I) const
5147 {
5148  int k, j;
5149 #ifdef MFEM_THREAD_SAFE
5151 #endif
5152 
5153 #ifdef MFEM_DEBUG
5154  for (k = 0; k < 6; k++)
5155  {
5157  for (j = 0; j < 6; j++)
5158  {
5159  double d = ( vshape(j,0)*tk[k][0] + vshape(j,1)*tk[k][1] +
5160  vshape(j,2)*tk[k][2] );
5161  if (j == k) { d -= 1.0; }
5162  if (fabs(d) > 1.0e-12)
5163  {
5164  cerr << "Nedelec1TetFiniteElement::GetLocalInterpolation (...)\n"
5165  " k = " << k << ", j = " << j << ", d = " << d << endl;
5166  mfem_error();
5167  }
5168  }
5169  }
5170 #endif
5171 
5172  IntegrationPoint ip;
5173  ip.x = ip.y = ip.z = 0.0;
5174  Trans.SetIntPoint (&ip);
5175  // Trans must be linear
5176  const DenseMatrix &J = Trans.Jacobian();
5177  double vk[3];
5178  Vector xk (vk, 3);
5179 
5180  for (k = 0; k < 6; k++)
5181  {
5182  Trans.Transform (Nodes.IntPoint (k), xk);
5183  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5184  CalcVShape (ip, vshape);
5185  // vk = J tk
5186  vk[0] = J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2];
5187  vk[1] = J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2];
5188  vk[2] = J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2];
5189  for (j = 0; j < 6; j++)
5190  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5191  vshape(j,2)*vk[2])) < 1.0e-12)
5192  {
5193  I(k,j) = 0.0;
5194  }
5195  }
5196 }
5197 
5200  Vector &dofs) const
5201 {
5202  double vk[3];
5203  Vector xk (vk, 3);
5204 
5205  for (int k = 0; k < 6; k++)
5206  {
5207  Trans.SetIntPoint (&Nodes.IntPoint (k));
5208  const DenseMatrix &J = Trans.Jacobian();
5209 
5210  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5211  // xk^t J tk
5212  dofs(k) =
5213  vk[0] * ( J(0,0)*tk[k][0]+J(0,1)*tk[k][1]+J(0,2)*tk[k][2] ) +
5214  vk[1] * ( J(1,0)*tk[k][0]+J(1,1)*tk[k][1]+J(1,2)*tk[k][2] ) +
5215  vk[2] * ( J(2,0)*tk[k][0]+J(2,1)*tk[k][1]+J(2,2)*tk[k][2] );
5216  }
5217 }
5218 
5220  : VectorFiniteElement(3, Geometry::CUBE, 6, 1, H_DIV, FunctionSpace::Qk)
5221 {
5222  // not real nodes ...
5223  // z = 0, y = 0, x = 1, y = 1, x = 0, z = 1
5224  Nodes.IntPoint(0).x = 0.5;
5225  Nodes.IntPoint(0).y = 0.5;
5226  Nodes.IntPoint(0).z = 0.0;
5227 
5228  Nodes.IntPoint(1).x = 0.5;
5229  Nodes.IntPoint(1).y = 0.0;
5230  Nodes.IntPoint(1).z = 0.5;
5231 
5232  Nodes.IntPoint(2).x = 1.0;
5233  Nodes.IntPoint(2).y = 0.5;
5234  Nodes.IntPoint(2).z = 0.5;
5235 
5236  Nodes.IntPoint(3).x = 0.5;
5237  Nodes.IntPoint(3).y = 1.0;
5238  Nodes.IntPoint(3).z = 0.5;
5239 
5240  Nodes.IntPoint(4).x = 0.0;
5241  Nodes.IntPoint(4).y = 0.5;
5242  Nodes.IntPoint(4).z = 0.5;
5243 
5244  Nodes.IntPoint(5).x = 0.5;
5245  Nodes.IntPoint(5).y = 0.5;
5246  Nodes.IntPoint(5).z = 1.0;
5247 }
5248 
5250  DenseMatrix &shape) const
5251 {
5252  double x = ip.x, y = ip.y, z = ip.z;
5253  // z = 0
5254  shape(0,0) = 0.;
5255  shape(0,1) = 0.;
5256  shape(0,2) = z - 1.;
5257  // y = 0
5258  shape(1,0) = 0.;
5259  shape(1,1) = y - 1.;
5260  shape(1,2) = 0.;
5261  // x = 1
5262  shape(2,0) = x;
5263  shape(2,1) = 0.;
5264  shape(2,2) = 0.;
5265  // y = 1
5266  shape(3,0) = 0.;
5267  shape(3,1) = y;
5268  shape(3,2) = 0.;
5269  // x = 0
5270  shape(4,0) = x - 1.;
5271  shape(4,1) = 0.;
5272  shape(4,2) = 0.;
5273  // z = 1
5274  shape(5,0) = 0.;
5275  shape(5,1) = 0.;
5276  shape(5,2) = z;
5277 }
5278 
5280  Vector &divshape) const
5281 {
5282  divshape(0) = 1.;
5283  divshape(1) = 1.;
5284  divshape(2) = 1.;
5285  divshape(3) = 1.;
5286  divshape(4) = 1.;
5287  divshape(5) = 1.;
5288 }
5289 
5290 const double RT0HexFiniteElement::nk[6][3] =
5291 {{0,0,-1}, {0,-1,0}, {1,0,0}, {0,1,0}, {-1,0,0}, {0,0,1}};
5292 
5294  ElementTransformation &Trans, DenseMatrix &I) const
5295 {
5296  int k, j;
5297 #ifdef MFEM_THREAD_SAFE
5299  DenseMatrix Jinv(Dim);
5300 #endif
5301 
5302 #ifdef MFEM_DEBUG
5303  for (k = 0; k < 6; k++)
5304  {
5306  for (j = 0; j < 6; j++)
5307  {
5308  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5309  vshape(j,2)*nk[k][2] );
5310  if (j == k) { d -= 1.0; }
5311  if (fabs(d) > 1.0e-12)
5312  {
5313  cerr << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5314  " k = " << k << ", j = " << j << ", d = " << d << endl;
5315  mfem_error();
5316  }
5317  }
5318  }
5319 #endif
5320 
5321  IntegrationPoint ip;
5322  ip.x = ip.y = ip.z = 0.0;
5323  Trans.SetIntPoint (&ip);
5324  // Trans must be linear
5325  // set Jinv = |J| J^{-t} = adj(J)^t
5326  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5327  double vk[3];
5328  Vector xk (vk, 3);
5329 
5330  for (k = 0; k < 6; k++)
5331  {
5332  Trans.Transform (Nodes.IntPoint (k), xk);
5333  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5334  CalcVShape (ip, vshape);
5335  // vk = |J| J^{-t} nk
5336  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5337  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5338  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5339  for (j = 0; j < 6; j++)
5340  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5341  vshape(j,2)*vk[2])) < 1.0e-12)
5342  {
5343  I(k,j) = 0.0;
5344  }
5345  }
5346 }
5347 
5350  Vector &dofs) const
5351 {
5352  double vk[3];
5353  Vector xk (vk, 3);
5354 #ifdef MFEM_THREAD_SAFE
5355  DenseMatrix Jinv(Dim);
5356 #endif
5357 
5358  for (int k = 0; k < 6; k++)
5359  {
5360  Trans.SetIntPoint (&Nodes.IntPoint (k));
5361  // set Jinv = |J| J^{-t} = adj(J)^t
5362  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5363 
5364  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5365  // xk^t |J| J^{-t} nk
5366  dofs(k) =
5367  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5368  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5369  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5370  }
5371 }
5372 
5374  : VectorFiniteElement(3, Geometry::CUBE, 36, 2, H_DIV, FunctionSpace::Qk)
5375 {
5376  // z = 0
5377  Nodes.IntPoint(2).x = 1./3.;
5378  Nodes.IntPoint(2).y = 1./3.;
5379  Nodes.IntPoint(2).z = 0.0;
5380  Nodes.IntPoint(3).x = 2./3.;
5381  Nodes.IntPoint(3).y = 1./3.;
5382  Nodes.IntPoint(3).z = 0.0;
5383  Nodes.IntPoint(0).x = 1./3.;
5384  Nodes.IntPoint(0).y = 2./3.;
5385  Nodes.IntPoint(0).z = 0.0;
5386  Nodes.IntPoint(1).x = 2./3.;
5387  Nodes.IntPoint(1).y = 2./3.;
5388  Nodes.IntPoint(1).z = 0.0;
5389  // y = 0
5390  Nodes.IntPoint(4).x = 1./3.;
5391  Nodes.IntPoint(4).y = 0.0;
5392  Nodes.IntPoint(4).z = 1./3.;
5393  Nodes.IntPoint(5).x = 2./3.;
5394  Nodes.IntPoint(5).y = 0.0;
5395  Nodes.IntPoint(5).z = 1./3.;
5396  Nodes.IntPoint(6).x = 1./3.;
5397  Nodes.IntPoint(6).y = 0.0;
5398  Nodes.IntPoint(6).z = 2./3.;
5399  Nodes.IntPoint(7).x = 2./3.;
5400  Nodes.IntPoint(7).y = 0.0;
5401  Nodes.IntPoint(7).z = 2./3.;
5402  // x = 1
5403  Nodes.IntPoint(8).x = 1.0;
5404  Nodes.IntPoint(8).y = 1./3.;
5405  Nodes.IntPoint(8).z = 1./3.;
5406  Nodes.IntPoint(9).x = 1.0;
5407  Nodes.IntPoint(9).y = 2./3.;
5408  Nodes.IntPoint(9).z = 1./3.;
5409  Nodes.IntPoint(10).x = 1.0;
5410  Nodes.IntPoint(10).y = 1./3.;
5411  Nodes.IntPoint(10).z = 2./3.;
5412  Nodes.IntPoint(11).x = 1.0;
5413  Nodes.IntPoint(11).y = 2./3.;
5414  Nodes.IntPoint(11).z = 2./3.;
5415  // y = 1
5416  Nodes.IntPoint(13).x = 1./3.;
5417  Nodes.IntPoint(13).y = 1.0;
5418  Nodes.IntPoint(13).z = 1./3.;
5419  Nodes.IntPoint(12).x = 2./3.;
5420  Nodes.IntPoint(12).y = 1.0;
5421  Nodes.IntPoint(12).z = 1./3.;
5422  Nodes.IntPoint(15).x = 1./3.;
5423  Nodes.IntPoint(15).y = 1.0;
5424  Nodes.IntPoint(15).z = 2./3.;
5425  Nodes.IntPoint(14).x = 2./3.;
5426  Nodes.IntPoint(14).y = 1.0;
5427  Nodes.IntPoint(14).z = 2./3.;
5428  // x = 0
5429  Nodes.IntPoint(17).x = 0.0;
5430  Nodes.IntPoint(17).y = 1./3.;
5431  Nodes.IntPoint(17).z = 1./3.;
5432  Nodes.IntPoint(16).x = 0.0;
5433  Nodes.IntPoint(16).y = 2./3.;
5434  Nodes.IntPoint(16).z = 1./3.;
5435  Nodes.IntPoint(19).x = 0.0;
5436  Nodes.IntPoint(19).y = 1./3.;
5437  Nodes.IntPoint(19).z = 2./3.;
5438  Nodes.IntPoint(18).x = 0.0;
5439  Nodes.IntPoint(18).y = 2./3.;
5440  Nodes.IntPoint(18).z = 2./3.;
5441  // z = 1
5442  Nodes.IntPoint(20).x = 1./3.;
5443  Nodes.IntPoint(20).y = 1./3.;
5444  Nodes.IntPoint(20).z = 1.0;
5445  Nodes.IntPoint(21).x = 2./3.;
5446  Nodes.IntPoint(21).y = 1./3.;
5447  Nodes.IntPoint(21).z = 1.0;
5448  Nodes.IntPoint(22).x = 1./3.;
5449  Nodes.IntPoint(22).y = 2./3.;
5450  Nodes.IntPoint(22).z = 1.0;
5451  Nodes.IntPoint(23).x = 2./3.;
5452  Nodes.IntPoint(23).y = 2./3.;
5453  Nodes.IntPoint(23).z = 1.0;
5454  // x = 0.5 (interior)
5455  Nodes.IntPoint(24).x = 0.5;
5456  Nodes.IntPoint(24).y = 1./3.;
5457  Nodes.IntPoint(24).z = 1./3.;
5458  Nodes.IntPoint(25).x = 0.5;
5459  Nodes.IntPoint(25).y = 1./3.;
5460  Nodes.IntPoint(25).z = 2./3.;
5461  Nodes.IntPoint(26).x = 0.5;
5462  Nodes.IntPoint(26).y = 2./3.;
5463  Nodes.IntPoint(26).z = 1./3.;
5464  Nodes.IntPoint(27).x = 0.5;
5465  Nodes.IntPoint(27).y = 2./3.;
5466  Nodes.IntPoint(27).z = 2./3.;
5467  // y = 0.5 (interior)
5468  Nodes.IntPoint(28).x = 1./3.;
5469  Nodes.IntPoint(28).y = 0.5;
5470  Nodes.IntPoint(28).z = 1./3.;
5471  Nodes.IntPoint(29).x = 1./3.;
5472  Nodes.IntPoint(29).y = 0.5;
5473  Nodes.IntPoint(29).z = 2./3.;
5474  Nodes.IntPoint(30).x = 2./3.;
5475  Nodes.IntPoint(30).y = 0.5;
5476  Nodes.IntPoint(30).z = 1./3.;
5477  Nodes.IntPoint(31).x = 2./3.;
5478  Nodes.IntPoint(31).y = 0.5;
5479  Nodes.IntPoint(31).z = 2./3.;
5480  // z = 0.5 (interior)
5481  Nodes.IntPoint(32).x = 1./3.;
5482  Nodes.IntPoint(32).y = 1./3.;
5483  Nodes.IntPoint(32).z = 0.5;
5484  Nodes.IntPoint(33).x = 1./3.;
5485  Nodes.IntPoint(33).y = 2./3.;
5486  Nodes.IntPoint(33).z = 0.5;
5487  Nodes.IntPoint(34).x = 2./3.;
5488  Nodes.IntPoint(34).y = 1./3.;
5489  Nodes.IntPoint(34).z = 0.5;
5490  Nodes.IntPoint(35).x = 2./3.;
5491  Nodes.IntPoint(35).y = 2./3.;
5492  Nodes.IntPoint(35).z = 0.5;
5493 }
5494 
5496  DenseMatrix &shape) const
5497 {
5498  double x = ip.x, y = ip.y, z = ip.z;
5499  // z = 0
5500  shape(2,0) = 0.;
5501  shape(2,1) = 0.;
5502  shape(2,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5503  shape(3,0) = 0.;
5504  shape(3,1) = 0.;
5505  shape(3,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5506  shape(0,0) = 0.;
5507  shape(0,1) = 0.;
5508  shape(0,2) = -(1. - 3.*z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5509  shape(1,0) = 0.;
5510  shape(1,1) = 0.;
5511  shape(1,2) = -(1. - 3.*z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5512  // y = 0
5513  shape(4,0) = 0.;
5514  shape(4,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5515  shape(4,2) = 0.;
5516  shape(5,0) = 0.;
5517  shape(5,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5518  shape(5,2) = 0.;
5519  shape(6,0) = 0.;
5520  shape(6,1) = -(1. - 3.*y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5521  shape(6,2) = 0.;
5522  shape(7,0) = 0.;
5523  shape(7,1) = -(1. - 3.*y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5524  shape(7,2) = 0.;
5525  // x = 1
5526  shape(8,0) = (-x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5527  shape(8,1) = 0.;
5528  shape(8,2) = 0.;
5529  shape(9,0) = (-x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5530  shape(9,1) = 0.;
5531  shape(9,2) = 0.;
5532  shape(10,0) = (-x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5533  shape(10,1) = 0.;
5534  shape(10,2) = 0.;
5535  shape(11,0) = (-x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5536  shape(11,1) = 0.;
5537  shape(11,2) = 0.;
5538  // y = 1
5539  shape(13,0) = 0.;
5540  shape(13,1) = (-y + 2.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5541  shape(13,2) = 0.;
5542  shape(12,0) = 0.;
5543  shape(12,1) = (-y + 2.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5544  shape(12,2) = 0.;
5545  shape(15,0) = 0.;
5546  shape(15,1) = (-y + 2.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5547  shape(15,2) = 0.;
5548  shape(14,0) = 0.;
5549  shape(14,1) = (-y + 2.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5550  shape(14,2) = 0.;
5551  // x = 0
5552  shape(17,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5553  shape(17,1) = 0.;
5554  shape(17,2) = 0.;
5555  shape(16,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5556  shape(16,1) = 0.;
5557  shape(16,2) = 0.;
5558  shape(19,0) = -(1. - 3.*x + 2.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5559  shape(19,1) = 0.;
5560  shape(19,2) = 0.;
5561  shape(18,0) = -(1. - 3.*x + 2.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5562  shape(18,1) = 0.;
5563  shape(18,2) = 0.;
5564  // z = 1
5565  shape(20,0) = 0.;
5566  shape(20,1) = 0.;
5567  shape(20,2) = (-z + 2.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5568  shape(21,0) = 0.;
5569  shape(21,1) = 0.;
5570  shape(21,2) = (-z + 2.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5571  shape(22,0) = 0.;
5572  shape(22,1) = 0.;
5573  shape(22,2) = (-z + 2.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5574  shape(23,0) = 0.;
5575  shape(23,1) = 0.;
5576  shape(23,2) = (-z + 2.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5577  // x = 0.5 (interior)
5578  shape(24,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*( 2. - 3.*z);
5579  shape(24,1) = 0.;
5580  shape(24,2) = 0.;
5581  shape(25,0) = (4.*x - 4.*x*x)*( 2. - 3.*y)*(-1. + 3.*z);
5582  shape(25,1) = 0.;
5583  shape(25,2) = 0.;
5584  shape(26,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*( 2. - 3.*z);
5585  shape(26,1) = 0.;
5586  shape(26,2) = 0.;
5587  shape(27,0) = (4.*x - 4.*x*x)*(-1. + 3.*y)*(-1. + 3.*z);
5588  shape(27,1) = 0.;
5589  shape(27,2) = 0.;
5590  // y = 0.5 (interior)
5591  shape(28,0) = 0.;
5592  shape(28,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*( 2. - 3.*z);
5593  shape(28,2) = 0.;
5594  shape(29,0) = 0.;
5595  shape(29,1) = (4.*y - 4.*y*y)*( 2. - 3.*x)*(-1. + 3.*z);
5596  shape(29,2) = 0.;
5597  shape(30,0) = 0.;
5598  shape(30,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*( 2. - 3.*z);
5599  shape(30,2) = 0.;
5600  shape(31,0) = 0.;
5601  shape(31,1) = (4.*y - 4.*y*y)*(-1. + 3.*x)*(-1. + 3.*z);
5602  shape(31,2) = 0.;
5603  // z = 0.5 (interior)
5604  shape(32,0) = 0.;
5605  shape(32,1) = 0.;
5606  shape(32,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*( 2. - 3.*y);
5607  shape(33,0) = 0.;
5608  shape(33,1) = 0.;
5609  shape(33,2) = (4.*z - 4.*z*z)*( 2. - 3.*x)*(-1. + 3.*y);
5610  shape(34,0) = 0.;
5611  shape(34,1) = 0.;
5612  shape(34,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*( 2. - 3.*y);
5613  shape(35,0) = 0.;
5614  shape(35,1) = 0.;
5615  shape(35,2) = (4.*z - 4.*z*z)*(-1. + 3.*x)*(-1. + 3.*y);
5616 }
5617 
5619  Vector &divshape) const
5620 {
5621  double x = ip.x, y = ip.y, z = ip.z;
5622  // z = 0
5623  divshape(2) = -(-3. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5624  divshape(3) = -(-3. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5625  divshape(0) = -(-3. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5626  divshape(1) = -(-3. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5627  // y = 0
5628  divshape(4) = -(-3. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5629  divshape(5) = -(-3. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5630  divshape(6) = -(-3. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5631  divshape(7) = -(-3. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5632  // x = 1
5633  divshape(8) = (-1. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5634  divshape(9) = (-1. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5635  divshape(10) = (-1. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5636  divshape(11) = (-1. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5637  // y = 1
5638  divshape(13) = (-1. + 4.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5639  divshape(12) = (-1. + 4.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5640  divshape(15) = (-1. + 4.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5641  divshape(14) = (-1. + 4.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5642  // x = 0
5643  divshape(17) = -(-3. + 4.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5644  divshape(16) = -(-3. + 4.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5645  divshape(19) = -(-3. + 4.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5646  divshape(18) = -(-3. + 4.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5647  // z = 1
5648  divshape(20) = (-1. + 4.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5649  divshape(21) = (-1. + 4.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5650  divshape(22) = (-1. + 4.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5651  divshape(23) = (-1. + 4.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5652  // x = 0.5 (interior)
5653  divshape(24) = ( 4. - 8.*x)*( 2. - 3.*y)*( 2. - 3.*z);
5654  divshape(25) = ( 4. - 8.*x)*( 2. - 3.*y)*(-1. + 3.*z);
5655  divshape(26) = ( 4. - 8.*x)*(-1. + 3.*y)*( 2. - 3.*z);
5656  divshape(27) = ( 4. - 8.*x)*(-1. + 3.*y)*(-1. + 3.*z);
5657  // y = 0.5 (interior)
5658  divshape(28) = ( 4. - 8.*y)*( 2. - 3.*x)*( 2. - 3.*z);
5659  divshape(29) = ( 4. - 8.*y)*( 2. - 3.*x)*(-1. + 3.*z);
5660  divshape(30) = ( 4. - 8.*y)*(-1. + 3.*x)*( 2. - 3.*z);
5661  divshape(31) = ( 4. - 8.*y)*(-1. + 3.*x)*(-1. + 3.*z);
5662  // z = 0.5 (interior)
5663  divshape(32) = ( 4. - 8.*z)*( 2. - 3.*x)*( 2. - 3.*y);
5664  divshape(33) = ( 4. - 8.*z)*( 2. - 3.*x)*(-1. + 3.*y);
5665  divshape(34) = ( 4. - 8.*z)*(-1. + 3.*x)*( 2. - 3.*y);
5666  divshape(35) = ( 4. - 8.*z)*(-1. + 3.*x)*(-1. + 3.*y);
5667 }
5668 
5669 const double RT1HexFiniteElement::nk[36][3] =
5670 {
5671  {0, 0,-1}, {0, 0,-1}, {0, 0,-1}, {0, 0,-1},
5672  {0,-1, 0}, {0,-1, 0}, {0,-1, 0}, {0,-1, 0},
5673  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5674  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5675  {-1,0, 0}, {-1,0, 0}, {-1,0, 0}, {-1,0, 0},
5676  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1},
5677  {1, 0, 0}, {1, 0, 0}, {1, 0, 0}, {1, 0, 0},
5678  {0, 1, 0}, {0, 1, 0}, {0, 1, 0}, {0, 1, 0},
5679  {0, 0, 1}, {0, 0, 1}, {0, 0, 1}, {0, 0, 1}
5680 };
5681 
5683  ElementTransformation &Trans, DenseMatrix &I) const
5684 {
5685  int k, j;
5686 #ifdef MFEM_THREAD_SAFE
5688  DenseMatrix Jinv(Dim);
5689 #endif
5690 
5691 #ifdef MFEM_DEBUG
5692  for (k = 0; k < 36; k++)
5693  {
5695  for (j = 0; j < 36; j++)
5696  {
5697  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5698  vshape(j,2)*nk[k][2] );
5699  if (j == k) { d -= 1.0; }
5700  if (fabs(d) > 1.0e-12)
5701  {
5702  cerr << "RT0HexFiniteElement::GetLocalInterpolation (...)\n"
5703  " k = " << k << ", j = " << j << ", d = " << d << endl;
5704  mfem_error();
5705  }
5706  }
5707  }
5708 #endif
5709 
5710  IntegrationPoint ip;
5711  ip.x = ip.y = ip.z = 0.0;
5712  Trans.SetIntPoint (&ip);
5713  // Trans must be linear
5714  // set Jinv = |J| J^{-t} = adj(J)^t
5715  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5716  double vk[3];
5717  Vector xk (vk, 3);
5718 
5719  for (k = 0; k < 36; k++)
5720  {
5721  Trans.Transform (Nodes.IntPoint (k), xk);
5722  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5723  CalcVShape (ip, vshape);
5724  // vk = |J| J^{-t} nk
5725  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5726  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5727  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5728  for (j = 0; j < 36; j++)
5729  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5730  vshape(j,2)*vk[2])) < 1.0e-12)
5731  {
5732  I(k,j) = 0.0;
5733  }
5734  }
5735 }
5736 
5739  Vector &dofs) const
5740 {
5741  double vk[3];
5742  Vector xk (vk, 3);
5743 #ifdef MFEM_THREAD_SAFE
5744  DenseMatrix Jinv(Dim);
5745 #endif
5746 
5747  for (int k = 0; k < 36; k++)
5748  {
5749  Trans.SetIntPoint (&Nodes.IntPoint (k));
5750  // set Jinv = |J| J^{-t} = adj(J)^t
5751  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5752 
5753  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5754  // xk^t |J| J^{-t} nk
5755  dofs(k) =
5756  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5757  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5758  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5759  }
5760 }
5761 
5763  : VectorFiniteElement(3, Geometry::TETRAHEDRON, 4, 1, H_DIV)
5764 {
5765  // not real nodes ...
5766  Nodes.IntPoint(0).x = 0.33333333333333333333;
5767  Nodes.IntPoint(0).y = 0.33333333333333333333;
5768  Nodes.IntPoint(0).z = 0.33333333333333333333;
5769 
5770  Nodes.IntPoint(1).x = 0.0;
5771  Nodes.IntPoint(1).y = 0.33333333333333333333;
5772  Nodes.IntPoint(1).z = 0.33333333333333333333;
5773 
5774  Nodes.IntPoint(2).x = 0.33333333333333333333;
5775  Nodes.IntPoint(2).y = 0.0;
5776  Nodes.IntPoint(2).z = 0.33333333333333333333;
5777 
5778  Nodes.IntPoint(3).x = 0.33333333333333333333;
5779  Nodes.IntPoint(3).y = 0.33333333333333333333;
5780  Nodes.IntPoint(3).z = 0.0;
5781 }
5782 
5784  DenseMatrix &shape) const
5785 {
5786  double x2 = 2.0*ip.x, y2 = 2.0*ip.y, z2 = 2.0*ip.z;
5787 
5788  shape(0,0) = x2;
5789  shape(0,1) = y2;
5790  shape(0,2) = z2;
5791 
5792  shape(1,0) = x2 - 2.0;
5793  shape(1,1) = y2;
5794  shape(1,2) = z2;
5795 
5796  shape(2,0) = x2;
5797  shape(2,1) = y2 - 2.0;
5798  shape(2,2) = z2;
5799 
5800  shape(3,0) = x2;
5801  shape(3,1) = y2;
5802  shape(3,2) = z2 - 2.0;
5803 }
5804 
5806  Vector &divshape) const
5807 {
5808  divshape(0) = 6.0;
5809  divshape(1) = 6.0;
5810  divshape(2) = 6.0;
5811  divshape(3) = 6.0;
5812 }
5813 
5814 const double RT0TetFiniteElement::nk[4][3] =
5815 {{.5,.5,.5}, {-.5,0,0}, {0,-.5,0}, {0,0,-.5}};
5816 
5818  ElementTransformation &Trans, DenseMatrix &I) const
5819 {
5820  int k, j;
5821 #ifdef MFEM_THREAD_SAFE
5823  DenseMatrix Jinv(Dim);
5824 #endif
5825 
5826 #ifdef MFEM_DEBUG
5827  for (k = 0; k < 4; k++)
5828  {
5830  for (j = 0; j < 4; j++)
5831  {
5832  double d = ( vshape(j,0)*nk[k][0] + vshape(j,1)*nk[k][1] +
5833  vshape(j,2)*nk[k][2] );
5834  if (j == k) { d -= 1.0; }
5835  if (fabs(d) > 1.0e-12)
5836  {
5837  cerr << "RT0TetFiniteElement::GetLocalInterpolation (...)\n"
5838  " k = " << k << ", j = " << j << ", d = " << d << endl;
5839  mfem_error();
5840  }
5841  }
5842  }
5843 #endif
5844 
5845  IntegrationPoint ip;
5846  ip.x = ip.y = ip.z = 0.0;
5847  Trans.SetIntPoint (&ip);
5848  // Trans must be linear
5849  // set Jinv = |J| J^{-t} = adj(J)^t
5850  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5851  double vk[3];
5852  Vector xk (vk, 3);
5853 
5854  for (k = 0; k < 4; k++)
5855  {
5856  Trans.Transform (Nodes.IntPoint (k), xk);
5857  ip.x = vk[0]; ip.y = vk[1]; ip.z = vk[2];
5858  CalcVShape (ip, vshape);
5859  // vk = |J| J^{-t} nk
5860  vk[0] = Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2];
5861  vk[1] = Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2];
5862  vk[2] = Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2];
5863  for (j = 0; j < 4; j++)
5864  if (fabs (I(k,j) = (vshape(j,0)*vk[0]+vshape(j,1)*vk[1]+
5865  vshape(j,2)*vk[2])) < 1.0e-12)
5866  {
5867  I(k,j) = 0.0;
5868  }
5869  }
5870 }
5871 
5874  Vector &dofs) const
5875 {
5876  double vk[3];
5877  Vector xk (vk, 3);
5878 #ifdef MFEM_THREAD_SAFE
5879  DenseMatrix Jinv(Dim);
5880 #endif
5881 
5882  for (int k = 0; k < 4; k++)
5883  {
5884  Trans.SetIntPoint (&Nodes.IntPoint (k));
5885  // set Jinv = |J| J^{-t} = adj(J)^t
5886  CalcAdjugateTranspose (Trans.Jacobian(), Jinv);
5887 
5888  vc.Eval (xk, Trans, Nodes.IntPoint (k));
5889  // xk^t |J| J^{-t} nk
5890  dofs(k) =
5891  vk[0] * ( Jinv(0,0)*nk[k][0]+Jinv(0,1)*nk[k][1]+Jinv(0,2)*nk[k][2] ) +
5892  vk[1] * ( Jinv(1,0)*nk[k][0]+Jinv(1,1)*nk[k][1]+Jinv(1,2)*nk[k][2] ) +
5893  vk[2] * ( Jinv(2,0)*nk[k][0]+Jinv(2,1)*nk[k][1]+Jinv(2,2)*nk[k][2] );
5894  }
5895 }
5896 
5898  : NodalFiniteElement(3, Geometry::CUBE, 6, 2, FunctionSpace::Qk)
5899 {
5900  Nodes.IntPoint(0).x = 0.5;
5901  Nodes.IntPoint(0).y = 0.5;
5902  Nodes.IntPoint(0).z = 0.0;
5903 
5904  Nodes.IntPoint(1).x = 0.5;
5905  Nodes.IntPoint(1).y = 0.0;
5906  Nodes.IntPoint(1).z = 0.5;
5907 
5908  Nodes.IntPoint(2).x = 1.0;
5909  Nodes.IntPoint(2).y = 0.5;
5910  Nodes.IntPoint(2).z = 0.5;
5911 
5912  Nodes.IntPoint(3).x = 0.5;
5913  Nodes.IntPoint(3).y = 1.0;
5914  Nodes.IntPoint(3).z = 0.5;
5915 
5916  Nodes.IntPoint(4).x = 0.0;
5917  Nodes.IntPoint(4).y = 0.5;
5918  Nodes.IntPoint(4).z = 0.5;
5919 
5920  Nodes.IntPoint(5).x = 0.5;
5921  Nodes.IntPoint(5).y = 0.5;
5922  Nodes.IntPoint(5).z = 1.0;
5923 }
5924 
5926  Vector &shape) const
5927 {
5928  double x = 2. * ip.x - 1.;
5929  double y = 2. * ip.y - 1.;
5930  double z = 2. * ip.z - 1.;
5931  double f5 = x * x - y * y;
5932  double f6 = y * y - z * z;
5933 
5934  shape(0) = (1./6.) * (1. - 3. * z - f5 - 2. * f6);
5935  shape(1) = (1./6.) * (1. - 3. * y - f5 + f6);
5936  shape(2) = (1./6.) * (1. + 3. * x + 2. * f5 + f6);
5937  shape(3) = (1./6.) * (1. + 3. * y - f5 + f6);
5938  shape(4) = (1./6.) * (1. - 3. * x + 2. * f5 + f6);
5939  shape(5) = (1./6.) * (1. + 3. * z - f5 - 2. * f6);
5940 }
5941 
5943  DenseMatrix &dshape) const
5944 {
5945  const double a = 2./3.;
5946 
5947  double xt = a * (1. - 2. * ip.x);
5948  double yt = a * (1. - 2. * ip.y);
5949  double zt = a * (1. - 2. * ip.z);
5950 
5951  dshape(0,0) = xt;
5952  dshape(0,1) = yt;
5953  dshape(0,2) = -1. - 2. * zt;
5954 
5955  dshape(1,0) = xt;
5956  dshape(1,1) = -1. - 2. * yt;
5957  dshape(1,2) = zt;
5958 
5959  dshape(2,0) = 1. - 2. * xt;
5960  dshape(2,1) = yt;
5961  dshape(2,2) = zt;
5962 
5963  dshape(3,0) = xt;
5964  dshape(3,1) = 1. - 2. * yt;
5965  dshape(3,2) = zt;
5966 
5967  dshape(4,0) = -1. - 2. * xt;
5968  dshape(4,1) = yt;
5969  dshape(4,2) = zt;
5970 
5971  dshape(5,0) = xt;
5972  dshape(5,1) = yt;
5973  dshape(5,2) = 1. - 2. * zt;
5974 }
5975 
5976 
5977 Poly_1D::Basis::Basis(const int p, const double *nodes, int _mode)
5978  : x(p + 1), w(p + 1)
5979 {
5980  mode = _mode;
5981  if (mode == 0)
5982  {
5983  DenseMatrix A(p + 1);
5984  for (int i = 0; i <= p; i++)
5985  {
5986  CalcBasis(p, nodes[i], x);
5987  for (int j = 0; j <= p; j++)
5988  {
5989  A(j, i) = x(j);
5990  }
5991  }
5992 
5993  Ai.Factor(A);
5994  // cout << "Poly_1D::Basis(" << p << ",...) : "; Ai.TestInversion();
5995  }
5996  else
5997  {
5998  x = nodes;
5999  w = 1.0;
6000  for (int i = 0; i <= p; i++)
6001  for (int j = 0; j < i; j++)
6002  {
6003  double xij = x(i) - x(j);
6004  w(i) *= xij;
6005  w(j) *= -xij;
6006  }
6007  for (int i = 0; i <= p; i++)
6008  {
6009  w(i) = 1.0/w(i);
6010  }
6011 
6012 #ifdef MFEM_DEBUG
6013  // Make sure the nodes are increasing
6014  for (int i = 0; i < p; i++)
6015  if (x(i) >= x(i+1))
6016  {
6017  mfem_error("Poly_1D::Basis::Basis : nodes are not increasing!");
6018  }
6019 #endif
6020  }
6021 }
6022 
6023 void Poly_1D::Basis::Eval(const double y, Vector &u) const
6024 {
6025  if (mode == 0)
6026  {
6027  CalcBasis(Ai.Width() - 1, y, x);
6028  Ai.Mult(x, u);
6029  }
6030  else
6031  {
6032  int i, k, p = x.Size() - 1;
6033  double l, lk;
6034 
6035  if (p == 0)
6036  {
6037  u(0) = 1.0;
6038  return;
6039  }
6040 
6041  lk = 1.0;
6042  for (k = 0; k < p; k++)
6043  if (y >= (x(k) + x(k+1))/2)
6044  {
6045  lk *= y - x(k);
6046  }
6047  else
6048  {
6049  for (i = k+1; i <= p; i++)
6050  {
6051  lk *= y - x(i);
6052  }
6053  break;
6054  }
6055  l = lk * (y - x(k));
6056 
6057  for (i = 0; i < k; i++)
6058  {
6059  u(i) = l * w(i) / (y - x(i));
6060  }
6061  u(k) = lk * w(k);
6062  for (i++; i <= p; i++)
6063  {
6064  u(i) = l * w(i) / (y - x(i));
6065  }
6066  }
6067 }
6068 
6069 void Poly_1D::Basis::Eval(const double y, Vector &u, Vector &d) const
6070 {
6071  if (mode == 0)
6072  {
6073  CalcBasis(Ai.Width() - 1, y, x, w);
6074  Ai.Mult(x, u);
6075  Ai.Mult(w, d);
6076  }
6077  else
6078  {
6079  int i, k, p = x.Size() - 1;
6080  double l, lp, lk, sk, si;
6081 
6082  if (p == 0)
6083  {
6084  u(0) = 1.0;
6085  d(0) = 0.0;
6086  return;
6087  }
6088 
6089  lk = 1.0;
6090  for (k = 0; k < p; k++)
6091  if (y >= (x(k) + x(k+1))/2)
6092  {
6093  lk *= y - x(k);
6094  }
6095  else
6096  {
6097  for (i = k+1; i <= p; i++)
6098  {
6099  lk *= y - x(i);
6100  }
6101  break;
6102  }
6103  l = lk * (y - x(k));
6104 
6105  sk = 0.0;
6106  for (i = 0; i < k; i++)
6107  {
6108  si = 1.0/(y - x(i));
6109  sk += si;
6110  u(i) = l * si * w(i);
6111  }
6112  u(k) = lk * w(k);
6113  for (i++; i <= p; i++)
6114  {
6115  si = 1.0/(y - x(i));
6116  sk += si;
6117  u(i) = l * si * w(i);
6118  }
6119  lp = l * sk + lk;
6120 
6121  for (i = 0; i < k; i++)
6122  {
6123  d(i) = (lp * w(i) - u(i))/(y - x(i));
6124  }
6125  d(k) = sk * u(k);
6126  for (i++; i <= p; i++)
6127  {
6128  d(i) = (lp * w(i) - u(i))/(y - x(i));
6129  }
6130  }
6131 }
6132 
6133 const int *Poly_1D::Binom(const int p)
6134 {
6135  if (binom.NumCols() <= p)
6136  {
6137  binom.SetSize(p + 1, p + 1);
6138  for (int i = 0; i <= p; i++)
6139  {
6140  binom(i,0) = binom(i,i) = 1;
6141  for (int j = 1; j < i; j++)
6142  {
6143  binom(i,j) = binom(i-1,j) + binom(i-1,j-1);
6144  }
6145  }
6146  }
6147  return binom[p];
6148 }
6149 
6150 void Poly_1D::UniformPoints(const int p, double *x)
6151 {
6152  if (p == 0)
6153  {
6154  x[0] = 0.5;
6155  }
6156  else
6157  {
6158  for (int i = 0; i <= p; i++)
6159  {
6160  x[i] = double(i)/p;
6161  }
6162  }
6163 }
6164 
6165 void Poly_1D::GaussPoints(const int p, double *x)
6166 {
6167  int m = (p+1)/2, odd_p = p%2;
6168 
6169  if (!odd_p)
6170  {
6171  x[m] = 0.5;
6172  }
6173 
6174  for (int i = 0; i < m; i++)
6175  {
6176  double z, y, p0, d0;
6177  z = cos(M_PI*(i + 0.75)/(p + 1.5));
6178 
6179  for (int k = 0; true; )
6180  {
6181  // compute p0, d0 -- P_{p+1}(z), P'_{p+1}(z) using
6182  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6183  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
6184  {
6185  double p1, p2;
6186  p2 = 1.;
6187  p1 = z;
6188  d0 = 1 - odd_p;
6189  for (int n = 1; true; n++)
6190  {
6191  p0 = ((2*n+1)*z*p1 - n*p2)/(n + 1);
6192  if (n%2 == odd_p)
6193  {
6194  d0 += (2*n+1)*p1;
6195  }
6196  if (n == p) { break; }
6197  p2 = p1;
6198  p1 = p0;
6199  }
6200  // d0 = (p + 1)*(z*p0 - p1)/(z*z - 1); // alternative formula
6201  }
6202 
6203  if (fabs(p0/d0) < 2e-16) { break; }
6204 
6205  if (++k == 5)
6206  {
6207  std::cout << "Poly_1D::GaussPoints : No convergence!"
6208  " p = " << p << ", i = " << i << ", p0/d0 = " << p0/d0
6209  << std::endl;
6210  break;
6211  }
6212 
6213  z = z - p0/d0;
6214  }
6215 
6216  // z = z - p0/d0; y = (1 - z)/2; // bad roundoff !!!
6217  y = ((1 - z) + p0/d0)/2;
6218 
6219  x[i] = y;
6220  x[p-i] = 1 - y;
6221  // the weight is: 1./(4*y*(1 - y)*d0*d0)
6222  }
6223 }
6224 
6225 void Poly_1D::GaussLobattoPoints(const int p, double *x)
6226 {
6227  if (p == 0)
6228  {
6229  x[0] = 0.5;
6230  }
6231  else
6232  {
6233  x[0] = 0.;
6234  x[p] = 1.;
6235  if (p == 1) { return; }
6236 
6237  // x[1],...,x[p-1] are the (shifted) roots of P'_p
6238  int m = (p - 1)/2, odd_p = p%2;
6239 
6240  if (!odd_p)
6241  {
6242  x[m+1] = 0.5;
6243  }
6244  for (int i = 0; i < m; )
6245  {
6246  double y, z, d0, s0;
6247  z = cos(M_PI*(i + 1)/p);
6248 
6249  for (int k = 0; true; )
6250  {
6251  // compute d0, s0 -- P'_p(z), P"_p(z)
6252  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6253  // P'_{n+1}(z) = (2*n+1)* P_n(z)+P'_{n-1}(z)
6254  // P"_{n+1}(z) = (2*n+1)*P'_n(z)+P"_{n-1}(z)
6255  {
6256  double p0, p1, p2, d1;
6257  p2 = 1.;
6258  p1 = z;
6259  d0 = odd_p;
6260  d1 = 1 - odd_p;
6261  s0 = 0;
6262  for (int n = 1; true; n++)
6263  {
6264  p0 = ((2*n+1)*z*p1 - n*p2)/(n + 1);
6265  if (n%2 != odd_p)
6266  {
6267  d0 += (2*n+1)*p1;
6268  s0 += (2*n+1)*d1;
6269  }
6270  else
6271  {
6272  d1 += (2*n+1)*p1;
6273  }
6274  if (n == p - 1) { break; }
6275  p2 = p1;
6276  p1 = p0;
6277  }
6278  }
6279 
6280  if (fabs(d0/s0) < 2e-16) { break; }
6281 
6282  if (++k == 6)
6283  {
6284  std::cout << "Poly_1D::GaussLobattoPoints : No convergence!"
6285  " p = " << p << ", i = " << i << ", d0/s0 = " << d0/s0
6286  << std::endl;
6287  break;
6288  }
6289 
6290  z = z - d0/s0;
6291  }
6292 
6293  y = ((1 - z) + d0/s0)/2;
6294 
6295  x[++i] = y;
6296  x[p-i] = 1 - y;
6297  }
6298  }
6299 }
6300 
6301 void Poly_1D::ChebyshevPoints(const int p, double *x)
6302 {
6303  for (int i = 0; i <= p; i++)
6304  {
6305  // x[i] = 0.5*(1. + cos(M_PI*(p - i + 0.5)/(p + 1)));
6306  double s = sin(M_PI_2*(i + 0.5)/(p + 1));
6307  x[i] = s*s;
6308  }
6309 }
6310 
6311 void Poly_1D::CalcMono(const int p, const double x, double *u)
6312 {
6313  double xn;
6314  u[0] = xn = 1.;
6315  for (int n = 1; n <= p; n++)
6316  {
6317  u[n] = (xn *= x);
6318  }
6319 }
6320 
6321 void Poly_1D::CalcMono(const int p, const double x, double *u, double *d)
6322 {
6323  double xn;
6324  u[0] = xn = 1.;
6325  d[0] = 0.;
6326  for (int n = 1; n <= p; n++)
6327  {
6328  d[n] = n * xn;
6329  u[n] = (xn *= x);
6330  }
6331 }
6332 
6333 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6334  double *u)
6335 {
6336  if (p == 0)
6337  {
6338  u[0] = 1.;
6339  }
6340  else
6341  {
6342  int i;
6343  const int *b = Binom(p);
6344  double z = x;
6345 
6346  for (i = 1; i < p; i++)
6347  {
6348  u[i] = b[i]*z;
6349  z *= x;
6350  }
6351  u[p] = z;
6352  z = y;
6353  for (i--; i > 0; i--)
6354  {
6355  u[i] *= z;
6356  z *= y;
6357  }
6358  u[0] = z;
6359  }
6360 }
6361 
6362 void Poly_1D::CalcBinomTerms(const int p, const double x, const double y,
6363  double *u, double *d)
6364 {
6365  if (p == 0)
6366  {
6367  u[0] = 1.;
6368  d[0] = 0.;
6369  }
6370  else
6371  {
6372  int i;
6373  const int *b = Binom(p);
6374  const double xpy = x + y, ptx = p*x;
6375  double z = 1.;
6376 
6377  for (i = 1; i < p; i++)
6378  {
6379  d[i] = b[i]*z*(i*xpy - ptx);
6380  z *= x;
6381  u[i] = b[i]*z;
6382  }
6383  d[p] = p*z;
6384  u[p] = z*x;
6385  z = 1.;
6386  for (i--; i > 0; i--)
6387  {
6388  d[i] *= z;
6389  z *= y;
6390  u[i] *= z;
6391  }
6392  d[0] = -p*z;
6393  u[0] = z*y;
6394  }
6395 }
6396 
6397 void Poly_1D::CalcDBinomTerms(const int p, const double x, const double y,
6398  double *d)
6399 {
6400  if (p == 0)
6401  {
6402  d[0] = 0.;
6403  }
6404  else
6405  {
6406  int i;
6407  const int *b = Binom(p);
6408  const double xpy = x + y, ptx = p*x;
6409  double z = 1.;
6410 
6411  for (i = 1; i < p; i++)
6412  {
6413  d[i] = b[i]*z*(i*xpy - ptx);
6414  z *= x;
6415  }
6416  d[p] = p*z;
6417  z = 1.;
6418  for (i--; i > 0; i--)
6419  {
6420  d[i] *= z;
6421  z *= y;
6422  }
6423  d[0] = -p*z;
6424  }
6425 }
6426 
6427 void Poly_1D::CalcLegendre(const int p, const double x, double *u)
6428 {
6429  // use the recursive definition for [-1,1]:
6430  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6431  double z;
6432  u[0] = 1.;
6433  if (p == 0) { return; }
6434  u[1] = z = 2.*x - 1.;
6435  for (int n = 1; n < p; n++)
6436  {
6437  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6438  }
6439 }
6440 
6441 void Poly_1D::CalcLegendre(const int p, const double x, double *u, double *d)
6442 {
6443  // use the recursive definition for [-1,1]:
6444  // (n+1)*P_{n+1}(z) = (2*n+1)*z*P_n(z)-n*P_{n-1}(z)
6445  // for the derivative use, z in [-1,1]:
6446  // P'_{n+1}(z) = (2*n+1)*P_n(z)+P'_{n-1}(z)
6447  double z;
6448  u[0] = 1.;
6449  d[0] = 0.;
6450  if (p == 0) { return; }
6451  u[1] = z = 2.*x - 1.;
6452  d[1] = 2.;
6453  for (int n = 1; n < p; n++)
6454  {
6455  u[n+1] = ((2*n + 1)*z*u[n] - n*u[n-1])/(n + 1);
6456  d[n+1] = (4*n + 2)*u[n] + d[n-1];
6457  }
6458 }
6459 
6460 void Poly_1D::CalcChebyshev(const int p, const double x, double *u)
6461 {
6462  // recursive definition, z in [-1,1]
6463  // T_0(z) = 1, T_1(z) = z
6464  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6465  double z;
6466  u[0] = 1.;
6467  if (p == 0) { return; }
6468  u[1] = z = 2.*x - 1.;
6469  for (int n = 1; n < p; n++)
6470  {
6471  u[n+1] = 2*z*u[n] - u[n-1];
6472  }
6473 }
6474 
6475 void Poly_1D::CalcChebyshev(const int p, const double x, double *u, double *d)
6476 {
6477  // recursive definition, z in [-1,1]
6478  // T_0(z) = 1, T_1(z) = z
6479  // T_{n+1}(z) = 2*z*T_n(z) - T_{n-1}(z)
6480  // T'_n(z) = n*U_{n-1}(z)
6481  // U_0(z) = 1 U_1(z) = 2*z
6482  // U_{n+1}(z) = 2*z*U_n(z) - U_{n-1}(z)
6483  // U_n(z) = z*U_{n-1}(z) + T_n(z) = z*T'_n(z)/n + T_n(z)
6484  // T'_{n+1}(z) = (n + 1)*(z*T'_n(z)/n + T_n(z))
6485  double z;
6486  u[0] = 1.;
6487  d[0] = 0.;
6488  if (p == 0) { return; }
6489  u[1] = z = 2.*x - 1.;
6490  d[1] = 2.;
6491  for (int n = 1; n < p; n++)
6492  {
6493  u[n+1] = 2*z*u[n] - u[n-1];
6494  d[n+1] = (n + 1)*(z*d[n]/n + 2*u[n]);
6495  }
6496 }
6497 
6498 const double *Poly_1D::OpenPoints(const int p)
6499 {
6500  double *op;
6501 
6502  if (open_pts.Size() <= p)
6503  {
6504  int i = open_pts.Size();
6505  open_pts.SetSize(p + 1);
6506  for ( ; i < p; i++)
6507  {
6508  open_pts[i] = NULL;
6509  }
6510  goto alloc_open;
6511  }
6512  if ((op = open_pts[p]) != NULL)
6513  {
6514  return op;
6515  }
6516 alloc_open:
6517  open_pts[p] = op = new double[p + 1];
6518  GaussPoints(p, op);
6519  // ChebyshevPoints(p, op);
6520  return op;
6521 }
6522 
6523 const double *Poly_1D::ClosedPoints(const int p)
6524 {
6525  double *cp;
6526 
6527  if (closed_pts.Size() <= p)
6528  {
6529  int i = closed_pts.Size();
6530  closed_pts.SetSize(p + 1);
6531  for ( ; i < p; i++)
6532  {
6533  closed_pts[i] = NULL;
6534  }
6535  goto alloc_closed;
6536  }
6537  if ((cp = closed_pts[p]) != NULL)
6538  {
6539  return cp;
6540  }
6541 alloc_closed:
6542  closed_pts[p] = cp = new double[p + 1];
6543  GaussLobattoPoints(p, cp);
6544  // UniformPoints(p, cp);
6545  return cp;
6546 }
6547 
6549 {
6550  Basis *ob;
6551 
6552  if (open_basis.Size() <= p)
6553  {
6554  int i = open_basis.Size();
6555  open_basis.SetSize(p + 1);
6556  for ( ; i < p; i++)
6557  {
6558  open_basis[i] = NULL;
6559  }
6560  goto alloc_obasis;
6561  }
6562  if ((ob = open_basis[p]) != NULL)
6563  {
6564  return *ob;
6565  }
6566 alloc_obasis:
6567  open_basis[p] = ob = new Basis(p, OpenPoints(p));
6568  return *ob;
6569 }
6570 
6572 {
6573  Basis *cb;
6574 
6575  if (closed_basis.Size() <= p)
6576  {
6577  int i = closed_basis.Size();
6578  closed_basis.SetSize(p + 1);
6579  for ( ; i < p; i++)
6580  {
6581  closed_basis[i] = NULL;
6582  }
6583  goto alloc_cbasis;
6584  }
6585  if ((cb = closed_basis[p]) != NULL)
6586  {
6587  return *cb;
6588  }
6589 alloc_cbasis:
6590  closed_basis[p] = cb = new Basis(p, ClosedPoints(p));
6591  return *cb;
6592 }
6593 
6595 {
6596  for (int i = 0; i < open_pts.Size(); i++)
6597  {
6598  delete [] open_pts[i];
6599  }
6600  for (int i = 0; i < closed_pts.Size(); i++)
6601  {
6602  delete [] closed_pts[i];
6603  }
6604  for (int i = 0; i < open_basis.Size(); i++)
6605  {
6606  delete open_basis[i];
6607  }
6608  for (int i = 0; i < closed_basis.Size(); i++)
6609  {
6610  delete closed_basis[i];
6611  }
6612 }
6613 
6615 Array2D<int> Poly_1D::binom;
6616 
6617 
6619  : NodalFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk),
6620  basis1d(poly1d.ClosedBasis(p))
6621 {
6622  const double *cp = poly1d.ClosedPoints(p);
6623 
6624 #ifndef MFEM_THREAD_SAFE
6625  shape_x.SetSize(p+1);
6626  dshape_x.SetSize(p+1);
6627 #endif
6628 
6629  Nodes.IntPoint(0).x = cp[0];
6630  Nodes.IntPoint(1).x = cp[p];
6631  for (int i = 1; i < p; i++)
6632  {
6633  Nodes.IntPoint(i+1).x = cp[i];
6634  }
6635 }
6636 
6638  Vector &shape) const
6639 {
6640  const int p = Order;
6641 
6642 #ifdef MFEM_THREAD_SAFE
6643  Vector shape_x(p+1);
6644 #endif
6645 
6646  basis1d.Eval(ip.x, shape_x);
6647 
6648  shape(0) = shape_x(0);
6649  shape(1) = shape_x(p);
6650  for (int i = 1; i < p; i++)
6651  {
6652  shape(i+1) = shape_x(i);
6653  }
6654 }
6655 
6657  DenseMatrix &dshape) const
6658 {
6659  const int p = Order;
6660 
6661 #ifdef MFEM_THREAD_SAFE
6662  Vector shape_x(p+1), dshape_x(p+1);
6663 #endif
6664 
6665  basis1d.Eval(ip.x, shape_x, dshape_x);
6666 
6667  dshape(0,0) = dshape_x(0);
6668  dshape(1,0) = dshape_x(p);
6669  for (int i = 1; i < p; i++)
6670  {
6671  dshape(i+1,0) = dshape_x(i);
6672  }
6673 }
6674 
6675 void H1_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
6676 {
6677  const int p = Order;
6678  const double *cp = poly1d.ClosedPoints(p);
6679 
6680  switch (vertex)
6681  {
6682  case 0:
6683  dofs(0) = poly1d.CalcDelta(p, (1.0 - cp[0]));
6684  dofs(1) = poly1d.CalcDelta(p, (1.0 - cp[p]));
6685  for (int i = 1; i < p; i++)
6686  {
6687  dofs(i+1) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6688  }
6689  break;
6690 
6691  case 1:
6692  dofs(0) = poly1d.CalcDelta(p, cp[0]);
6693  dofs(1) = poly1d.CalcDelta(p, cp[p]);
6694  for (int i = 1; i < p; i++)
6695  {
6696  dofs(i+1) = poly1d.CalcDelta(p, cp[i]);
6697  }
6698  break;
6699  }
6700 }
6701 
6702 
6704  : NodalFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
6705  FunctionSpace::Qk),
6706  basis1d(poly1d.ClosedBasis(p)), dof_map((p + 1)*(p + 1))
6707 {
6708  const double *cp = poly1d.ClosedPoints(p);
6709 
6710  const int p1 = p + 1;
6711 
6712 #ifndef MFEM_THREAD_SAFE
6713  shape_x.SetSize(p1);
6714  shape_y.SetSize(p1);
6715  dshape_x.SetSize(p1);
6716  dshape_y.SetSize(p1);
6717 #endif
6718 
6719  // vertices
6720  dof_map[0 + 0*p1] = 0;
6721  dof_map[p + 0*p1] = 1;
6722  dof_map[p + p*p1] = 2;
6723  dof_map[0 + p*p1] = 3;
6724 
6725  // edges
6726  int o = 4;
6727  for (int i = 1; i < p; i++)
6728  {
6729  dof_map[i + 0*p1] = o++;
6730  }
6731  for (int i = 1; i < p; i++)
6732  {
6733  dof_map[p + i*p1] = o++;
6734  }
6735  for (int i = 1; i < p; i++)
6736  {
6737  dof_map[(p-i) + p*p1] = o++;
6738  }
6739  for (int i = 1; i < p; i++)
6740  {
6741  dof_map[0 + (p-i)*p1] = o++;
6742  }
6743 
6744  // interior
6745  for (int j = 1; j < p; j++)
6746  for (int i = 1; i < p; i++)
6747  {
6748  dof_map[i + j*p1] = o++;
6749  }
6750 
6751  o = 0;
6752  for (int j = 0; j <= p; j++)
6753  for (int i = 0; i <= p; i++)
6754  {
6755  Nodes.IntPoint(dof_map[o++]).Set2(cp[i], cp[j]);
6756  }
6757 }
6758 
6760  Vector &shape) const
6761 {
6762  const int p = Order;
6763 
6764 #ifdef MFEM_THREAD_SAFE
6765  Vector shape_x(p+1), shape_y(p+1);
6766 #endif
6767 
6768  basis1d.Eval(ip.x, shape_x);
6769  basis1d.Eval(ip.y, shape_y);
6770 
6771  for (int o = 0, j = 0; j <= p; j++)
6772  for (int i = 0; i <= p; i++)
6773  {
6774  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
6775  }
6776 }
6777 
6779  DenseMatrix &dshape) const
6780 {
6781  const int p = Order;
6782 
6783 #ifdef MFEM_THREAD_SAFE
6784  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
6785 #endif
6786 
6787  basis1d.Eval(ip.x, shape_x, dshape_x);
6788  basis1d.Eval(ip.y, shape_y, dshape_y);
6789 
6790  for (int o = 0, j = 0; j <= p; j++)
6791  for (int i = 0; i <= p; i++)
6792  {
6793  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
6794  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
6795  }
6796 }
6797 
6798 void H1_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
6799 {
6800  const int p = Order;
6801  const double *cp = poly1d.ClosedPoints(p);
6802 
6803 #ifdef MFEM_THREAD_SAFE
6804  Vector shape_x(p+1), shape_y(p+1);
6805 #endif
6806 
6807  for (int i = 0; i <= p; i++)
6808  {
6809  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
6810  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
6811  }
6812 
6813  switch (vertex)
6814  {
6815  case 0:
6816  for (int o = 0, j = 0; j <= p; j++)
6817  for (int i = 0; i <= p; i++)
6818  {
6819  dofs(dof_map[o++]) = shape_x(i)*shape_x(j);
6820  }
6821  break;
6822  case 1:
6823  for (int o = 0, j = 0; j <= p; j++)
6824  for (int i = 0; i <= p; i++)
6825  {
6826  dofs(dof_map[o++]) = shape_y(i)*shape_x(j);
6827  }
6828  break;
6829  case 2:
6830  for (int o = 0, j = 0; j <= p; j++)
6831  for (int i = 0; i <= p; i++)
6832  {
6833  dofs(dof_map[o++]) = shape_y(i)*shape_y(j);
6834  }
6835  break;
6836  case 3:
6837  for (int o = 0, j = 0; j <= p; j++)
6838  for (int i = 0; i <= p; i++)
6839  {
6840  dofs(dof_map[o++]) = shape_x(i)*shape_y(j);
6841  }
6842  break;
6843  }
6844 }
6845 
6846 
6848  : NodalFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
6849  FunctionSpace::Qk),
6850  basis1d(poly1d.ClosedBasis(p)), dof_map((p + 1)*(p + 1)*(p + 1))
6851 {
6852  const double *cp = poly1d.ClosedPoints(p);
6853 
6854  const int p1 = p + 1;
6855 
6856 #ifndef MFEM_THREAD_SAFE
6857  shape_x.SetSize(p1);
6858  shape_y.SetSize(p1);
6859  shape_z.SetSize(p1);
6860  dshape_x.SetSize(p1);
6861  dshape_y.SetSize(p1);
6862  dshape_z.SetSize(p1);
6863 #endif
6864 
6865  // vertices
6866  dof_map[0 + (0 + 0*p1)*p1] = 0;
6867  dof_map[p + (0 + 0*p1)*p1] = 1;
6868  dof_map[p + (p + 0*p1)*p1] = 2;
6869  dof_map[0 + (p + 0*p1)*p1] = 3;
6870  dof_map[0 + (0 + p*p1)*p1] = 4;
6871  dof_map[p + (0 + p*p1)*p1] = 5;
6872  dof_map[p + (p + p*p1)*p1] = 6;
6873  dof_map[0 + (p + p*p1)*p1] = 7;
6874 
6875  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
6876  int o = 8;
6877  for (int i = 1; i < p; i++)
6878  {
6879  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
6880  }
6881  for (int i = 1; i < p; i++)
6882  {
6883  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
6884  }
6885  for (int i = 1; i < p; i++)
6886  {
6887  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
6888  }
6889  for (int i = 1; i < p; i++)
6890  {
6891  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
6892  }
6893  for (int i = 1; i < p; i++)
6894  {
6895  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
6896  }
6897  for (int i = 1; i < p; i++)
6898  {
6899  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
6900  }
6901  for (int i = 1; i < p; i++)
6902  {
6903  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
6904  }
6905  for (int i = 1; i < p; i++)
6906  {
6907  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
6908  }
6909  for (int i = 1; i < p; i++)
6910  {
6911  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
6912  }
6913  for (int i = 1; i < p; i++)
6914  {
6915  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
6916  }
6917  for (int i = 1; i < p; i++)
6918  {
6919  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
6920  }
6921  for (int i = 1; i < p; i++)
6922  {
6923  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
6924  }
6925 
6926  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
6927  for (int j = 1; j < p; j++)
6928  for (int i = 1; i < p; i++)
6929  {
6930  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
6931  }
6932  for (int j = 1; j < p; j++)
6933  for (int i = 1; i < p; i++)
6934  {
6935  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
6936  }
6937  for (int j = 1; j < p; j++)
6938  for (int i = 1; i < p; i++)
6939  {
6940  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
6941  }
6942  for (int j = 1; j < p; j++)
6943  for (int i = 1; i < p; i++)
6944  {
6945  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
6946  }
6947  for (int j = 1; j < p; j++)
6948  for (int i = 1; i < p; i++)
6949  {
6950  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
6951  }
6952  for (int j = 1; j < p; j++)
6953  for (int i = 1; i < p; i++)
6954  {
6955  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
6956  }
6957 
6958  // interior
6959  for (int k = 1; k < p; k++)
6960  for (int j = 1; j < p; j++)
6961  for (int i = 1; i < p; i++)
6962  {
6963  dof_map[i + (j + k*p1)*p1] = o++;
6964  }
6965 
6966  o = 0;
6967  for (int k = 0; k <= p; k++)
6968  for (int j = 0; j <= p; j++)
6969  for (int i = 0; i <= p; i++)
6970  {
6971  Nodes.IntPoint(dof_map[o++]).Set3(cp[i], cp[j], cp[k]);
6972  }
6973 }
6974 
6976  Vector &shape) const
6977 {
6978  const int p = Order;
6979 
6980 #ifdef MFEM_THREAD_SAFE
6981  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
6982 #endif
6983 
6984  basis1d.Eval(ip.x, shape_x);
6985  basis1d.Eval(ip.y, shape_y);
6986  basis1d.Eval(ip.z, shape_z);
6987 
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  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
6993  }
6994 }
6995 
6997  DenseMatrix &dshape) const
6998 {
6999  const int p = Order;
7000 
7001 #ifdef MFEM_THREAD_SAFE
7002  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7003  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7004 #endif
7005 
7006  basis1d.Eval(ip.x, shape_x, dshape_x);
7007  basis1d.Eval(ip.y, shape_y, dshape_y);
7008  basis1d.Eval(ip.z, shape_z, dshape_z);
7009 
7010  for (int o = 0, k = 0; k <= p; k++)
7011  for (int j = 0; j <= p; j++)
7012  for (int i = 0; i <= p; i++)
7013  {
7014  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7015  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7016  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7017  }
7018 }
7019 
7020 void H1_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7021 {
7022  const int p = Order;
7023  const double *cp = poly1d.ClosedPoints(p);
7024 
7025 #ifdef MFEM_THREAD_SAFE
7026  Vector shape_x(p+1), shape_y(p+1);
7027 #endif
7028 
7029  for (int i = 0; i <= p; i++)
7030  {
7031  shape_x(i) = poly1d.CalcDelta(p, (1.0 - cp[i]));
7032  shape_y(i) = poly1d.CalcDelta(p, cp[i]);
7033  }
7034 
7035  switch (vertex)
7036  {
7037  case 0:
7038  for (int o = 0, k = 0; k <= p; k++)
7039  for (int j = 0; j <= p; j++)
7040  for (int i = 0; i <= p; i++)
7041  {
7042  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_x(k);
7043  }
7044  break;
7045  case 1:
7046  for (int o = 0, k = 0; k <= p; k++)
7047  for (int j = 0; j <= p; j++)
7048  for (int i = 0; i <= p; i++)
7049  {
7050  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_x(k);
7051  }
7052  break;
7053  case 2:
7054  for (int o = 0, k = 0; k <= p; k++)
7055  for (int j = 0; j <= p; j++)
7056  for (int i = 0; i <= p; i++)
7057  {
7058  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_x(k);
7059  }
7060  break;
7061  case 3:
7062  for (int o = 0, k = 0; k <= p; k++)
7063  for (int j = 0; j <= p; j++)
7064  for (int i = 0; i <= p; i++)
7065  {
7066  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_x(k);
7067  }
7068  break;
7069  case 4:
7070  for (int o = 0, k = 0; k <= p; k++)
7071  for (int j = 0; j <= p; j++)
7072  for (int i = 0; i <= p; i++)
7073  {
7074  dofs(dof_map[o++]) = shape_x(i)*shape_x(j)*shape_y(k);
7075  }
7076  break;
7077  case 5:
7078  for (int o = 0, k = 0; k <= p; k++)
7079  for (int j = 0; j <= p; j++)
7080  for (int i = 0; i <= p; i++)
7081  {
7082  dofs(dof_map[o++]) = shape_y(i)*shape_x(j)*shape_y(k);
7083  }
7084  break;
7085  case 6:
7086  for (int o = 0, k = 0; k <= p; k++)
7087  for (int j = 0; j <= p; j++)
7088  for (int i = 0; i <= p; i++)
7089  {
7090  dofs(dof_map[o++]) = shape_y(i)*shape_y(j)*shape_y(k);
7091  }
7092  break;
7093  case 7:
7094  for (int o = 0, k = 0; k <= p; k++)
7095  for (int j = 0; j <= p; j++)
7096  for (int i = 0; i <= p; i++)
7097  {
7098  dofs(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_y(k);
7099  }
7100  break;
7101  }
7102 }
7103 
7104 
7106  : PositiveFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk)
7107 {
7108 #ifndef MFEM_THREAD_SAFE
7109  // thread private versions; see class header.
7110  shape_x.SetSize(p+1);
7111  dshape_x.SetSize(p+1);
7112 #endif
7113 
7114  // Endpoints need to be first in the list, so reorder them.
7115  Nodes.IntPoint(0).x = 0.0;
7116  Nodes.IntPoint(1).x = 1.0;
7117  for (int i = 1; i < p; i++)
7118  {
7119  Nodes.IntPoint(i+1).x = double(i)/p;
7120  }
7121 }
7122 
7124  Vector &shape) const
7125 {
7126  const int p = Order;
7127 
7128 #ifdef MFEM_THREAD_SAFE
7129  Vector shape_x(p+1);
7130 #endif
7131 
7132  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7133 
7134  // Endpoints need to be first in the list, so reorder them.
7135  shape(0) = shape_x(0);
7136  shape(1) = shape_x(p);
7137  for (int i = 1; i < p; i++)
7138  {
7139  shape(i+1) = shape_x(i);
7140  }
7141 }
7142 
7144  DenseMatrix &dshape) const
7145 {
7146  const int p = Order;
7147 
7148 #ifdef MFEM_THREAD_SAFE
7149  Vector shape_x(p+1), dshape_x(p+1);
7150 #endif
7151 
7152  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7153 
7154  // Endpoints need to be first in the list, so reorder them.
7155  dshape(0,0) = dshape_x(0);
7156  dshape(1,0) = dshape_x(p);
7157  for (int i = 1; i < p; i++)
7158  {
7159  dshape(i+1,0) = dshape_x(i);
7160  }
7161 }
7162 
7163 void H1Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7164 {
7165  dofs = 0.0;
7166  dofs[vertex] = 1.0;
7167 }
7168 
7169 
7171  : PositiveFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
7172  FunctionSpace::Qk),
7173  dof_map((p + 1)*(p + 1))
7174 {
7175  const int p1 = p + 1;
7176 
7177 #ifndef MFEM_THREAD_SAFE
7178  shape_x.SetSize(p1);
7179  shape_y.SetSize(p1);
7180  dshape_x.SetSize(p1);
7181  dshape_y.SetSize(p1);
7182 #endif
7183 
7184  // vertices must be the first ones in the list of DOF's for
7185  // this element. So we need to reorder the points.
7186  dof_map[0 + 0*p1] = 0;
7187  dof_map[p + 0*p1] = 1;
7188  dof_map[p + p*p1] = 2;
7189  dof_map[0 + p*p1] = 3;
7190 
7191  // edges
7192  int o = 4;
7193  for (int i = 1; i < p; i++)
7194  {
7195  dof_map[i + 0*p1] = o++;
7196  }
7197  for (int i = 1; i < p; i++)
7198  {
7199  dof_map[p + i*p1] = o++;
7200  }
7201  for (int i = 1; i < p; i++)
7202  {
7203  dof_map[(p-i) + p*p1] = o++;
7204  }
7205  for (int i = 1; i < p; i++)
7206  {
7207  dof_map[0 + (p-i)*p1] = o++;
7208  }
7209 
7210  // interior
7211  for (int j = 1; j < p; j++)
7212  for (int i = 1; i < p; i++)
7213  {
7214  dof_map[i + j*p1] = o++;
7215  }
7216 
7217  o = 0;
7218  for (int j = 0; j <= p; j++)
7219  for (int i = 0; i <= p; i++)
7220  {
7221  Nodes.IntPoint(dof_map[o++]).Set2(double(i)/p, double(j)/p);
7222  }
7223 }
7224 
7226  Vector &shape) const
7227 {
7228  const int p = Order;
7229 
7230 #ifdef MFEM_THREAD_SAFE
7231  Vector shape_x(p+1), shape_y(p+1);
7232 #endif
7233 
7234  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7235  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7236 
7237  // Reorder so that vertices are at the beginning of the list
7238  for (int o = 0, j = 0; j <= p; j++)
7239  for (int i = 0; i <= p; i++)
7240  {
7241  shape(dof_map[o++]) = shape_x(i)*shape_y(j);
7242  }
7243 }
7244 
7246  DenseMatrix &dshape) const
7247 {
7248  const int p = Order;
7249 
7250 #ifdef MFEM_THREAD_SAFE
7251  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7252 #endif
7253 
7254  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7255  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7256 
7257  // Reorder so that vertices are at the beginning of the list
7258  for (int o = 0, j = 0; j <= p; j++)
7259  for (int i = 0; i <= p; i++)
7260  {
7261  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j);
7262  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j); o++;
7263  }
7264 }
7265 
7267 {
7268  dofs = 0.0;
7269  dofs[vertex] = 1.0;
7270 }
7271 
7272 
7274  : PositiveFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
7275  FunctionSpace::Qk),
7276  dof_map((p + 1)*(p + 1)*(p + 1))
7277 {
7278  const int p1 = p + 1;
7279 
7280 #ifndef MFEM_THREAD_SAFE
7281  shape_x.SetSize(p1);
7282  shape_y.SetSize(p1);
7283  shape_z.SetSize(p1);
7284  dshape_x.SetSize(p1);
7285  dshape_y.SetSize(p1);
7286  dshape_z.SetSize(p1);
7287 #endif
7288 
7289  // vertices must be the first ones in the list of DOF's for
7290  // this element. So we need to reorder the points.
7291  dof_map[0 + (0 + 0*p1)*p1] = 0;
7292  dof_map[p + (0 + 0*p1)*p1] = 1;
7293  dof_map[p + (p + 0*p1)*p1] = 2;
7294  dof_map[0 + (p + 0*p1)*p1] = 3;
7295  dof_map[0 + (0 + p*p1)*p1] = 4;
7296  dof_map[p + (0 + p*p1)*p1] = 5;
7297  dof_map[p + (p + p*p1)*p1] = 6;
7298  dof_map[0 + (p + p*p1)*p1] = 7;
7299 
7300  // edges (see Hexahedron::edges in mesh/hexahedron.cpp)
7301  int o = 8;
7302  for (int i = 1; i < p; i++)
7303  {
7304  dof_map[i + (0 + 0*p1)*p1] = o++; // (0,1)
7305  }
7306  for (int i = 1; i < p; i++)
7307  {
7308  dof_map[p + (i + 0*p1)*p1] = o++; // (1,2)
7309  }
7310  for (int i = 1; i < p; i++)
7311  {
7312  dof_map[i + (p + 0*p1)*p1] = o++; // (3,2)
7313  }
7314  for (int i = 1; i < p; i++)
7315  {
7316  dof_map[0 + (i + 0*p1)*p1] = o++; // (0,3)
7317  }
7318  for (int i = 1; i < p; i++)
7319  {
7320  dof_map[i + (0 + p*p1)*p1] = o++; // (4,5)
7321  }
7322  for (int i = 1; i < p; i++)
7323  {
7324  dof_map[p + (i + p*p1)*p1] = o++; // (5,6)
7325  }
7326  for (int i = 1; i < p; i++)
7327  {
7328  dof_map[i + (p + p*p1)*p1] = o++; // (7,6)
7329  }
7330  for (int i = 1; i < p; i++)
7331  {
7332  dof_map[0 + (i + p*p1)*p1] = o++; // (4,7)
7333  }
7334  for (int i = 1; i < p; i++)
7335  {
7336  dof_map[0 + (0 + i*p1)*p1] = o++; // (0,4)
7337  }
7338  for (int i = 1; i < p; i++)
7339  {
7340  dof_map[p + (0 + i*p1)*p1] = o++; // (1,5)
7341  }
7342  for (int i = 1; i < p; i++)
7343  {
7344  dof_map[p + (p + i*p1)*p1] = o++; // (2,6)
7345  }
7346  for (int i = 1; i < p; i++)
7347  {
7348  dof_map[0 + (p + i*p1)*p1] = o++; // (3,7)
7349  }
7350 
7351  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7352  for (int j = 1; j < p; j++)
7353  for (int i = 1; i < p; i++)
7354  {
7355  dof_map[i + ((p-j) + 0*p1)*p1] = o++; // (3,2,1,0)
7356  }
7357  for (int j = 1; j < p; j++)
7358  for (int i = 1; i < p; i++)
7359  {
7360  dof_map[i + (0 + j*p1)*p1] = o++; // (0,1,5,4)
7361  }
7362  for (int j = 1; j < p; j++)
7363  for (int i = 1; i < p; i++)
7364  {
7365  dof_map[p + (i + j*p1)*p1] = o++; // (1,2,6,5)
7366  }
7367  for (int j = 1; j < p; j++)
7368  for (int i = 1; i < p; i++)
7369  {
7370  dof_map[(p-i) + (p + j*p1)*p1] = o++; // (2,3,7,6)
7371  }
7372  for (int j = 1; j < p; j++)
7373  for (int i = 1; i < p; i++)
7374  {
7375  dof_map[0 + ((p-i) + j*p1)*p1] = o++; // (3,0,4,7)
7376  }
7377  for (int j = 1; j < p; j++)
7378  for (int i = 1; i < p; i++)
7379  {
7380  dof_map[i + (j + p*p1)*p1] = o++; // (4,5,6,7)
7381  }
7382 
7383  // interior
7384  for (int k = 1; k < p; k++)
7385  for (int j = 1; j < p; j++)
7386  for (int i = 1; i < p; i++)
7387  {
7388  dof_map[i + (j + k*p1)*p1] = o++;
7389  }
7390 
7391  o = 0;
7392  for (int k = 0; k <= p; k++)
7393  for (int j = 0; j <= p; j++)
7394  for (int i = 0; i <= p; i++)
7395  Nodes.IntPoint(dof_map[o++]).Set3(double(i)/p, double(j)/p,
7396  double(k)/p);
7397 }
7398 
7400  Vector &shape) const
7401 {
7402  const int p = Order;
7403 
7404 #ifdef MFEM_THREAD_SAFE
7405  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7406 #endif
7407 
7408  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData() );
7409  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData() );
7410  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData() );
7411 
7412  for (int o = 0, k = 0; k <= p; k++)
7413  for (int j = 0; j <= p; j++)
7414  for (int i = 0; i <= p; i++)
7415  {
7416  shape(dof_map[o++]) = shape_x(i)*shape_y(j)*shape_z(k);
7417  }
7418 }
7419 
7421  DenseMatrix &dshape) const
7422 {
7423  const int p = Order;
7424 
7425 #ifdef MFEM_THREAD_SAFE
7426  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
7427  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
7428 #endif
7429 
7430  Poly_1D::CalcBernstein(p, ip.x, shape_x.GetData(), dshape_x.GetData() );
7431  Poly_1D::CalcBernstein(p, ip.y, shape_y.GetData(), dshape_y.GetData() );
7432  Poly_1D::CalcBernstein(p, ip.z, shape_z.GetData(), dshape_z.GetData() );
7433 
7434  for (int o = 0, k = 0; k <= p; k++)
7435  for (int j = 0; j <= p; j++)
7436  for (int i = 0; i <= p; i++)
7437  {
7438  dshape(dof_map[o],0) = dshape_x(i)* shape_y(j)* shape_z(k);
7439  dshape(dof_map[o],1) = shape_x(i)*dshape_y(j)* shape_z(k);
7440  dshape(dof_map[o],2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
7441  }
7442 }
7443 
7444 void H1Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
7445 {
7446  dofs = 0.0;
7447  dofs[vertex] = 1.0;
7448 }
7449 
7450 
7452  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
7453  FunctionSpace::Pk)
7454 {
7455  const double *cp = poly1d.ClosedPoints(p);
7456 
7457 #ifndef MFEM_THREAD_SAFE
7458  shape_x.SetSize(p + 1);
7459  shape_y.SetSize(p + 1);
7460  shape_l.SetSize(p + 1);
7461  dshape_x.SetSize(p + 1);
7462  dshape_y.SetSize(p + 1);
7463  dshape_l.SetSize(p + 1);
7464  u.SetSize(Dof);
7465  du.SetSize(Dof, Dim);
7466 #else
7467  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7468 #endif
7469 
7470  // vertices
7471  Nodes.IntPoint(0).Set2(cp[0], cp[0]);
7472  Nodes.IntPoint(1).Set2(cp[p], cp[0]);
7473  Nodes.IntPoint(2).Set2(cp[0], cp[p]);
7474 
7475  // edges
7476  int o = 3;
7477  for (int i = 1; i < p; i++)
7478  {
7479  Nodes.IntPoint(o++).Set2(cp[i], cp[0]);
7480  }
7481  for (int i = 1; i < p; i++)
7482  {
7483  Nodes.IntPoint(o++).Set2(cp[p-i], cp[i]);
7484  }
7485  for (int i = 1; i < p; i++)
7486  {
7487  Nodes.IntPoint(o++).Set2(cp[0], cp[p-i]);
7488  }
7489 
7490  // interior
7491  for (int j = 1; j < p; j++)
7492  for (int i = 1; i + j < p; i++)
7493  {
7494  const double w = cp[i] + cp[j] + cp[p-i-j];
7495  Nodes.IntPoint(o++).Set2(cp[i]/w, cp[j]/w);
7496  }
7497 
7498  DenseMatrix T(Dof);
7499  for (int k = 0; k < Dof; k++)
7500  {
7501  IntegrationPoint &ip = Nodes.IntPoint(k);
7502  poly1d.CalcBasis(p, ip.x, shape_x);
7503  poly1d.CalcBasis(p, ip.y, shape_y);
7504  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7505 
7506  o = 0;
7507  for (int j = 0; j <= p; j++)
7508  for (int i = 0; i + j <= p; i++)
7509  {
7510  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7511  }
7512  }
7513 
7514  Ti.Factor(T);
7515  // cout << "H1_TriangleElement(" << p << ") : "; Ti.TestInversion();
7516 }
7517 
7519  Vector &shape) const
7520 {
7521  const int p = Order;
7522 
7523 #ifdef MFEM_THREAD_SAFE
7524  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
7525 #endif
7526 
7527  poly1d.CalcBasis(p, ip.x, shape_x);
7528  poly1d.CalcBasis(p, ip.y, shape_y);
7529  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
7530 
7531  for (int o = 0, j = 0; j <= p; j++)
7532  for (int i = 0; i + j <= p; i++)
7533  {
7534  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
7535  }
7536 
7537  Ti.Mult(u, shape);
7538 }
7539 
7541  DenseMatrix &dshape) const
7542 {
7543  const int p = Order;
7544 
7545 #ifdef MFEM_THREAD_SAFE
7546  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
7547  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
7548  DenseMatrix du(Dof, Dim);
7549 #endif
7550 
7551  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7552  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7553  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
7554 
7555  for (int o = 0, j = 0; j <= p; j++)
7556  for (int i = 0; i + j <= p; i++)
7557  {
7558  int k = p - i - j;
7559  du(o,0) = ((dshape_x(i)* shape_l(k)) -
7560  ( shape_x(i)*dshape_l(k)))*shape_y(j);
7561  du(o,1) = ((dshape_y(j)* shape_l(k)) -
7562  ( shape_y(j)*dshape_l(k)))*shape_x(i);
7563  o++;
7564  }
7565 
7566  Ti.Mult(du, dshape);
7567 }
7568 
7569 
7571  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
7572  p, FunctionSpace::Pk)
7573 {
7574  const double *cp = poly1d.ClosedPoints(p);
7575 
7576 #ifndef MFEM_THREAD_SAFE
7577  shape_x.SetSize(p + 1);
7578  shape_y.SetSize(p + 1);
7579  shape_z.SetSize(p + 1);
7580  shape_l.SetSize(p + 1);
7581  dshape_x.SetSize(p + 1);
7582  dshape_y.SetSize(p + 1);
7583  dshape_z.SetSize(p + 1);
7584  dshape_l.SetSize(p + 1);
7585  u.SetSize(Dof);
7586  du.SetSize(Dof, Dim);
7587 #else
7588  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7589 #endif
7590 
7591  // vertices
7592  Nodes.IntPoint(0).Set3(cp[0], cp[0], cp[0]);
7593  Nodes.IntPoint(1).Set3(cp[p], cp[0], cp[0]);
7594  Nodes.IntPoint(2).Set3(cp[0], cp[p], cp[0]);
7595  Nodes.IntPoint(3).Set3(cp[0], cp[0], cp[p]);
7596 
7597  // edges (see Tetrahedron::edges in mesh/tetrahedron.cpp)
7598  int o = 4;
7599  for (int i = 1; i < p; i++) // (0,1)
7600  {
7601  Nodes.IntPoint(o++).Set3(cp[i], cp[0], cp[0]);
7602  }
7603  for (int i = 1; i < p; i++) // (0,2)
7604  {
7605  Nodes.IntPoint(o++).Set3(cp[0], cp[i], cp[0]);
7606  }
7607  for (int i = 1; i < p; i++) // (0,3)
7608  {
7609  Nodes.IntPoint(o++).Set3(cp[0], cp[0], cp[i]);
7610  }
7611  for (int i = 1; i < p; i++) // (1,2)
7612  {
7613  Nodes.IntPoint(o++).Set3(cp[p-i], cp[i], cp[0]);
7614  }
7615  for (int i = 1; i < p; i++) // (1,3)
7616  {
7617  Nodes.IntPoint(o++).Set3(cp[p-i], cp[0], cp[i]);
7618  }
7619  for (int i = 1; i < p; i++) // (2,3)
7620  {
7621  Nodes.IntPoint(o++).Set3(cp[0], cp[p-i], cp[i]);
7622  }
7623 
7624  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp)
7625  for (int j = 1; j < p; j++)
7626  for (int i = 1; i + j < p; i++) // (1,2,3)
7627  {
7628  double w = cp[i] + cp[j] + cp[p-i-j];
7629  Nodes.IntPoint(o++).Set3(cp[p-i-j]/w, cp[i]/w, cp[j]/w);
7630  }
7631  for (int j = 1; j < p; j++)
7632  for (int i = 1; i + j < p; i++) // (0,3,2)
7633  {
7634  double w = cp[i] + cp[j] + cp[p-i-j];
7635  Nodes.IntPoint(o++).Set3(cp[0], cp[j]/w, cp[i]/w);
7636  }
7637  for (int j = 1; j < p; j++)
7638  for (int i = 1; i + j < p; i++) // (0,1,3)
7639  {
7640  double w = cp[i] + cp[j] + cp[p-i-j];
7641  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[0], cp[j]/w);
7642  }
7643  for (int j = 1; j < p; j++)
7644  for (int i = 1; i + j < p; i++) // (0,2,1)
7645  {
7646  double w = cp[i] + cp[j] + cp[p-i-j];
7647  Nodes.IntPoint(o++).Set3(cp[j]/w, cp[i]/w, cp[0]);
7648  }
7649 
7650  // interior
7651  for (int k = 1; k < p; k++)
7652  for (int j = 1; j + k < p; j++)
7653  for (int i = 1; i + j + k < p; i++)
7654  {
7655  double w = cp[i] + cp[j] + cp[k] + cp[p-i-j-k];
7656  Nodes.IntPoint(o++).Set3(cp[i]/w, cp[j]/w, cp[k]/w);
7657  }
7658 
7659  DenseMatrix T(Dof);
7660  for (int m = 0; m < Dof; m++)
7661  {
7662  IntegrationPoint &ip = Nodes.IntPoint(m);
7663  poly1d.CalcBasis(p, ip.x, shape_x);
7664  poly1d.CalcBasis(p, ip.y, shape_y);
7665  poly1d.CalcBasis(p, ip.z, shape_z);
7666  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7667 
7668  o = 0;
7669  for (int k = 0; k <= p; k++)
7670  for (int j = 0; j + k <= p; j++)
7671  for (int i = 0; i + j + k <= p; i++)
7672  {
7673  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7674  }
7675  }
7676 
7677  Ti.Factor(T);
7678  // cout << "H1_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
7679 }
7680 
7682  Vector &shape) const
7683 {
7684  const int p = Order;
7685 
7686 #ifdef MFEM_THREAD_SAFE
7687  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7688  Vector u(Dof);
7689 #endif
7690 
7691  poly1d.CalcBasis(p, ip.x, shape_x);
7692  poly1d.CalcBasis(p, ip.y, shape_y);
7693  poly1d.CalcBasis(p, ip.z, shape_z);
7694  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
7695 
7696  for (int o = 0, k = 0; k <= p; k++)
7697  for (int j = 0; j + k <= p; j++)
7698  for (int i = 0; i + j + k <= p; i++)
7699  {
7700  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
7701  }
7702 
7703  Ti.Mult(u, shape);
7704 }
7705 
7707  DenseMatrix &dshape) const
7708 {
7709  const int p = Order;
7710 
7711 #ifdef MFEM_THREAD_SAFE
7712  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
7713  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
7714  DenseMatrix du(Dof, Dim);
7715 #endif
7716 
7717  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
7718  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
7719  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
7720  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
7721 
7722  for (int o = 0, k = 0; k <= p; k++)
7723  for (int j = 0; j + k <= p; j++)
7724  for (int i = 0; i + j + k <= p; i++)
7725  {
7726  int l = p - i - j - k;
7727  du(o,0) = ((dshape_x(i)* shape_l(l)) -
7728  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
7729  du(o,1) = ((dshape_y(j)* shape_l(l)) -
7730  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
7731  du(o,2) = ((dshape_z(k)* shape_l(l)) -
7732  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
7733  o++;
7734  }
7735 
7736  Ti.Mult(du, dshape);
7737 }
7738 
7739 
7740 L2_SegmentElement::L2_SegmentElement(const int p, const int _type)
7741  : NodalFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk)
7742 {
7743  const double *op;
7744 
7745  type = _type;
7746  switch (type)
7747  {
7748  case 0:
7749  basis1d = &poly1d.OpenBasis(p);
7750  op = poly1d.OpenPoints(p);
7751  break;
7752  case 1:
7753  default:
7754  basis1d = &poly1d.ClosedBasis(p);
7755  op = poly1d.ClosedPoints(p);
7756  }
7757 
7758 #ifndef MFEM_THREAD_SAFE
7759  shape_x.SetSize(p + 1);
7760  dshape_x.SetDataAndSize(NULL, p + 1);
7761 #endif
7762 
7763  for (int i = 0; i <= p; i++)
7764  {
7765  Nodes.IntPoint(i).x = op[i];
7766  }
7767 }
7768 
7770  Vector &shape) const
7771 {
7772  basis1d->Eval(ip.x, shape);
7773 }
7774 
7776  DenseMatrix &dshape) const
7777 {
7778 #ifdef MFEM_THREAD_SAFE
7779  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
7780 #else
7781  dshape_x.SetData(dshape.Data());
7782 #endif
7783  basis1d->Eval(ip.x, shape_x, dshape_x);
7784 }
7785 
7787  Vector &dofs) const
7788 {
7789  const int p = Order;
7790  const double *op;
7791 
7792  switch (type)
7793  {
7794  case 0: op = poly1d.OpenPoints(p); break;
7795  case 1:
7796  default: op = poly1d.ClosedPoints(p);
7797  }
7798 
7799  switch (vertex)
7800  {
7801  case 0:
7802  for (int i = 0; i <= p; i++)
7803  {
7804  dofs(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
7805  }
7806  break;
7807 
7808  case 1:
7809  for (int i = 0; i <= p; i++)
7810  {
7811  dofs(i) = poly1d.CalcDelta(p,op[i]);
7812  }
7813  break;
7814  }
7815 }
7816 
7817 
7819  : PositiveFiniteElement(1, Geometry::SEGMENT, p + 1, p, FunctionSpace::Pk)
7820 {
7821 #ifndef MFEM_THREAD_SAFE
7822  shape_x.SetSize(p + 1);
7823  dshape_x.SetDataAndSize(NULL, p + 1);
7824 #endif
7825 
7826  if (p == 0)
7827  {
7828  Nodes.IntPoint(0).x = 0.5;
7829  }
7830  else
7831  {
7832  for (int i = 0; i <= p; i++)
7833  {
7834  Nodes.IntPoint(i).x = double(i)/p;
7835  }
7836  }
7837 }
7838 
7840  Vector &shape) const
7841 {
7842  Poly_1D::CalcBernstein(Order, ip.x, shape);
7843 }
7844 
7846  DenseMatrix &dshape) const
7847 {
7848 #ifdef MFEM_THREAD_SAFE
7849  Vector shape_x(Dof), dshape_x(dshape.Data(), Dof);
7850 #else
7851  dshape_x.SetData(dshape.Data());
7852 #endif
7853  Poly_1D::CalcBernstein(Order, ip.x, shape_x, dshape_x);
7854 }
7855 
7856 void L2Pos_SegmentElement::ProjectDelta(int vertex, Vector &dofs) const
7857 {
7858  dofs = 0.0;
7859  dofs[vertex*Order] = 1.0;
7860 }
7861 
7862 
7864  : NodalFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
7865  FunctionSpace::Qk)
7866 {
7867  const double *op;
7868 
7869  type = _type;
7870  switch (type)
7871  {
7872  case 0:
7873  basis1d = &poly1d.OpenBasis(p);
7874  op = poly1d.OpenPoints(p);
7875  break;
7876  case 1:
7877  default:
7878  basis1d = &poly1d.ClosedBasis(p);
7879  op = poly1d.ClosedPoints(p);
7880  }
7881 
7882 #ifndef MFEM_THREAD_SAFE
7883  shape_x.SetSize(p + 1);
7884  shape_y.SetSize(p + 1);
7885  dshape_x.SetSize(p + 1);
7886  dshape_y.SetSize(p + 1);
7887 #endif
7888 
7889  for (int o = 0, j = 0; j <= p; j++)
7890  for (int i = 0; i <= p; i++)
7891  {
7892  Nodes.IntPoint(o++).Set2(op[i], op[j]);
7893  }
7894 }
7895 
7897  Vector &shape) const
7898 {
7899  const int p = Order;
7900 
7901 #ifdef MFEM_THREAD_SAFE
7902  Vector shape_x(p+1), shape_y(p+1);
7903 #endif
7904 
7905  basis1d->Eval(ip.x, shape_x);
7906  basis1d->Eval(ip.y, shape_y);
7907 
7908  for (int o = 0, j = 0; j <= p; j++)
7909  for (int i = 0; i <= p; i++)
7910  {
7911  shape(o++) = shape_x(i)*shape_y(j);
7912  }
7913 }
7914 
7916  DenseMatrix &dshape) const
7917 {
7918  const int p = Order;
7919 
7920 #ifdef MFEM_THREAD_SAFE
7921  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
7922 #endif
7923 
7924  basis1d->Eval(ip.x, shape_x, dshape_x);
7925  basis1d->Eval(ip.y, shape_y, dshape_y);
7926 
7927  for (int o = 0, j = 0; j <= p; j++)
7928  for (int i = 0; i <= p; i++)
7929  {
7930  dshape(o,0) = dshape_x(i)* shape_y(j);
7931  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
7932  }
7933 }
7934 
7935 void L2_QuadrilateralElement::ProjectDelta(int vertex, Vector &dofs) const
7936 {
7937  const int p = Order;
7938  const double *op;
7939 
7940  switch (type)
7941  {
7942  case 0: op = poly1d.OpenPoints(p); break;
7943  case 1:
7944  default: op = poly1d.ClosedPoints(p);
7945  }
7946 
7947 #ifdef MFEM_THREAD_SAFE
7948  Vector shape_x(p+1), shape_y(p+1);
7949 #endif
7950 
7951  for (int i = 0; i <= p; i++)
7952  {
7953  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
7954  shape_y(i) = poly1d.CalcDelta(p,op[i]);
7955  }
7956 
7957  switch (vertex)
7958  {
7959  case 0:
7960  for (int o = 0, j = 0; j <= p; j++)
7961  for (int i = 0; i <= p; i++)
7962  {
7963  dofs[o++] = shape_x(i)*shape_x(j);
7964  }
7965  break;
7966  case 1:
7967  for (int o = 0, j = 0; j <= p; j++)
7968  for (int i = 0; i <= p; i++)
7969  {
7970  dofs[o++] = shape_y(i)*shape_x(j);
7971  }
7972  break;
7973  case 2:
7974  for (int o = 0, j = 0; j <= p; j++)
7975  for (int i = 0; i <= p; i++)
7976  {
7977  dofs[o++] = shape_y(i)*shape_y(j);
7978  }
7979  break;
7980  case 3:
7981  for (int o = 0, j = 0; j <= p; j++)
7982  for (int i = 0; i <= p; i++)
7983  {
7984  dofs[o++] = shape_x(i)*shape_y(j);
7985  }
7986  break;
7987  }
7988 }
7989 
7990 
7992  : PositiveFiniteElement(2, Geometry::SQUARE, (p + 1)*(p + 1), p,
7993  FunctionSpace::Qk)
7994 {
7995 #ifndef MFEM_THREAD_SAFE
7996  shape_x.SetSize(p + 1);
7997  shape_y.SetSize(p + 1);
7998  dshape_x.SetSize(p + 1);
7999  dshape_y.SetSize(p + 1);
8000 #endif
8001 
8002  if (p == 0)
8003  {
8004  Nodes.IntPoint(0).Set2(0.5, 0.5);
8005  }
8006  else
8007  {
8008  for (int o = 0, j = 0; j <= p; j++)
8009  for (int i = 0; i <= p; i++)
8010  {
8011  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8012  }
8013  }
8014 }
8015 
8017  Vector &shape) const
8018 {
8019  const int p = Order;
8020 
8021 #ifdef MFEM_THREAD_SAFE
8022  Vector shape_x(p+1), shape_y(p+1);
8023 #endif
8024 
8025  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8026  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8027 
8028  for (int o = 0, j = 0; j <= p; j++)
8029  for (int i = 0; i <= p; i++)
8030  {
8031  shape(o++) = shape_x(i)*shape_y(j);
8032  }
8033 }
8034 
8036  DenseMatrix &dshape) const
8037 {
8038  const int p = Order;
8039 
8040 #ifdef MFEM_THREAD_SAFE
8041  Vector shape_x(p+1), shape_y(p+1), dshape_x(p+1), dshape_y(p+1);
8042 #endif
8043 
8044  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8045  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8046 
8047  for (int o = 0, j = 0; j <= p; j++)
8048  for (int i = 0; i <= p; i++)
8049  {
8050  dshape(o,0) = dshape_x(i)* shape_y(j);
8051  dshape(o,1) = shape_x(i)*dshape_y(j); o++;
8052  }
8053 }
8054 
8056 {
8057  const int p = Order;
8058 
8059  dofs = 0.0;
8060  switch (vertex)
8061  {
8062  case 0: dofs[0] = 1.0; break;
8063  case 1: dofs[p] = 1.0; break;
8064  case 2: dofs[p*(p + 2)] = 1.0; break;
8065  case 3: dofs[p*(p + 1)] = 1.0; break;
8066  }
8067 }
8068 
8069 
8070 L2_HexahedronElement::L2_HexahedronElement(const int p, const int _type)
8071  : NodalFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
8072  FunctionSpace::Qk)
8073 {
8074  const double *op;
8075 
8076  type = _type;
8077  switch (type)
8078  {
8079  case 0:
8080  basis1d = &poly1d.OpenBasis(p);
8081  op = poly1d.OpenPoints(p);
8082  break;
8083  case 1:
8084  default:
8085  basis1d = &poly1d.ClosedBasis(p);
8086  op = poly1d.ClosedPoints(p);
8087  }
8088 
8089 #ifndef MFEM_THREAD_SAFE
8090  shape_x.SetSize(p + 1);
8091  shape_y.SetSize(p + 1);
8092  shape_z.SetSize(p + 1);
8093  dshape_x.SetSize(p + 1);
8094  dshape_y.SetSize(p + 1);
8095  dshape_z.SetSize(p + 1);
8096 #endif
8097 
8098  for (int o = 0, k = 0; k <= p; k++)
8099  for (int j = 0; j <= p; j++)
8100  for (int i = 0; i <= p; i++)
8101  {
8102  Nodes.IntPoint(o++).Set3(op[i], op[j], op[k]);
8103  }
8104 }
8105 
8107  Vector &shape) const
8108 {
8109  const int p = Order;
8110 
8111 #ifdef MFEM_THREAD_SAFE
8112  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8113 #endif
8114 
8115  basis1d->Eval(ip.x, shape_x);
8116  basis1d->Eval(ip.y, shape_y);
8117  basis1d->Eval(ip.z, shape_z);
8118 
8119  for (int o = 0, k = 0; k <= p; k++)
8120  for (int j = 0; j <= p; j++)
8121  for (int i = 0; i <= p; i++)
8122  {
8123  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8124  }
8125 }
8126 
8128  DenseMatrix &dshape) const
8129 {
8130  const int p = Order;
8131 
8132 #ifdef MFEM_THREAD_SAFE
8133  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8134  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8135 #endif
8136 
8137  basis1d->Eval(ip.x, shape_x, dshape_x);
8138  basis1d->Eval(ip.y, shape_y, dshape_y);
8139  basis1d->Eval(ip.z, shape_z, dshape_z);
8140 
8141  for (int o = 0, k = 0; k <= p; k++)
8142  for (int j = 0; j <= p; j++)
8143  for (int i = 0; i <= p; i++)
8144  {
8145  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8146  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8147  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8148  }
8149 }
8150 
8151 void L2_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8152 {
8153  const int p = Order;
8154  const double *op;
8155 
8156  switch (type)
8157  {
8158  case 0: op = poly1d.OpenPoints(p); break;
8159  case 1:
8160  default: op = poly1d.ClosedPoints(p);
8161  }
8162 
8163 #ifdef MFEM_THREAD_SAFE
8164  Vector shape_x(p+1), shape_y(p+1);
8165 #endif
8166 
8167  for (int i = 0; i <= p; i++)
8168  {
8169  shape_x(i) = poly1d.CalcDelta(p,(1.0 - op[i]));
8170  shape_y(i) = poly1d.CalcDelta(p,op[i]);
8171  }
8172 
8173  switch (vertex)
8174  {
8175  case 0:
8176  for (int o = 0, k = 0; k <= p; k++)
8177  for (int j = 0; j <= p; j++)
8178  for (int i = 0; i <= p; i++)
8179  {
8180  dofs[o++] = shape_x(i)*shape_x(j)*shape_x(k);
8181  }
8182  break;
8183  case 1:
8184  for (int o = 0, k = 0; k <= p; k++)
8185  for (int j = 0; j <= p; j++)
8186  for (int i = 0; i <= p; i++)
8187  {
8188  dofs[o++] = shape_y(i)*shape_x(j)*shape_x(k);
8189  }
8190  break;
8191  case 2:
8192  for (int o = 0, k = 0; k <= p; k++)
8193  for (int j = 0; j <= p; j++)
8194  for (int i = 0; i <= p; i++)
8195  {
8196  dofs[o++] = shape_y(i)*shape_y(j)*shape_x(k);
8197  }
8198  break;
8199  case 3:
8200  for (int o = 0, k = 0; k <= p; k++)
8201  for (int j = 0; j <= p; j++)
8202  for (int i = 0; i <= p; i++)
8203  {
8204  dofs[o++] = shape_x(i)*shape_y(j)*shape_x(k);
8205  }
8206  break;
8207  case 4:
8208  for (int o = 0, k = 0; k <= p; k++)
8209  for (int j = 0; j <= p; j++)
8210  for (int i = 0; i <= p; i++)
8211  {
8212  dofs[o++] = shape_x(i)*shape_x(j)*shape_y(k);
8213  }
8214  break;
8215  case 5:
8216  for (int o = 0, k = 0; k <= p; k++)
8217  for (int j = 0; j <= p; j++)
8218  for (int i = 0; i <= p; i++)
8219  {
8220  dofs[o++] = shape_y(i)*shape_x(j)*shape_y(k);
8221  }
8222  break;
8223  case 6:
8224  for (int o = 0, k = 0; k <= p; k++)
8225  for (int j = 0; j <= p; j++)
8226  for (int i = 0; i <= p; i++)
8227  {
8228  dofs[o++] = shape_y(i)*shape_y(j)*shape_y(k);
8229  }
8230  break;
8231  case 7:
8232  for (int o = 0, k = 0; k <= p; k++)
8233  for (int j = 0; j <= p; j++)
8234  for (int i = 0; i <= p; i++)
8235  {
8236  dofs[o++] = shape_x(i)*shape_y(j)*shape_y(k);
8237  }
8238  break;
8239  }
8240 }
8241 
8242 
8244  : PositiveFiniteElement(3, Geometry::CUBE, (p + 1)*(p + 1)*(p + 1), p,
8245  FunctionSpace::Qk)
8246 {
8247 #ifndef MFEM_THREAD_SAFE
8248  shape_x.SetSize(p + 1);
8249  shape_y.SetSize(p + 1);
8250  shape_z.SetSize(p + 1);
8251  dshape_x.SetSize(p + 1);
8252  dshape_y.SetSize(p + 1);
8253  dshape_z.SetSize(p + 1);
8254 #endif
8255 
8256  if (p == 0)
8257  {
8258  Nodes.IntPoint(0).Set3(0.5, 0.5, 0.5);
8259  }
8260  else
8261  {
8262  for (int o = 0, k = 0; k <= p; k++)
8263  for (int j = 0; j <= p; j++)
8264  for (int i = 0; i <= p; i++)
8265  {
8266  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8267  }
8268  }
8269 }
8270 
8272  Vector &shape) const
8273 {
8274  const int p = Order;
8275 
8276 #ifdef MFEM_THREAD_SAFE
8277  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8278 #endif
8279 
8280  Poly_1D::CalcBernstein(p, ip.x, shape_x);
8281  Poly_1D::CalcBernstein(p, ip.y, shape_y);
8282  Poly_1D::CalcBernstein(p, ip.z, shape_z);
8283 
8284  for (int o = 0, k = 0; k <= p; k++)
8285  for (int j = 0; j <= p; j++)
8286  for (int i = 0; i <= p; i++)
8287  {
8288  shape(o++) = shape_x(i)*shape_y(j)*shape_z(k);
8289  }
8290 }
8291 
8293  DenseMatrix &dshape) const
8294 {
8295  const int p = Order;
8296 
8297 #ifdef MFEM_THREAD_SAFE
8298  Vector shape_x(p+1), shape_y(p+1), shape_z(p+1);
8299  Vector dshape_x(p+1), dshape_y(p+1), dshape_z(p+1);
8300 #endif
8301 
8302  Poly_1D::CalcBernstein(p, ip.x, shape_x, dshape_x);
8303  Poly_1D::CalcBernstein(p, ip.y, shape_y, dshape_y);
8304  Poly_1D::CalcBernstein(p, ip.z, shape_z, dshape_z);
8305 
8306  for (int o = 0, k = 0; k <= p; k++)
8307  for (int j = 0; j <= p; j++)
8308  for (int i = 0; i <= p; i++)
8309  {
8310  dshape(o,0) = dshape_x(i)* shape_y(j)* shape_z(k);
8311  dshape(o,1) = shape_x(i)*dshape_y(j)* shape_z(k);
8312  dshape(o,2) = shape_x(i)* shape_y(j)*dshape_z(k); o++;
8313  }
8314 }
8315 
8316 void L2Pos_HexahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8317 {
8318  const int p = Order;
8319 
8320  dofs = 0.0;
8321  switch (vertex)
8322  {
8323  case 0: dofs[0] = 1.0; break;
8324  case 1: dofs[p] = 1.0; break;
8325  case 2: dofs[p*(p + 2)] = 1.0; break;
8326  case 3: dofs[p*(p + 1)] = 1.0; break;
8327  case 4: dofs[p*(p + 1)*(p + 1)] = 1.0; break;
8328  case 5: dofs[p + p*(p + 1)*(p + 1)] = 1.0; break;
8329  case 6: dofs[Dof - 1] = 1.0; break;
8330  case 7: dofs[Dof - p - 1] = 1.0; break;
8331  }
8332 }
8333 
8334 
8335 L2_TriangleElement::L2_TriangleElement(const int p, const int _type)
8336  : NodalFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8337  FunctionSpace::Pk)
8338 {
8339  const double *op;
8340 
8341  type = _type;
8342  switch (type)
8343  {
8344  case 0: op = poly1d.OpenPoints(p); break;
8345  case 1:
8346  default: op = poly1d.ClosedPoints(p);
8347  }
8348 
8349 #ifndef MFEM_THREAD_SAFE
8350  shape_x.SetSize(p + 1);
8351  shape_y.SetSize(p + 1);
8352  shape_l.SetSize(p + 1);
8353  dshape_x.SetSize(p + 1);
8354  dshape_y.SetSize(p + 1);
8355  dshape_l.SetSize(p + 1);
8356  u.SetSize(Dof);
8357  du.SetSize(Dof, Dim);
8358 #else
8359  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8360 #endif
8361 
8362  for (int o = 0, j = 0; j <= p; j++)
8363  for (int i = 0; i + j <= p; i++)
8364  {
8365  double w = op[i] + op[j] + op[p-i-j];
8366  Nodes.IntPoint(o++).Set2(op[i]/w, op[j]/w);
8367  }
8368 
8369  DenseMatrix T(Dof);
8370  for (int k = 0; k < Dof; k++)
8371  {
8372  IntegrationPoint &ip = Nodes.IntPoint(k);
8373  poly1d.CalcBasis(p, ip.x, shape_x);
8374  poly1d.CalcBasis(p, ip.y, shape_y);
8375  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8376 
8377  for (int o = 0, j = 0; j <= p; j++)
8378  for (int i = 0; i + j <= p; i++)
8379  {
8380  T(o++, k) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8381  }
8382  }
8383 
8384  Ti.Factor(T);
8385  // cout << "L2_TriangleElement(" << p << ") : "; Ti.TestInversion();
8386 }
8387 
8389  Vector &shape) const
8390 {
8391  const int p = Order;
8392 
8393 #ifdef MFEM_THREAD_SAFE
8394  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1), u(Dof);
8395 #endif
8396 
8397  poly1d.CalcBasis(p, ip.x, shape_x);
8398  poly1d.CalcBasis(p, ip.y, shape_y);
8399  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
8400 
8401  for (int o = 0, j = 0; j <= p; j++)
8402  for (int i = 0; i + j <= p; i++)
8403  {
8404  u(o++) = shape_x(i)*shape_y(j)*shape_l(p-i-j);
8405  }
8406 
8407  Ti.Mult(u, shape);
8408 }
8409 
8411  DenseMatrix &dshape) const
8412 {
8413  const int p = Order;
8414 
8415 #ifdef MFEM_THREAD_SAFE
8416  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
8417  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
8418  DenseMatrix du(Dof, Dim);
8419 #endif
8420 
8421  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8422  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8423  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
8424 
8425  for (int o = 0, j = 0; j <= p; j++)
8426  for (int i = 0; i + j <= p; i++)
8427  {
8428  int k = p - i - j;
8429  du(o,0) = ((dshape_x(i)* shape_l(k)) -
8430  ( shape_x(i)*dshape_l(k)))*shape_y(j);
8431  du(o,1) = ((dshape_y(j)* shape_l(k)) -
8432  ( shape_y(j)*dshape_l(k)))*shape_x(i);
8433  o++;
8434  }
8435 
8436  Ti.Mult(du, dshape);
8437 }
8438 
8439 void L2_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8440 {
8441  switch (vertex)
8442  {
8443  case 0:
8444  for (int i = 0; i < Dof; i++)
8445  {
8446  const IntegrationPoint &ip = Nodes.IntPoint(i);
8447  dofs[i] = pow(1.0 - ip.x - ip.y, Order);
8448  }
8449  break;
8450  case 1:
8451  for (int i = 0; i < Dof; i++)
8452  {
8453  const IntegrationPoint &ip = Nodes.IntPoint(i);
8454  dofs[i] = pow(ip.x, Order);
8455  }
8456  break;
8457  case 2:
8458  for (int i = 0; i < Dof; i++)
8459  {
8460  const IntegrationPoint &ip = Nodes.IntPoint(i);
8461  dofs[i] = pow(ip.y, Order);
8462  }
8463  break;
8464  }
8465 }
8466 
8467 
8469  : PositiveFiniteElement(2, Geometry::TRIANGLE, ((p + 1)*(p + 2))/2, p,
8470  FunctionSpace::Pk)
8471 {
8472 #ifndef MFEM_THREAD_SAFE
8473  dshape_1d.SetSize(p + 1);
8474 #endif
8475 
8476  if (p == 0)
8477  {
8478  Nodes.IntPoint(0).Set2(1./3, 1./3);
8479  }
8480  else
8481  {
8482  for (int o = 0, j = 0; j <= p; j++)
8483  for (int i = 0; i + j <= p; i++)
8484  {
8485  Nodes.IntPoint(o++).Set2(double(i)/p, double(j)/p);
8486  }
8487  }
8488 }
8489 
8491  Vector &shape) const
8492 {
8493  const int p = Order;
8494  const double l1 = ip.x, l2 = ip.y, l3 = 1. - l1 - l2;
8495 
8496  // The (i,j) basis function is given by: T(i,j,p-i-j) l1^i l2^j l3^{p-i-j},
8497  // where T(i,j,k) = (i+j+k)! / (i! j! k!)
8498  // Another expression is given by the terms of the expansion:
8499  // (l1 + l2 + l3)^p =
8500  // \sum_{j=0}^p \binom{p}{j} l2^j
8501  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i l3^{p-j-i}
8502  const int *bp = Poly_1D::Binom(p);
8503  double z = 1.;
8504  for (int o = 0, j = 0; j <= p; j++)
8505  {
8506  Poly_1D::CalcBinomTerms(p - j, l1, l3, &shape(o));
8507  double s = bp[j]*z;
8508  for (int i = 0; i <= p - j; i++)
8509  {
8510  shape(o++) *= s;
8511  }
8512  z *= l2;
8513  }
8514 }
8515 
8517  DenseMatrix &dshape) const
8518 {
8519  const int p = Order;
8520  const double l1 = ip.x, l2 = ip.y, l3 = 1. - l1 - l2;
8521 
8522 #ifdef MFEM_THREAD_SAFE
8523  Vector dshape_1d(p + 1);
8524 #endif
8525 
8526  const int *bp = Poly_1D::Binom(p);
8527  double z = 1.;
8528  for (int o = 0, j = 0; j <= p; j++)
8529  {
8530  Poly_1D::CalcDBinomTerms(p - j, l1, l3, dshape_1d);
8531  double s = bp[j]*z;
8532  for (int i = 0; i <= p - j; i++)
8533  {
8534  dshape(o++,0) = s*dshape_1d(i);
8535  }
8536  z *= l2;
8537  }
8538  z = 1.;
8539  for (int i = 0; i <= p; i++)
8540  {
8541  Poly_1D::CalcDBinomTerms(p - i, l2, l3, dshape_1d);
8542  double s = bp[i]*z;
8543  for (int o = i, j = 0; j <= p - i; j++)
8544  {
8545  dshape(o,1) = s*dshape_1d(j);
8546  o += p + 1 - j;
8547  }
8548  z *= l1;
8549  }
8550 }
8551 
8552 void L2Pos_TriangleElement::ProjectDelta(int vertex, Vector &dofs) const
8553 {
8554  dofs = 0.0;
8555  switch (vertex)
8556  {
8557  case 0: dofs[0] = 1.0; break;
8558  case 1: dofs[Order] = 1.0; break;
8559  case 2: dofs[Dof-1] = 1.0; break;
8560  }
8561 }
8562 
8563 
8565  : NodalFiniteElement(3, Geometry::TETRAHEDRON, ((p + 1)*(p + 2)*(p + 3))/6,
8566  p, FunctionSpace::Pk)
8567 {
8568  const double *op;
8569 
8570  type = _type;
8571  switch (type)
8572  {
8573  case 0: op = poly1d.OpenPoints(p); break;
8574  case 1:
8575  default: op = poly1d.ClosedPoints(p);
8576  }
8577 
8578 #ifndef MFEM_THREAD_SAFE
8579  shape_x.SetSize(p + 1);
8580  shape_y.SetSize(p + 1);
8581  shape_z.SetSize(p + 1);
8582  shape_l.SetSize(p + 1);
8583  dshape_x.SetSize(p + 1);
8584  dshape_y.SetSize(p + 1);
8585  dshape_z.SetSize(p + 1);
8586  dshape_l.SetSize(p + 1);
8587  u.SetSize(Dof);
8588  du.SetSize(Dof, Dim);
8589 #else
8590  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8591 #endif
8592 
8593  for (int o = 0, k = 0; k <= p; k++)
8594  for (int j = 0; j + k <= p; j++)
8595  for (int i = 0; i + j + k <= p; i++)
8596  {
8597  double w = op[i] + op[j] + op[k] + op[p-i-j-k];
8598  Nodes.IntPoint(o++).Set3(op[i]/w, op[j]/w, op[k]/w);
8599  }
8600 
8601  DenseMatrix T(Dof);
8602  for (int m = 0; m < Dof; m++)
8603  {
8604  IntegrationPoint &ip = Nodes.IntPoint(m);
8605  poly1d.CalcBasis(p, ip.x, shape_x);
8606  poly1d.CalcBasis(p, ip.y, shape_y);
8607  poly1d.CalcBasis(p, ip.z, shape_z);
8608  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8609 
8610  for (int o = 0, k = 0; k <= p; k++)
8611  for (int j = 0; j + k <= p; j++)
8612  for (int i = 0; i + j + k <= p; i++)
8613  {
8614  T(o++, m) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8615  }
8616  }
8617 
8618  Ti.Factor(T);
8619  // cout << "L2_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
8620 }
8621 
8623  Vector &shape) const
8624 {
8625  const int p = Order;
8626 
8627 #ifdef MFEM_THREAD_SAFE
8628  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8629  Vector u(Dof);
8630 #endif
8631 
8632  poly1d.CalcBasis(p, ip.x, shape_x);
8633  poly1d.CalcBasis(p, ip.y, shape_y);
8634  poly1d.CalcBasis(p, ip.z, shape_z);
8635  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
8636 
8637  for (int o = 0, k = 0; k <= p; k++)
8638  for (int j = 0; j + k <= p; j++)
8639  for (int i = 0; i + j + k <= p; i++)
8640  {
8641  u(o++) = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
8642  }
8643 
8644  Ti.Mult(u, shape);
8645 }
8646 
8648  DenseMatrix &dshape) const
8649 {
8650  const int p = Order;
8651 
8652 #ifdef MFEM_THREAD_SAFE
8653  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
8654  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
8655  DenseMatrix du(Dof, Dim);
8656 #endif
8657 
8658  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
8659  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
8660  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
8661  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
8662 
8663  for (int o = 0, k = 0; k <= p; k++)
8664  for (int j = 0; j + k <= p; j++)
8665  for (int i = 0; i + j + k <= p; i++)
8666  {
8667  int l = p - i - j - k;
8668  du(o,0) = ((dshape_x(i)* shape_l(l)) -
8669  ( shape_x(i)*dshape_l(l)))*shape_y(j)*shape_z(k);
8670  du(o,1) = ((dshape_y(j)* shape_l(l)) -
8671  ( shape_y(j)*dshape_l(l)))*shape_x(i)*shape_z(k);
8672  du(o,2) = ((dshape_z(k)* shape_l(l)) -
8673  ( shape_z(k)*dshape_l(l)))*shape_x(i)*shape_y(j);
8674  o++;
8675  }
8676 
8677  Ti.Mult(du, dshape);
8678 }
8679 
8680 void L2_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8681 {
8682  switch (vertex)
8683  {
8684  case 0:
8685  for (int i = 0; i < Dof; i++)
8686  {
8687  const IntegrationPoint &ip = Nodes.IntPoint(i);
8688  dofs[i] = pow(1.0 - ip.x - ip.y - ip.z, Order);
8689  }
8690  break;
8691  case 1:
8692  for (int i = 0; i < Dof; i++)
8693  {
8694  const IntegrationPoint &ip = Nodes.IntPoint(i);
8695  dofs[i] = pow(ip.x, Order);
8696  }
8697  break;
8698  case 2:
8699  for (int i = 0; i < Dof; i++)
8700  {
8701  const IntegrationPoint &ip = Nodes.IntPoint(i);
8702  dofs[i] = pow(ip.y, Order);
8703  }
8704  case 3:
8705  for (int i = 0; i < Dof; i++)
8706  {
8707  const IntegrationPoint &ip = Nodes.IntPoint(i);
8708  dofs[i] = pow(ip.z, Order);
8709  }
8710  break;
8711  }
8712 }
8713 
8714 
8716  : PositiveFiniteElement(3, Geometry::TETRAHEDRON,
8717  ((p + 1)*(p + 2)*(p + 3))/6, p, FunctionSpace::Pk)
8718 {
8719 #ifndef MFEM_THREAD_SAFE
8720  dshape_1d.SetSize(p + 1);
8721 #endif
8722 
8723  if (p == 0)
8724  {
8725  Nodes.IntPoint(0).Set3(0.25, 0.25, 0.25);
8726  }
8727  else
8728  {
8729  for (int o = 0, k = 0; k <= p; k++)
8730  for (int j = 0; j + k <= p; j++)
8731  for (int i = 0; i + j + k <= p; i++)
8732  {
8733  Nodes.IntPoint(o++).Set3(double(i)/p, double(j)/p, double(k)/p);
8734  }
8735  }
8736 }
8737 
8739  Vector &shape) const
8740 {
8741  const int p = Order;
8742  const double l1 = ip.x, l2 = ip.y, l3 = ip.z, l4 = 1. - l1 - l2 - l3;
8743 
8744  // The basis functions are the terms in the expansion:
8745  // (l1 + l2 + l3 + l4)^p =
8746  // \sum_{k=0}^p \binom{p}{k} l3^k
8747  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8748  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8749  const int *bp = Poly_1D::Binom(p);
8750  double l3k = 1.;
8751  for (int o = 0, k = 0; k <= p; k++)
8752  {
8753  const int *bpk = Poly_1D::Binom(p - k);
8754  const double ek = bp[k]*l3k;
8755  double l2j = 1.;
8756  for (int j = 0; j <= p - k; j++)
8757  {
8758  Poly_1D::CalcBinomTerms(p - k - j, l1, l4, &shape(o));
8759  double ekj = ek*bpk[j]*l2j;
8760  for (int i = 0; i <= p - k - j; i++)
8761  {
8762  shape(o++) *= ekj;
8763  }
8764  l2j *= l2;
8765  }
8766  l3k *= l3;
8767  }
8768 }
8769 
8771  DenseMatrix &dshape) const
8772 {
8773  const int p = Order;
8774  const double l1 = ip.x, l2 = ip.y, l3 = ip.z, l4 = 1. - l1 - l2 - l3;
8775 
8776 #ifdef MFEM_THREAD_SAFE
8777  Vector dshape_1d(p + 1);
8778 #endif
8779 
8780  // For the x derivatives, differentiate the terms of the expression:
8781  // \sum_{k=0}^p \binom{p}{k} l3^k
8782  // \sum_{j=0}^{p-k} \binom{p-k}{j} l2^j
8783  // \sum_{i=0}^{p-k-j} \binom{p-k-j}{i} l1^i l4^{p-k-j-i}
8784  const int *bp = Poly_1D::Binom(p);
8785  double l3k = 1.;
8786  for (int o = 0, k = 0; k <= p; k++)
8787  {
8788  const int *bpk = Poly_1D::Binom(p - k);
8789  const double ek = bp[k]*l3k;
8790  double l2j = 1.;
8791  for (int j = 0; j <= p - k; j++)
8792  {
8793  Poly_1D::CalcDBinomTerms(p - k - j, l1, l4, dshape_1d);
8794  double ekj = ek*bpk[j]*l2j;
8795  for (int i = 0; i <= p - k - j; i++)
8796  {
8797  dshape(o++,0) = dshape_1d(i)*ekj;
8798  }
8799  l2j *= l2;
8800  }
8801  l3k *= l3;
8802  }
8803  // For the y derivatives, differentiate the terms of the expression:
8804  // \sum_{k=0}^p \binom{p}{k} l3^k
8805  // \sum_{i=0}^{p-k} \binom{p-k}{i} l1^i
8806  // \sum_{j=0}^{p-k-i} \binom{p-k-i}{j} l2^j l4^{p-k-j-i}
8807  l3k = 1.;
8808  for (int ok = 0, k = 0; k <= p; k++)
8809  {
8810  const int *bpk = Poly_1D::Binom(p - k);
8811  const double ek = bp[k]*l3k;
8812  double l1i = 1.;
8813  for (int i = 0; i <= p - k; i++)
8814  {
8815  Poly_1D::CalcDBinomTerms(p - k - i, l2, l4, dshape_1d);
8816  double eki = ek*bpk[i]*l1i;
8817  int o = ok + i;
8818  for (int j = 0; j <= p - k - i; j++)
8819  {
8820  dshape(o,1) = dshape_1d(j)*eki;
8821  o += p - k - j + 1;
8822  }
8823  l1i *= l1;
8824  }
8825  l3k *= l3;
8826  ok += ((p - k + 2)*(p - k + 1))/2;
8827  }
8828  // For the z derivatives, differentiate the terms of the expression:
8829  // \sum_{j=0}^p \binom{p}{j} l2^j
8830  // \sum_{i=0}^{p-j} \binom{p-j}{i} l1^i
8831  // \sum_{k=0}^{p-j-i} \binom{p-j-i}{k} l3^k l4^{p-k-j-i}
8832  double l2j = 1.;
8833  for (int j = 0; j <= p; j++)
8834  {
8835  const int *bpj = Poly_1D::Binom(p - j);
8836  const double ej = bp[j]*l2j;
8837  double l1i = 1.;
8838  for (int i = 0; i <= p - j; i++)
8839  {
8840  Poly_1D::CalcDBinomTerms(p - j - i, l3, l4, dshape_1d);
8841  double eji = ej*bpj[i]*l1i;
8842  int m = ((p + 2)*(p + 1))/2;
8843  int n = ((p - j + 2)*(p - j + 1))/2;
8844  for (int o = i, k = 0; k <= p - j - i; k++)
8845  {
8846  // m = ((p - k + 2)*(p - k + 1))/2;
8847  // n = ((p - k - j + 2)*(p - k - j + 1))/2;
8848  o += m;
8849  dshape(o - n,2) = dshape_1d(k)*eji;
8850  m -= p - k + 1;
8851  n -= p - k - j + 1;
8852  }
8853  l1i *= l1;
8854  }
8855  l2j *= l2;
8856  }
8857 }
8858 
8859 void L2Pos_TetrahedronElement::ProjectDelta(int vertex, Vector &dofs) const
8860 {
8861  dofs = 0.0;
8862  switch (vertex)
8863  {
8864  case 0: dofs[0] = 1.0; break;
8865  case 1: dofs[Order] = 1.0; break;
8866  case 2: dofs[(Order*(Order+3))/2] = 1.0; break;
8867  case 3: dofs[Dof-1] = 1.0; break;
8868  }
8869 }
8870 
8871 
8872 const double RT_QuadrilateralElement::nk[8] =
8873 { 0., -1., 1., 0., 0., 1., -1., 0. };
8874 
8876  : VectorFiniteElement(2, Geometry::SQUARE, 2*(p + 1)*(p + 2), p + 1,
8877  H_DIV, FunctionSpace::Qk),
8878  cbasis1d(poly1d.ClosedBasis(p + 1)), obasis1d(poly1d.OpenBasis(p)),
8879  dof_map(Dof), dof2nk(Dof)
8880 {
8881  const double *cp = poly1d.ClosedPoints(p + 1);
8882  const double *op = poly1d.OpenPoints(p);
8883  const int dof2 = Dof/2;
8884 
8885 #ifndef MFEM_THREAD_SAFE
8886  shape_cx.SetSize(p + 2);
8887  shape_ox.SetSize(p + 1);
8888  shape_cy.SetSize(p + 2);
8889  shape_oy.SetSize(p + 1);
8890  dshape_cx.SetSize(p + 2);
8891  dshape_cy.SetSize(p + 2);
8892 #endif
8893 
8894  // edges
8895  int o = 0;
8896  for (int i = 0; i <= p; i++) // (0,1)
8897  {
8898  dof_map[1*dof2 + i + 0*(p + 1)] = o++;
8899  }
8900  for (int i = 0; i <= p; i++) // (1,2)
8901  {
8902  dof_map[0*dof2 + (p + 1) + i*(p + 2)] = o++;
8903  }
8904  for (int i = 0; i <= p; i++) // (2,3)
8905  {
8906  dof_map[1*dof2 + (p - i) + (p + 1)*(p + 1)] = o++;
8907  }
8908  for (int i = 0; i <= p; i++) // (3,0)
8909  {
8910  dof_map[0*dof2 + 0 + (p - i)*(p + 2)] = o++;
8911  }
8912 
8913  // interior
8914  for (int j = 0; j <= p; j++) // x-components
8915  for (int i = 1; i <= p; i++)
8916  {
8917  dof_map[0*dof2 + i + j*(p + 2)] = o++;
8918  }
8919  for (int j = 1; j <= p; j++) // y-components
8920  for (int i = 0; i <= p; i++)
8921  {
8922  dof_map[1*dof2 + i + j*(p + 1)] = o++;
8923  }
8924 
8925  // dof orientations
8926  // x-components
8927  for (int j = 0; j <= p; j++)
8928  for (int i = 0; i <= p/2; i++)
8929  {
8930  int idx = 0*dof2 + i + j*(p + 2);
8931  dof_map[idx] = -1 - dof_map[idx];
8932  }
8933  if (p%2 == 1)
8934  for (int j = p/2 + 1; j <= p; j++)
8935  {
8936  int idx = 0*dof2 + (p/2 + 1) + j*(p + 2);
8937  dof_map[idx] = -1 - dof_map[idx];
8938  }
8939  // y-components
8940  for (int j = 0; j <= p/2; j++)
8941  for (int i = 0; i <= p; i++)
8942  {
8943  int idx = 1*dof2 + i + j*(p + 1);
8944  dof_map[idx] = -1 - dof_map[idx];
8945  }
8946  if (p%2 == 1)
8947  for (int i = 0; i <= p/2; i++)
8948  {
8949  int idx = 1*dof2 + i + (p/2 + 1)*(p + 1);
8950  dof_map[idx] = -1 - dof_map[idx];
8951  }
8952 
8953  o = 0;
8954  for (int j = 0; j <= p; j++)
8955  for (int i = 0; i <= p + 1; i++)
8956  {
8957  int idx;
8958  if ((idx = dof_map[o++]) < 0)
8959  {
8960  idx = -1 - idx;
8961  dof2nk[idx] = 3;
8962  }
8963  else
8964  {
8965  dof2nk[idx] = 1;
8966  }
8967  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
8968  }
8969  for (int j = 0; j <= p + 1; j++)
8970  for (int i = 0; i <= p; i++)
8971  {
8972  int idx;
8973  if ((idx = dof_map[o++]) < 0)
8974  {
8975  idx = -1 - idx;
8976  dof2nk[idx] = 0;
8977  }
8978  else
8979  {
8980  dof2nk[idx] = 2;
8981  }
8982  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
8983  }
8984 }
8985 
8987  DenseMatrix &shape) const
8988 {
8989  const int pp1 = Order;
8990 
8991 #ifdef MFEM_THREAD_SAFE
8992  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
8993 #endif
8994 
8995  cbasis1d.Eval(ip.x, shape_cx);
8996  obasis1d.Eval(ip.x, shape_ox);
8997  cbasis1d.Eval(ip.y, shape_cy);
8998  obasis1d.Eval(ip.y, shape_oy);
8999 
9000  int o = 0;
9001  for (int j = 0; j < pp1; j++)
9002  for (int i = 0; i <= pp1; i++)
9003  {
9004  int idx, s;
9005  if ((idx = dof_map[o++]) < 0)
9006  {
9007  idx = -1 - idx, s = -1;
9008  }
9009  else
9010  {
9011  s = +1;
9012  }
9013  shape(idx,0) = s*shape_cx(i)*shape_oy(j);
9014  shape(idx,1) = 0.;
9015  }
9016  for (int j = 0; j <= pp1; j++)
9017  for (int i = 0; i < pp1; i++)
9018  {
9019  int idx, s;
9020  if ((idx = dof_map[o++]) < 0)
9021  {
9022  idx = -1 - idx, s = -1;
9023  }
9024  else
9025  {
9026  s = +1;
9027  }
9028  shape(idx,0) = 0.;
9029  shape(idx,1) = s*shape_ox(i)*shape_cy(j);
9030  }
9031 }
9032 
9034  Vector &divshape) const
9035 {
9036  const int pp1 = Order;
9037 
9038 #ifdef MFEM_THREAD_SAFE
9039  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9040  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1);
9041 #endif
9042 
9043  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9044  obasis1d.Eval(ip.x, shape_ox);
9045  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9046  obasis1d.Eval(ip.y, shape_oy);
9047 
9048  int o = 0;
9049  for (int j = 0; j < pp1; j++)
9050  for (int i = 0; i <= pp1; i++)
9051  {
9052  int idx, s;
9053  if ((idx = dof_map[o++]) < 0)
9054  {
9055  idx = -1 - idx, s = -1;
9056  }
9057  else
9058  {
9059  s = +1;
9060  }
9061  divshape(idx) = s*dshape_cx(i)*shape_oy(j);
9062  }
9063  for (int j = 0; j <= pp1; j++)
9064  for (int i = 0; i < pp1; i++)
9065  {
9066  int idx, s;
9067  if ((idx = dof_map[o++]) < 0)
9068  {
9069  idx = -1 - idx, s = -1;
9070  }
9071  else
9072  {
9073  s = +1;
9074  }
9075  divshape(idx) = s*shape_ox(i)*dshape_cy(j);
9076  }
9077 }
9078 
9079 
9080 const double RT_HexahedronElement::nk[18] =
9081 { 0.,0.,-1., 0.,-1.,0., 1.,0.,0., 0.,1.,0., -1.,0.,0., 0.,0.,1. };
9082 
9084  : VectorFiniteElement(3, Geometry::CUBE, 3*(p + 1)*(p + 1)*(p + 2), p + 1,
9085  H_DIV, FunctionSpace::Qk),
9086  cbasis1d(poly1d.ClosedBasis(p + 1)), obasis1d(poly1d.OpenBasis(p)),
9087  dof_map(Dof), dof2nk(Dof)
9088 {
9089  const double *cp = poly1d.ClosedPoints(p + 1);
9090  const double *op = poly1d.OpenPoints(p);
9091  const int dof3 = Dof/3;
9092 
9093 #ifndef MFEM_THREAD_SAFE
9094  shape_cx.SetSize(p + 2);
9095  shape_ox.SetSize(p + 1);
9096  shape_cy.SetSize(p + 2);
9097  shape_oy.SetSize(p + 1);
9098  shape_cz.SetSize(p + 2);
9099  shape_oz.SetSize(p + 1);
9100  dshape_cx.SetSize(p + 2);
9101  dshape_cy.SetSize(p + 2);
9102  dshape_cz.SetSize(p + 2);
9103 #endif
9104 
9105  // faces
9106  int o = 0;
9107  for (int j = 0; j <= p; j++) // (3,2,1,0) -- bottom
9108  for (int i = 0; i <= p; i++)
9109  {
9110  dof_map[2*dof3 + i + ((p - j) + 0*(p + 1))*(p + 1)] = o++;
9111  }
9112  for (int j = 0; j <= p; j++) // (0,1,5,4) -- front
9113  for (int i = 0; i <= p; i++)
9114  {
9115  dof_map[1*dof3 + i + (0 + j*(p + 2))*(p + 1)] = o++;
9116  }
9117  for (int j = 0; j <= p; j++) // (1,2,6,5) -- right
9118  for (int i = 0; i <= p; i++)
9119  {
9120  dof_map[0*dof3 + (p + 1) + (i + j*(p + 1))*(p + 2)] = o++;
9121  }
9122  for (int j = 0; j <= p; j++) // (2,3,7,6) -- back
9123  for (int i = 0; i <= p; i++)
9124  {
9125  dof_map[1*dof3 + (p - i) + ((p + 1) + j*(p + 2))*(p + 1)] = o++;
9126  }
9127  for (int j = 0; j <= p; j++) // (3,0,4,7) -- left
9128  for (int i = 0; i <= p; i++)
9129  {
9130  dof_map[0*dof3 + 0 + ((p - i) + j*(p + 1))*(p + 2)] = o++;
9131  }
9132  for (int j = 0; j <= p; j++) // (4,5,6,7) -- top
9133  for (int i = 0; i <= p; i++)
9134  {
9135  dof_map[2*dof3 + i + (j + (p + 1)*(p + 1))*(p + 1)] = o++;
9136  }
9137 
9138  // interior
9139  // x-components
9140  for (int k = 0; k <= p; k++)
9141  for (int j = 0; j <= p; j++)
9142  for (int i = 1; i <= p; i++)
9143  {
9144  dof_map[0*dof3 + i + (j + k*(p + 1))*(p + 2)] = o++;
9145  }
9146  // y-components
9147  for (int k = 0; k <= p; k++)
9148  for (int j = 1; j <= p; j++)
9149  for (int i = 0; i <= p; i++)
9150  {
9151  dof_map[1*dof3 + i + (j + k*(p + 2))*(p + 1)] = o++;
9152  }
9153  // z-components
9154  for (int k = 1; k <= p; k++)
9155  for (int j = 0; j <= p; j++)
9156  for (int i = 0; i <= p; i++)
9157  {
9158  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
9159  }
9160 
9161  // dof orientations
9162  // for odd p, do not change the orientations in the mid-planes
9163  // {i = p/2 + 1}, {j = p/2 + 1}, {k = p/2 + 1} in the x, y, z-components
9164  // respectively.
9165  // x-components
9166  for (int k = 0; k <= p; k++)
9167  for (int j = 0; j <= p; j++)
9168  for (int i = 0; i <= p/2; i++)
9169  {
9170  int idx = 0*dof3 + i + (j + k*(p + 1))*(p + 2);
9171  dof_map[idx] = -1 - dof_map[idx];
9172  }
9173  // y-components
9174  for (int k = 0; k <= p; k++)
9175  for (int j = 0; j <= p/2; j++)
9176  for (int i = 0; i <= p; i++)
9177  {
9178  int idx = 1*dof3 + i + (j + k*(p + 2))*(p + 1);
9179  dof_map[idx] = -1 - dof_map[idx];
9180  }
9181  // z-components
9182  for (int k = 0; k <= p/2; k++)
9183  for (int j = 0; j <= p; j++)
9184  for (int i = 0; i <= p; i++)
9185  {
9186  int idx = 2*dof3 + i + (j + k*(p + 1))*(p + 1);
9187  dof_map[idx] = -1 - dof_map[idx];
9188  }
9189 
9190  o = 0;
9191  // x-components
9192  for (int k = 0; k <= p; k++)
9193  for (int j = 0; j <= p; j++)
9194  for (int i = 0; i <= p + 1; i++)
9195  {
9196  int idx;
9197  if ((idx = dof_map[o++]) < 0)
9198  {
9199  idx = -1 - idx;
9200  dof2nk[idx] = 4;
9201  }
9202  else
9203  {
9204  dof2nk[idx] = 2;
9205  }
9206  Nodes.IntPoint(idx).Set3(cp[i], op[j], op[k]);
9207  }
9208  // y-components
9209  for (int k = 0; k <= p; k++)
9210  for (int j = 0; j <= p + 1; j++)
9211  for (int i = 0; i <= p; i++)
9212  {
9213  int idx;
9214  if ((idx = dof_map[o++]) < 0)
9215  {
9216  idx = -1 - idx;
9217  dof2nk[idx] = 1;
9218  }
9219  else
9220  {
9221  dof2nk[idx] = 3;
9222  }
9223  Nodes.IntPoint(idx).Set3(op[i], cp[j], op[k]);
9224  }
9225  // z-components
9226  for (int k = 0; k <= p + 1; k++)
9227  for (int j = 0; j <= p; j++)
9228  for (int i = 0; i <= p; i++)
9229  {
9230  int idx;
9231  if ((idx = dof_map[o++]) < 0)
9232  {
9233  idx = -1 - idx;
9234  dof2nk[idx] = 0;
9235  }
9236  else
9237  {
9238  dof2nk[idx] = 5;
9239  }
9240  Nodes.IntPoint(idx).Set3(op[i], op[j], cp[k]);
9241  }
9242 }
9243 
9245  DenseMatrix &shape) const
9246 {
9247  const int pp1 = Order;
9248 
9249 #ifdef MFEM_THREAD_SAFE
9250  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9251  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9252 #endif
9253 
9254  cbasis1d.Eval(ip.x, shape_cx);
9255  obasis1d.Eval(ip.x, shape_ox);
9256  cbasis1d.Eval(ip.y, shape_cy);
9257  obasis1d.Eval(ip.y, shape_oy);
9258  cbasis1d.Eval(ip.z, shape_cz);
9259  obasis1d.Eval(ip.z, shape_oz);
9260 
9261  int o = 0;
9262  // x-components
9263  for (int k = 0; k < pp1; k++)
9264  for (int j = 0; j < pp1; j++)
9265  for (int i = 0; i <= pp1; i++)
9266  {
9267  int idx, s;
9268  if ((idx = dof_map[o++]) < 0)
9269  {
9270  idx = -1 - idx, s = -1;
9271  }
9272  else
9273  {
9274  s = +1;
9275  }
9276  shape(idx,0) = s*shape_cx(i)*shape_oy(j)*shape_oz(k);
9277  shape(idx,1) = 0.;
9278  shape(idx,2) = 0.;
9279  }
9280  // y-components
9281  for (int k = 0; k < pp1; k++)
9282  for (int j = 0; j <= pp1; j++)
9283  for (int i = 0; i < pp1; i++)
9284  {
9285  int idx, s;
9286  if ((idx = dof_map[o++]) < 0)
9287  {
9288  idx = -1 - idx, s = -1;
9289  }
9290  else
9291  {
9292  s = +1;
9293  }
9294  shape(idx,0) = 0.;
9295  shape(idx,1) = s*shape_ox(i)*shape_cy(j)*shape_oz(k);
9296  shape(idx,2) = 0.;
9297  }
9298  // z-components
9299  for (int k = 0; k <= pp1; k++)
9300  for (int j = 0; j < pp1; j++)
9301  for (int i = 0; i < pp1; i++)
9302  {
9303  int idx, s;
9304  if ((idx = dof_map[o++]) < 0)
9305  {
9306  idx = -1 - idx, s = -1;
9307  }
9308  else
9309  {
9310  s = +1;
9311  }
9312  shape(idx,0) = 0.;
9313  shape(idx,1) = 0.;
9314  shape(idx,2) = s*shape_ox(i)*shape_oy(j)*shape_cz(k);
9315  }
9316 }
9317 
9319  Vector &divshape) const
9320 {
9321  const int pp1 = Order;
9322 
9323 #ifdef MFEM_THREAD_SAFE
9324  Vector shape_cx(pp1 + 1), shape_ox(pp1), shape_cy(pp1 + 1), shape_oy(pp1);
9325  Vector shape_cz(pp1 + 1), shape_oz(pp1);
9326  Vector dshape_cx(pp1 + 1), dshape_cy(pp1 + 1), dshape_cz(pp1 + 1);
9327 #endif
9328 
9329  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
9330  obasis1d.Eval(ip.x, shape_ox);
9331  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
9332  obasis1d.Eval(ip.y, shape_oy);
9333  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
9334  obasis1d.Eval(ip.z, shape_oz);
9335 
9336  int o = 0;
9337  // x-components
9338  for (int k = 0; k < pp1; k++)
9339  for (int j = 0; j < pp1; j++)
9340  for (int i = 0; i <= pp1; i++)
9341  {
9342  int idx, s;
9343  if ((idx = dof_map[o++]) < 0)
9344  {
9345  idx = -1 - idx, s = -1;
9346  }
9347  else
9348  {
9349  s = +1;
9350  }
9351  divshape(idx) = s*dshape_cx(i)*shape_oy(j)*shape_oz(k);
9352  }
9353  // y-components
9354  for (int k = 0; k < pp1; k++)
9355  for (int j = 0; j <= pp1; j++)
9356  for (int i = 0; i < pp1; i++)
9357  {
9358  int idx, s;
9359  if ((idx = dof_map[o++]) < 0)
9360  {
9361  idx = -1 - idx, s = -1;
9362  }
9363  else
9364  {
9365  s = +1;
9366  }
9367  divshape(idx) = s*shape_ox(i)*dshape_cy(j)*shape_oz(k);
9368  }
9369  // z-components
9370  for (int k = 0; k <= pp1; k++)
9371  for (int j = 0; j < pp1; j++)
9372  for (int i = 0; i < pp1; i++)
9373  {
9374  int idx, s;
9375  if ((idx = dof_map[o++]) < 0)
9376  {
9377  idx = -1 - idx, s = -1;
9378  }
9379  else
9380  {
9381  s = +1;
9382  }
9383  divshape(idx) = s*shape_ox(i)*shape_oy(j)*dshape_cz(k);
9384  }
9385 }
9386 
9387 
9388 const double RT_TriangleElement::nk[6] =
9389 { 0., -1., 1., 1., -1., 0. };
9390 
9391 const double RT_TriangleElement::c = 1./3.;
9392 
9394  : VectorFiniteElement(2, Geometry::TRIANGLE, (p + 1)*(p + 3), p + 1,
9395  H_DIV, FunctionSpace::Pk), dof2nk(Dof)
9396 {
9397  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9398  const double *bop = poly1d.OpenPoints(p);
9399 
9400 #ifndef MFEM_THREAD_SAFE
9401  shape_x.SetSize(p + 1);
9402  shape_y.SetSize(p + 1);
9403  shape_l.SetSize(p + 1);
9404  dshape_x.SetSize(p + 1);
9405  dshape_y.SetSize(p + 1);
9406  dshape_l.SetSize(p + 1);
9407  u.SetSize(Dof, Dim);
9408  divu.SetSize(Dof);
9409 #else
9410  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9411 #endif
9412 
9413  // edges
9414  int o = 0;
9415  for (int i = 0; i <= p; i++) // (0,1)
9416  {
9417  Nodes.IntPoint(o).Set2(bop[i], 0.);
9418  dof2nk[o++] = 0;
9419  }
9420  for (int i = 0; i <= p; i++) // (1,2)
9421  {
9422  Nodes.IntPoint(o).Set2(bop[p-i], bop[i]);
9423  dof2nk[o++] = 1;
9424  }
9425  for (int i = 0; i <= p; i++) // (2,0)
9426  {
9427  Nodes.IntPoint(o).Set2(0., bop[p-i]);
9428  dof2nk[o++] = 2;
9429  }
9430 
9431  // interior
9432  for (int j = 0; j < p; j++)
9433  for (int i = 0; i + j < p; i++)
9434  {
9435  double w = iop[i] + iop[j] + iop[p-1-i-j];
9436  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9437  dof2nk[o++] = 0;
9438  Nodes.IntPoint(o).Set2(iop[i]/w, iop[j]/w);
9439  dof2nk[o++] = 2;
9440  }
9441 
9442  DenseMatrix T(Dof);
9443  for (int k = 0; k < Dof; k++)
9444  {
9445  const IntegrationPoint &ip = Nodes.IntPoint(k);
9446  poly1d.CalcBasis(p, ip.x, shape_x);
9447  poly1d.CalcBasis(p, ip.y, shape_y);
9448  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9449  const double *n_k = nk + 2*dof2nk[k];
9450 
9451  o = 0;
9452  for (int j = 0; j <= p; j++)
9453  for (int i = 0; i + j <= p; i++)
9454  {
9455  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9456  T(o++, k) = s*n_k[0];
9457  T(o++, k) = s*n_k[1];
9458  }
9459  for (int i = 0; i <= p; i++)
9460  {
9461  double s = shape_x(i)*shape_y(p-i);
9462  T(o++, k) = s*((ip.x - c)*n_k[0] + (ip.y - c)*n_k[1]);
9463  }
9464  }
9465 
9466  Ti.Factor(T);
9467  // cout << "RT_TriangleElement(" << p << ") : "; Ti.TestInversion();
9468 }
9469 
9471  DenseMatrix &shape) const
9472 {
9473  const int p = Order - 1;
9474 
9475 #ifdef MFEM_THREAD_SAFE
9476  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9477  DenseMatrix u(Dof, Dim);
9478 #endif
9479 
9480  poly1d.CalcBasis(p, ip.x, shape_x);
9481  poly1d.CalcBasis(p, ip.y, shape_y);
9482  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l);
9483 
9484  int o = 0;
9485  for (int j = 0; j <= p; j++)
9486  for (int i = 0; i + j <= p; i++)
9487  {
9488  double s = shape_x(i)*shape_y(j)*shape_l(p-i-j);
9489  u(o,0) = s; u(o,1) = 0; o++;
9490  u(o,0) = 0; u(o,1) = s; o++;
9491  }
9492  for (int i = 0; i <= p; i++)
9493  {
9494  double s = shape_x(i)*shape_y(p-i);
9495  u(o,0) = (ip.x - c)*s;
9496  u(o,1) = (ip.y - c)*s;
9497  o++;
9498  }
9499 
9500  Ti.Mult(u, shape);
9501 }
9502 
9504  Vector &divshape) const
9505 {
9506  const int p = Order - 1;
9507 
9508 #ifdef MFEM_THREAD_SAFE
9509  Vector shape_x(p + 1), shape_y(p + 1), shape_l(p + 1);
9510  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_l(p + 1);
9511  Vector divu(Dof);
9512 #endif
9513 
9514  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9515  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9516  poly1d.CalcBasis(p, 1. - ip.x - ip.y, shape_l, dshape_l);
9517 
9518  int o = 0;
9519  for (int j = 0; j <= p; j++)
9520  for (int i = 0; i + j <= p; i++)
9521  {
9522  int k = p - i - j;
9523  divu(o++) = (dshape_x(i)*shape_l(k) -
9524  shape_x(i)*dshape_l(k))*shape_y(j);
9525  divu(o++) = (dshape_y(j)*shape_l(k) -
9526  shape_y(j)*dshape_l(k))*shape_x(i);
9527  }
9528  for (int i = 0; i <= p; i++)
9529  {
9530  int j = p - i;
9531  divu(o++) = ((shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j) +
9532  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i));
9533  }
9534 
9535  Ti.Mult(divu, divshape);
9536 }
9537 
9538 
9539 const double RT_TetrahedronElement::nk[12] =
9540 { 1,1,1, -1,0,0, 0,-1,0, 0,0,-1 };
9541 // { .5,.5,.5, -.5,0,0, 0,-.5,0, 0,0,-.5}; // n_F |F|
9542 
9543 const double RT_TetrahedronElement::c = 1./4.;
9544 
9546  : VectorFiniteElement(3, Geometry::TETRAHEDRON, (p + 1)*(p + 2)*(p + 4)/2,
9547  p + 1, H_DIV, FunctionSpace::Pk), dof2nk(Dof)
9548 {
9549  const double *iop = (p > 0) ? poly1d.OpenPoints(p - 1) : NULL;
9550  const double *bop = poly1d.OpenPoints(p);
9551 
9552 #ifndef MFEM_THREAD_SAFE
9553  shape_x.SetSize(p + 1);
9554  shape_y.SetSize(p + 1);
9555  shape_z.SetSize(p + 1);
9556  shape_l.SetSize(p + 1);
9557  dshape_x.SetSize(p + 1);
9558  dshape_y.SetSize(p + 1);
9559  dshape_z.SetSize(p + 1);
9560  dshape_l.SetSize(p + 1);
9561  u.SetSize(Dof, Dim);
9562  divu.SetSize(Dof);
9563 #else
9564  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9565 #endif
9566 
9567  int o = 0;
9568  // faces (see Mesh::GenerateFaces in mesh/mesh.cpp,
9569  // the constructor of H1_TetrahedronElement)
9570  for (int j = 0; j <= p; j++)
9571  for (int i = 0; i + j <= p; i++) // (1,2,3)
9572  {
9573  double w = bop[i] + bop[j] + bop[p-i-j];
9574  Nodes.IntPoint(o).Set3(bop[p-i-j]/w, bop[i]/w, bop[j]/w);
9575  dof2nk[o++] = 0;
9576  }
9577  for (int j = 0; j <= p; j++)
9578  for (int i = 0; i + j <= p; i++) // (0,3,2)
9579  {
9580  double w = bop[i] + bop[j] + bop[p-i-j];
9581  Nodes.IntPoint(o).Set3(0., bop[j]/w, bop[i]/w);
9582  dof2nk[o++] = 1;
9583  }
9584  for (int j = 0; j <= p; j++)
9585  for (int i = 0; i + j <= p; i++) // (0,1,3)
9586  {
9587  double w = bop[i] + bop[j] + bop[p-i-j];
9588  Nodes.IntPoint(o).Set3(bop[i]/w, 0., bop[j]/w);
9589  dof2nk[o++] = 2;
9590  }
9591  for (int j = 0; j <= p; j++)
9592  for (int i = 0; i + j <= p; i++) // (0,2,1)
9593  {
9594  double w = bop[i] + bop[j] + bop[p-i-j];
9595  Nodes.IntPoint(o).Set3(bop[j]/w, bop[i]/w, 0.);
9596  dof2nk[o++] = 3;
9597  }
9598 
9599  // interior
9600  for (int k = 0; k < p; k++)
9601  for (int j = 0; j + k < p; j++)
9602  for (int i = 0; i + j + k < p; i++)
9603  {
9604  double w = iop[i] + iop[j] + iop[k] + iop[p-1-i-j-k];
9605  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9606  dof2nk[o++] = 1;
9607  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9608  dof2nk[o++] = 2;
9609  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
9610  dof2nk[o++] = 3;
9611  }
9612 
9613  DenseMatrix T(Dof);
9614  for (int m = 0; m < Dof; m++)
9615  {
9616  const IntegrationPoint &ip = Nodes.IntPoint(m);
9617  poly1d.CalcBasis(p, ip.x, shape_x);
9618  poly1d.CalcBasis(p, ip.y, shape_y);
9619  poly1d.CalcBasis(p, ip.z, shape_z);
9620  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9621  const double *nm = nk + 3*dof2nk[m];
9622 
9623  o = 0;
9624  for (int k = 0; k <= p; k++)
9625  for (int j = 0; j + k <= p; j++)
9626  for (int i = 0; i + j + k <= p; i++)
9627  {
9628  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9629  T(o++, m) = s * nm[0];
9630  T(o++, m) = s * nm[1];
9631  T(o++, m) = s * nm[2];
9632  }
9633  for (int j = 0; j <= p; j++)
9634  for (int i = 0; i + j <= p; i++)
9635  {
9636  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9637  T(o++, m) = s*((ip.x - c)*nm[0] + (ip.y - c)*nm[1] +
9638  (ip.z - c)*nm[2]);
9639  }
9640  }
9641 
9642  Ti.Factor(T);
9643  // cout << "RT_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
9644 }
9645 
9647  DenseMatrix &shape) const
9648 {
9649  const int p = Order - 1;
9650 
9651 #ifdef MFEM_THREAD_SAFE
9652  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9653  DenseMatrix u(Dof, Dim);
9654 #endif
9655 
9656  poly1d.CalcBasis(p, ip.x, shape_x);
9657  poly1d.CalcBasis(p, ip.y, shape_y);
9658  poly1d.CalcBasis(p, ip.z, shape_z);
9659  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l);
9660 
9661  int o = 0;
9662  for (int k = 0; k <= p; k++)
9663  for (int j = 0; j + k <= p; j++)
9664  for (int i = 0; i + j + k <= p; i++)
9665  {
9666  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(p-i-j-k);
9667  u(o,0) = s; u(o,1) = 0; u(o,2) = 0; o++;
9668  u(o,0) = 0; u(o,1) = s; u(o,2) = 0; o++;
9669  u(o,0) = 0; u(o,1) = 0; u(o,2) = s; o++;
9670  }
9671  for (int j = 0; j <= p; j++)
9672  for (int i = 0; i + j <= p; i++)
9673  {
9674  double s = shape_x(i)*shape_y(j)*shape_z(p-i-j);
9675  u(o,0) = (ip.x - c)*s; u(o,1) = (ip.y - c)*s; u(o,2) = (ip.z - c)*s;
9676  o++;
9677  }
9678 
9679  Ti.Mult(u, shape);
9680 }
9681 
9683  Vector &divshape) const
9684 {
9685  const int p = Order - 1;
9686 
9687 #ifdef MFEM_THREAD_SAFE
9688  Vector shape_x(p + 1), shape_y(p + 1), shape_z(p + 1), shape_l(p + 1);
9689  Vector dshape_x(p + 1), dshape_y(p + 1), dshape_z(p + 1), dshape_l(p + 1);
9690  Vector divu(Dof);
9691 #endif
9692 
9693  poly1d.CalcBasis(p, ip.x, shape_x, dshape_x);
9694  poly1d.CalcBasis(p, ip.y, shape_y, dshape_y);
9695  poly1d.CalcBasis(p, ip.z, shape_z, dshape_z);
9696  poly1d.CalcBasis(p, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
9697 
9698  int o = 0;
9699  for (int k = 0; k <= p; k++)
9700  for (int j = 0; j + k <= p; j++)
9701  for (int i = 0; i + j + k <= p; i++)
9702  {
9703  int l = p - i - j - k;
9704  divu(o++) = (dshape_x(i)*shape_l(l) -
9705  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
9706  divu(o++) = (dshape_y(j)*shape_l(l) -
9707  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
9708  divu(o++) = (dshape_z(k)*shape_l(l) -
9709  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
9710  }
9711  for (int j = 0; j <= p; j++)
9712  for (int i = 0; i + j <= p; i++)
9713  {
9714  int k = p - i - j;
9715  divu(o++) =
9716  (shape_x(i) + (ip.x - c)*dshape_x(i))*shape_y(j)*shape_z(k) +
9717  (shape_y(j) + (ip.y - c)*dshape_y(j))*shape_x(i)*shape_z(k) +
9718  (shape_z(k) + (ip.z - c)*dshape_z(k))*shape_x(i)*shape_y(j);
9719  }
9720 
9721  Ti.Mult(divu, divshape);
9722 }
9723 
9724 
9725 const double ND_HexahedronElement::tk[18] =
9726 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,0.,0., 0.,-1.,0., 0.,0.,-1. };
9727 
9729  : VectorFiniteElement(3, Geometry::CUBE, 3*p*(p + 1)*(p + 1), p,
9730  H_CURL, FunctionSpace::Qk),
9731  cbasis1d(poly1d.ClosedBasis(p)), obasis1d(poly1d.OpenBasis(p - 1)),
9732  dof_map(Dof), dof2tk(Dof)
9733 {
9734  const double *cp = poly1d.ClosedPoints(p);
9735  const double *op = poly1d.OpenPoints(p - 1);
9736  const int dof3 = Dof/3;
9737 
9738 #ifndef MFEM_THREAD_SAFE
9739  shape_cx.SetSize(p + 1);
9740  shape_ox.SetSize(p);
9741  shape_cy.SetSize(p + 1);
9742  shape_oy.SetSize(p);
9743  shape_cz.SetSize(p + 1);
9744  shape_oz.SetSize(p);
9745  dshape_cx.SetSize(p + 1);
9746  dshape_cy.SetSize(p + 1);
9747  dshape_cz.SetSize(p + 1);
9748 #endif
9749 
9750  // edges
9751  int o = 0;
9752  for (int i = 0; i < p; i++) // (0,1)
9753  {
9754  dof_map[0*dof3 + i + (0 + 0*(p + 1))*p] = o++;
9755  }
9756  for (int i = 0; i < p; i++) // (1,2)
9757  {
9758  dof_map[1*dof3 + p + (i + 0*p)*(p + 1)] = o++;
9759  }
9760  for (int i = 0; i < p; i++) // (3,2)
9761  {
9762  dof_map[0*dof3 + i + (p + 0*(p + 1))*p] = o++;
9763  }
9764  for (int i = 0; i < p; i++) // (0,3)
9765  {
9766  dof_map[1*dof3 + 0 + (i + 0*p)*(p + 1)] = o++;
9767  }
9768  for (int i = 0; i < p; i++) // (4,5)
9769  {
9770  dof_map[0*dof3 + i + (0 + p*(p + 1))*p] = o++;
9771  }
9772  for (int i = 0; i < p; i++) // (5,6)
9773  {
9774  dof_map[1*dof3 + p + (i + p*p)*(p + 1)] = o++;
9775  }
9776  for (int i = 0; i < p; i++) // (7,6)
9777  {
9778  dof_map[0*dof3 + i + (p + p*(p + 1))*p] = o++;
9779  }
9780  for (int i = 0; i < p; i++) // (4,7)
9781  {
9782  dof_map[1*dof3 + 0 + (i + p*p)*(p + 1)] = o++;
9783  }
9784  for (int i = 0; i < p; i++) // (0,4)
9785  {
9786  dof_map[2*dof3 + 0 + (0 + i*(p + 1))*(p + 1)] = o++;
9787  }
9788  for (int i = 0; i < p; i++) // (1,5)
9789  {
9790  dof_map[2*dof3 + p + (0 + i*(p + 1))*(p + 1)] = o++;
9791  }
9792  for (int i = 0; i < p; i++) // (2,6)
9793  {
9794  dof_map[2*dof3 + p + (p + i*(p + 1))*(p + 1)] = o++;
9795  }
9796  for (int i = 0; i < p; i++) // (3,7)
9797  {
9798  dof_map[2*dof3 + 0 + (p + i*(p + 1))*(p + 1)] = o++;
9799  }
9800 
9801  // faces
9802  // (3,2,1,0) -- bottom
9803  for (int j = 1; j < p; j++) // x - components
9804  for (int i = 0; i < p; i++)
9805  {
9806  dof_map[0*dof3 + i + ((p - j) + 0*(p + 1))*p] = o++;
9807  }
9808  for (int j = 0; j < p; j++) // y - components
9809  for (int i = 1; i < p; i++)
9810  {
9811  dof_map[1*dof3 + i + ((p - 1 - j) + 0*p)*(p + 1)] = -1 - (o++);
9812  }
9813  // (0,1,5,4) -- front
9814  for (int k = 1; k < p; k++) // x - components
9815  for (int i = 0; i < p; i++)
9816  {
9817  dof_map[0*dof3 + i + (0 + k*(p + 1))*p] = o++;
9818  }
9819  for (int k = 0; k < p; k++) // z - components
9820  for (int i = 1; i < p; i++ )
9821  {
9822  dof_map[2*dof3 + i + (0 + k*(p + 1))*(p + 1)] = o++;
9823  }
9824  // (1,2,6,5) -- right
9825  for (int k = 1; k < p; k++) // y - components
9826  for (int j = 0; j < p; j++)
9827  {
9828  dof_map[1*dof3 + p + (j + k*p)*(p + 1)] = o++;
9829  }
9830  for (int k = 0; k < p; k++) // z - components
9831  for (int j = 1; j < p; j++)
9832  {
9833  dof_map[2*dof3 + p + (j + k*(p + 1))*(p + 1)] = o++;
9834  }
9835  // (2,3,7,6) -- back
9836  for (int k = 1; k < p; k++) // x - components
9837  for (int i = 0; i < p; i++)
9838  {
9839  dof_map[0*dof3 + (p - 1 - i) + (p + k*(p + 1))*p] = -1 - (o++);
9840  }
9841  for (int k = 0; k < p; k++) // z - components
9842  for (int i = 1; i < p; i++)
9843  {
9844  dof_map[2*dof3 + (p - i) + (p + k*(p + 1))*(p + 1)] = o++;
9845  }
9846  // (3,0,4,7) -- left
9847  for (int k = 1; k < p; k++) // y - components
9848  for (int j = 0; j < p; j++)
9849  {
9850  dof_map[1*dof3 + 0 + ((p - 1 - j) + k*p)*(p + 1)] = -1 - (o++);
9851  }
9852  for (int k = 0; k < p; k++) // z - components
9853  for (int j = 1; j < p; j++)
9854  {
9855  dof_map[2*dof3 + 0 + ((p - j) + k*(p + 1))*(p + 1)] = o++;
9856  }
9857  // (4,5,6,7) -- top
9858  for (int j = 1; j < p; j++) // x - components
9859  for (int i = 0; i < p; i++)
9860  {
9861  dof_map[0*dof3 + i + (j + p*(p + 1))*p] = o++;
9862  }
9863  for (int j = 0; j < p; j++) // y - components
9864  for (int i = 1; i < p; i++)
9865  {
9866  dof_map[1*dof3 + i + (j + p*p)*(p + 1)] = o++;
9867  }
9868 
9869  // interior
9870  // x-components
9871  for (int k = 1; k < p; k++)
9872  for (int j = 1; j < p; j++)
9873  for (int i = 0; i < p; i++)
9874  {
9875  dof_map[0*dof3 + i + (j + k*(p + 1))*p] = o++;
9876  }
9877  // y-components
9878  for (int k = 1; k < p; k++)
9879  for (int j = 0; j < p; j++)
9880  for (int i = 1; i < p; i++)
9881  {
9882  dof_map[1*dof3 + i + (j + k*p)*(p + 1)] = o++;
9883  }
9884  // z-components
9885  for (int k = 0; k < p; k++)
9886  for (int j = 1; j < p; j++)
9887  for (int i = 1; i < p; i++)
9888  {
9889  dof_map[2*dof3 + i + (j + k*(p + 1))*(p + 1)] = o++;
9890  }
9891 
9892  // set dof2tk and Nodes
9893  o = 0;
9894  // x-components
9895  for (int k = 0; k <= p; k++)
9896  for (int j = 0; j <= p; j++)
9897  for (int i = 0; i < p; i++)
9898  {
9899  int idx;
9900  if ((idx = dof_map[o++]) < 0)
9901  {
9902  dof2tk[idx = -1 - idx] = 3;
9903  }
9904  else
9905  {
9906  dof2tk[idx] = 0;
9907  }
9908  Nodes.IntPoint(idx).Set3(op[i], cp[j], cp[k]);
9909  }
9910  // y-components
9911  for (int k = 0; k <= p; k++)
9912  for (int j = 0; j < p; j++)
9913  for (int i = 0; i <= p; i++)
9914  {
9915  int idx;
9916  if ((idx = dof_map[o++]) < 0)
9917  {
9918  dof2tk[idx = -1 - idx] = 4;
9919  }
9920  else
9921  {
9922  dof2tk[idx] = 1;
9923  }
9924  Nodes.IntPoint(idx).Set3(cp[i], op[j], cp[k]);
9925  }
9926  // z-components
9927  for (int k = 0; k < p; k++)
9928  for (int j = 0; j <= p; j++)
9929  for (int i = 0; i <= p; i++)
9930  {
9931  int idx;
9932  if ((idx = dof_map[o++]) < 0)
9933  {
9934  dof2tk[idx = -1 - idx] = 5;
9935  }
9936  else
9937  {
9938  dof2tk[idx] = 2;
9939  }
9940  Nodes.IntPoint(idx).Set3(cp[i], cp[j], op[k]);
9941  }
9942 }
9943 
9945  DenseMatrix &shape) const
9946 {
9947  const int p = Order;
9948 
9949 #ifdef MFEM_THREAD_SAFE
9950  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
9951  Vector shape_cz(p + 1), shape_oz(p);
9952 #endif
9953 
9954  cbasis1d.Eval(ip.x, shape_cx);
9955  obasis1d.Eval(ip.x, shape_ox);
9956  cbasis1d.Eval(ip.y, shape_cy);
9957  obasis1d.Eval(ip.y, shape_oy);
9958  cbasis1d.Eval(ip.z, shape_cz);
9959  obasis1d.Eval(ip.z, shape_oz);
9960 
9961  int o = 0;
9962  // x-components
9963  for (int k = 0; k <= p; k++)
9964  for (int j = 0; j <= p; j++)
9965  for (int i = 0; i < p; i++)
9966  {
9967  int idx, s;
9968  if ((idx = dof_map[o++]) < 0)
9969  {
9970  idx = -1 - idx, s = -1;
9971  }
9972  else
9973  {
9974  s = +1;
9975  }
9976  shape(idx,0) = s*shape_ox(i)*shape_cy(j)*shape_cz(k);
9977  shape(idx,1) = 0.;
9978  shape(idx,2) = 0.;
9979  }
9980  // y-components
9981  for (int k = 0; k <= p; k++)
9982  for (int j = 0; j < p; j++)
9983  for (int i = 0; i <= p; i++)
9984  {
9985  int idx, s;
9986  if ((idx = dof_map[o++]) < 0)
9987  {
9988  idx = -1 - idx, s = -1;
9989  }
9990  else
9991  {
9992  s = +1;
9993  }
9994  shape(idx,0) = 0.;
9995  shape(idx,1) = s*shape_cx(i)*shape_oy(j)*shape_cz(k);
9996  shape(idx,2) = 0.;
9997  }
9998  // z-components
9999  for (int k = 0; k < p; k++)
10000  for (int j = 0; j <= p; j++)
10001  for (int i = 0; i <= p; i++)
10002  {
10003  int idx, s;
10004  if ((idx = dof_map[o++]) < 0)
10005  {
10006  idx = -1 - idx, s = -1;
10007  }
10008  else
10009  {
10010  s = +1;
10011  }
10012  shape(idx,0) = 0.;
10013  shape(idx,1) = 0.;
10014  shape(idx,2) = s*shape_cx(i)*shape_cy(j)*shape_oz(k);
10015  }
10016 }
10017 
10019  DenseMatrix &curl_shape) const
10020 {
10021  const int p = Order;
10022 
10023 #ifdef MFEM_THREAD_SAFE
10024  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10025  Vector shape_cz(p + 1), shape_oz(p);
10026  Vector dshape_cx(p + 1), dshape_cy(p + 1), dshape_cz(p + 1);
10027 #endif
10028 
10029  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10030  obasis1d.Eval(ip.x, shape_ox);
10031  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10032  obasis1d.Eval(ip.y, shape_oy);
10033  cbasis1d.Eval(ip.z, shape_cz, dshape_cz);
10034  obasis1d.Eval(ip.z, shape_oz);
10035 
10036  int o = 0;
10037  // x-components
10038  for (int k = 0; k <= p; k++)
10039  for (int j = 0; j <= p; j++)
10040  for (int i = 0; i < p; i++)
10041  {
10042  int idx, s;
10043  if ((idx = dof_map[o++]) < 0)
10044  {
10045  idx = -1 - idx, s = -1;
10046  }
10047  else
10048  {
10049  s = +1;
10050  }
10051  curl_shape(idx,0) = 0.;
10052  curl_shape(idx,1) = s*shape_ox(i)* shape_cy(j)*dshape_cz(k);
10053  curl_shape(idx,2) = -s*shape_ox(i)*dshape_cy(j)* shape_cz(k);
10054  }
10055  // y-components
10056  for (int k = 0; k <= p; k++)
10057  for (int j = 0; j < p; j++)
10058  for (int i = 0; i <= p; i++)
10059  {
10060  int idx, s;
10061  if ((idx = dof_map[o++]) < 0)
10062  {
10063  idx = -1 - idx, s = -1;
10064  }
10065  else
10066  {
10067  s = +1;
10068  }
10069  curl_shape(idx,0) = -s* shape_cx(i)*shape_oy(j)*dshape_cz(k);
10070  curl_shape(idx,1) = 0.;
10071  curl_shape(idx,2) = s*dshape_cx(i)*shape_oy(j)* shape_cz(k);
10072  }
10073  // z-components
10074  for (int k = 0; k < p; k++)
10075  for (int j = 0; j <= p; j++)
10076  for (int i = 0; i <= p; i++)
10077  {
10078  int idx, s;
10079  if ((idx = dof_map[o++]) < 0)
10080  {
10081  idx = -1 - idx, s = -1;
10082  }
10083  else
10084  {
10085  s = +1;
10086  }
10087  curl_shape(idx,0) = s* shape_cx(i)*dshape_cy(j)*shape_oz(k);
10088  curl_shape(idx,1) = -s*dshape_cx(i)* shape_cy(j)*shape_oz(k);
10089  curl_shape(idx,2) = 0.;
10090  }
10091 }
10092 
10093 
10094 const double ND_QuadrilateralElement::tk[8] =
10095 { 1.,0., 0.,1., -1.,0., 0.,-1. };
10096 
10098  : VectorFiniteElement(2, Geometry::SQUARE, 2*p*(p + 1), p,
10099  H_CURL, FunctionSpace::Qk),
10100  cbasis1d(poly1d.ClosedBasis(p)), obasis1d(poly1d.OpenBasis(p - 1)),
10101  dof_map(Dof), dof2tk(Dof)
10102 {
10103  const double *cp = poly1d.ClosedPoints(p);
10104  const double *op = poly1d.OpenPoints(p - 1);
10105  const int dof2 = Dof/2;
10106 
10107 #ifndef MFEM_THREAD_SAFE
10108  shape_cx.SetSize(p + 1);
10109  shape_ox.SetSize(p);
10110  shape_cy.SetSize(p + 1);
10111  shape_oy.SetSize(p);
10112  dshape_cx.SetSize(p + 1);
10113  dshape_cy.SetSize(p + 1);
10114 #endif
10115 
10116  // edges
10117  int o = 0;
10118  for (int i = 0; i < p; i++) // (0,1)
10119  {
10120  dof_map[0*dof2 + i + 0*p] = o++;
10121  }
10122  for (int j = 0; j < p; j++) // (1,2)
10123  {
10124  dof_map[1*dof2 + p + j*(p + 1)] = o++;
10125  }
10126  for (int i = 0; i < p; i++) // (2,3)
10127  {
10128  dof_map[0*dof2 + (p - 1 - i) + p*p] = -1 - (o++);
10129  }
10130  for (int j = 0; j < p; j++) // (3,0)
10131  {
10132  dof_map[1*dof2 + 0 + (p - 1 - j)*(p + 1)] = -1 - (o++);
10133  }
10134 
10135  // interior
10136  // x-components
10137  for (int j = 1; j < p; j++)
10138  for (int i = 0; i < p; i++)
10139  {
10140  dof_map[0*dof2 + i + j*p] = o++;
10141  }
10142  // y-components
10143  for (int j = 0; j < p; j++)
10144  for (int i = 1; i < p; i++)
10145  {
10146  dof_map[1*dof2 + i + j*(p + 1)] = o++;
10147  }
10148 
10149  // set dof2tk and Nodes
10150  o = 0;
10151  // x-components
10152  for (int j = 0; j <= p; j++)
10153  for (int i = 0; i < p; i++)
10154  {
10155  int idx;
10156  if ((idx = dof_map[o++]) < 0)
10157  {
10158  dof2tk[idx = -1 - idx] = 2;
10159  }
10160  else
10161  {
10162  dof2tk[idx] = 0;
10163  }
10164  Nodes.IntPoint(idx).Set2(op[i], cp[j]);
10165  }
10166  // y-components
10167  for (int j = 0; j < p; j++)
10168  for (int i = 0; i <= p; i++)
10169  {
10170  int idx;
10171  if ((idx = dof_map[o++]) < 0)
10172  {
10173  dof2tk[idx = -1 - idx] = 3;
10174  }
10175  else
10176  {
10177  dof2tk[idx] = 1;
10178  }
10179  Nodes.IntPoint(idx).Set2(cp[i], op[j]);
10180  }
10181 }
10182 
10184  DenseMatrix &shape) const
10185 {
10186  const int p = Order;
10187 
10188 #ifdef MFEM_THREAD_SAFE
10189  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10190 #endif
10191 
10192  cbasis1d.Eval(ip.x, shape_cx);
10193  obasis1d.Eval(ip.x, shape_ox);
10194  cbasis1d.Eval(ip.y, shape_cy);
10195  obasis1d.Eval(ip.y, shape_oy);
10196 
10197  int o = 0;
10198  // x-components
10199  for (int j = 0; j <= p; j++)
10200  for (int i = 0; i < p; i++)
10201  {
10202  int idx, s;
10203  if ((idx = dof_map[o++]) < 0)
10204  {
10205  idx = -1 - idx, s = -1;
10206  }
10207  else
10208  {
10209  s = +1;
10210  }
10211  shape(idx,0) = s*shape_ox(i)*shape_cy(j);
10212  shape(idx,1) = 0.;
10213  }
10214  // y-components
10215  for (int j = 0; j < p; j++)
10216  for (int i = 0; i <= p; i++)
10217  {
10218  int idx, s;
10219  if ((idx = dof_map[o++]) < 0)
10220  {
10221  idx = -1 - idx, s = -1;
10222  }
10223  else
10224  {
10225  s = +1;
10226  }
10227  shape(idx,0) = 0.;
10228  shape(idx,1) = s*shape_cx(i)*shape_oy(j);
10229  }
10230 }
10231 
10233  DenseMatrix &curl_shape) const
10234 {
10235  const int p = Order;
10236 
10237 #ifdef MFEM_THREAD_SAFE
10238  Vector shape_cx(p + 1), shape_ox(p), shape_cy(p + 1), shape_oy(p);
10239  Vector dshape_cx(p + 1), dshape_cy(p + 1);
10240 #endif
10241 
10242  cbasis1d.Eval(ip.x, shape_cx, dshape_cx);
10243  obasis1d.Eval(ip.x, shape_ox);
10244  cbasis1d.Eval(ip.y, shape_cy, dshape_cy);
10245  obasis1d.Eval(ip.y, shape_oy);
10246 
10247  int o = 0;
10248  // x-components
10249  for (int j = 0; j <= p; j++)
10250  for (int i = 0; i < p; i++)
10251  {
10252  int idx, s;
10253  if ((idx = dof_map[o++]) < 0)
10254  {
10255  idx = -1 - idx, s = -1;
10256  }
10257  else
10258  {
10259  s = +1;
10260  }
10261  curl_shape(idx,0) = -s*shape_ox(i)*dshape_cy(j);
10262  }
10263  // y-components
10264  for (int j = 0; j < p; j++)
10265  for (int i = 0; i <= p; i++)
10266  {
10267  int idx, s;
10268  if ((idx = dof_map[o++]) < 0)
10269  {
10270  idx = -1 - idx, s = -1;
10271  }
10272  else
10273  {
10274  s = +1;
10275  }
10276  curl_shape(idx,0) = s*dshape_cx(i)*shape_oy(j);
10277  }
10278 }
10279 
10280 
10281 const double ND_TetrahedronElement::tk[18] =
10282 { 1.,0.,0., 0.,1.,0., 0.,0.,1., -1.,1.,0., -1.,0.,1., 0.,-1.,1. };
10283 
10284 const double ND_TetrahedronElement::c = 1./4.;
10285 
10287  : VectorFiniteElement(3, Geometry::TETRAHEDRON, p*(p + 2)*(p + 3)/2, p,
10288  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
10289 {
10290  const double *eop = poly1d.OpenPoints(p - 1);
10291  const double *fop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10292  const double *iop = (p > 2) ? poly1d.OpenPoints(p - 3) : NULL;
10293 
10294  const int pm1 = p - 1, pm2 = p - 2, pm3 = p - 3;
10295 
10296 #ifndef MFEM_THREAD_SAFE
10297  shape_x.SetSize(p);
10298  shape_y.SetSize(p);
10299  shape_z.SetSize(p);
10300  shape_l.SetSize(p);
10301  dshape_x.SetSize(p);
10302  dshape_y.SetSize(p);
10303  dshape_z.SetSize(p);
10304  dshape_l.SetSize(p);
10305  u.SetSize(Dof, Dim);
10306 #else
10307  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10308 #endif
10309 
10310  int o = 0;
10311  // edges
10312  for (int i = 0; i < p; i++) // (0,1)
10313  {
10314  Nodes.IntPoint(o).Set3(eop[i], 0., 0.);
10315  dof2tk[o++] = 0;
10316  }
10317  for (int i = 0; i < p; i++) // (0,2)
10318  {
10319  Nodes.IntPoint(o).Set3(0., eop[i], 0.);
10320  dof2tk[o++] = 1;
10321  }
10322  for (int i = 0; i < p; i++) // (0,3)
10323  {
10324  Nodes.IntPoint(o).Set3(0., 0., eop[i]);
10325  dof2tk[o++] = 2;
10326  }
10327  for (int i = 0; i < p; i++) // (1,2)
10328  {
10329  Nodes.IntPoint(o).Set3(eop[pm1-i], eop[i], 0.);
10330  dof2tk[o++] = 3;
10331  }
10332  for (int i = 0; i < p; i++) // (1,3)
10333  {
10334  Nodes.IntPoint(o).Set3(eop[pm1-i], 0., eop[i]);
10335  dof2tk[o++] = 4;
10336  }
10337  for (int i = 0; i < p; i++) // (2,3)
10338  {
10339  Nodes.IntPoint(o).Set3(0., eop[pm1-i], eop[i]);
10340  dof2tk[o++] = 5;
10341  }
10342 
10343  // faces
10344  for (int j = 0; j <= pm2; j++) // (1,2,3)
10345  for (int i = 0; i + j <= pm2; i++)
10346  {
10347  double w = fop[i] + fop[j] + fop[pm2-i-j];
10348  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10349  dof2tk[o++] = 3;
10350  Nodes.IntPoint(o).Set3(fop[pm2-i-j]/w, fop[i]/w, fop[j]/w);
10351  dof2tk[o++] = 4;
10352  }
10353  for (int j = 0; j <= pm2; j++) // (0,3,2)
10354  for (int i = 0; i + j <= pm2; i++)
10355  {
10356  double w = fop[i] + fop[j] + fop[pm2-i-j];
10357  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10358  dof2tk[o++] = 2;
10359  Nodes.IntPoint(o).Set3(0., fop[j]/w, fop[i]/w);
10360  dof2tk[o++] = 1;
10361  }
10362  for (int j = 0; j <= pm2; j++) // (0,1,3)
10363  for (int i = 0; i + j <= pm2; i++)
10364  {
10365  double w = fop[i] + fop[j] + fop[pm2-i-j];
10366  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10367  dof2tk[o++] = 0;
10368  Nodes.IntPoint(o).Set3(fop[i]/w, 0., fop[j]/w);
10369  dof2tk[o++] = 2;
10370  }
10371  for (int j = 0; j <= pm2; j++) // (0,2,1)
10372  for (int i = 0; i + j <= pm2; i++)
10373  {
10374  double w = fop[i] + fop[j] + fop[pm2-i-j];
10375  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10376  dof2tk[o++] = 1;
10377  Nodes.IntPoint(o).Set3(fop[j]/w, fop[i]/w, 0.);
10378  dof2tk[o++] = 0;
10379  }
10380 
10381  // interior
10382  for (int k = 0; k <= pm3; k++)
10383  for (int j = 0; j + k <= pm3; j++)
10384  for (int i = 0; i + j + k <= pm3; i++)
10385  {
10386  double w = iop[i] + iop[j] + iop[k] + iop[pm3-i-j-k];
10387  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10388  dof2tk[o++] = 0;
10389  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10390  dof2tk[o++] = 1;
10391  Nodes.IntPoint(o).Set3(iop[i]/w, iop[j]/w, iop[k]/w);
10392  dof2tk[o++] = 2;
10393  }
10394 
10395  DenseMatrix T(Dof);
10396  for (int m = 0; m < Dof; m++)
10397  {
10398  const IntegrationPoint &ip = Nodes.IntPoint(m);
10399  const double *tm = tk + 3*dof2tk[m];
10400  o = 0;
10401 
10402  poly1d.CalcBasis(pm1, ip.x, shape_x);
10403  poly1d.CalcBasis(pm1, ip.y, shape_y);
10404  poly1d.CalcBasis(pm1, ip.z, shape_z);
10405  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10406 
10407  for (int k = 0; k <= pm1; k++)
10408  for (int j = 0; j + k <= pm1; j++)
10409  for (int i = 0; i + j + k <= pm1; i++)
10410  {
10411  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10412  T(o++, m) = s * tm[0];
10413  T(o++, m) = s * tm[1];
10414  T(o++, m) = s * tm[2];
10415  }
10416  for (int k = 0; k <= pm1; k++)
10417  for (int j = 0; j + k <= pm1; j++)
10418  {
10419  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10420  T(o++, m) = s*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10421  T(o++, m) = s*((ip.z - c)*tm[0] - (ip.x - c)*tm[2]);
10422  }
10423  for (int k = 0; k <= pm1; k++)
10424  {
10425  T(o++, m) =
10426  shape_y(pm1-k)*shape_z(k)*((ip.z - c)*tm[1] - (ip.y - c)*tm[2]);
10427  }
10428  }
10429 
10430  Ti.Factor(T);
10431  // cout << "ND_TetrahedronElement(" << p << ") : "; Ti.TestInversion();
10432 }
10433 
10435  DenseMatrix &shape) const
10436 {
10437  const int pm1 = Order - 1;
10438 
10439 #ifdef MFEM_THREAD_SAFE
10440  const int p = Order;
10441  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10442  DenseMatrix u(Dof, Dim);
10443 #endif
10444 
10445  poly1d.CalcBasis(pm1, ip.x, shape_x);
10446  poly1d.CalcBasis(pm1, ip.y, shape_y);
10447  poly1d.CalcBasis(pm1, ip.z, shape_z);
10448  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l);
10449 
10450  int n = 0;
10451  for (int k = 0; k <= pm1; k++)
10452  for (int j = 0; j + k <= pm1; j++)
10453  for (int i = 0; i + j + k <= pm1; i++)
10454  {
10455  double s = shape_x(i)*shape_y(j)*shape_z(k)*shape_l(pm1-i-j-k);
10456  u(n,0) = s; u(n,1) = 0.; u(n,2) = 0.; n++;
10457  u(n,0) = 0.; u(n,1) = s; u(n,2) = 0.; n++;
10458  u(n,0) = 0.; u(n,1) = 0.; u(n,2) = s; n++;
10459  }
10460  for (int k = 0; k <= pm1; k++)
10461  for (int j = 0; j + k <= pm1; j++)
10462  {
10463  double s = shape_x(pm1-j-k)*shape_y(j)*shape_z(k);
10464  u(n,0) = s*(ip.y - c); u(n,1) = -s*(ip.x - c); u(n,2) = 0.; n++;
10465  u(n,0) = s*(ip.z - c); u(n,1) = 0.; u(n,2) = -s*(ip.x - c); n++;
10466  }
10467  for (int k = 0; k <= pm1; k++)
10468  {
10469  double s = shape_y(pm1-k)*shape_z(k);
10470  u(n,0) = 0.; u(n,1) = s*(ip.z - c); u(n,2) = -s*(ip.y - c); n++;
10471  }
10472 
10473  Ti.Mult(u, shape);
10474 }
10475 
10477  DenseMatrix &curl_shape) const
10478 {
10479  const int pm1 = Order - 1;
10480 
10481 #ifdef MFEM_THREAD_SAFE
10482  const int p = Order;
10483  Vector shape_x(p), shape_y(p), shape_z(p), shape_l(p);
10484  Vector dshape_x(p), dshape_y(p), dshape_z(p), dshape_l(p);
10485  DenseMatrix u(Dof, Dim);
10486 #endif
10487 
10488  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10489  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10490  poly1d.CalcBasis(pm1, ip.z, shape_z, dshape_z);
10491  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y - ip.z, shape_l, dshape_l);
10492 
10493  int n = 0;
10494  for (int k = 0; k <= pm1; k++)
10495  for (int j = 0; j + k <= pm1; j++)
10496  for (int i = 0; i + j + k <= pm1; i++)
10497  {
10498  int l = pm1-i-j-k;
10499  const double dx = (dshape_x(i)*shape_l(l) -
10500  shape_x(i)*dshape_l(l))*shape_y(j)*shape_z(k);
10501  const double dy = (dshape_y(j)*shape_l(l) -
10502  shape_y(j)*dshape_l(l))*shape_x(i)*shape_z(k);
10503  const double dz = (dshape_z(k)*shape_l(l) -
10504  shape_z(k)*dshape_l(l))*shape_x(i)*shape_y(j);
10505 
10506  u(n,0) = 0.; u(n,1) = dz; u(n,2) = -dy; n++;
10507  u(n,0) = -dz; u(n,1) = 0.; u(n,2) = dx; n++;
10508  u(n,0) = dy; u(n,1) = -dx; u(n,2) = 0.; n++;
10509  }
10510  for (int k = 0; k <= pm1; k++)
10511  for (int j = 0; j + k <= pm1; j++)
10512  {
10513  int i = pm1 - j - k;
10514  // s = shape_x(i)*shape_y(j)*shape_z(k);
10515  // curl of s*(ip.y - c, -(ip.x - c), 0):
10516  u(n,0) = shape_x(i)*(ip.x - c)*shape_y(j)*dshape_z(k);
10517  u(n,1) = shape_x(i)*shape_y(j)*(ip.y - c)*dshape_z(k);
10518  u(n,2) =
10519  -((dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k) +
10520  (dshape_y(j)*(ip.y - c) + shape_y(j))*shape_x(i)*shape_z(k));
10521  n++;
10522  // curl of s*(ip.z - c, 0, -(ip.x - c)):
10523  u(n,0) = -shape_x(i)*(ip.x - c)*dshape_y(j)*shape_z(k);
10524  u(n,1) = (shape_x(i)*shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)) +
10525  (dshape_x(i)*(ip.x - c) + shape_x(i))*shape_y(j)*shape_z(k));
10526  u(n,2) = -shape_x(i)*dshape_y(j)*shape_z(k)*(ip.z - c);
10527  n++;
10528  }
10529  for (int k = 0; k <= pm1; k++)
10530  {
10531  int j = pm1 - k;
10532  // curl of shape_y(j)*shape_z(k)*(0, ip.z - c, -(ip.y - c)):
10533  u(n,0) = -((dshape_y(j)*(ip.y - c) + shape_y(j))*shape_z(k) +
10534  shape_y(j)*(dshape_z(k)*(ip.z - c) + shape_z(k)));
10535  u(n,1) = 0.;
10536  u(n,2) = 0.; n++;
10537  }
10538 
10539  Ti.Mult(u, curl_shape);
10540 }
10541 
10542 
10543 const double ND_TriangleElement::tk[8] =
10544 { 1.,0., -1.,1., 0.,-1., 0.,1. };
10545 
10546 const double ND_TriangleElement::c = 1./3.;
10547 
10549  : VectorFiniteElement(2, Geometry::TRIANGLE, p*(p + 2), p,
10550  H_CURL, FunctionSpace::Pk), dof2tk(Dof)
10551 {
10552  const double *eop = poly1d.OpenPoints(p - 1);
10553  const double *iop = (p > 1) ? poly1d.OpenPoints(p - 2) : NULL;
10554 
10555  const int pm1 = p - 1, pm2 = p - 2;
10556 
10557 #ifndef MFEM_THREAD_SAFE
10558  shape_x.SetSize(p);
10559  shape_y.SetSize(p);
10560  shape_l.SetSize(p);
10561  dshape_x.SetSize(p);
10562  dshape_y.SetSize(p);
10563  dshape_l.SetSize(p);
10564  u.SetSize(Dof, Dim);
10565  curlu.SetSize(Dof);
10566 #else
10567  Vector shape_x(p), shape_y(p), shape_l(p);
10568 #endif
10569 
10570  int n = 0;
10571  // edges
10572  for (int i = 0; i < p; i++) // (0,1)
10573  {
10574  Nodes.IntPoint(n).Set2(eop[i], 0.);
10575  dof2tk[n++] = 0;
10576  }
10577  for (int i = 0; i < p; i++) // (1,2)
10578  {
10579  Nodes.IntPoint(n).Set2(eop[pm1-i], eop[i]);
10580  dof2tk[n++] = 1;
10581  }
10582  for (int i = 0; i < p; i++) // (2,0)
10583  {
10584  Nodes.IntPoint(n).Set2(0., eop[pm1-i]);
10585  dof2tk[n++] = 2;
10586  }
10587 
10588  // interior
10589  for (int j = 0; j <= pm2; j++)
10590  for (int i = 0; i + j <= pm2; i++)
10591  {
10592  double w = iop[i] + iop[j] + iop[pm2-i-j];
10593  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10594  dof2tk[n++] = 0;
10595  Nodes.IntPoint(n).Set2(iop[i]/w, iop[j]/w);
10596  dof2tk[n++] = 3;
10597  }
10598 
10599  DenseMatrix T(Dof);
10600  for (int m = 0; m < Dof; m++)
10601  {
10602  const IntegrationPoint &ip = Nodes.IntPoint(m);
10603  const double *tm = tk + 2*dof2tk[m];
10604  n = 0;
10605 
10606  poly1d.CalcBasis(pm1, ip.x, shape_x);
10607  poly1d.CalcBasis(pm1, ip.y, shape_y);
10608  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10609 
10610  for (int j = 0; j <= pm1; j++)
10611  for (int i = 0; i + j <= pm1; i++)
10612  {
10613  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10614  T(n++, m) = s * tm[0];
10615  T(n++, m) = s * tm[1];
10616  }
10617  for (int j = 0; j <= pm1; j++)
10618  {
10619  T(n++, m) =
10620  shape_x(pm1-j)*shape_y(j)*((ip.y - c)*tm[0] - (ip.x - c)*tm[1]);
10621  }
10622  }
10623 
10624  Ti.Factor(T);
10625  // cout << "ND_TriangleElement(" << p << ") : "; Ti.TestInversion();
10626 }
10627 
10629  DenseMatrix &shape) const
10630 {
10631  const int pm1 = Order - 1;
10632 
10633 #ifdef MFEM_THREAD_SAFE
10634  const int p = Order;
10635  Vector shape_x(p), shape_y(p), shape_l(p);
10636  DenseMatrix u(Dof, Dim);
10637 #endif
10638 
10639  poly1d.CalcBasis(pm1, ip.x, shape_x);
10640  poly1d.CalcBasis(pm1, ip.y, shape_y);
10641  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l);
10642 
10643  int n = 0;
10644  for (int j = 0; j <= pm1; j++)
10645  for (int i = 0; i + j <= pm1; i++)
10646  {
10647  double s = shape_x(i)*shape_y(j)*shape_l(pm1-i-j);
10648  u(n,0) = s; u(n,1) = 0; n++;
10649  u(n,0) = 0; u(n,1) = s; n++;
10650  }
10651  for (int j = 0; j <= pm1; j++)
10652  {
10653  double s = shape_x(pm1-j)*shape_y(j);
10654  u(n,0) = s*(ip.y - c);
10655  u(n,1) = -s*(ip.x - c);
10656  n++;
10657  }
10658 
10659  Ti.Mult(u, shape);
10660 }
10661 
10663  DenseMatrix &curl_shape) const
10664 {
10665  const int pm1 = Order - 1;
10666 
10667 #ifdef MFEM_THREAD_SAFE
10668  const int p = Order;
10669  Vector shape_x(p), shape_y(p), shape_l(p);
10670  Vector dshape_x(p), dshape_y(p), dshape_l(p);
10671  Vector curlu(Dof);
10672 #endif
10673 
10674  poly1d.CalcBasis(pm1, ip.x, shape_x, dshape_x);
10675  poly1d.CalcBasis(pm1, ip.y, shape_y, dshape_y);
10676  poly1d.CalcBasis(pm1, 1. - ip.x - ip.y, shape_l, dshape_l);
10677 
10678  int n = 0;
10679  for (int j = 0; j <= pm1; j++)
10680  for (int i = 0; i + j <= pm1; i++)
10681  {
10682  int l = pm1-i-j;
10683  const double dx = (dshape_x(i)*shape_l(l) -
10684  shape_x(i)*dshape_l(l)) * shape_y(j);
10685  const double dy = (dshape_y(j)*shape_l(l) -
10686  shape_y(j)*dshape_l(l)) * shape_x(i);
10687 
10688  curlu(n++) = -dy;
10689  curlu(n++) = dx;
10690  }
10691 
10692  for (int j = 0; j <= pm1; j++)
10693  {
10694  int i = pm1 - j;
10695  // curl of shape_x(i)*shape_y(j) * (ip.y - c, -(ip.x - c), 0):
10696  curlu(n++) = -((dshape_x(i)*(ip.x - c) + shape_x(i)) * shape_y(j) +
10697  (dshape_y(j)*(ip.y - c) + shape_y(j)) * shape_x(i));
10698  }
10699 
10700  Vector curl2d(curl_shape.Data(),Dof);
10701  Ti.Mult(curlu, curl2d);
10702 }
10703 
10704 
10705 const double ND_SegmentElement::tk[1] = { 1. };
10706 
10708  : VectorFiniteElement(1, Geometry::SEGMENT, p, p - 1,
10709  H_CURL, FunctionSpace::Pk),
10710  obasis1d(poly1d.OpenBasis(p - 1)), dof2tk(Dof)
10711 {
10712  const double *op = poly1d.OpenPoints(p - 1);
10713 
10714  // set dof2tk and Nodes
10715  for (int i = 0; i < p; i++)
10716  {
10717  dof2tk[i] = 0;
10718  Nodes.IntPoint(i).x = op[i];
10719  }
10720 }
10721 
10723  DenseMatrix &shape) const
10724 {
10725  Vector vshape(shape.Data(), Dof);
10726 
10727  obasis1d.Eval(ip.x, vshape);
10728 }
10729 
10730 
10732  Vector &shape) const
10733 {
10734  kv[0]->CalcShape(shape, ijk[0], ip.x);
10735 
10736  double sum = 0.0;
10737  for (int i = 0; i <= Order; i++)
10738  {
10739  sum += (shape(i) *= weights(i));
10740  }
10741 
10742  shape /= sum;
10743 }
10744 
10746  DenseMatrix &dshape) const
10747 {
10748  Vector grad(dshape.Data(), Dof);
10749 
10750  kv[0]->CalcShape (shape_x, ijk[0], ip.x);
10751  kv[0]->CalcDShape(grad, ijk[0], ip.x);
10752 
10753  double sum = 0.0, dsum = 0.0;
10754  for (int i = 0; i <= Order; i++)
10755  {
10756  sum += (shape_x(i) *= weights(i));
10757  dsum += ( grad(i) *= weights(i));
10758  }
10759 
10760  sum = 1.0/sum;
10761  add(sum, grad, -dsum*sum*sum, shape_x, grad);
10762 }
10763 
10765  Vector &shape) const
10766 {
10767  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
10768  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
10769 
10770  double sum = 0.0;
10771  for (int o = 0, j = 0; j <= Order; j++)
10772  {
10773  const double sy = shape_y(j);
10774  for (int i = 0; i <= Order; i++, o++)
10775  {
10776  sum += ( shape(o) = shape_x(i)*sy*weights(o) );
10777  }
10778  }
10779 
10780  shape /= sum;
10781 }
10782 
10784  DenseMatrix &dshape) const
10785 {
10786  double sum, dsum[2];
10787 
10788  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
10789  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
10790 
10791  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
10792  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
10793 
10794  sum = dsum[0] = dsum[1] = 0.0;
10795  for (int o = 0, j = 0; j <= Order; j++)
10796  {
10797  const double sy = shape_y(j), dsy = dshape_y(j);
10798  for (int i = 0; i <= Order; i++, o++)
10799  {
10800  sum += ( u(o) = shape_x(i)*sy*weights(o) );
10801 
10802  dsum[0] += ( dshape(o,0) = dshape_x(i)*sy *weights(o) );
10803  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy*weights(o) );
10804  }
10805  }
10806 
10807  sum = 1.0/sum;
10808  dsum[0] *= sum*sum;
10809  dsum[1] *= sum*sum;
10810 
10811  for (int o = 0; o < Dof; o++)
10812  {
10813  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
10814  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
10815  }
10816 }
10817 
10819  Vector &shape) const
10820 {
10821  kv[0]->CalcShape(shape_x, ijk[0], ip.x);
10822  kv[1]->CalcShape(shape_y, ijk[1], ip.y);
10823  kv[2]->CalcShape(shape_z, ijk[2], ip.z);
10824 
10825  double sum = 0.0;
10826  for (int o = 0, k = 0; k <= Order; k++)
10827  {
10828  const double sz = shape_z(k);
10829  for (int j = 0; j <= Order; j++)
10830  {
10831  const double sy_sz = shape_y(j)*sz;
10832  for (int i = 0; i <= Order; i++, o++)
10833  {
10834  sum += ( shape(o) = shape_x(i)*sy_sz*weights(o) );
10835  }
10836  }
10837  }
10838 
10839  shape /= sum;
10840 }
10841 
10843  DenseMatrix &dshape) const
10844 {
10845  double sum, dsum[3];
10846 
10847  kv[0]->CalcShape ( shape_x, ijk[0], ip.x);
10848  kv[1]->CalcShape ( shape_y, ijk[1], ip.y);
10849  kv[2]->CalcShape ( shape_z, ijk[2], ip.z);
10850 
10851  kv[0]->CalcDShape(dshape_x, ijk[0], ip.x);
10852  kv[1]->CalcDShape(dshape_y, ijk[1], ip.y);
10853  kv[2]->CalcDShape(dshape_z, ijk[2], ip.z);
10854 
10855  sum = dsum[0] = dsum[1] = dsum[2] = 0.0;
10856  for (int o = 0, k = 0; k <= Order; k++)
10857  {
10858  const double sz = shape_z(k), dsz = dshape_z(k);
10859  for (int j = 0; j <= Order; j++)
10860  {
10861  const double sy_sz = shape_y(j)* sz;
10862  const double dsy_sz = dshape_y(j)* sz;
10863  const double sy_dsz = shape_y(j)*dsz;
10864  for (int i = 0; i <= Order; i++, o++)
10865  {
10866  sum += ( u(o) = shape_x(i)*sy_sz*weights(o) );
10867 
10868  dsum[0] += ( dshape(o,0) = dshape_x(i)* sy_sz *weights(o) );
10869  dsum[1] += ( dshape(o,1) = shape_x(i)*dsy_sz *weights(o) );
10870  dsum[2] += ( dshape(o,2) = shape_x(i)* sy_dsz*weights(o) );
10871  }
10872  }
10873  }
10874 
10875  sum = 1.0/sum;
10876  dsum[0] *= sum*sum;
10877  dsum[1] *= sum*sum;
10878  dsum[2] *= sum*sum;
10879 
10880  for (int o = 0; o < Dof; o++)
10881  {
10882  dshape(o,0) = dshape(o,0)*sum - u(o)*dsum[0];
10883  dshape(o,1) = dshape(o,1)*sum - u(o)*dsum[1];
10884  dshape(o,2) = dshape(o,2)*sum - u(o)*dsum[2];
10885  }
10886 }
10887 
10888 }
Abstract class for Finite Elements.
Definition: fe.hpp:44
RefinedLinear3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:4073
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1189
void Set(const double *p, const int dim)
Definition: intrules.hpp:32
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7896
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:3182
int Size() const
Logical size of the array.
Definition: array.hpp:109
RT_QuadrilateralElement(const int p)
Definition: fe.cpp:8875
DenseMatrix curlshape_J
Definition: fe.hpp:280
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5872
int GetDim() const
Returns the space dimension for the finite element.
Definition: fe.hpp:82
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7163
L2_TetrahedronElement(const int p, const int _type=0)
Definition: fe.cpp:8564
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2714
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3651
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:937
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8316
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:10783
Linear3DFiniteElement()
Construct a linear FE on tetrahedron.
Definition: fe.cpp:2112
static double CalcDelta(const int p, const double x)
Definition: fe.hpp:1280
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2896
H1_HexahedronElement(const int p)
Definition: fe.cpp:6847
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8055
int NumCols() const
Definition: array.hpp:259
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:9646
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:30
RefinedBiLinear2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4305
ND_QuadrilateralElement(const int p)
Definition: fe.cpp:10097
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1507
L2Pos_TriangleElement(const int p)
Definition: fe.cpp:8468
H1Pos_SegmentElement(const int p)
Definition: fe.cpp:7105
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:116
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:4917
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:75
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2350
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2129
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8552
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:2668
virtual void Eval(Vector &V, ElementTransformation &T, const IntegrationPoint &ip)=0
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2948
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1303
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7143
L2Pos_TetrahedronElement(const int p)
Definition: fe.cpp:8715
Array< KnotVector * > kv
Definition: fe.hpp:2004
void CalcVShape_RT(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:372
void SetSize(int s)
Resizes the vector if the new size is different.
Definition: vector.hpp:259
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:9033
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:4979
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3438
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:858
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:177
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1327
void LocalInterpolation_ND(const double *tk, const Array< int > &d2t, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:687
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1685
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1596
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:2433
static void UniformPoints(const int p, double *x)
Definition: fe.cpp:6150
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:445
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
evaluate derivatives of shape function - constant 0
Definition: fe.cpp:2083
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols.
Definition: operator.hpp:41
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:747
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6675
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:10731
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7915
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:33
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
Definition: densemat.cpp:2864
LagrangeHexFiniteElement(int degree)
Definition: fe.cpp:3703
int GetOrder() const
Returns the order of the finite element.
Definition: fe.hpp:91
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:2446
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3559
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3865
Data type dense matrix using column-major storage.
Definition: densemat.hpp:22
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3513
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:259
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:10745
Basis & OpenBasis(const int p)
Definition: fe.cpp:6548
const double * ClosedPoints(const int p)
Definition: fe.cpp:6523
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:9503
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5145
void ProjectCurl_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:509
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2098
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1756
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:69
RefinedTriLinear3DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:4452
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3690
Quadratic3DFiniteElement()
Construct a quadratic FE on tetrahedron.
Definition: fe.cpp:2168
int GetMapType() const
Definition: fe.hpp:98
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7769
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:5495
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5682
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:3850
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:2545
const IntegrationPoint & GetIntPoint()
Definition: eltrans.hpp:35
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8680
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1808
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8770
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2375
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2367
const IntegrationPoint & GetCenter(int GeomType)
Definition: geom.hpp:51
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7839
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:6759
void ProjectCurl_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:547
H1Pos_HexahedronElement(const int p)
Definition: fe.cpp:7273
virtual void ProjectGrad(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:100
double * GetData() const
Definition: vector.hpp:88
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8622
RT_HexahedronElement(const int p)
Definition: fe.cpp:9083
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:819
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7245
Linear2DFiniteElement()
Construct a linear FE on triangle.
Definition: fe.cpp:761
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2225
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5817
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:259
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4641
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10628
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:728
L2_SegmentElement(const int p, const int _type=0)
Definition: fe.cpp:7740
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1828
L2Pos_HexahedronElement(const int p)
Definition: fe.cpp:8243
ND_TriangleElement(const int p)
Definition: fe.cpp:10548
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:9682
static void CalcBasis(const int p, const double x, double *u)
Definition: fe.hpp:1264
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
evaluate shape function - constant 1
Definition: fe.cpp:2077
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1856
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:6333
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:63
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:3150
Cubic3DFiniteElement()
Construct a cubic FE on tetrahedron.
Definition: fe.cpp:1903
Linear1DFiniteElement()
Construct a linear FE on interval.
Definition: fe.cpp:740
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4014
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:5805
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:1376
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:3883
virtual void ProjectCurl(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:108
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:994
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2399
void SetSize(int m, int n)
Definition: array.hpp:256
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1996
Geometry Geometries
Definition: geom.cpp:443
IntegrationPoint & IntPoint(int i)
Returns a reference to the i-th integration point.
Definition: intrules.hpp:231
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3456
virtual void AssembleElementMatrix(const FiniteElement &el, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:488
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:2936
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7775
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:954
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:965
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1213
ND_SegmentElement(const int p)
Definition: fe.cpp:10707
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows.
Definition: operator.hpp:35
H1_TriangleElement(const int p)
Definition: fe.cpp:7451
RefinedLinear1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:3903
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7020
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7266
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1480
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8410
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7518
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3930
void LocalInterpolation_RT(const double *nk, const Array< int > &d2n, ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:651
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:3089
static void ChebyshevPoints(const int p, double *x)
Definition: fe.cpp:6301
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:5942
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3675
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:5783
ND_TetrahedronElement(const int p)
Definition: fe.cpp:10286
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8516
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const =0
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:734
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1771
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:568
const IntegrationRule & GetNodes() const
Definition: fe.hpp:113
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5032
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1035
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8151
DenseMatrix vshape
Definition: fe.hpp:280
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2203
L2Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:7991
P0SegmentFiniteElement(int Ord=0)
Definition: fe.cpp:2338
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:2691
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:10818
DenseMatrix curlshape
Definition: fe.hpp:280
void Set2(const double x1, const double x2)
Definition: intrules.hpp:73
virtual double Weight()=0
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:9244
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:5083
int GetVDim()
Returns dimension of the vector.
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8388
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:8986
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1635
void SetData(double *d)
Definition: vector.hpp:67
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:3348
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:810
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2138
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:9318
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7681
virtual void CalcHessian(const IntegrationPoint &ip, DenseMatrix &h) const
Definition: fe.cpp:1059
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1137
void ProjectGrad_ND(const double *tk, const Array< int > &d2t, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:630
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8490
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:2972
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:10842
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:1151
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:10232
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8016
void Set3(const double x1, const double x2, const double x3)
Definition: intrules.hpp:63
ND_HexahedronElement(const int p)
Definition: fe.cpp:9728
IntegrationRule Nodes
Definition: fe.hpp:48
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1021
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8271
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7123
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7444
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:3400
double * Data() const
Returns vector of the elements.
Definition: densemat.hpp:77
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:10662
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:2560
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4328
H1_QuadrilateralElement(const int p)
Definition: fe.cpp:6703
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2457
void CalcVShape_ND(ElementTransformation &Trans, DenseMatrix &shape) const
Definition: fe.cpp:385
DenseMatrix Jinv
Definition: fe.hpp:279
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7786
int GetDof() const
Returns the degrees of freedom in the FE space.
Definition: fe.hpp:88
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7706
Base class Coefficient that may optionally depend on time.
Definition: coefficient.hpp:31
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:905
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:5113
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8738
void mfem_error(const char *msg)
Definition: error.cpp:23
void SetSize(int nsize)
Change logical size of the array, keep existing entries.
Definition: array.hpp:323
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:772
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4498
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4195
static const int * Binom(const int p)
Definition: fe.cpp:6133
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:3250
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:44
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:840
static void GaussLobattoPoints(const int p, double *x)
Definition: fe.cpp:6225
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8647
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:9944
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2624
void SetDataAndSize(double *d, int s)
Definition: vector.hpp:69
FiniteElement(int D, int G, int Do, int O, int F=FunctionSpace::Pk)
Definition: fe.cpp:22
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1262
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2283
Quad1DFiniteElement()
Construct a quadratic FE on interval.
Definition: fe.cpp:946
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7399
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:58
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:894
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:801
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:51
H1Pos_QuadrilateralElement(const int p)
Definition: fe.cpp:7170
Class for integration point with weight.
Definition: intrules.hpp:25
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:754
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8439
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7420
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7845
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2104
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8292
void Project_RT(const double *nk, const Array< int > &d2n, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:404
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:6975
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:929
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:3064
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10434
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:2824
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10183
virtual void ProjectDiv(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &div) const
Definition: fe.cpp:288
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:2572
virtual void AssembleElementMatrix2(const FiniteElement &trial_fe, const FiniteElement &test_fe, ElementTransformation &Trans, DenseMatrix &elmat)
Definition: bilininteg.cpp:531
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7856
RefinedLinear2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:3949
void NodalLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I, const NodalFiniteElement &fine_fe) const
Definition: fe.cpp:125
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5737
void ProjectCurl_2D(const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &curl) const
Definition: fe.cpp:158
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3911
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3639
RT_TetrahedronElement(const int p)
Definition: fe.cpp:9545
L2_TriangleElement(const int p, const int _type=0)
Definition: fe.cpp:8335
virtual void GetLocalInterpolation(ElementTransformation &Trans, DenseMatrix &I) const
Definition: fe.cpp:5293
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3844
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:6656
H1_TetrahedronElement(const int p)
Definition: fe.cpp:7570
BiQuad2DFiniteElement()
Construct a biquadratic FE on quadrilateral.
Definition: fe.cpp:1166
virtual void GetFaceDofs(int face, int **dofs, int *ndofs) const
Definition: fe.cpp:2158
Basis & ClosedBasis(const int p)
Definition: fe.cpp:6571
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:2861
P0TriangleFiniteElement()
Construct P0 triangle finite element.
Definition: fe.cpp:2070
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:2344
virtual double Eval(ElementTransformation &T, const IntegrationPoint &ip)=0
RT_TriangleElement(const int p)
Definition: fe.cpp:9393
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:6637
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:10722
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:10018
void Eval(const double x, Vector &u) const
Definition: fe.cpp:6023
L2Pos_SegmentElement(const int p)
Definition: fe.cpp:7818
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:4108
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5348
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:3362
Vector data type.
Definition: vector.hpp:33
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:5279
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:1299
virtual void Transform(const IntegrationPoint &, Vector &)=0
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:7225
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8127
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:1087
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:9470
Quad2DFiniteElement()
Construct a quadratic FE on triangle.
Definition: fe.cpp:1004
virtual int GetSpaceDim()=0
Describes the space on each element.
Definition: fe.hpp:27
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2299
const double * OpenPoints(const int p)
Definition: fe.cpp:6498
virtual const DenseMatrix & Jacobian()=0
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:5198
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:8035
static void GaussPoints(const int p, double *x)
Definition: fe.cpp:6165
virtual void CalcCurlShape(const IntegrationPoint &ip, DenseMatrix &curl_shape) const
Definition: fe.cpp:10476
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3696
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:1405
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:780
H1_SegmentElement(const int p)
Definition: fe.cpp:6618
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:1968
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:2410
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:71
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:6798
L2_HexahedronElement(const int p, const int _type=0)
Definition: fe.cpp:8070
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:5249
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:3468
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:4379
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const =0
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:10764
void Project_ND(const double *tk, const Array< int > &d2t, VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:566
int GetRangeType() const
Definition: fe.hpp:96
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:883
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2766
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3669
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:6996
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:6778
Basis(const int p, const double *nodes, const int _mode=1)
Definition: fe.cpp:5977
static void CalcDBinomTerms(const int p, const double x, const double y, double *d)
Definition: fe.cpp:6397
virtual void CalcVShape(const IntegrationPoint &ip, DenseMatrix &shape) const
Definition: fe.cpp:4862
TriLinear3DFiniteElement()
Construct a tri-linear FE on cube.
Definition: fe.cpp:2247
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:87
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:984
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:8106
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3966
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:3429
BiLinear2DFiniteElement()
Construct a bilinear FE on quadrilateral.
Definition: fe.cpp:788
Poly_1D poly1d
Definition: fe.cpp:6614
L2_QuadrilateralElement(const int p, const int _type=0)
Definition: fe.cpp:7863
virtual void CalcShape(const IntegrationPoint &ip, Vector &shape) const
Definition: fe.cpp:5925
Lagrange1DFiniteElement(int degree)
Definition: fe.cpp:3481
virtual void Project(VectorCoefficient &vc, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:2509
virtual void CalcDivShape(const IntegrationPoint &ip, Vector &divshape) const
Definition: fe.cpp:5618
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:8859
virtual void ProjectDelta(int vertex, Vector &dofs) const
Definition: fe.cpp:7935
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:850
virtual void CalcDShape(const IntegrationPoint &ip, DenseMatrix &dshape) const
Definition: fe.cpp:7540
void ProjectGrad_RT(const double *nk, const Array< int > &d2n, const FiniteElement &fe, ElementTransformation &Trans, DenseMatrix &grad) const
Definition: fe.cpp:482
virtual void Project(Coefficient &coeff, ElementTransformation &Trans, Vector &dofs) const
Definition: fe.cpp:320