[cig-commits] r22075 - short/3D/PyLith/trunk/libsrc/pylith/meshio

brad at geodynamics.org brad at geodynamics.org
Wed May 15 10:00:24 PDT 2013


Author: brad
Date: 2013-05-15 10:00:24 -0700 (Wed, 15 May 2013)
New Revision: 22075

Modified:
   short/3D/PyLith/trunk/libsrc/pylith/meshio/DataWriterVTK.cc
   short/3D/PyLith/trunk/libsrc/pylith/meshio/DataWriterVTK.hh
Log:
Added caching of fields in DataWriterVTK using Fields object. Required by PETSC VTK viewer because XML files require information about all fields up front.

Modified: short/3D/PyLith/trunk/libsrc/pylith/meshio/DataWriterVTK.cc
===================================================================
--- short/3D/PyLith/trunk/libsrc/pylith/meshio/DataWriterVTK.cc	2013-05-15 16:59:16 UTC (rev 22074)
+++ short/3D/PyLith/trunk/libsrc/pylith/meshio/DataWriterVTK.cc	2013-05-15 17:00:24 UTC (rev 22075)
@@ -22,6 +22,7 @@
 
 #include "pylith/topology/Mesh.hh" // USES Mesh
 #include "pylith/topology/Field.hh" // USES Field
+#include "pylith/topology/Fields.hh" // HOLDSA Fields
 #include "pylith/topology/Stratum.hh" // USES StratumIS
 
 #include <petscdmplex.h>
@@ -42,11 +43,13 @@
   _timeFormat("%f"),
   _viewer(NULL),
   _dm(NULL),
+  _vertexFieldCache(0),
+  _cellFieldCache(0),
+  _precision(6),
   _isOpen(false),
   _isOpenTimeStep(false),
   _wroteVertexHeader(false),
-  _wroteCellHeader(false),
-  _precision(6)
+  _wroteCellHeader(false)
 { // constructor
 } // constructor
 
@@ -64,6 +67,9 @@
 { // deallocate
   PYLITH_METHOD_BEGIN;
 
+  delete _vertexFieldCache; _vertexFieldCache = 0;
+  delete _cellFieldCache; _cellFieldCache = 0;
+
   closeTimeStep(); // Insure time step is closed.
   close(); // Insure clean up.
   DataWriter::deallocate();
@@ -80,6 +86,9 @@
   _timeFormat(w._timeFormat),
   _viewer(NULL),
   _dm(NULL),
+  _vertexFieldCache(0),
+  _cellFieldCache(0),
+  _precision(w._precision),
   _isOpen(w._isOpen),
   _isOpenTimeStep(w._isOpenTimeStep),
   _wroteVertexHeader(w._wroteVertexHeader),
@@ -175,10 +184,19 @@
     } // if
     err = DMDestroy(&_dm);PYLITH_CHECK_ERROR(err);
   } // if
-  _isOpen = false;
 
+  // Clear field caches.
+  if (_vertexFieldCache) {
+    _vertexFieldCache->deallocate();
+  } // if
+  if (_cellFieldCache) {
+    _cellFieldCache->deallocate();
+  } // if
+
   DataWriter::close();
 
+  _isOpen = false;
+
   PYLITH_METHOD_END;
 } // close
 
@@ -246,16 +264,32 @@
   assert(_dm && _dm == mesh.dmMesh());
   assert(_isOpen && _isOpenTimeStep);
 
+  // Cache vertex field since PETSc writer collects all fields and
+  // then writes file. Caching the field locally allows the output
+  // manager to reuse fields as buffers.
+  if (!_vertexFieldCache) {
+    _vertexFieldCache = new topology::Fields(field.mesh());assert(_vertexFieldCache);
+  } // if/else
+  const char* fieldLabel = field.label();
+  if (!_vertexFieldCache->hasField(fieldLabel)) {
+    _vertexFieldCache->add(fieldLabel, fieldLabel);
+    topology::Field& fieldCached = _vertexFieldCache->get(fieldLabel);
+    fieldCached.cloneSection(field);
+  } // if
+  topology::Field& fieldCached = _vertexFieldCache->get(fieldLabel);
+  assert(fieldCached.sectionSize() == field.sectionSize());
+  fieldCached.copy(field);
+
   // Could check the field.petscSection() matches the default section from VecGetDM().
-  PetscVec v = field.localVector();assert(v);
+  PetscVec fieldVec = fieldCached.localVector();assert(fieldVec);
 
   // :KLUDGE: MATT You have a note that this is not fully implemented!
   //
   // Will change to just VecView() once I setup the vectors correctly
   // (use VecSetOperation() to change the view method).
