31 #include "../common/mfem-common.hpp" 49 struct DeformationData
77 enum DefType {INVALID, UNIFORM, SQUEEZE, SHEAR};
79 Deformation(
int dim, DefType dType,
const DeformationData & data)
83 using VectorCoefficient::Eval;
91 const DeformationData & data_;
106 int update_basis(vector<socketstream*> & sock,
const VisWinLayout & vwl,
108 Deformation::DefType dType,
const DeformationData & defData,
109 bool visualization,
int &onlySome);
111 int main(
int argc,
char *argv[])
128 Deformation::DefType dType = Deformation::INVALID;
129 DeformationData defData;
131 bool visualization =
true;
134 vector<socketstream*> sock;
137 args.
AddOption(&eInt,
"-e",
"--elem-type",
138 "Element Type: (1-Segment, 2-Triangle, 3-Quadrilateral, " 139 "4-Tetrahedron, 5-Hexahedron, 6-Wedge)");
140 args.
AddOption(&bInt,
"-b",
"--basis-type",
141 "Basis Function Type (0-H1, 1-Nedelec, 2-Raviart-Thomas, " 142 "3-L2, 4-Fixed Order Cont.,\n\t5-Gaussian Discontinuous (2D)," 143 " 6-Crouzeix-Raviart, 7-Serendipity)");
144 args.
AddOption(&bOrder,
"-o",
"--order",
"Basis function order");
145 args.
AddOption(&vwl.nx,
"-nx",
"--num-win-x",
146 "Number of Viz windows in X");
147 args.
AddOption(&vwl.ny,
"-ny",
"--num-win-y",
148 "Number of Viz windows in y");
150 "Width of Viz windows");
152 "Height of Viz windows");
153 args.
AddOption(&visualization,
"-vis",
"--visualization",
"-no-vis",
154 "--no-visualization",
155 "Enable or disable GLVis visualization.");
156 args.
AddOption(&onlySome,
"-only",
"--onlySome",
157 "Only view 10 dofs, starting with the specified one.");
167 if ( eInt > 0 && eInt < 7 )
202 bool print_char =
true;
208 cout <<
"Element Type: " <<
elemTypeStr(eType) << endl;
210 cout <<
"Basis function order: " << bOrder << endl;
211 cout <<
"Map Type: " <<
mapTypeStr(mType) << endl;
213 if (
update_basis(sock, vwl, eType, bType, bOrder, mType,
214 dType, defData, visualization, onlySome) )
216 cerr <<
"Invalid combination of basis info (try again)" << endl;
219 if (!visualization) {
break; }
223 cout <<
"What would you like to do?\n" 225 "c) Close Windows and Quit\n" 226 "e) Change Element Type\n" 227 "b) Change Basis Type\n";
228 if ( bType ==
'h' || bType ==
'p' || bType ==
'n' || bType ==
'r' ||
229 bType ==
'l' || bType ==
'f' || bType ==
'g' || bType ==
's')
231 cout <<
"o) Change Basis Order\n";
234 if ( bType ==
'l' &&
false )
236 cout <<
"m) Change Map Type\n";
238 cout <<
"t) Transform Element\n";
239 cout <<
"--> " << flush;
249 for (
unsigned int i=0; i<sock.size(); i++)
251 *sock[i] <<
"keys q";
258 cout <<
"valid element types:\n";
268 "3) Quadrilateral\n";
277 cout <<
"enter new element type --> " << flush;
279 if ( eInt <= 0 || eInt > 6 )
281 cout <<
"invalid element type \"" << eInt <<
"\"" << endl << flush;
291 dType = Deformation::INVALID;
299 cout <<
"invalid element type \"" << eInt <<
300 "\" for basis type \"" <<
basisTypeStr(bType) <<
"\"." << endl;
306 cout <<
"valid basis types:\n";
307 cout <<
"h) H1 Finite Element\n";
308 cout <<
"p) H1 Positive Finite Element\n";
311 cout <<
"s) H1 Serendipity Finite Element\n";
312 cout <<
"n) Nedelec Finite Element\n";
313 cout <<
"r) Raviart-Thomas Finite Element\n";
315 cout <<
"l) L2 Finite Element\n";
318 cout <<
"c) Crouzeix-Raviart Finite Element\n";
320 cout <<
"f) Fixed Order Continuous Finite Element\n";
323 cout <<
"g) Gauss Discontinuous Finite Element\n";
325 cout <<
"enter new basis type --> " << flush;
327 if (bChar ==
'h' || bChar ==
'p' || bChar ==
'l' || bChar ==
'f' ||
336 mType = FiniteElement::VALUE;
338 else if ( bType ==
'p' )
340 mType = FiniteElement::VALUE;
342 else if (bType ==
's')
344 mType = FiniteElement::VALUE;
346 else if ( bType ==
'n' )
348 mType = FiniteElement::H_CURL;
350 else if ( bType ==
'r' )
352 mType = FiniteElement::H_DIV;
354 else if ( bType ==
'l' )
356 if ( mType != FiniteElement::VALUE &&
357 mType != FiniteElement::INTEGRAL )
359 mType = FiniteElement::VALUE;
362 else if ( bType ==
'c' )
365 mType = FiniteElement::VALUE;
367 else if ( bType ==
'f' )
369 if ( bOrder < 1 || bOrder > 3)
373 mType = FiniteElement::VALUE;
375 else if ( bType ==
'g' )
377 if ( bOrder < 1 || bOrder > 2)
381 mType = FiniteElement::VALUE;
387 cout <<
"invalid basis type \"" << bChar <<
"\"." << endl;
390 if (mk ==
'm' && bType ==
'l')
393 cout <<
"valid map types:\n" 396 cout <<
"enter new map type --> " << flush;
398 if (mInt >=0 && mInt <= 1)
405 cout <<
"invalid map type \"" << mInt <<
"\"." << endl;
411 int oMin = ( bType ==
'h' || bType ==
'p' || bType ==
'n' ||
412 bType ==
'f' || bType ==
'g' || bType ==
's')?1:0;
425 cout <<
"basis function order must be >= " << oMin;
428 cout <<
" and <= " << oMax;
431 cout <<
"enter new basis function order --> " << flush;
433 if ( oInt >= oMin && oInt <= (oMax>=0)?oMax:oInt )
440 cout <<
"invalid basis order \"" << oInt <<
"\"." << endl;
445 cout <<
"transformation options:\n";
446 cout <<
"r) reset to reference element\n";
447 cout <<
"u) uniform scaling\n";
450 cout <<
"c) compression\n";
451 cout <<
"s) shear\n";
453 cout <<
"enter transformation type --> " << flush;
458 dType = Deformation::INVALID;
462 cout <<
"enter scaling constant --> " << flush;
463 cin >> defData.uniformScale;
464 if ( defData.uniformScale > 0.0 )
466 dType = Deformation::UNIFORM;
469 else if (tk ==
'c' && !
elemIs1D(eType))
472 cout <<
"enter compression factor --> " << flush;
473 cin >> defData.squeezeFactor;
474 cout <<
"enter compression axis (0-" <<
dim-1 <<
") --> " << flush;
475 cin >> defData.squeezeAxis;
477 if ( defData.squeezeFactor > 0.0 &&
478 (defData.squeezeAxis >= 0 && defData.squeezeAxis <
dim))
480 dType = Deformation::SQUEEZE;
483 else if (tk ==
's' && !
elemIs1D(eType))
486 cout <<
"enter shear vector (components separated by spaces) --> " 488 defData.shearVec.SetSize(
dim);
489 for (
int i=0; i<
dim; i++)
491 cin >> defData.shearVec[i];
493 cout <<
"enter shear axis (0-" <<
dim-1 <<
") --> " << flush;
494 cin >> defData.shearAxis;
496 if ( defData.shearAxis >= 0 && defData.shearAxis <
dim )
498 dType = Deformation::SHEAR;
505 for (
unsigned int i=0; i<sock.size(); i++)
520 case Element::SEGMENT:
522 case Element::TRIANGLE:
524 case Element::QUADRILATERAL:
525 return "QUADRILATERAL";
526 case Element::TETRAHEDRON:
527 return "TETRAHEDRON";
528 case Element::HEXAHEDRON:
540 return eType == Element::SEGMENT;
546 return eType == Element::TRIANGLE || eType == Element::QUADRILATERAL;
552 return eType == Element::TETRAHEDRON || eType == Element::HEXAHEDRON ||
553 eType == Element::WEDGE;
562 return "Continuous (H1)";
564 return "Continuous Positive (H1)";
566 return "Continuous Serendipity (H1)";
570 return "Raviart-Thomas";
572 return "Discontinuous (L2)";
574 return "Fixed Order Continuous";
576 return "Gaussian Discontinuous";
578 return "Crouzeix-Raviart";
587 return bType ==
'h' || bType ==
'p' || bType ==
'l' || bType ==
'c' ||
594 return bType ==
'h' || bType ==
'p' || bType ==
'n' || bType ==
'r' ||
595 bType ==
'l' || bType ==
'c' || bType ==
'f' || bType ==
'g' ||
602 return bType ==
'h' || bType ==
'p' || bType ==
'n' || bType ==
'r' ||
603 bType ==
'f' || bType ==
'l';
611 case FiniteElement::VALUE:
613 case FiniteElement::H_CURL:
615 case FiniteElement::H_DIV:
617 case FiniteElement::INTEGRAL:
649 if ( dType_ == UNIFORM )
651 v *= data_.uniformScale;
662 v *= data_.uniformScale;
666 v[ data_.squeezeAxis ] /= data_.squeezeFactor;
667 v[(data_.squeezeAxis+1)%2] *= data_.squeezeFactor;
671 v.
Add(v[data_.shearAxis], data_.shearVec);
685 v *= data_.uniformScale;
689 v[ data_.squeezeAxis ] /= data_.squeezeFactor;
690 v[(data_.squeezeAxis+1)%2] *= sqrt(data_.squeezeFactor);
691 v[(data_.squeezeAxis+2)%2] *= sqrt(data_.squeezeFactor);
695 v.
Add(v[data_.shearAxis], data_.shearVec);
705 Deformation::DefType dType,
const DeformationData & defData,
706 bool visualization,
int &onlySome)
715 cerr <<
"\nProblem with meshstream object\n" << endl;
719 mesh =
new Mesh(imesh, 1, 1);
722 if ( dType != Deformation::INVALID )
724 Deformation defCoef(
dim, dType, defData);
771 else if ( bOrder == 2 )
775 else if ( bOrder == 3 )
785 else if ( bOrder == 2 )
807 int offx = vwl.w+10,
offy = vwl.h+45;
809 for (
unsigned int i=0; i<sock.size(); i++)
811 *sock[i] <<
"keys q";
816 for (
int i=0; i<ndof; i++)
822 for (
int i=0; i<ndof; i++)
828 (*x[i])(-1-vdofs[i]) = -1.0;
832 (*x[i])(vdofs[i]) = 1.0;
838 if ( bType ==
'n' ) { exOrder++; }
839 if ( bType ==
'r' ) { exOrder += 2; }
840 while ( 1<<ref < bOrder + exOrder || ref == 0 )
845 for (
int i=0; i<ndof; i++)
853 if (ndof > 25 && onlySome == -1)
856 cout <<
"There are more than 25 windows to open.\n" 857 <<
"Only showing Dofs 1-10 to avoid crashing.\n" 858 <<
"Use the option -only N to show Dofs N to N+9 instead.\n";
861 for (
int i = 0; i < stopAt; i++)
863 if (i ==0 && onlySome > 0 && onlySome <ndof)
866 stopAt = min(ndof,onlySome+9);
870 oss <<
"DoF " << i + 1;
874 (i % vwl.nx) *
offx, ((i / vwl.nx) % vwl.ny) *
offy,
880 for (
int i=0; i<ndof; i++)
bool elemIs3D(const Element::Type &eType)
Version of QuadraticDiscont2DFECollection with dofs in the Gaussian points.
Class for grid function - Vector with associated FE space.
virtual void Update(bool want_transform=true)
Reflect changes in the mesh: update number of DOFs, etc. Also, calculate GridFunction transformation ...
Base class for vector Coefficients that optionally depend on time and space.
void PrintOptions(std::ostream &out) const
Print the options.
bool elemIs1D(const Element::Type &eType)
void PrintUsage(std::ostream &out) const
Print the usage message.
Piecewise-(bi/tri)linear continuous finite elements.
void Transform(void(*f)(const Vector &, Vector &))
bool Good() const
Return true if the command line options were parsed successfully.
Piecewise-(bi)cubic continuous finite elements.
string mapTypeStr(int mType)
void Parse()
Parse the command-line options. Note that this function expects all the options provided through the ...
void UniformRefinement(int i, const DSTable &, int *, int *, int *)
bool basisIs1D(char bType)
virtual void Eval(DenseMatrix &M, ElementTransformation &T, const IntegrationRule &ir)
Evaluate the vector coefficient in the element described by T at all points of ir, storing the result in M.
Type
Constants for the classes derived from Element.
string elemTypeStr(const Element::Type &eType)
void VisualizeField(socketstream &sock, const char *vishost, int visport, ParGridFunction &gf, const char *title, int x=0, int y=0, int w=400, int h=400, bool vec=false)
Crouzeix-Raviart nonconforming elements in 2D.
Arbitrary order H(div)-conforming Raviart-Thomas finite elements.
DofTransformation * GetElementVDofs(int i, Array< int > &vdofs) const
Returns indexes of degrees of freedom in array dofs for i'th element.
Class FiniteElementSpace - responsible for providing FEM view of the mesh, mainly managing the set of...
Collection of finite elements from the same family in multiple dimensions. This class is used to matc...
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)
Add a boolean option and set 'var' to receive the value. Enable/disable tags are used to set the bool...
virtual void Update()
Transform by the Space UpdateMatrix (e.g., on Mesh change).
bool basisIs3D(char bType)
Version of LinearDiscont2DFECollection with dofs in the Gaussian points.
Arbitrary order H1-conforming (continuous) finite elements with positive basis functions.
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
Class for integration point with weight.
int GetVSize() const
Return the number of vector dofs, i.e. GetNDofs() x GetVDim().
int main(int argc, char *argv[])
bool elemIs2D(const Element::Type &eType)
Piecewise-(bi)quadratic continuous finite elements.
bool basisIs2D(char bType)
Arbitrary order H(curl)-conforming Nedelec finite elements.
Arbitrary order H1-conforming (continuous) finite elements.
double u(const Vector &xvec)
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 &onlySome)
Arbitrary order "L2-conforming" discontinuous finite elements.
string basisTypeStr(char bType)