[cig-commits] [commit] knepley/upgrade-petsc-interface: Update ReverseCuthillMcKee for DMPlex [unit tests not passing]. (aba87a2)

cig_noreply at geodynamics.org cig_noreply at geodynamics.org
Thu Oct 17 15:35:56 PDT 2013


Repository : ssh://geoshell/pylith

On branch  : knepley/upgrade-petsc-interface
Link       : https://github.com/geodynamics/pylith/compare/6b5ddb40724b13328c73e9702f6f00ca998a90ed...8e347a9f5d96fe4c665278ebea3720639379892b

>---------------------------------------------------------------

commit aba87a2852241beea769cd4525049849e62f4170
Author: Brad Aagaard <baagaard at usgs.gov>
Date:   Thu Oct 17 15:36:53 2013 -0700

    Update ReverseCuthillMcKee for DMPlex [unit tests not passing].
    
    Also added unit tests that were missing.
    
    Reorder mesh *before* adjusting topology and *after* refinement.


>---------------------------------------------------------------

aba87a2852241beea769cd4525049849e62f4170
 libsrc/pylith/topology/ReverseCuthillMcKee.cc      |  38 ++-
 pylith/topology/MeshImporter.py                    |  11 +-
 unittests/libtests/topology/Makefile.am            |   2 +
 .../libtests/topology/TestReverseCuthillMcKee.cc   | 270 +++++++++++++++++++++
 .../libtests/topology/TestReverseCuthillMcKee.hh   | 115 +++++++++
 5 files changed, 412 insertions(+), 24 deletions(-)

diff --git a/libsrc/pylith/topology/ReverseCuthillMcKee.cc b/libsrc/pylith/topology/ReverseCuthillMcKee.cc
index 779288e..a1dbb25 100644
--- a/libsrc/pylith/topology/ReverseCuthillMcKee.cc
+++ b/libsrc/pylith/topology/ReverseCuthillMcKee.cc
@@ -21,36 +21,28 @@
 #include "ReverseCuthillMcKee.hh" // implementation of class methods
 
 #include "pylith/topology/Mesh.hh" // USES Mesh
-
-#include <cassert> // USES assert()
-#include <stdexcept> // USES std::exception
-#include <iostream> // USES std::cerr
+#include "pylith/utils/error.h" // USES PYLITH_CHECK_ERROR
 
 // ----------------------------------------------------------------------
