[cig-commits] [commit] knepley/upgrade-petsc-interface: Cleanup of some names of Field methods. (d2e775b)

cig_noreply at geodynamics.org cig_noreply at geodynamics.org
Thu Oct 31 17:14:56 PDT 2013


Repository : ssh://geoshell/pylith

On branch  : knepley/upgrade-petsc-interface
Link       : https://github.com/geodynamics/pylith/compare/89e29faba55ec6ad39b71ed64e702e732b9fdc2f...52536faa2c7b081390b2a5999b2d2ed824e13d82

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

commit d2e775bfe2500b54cb20e98649245a6f13e99611
Author: Brad Aagaard <baagaard at usgs.gov>
Date:   Thu Oct 31 17:13:42 2013 -0700

    Cleanup of some names of Field methods.
    
    Improve names of Field methods for creating subfields. Removed
    newSection(void). Added some helper functions for setting DOF in
    sections when newSection(args) won't work.


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

d2e775bfe2500b54cb20e98649245a6f13e99611
 libsrc/pylith/feassemble/IntegratorElasticity.cc |  18 +--
 libsrc/pylith/meshio/CellFilterAvg.cc            |   2 +-
 libsrc/pylith/meshio/OutputManager.cc            |   4 +-
 libsrc/pylith/topology/Field.cc                  | 174 +++++++++++++++--------
 libsrc/pylith/topology/Field.hh                  |  81 +++++++----
 libsrc/pylith/topology/Field.icc                 |   4 +-
 libsrc/pylith/topology/FieldBase.hh              |   7 +-
 modulesrc/topology/Field.i                       |  35 +++--
 unittests/libtests/bc/TestDirichletBC.cc         |  24 ++--
 unittests/libtests/bc/TestDirichletBCMulti.cc    |  24 ++--
 unittests/libtests/topology/TestFieldMesh.cc     |  41 ++----
 unittests/libtests/topology/TestFieldMesh.hh     |   4 -
 unittests/libtests/topology/TestFieldSubMesh.cc  |  25 +---
 unittests/libtests/topology/TestFieldSubMesh.hh  |   4 -
 14 files changed, 254 insertions(+), 193 deletions(-)

