307 lines
8.7 KiB
C++
307 lines
8.7 KiB
C++
|
|
#include "mfem.hpp"
|
|
#include <fstream>
|
|
#include <iostream>
|
|
|
|
using namespace std;
|
|
using namespace mfem;
|
|
|
|
Mesh * ExtendMesh(Mesh * mesh, const Array<int> & directions);
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
// 1. Parse command-line options.
|
|
const char *mesh_file = "../../data/inline-quad.mesh";
|
|
int order = 1;
|
|
bool visualization = true;
|
|
|
|
OptionsParser args(argc, argv);
|
|
args.AddOption(&mesh_file, "-m", "--mesh",
|
|
"Mesh file to use.");
|
|
args.AddOption(&order, "-o", "--order",
|
|
"Finite element order (polynomial degree) or -1 for"
|
|
" isoparametric space.");
|
|
args.AddOption(&visualization, "-vis", "--visualization", "-no-vis",
|
|
"--no-visualization",
|
|
"Enable or disable GLVis visualization.");
|
|
args.Parse();
|
|
if (!args.Good())
|
|
{
|
|
args.PrintUsage(cout);
|
|
return 1;
|
|
}
|
|
args.PrintOptions(cout);
|
|
|
|
// 3. Read the mesh from the given mesh file. We can handle triangular,
|
|
// quadrilateral, tetrahedral, hexahedral, surface and volume meshes with
|
|
// the same code.
|
|
Mesh *mesh = new Mesh(mesh_file, 1, 1);
|
|
// Mesh *mesh = new Mesh(4,4, Element::QUADRILATERAL, true, 1.0, 1.0, false);
|
|
|
|
// 14. Send the solution by socket to a GLVis server.
|
|
if (visualization)
|
|
{
|
|
char vishost[] = "localhost";
|
|
int visport = 19916;
|
|
socketstream sol_sock(vishost, visport);
|
|
sol_sock.precision(8);
|
|
sol_sock << "mesh\n" << *mesh <<
|
|
"window_title 'Original Mesh' " << "keys anm" << flush;
|
|
}
|
|
|
|
|
|
Array<int> directions;
|
|
// directions.Append(2);
|
|
// directions.Append(2);
|
|
// directions.Append(1);
|
|
// directions.Append(-1);
|
|
// directions.Append(2);
|
|
// directions.Append(-2);
|
|
// directions.Append(-1);
|
|
|
|
directions.Append(1);
|
|
directions.Append(-1);
|
|
directions.Append(2);
|
|
directions.Append(-2);
|
|
directions.Append(3);
|
|
directions.Append(-3);
|
|
// directions.Append(-1);
|
|
|
|
Mesh * mesh_ext = ExtendMesh(mesh,directions);
|
|
|
|
if (visualization)
|
|
{
|
|
char vishost[] = "localhost";
|
|
int visport = 19916;
|
|
socketstream mesh_sock(vishost, visport);
|
|
mesh_sock.precision(8);
|
|
mesh_sock << "mesh\n" << *mesh_ext <<
|
|
"window_title 'New Mesh' " << "keys anm" << flush;
|
|
}
|
|
|
|
// 15. Free the used memory.
|
|
delete mesh;
|
|
return 0;
|
|
}
|
|
|
|
Mesh * ExtendMesh(Mesh * mesh, const Array<int> & directions)
|
|
{
|
|
// extrute on one dimension
|
|
// flag = 1 +x, -1 -x, 2 +y, -2 +y , 3 +z, -3, -z
|
|
|
|
// copy the original mesh;
|
|
Mesh * mesh_orig = new Mesh(*mesh);
|
|
int dim = mesh_orig->Dimension();
|
|
|
|
// Mesh * mesh_ext;
|
|
|
|
// for (int j=0; j<directions.Size(); j++)
|
|
// {
|
|
// int d = directions[j];
|
|
// MFEM_VERIFY(abs(d)<= dim, "Cannot Extend in dimension " << d << ". Dim = " << dim << endl);
|
|
// int nrelem = mesh_orig->GetNE();
|
|
|
|
|
|
// Vector pmin;
|
|
// Vector pmax;
|
|
// mesh_orig->GetBoundingBox(pmin,pmax);
|
|
|
|
// DenseMatrix J(dim);
|
|
// double hmin, hmax;
|
|
// hmin = infinity();
|
|
// hmax = -infinity();
|
|
// Vector attr(nrelem);
|
|
// // element size
|
|
|
|
// for (int iel=0; iel<nrelem; ++iel)
|
|
// {
|
|
// int geom = mesh_orig->GetElementBaseGeometry(iel);
|
|
// ElementTransformation *T = mesh_orig->GetElementTransformation(iel);
|
|
// T->SetIntPoint(&Geometries.GetCenter(geom));
|
|
// Geometries.JacToPerfJac(geom, T->Jacobian(), J);
|
|
// attr(iel) = J.Det();
|
|
// attr(iel) = pow(abs(attr(iel)), 1.0/double(dim));
|
|
// hmin = min(hmin, attr(iel));
|
|
// hmax = max(hmax, attr(iel));
|
|
// }
|
|
// MFEM_VERIFY(hmin==hmax, "Case not supported yet")
|
|
|
|
// double val;
|
|
// // find the vertices on the specific boundary
|
|
// switch (d)
|
|
// {
|
|
// case 1:
|
|
// val = pmax[0];
|
|
// break;
|
|
// case -1:
|
|
// val = pmin[0];
|
|
// hmax = -hmax;
|
|
// break;
|
|
// case 2:
|
|
// val = pmax[1];
|
|
// break;
|
|
// case -2:
|
|
// val = pmin[1];
|
|
// hmax = -hmax;
|
|
// break;
|
|
// case 3:
|
|
// val = pmax[2];
|
|
// break;
|
|
// case -3:
|
|
// val = pmin[2];
|
|
// hmax = -hmax;
|
|
// break;
|
|
// }
|
|
// int k = 0;
|
|
// for (int i = 0; i<mesh_orig->GetNV(); ++i)
|
|
// {
|
|
// double * coords = mesh_orig->GetVertex(i);
|
|
// switch (abs(d))
|
|
// {
|
|
// case 1:
|
|
// if (coords[0] == val) k++;
|
|
// break;
|
|
// case 2:
|
|
// if (coords[1] == val) k++;
|
|
// break;
|
|
// case 3:
|
|
// if (coords[2] == val) k++;
|
|
// break;
|
|
// }
|
|
// }
|
|
// int nrvertices = mesh_orig->GetNV() + k;
|
|
// int nrelements = mesh_orig->GetNE() + pow(pow(k,1.0/(dim-1))-1.0,dim-1);
|
|
|
|
// mesh_ext = new Mesh(dim, nrvertices, nrelements);
|
|
|
|
// // Add existing vertices
|
|
// Array<int> vmap(mesh_orig->GetNV()); vmap = 0;
|
|
// k = mesh_orig->GetNV();
|
|
// for (int i=0; i<mesh_orig->GetNV(); ++i)
|
|
// {
|
|
// double * vert = mesh_orig->GetVertex(i);
|
|
// mesh_ext->AddVertex(vert);
|
|
// switch (abs(d))
|
|
// {
|
|
// case 1:
|
|
// if (vert[0] == val)
|
|
// {
|
|
// vmap[i] = k;
|
|
// k++;
|
|
// }
|
|
// break;
|
|
// case 2:
|
|
// if (vert[1] == val)
|
|
// {
|
|
// vmap[i] = k;
|
|
// k++;
|
|
// }
|
|
// break;
|
|
// case 3:
|
|
// if (vert[2] == val)
|
|
// {
|
|
// vmap[i] = k;
|
|
// k++;
|
|
// }
|
|
// break;
|
|
// }
|
|
// }
|
|
// // Add existing elements
|
|
// for (int i=0; i<mesh_orig->GetNE(); ++i)
|
|
// {
|
|
// Array<int>ind;
|
|
// mesh_orig->GetElementVertices(i,ind);
|
|
// if (dim == 2)
|
|
// {
|
|
// mesh_ext->AddQuad(ind);
|
|
// }
|
|
// else if (dim == 3)
|
|
// {
|
|
// mesh_ext->AddHex(ind);
|
|
// }
|
|
// }
|
|
// // Add new vertices
|
|
// k = mesh_orig->GetNV();
|
|
// for (int i=0; i<mesh_orig->GetNV(); ++i)
|
|
// {
|
|
// double * vert = mesh_orig->GetVertex(i);
|
|
// switch (abs(d))
|
|
// {
|
|
// case 1:
|
|
// if (vert[0] == val)
|
|
// {
|
|
// double coords[dim];
|
|
// coords[0] = vert[0] + hmax;
|
|
// coords[1] = vert[1];
|
|
// if (dim == 3) coords[2] = vert[2];
|
|
// mesh_ext->AddVertex(coords);
|
|
// }
|
|
// break;
|
|
// case 2:
|
|
// if (vert[1] == val)
|
|
// {
|
|
// double coords[dim];
|
|
// coords[0] = vert[0];
|
|
// coords[1] = vert[1] + hmax;
|
|
// if (dim == 3) coords[2] = vert[2];
|
|
// mesh_ext->AddVertex(coords);
|
|
// }
|
|
// break;
|
|
// case 3:
|
|
// if (vert[2] == val)
|
|
// {
|
|
// double coords[dim];
|
|
// coords[0] = vert[0];
|
|
// coords[1] = vert[1];
|
|
// coords[2] = vert[2] + hmax;
|
|
// mesh_ext->AddVertex(coords);
|
|
// }
|
|
// break;
|
|
// }
|
|
// }
|
|
// // loop through boundary elements and extend in the given direction
|
|
// for (int i=0; i<mesh_orig->GetNBE(); ++i)
|
|
// {
|
|
// Array<int> vertices;
|
|
// mesh_orig->GetBdrElementVertices(i,vertices);
|
|
// if (dim == 2)
|
|
// {
|
|
// int ind[4];
|
|
// if (vmap[vertices[0]] && vmap[vertices[1]])
|
|
// {
|
|
// ind[0] = vmap[vertices[0]];
|
|
// ind[1] = vmap[vertices[1]];
|
|
// ind[2] = vertices[1];
|
|
// ind[3] = vertices[0];
|
|
// mesh_ext->AddQuad(ind);
|
|
// }
|
|
// }
|
|
// else if (dim == 3)
|
|
// {
|
|
// int ind[8];
|
|
// if (vmap[vertices[0]] && vmap[vertices[1]] && vmap[vertices[2]] && vmap[vertices[3]])
|
|
// {
|
|
// ind[0] = vmap[vertices[0]];
|
|
// ind[1] = vmap[vertices[1]];
|
|
// ind[2] = vmap[vertices[2]];
|
|
// ind[3] = vmap[vertices[3]];
|
|
// ind[4] = vertices[0];
|
|
// ind[5] = vertices[1];
|
|
// ind[6] = vertices[2];
|
|
// ind[7] = vertices[3];
|
|
// mesh_ext->AddHex(ind);
|
|
// }
|
|
// }
|
|
// }
|
|
// mesh_ext->FinalizeTopology();
|
|
|
|
// if (j<directions.Size()-1)
|
|
// {
|
|
// delete mesh_orig;
|
|
// mesh_orig = mesh_ext;
|
|
// }
|
|
// }
|
|
// delete mesh_orig;
|
|
// return mesh_ext;
|
|
// }
|