-// Set vertices and cells in mesh.
+// Reorder vertices and cells in mesh.
 void
 pylith::topology::ReverseCuthillMcKee::reorder(topology::Mesh* mesh)
 { // reorder
   assert(mesh);
 
-  const int commRank = mesh->commRank();
-  if (0 == commRank) {
-#if 0
-    const ALE::Obj<SieveMesh>& sieveMesh = mesh->sieveMesh();
-    assert(!sieveMesh.isNull());
-    ALE::Obj<ALE::Ordering<>::perm_type> perm = 
-      new ALE::Ordering<>::perm_type(sieveMesh->comm(), sieveMesh->debug());
-    ALE::Obj<ALE::Ordering<>::perm_type> reordering = 
-      new ALE::Ordering<>::perm_type(sieveMesh->comm(), sieveMesh->debug());
-    
-    ALE::Ordering<>::calculateMeshReordering(sieveMesh, perm, reordering);
-    
-    //perm->view("PERMUTATION");
-    //reordering->view("REORDERING");
-    //sieveMesh->view("MESH BEFORE RELABEL");
-    
-    sieveMesh->relabel(*reordering);
-    //sieveMesh->view("MESH AFTER RELABEL");
+  const int numCells = mesh->numCells();
+  if (numCells > 0) {
+    // Reorder mesh if mesh is only on proc 0 --or--
+    // reorder mesh on each processor indpendently.
+#if 1
+    PetscIS permutation;
+    PetscDM dmOrig = mesh->dmMesh();
+    PetscDM dmNew = NULL;
+    PetscErrorCode err;
+    err = DMPlexGetOrdering(dmOrig, MATORDERINGRCM, &permutation);PYLITH_CHECK_ERROR(err);
+    err = DMPlexPermute(dmOrig, permutation, &dmNew);PYLITH_CHECK_ERROR(err);
+    err = ISDestroy(&permutation);PYLITH_CHECK_ERROR(err);
+    mesh->dmMesh(dmNew);
 #else
     std::cerr << "WARNING: Reverse Cuthill McKee temporarily disabled." << std::endl;
 #endif
diff --git a/pylith/topology/MeshImporter.py b/pylith/topology/MeshImporter.py
index e28ea69..60868d5 100644
--- a/pylith/topology/MeshImporter.py
+++ b/pylith/topology/MeshImporter.py
@@ -101,7 +101,7 @@ class MeshImporter(MeshGenerator):
     if self.debug:
       mesh.view("Finite-element mesh.")
 
-    # Reorder mesh
+    # Reorder mesh (serial) :TODO: Move this after adjusting topology?
     if self.reorderMesh:
       logEvent2 = "%sreorder" % self._loggingPrefix
       self._eventLogger.eventBegin(logEvent2)
@@ -134,6 +134,15 @@ class MeshImporter(MeshGenerator):
       mesh.cleanup()
       newMesh.memLoggingStage = "RefinedMesh"
 
+    # Reorder mesh again (each processor independently)
+    if self.reorderMesh:
+      self._eventLogger.eventBegin(logEvent2)
+      self._debug.log(resourceUsageString())
+      if 0 == comm.rank:
+        self._info.log("Reordering cells and vertices.")
+      ordering.reorder(mesh)
+      self._eventLogger.eventEnd(logEvent2)
+
     # Nondimensionalize mesh (coordinates of vertices).
     from pylith.topology.topology import MeshOps_nondimensionalize
     MeshOps_nondimensionalize(newMesh, normalizer)
diff --git a/unittests/libtests/topology/Makefile.am b/unittests/libtests/topology/Makefile.am
index bb0b891..c8ba46c 100644
--- a/unittests/libtests/topology/Makefile.am
+++ b/unittests/libtests/topology/Makefile.am
@@ -38,6 +38,7 @@ testtopology_SOURCES = \
 	TestSolutionFields.cc \
 	TestJacobian.cc \
 	TestRefineUniform.cc \
+	TestReverseCuthillMcKee.cc \
 	test_topology.cc
 
 
@@ -53,6 +54,7 @@ noinst_HEADERS = \
 	TestFieldsSubMesh.hh \
 	TestSolutionFields.hh \
 	TestRefineUniform.hh \
+	TestReverseCuthillMcKee.hh \
 	TestJacobian.hh
 
 
diff --git a/unittests/libtests/topology/TestReverseCuthillMcKee.cc b/unittests/libtests/topology/TestReverseCuthillMcKee.cc
new file mode 100644
index 0000000..be77f49
--- /dev/null
+++ b/unittests/libtests/topology/TestReverseCuthillMcKee.cc
@@ -0,0 +1,270 @@
+// -*- C++ -*-
+//
+// ----------------------------------------------------------------------
+//
+// Brad T. Aagaard, U.S. Geological Survey
+// Charles A. Williams, GNS Science
+// Matthew G. Knepley, University of Chicago
+//
+// This code was developed as part of the Computational Infrastructure
+// for Geodynamics (http://geodynamics.org).
+//
+// Copyright (c) 2010-2013 University of California, Davis
+//
+// See COPYING for license information.
+//
+// ----------------------------------------------------------------------
+//
+
+#include <portinfo>
+
+#include "TestReverseCuthillMcKee.hh" // Implementation of class methods
+
+#include "pylith/topology/ReverseCuthillMcKee.hh" // USES ReverseCuthillMcKee
+
+#include "pylith/topology/Mesh.hh" // USES Mesh
+#include "pylith/topology/Stratum.hh" // USES Stratum
+#include "pylith/meshio/MeshIOAscii.hh" // USES MeshIOAscii
+#include "pylith/faults/FaultCohesiveKin.hh" // USES FaultCohesiveKin
+
+#include "data/MeshDataCohesiveTri3Level1.hh"
+#include "data/MeshDataCohesiveTri3Level1Fault1.hh"
+#include "data/MeshDataCohesiveQuad4Level1.hh"
+#include "data/MeshDataCohesiveQuad4Level1Fault1.hh"
+#include "data/MeshDataCohesiveTet4Level1.hh"
+#include "data/MeshDataCohesiveTet4Level1Fault1.hh"
+#include "data/MeshDataCohesiveHex8Level1.hh"
+#include "data/MeshDataCohesiveHex8Level1Fault1.hh"
+
+#include <strings.h> // USES strcasecmp()
+#include <stdexcept> // USES std::logic_error
+
+// ----------------------------------------------------------------------
+CPPUNIT_TEST_SUITE_REGISTRATION( pylith::topology::TestReverseCuthillMcKee );
+
+// ----------------------------------------------------------------------
+// Test reorder() with tri3 cells and no fault.
+void
+pylith::topology::TestReverseCuthillMcKee::testReorderTri3(void)
+{ // testReorderTri3
+  PYLITH_METHOD_BEGIN;
+
+  MeshDataCohesiveTri3Level1 data;
+  _testReorder(data);
+
+  PYLITH_METHOD_END;
+} // testReorderTri3
+
+// ----------------------------------------------------------------------
+// Test reorder() with level 2, tri3 cells, and one fault.
+void
+pylith::topology::TestReverseCuthillMcKee::testReorderTri3Fault(void)
+{ // testReorderTri3Fault
+  PYLITH_METHOD_BEGIN;
+
+  MeshDataCohesiveTri3Level1Fault1 data;
+  _testReorder(data);
+
+  PYLITH_METHOD_END;
+} // testReorderTri3Fault
+
+// ----------------------------------------------------------------------
+// Test reorder() with level 2, quad4 cells, and no fault.
+void
+pylith::topology::TestReverseCuthillMcKee::testReorderQuad4(void)
+{ // testReorderQuad4
+  PYLITH_METHOD_BEGIN;
+
+  MeshDataCohesiveQuad4Level1 data;
+  _testReorder(data);
+
+  PYLITH_METHOD_END;
+} // testReorderQuad4
+
+// ----------------------------------------------------------------------
+// Test reorder() with level 2, quad4 cells, and one fault.
+void
+pylith::topology::TestReverseCuthillMcKee::testReorderQuad4Fault(void)
+{ // testReorderQuad4Fault
+  PYLITH_METHOD_BEGIN;
+
+  MeshDataCohesiveQuad4Level1Fault1 data;
+  _testReorder(data);
+
+  PYLITH_METHOD_END;
+} // testReorderQuad4Fault
+
+// ----------------------------------------------------------------------
+// Test reorder() with level 2, tet4 cells, and no fault.
+void
+pylith::topology::TestReverseCuthillMcKee::testReorderTet4(void)
+{ // testReorderTet4
+  PYLITH_METHOD_BEGIN;
+
+  MeshDataCohesiveTet4Level1 data;
+  _testReorder(data);
+
+  PYLITH_METHOD_END;
+} // testReorderTet4
+
+// ----------------------------------------------------------------------
+// Test reorder() with level 2, tet4 cells, and one fault.
+void
+pylith::topology::TestReverseCuthillMcKee::testReorderTet4Fault(void)
+{ // testReorderTet4Fault
+  PYLITH_METHOD_BEGIN;
+
+  MeshDataCohesiveTet4Level1Fault1 data;
+  _testReorder(data);
+
+  PYLITH_METHOD_END;
+} // testReorderTet4Fault
+
+// ----------------------------------------------------------------------
+// Test reorder() with hex8 cells and no fault.
+void
+pylith::topology::TestReverseCuthillMcKee::testReorderHex8(void)
+{ // testReorderHex8
+  PYLITH_METHOD_BEGIN;
+
+  MeshDataCohesiveHex8Level1 data;
+  _testReorder(data);
+
+  PYLITH_METHOD_END;
+} // testReorderHex8
+
+// ----------------------------------------------------------------------
+// Test reorder() with hex8 cells and one fault.
+void
+pylith::topology::TestReverseCuthillMcKee::testReorderHex8Fault(void)
+{ // testReorderHex8Fault
+  PYLITH_METHOD_BEGIN;
+
+  MeshDataCohesiveHex8Level1Fault1 data;
+  _testReorder(data);
+
+  PYLITH_METHOD_END;
+} // testReorderHex8Fault
+
+// ----------------------------------------------------------------------
+void
+pylith::topology::TestReverseCuthillMcKee::_setupMesh(Mesh* const mesh,
+						      const MeshDataCohesive& data)
+{ // _setupMesh
+  PYLITH_METHOD_BEGIN;
+
+  assert(mesh);
+
+  meshio::MeshIOAscii iohandler;
+  iohandler.filename(data.filename);
+  iohandler.interpolate(true);
+
+  iohandler.read(mesh);
+
+  // Adjust topology if necessary.
+  if (data.faultA || data.faultB) {
+    int firstLagrangeVertex = 0;
+    int firstFaultCell = 0;
+
+    faults::FaultCohesiveKin faultA;
+    faultA.id(100);
+    if (data.faultA) {
+      faultA.label(data.faultA);
+      const int nvertices = faultA.numVerticesNoMesh(*mesh);
+      firstLagrangeVertex += nvertices;
+      firstFaultCell += 2*nvertices; // shadow + Lagrange vertices
+    } // if
+
+    faults::FaultCohesiveKin faultB;
+    faultB.id(101);
+    if (data.faultB) {
+      faultA.label(data.faultB);
+      const int nvertices = faultB.numVerticesNoMesh(*mesh);
+      firstLagrangeVertex += nvertices;
+      firstFaultCell += 2*nvertices; // shadow + Lagrange vertices
+    } // if
+    
+    int firstFaultVertex = 0;
+    if (data.faultA) {
+      faultA.adjustTopology(mesh, &firstFaultVertex, &firstLagrangeVertex, &firstFaultCell);
+    } // if
+    if (data.faultB) {
+      faultB.adjustTopology(mesh, &firstFaultVertex, &firstLagrangeVertex, &firstFaultCell);
+    } // if
+  } // if
+
+  PYLITH_METHOD_END;
+} // _setupMesh
+
+// ----------------------------------------------------------------------
+// Test reorder().
+void
+pylith::topology::TestReverseCuthillMcKee::_testReorder(const MeshDataCohesive& data)
+{ // _testReorder
+  PYLITH_METHOD_BEGIN;
+
+  Mesh mesh(data.cellDim);
+  _setupMesh(&mesh, data);
+
+  ReverseCuthillMcKee::reorder(&mesh);
+  
+  // Check mesh dimension
+  CPPUNIT_ASSERT_EQUAL(data.cellDim, mesh.dimension());
+
+  const PetscDM& dmMesh = mesh.dmMesh();CPPUNIT_ASSERT(dmMesh);
+
+  // Check vertices (size only)
+  topology::Stratum verticesStratum(dmMesh, topology::Stratum::DEPTH, 0);
+  CPPUNIT_ASSERT_EQUAL(data.numVertices, verticesStratum.size());
+
+  // Check cells (size only)
+  topology::Stratum cellsStratum(dmMesh, topology::Stratum::HEIGHT, 0);
+  const PetscInt cStart = cellsStratum.begin();
+  const PetscInt cEnd = cellsStratum.end();
+  const PetscInt numCells = cellsStratum.size();
+  CPPUNIT_ASSERT_EQUAL(data.numCells+data.numCellsCohesive, numCells);
+
+  // Check groups
+  PetscInt numGroups, pStart, pEnd;
+  PetscErrorCode err;
+  err = DMPlexGetChart(dmMesh, &pStart, &pEnd);PYLITH_CHECK_ERROR(err);
+  err = DMPlexGetNumLabels(dmMesh, &numGroups);PYLITH_CHECK_ERROR(err);
+  CPPUNIT_ASSERT_EQUAL(data.numGroups, numGroups-2); // Omit depth and material labels
+  PetscInt index  = 0;
+  for(PetscInt iGroup = 0; iGroup < data.numGroups; ++iGroup) {
+    // Don't know order of labels, so do brute force linear search
+    bool foundLabel = false;
+    int iLabel = 0;
+    const char *name = NULL;
+    PetscInt firstPoint = 0;
+    while (iLabel < numGroups) {
+      err = DMPlexGetLabelName(dmMesh, iLabel, &name);PYLITH_CHECK_ERROR(err);
+      if (0 == strcmp(data.groupNames[iGroup], name)) {
+	foundLabel = true;
+	break;
+      } else {
+	++iLabel;
+      } // if/else
+    } // while
+    CPPUNIT_ASSERT(foundLabel);
+
+    for(PetscInt p = pStart; p < pEnd; ++p) {
+      PetscInt val;
+      err = DMPlexGetLabelValue(dmMesh, name, p, &val);PYLITH_CHECK_ERROR(err);
+      if (val >= 0) {
+        firstPoint = p;
+        break;
+      } // if
+    } // for
+    std::string groupType = (firstPoint >= cStart && firstPoint < cEnd) ? "cell" : "vertex";
+    CPPUNIT_ASSERT_EQUAL(std::string(data.groupTypes[iGroup]), groupType);
+    PetscInt numPoints;
+    err = DMPlexGetStratumSize(dmMesh, name, 1, &numPoints);PYLITH_CHECK_ERROR(err);
+    CPPUNIT_ASSERT_EQUAL(data.groupSizes[iGroup], numPoints);
+  } // for
+
+  PYLITH_METHOD_END;
+} // _testReorder
+
+
+// End of file 
diff --git a/unittests/libtests/topology/TestReverseCuthillMcKee.hh b/unittests/libtests/topology/TestReverseCuthillMcKee.hh
new file mode 100644
index 0000000..491d378
--- /dev/null
+++ b/unittests/libtests/topology/TestReverseCuthillMcKee.hh
@@ -0,0 +1,115 @@
+// -*- C++ -*-
+//
+// ----------------------------------------------------------------------
+//
+// Brad T. Aagaard, U.S. Geological Survey
+// Charles A. Williams, GNS Science
+// Matthew G. Knepley, University of Chicago
+//
+// This code was developed as part of the Computational Infrastructure
+// for Geodynamics (http://geodynamics.org).
+//
+// Copyright (c) 2010-2013 University of California, Davis
+//
+// See COPYING for license information.
+//
+// ----------------------------------------------------------------------
+//
+
+/**
+ * @file unittests/libtests/topology/TestReverseCuthillMcKee.hh
+ *
+ * @brief C++ TestReverseCuthillMcKee object
+ *
+ * C++ unit testing for ReverseCuthillMcKee.
+ */
+
+#if !defined(pylith_topology_testreversecuthillmckee_hh)
+#define pylith_topology_testreversecuthillmckee_hh
+
+// Include directives ---------------------------------------------------
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "pylith/topology/topologyfwd.hh" // USES Mesh
+
+// Forward declarations -------------------------------------------------
+/// Namespace for pylith package
+namespace pylith {
+  namespace topology {
+    class TestReverseCuthillMcKee;
+
+    class MeshDataCohesive; // test data
+  } // topology
+} // pylith
+
+// ReverseCuthillMcKee ---------------------------------------------------------------
+class pylith::topology::TestReverseCuthillMcKee : public CppUnit::TestFixture
+{ // class TestReverseCuthillMcKee
+
+  // CPPUNIT TEST SUITE /////////////////////////////////////////////////
+  CPPUNIT_TEST_SUITE( TestReverseCuthillMcKee );
+
+  CPPUNIT_TEST( testReorderTri3 );
+  CPPUNIT_TEST( testReorderTri3Fault );
+
+  CPPUNIT_TEST( testReorderQuad4 );
+  CPPUNIT_TEST( testReorderQuad4Fault );
+
+  CPPUNIT_TEST( testReorderTet4 );
+  CPPUNIT_TEST( testReorderTet4Fault );
+
+  CPPUNIT_TEST( testReorderHex8 );
+  CPPUNIT_TEST( testReorderHex8Fault );
+
+  CPPUNIT_TEST_SUITE_END();
+
+  // PUBLIC METHODS /////////////////////////////////////////////////////
+public :
+
+  /// Test reorder() with tri3 cells and no fault.
+  void testReorderTri3(void);
+
+  /// Test reorder() with tri3 cells and one fault.
+  void testReorderTri3Fault(void);
+
+  /// Test reorder() with quad4 cells and no fault.
+  void testReorderQuad4(void);
+
+  /// Test reorder() with quad4 cells and one fault.
+  void testReorderQuad4Fault(void);
+
+  /// Test reorder() with tet4 cells and no fault.
+  void testReorderTet4(void);
+
+  /// Test reorder() with tet4 cells and one fault.
+  void testReorderTet4Fault(void);
+
+  /// Test reorder() with hex8 cells and no fault.
+  void testReorderHex8(void);
+
+  /// Test reorder() with hex8 cells and one fault.
+  void testReorderHex8Fault(void);
+
+// PRIVATE METHODS //////////////////////////////////////////////////////
+private :
+
+  /** Setup mesh.
+   *
+   * @mesh Mesh to setup.
+   * @param data Test data.
+   */
+  void _setupMesh(Mesh* const mesh,
+		  const MeshDataCohesive& data);
+
+  /** Test reorder().
+   *
+   * @param data Test data.
+   */
+  void _testReorder(const MeshDataCohesive& data);
+
+}; // class TestReverseCuthillMcKee
+
+#endif // pylith_topology_testreversecuthillmckee_hh
+
+
+// End of file 



More information about the CIG-COMMITS mailing list