// Contact example // // Compile with: make contact // // Sample runs: ./contact -m1 block1.mesh -m2 block2.mesh -at "5 6 7 8" #include "mfem.hpp" #include #include //#include "nodepair.hpp" using namespace std; using namespace mfem; Vector GetNormalVector(Mesh & mesh, const int elem, const double *ref) { ElementTransformation *trans = mesh.GetElementTransformation(elem); const int dim = mesh.Dimension(); const int spaceDim = trans->GetSpaceDim(); MFEM_VERIFY(spaceDim == 3, ""); Vector n(spaceDim); IntegrationPoint ip; ip.Set(ref, dim); trans->SetIntPoint(&ip); //CalcOrtho(trans->Jacobian(), n); // Works only for face transformations const DenseMatrix jac = trans->Jacobian(); int dimNormal = -1; int normalSide = -1; const double tol = 1.0e-8; for (int i=0; i= 0 && normalSide >= 0, ""); MFEM_VERIFY(dim == 3, ""); std::vector tang(2); int tangDir[2] = {-1, -1}; { int t = 0; for (int i=0; i codes = finder.GetCode(); /// Return element number for each point found by FindPoints. Array elems = finder.GetElem(); /// Return reference coordinates for each point found by FindPoints. Vector refcrd = finder.GetReferencePosition(); /// Return distance between the sought and the found point in physical space, /// for each point found by FindPoints. Vector dist = finder.GetDist(); MFEM_VERIFY(dist.Size() == np, ""); MFEM_VERIFY(refcrd.Size() == np * dim, ""); MFEM_VERIFY(elems.Size() == np, ""); MFEM_VERIFY(codes.Size() == np, ""); bool allfound = true; for (auto code : codes) if (code == 2) { allfound = false; } MFEM_VERIFY(allfound, "A point was not found"); cout << "Maximum distance of projected points: " << dist.Max() << endl; for (int i=0; i vert; mesh.GetElementVertices(elems[i], vert); for (auto v : vert) { cout << " " << v << endl; } cout << " reference coordinates: ("; for (int j=0; jGetSpaceDim()); trans->Transform(ip, phys); cout << " physical coordinates: "; phys.Print(); } } int main(int argc, char *argv[]) { // 1. Parse command-line options. const char *mesh_file1 = "block1.mesh"; const char *mesh_file2 = "block2.mesh"; Array attr; OptionsParser args(argc, argv); args.AddOption(&mesh_file1, "-m1", "--mesh1", "First mesh file to use."); args.AddOption(&mesh_file2, "-m2", "--mesh2", "Second mesh file to use."); args.AddOption(&attr, "-at", "--attributes-surf", "Attributes of boundary faces on contact surface for mesh 2."); args.Parse(); if (!args.Good()) { args.PrintUsage(cout); return 1; } args.PrintOptions(cout); Mesh mesh1(mesh_file1, 1, 1); Mesh mesh2(mesh_file2, 1, 1); const int dim = mesh1.Dimension(); MFEM_VERIFY(dim == mesh2.Dimension(), ""); attr.Sort(); cout << "Boundary attributes for contact surface faces in mesh 2" << endl; for (auto a : attr) { cout << a << endl; } Array bdryFaces2; // TODO: remove this? std::set bdryVerts2; for (int b=0; b= 0) { bdryFaces2.Append(b); Array vert; mesh2.GetBdrElementVertices(b, vert); for (auto v : vert) { bdryVerts2.insert(v); } } } int npoints = bdryVerts2.size(); Vector xyz(dim * npoints); xyz = 0.0; cout << "Boundary vertices for contact surface vertices in mesh 2" << endl; int count = 0; for (auto v : bdryVerts2) { cout << v << ": " << mesh2.GetVertex(v)[0] << ", " << mesh2.GetVertex(v)[1] << ", " << mesh2.GetVertex(v)[2] << endl; for (int i=0; i