-  PetscViewerVTKFieldType ft = field.vectorFieldType() != topology::FieldBase::VECTOR ? PETSC_VTK_POINT_FIELD : PETSC_VTK_POINT_VECTOR_FIELD;
-  PetscErrorCode err = PetscViewerVTKAddField(_viewer, (PetscObject) _dm, DMPlexVTKWriteAll, ft, (PetscObject) v);PYLITH_CHECK_ERROR(err);
-  err = PetscObjectReference((PetscObject) v);PYLITH_CHECK_ERROR(err); /* Needed because viewer destroys the Vec */
+  PetscViewerVTKFieldType ft = fieldCached.vectorFieldType() != topology::FieldBase::VECTOR ? PETSC_VTK_POINT_FIELD : PETSC_VTK_POINT_VECTOR_FIELD;
+  PetscErrorCode err = PetscViewerVTKAddField(_viewer, (PetscObject) _dm, DMPlexVTKWriteAll, ft, (PetscObject) fieldVec);PYLITH_CHECK_ERROR(err);
+  err = PetscObjectReference((PetscObject) fieldVec);PYLITH_CHECK_ERROR(err); // Viewer destroys Vec
   
   _wroteVertexHeader = true;
 
@@ -274,15 +308,33 @@
 
   assert(_dm && _dm == field.mesh().dmMesh());
   assert(_isOpen && _isOpenTimeStep);
-  PetscVec v = field.localVector();assert(v);
 
+  // Cache cell field since PETSc writer collects all fields and
+  // then writes file. Caching the field locally allows the output
+  // manager to reuse fields as buffers.
+  if (!_cellFieldCache) {
+    _cellFieldCache = new topology::Fields(field.mesh());assert(_cellFieldCache);
+  } // if/else
+  const char* fieldLabel = field.label();
+  if (!_cellFieldCache->hasField(fieldLabel)) {
+    _cellFieldCache->add(fieldLabel, fieldLabel);
+    topology::Field& fieldCached = _cellFieldCache->get(fieldLabel);
+    fieldCached.cloneSection(field);
+  } // if
+  topology::Field& fieldCached = _cellFieldCache->get(fieldLabel);
+  assert(fieldCached.sectionSize() == field.sectionSize());
+  fieldCached.copy(field);
+
+  // Could check the field.petscSection() matches the default section from VecGetDM().
+  PetscVec fieldVec = fieldCached.localVector();assert(fieldVec);
+
   // :KLUDGE: MATT You have a note that this is not fully implemented!
   //
   // Will change to just VecView() once I setup the vectors correctly
   // (use VecSetOperation() to change the view).
-  PetscViewerVTKFieldType ft = field.vectorFieldType() != topology::FieldBase::VECTOR ? PETSC_VTK_CELL_FIELD : PETSC_VTK_CELL_VECTOR_FIELD;
-  PetscErrorCode err = PetscViewerVTKAddField(_viewer, (PetscObject) _dm, DMPlexVTKWriteAll, ft, (PetscObject) v); PYLITH_CHECK_ERROR(err);
-  err = PetscObjectReference((PetscObject) v);PYLITH_CHECK_ERROR(err); /* Needed because viewer destroys the Vec */
+  PetscViewerVTKFieldType ft = fieldCached.vectorFieldType() != topology::FieldBase::VECTOR ? PETSC_VTK_CELL_FIELD : PETSC_VTK_CELL_VECTOR_FIELD;
+  PetscErrorCode err = PetscViewerVTKAddField(_viewer, (PetscObject) _dm, DMPlexVTKWriteAll, ft, (PetscObject) fieldVec); PYLITH_CHECK_ERROR(err);
+  err = PetscObjectReference((PetscObject) fieldVec);PYLITH_CHECK_ERROR(err); // Viewer destroys Vec
   
   _wroteCellHeader = true;
 

Modified: short/3D/PyLith/trunk/libsrc/pylith/meshio/DataWriterVTK.hh
===================================================================
--- short/3D/PyLith/trunk/libsrc/pylith/meshio/DataWriterVTK.hh	2013-05-15 16:59:16 UTC (rev 22074)
+++ short/3D/PyLith/trunk/libsrc/pylith/meshio/DataWriterVTK.hh	2013-05-15 17:00:24 UTC (rev 22075)
@@ -20,6 +20,12 @@
  * @file libsrc/meshio/DataWriterVTK.hh
  *
  * @brief Object for writing finite-element data to VTK file.
+ *
+ * The PETSc VTK viewer collects all fields and then writes them all
+ * at once. This means we need to cache fields locally in order to
+ * allow the output manager to reuse fields for dimensionalizing,
+ * etc. Other writers do not suffer from this restriction, so we
+ * implement this functionality in DataWriterVTK.
  */
 
 #if !defined(pylith_meshio_datawritervtk_hh)
@@ -28,6 +34,7 @@
 // Include directives ---------------------------------------------------
 #include "DataWriter.hh" // ISA DataWriter
 
+#include "pylith/topology/topologyfwd.hh" // HOLDSA Fields
 #include "pylith/utils/petscfwd.h" // HASA PetscDM
 
 // DataWriterVTK --------------------------------------------------------
@@ -172,6 +179,9 @@
   PetscViewer _viewer; ///< Output file
   PetscDM _dm; ///< Handle to PETSc DM for mesh
 
+  topology::Fields* _vertexFieldCache; ///< Cache for vertex fields.
+  topology::Fields* _cellFieldCache; ///< Cache for cell fields.
+
   int _precision; ///< Precision of floating point values in output.
 
   bool _isOpen; ///< True if called open().



More information about the CIG-COMMITS mailing list