MFEM  v3.3
Finite element discretization library
display-basis.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 // ----------------------------------------------------------------
13 // Display Basis Miniapp: Visualize finite element basis functions
14 // ----------------------------------------------------------------
15 //
16 // This miniapp visualizes various types of finite element basis functions on a
17 // single mesh element in 1D, 2D and 3D. The order and the type of finite
18 // element space can be changed, and the mesh element is either the reference
19 // one, or a simple transformation of it. Dynamic creation and interaction with
20 // multiple GLVis windows is demonstrated.
21 //
22 // Compile with: make display-basis
23 //
24 // Sample runs: display-basis
25 // display_basis -e 2 -b 3 -o 3
26 // display-basis -e 5 -b 1 -o 1
27 
28 #include "mfem.hpp"
29 #include "../common/fem_extras.hpp"
30 #include "../common/mesh_extras.hpp"
31 #include <vector>
32 #include <iostream>
33 
34 using namespace std;
35 using namespace mfem;
36 using namespace mfem::miniapps;
37 
38 // Data structure used to collect visualization window layout parameters
39 struct VisWinLayout
40 {
41  int nx;
42  int ny;
43  int w;
44  int h;
45 };
46 
47 // Data structure used to define simple coordinate transformations
48 struct DeformationData
49 {
50  double uniformScale;
51 
52  int squeezeAxis;
53  double squeezeFactor;
54 
55  int shearAxis;
56  Vector shearVec;
57 };
58 
59 /** The Deformation class implements three simple coordinate transformations:
60  Uniform Scaling:
61  u = a v for a scalar constant 'a'
62 
63  Compression or Squeeze (along a coordinate axis):
64  / 1/b 0 \ / 1/b 0 0 \ for a scalar constant b
65  u = \ 0 b / v or u = | 0 c 0 | v, and c = sqrt(b)
66  \ 0 0 c / the axis can also be chosen
67 
68  Shear:
69  u = v + v_i * s where 's' is the shear vector
70  and 'i' is the shear axis
71 */
72 class Deformation : public VectorCoefficient
73 {
74 public:
75 
76  enum DefType {INVALID, UNIFORM, SQUEEZE, SHEAR};
77 
78  Deformation(int dim, DefType dType, const DeformationData & data)
79  : VectorCoefficient(dim), dim_(dim), dType_(dType), data_(data) {}
80 
81  void Eval(Vector &v, ElementTransformation &T, const IntegrationPoint &ip);
82 
83 private:
84  void Def1D(const Vector & u, Vector & v);
85  void Def2D(const Vector & u, Vector & v);
86  void Def3D(const Vector & u, Vector & v);
87 
88  int dim_;
89  DefType dType_;
90  const DeformationData & data_;
91 };
92 
93 string elemTypeStr(const Element::Type & eType);
94 inline bool elemIs1D(const Element::Type & eType);
95 inline bool elemIs2D(const Element::Type & eType);
96 inline bool elemIs3D(const Element::Type & eType);
97 
98 string basisTypeStr(char bType);
99 inline bool basisIs1D(char bType);
100 inline bool basisIs2D(char bType);
101 inline bool basisIs3D(char bType);
102 
103 string mapTypeStr(int mType);
104 
105 int update_basis(vector<socketstream*> & sock, const VisWinLayout & vwl,
106  Element::Type e, char bType, int bOrder, int mType,
107  Deformation::DefType dType, const DeformationData & defData,
108  bool visualization);
109 
110 int main(int argc, char *argv[])
111 {
112  // Parse command-line options.
113  Element::Type eType = Element::TRIANGLE;
114  char bType = 'h';
115  int bOrder = 2;
116  int mType = 0;
117 
118  int eInt = -1;
119  int bInt = -1;
120 
121  VisWinLayout vwl;
122  vwl.nx = 5;
123  vwl.ny = 3;
124  vwl.w = 250;
125  vwl.h = 250;
126 
127  Deformation::DefType dType = Deformation::INVALID;
128  DeformationData defData;
129 
130  bool visualization = true;
131 
132  vector<socketstream*> sock;
133 
134  OptionsParser args(argc, argv);
135  args.AddOption(&eInt, "-e", "--elem-type",
136  "Element Type: (1-Segment, 2-Triangle, 3-Quadrilateral, "
137  "4-Tetrahedron, 5-Hexahedron)");
138  args.AddOption(&bInt, "-b", "--basis-type",
139  "Basis Function Type (0-H1, 1-Nedelec, 2-Raviart-Thomas, "
140  "3-L2, 4-Fixed Order Cont.,\n\t5-Gaussian Discontinuous (2D),"
141  " 6-Crouzeix-Raviart)");
142  args.AddOption(&bOrder, "-o", "--order", "Basis function order");
143  args.AddOption(&vwl.nx, "-nx", "--num-win-x",
144  "Number of Viz windows in X");
145  args.AddOption(&vwl.ny, "-ny", "--num-win-y",
146  "Number of Viz windows in y");
147  args.AddOption(&vwl.w, "-w", "--width",
148  "Width of Viz windows");
149  args.AddOption(&vwl.h, "-h", "--height",
150  "Height of Viz windows");
151  args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
152  "--no-visualization",
153  "Enable or disable GLVis visualization.");
154  args.Parse();
155  if (!args.Good())
156  {
157  args.PrintUsage(cout);
158  return 1;
159  }
160  {
161  args.PrintOptions(cout);
162  }
163  if ( eInt > 0 && eInt < 6 )
164  {
165  eType = (Element::Type)eInt;
166  }
167  switch (bInt)
168  {
169  case 0:
170  bType = 'h';
171  break;
172  case 1:
173  bType = 'n';
174  break;
175  case 2:
176  bType = 'r';
177  break;
178  case 3:
179  bType = 'l';
180  break;
181  case 4:
182  bType = 'f';
183  break;
184  case 5:
185  bType = 'g';
186  break;
187  case 6:
188  bType = 'c';
189  break;
190  default:
191  bType = 'h';
192  }
193 
194  // Collect user input
195  bool print_char = true;
196  while (true)
197  {
198  if (print_char)
199  {
200  cout << endl;
201  cout << "Element Type: " << elemTypeStr(eType) << endl;
202  cout << "Basis Type: " << basisTypeStr(bType) << endl;;
203  cout << "Basis function order: " << bOrder << endl;
204  cout << "Map Type: " << mapTypeStr(mType) << endl;
205  }
206  if ( update_basis(sock, vwl, eType, bType, bOrder, mType,
207  dType, defData, visualization) )
208  {
209  cerr << "Invalid combination of basis info (try again)" << endl;
210  }
211 
212  if (!visualization) { break; }
213 
214  print_char = false;
215  cout << endl;
216  cout << "What would you like to do?\n"
217  "q) Quit\n"
218  "c) Close Windows and Quit\n"
219  "e) Change Element Type\n"
220  "b) Change Basis Type\n";
221  if ( bType == 'h' || bType == 'p' || bType == 'n' || bType == 'r' ||
222  bType == 'l' || bType == 'f' || bType == 'g' )
223  {
224  cout << "o) Change Basis Order\n";
225  }
226  // The following is disabled pending updates to GLVis
227  if ( bType == 'l' && false )
228  {
229  cout << "m) Change Map Type\n";
230  }
231  cout << "t) Transform Element\n";
232  cout << "--> " << flush;
233  char mk;
234  cin >> mk;
235 
236  if (mk == 'q')
237  {
238  break;
239  }
240  if (mk == 'c')
241  {
242  for (unsigned int i=0; i<sock.size(); i++)
243  {
244  *sock[i] << "keys q";
245  }
246  break;
247  }
248  if (mk == 'e')
249  {
250  eInt = 0;
251  cout << "valid element types:\n";
252  if ( basisIs1D(bType) )
253  {
254  cout <<
255  "1) Segment\n";
256  }
257  if ( basisIs2D(bType) )
258  {
259  cout <<
260  "2) Triangle\n"
261  "3) Quadrilateral\n";
262  }
263  if ( basisIs3D(bType) )
264  {
265  cout <<
266  "4) Tetrahedron\n"
267  "5) Hexahedron\n";
268  }
269  cout << "enter new element type --> " << flush;
270  cin >> eInt;
271  if ( eInt <= 0 || eInt > 5 )
272  {
273  cout << "invalid element type \"" << eInt << "\"" << endl << flush;
274  }
275  else if ( (elemIs1D((Element::Type)eInt) && basisIs1D(bType)) ||
276  (elemIs2D((Element::Type)eInt) && basisIs2D(bType)) ||
277  (elemIs3D((Element::Type)eInt) && basisIs3D(bType)) )
278  {
279  if ( (elemIs1D((Element::Type)eInt) && !elemIs1D(eType)) ||
280  (elemIs2D((Element::Type)eInt) && !elemIs2D(eType)) ||
281  (elemIs3D((Element::Type)eInt) && !elemIs3D(eType)) )
282  {
283  dType = Deformation::INVALID;
284  }
285  eType = (Element::Type)eInt;
286 
287  print_char = true;
288  }
289  else
290  {
291  cout << "invalid element type \"" << eInt <<
292  "\" for basis type \"" << basisTypeStr(bType) << "\"." << endl;
293  }
294  }
295  if (mk == 'b')
296  {
297  char bChar = 0;
298  cout << "valid basis types:\n";
299  cout << "h) H1 Finite Element\n";
300  cout << "p) H1 Positive Finite Element\n";
301  if ( elemIs2D(eType) || elemIs3D(eType) )
302  {
303  cout << "n) Nedelec Finite Element\n";
304  cout << "r) Raviart-Thomas Finite Element\n";
305  }
306  cout << "l) L2 Finite Element\n";
307  if ( elemIs1D(eType) || elemIs2D(eType) )
308  {
309  cout << "c) Crouzeix-Raviart Finite Element\n";
310  }
311  cout << "f) Fixed Order Continuous Finite Element\n";
312  if ( elemIs2D(eType) )
313  {
314  cout << "g) Gauss Discontinuous Finite Element\n";
315  }
316  cout << "enter new basis type --> " << flush;
317  cin >> bChar;
318  if ( bChar == 'h' || bChar == 'p' || bChar == 'l' || bChar == 'f' ||
319  ((bChar == 'n' || bChar == 'r') &&
320  (elemIs2D(eType) || elemIs3D(eType))) ||
321  (bChar == 'c' && (elemIs1D(eType) || elemIs2D(eType))) ||
322  (bChar == 'g' && elemIs2D(eType)))
323  {
324  bType = bChar;
325  if ( bType == 'h' )
326  {
327  mType = FiniteElement::VALUE;
328  }
329  else if ( bType == 'p' )
330  {
331  mType = FiniteElement::VALUE;
332  }
333  else if ( bType == 'n' )
334  {
335  mType = FiniteElement::H_CURL;
336  }
337  else if ( bType == 'r' )
338  {
339  mType = FiniteElement::H_DIV;
340  }
341  else if ( bType == 'l' )
342  {
343  if ( mType != FiniteElement::VALUE &&
344  mType != FiniteElement::INTEGRAL )
345  {
346  mType = FiniteElement::VALUE;
347  }
348  }
349  else if ( bType == 'c' )
350  {
351  bOrder = 1;
352  mType = FiniteElement::VALUE;
353  }
354  else if ( bType == 'f' )
355  {
356  if ( bOrder < 1 || bOrder > 3)
357  {
358  bOrder = 1;
359  }
360  mType = FiniteElement::VALUE;
361  }
362  else if ( bType == 'g' )
363  {
364  if ( bOrder < 1 || bOrder > 2)
365  {
366  bOrder = 1;
367  }
368  mType = FiniteElement::VALUE;
369  }
370  print_char = true;
371  }
372  else
373  {
374  cout << "invalid basis type \"" << bChar << "\"." << endl;
375  }
376  }
377  if (mk == 'm' && bType == 'l')
378  {
379  int mInt = 0;
380  cout << "valid map types:\n"
381  "0) VALUE\n"
382  "1) INTEGRAL\n";
383  cout << "enter new map type --> " << flush;
384  cin >> mInt;
385  if (mInt >=0 && mInt <= 1)
386  {
387  mType = mInt;
388  print_char = true;
389  }
390  else
391  {
392  cout << "invalid map type \"" << mInt << "\"." << endl;
393  }
394  }
395  if (mk == 'o')
396  {
397  int oInt = 1;
398  int oMin = ( bType == 'h' || bType == 'p' || bType == 'n' ||
399  bType == 'f' || bType == 'g')?1:0;
400  int oMax = -1;
401  switch (bType)
402  {
403  case 'g':
404  oMax = 2;
405  break;
406  case 'f':
407  oMax = 3;
408  break;
409  default:
410  oMax = -1;
411  }
412  cout << "basis function order must be >= " << oMin;
413  if ( oMax >= 0 )
414  {
415  cout << " and <= " << oMax;
416  }
417  cout << endl;
418  cout << "enter new basis function order --> " << flush;
419  cin >> oInt;
420  if ( oInt >= oMin && oInt <= (oMax>=0)?oMax:oInt )
421  {
422  bOrder = oInt;
423  print_char = true;
424  }
425  else
426  {
427  cout << "invalid basis order \"" << oInt << "\"." << endl;
428  }
429  }
430  if (mk == 't')
431  {
432  cout << "transformation options:\n";
433  cout << "r) reset to reference element\n";
434  cout << "u) uniform scaling\n";
435  if ( elemIs2D(eType) || elemIs3D(eType) )
436  {
437  cout << "c) compression\n";
438  cout << "s) shear\n";
439  }
440  cout << "enter transformation type --> " << flush;
441  char tk;
442  cin >> tk;
443  if (tk == 'r')
444  {
445  dType = Deformation::INVALID;
446  }
447  else if (tk == 'u')
448  {
449  cout << "enter scaling constant --> " << flush;
450  cin >> defData.uniformScale;
451  if ( defData.uniformScale > 0.0 )
452  {
453  dType = Deformation::UNIFORM;
454  }
455  }
456  else if (tk == 'c' && !elemIs1D(eType))
457  {
458  int dim = elemIs2D(eType)?2:3;
459  cout << "enter compression factor --> " << flush;
460  cin >> defData.squeezeFactor;
461  cout << "enter compression axis (0-" << dim-1 << ") --> " << flush;
462  cin >> defData.squeezeAxis;
463 
464  if ( defData.squeezeFactor > 0.0 &&
465  (defData.squeezeAxis >= 0 && defData.squeezeAxis < dim))
466  {
467  dType = Deformation::SQUEEZE;
468  }
469  }
470  else if (tk == 's' && !elemIs1D(eType))
471  {
472  int dim = elemIs2D(eType)?2:3;
473  cout << "enter shear vector (components separated by spaces) --> "
474  << flush;
475  defData.shearVec.SetSize(dim);
476  for (int i=0; i<dim; i++)
477  {
478  cin >> defData.shearVec[i];
479  }
480  cout << "enter shear axis (0-" << dim-1 << ") --> " << flush;
481  cin >> defData.shearAxis;
482 
483  if ( defData.shearAxis >= 0 && defData.shearAxis < dim )
484  {
485  dType = Deformation::SHEAR;
486  }
487  }
488  }
489  }
490 
491  // Cleanup
492  for (unsigned int i=0; i<sock.size(); i++)
493  {
494  delete sock[i];
495  }
496 
497  // Exit
498  return 0;
499 }
500 
501 string elemTypeStr(const Element::Type & eType)
502 {
503  switch (eType)
504  {
505  case Element::POINT:
506  return "POINT";
507  break;
508  case Element::SEGMENT:
509  return "SEGMENT";
510  break;
511  case Element::TRIANGLE:
512  return "TRIANGLE";
513  break;
514  case Element::QUADRILATERAL:
515  return "QUADRILATERAL";
516  break;
517  case Element::TETRAHEDRON:
518  return "TETRAHEDRON";
519  break;
520  case Element::HEXAHEDRON:
521  return "HEXAHEDRON";
522  break;
523  default:
524  return "INVALID";
525  break;
526  };
527 }
528 
529 bool
530 elemIs1D(const Element::Type & eType)
531 {
532  return eType == Element::SEGMENT;
533 }
534 
535 bool
536 elemIs2D(const Element::Type & eType)
537 {
538  return eType == Element::TRIANGLE || eType == Element::QUADRILATERAL;
539 }
540 
541 bool
542 elemIs3D(const Element::Type & eType)
543 {
544  return eType == Element::TETRAHEDRON || eType == Element::HEXAHEDRON;
545 }
546 
547 string
548 basisTypeStr(char bType)
549 {
550  switch (bType)
551  {
552  case 'h':
553  return "Continuous (H1)";
554  break;
555  case 'p':
556  return "Continuous Positive (H1)";
557  break;
558  case 'n':
559  return "Nedelec";
560  break;
561  case 'r':
562  return "Raviart-Thomas";
563  break;
564  case 'l':
565  return "Discontinuous (L2)";
566  break;
567  case 'f':
568  return "Fixed Order Continuous";
569  break;
570  case 'g':
571  return "Gaussian Discontinuous";
572  break;
573  case 'c':
574  return "Crouzeix-Raviart";
575  break;
576  default:
577  return "INVALID";
578  break;
579  };
580 }
581 
582 bool
583 basisIs1D(char bType)
584 {
585  return bType == 'h' || bType == 'p' || bType == 'l' || bType == 'c' ||
586  bType == 'f';
587 }
588 
589 bool
590 basisIs2D(char bType)
591 {
592  return bType == 'h' || bType == 'p' || bType == 'n' || bType == 'r' ||
593  bType == 'l' || bType == 'c' || bType == 'f' || bType == 'g';
594 }
595 
596 bool
597 basisIs3D(char bType)
598 {
599  return bType == 'h' || bType == 'p' || bType == 'n' || bType == 'r' ||
600  bType == 'f' || bType == 'l';
601 }
602 
603 string
604 mapTypeStr(int mType)
605 {
606  switch (mType)
607  {
608  case FiniteElement::VALUE:
609  return "VALUE";
610  break;
611  case FiniteElement::H_CURL:
612  return "H_CURL";
613  break;
614  case FiniteElement::H_DIV:
615  return "H_DIV";
616  break;
617  case FiniteElement::INTEGRAL:
618  return "INTEGRAL";
619  break;
620  default:
621  return "INVALID";
622  break;
623  }
624 }
625 
626 void
628  const IntegrationPoint &ip)
629 {
630  Vector u(dim_);
631  T.Transform(ip, u);
632 
633  switch (dim_)
634  {
635  case 1:
636  Def1D(u, v);
637  break;
638  case 2:
639  Def2D(u, v);
640  break;
641  case 3:
642  Def3D(u, v);
643  break;
644  }
645 }
646 
647 void
648 Deformation::Def1D(const Vector & u, Vector & v)
649 {
650  v = u;
651  if ( dType_ == UNIFORM )
652  {
653  v *= data_.uniformScale;
654  }
655 }
656 
657 void
658 Deformation::Def2D(const Vector & u, Vector & v)
659 {
660  switch (dType_)
661  {
662  case UNIFORM:
663  v = u;
664  v *= data_.uniformScale;
665  break;
666  case SQUEEZE:
667  v = u;
668  v[ data_.squeezeAxis ] /= data_.squeezeFactor;
669  v[(data_.squeezeAxis+1)%2] *= data_.squeezeFactor;
670  break;
671  case SHEAR:
672  v = u;
673  v.Add(v[data_.shearAxis], data_.shearVec);
674  break;
675  default:
676  v = u;
677  }
678 }
679 
680 void
681 Deformation::Def3D(const Vector & u, Vector & v)
682 {
683  switch (dType_)
684  {
685  case UNIFORM:
686  v = u;
687  v *= data_.uniformScale;
688  break;
689  case SQUEEZE:
690  v = u;
691  v[ data_.squeezeAxis ] /= data_.squeezeFactor;
692  v[(data_.squeezeAxis+1)%2] *= sqrt(data_.squeezeFactor);
693  v[(data_.squeezeAxis+2)%2] *= sqrt(data_.squeezeFactor);
694  break;
695  case SHEAR:
696  v = u;
697  v.Add(v[data_.shearAxis], data_.shearVec);
698  break;
699  default:
700  v = u;
701  }
702 }
703 
704 int
705 update_basis(vector<socketstream*> & sock, const VisWinLayout & vwl,
706  Element::Type e, char bType, int bOrder, int mType,
707  Deformation::DefType dType, const DeformationData & defData,
708  bool visualization)
709 {
710  bool vec = false;
711 
712  Mesh *mesh;
713  ElementMeshStream imesh(e);
714  if (!imesh)
715  {
716  {
717  cerr << "\nProblem with meshstream object\n" << endl;
718  }
719  return 2;
720  }
721  mesh = new Mesh(imesh, 1, 1);
722  int dim = mesh->Dimension();
723 
724  if ( dType != Deformation::INVALID )
725  {
726  Deformation defCoef(dim, dType, defData);
727  mesh->Transform(defCoef);
728  }
729 
730  FiniteElementCollection * FEC = NULL;
731  switch (bType)
732  {
733  case 'h':
734  FEC = new H1_FECollection(bOrder, dim);
735  vec = false;
736  break;
737  case 'p':
738  FEC = new H1Pos_FECollection(bOrder, dim);
739  vec = false;
740  break;
741  case 'n':
742  FEC = new ND_FECollection(bOrder, dim);
743  vec = true;
744  break;
745  case 'r':
746  FEC = new RT_FECollection(bOrder-1, dim);
747  vec = true;
748  break;
749  case 'l':
750  FEC = new L2_FECollection(bOrder, dim, BasisType::GaussLegendre,
751  mType);
752  vec = false;
753  break;
754  case 'c':
755  FEC = new CrouzeixRaviartFECollection();
756  break;
757  case 'f':
758  if ( bOrder == 1 )
759  {
760  FEC = new LinearFECollection();
761  }
762  else if ( bOrder == 2 )
763  {
764  FEC = new QuadraticFECollection();
765  }
766  else if ( bOrder == 3 )
767  {
768  FEC = new CubicFECollection();
769  }
770  break;
771  case 'g':
772  if ( bOrder == 1 )
773  {
775  }
776  else if ( bOrder == 2 )
777  {
779  }
780  break;
781  }
782  if ( FEC == NULL)
783  {
784  return 1;
785  }
786 
787  FiniteElementSpace FESpace(mesh, FEC);
788 
789  int ndof = FESpace.GetVSize();
790 
791  Array<int> vdofs;
792  FESpace.GetElementVDofs(0,vdofs);
793 
794  char vishost[] = "localhost";
795  int visport = 19916;
796 
797  int offx = vwl.w+10, offy = vwl.h+45; // window offsets
798 
799  for (unsigned int i=0; i<sock.size(); i++)
800  {
801  *sock[i] << "keys q";
802  delete sock[i];
803  }
804 
805  sock.resize(ndof);
806  for (int i=0; i<ndof; i++)
807  {
808  sock[i] = new socketstream; sock[i]->precision(8);
809  }
810 
811  GridFunction ** x = new GridFunction*[ndof];
812  for (int i=0; i<ndof; i++)
813  {
814  x[i] = new GridFunction(&FESpace);
815  *x[i] = 0.0;
816  if ( vdofs[i] < 0 )
817  {
818  (*x[i])(-1-vdofs[i]) = -1.0;
819  }
820  else
821  {
822  (*x[i])(vdofs[i]) = 1.0;
823  }
824  }
825 
826  int ref = 0;
827  int exOrder = 0;
828  if ( bType == 'n' ) { exOrder++; }
829  if ( bType == 'r' ) { exOrder += 2; }
830  while ( 1<<ref < bOrder + exOrder || ref == 0 )
831  {
832  mesh->UniformRefinement();
833  FESpace.Update();
834 
835  for (int i=0; i<ndof; i++)
836  {
837  x[i]->Update();
838  }
839  ref++;
840  }
841 
842  for (int i=0; i<ndof; i++)
843  {
844  ostringstream oss;
845  oss << "DoF " << i + 1;
846  if (visualization)
847  {
848  VisualizeField(*sock[i], vishost, visport, *x[i], oss.str().c_str(),
849  (i % vwl.nx) * offx, ((i / vwl.nx) % vwl.ny) * offy,
850  vwl.w, vwl.h,
851  vec);
852  }
853  }
854 
855  for (int i=0; i<ndof; i++)
856  {
857  delete x[i];
858  }
859  delete [] x;
860 
861  delete FEC;
862  delete mesh;
863 
864  return 0;
865 }
bool elemIs3D(const Element::Type &eType)
Version of QuadraticDiscont2DFECollection with dofs in the Gaussian points.
Definition: fe_coll.hpp:686
int GetVSize() const
Definition: fespace.hpp:163
Class for grid function - Vector with associated FE space.
Definition: gridfunc.hpp:27
virtual void Update(bool want_transform=true)
Definition: fespace.cpp:1457
bool elemIs1D(const Element::Type &eType)
void GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
Definition: fespace.cpp:133
Piecewise-(bi)linear continuous finite elements.
Definition: fe_coll.hpp:376
void Transform(void(*f)(const Vector &, Vector &))
Definition: mesh.cpp:8228
STL namespace.
Piecewise-(bi)cubic continuous finite elements.
Definition: fe_coll.hpp:443
string mapTypeStr(int mType)
int update_basis(vector< socketstream * > &sock, const VisWinLayout &vwl, Element::Type e, char bType, int bOrder, int mType, Deformation::DefType dType, const DeformationData &defData, bool visualization)
int dim
Definition: ex3.cpp:47
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
Definition: mesh.cpp:6684
bool basisIs1D(char bType)
void VisualizeField(socketstream &sock, const char *vishost, int visport, GridFunction &gf, const char *title, int x, int y, int w, int h, bool vec)
Definition: fem_extras.cpp:59
virtual void Eval(DenseMatrix &M, ElementTransformation &T, const IntegrationRule &ir)
Definition: coefficient.cpp:69
Type
Constants for the classes derived from Element.
Definition: element.hpp:37
string elemTypeStr(const Element::Type &eType)
int Dimension() const
Definition: mesh.hpp:611
void PrintUsage(std::ostream &out) const
Definition: optparser.cpp:434
Crouzeix-Raviart nonconforming elements in 2D.
Definition: fe_coll.hpp:467
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
Definition: fe_coll.hpp:239
void AddOption(bool *var, const char *enable_short_name, const char *enable_long_name, const char *disable_short_name, const char *disable_long_name, const char *description, bool required=false)
Definition: optparser.hpp:74
void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
Definition: gridfunc.cpp:144
bool basisIs3D(char bType)
Version of LinearDiscont2DFECollection with dofs in the Gaussian points.
Definition: fe_coll.hpp:614
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
Definition: vector.cpp:205
Class for integration point with weight.
Definition: intrules.hpp:25
void PrintOptions(std::ostream &out) const
Definition: optparser.cpp:304
int main(int argc, char *argv[])
bool elemIs2D(const Element::Type &eType)
Piecewise-(bi)quadratic continuous finite elements.
Definition: fe_coll.hpp:399
bool basisIs2D(char bType)
Arbitrary order H(curl)-conforming Nedelec finite elements.
Definition: fe_coll.hpp:297
Vector data type.
Definition: vector.hpp:36
virtual void Transform(const IntegrationPoint &, Vector &)=0
Arbitrary order H1-conforming (continuous) finite elements.
Definition: fe_coll.hpp:146
Arbitrary order "L2-conforming" discontinuous finite elements.
Definition: fe_coll.hpp:195
string basisTypeStr(char bType)
bool Good() const
Definition: optparser.hpp:120