diff --git a/libsrc/pylith/feassemble/IntegratorElasticity.cc b/libsrc/pylith/feassemble/IntegratorElasticity.cc
index e38b49b..b5a01b3 100644
--- a/libsrc/pylith/feassemble/IntegratorElasticity.cc
+++ b/libsrc/pylith/feassemble/IntegratorElasticity.cc
@@ -319,7 +319,7 @@ pylith::feassemble::IntegratorElasticity::cellField(const char* name,
       _allocateTensorField(mesh);
       topology::Field& buffer = _outputFields->get("buffer (tensor)");    
       _material->getField(&buffer, "total_strain");
-      buffer.addDimensionOkay(true);
+      buffer.dimensionalizeOkay(true);
       PYLITH_METHOD_RETURN(buffer);
 
     } else { // must calculate total strain
@@ -328,7 +328,7 @@ pylith::feassemble::IntegratorElasticity::cellField(const char* name,
       topology::Field& buffer = _outputFields->get("buffer (tensor)");
       buffer.label("total_strain");
       buffer.scale(1.0);
-      buffer.addDimensionOkay(true);
+      buffer.dimensionalizeOkay(true);
       _calcStrainStressField(&buffer, name, fields);
       PYLITH_METHOD_RETURN(buffer);
 
@@ -341,7 +341,7 @@ pylith::feassemble::IntegratorElasticity::cellField(const char* name,
       _allocateTensorField(mesh);
       topology::Field& buffer = _outputFields->get("buffer (tensor)");    
       _material->getField(&buffer, "stress");
-      buffer.addDimensionOkay(true);
+      buffer.dimensionalizeOkay(true);
       PYLITH_METHOD_RETURN(buffer);
 
     } else { // must calculate stress from strain
@@ -354,7 +354,7 @@ pylith::feassemble::IntegratorElasticity::cellField(const char* name,
 	_material->getField(&buffer, "total_strain");
 	buffer.label(name);
 	buffer.scale(_normalizer->pressureScale());
-	buffer.addDimensionOkay(true);
+	buffer.dimensionalizeOkay(true);
 	_calcStressFromStrain(&buffer);
 	PYLITH_METHOD_RETURN(buffer);
 
@@ -365,7 +365,7 @@ pylith::feassemble::IntegratorElasticity::cellField(const char* name,
 	  _outputFields->get("buffer (tensor)");
 	buffer.label("stress");
 	buffer.scale(_normalizer->pressureScale());
-	buffer.addDimensionOkay(true);
+	buffer.dimensionalizeOkay(true);
 	_calcStrainStressField(&buffer, name, fields);
 	PYLITH_METHOD_RETURN(buffer);
 	
@@ -378,7 +378,7 @@ pylith::feassemble::IntegratorElasticity::cellField(const char* name,
       _outputFields->add("buffer (other)", "buffer");
     topology::Field& buffer = _outputFields->get("buffer (other)");
     _material->stableTimeStepImplicit(mesh, &buffer);
-    buffer.addDimensionOkay(true);
+    buffer.dimensionalizeOkay(true);
     PYLITH_METHOD_RETURN(buffer);
     
   } else if (0 == strcasecmp(name, "stable_dt_explicit")) {
@@ -386,7 +386,7 @@ pylith::feassemble::IntegratorElasticity::cellField(const char* name,
       _outputFields->add("buffer (other)", "buffer");
     topology::Field& buffer = _outputFields->get("buffer (other)");
     _material->stableTimeStepExplicit(mesh, _quadrature, &buffer);
-    buffer.addDimensionOkay(true);
+    buffer.dimensionalizeOkay(true);
     PYLITH_METHOD_RETURN(buffer);
     
   } else {
@@ -395,7 +395,7 @@ pylith::feassemble::IntegratorElasticity::cellField(const char* name,
     topology::Field& buffer =
       _outputFields->get("buffer (other)");
     _material->getField(&buffer, name);
-    buffer.addDimensionOkay(true);
+    buffer.dimensionalizeOkay(true);
     PYLITH_METHOD_RETURN(buffer);
     
   } // if/else
@@ -476,7 +476,7 @@ pylith::feassemble::IntegratorElasticity::_allocateTensorField(const topology::M
     buffer.newSection(cellsTmp, numQuadPts*tensorSize);
     buffer.allocate();
     buffer.vectorFieldType(topology::FieldBase::MULTI_TENSOR);
-    buffer.addDimensionOkay(true);
+    buffer.dimensionalizeOkay(true);
   } // if
 
   PYLITH_METHOD_END;
diff --git a/libsrc/pylith/meshio/CellFilterAvg.cc b/libsrc/pylith/meshio/CellFilterAvg.cc
index b69d2e1..0aff006 100644
--- a/libsrc/pylith/meshio/CellFilterAvg.cc
+++ b/libsrc/pylith/meshio/CellFilterAvg.cc
@@ -161,7 +161,7 @@ pylith::meshio::CellFilterAvg::filter(const topology::Field& fieldIn,
 
   _fieldAvg->label(fieldIn.label());
   _fieldAvg->scale(fieldIn.scale());
-  _fieldAvg->addDimensionOkay(true);
+  _fieldAvg->dimensionalizeOkay(true);
 
   topology::VecVisitorMesh fieldAvgVisitor(*_fieldAvg);
   PetscScalar* fieldAvgArray = fieldAvgVisitor.localArray();
diff --git a/libsrc/pylith/meshio/OutputManager.cc b/libsrc/pylith/meshio/OutputManager.cc
index 54c82b0..5a9685d 100644
--- a/libsrc/pylith/meshio/OutputManager.cc
+++ b/libsrc/pylith/meshio/OutputManager.cc
@@ -235,7 +235,7 @@ pylith::meshio::OutputManager::_dimension(topology::Field& fieldIn)
   if (1.0 == fieldIn.scale())
     PYLITH_METHOD_RETURN(fieldIn);
 
-  if (fieldIn.addDimensionOkay()) {
+  if (fieldIn.dimensionalizeOkay()) {
     fieldIn.dimensionalize();
     PYLITH_METHOD_RETURN(fieldIn);
   } else {
@@ -287,7 +287,7 @@ pylith::meshio::OutputManager::_dimension(topology::Field& fieldIn)
     } // if
     topology::Field& fieldOut = _fields->get(fieldName.c_str());
     fieldOut.copy(fieldIn);
-    fieldOut.addDimensionOkay(true);
+    fieldOut.dimensionalizeOkay(true);
     fieldOut.dimensionalize();
 
     PYLITH_METHOD_RETURN(fieldOut);
diff --git a/libsrc/pylith/topology/Field.cc b/libsrc/pylith/topology/Field.cc
index 959612c..2b129f2 100644
--- a/libsrc/pylith/topology/Field.cc
+++ b/libsrc/pylith/topology/Field.cc
@@ -41,6 +41,7 @@ pylith::topology::Field::Field(const Mesh& mesh) :
   PYLITH_METHOD_BEGIN;
 
   _metadata["default"].label = "unknown";
+  _metadata["default"].index = 0;
   _metadata["default"].vectorFieldType = OTHER;
   _metadata["default"].scale = 1.0;
   _metadata["default"].dimsOkay = false;
@@ -241,13 +242,81 @@ pylith::topology::Field::sectionSize(void) const
 } // sectionSize
 
 // ----------------------------------------------------------------------
-// Create seive section.
+// Set chart for solution.
 void
-pylith::topology::Field::newSection(void)
-{ // newSection
-  // Clear memory
+pylith::topology::Field::setupSolnChart(void)
+{ // setupSolnChart
+  PYLITH_METHOD_BEGIN;
+
   clear();
-} // newSection
+  assert(_dm);
+
+  // :TODO: Update this to use discretization information after removing FIAT.
+
+  // :KLUDGE: Assume solution has DOF over vertices and hybrid edges.
+  PetscErrorCode err;
+  // Get range of vertices.
+  PetscInt pStart = -1;
+  PetscInt pEnd = -1;
+  err = DMPlexGetDepthStratum(_dm, 0, &pStart, &pEnd);PYLITH_CHECK_ERROR(err);
+  // Get last edge and 
+  PetscInt eEnd = -1;
+  PetscInt eMax = -1;
+  err = DMPlexGetDepthStratum(_dm, 1, NULL, &eEnd);PYLITH_CHECK_ERROR(err);
+  err = DMPlexGetHybridBounds(_dm, NULL, NULL, &eMax, NULL);PYLITH_CHECK_ERROR(err);
+  // If have hybrid edges, extend chart to include hybrid edges; otherwise just use points.
+  if (eEnd > eMax) {
+    pEnd = eEnd;
+  } // if
+
+  PetscSection s = NULL;
+  if (pStart < pEnd) {
+    err = DMGetDefaultSection(_dm, &s);PYLITH_CHECK_ERROR(err);
+    err = DMSetDefaultGlobalSection(_dm, NULL);PYLITH_CHECK_ERROR(err);
+    err = PetscSectionSetChart(s, pStart, pEnd);PYLITH_CHECK_ERROR(err);
+  } else { // create empty chart
+    err = DMGetDefaultSection(_dm, &s);PYLITH_CHECK_ERROR(err);
+    err = DMSetDefaultGlobalSection(_dm, NULL);PYLITH_CHECK_ERROR(err);
+    err = PetscSectionSetChart(s, 0, 0);PYLITH_CHECK_ERROR(err);
+  } // if/else
+
+  PYLITH_METHOD_END;
+} // setupSolnChart
+
+
+// ----------------------------------------------------------------------
+// Setup default DOF for solution.
+void
+pylith::topology::Field::setupSolnDof(const int fiberDim)
+{ // setupSolnDof
+  PYLITH_METHOD_BEGIN;
+
+  clear();
+  assert(_dm);
+
+  // :TODO: Update this to use discretization information after removing FIAT.
+
+  // :KLUDGE: Assume solution has DOF over vertices.
+  const int indexDisp = subfieldMetadata("displacement").index;
+
+  PetscErrorCode err;
+  // Get range of vertices.
+  PetscInt pStart = -1;
+  PetscInt pEnd = -1;
+  err = DMPlexGetDepthStratum(_dm, 0, &pStart, &pEnd);PYLITH_CHECK_ERROR(err);
+
+  PetscSection s = NULL;
+  err = DMGetDefaultSection(_dm, &s);PYLITH_CHECK_ERROR(err);
+  for (PetscInt p = pStart; p < pEnd; ++p) {
+    err = PetscSectionSetDof(s, p, fiberDim);PYLITH_CHECK_ERROR(err);
+
+    // Set DOF in displacement subfield
+    err = PetscSectionSetFieldDof(s, p, indexDisp, fiberDim);PYLITH_CHECK_ERROR(err);
+  } // for
+
+  PYLITH_METHOD_END;
+} // setupSolnDof
+
 
 // ----------------------------------------------------------------------
 // Create PETSc section and set chart and fiber dimesion for a list of
@@ -539,7 +608,8 @@ pylith::topology::Field::clear(void)
   err = VecDestroy(&_globalVec);PYLITH_CHECK_ERROR(err);
   err = VecDestroy(&_localVec);PYLITH_CHECK_ERROR(err);
 
-  _tmpFields.clear();
+  _subfieldComps.clear();
+  _metadata["default"].index = 0;
   _metadata["default"].scale = 1.0;
   _metadata["default"].vectorFieldType = OTHER;
   _metadata["default"].dimsOkay = false;
@@ -1184,29 +1254,6 @@ pylith::topology::Field::scatterGlobalToLocal(const PetscVec vector,
 } // scatterGlobalToLocal
 
 // ----------------------------------------------------------------------
-// Get fiber dimension associated with section (only works if fiber
-// dimension is uniform).
-int
-pylith::topology::Field::_getFiberDim(void)
-{ // _getFiberDim
-  PYLITH_METHOD_BEGIN;
-
-  assert(_dm);
-
-  PetscSection s = NULL;
-  PetscInt pStart, pEnd;
-  int fiberDimLocal, fiberDim = 0;
-  PetscErrorCode err;
-
-  err = DMGetDefaultSection(_dm, &s);PYLITH_CHECK_ERROR(err);
-  err = PetscSectionGetChart(s, &pStart, &pEnd);PYLITH_CHECK_ERROR(err);
-  if (pEnd > pStart) {err = PetscSectionGetDof(s, pStart, &fiberDimLocal);PYLITH_CHECK_ERROR(err);}
-  MPI_Allreduce(&fiberDimLocal, &fiberDim, 1, MPI_INT, MPI_MAX, _mesh.comm());
-
-  PYLITH_METHOD_RETURN(fiberDim);
-} // _getFiberDim
-
-// ----------------------------------------------------------------------
 // Get scatter for given context.
 pylith::topology::Field::ScatterInfo&
 pylith::topology::Field::_getScatter(const char* context,
@@ -1273,48 +1320,49 @@ pylith::topology::Field::_getScatter(const char* context) const
 // ----------------------------------------------------------------------
 // Experimental
 void
-pylith::topology::Field::addField(const char *name,
-				  int numComponents)
-{ // addField
+pylith::topology::Field::subfieldAdd(const char *name,
+				     int numComponents)
+{ // subfieldAdd
   PYLITH_METHOD_BEGIN;
 
   // Keep track of name/components until setup
-  _tmpFields[name] = numComponents;
+  _subfieldComps[name] = numComponents;
   _metadata[name]  = _metadata["default"];
 
   PYLITH_METHOD_END;
-} // addField
+} // subfieldAdd
 
 // ----------------------------------------------------------------------
 void
-pylith::topology::Field::setupFields(void)
-{ // setupFields
+pylith::topology::Field::subfieldsSetup(void)
+{ // subfieldsSetup
   PYLITH_METHOD_BEGIN;
 
   assert(_dm);
-  // Keep track of name/components until setup
-  PetscSection section;
-  PetscInt f = 0;
+
+  // Setup section now that we know the total number of sub-fields and components.
+  PetscSection section = NULL;
+  PetscInt iField = 0;
   PetscErrorCode err = DMGetDefaultSection(_dm, &section);PYLITH_CHECK_ERROR(err);assert(section);
-  err = PetscSectionSetNumFields(section, _tmpFields.size());PYLITH_CHECK_ERROR(err);
-  for(std::map<std::string, int>::const_iterator f_iter = _tmpFields.begin(); f_iter != _tmpFields.end(); ++f_iter, ++f) {
-    err = PetscSectionSetFieldName(section, f, f_iter->first.c_str());PYLITH_CHECK_ERROR(err);
-    err = PetscSectionSetFieldComponents(section, f, f_iter->second);PYLITH_CHECK_ERROR(err);
+  err = PetscSectionSetNumFields(section, _subfieldComps.size());PYLITH_CHECK_ERROR(err);
+  for(std::map<std::string, int>::const_iterator f_iter = _subfieldComps.begin(); f_iter != _subfieldComps.end(); ++f_iter, ++iField) {
+    err = PetscSectionSetFieldName(section, iField, f_iter->first.c_str());PYLITH_CHECK_ERROR(err);
+    err = PetscSectionSetFieldComponents(section, iField, f_iter->second);PYLITH_CHECK_ERROR(err);
+    _metadata[f_iter->first].index = iField;
   } // for
-  _tmpFields.clear();
 
   PYLITH_METHOD_END;
-} // setupFields
+} // subfieldsSetup
 
 // ----------------------------------------------------------------------
 void
-pylith::topology::Field::updateDof(const char *name,
-				   const DomainEnum domain,
-				   int fiberDim)
-{ // updateDof
+pylith::topology::Field::subfieldSetDof(const char *name,
+					const DomainEnum domain,
+					int fiberDim)
+{ // subfieldSetDof
   PYLITH_METHOD_BEGIN;
 
-  PetscInt pStart, pEnd, f = 0;
+  PetscInt pStart, pEnd;
   PetscErrorCode err;
 
   assert(_dm);
@@ -1338,18 +1386,28 @@ pylith::topology::Field::updateDof(const char *name,
   }
   PetscSection section = NULL;
   err = DMGetDefaultSection(_dm, &section);PYLITH_CHECK_ERROR(err);assert(section);
-  for(map_type::const_iterator f_iter = _metadata.begin(); f_iter != _metadata.end(); ++f_iter) {
-    if (f_iter->first == name) break;
-    if (f_iter->first == "default") continue;
-    ++f;
-  } // for
-  assert(f < _metadata.size());
+  const int iField = _metadata[name].index;
   for(PetscInt p = pStart; p < pEnd; ++p) {
     //err = PetscSectionAddDof(section, p, fiberDim);PYLITH_CHECK_ERROR(err); // Future use
-    err = PetscSectionSetFieldDof(section, p, f, fiberDim);PYLITH_CHECK_ERROR(err);
+    err = PetscSectionSetFieldDof(section, p, iField, fiberDim);PYLITH_CHECK_ERROR(err);
   } // for
 
   PYLITH_METHOD_END;
-} // updateDof
+} // subfieldSetDof
+
+// ----------------------------------------------------------------------
+// Get metadata for subfield.
+const pylith::topology::FieldBase::Metadata&
+pylith::topology::Field::subfieldMetadata(const char* name)
+{ // subfieldMetadata
+  try {
+    const Metadata& metadata = _metadata[name];
+    return metadata;
+  } catch (std::exception& err) {
+    std::ostringstream msg;
+    msg << "Could not find subfield '" << name << "' in field '" << label() << "'." << std::endl;
+    throw std::runtime_error(msg.str());
+  } // try/catch
+} // subfieldmetadata
 
 // End of file 
diff --git a/libsrc/pylith/topology/Field.hh b/libsrc/pylith/topology/Field.hh
index 720ee28..7c95101 100644
--- a/libsrc/pylith/topology/Field.hh
+++ b/libsrc/pylith/topology/Field.hh
@@ -40,6 +40,22 @@
  * mesh.
  *
  * Extends PETSc section and vector by adding metadata.
+ *
+ * General steps for setting up a field:
+ *
+ * 1. Set the number of subfields and the number of components per subfield.
+ * 2. Set the chart.
+ * 3. Set the DOF (fiberdim) for each point in the chart.
+ * 4. Set any constraints (known DOF).
+ * 5. Allocate.
+ * 6. Set the indices for the constrained DOF.
+ *
+ * For local fields associated with parameters, we do not have steps 4
+ * and 6. The newSection() methods provide a convenient interface for
+ * steps 2-3.
+ *
+ * For the solution field, etc, the integrators know how to layout the
+ * DOF over the points (vertices, edges, faces).
  */
 class pylith::topology::Field : public FieldBase
 { // Field
@@ -150,13 +166,13 @@ public :
    *
    * @param value True if it is okay to dimensionalize field.
    */
-  void addDimensionOkay(const bool value);
+  void dimensionalizeOkay(const bool value);
 
   /** Set flag indicating whether it is okay to dimensionalize field.
    *
    * @param value True if it is okay to dimensionalize field.
    */
-  bool addDimensionOkay(void) const;
+  bool dimensionalizeOkay(void) const;
 
   /** Get spatial dimension of domain.
    *
@@ -200,11 +216,14 @@ public :
    */
   PetscVec globalVector(void) const;
 
-  /** Create PETSc section.
+  /// Set chart for solution.
+  void setupSolnChart(void);
+
+  /** Set default DOF for solution.
    *
-   * @note Don't forget to call label().
+   * @param fiberDim Total number of components in solution.
    */
-  void newSection(void);
+  void setupSolnDof(const int fiberDim);
 
   /** Create PETSc section and set chart and fiber dimesion for a list
    * of points.
@@ -276,20 +295,40 @@ public :
    */
   void cloneSection(const Field& src);
 
-  /** :MATT: ADD DOCUMENTATION
+  /** Add subfield to current field.
+   *
+   * Should be followed by calls to subfieldsSetup() and subfieldSetDof().
+   *
+   * @param name Name of subfield.
+   * @param numComponents Number of components in subfield.
+   */
+  void subfieldAdd(const char *name, 
+		   int numComponents);
+  
+  /** Setup sections for subfields.
+   *
+   * Should be preceded by calls to subfieldAdd() and followed by calls to subfieldSetDof().
    */
-  void addField(const char *name,
-		int numComponents);
+  void subfieldsSetup(void);
   
-  /** :MATT: ADD DOCUMENTATION
+  /** Convenience method for setting number of DOF (fiberdim) for subfield at points.
+   *
+   * Should be preceded by calls to subfieldAdd() and subfieldsSetup().
+   *
+   * @param name Name of subfield.
+   * @param domain Point classification for subfield.
+   * @param fiberDim Number of subfield components per point.
    */
-  void setupFields(void);
+  void subfieldSetDof(const char *name, 
+		      const pylith::topology::FieldBase::DomainEnum domain, 
+		      const int fiberDim);
   
-  /** :MATT: ADD DOCUMENTATION
+  /** Get metadata for subfield.
+   *
+   * @param name Name of subfield.
+   * @returns Metadata for subfield.
    */
-  void updateDof(const char *name,
-		 const DomainEnum domain,
-		 const int fiberDim);
+  const Metadata& subfieldMetadata(const char* name);
 
   /// Clear variables associated with section.
   void clear(void);
@@ -453,14 +492,6 @@ private :
 // PRIVATE METHODS //////////////////////////////////////////////////////
 private :
 
-  /** Get fiber dimension associated with section (only works if fiber
-   * dimension is uniform).
-   *
-   * Fiber dimension is determined from the first point on each
-   * processor with the maximum value gathered across the processors.
-   */
-  int _getFiberDim(void);
-
   /** Get scatter for given context.
    *
    * @param context Context for scatter.
@@ -480,7 +511,8 @@ private :
 // PROTECTED TYPEDEFS ///////////////////////////////////////////////////
 protected :
 
-  typedef std::map< std::string, Metadata > map_type;
+  typedef std::map<std::string, Metadata> map_type;
+  typedef std::map<std::string, int> fieldcomps_type;
 
 // PRIVATE MEMBERS //////////////////////////////////////////////////////
 private :
@@ -490,11 +522,10 @@ private :
   const Mesh& _mesh; ///< Mesh associated with section.
   scatter_map_type _scatters; ///< Collection of scatters.
 
-  /* New construction */
   PetscDM _dm; ///< Manages the PetscSection
   PetscVec _globalVec; ///< Global PETSc vector
   PetscVec _localVec; ///< Local PETSc vector
-  std::map<std::string, int> _tmpFields; ///< Map of fields to bundle together.
+  fieldcomps_type _subfieldComps; ///< Map of subfields bundled together.
 
 // NOT IMPLEMENTED //////////////////////////////////////////////////////
 private :
diff --git a/libsrc/pylith/topology/Field.icc b/libsrc/pylith/topology/Field.icc
index c37a418..dfcc753 100644
--- a/libsrc/pylith/topology/Field.icc
+++ b/libsrc/pylith/topology/Field.icc
@@ -114,14 +114,14 @@ pylith::topology::Field::scale(void) const {
 // Set flag indicating whether it is okay to dimensionalize field.
 inline
 void
-pylith::topology::Field::addDimensionOkay(const bool value) {
+pylith::topology::Field::dimensionalizeOkay(const bool value) {
   _metadata["default"].dimsOkay = value;
 }
 
 // Set flag indicating whether it is okay to dimensionalize field.
 inline
 bool
-pylith::topology::Field::addDimensionOkay(void) const {
+pylith::topology::Field::dimensionalizeOkay(void) const {
   return const_cast<Field*>(this)->_metadata["default"].dimsOkay;
 }
 
diff --git a/libsrc/pylith/topology/FieldBase.hh b/libsrc/pylith/topology/FieldBase.hh
index 3c3fbe5..2d7e1c2 100644
--- a/libsrc/pylith/topology/FieldBase.hh
+++ b/libsrc/pylith/topology/FieldBase.hh
@@ -63,10 +63,11 @@ public :
 public :
 
   struct Metadata {
-    std::string label; // Label for field.
+    std::string label; //< Label for field.
     VectorFieldEnum vectorFieldType; ///< Type of vector field.
-    PylithScalar scale; // Dimension scale associated with values.
-    bool dimsOkay; // Ok to replace nondimensionalized values 
+    PylithScalar scale; //< Dimension scale associated with values.
+    int index; //< Index for corresponding PETSc section (subfields).
+    bool dimsOkay; //< Ok to replace nondimensionalized values 
                    // with dimensionalized values.
   }; // Metadata
 
diff --git a/modulesrc/topology/Field.i b/modulesrc/topology/Field.i
index 2540e7c..8987683 100644
--- a/modulesrc/topology/Field.i
+++ b/modulesrc/topology/Field.i
@@ -89,13 +89,13 @@ namespace pylith {
        *
        * @param value True if it is okay to dimensionalize field.
        */
-      void addDimensionOkay(const bool value);
+      void dimensionalizeOkay(const bool value);
       
       /** Set flag indicating whether it is okay to dimensionalize field.
        *
        * @param value True if it is okay to dimensionalize field.
        */
-      bool addDimensionOkay(void) const;
+      bool dimensionalizeOkay(void) const;
       
       /** Get spatial dimension of domain.
        *
@@ -121,9 +121,6 @@ namespace pylith {
        */
       bool hasSection(void) const;
 
-      /// Create PETSc section.
-      void newSection(void);
-
       /** Create PETSc section and set chart and fiber dimesion.
        *
        * @param domain Type of points over which to define section.
@@ -143,11 +140,33 @@ namespace pylith {
        */
       void cloneSection(const Field& src);
 
-      void addField(const char *name, int numComponents);
+      /** Add subfield to current field.
+       *
+       * Should be followed by calls to subfieldsSetup() and subfieldSetDof().
+       *
+       * @param name Name of subfield.
+       * @param numComponents Number of components in subfield.
+       */
+      void subfieldAdd(const char *name, 
+		       int numComponents);
 
-      void setupFields();
+      /** Setup sections for subfields.
+       *
+       * Should be preceded by calls to subfieldAdd() and followed by calls to subfieldSetDof().
+       */
+      void subfieldsSetup(void);
 
-      void updateDof(const char *name, const pylith::topology::FieldBase::DomainEnum domain, const int fiberDim);
+      /** Convenience method for setting number of DOF (fiberdim) for subfield at points.
+       *
+       * Should be preceded by calls to subfieldAdd() and subfieldsSetup().
+       *
+       * @param name Name of subfield.
+       * @param domain Point classification for subfield.
+       * @param fiberDim Number of subfield components per point.
+       */
+      void subfieldSetDof(const char *name, 
+			  const pylith::topology::FieldBase::DomainEnum domain, 
+			  const int fiberDim);
 
       /// Clear variables associated with section.
       void clear(void);
diff --git a/unittests/libtests/bc/TestDirichletBC.cc b/unittests/libtests/bc/TestDirichletBC.cc
index 8c04fab..7d2668b 100644
--- a/unittests/libtests/bc/TestDirichletBC.cc
+++ b/unittests/libtests/bc/TestDirichletBC.cc
@@ -174,10 +174,10 @@ pylith::bc::TestDirichletBC::testSetConstraintSizes(void)
   const int fiberDim = _data->numDOF;
   const int spaceDim = mesh.dimension();
   topology::Field field(mesh);
-  field.addField("bc", spaceDim);
-  field.setupFields();
+  field.subfieldAdd("bc", spaceDim);
+  field.subfieldsSetup();
   field.newSection(pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
-  field.updateDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
+  field.subfieldSetDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
   bc.setConstraintSizes(field); // Does not handle fields right now
   field.allocate();
 
@@ -237,10 +237,10 @@ pylith::bc::TestDirichletBC::testSetConstraints(void)
   const int spaceDim = mesh.dimension();
   const int fiberDim = _data->numDOF;
   topology::Field field(mesh);
-  field.addField("bc", spaceDim);
-  field.setupFields();
+  field.subfieldAdd("bc", spaceDim);
+  field.subfieldsSetup();
   field.newSection(pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
-  field.updateDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
+  field.subfieldSetDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
   bc.setConstraintSizes(field);
   field.allocate();
   bc.setConstraints(field);
@@ -304,10 +304,10 @@ pylith::bc::TestDirichletBC::testSetField(void)
 
   const int fiberDim = _data->numDOF;
   topology::Field field(mesh);
-  field.addField("bc", fiberDim);
-  field.setupFields();
+  field.subfieldAdd("bc", fiberDim);
+  field.subfieldsSetup();
   field.newSection(pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
-  field.updateDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
+  field.subfieldSetDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
   bc.setConstraintSizes(field);
   field.allocate();
   bc.setConstraints(field);
@@ -412,10 +412,10 @@ pylith::bc::TestDirichletBC::testSetFieldIncr(void)
 
   const int fiberDim = _data->numDOF;
   topology::Field field(mesh);
-  field.addField("bc", fiberDim);
-  field.setupFields();
+  field.subfieldAdd("bc", fiberDim);
+  field.subfieldsSetup();
   field.newSection(pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
-  field.updateDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
+  field.subfieldSetDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
   bc.setConstraintSizes(field);
   field.allocate();
   bc.setConstraints(field);
diff --git a/unittests/libtests/bc/TestDirichletBCMulti.cc b/unittests/libtests/bc/TestDirichletBCMulti.cc
index 6b6e1e3..5a2265f 100644
--- a/unittests/libtests/bc/TestDirichletBCMulti.cc
+++ b/unittests/libtests/bc/TestDirichletBCMulti.cc
@@ -77,10 +77,10 @@ pylith::bc::TestDirichletBCMulti::testSetConstraintSizes(void)
 
   const int fiberDim = _data->numDOF;
   topology::Field field(mesh);
-  field.addField("bc", fiberDim);
-  field.setupFields();
+  field.subfieldAdd("bc", fiberDim);
+  field.subfieldsSetup();
   field.newSection(pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
-  field.updateDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
+  field.subfieldSetDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
   bcA.setConstraintSizes(field);
   bcB.setConstraintSizes(field);
   bcC.setConstraintSizes(field);
@@ -128,10 +128,10 @@ pylith::bc::TestDirichletBCMulti::testSetConstraints(void)
 
   const int fiberDim = _data->numDOF;
   topology::Field field(mesh);
-  field.addField("bc", fiberDim);
-  field.setupFields();
+  field.subfieldAdd("bc", fiberDim);
+  field.subfieldsSetup();
   field.newSection(pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
-  field.updateDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
+  field.subfieldSetDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
   bcA.setConstraintSizes(field);
   bcB.setConstraintSizes(field);
   bcC.setConstraintSizes(field);
@@ -192,10 +192,10 @@ pylith::bc::TestDirichletBCMulti::testSetField(void)
 
   const int fiberDim = _data->numDOF;
   topology::Field field(mesh);
-  field.addField("bc", fiberDim);
-  field.setupFields();
+  field.subfieldAdd("bc", fiberDim);
+  field.subfieldsSetup();
   field.newSection(pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
-  field.updateDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
+  field.subfieldSetDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
   bcA.setConstraintSizes(field);
   bcB.setConstraintSizes(field);
   bcC.setConstraintSizes(field);
@@ -272,10 +272,10 @@ pylith::bc::TestDirichletBCMulti::testSetFieldIncr(void)
 
   const int fiberDim = _data->numDOF;
   topology::Field field(mesh);
-  field.addField("bc", fiberDim);
-  field.setupFields();
+  field.subfieldAdd("bc", fiberDim);
+  field.subfieldsSetup();
   field.newSection(pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
-  field.updateDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
+  field.subfieldSetDof("bc", pylith::topology::FieldBase::VERTICES_FIELD, fiberDim);
   bcA.setConstraintSizes(field);
   bcB.setConstraintSizes(field);
   bcC.setConstraintSizes(field);
diff --git a/unittests/libtests/topology/TestFieldMesh.cc b/unittests/libtests/topology/TestFieldMesh.cc
index 0b903ef..ebf3021 100644
--- a/unittests/libtests/topology/TestFieldMesh.cc
+++ b/unittests/libtests/topology/TestFieldMesh.cc
@@ -158,7 +158,7 @@ pylith::topology::TestFieldMesh::testScale(void)
 } // testScale
 
 // ----------------------------------------------------------------------
-// Test addDimensionOkay().
+// Test dimensionalizeOkay().
 void
 pylith::topology::TestFieldMesh::testAddDimensionOkay(void)
 { // testAddDimensionOkay
@@ -171,7 +171,7 @@ pylith::topology::TestFieldMesh::testAddDimensionOkay(void)
   Field field(mesh);
 
   CPPUNIT_ASSERT_EQUAL(false, field._metadata[label].dimsOkay);
-  field.addDimensionOkay(true);
+  field.dimensionalizeOkay(true);
   CPPUNIT_ASSERT_EQUAL(true, field._metadata[label].dimsOkay);
 
   PYLITH_METHOD_END;
@@ -269,27 +269,6 @@ pylith::topology::TestFieldMesh::testHasSection(void)
 } // testHasSection
 
 // ----------------------------------------------------------------------
-// Test newSection().
-void
-pylith::topology::TestFieldMesh::testNewSection(void)
-{ // testNewSection
-  PYLITH_METHOD_BEGIN;
-
-  Mesh mesh;
-  _buildMesh(&mesh);
-
-  Field field(mesh);
-  const std::string& label = "field A";
-  field.label(label.c_str());
-
-  field.newSection();
-  PetscDM dmMesh = mesh.dmMesh();CPPUNIT_ASSERT(dmMesh);
-  PetscSection section = field.petscSection();CPPUNIT_ASSERT(section);
-
-  PYLITH_METHOD_END;
-} // testNewSection
-
-// ----------------------------------------------------------------------
 // Test newSection(points).
 void
 pylith::topology::TestFieldMesh::testNewSectionPoints(void)
@@ -549,7 +528,7 @@ pylith::topology::TestFieldMesh::testClear(void)
 
   field.scale(2.0);
   field.vectorFieldType(Field::TENSOR);
-  field.addDimensionOkay(true);
+  field.dimensionalizeOkay(true);
   
   field.clear();
 
@@ -956,7 +935,7 @@ pylith::topology::TestFieldMesh::testDimensionalize(void)
   } // setup field
 
   field.scale(scale);
-  field.addDimensionOkay(true);
+  field.dimensionalizeOkay(true);
   field.dimensionalize();
 
   VecVisitorMesh fieldVisitor(field);
@@ -1332,14 +1311,14 @@ pylith::topology::TestFieldMesh::testSplitDefault(void)
     for(PetscInt f = 0; f < numFields; ++f) {
       std::ostringstream msg;
       msg << "Field "<<f;
-      fieldSrc.addField(msg.str().c_str(), 1);
+      fieldSrc.subfieldAdd(msg.str().c_str(), 1);
     } // for
-    fieldSrc.setupFields();
+    fieldSrc.subfieldsSetup();
     fieldSrc.newSection(Field::VERTICES_FIELD, spaceDim);
     for(PetscInt f = 0; f < spaceDim; ++f) {
       std::ostringstream msg;
       msg << "Field "<<f;
-      fieldSrc.updateDof(msg.str().c_str(), Field::VERTICES_FIELD, 1);
+      fieldSrc.subfieldSetDof(msg.str().c_str(), Field::VERTICES_FIELD, 1);
     } // for
     PetscSection section = fieldSrc.petscSection();CPPUNIT_ASSERT(section);
     PetscInt iV = 0, iC = 0;
@@ -1426,14 +1405,14 @@ pylith::topology::TestFieldMesh::testCloneSectionSplit(void)
     for(PetscInt f = 0; f < numFields; ++f) {
       std::ostringstream msg;
       msg << "Field "<<f;
-      fieldSrc.addField(msg.str().c_str(), 1);
+      fieldSrc.subfieldAdd(msg.str().c_str(), 1);
     } // for
-    fieldSrc.setupFields();
+    fieldSrc.subfieldsSetup();
     fieldSrc.newSection(Field::VERTICES_FIELD, spaceDim);
     for(PetscInt f = 0; f < spaceDim; ++f) {
       std::ostringstream msg;
       msg << "Field "<<f;
-      fieldSrc.updateDof(msg.str().c_str(), Field::VERTICES_FIELD, 1);
+      fieldSrc.subfieldSetDof(msg.str().c_str(), Field::VERTICES_FIELD, 1);
     } // for
     PetscSection section = fieldSrc.petscSection();
     CPPUNIT_ASSERT(section);
diff --git a/unittests/libtests/topology/TestFieldMesh.hh b/unittests/libtests/topology/TestFieldMesh.hh
index 5006b21..1610231 100644
--- a/unittests/libtests/topology/TestFieldMesh.hh
+++ b/unittests/libtests/topology/TestFieldMesh.hh
@@ -56,7 +56,6 @@ class pylith::topology::TestFieldMesh : public CppUnit::TestFixture
   CPPUNIT_TEST( testChartSize );
   CPPUNIT_TEST( testSectionSize );
   CPPUNIT_TEST( testHasSection );
-  CPPUNIT_TEST( testNewSection );
   CPPUNIT_TEST( testNewSectionPoints );
   CPPUNIT_TEST( testNewSectionPointsArray );
   CPPUNIT_TEST( testNewSectionDomain );
@@ -117,9 +116,6 @@ public :
   /// Test hasSection().
   void testHasSection(void);
 
-  /// Test newSection().
-  void testNewSection(void);
-
   /// Test newSection(points).
   void testNewSectionPoints(void);
 
diff --git a/unittests/libtests/topology/TestFieldSubMesh.cc b/unittests/libtests/topology/TestFieldSubMesh.cc
index 1ee998b..a5140b6 100644
--- a/unittests/libtests/topology/TestFieldSubMesh.cc
+++ b/unittests/libtests/topology/TestFieldSubMesh.cc
@@ -80,7 +80,7 @@ pylith::topology::TestFieldSubMesh::testConstructor(void)
 } // testConstructor
 
 // ----------------------------------------------------------------------
-// Test newSection().
+// Test section().
 void
 pylith::topology::TestFieldSubMesh::testSection(void)
 { // testSection
@@ -133,25 +133,6 @@ pylith::topology::TestFieldSubMesh::testSpaceDim(void)
 } // testSpaceDim
 
 // ----------------------------------------------------------------------
-// Test newSection().
-void
-pylith::topology::TestFieldSubMesh::testNewSection(void)
-{ // testNewSection
-  PYLITH_METHOD_BEGIN;
-
-  Mesh mesh;
-  _buildMesh(&mesh);
-  Mesh submesh(mesh, _TestFieldSubMesh::label);
-  Field field(submesh);
-
-  field.newSection();
-  PetscSection section = field.petscSection();
-  CPPUNIT_ASSERT(section);
-
-  PYLITH_METHOD_END;
-} // testNewSection
-
-// ----------------------------------------------------------------------
 // Test newSection(points).
 void
 pylith::topology::TestFieldSubMesh::testNewSectionPoints(void)
@@ -322,7 +303,7 @@ pylith::topology::TestFieldSubMesh::testClear(void)
 
   field.scale(2.0);
   field.vectorFieldType(Field::TENSOR);
-  field.addDimensionOkay(true);
+  field.dimensionalizeOkay(true);
   
   field.clear();
 
@@ -657,7 +638,7 @@ pylith::topology::TestFieldSubMesh::testDimensionalize(void)
   } // setup field
 
   field.scale(scale);
-  field.addDimensionOkay(true);
+  field.dimensionalizeOkay(true);
   field.dimensionalize();
 
   const PylithScalar tolerance = 1.0e-6;
diff --git a/unittests/libtests/topology/TestFieldSubMesh.hh b/unittests/libtests/topology/TestFieldSubMesh.hh
index 5f1be65..1bdfe79 100644
--- a/unittests/libtests/topology/TestFieldSubMesh.hh
+++ b/unittests/libtests/topology/TestFieldSubMesh.hh
@@ -50,7 +50,6 @@ class pylith::topology::TestFieldSubMesh : public CppUnit::TestFixture
   CPPUNIT_TEST( testSection );
   CPPUNIT_TEST( testMesh );
   CPPUNIT_TEST( testSpaceDim );
-  CPPUNIT_TEST( testNewSection );
   CPPUNIT_TEST( testNewSectionPoints );
   CPPUNIT_TEST( testNewSectionDomain );
   CPPUNIT_TEST( testNewSectionField );
@@ -86,9 +85,6 @@ public :
   /// Test spaceDim().
   void testSpaceDim(void);
 
-  /// Test newSection().
-  void testNewSection(void);
-
   /// Test newSection(points).
   void testNewSectionPoints(void);
 



More information about the CIG-COMMITS mailing list