[cig-commits] r20059 - in short/3D/PyLith/branches/v1.7-trunk: libsrc/pylith/faults modulesrc/bc modulesrc/faults pylith pylith/bc pylith/faults unittests/libtests/faults unittests/libtests/faults/data unittests/pytests/faults unittests/pytests/faults/data

brad at geodynamics.org brad at geodynamics.org
Wed May 9 15:48:02 PDT 2012


Author: brad
Date: 2012-05-09 15:48:01 -0700 (Wed, 09 May 2012)
New Revision: 20059

Added:
   short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/TractPerturbation.i
   short/3D/PyLith/branches/v1.7-trunk/pylith/faults/TractPerturbation.py
   short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/TestTractPerturbation.py
Modified:
   short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/FaultCohesiveDyn.cc
   short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/FaultCohesiveDyn.hh
   short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/Makefile.am
   short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/TractPerturbation.cc
   short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/TractPerturbation.hh
   short/3D/PyLith/branches/v1.7-trunk/modulesrc/bc/TimeDependent.i
   short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/FaultCohesiveDyn.i
   short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/Makefile.am
   short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/faults.i
   short/3D/PyLith/branches/v1.7-trunk/pylith/Makefile.am
   short/3D/PyLith/branches/v1.7-trunk/pylith/bc/DirichletBoundary.py
   short/3D/PyLith/branches/v1.7-trunk/pylith/bc/Neumann.py
   short/3D/PyLith/branches/v1.7-trunk/pylith/faults/FaultCohesiveDyn.py
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestFaultCohesiveDyn.cc
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestFaultCohesiveDyn.hh
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestTractPerturbation.cc
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestTractPerturbation.hh
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataHex8.cc
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataQuad4.cc
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTet4.cc
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTri3.cc
   short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTri3d.cc
   short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/TestFaultCohesiveDyn.py
   short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/data/Makefile.am
   short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/testfaults.py
Log:
Added use of TractPerturbation in FaultCohesiveDyn object. Updated unit tests. Fixed names of output fields for Neumann and DirichletBoundary fields.

Modified: short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/FaultCohesiveDyn.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/FaultCohesiveDyn.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/FaultCohesiveDyn.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -21,6 +21,7 @@
 #include "FaultCohesiveDyn.hh" // implementation of object methods
 
 #include "CohesiveTopology.hh" // USES CohesiveTopology
+#include "TractPerturbation.hh" // HOLDSA TractPerturbation
 
 #include "pylith/feassemble/Quadrature.hh" // USES Quadrature
 #include "pylith/feassemble/CellGeometry.hh" // USES CellGeometry
@@ -28,6 +29,7 @@
 #include "pylith/topology/SubMesh.hh" // USES SubMesh
 #include "pylith/topology/Field.hh" // USES Field
 #include "pylith/topology/Fields.hh" // USES Fields
+#include "pylith/topology/FieldsNew.hh" // USES FieldsNew
 #include "pylith/topology/Jacobian.hh" // USES Jacobian
 #include "pylith/topology/SolutionFields.hh" // USES SolutionFields
 #include "pylith/friction/FrictionModel.hh" // USES FrictionModel
@@ -53,6 +55,7 @@
 // ----------------------------------------------------------------------
 typedef pylith::topology::Mesh::SieveMesh SieveMesh;
 typedef pylith::topology::Mesh::RealSection RealSection;
+typedef pylith::topology::Mesh::RealUniformSection RealUniformSection;
 typedef pylith::topology::SubMesh::SieveMesh SieveSubMesh;
 
 typedef pylith::topology::Field<pylith::topology::SubMesh>::RestrictVisitor RestrictVisitor;
@@ -64,7 +67,7 @@
 pylith::faults::FaultCohesiveDyn::FaultCohesiveDyn(void) :
   _zeroTolerance(1.0e-10),
   _openFreeSurf(true),
-  _dbInitialTract(0),
+  _tractPerturbation(0),
   _friction(0),
   _jacobian(0),
   _ksp(0)
@@ -84,7 +87,7 @@
 { // deallocate
   FaultCohesiveLagrange::deallocate();
 
-  _dbInitialTract = 0; // :TODO: Use shared pointer
+  _tractPerturbation = 0; // :TODO: Use shared pointer
   _friction = 0; // :TODO: Use shared pointer
 
   delete _jacobian; _jacobian = 0;
@@ -97,10 +100,10 @@
 // ----------------------------------------------------------------------
 // Sets the spatial database for the inital tractions
 void
-pylith::faults::FaultCohesiveDyn::dbInitialTract(spatialdata::spatialdb::SpatialDB* db)
-{ // dbInitial
-  _dbInitialTract = db;
-} // dbInitial
+pylith::faults::FaultCohesiveDyn::tractPerturbation(TractPerturbation* tract)
+{ // tractPerturbation
+  _tractPerturbation = tract;
+} // tractPerturbation
 
 // ----------------------------------------------------------------------
 // Get the friction (constitutive) model.  
@@ -147,7 +150,10 @@
   FaultCohesiveLagrange::initialize(mesh, upDir);
 
   // Get initial tractions using a spatial database.
-  _setupInitialTractions();
+  if (_tractPerturbation) {
+    const topology::Field<topology::SubMesh>& orientation = _fields->get("orientation");
+    _tractPerturbation->initialize(*_faultMesh, orientation, *_normalizer);
+  } // if
 
   // Setup fault constitutive model.
   assert(_friction);
@@ -224,11 +230,22 @@
   scalar_array dispTpdtVertexP(spaceDim);
   scalar_array dispTpdtVertexL(spaceDim);
 
-  scalar_array initialTractionsVertex(spaceDim);
-  ALE::Obj<RealSection> initialTractionsSection;
-  if (_dbInitialTract) {
-    initialTractionsSection = _fields->get("initial traction").section();
-    assert(!initialTractionsSection.isNull());
+  scalar_array tractPerturbVertex(spaceDim);
+  ALE::Obj<RealUniformSection> tractPerturbSection;
+  int tractPerturbIndex = 0;
+  int tractPerturbFiberDim = 0;
+  if (_tractPerturbation) {
+    _tractPerturbation->calculate(t);
+    
+    const topology::FieldsNew<topology::SubMesh>* params = _tractPerturbation->parameterFields();
+    assert(params);
+    tractPerturbSection = params->section();
+    assert(!tractPerturbSection.isNull());
+
+    tractPerturbFiberDim = params->fiberDim();
+    tractPerturbIndex = params->sectionIndex("value");
+    const int valueFiberDim = params->sectionFiberDim("value");
+    assert(valueFiberDim == spaceDim);
   } // if
 
   const ALE::Obj<RealSection>& areaSection = _fields->get("area").section();
@@ -267,13 +284,17 @@
     _logger->eventBegin(restrictEvent);
 #endif
 
-    // Get initial tractions at fault vertex.
-    if (_dbInitialTract) {
-      initialTractionsSection->restrictPoint(v_fault, 
-					     &initialTractionsVertex[0], 
-					     initialTractionsVertex.size());
+    // Get prescribed traction perturbation at fault vertex.
+    if (_tractPerturbation) {
+      assert(tractPerturbFiberDim == tractPerturbSection->getFiberDimension(v_fault));
+      const PylithScalar* paramsVertex = tractPerturbSection->restrictPoint(v_fault);
+      assert(paramsVertex);
+      
+      for (int iDim=0; iDim < spaceDim; ++iDim) {
+	tractPerturbVertex[iDim] = paramsVertex[tractPerturbIndex+iDim];
+      } // for
     } else {
-      initialTractionsVertex = 0.0;
+      tractPerturbVertex = 0.0;
     } // if/else
 
     // Get orientation associated with fault vertex.
@@ -348,7 +369,7 @@
       //
       // Initial (external) tractions oppose (internal) tractions
       // associated with Lagrange multiplier.
-      residualVertexN = areaVertex * (dispTpdtVertexL - initialTractionsVertex);
+      residualVertexN = areaVertex * (dispTpdtVertexL - tractPerturbVertex);
 
     } else { // opening, normal traction should be zero
       if (fabs(tractionNormal) > _zeroTolerance) {
@@ -1473,7 +1494,7 @@
 // Get vertex field associated with integrator.
 const pylith::topology::Field<pylith::topology::SubMesh>&
 pylith::faults::FaultCohesiveDyn::vertexField(const char* name,
-                                               const topology::SolutionFields* fields)
+					      const topology::SolutionFields* fields)
 { // vertexField
   assert(_faultMesh);
   assert(_quadrature);
@@ -1555,17 +1576,6 @@
     buffer.copy(dirSection);
     return buffer;
 
-  } else if (0 == strcasecmp("initial_traction", name)) {
-    assert(_dbInitialTract);
-    _allocateBufferVectorField();
-    topology::Field<topology::SubMesh>& buffer =
-        _fields->get("buffer (vector)");
-    topology::Field<topology::SubMesh>& tractions =
-        _fields->get("initial traction");
-    buffer.copy(tractions);
-    FaultCohesiveLagrange::globalToFault(&buffer, orientation);
-    return buffer;
-
   } else if (0 == strcasecmp("traction", name)) {
     assert(fields);
     const topology::Field<topology::Mesh>& dispT = fields->get("disp(t)");
@@ -1578,6 +1588,19 @@
   } else if (_friction->hasPropStateVar(name)) {
     return _friction->getField(name);
 
+  } else if (_tractPerturbation && _tractPerturbation->hasParameter(name)) {
+    const topology::Field<topology::SubMesh>& param = _tractPerturbation->vertexField(name, fields);
+    if (param.vectorFieldType() == topology::FieldBase::VECTOR) {
+      _allocateBufferVectorField();
+      topology::Field<topology::SubMesh>& buffer =
+        _fields->get("buffer (vector)");
+      buffer.copy(param);
+      FaultCohesiveLagrange::globalToFault(&buffer, orientation);
+      return buffer;
+    } else {
+      return param;
+    } // if/else
+
   } else {
     std::ostringstream msg;
     msg << "Request for unknown vertex field '" << name << "' for fault '"
@@ -1597,131 +1620,6 @@
 } // vertexField
 
 // ----------------------------------------------------------------------
-void
-pylith::faults::FaultCohesiveDyn::_setupInitialTractions(void)
-{ // _setupInitialTractions
-  assert(_normalizer);
-
-  // If no initial tractions specified, leave method
-  if (0 == _dbInitialTract)
-    return;
-
-  assert(_normalizer);
-  const PylithScalar pressureScale = _normalizer->pressureScale();
-  const PylithScalar lengthScale = _normalizer->lengthScale();
-
-  const int spaceDim = _quadrature->spaceDim();
-
-  // Create section to hold initial tractions.
-  _fields->add("initial traction", "initial_traction");
-  topology::Field<topology::SubMesh>& initialTractions = 
-    _fields->get("initial traction");
-  topology::Field<topology::SubMesh>& dispRel = _fields->get("relative disp");
-  initialTractions.cloneSection(dispRel);
-  initialTractions.scale(pressureScale);
-
-  scalar_array initialTractionsVertex(spaceDim);
-  scalar_array initialTractionsVertexGlobal(spaceDim);
-  const ALE::Obj<RealSection>& initialTractionsSection = 
-    initialTractions.section();
-  assert(!initialTractionsSection.isNull());
-
-  const ALE::Obj<RealSection>& orientationSection =
-    _fields->get("orientation").section();
-  assert(!orientationSection.isNull());
-
-  const spatialdata::geocoords::CoordSys* cs = _faultMesh->coordsys();
-  assert(cs);
-
-  const ALE::Obj<SieveSubMesh>& faultSieveMesh = _faultMesh->sieveMesh();
-  assert(!faultSieveMesh.isNull());
-
-  scalar_array coordsVertex(spaceDim);
-  const ALE::Obj<RealSection>& coordsSection =
-    faultSieveMesh->getRealSection("coordinates");
-  assert(!coordsSection.isNull());
-
-
-  assert(_dbInitialTract);
-  _dbInitialTract->open();
-  switch (spaceDim) { // switch
-  case 1: {
-    const char* valueNames[] = { "traction-normal" };
-    _dbInitialTract->queryVals(valueNames, 1);
-    break;
-  } // case 1
-  case 2: {
-    const char* valueNames[] = { "traction-shear", "traction-normal" };
-    _dbInitialTract->queryVals(valueNames, 2);
-    break;
-  } // case 2
-  case 3: {
-    const char* valueNames[] = { "traction-shear-leftlateral",
-				 "traction-shear-updip", "traction-normal" };
-    _dbInitialTract->queryVals(valueNames, 3);
-    break;
-  } // case 3
-  default:
-    std::cerr << "Bad spatial dimension '" << spaceDim << "'." << std::endl;
-    assert(0);
-    throw std::logic_error("Bad spatial dimension in Neumann.");
-  } // switch
-
-  const int numVertices = _cohesiveVertices.size();
-  for (int iVertex=0; iVertex < numVertices; ++iVertex) {
-    const int v_fault = _cohesiveVertices[iVertex].fault;
-
-    coordsSection->restrictPoint(v_fault, &coordsVertex[0], coordsVertex.size());
-
-    assert(spaceDim*spaceDim == orientationSection->getFiberDimension(v_fault));
-    const PylithScalar* orientationVertex = 
-      orientationSection->restrictPoint(v_fault);
-    assert(orientationVertex);
-
-    _normalizer->dimensionalize(&coordsVertex[0], coordsVertex.size(),
-				lengthScale);
-
-    initialTractionsVertex = 0.0;
-    int err = _dbInitialTract->query(&initialTractionsVertex[0], 
-				     initialTractionsVertex.size(),
-				     &coordsVertex[0], coordsVertex.size(), cs);
-    if (err) {
-      std::ostringstream msg;
-      msg << "Could not find parameters for physical properties at \n" << "(";
-      for (int i = 0; i < spaceDim; ++i)
-	msg << "  " << coordsVertex[i];
-      msg << ") in friction model " << label() << "\n"
-	  << "using spatial database '" << _dbInitialTract->label() << "'.";
-      throw std::runtime_error(msg.str());
-    } // if
-    _normalizer->nondimensionalize(&initialTractionsVertex[0],
-				   initialTractionsVertex.size(), 
-				   pressureScale);
-
-    // Rotate tractions from fault coordinate system to global
-    // coordinate system
-    initialTractionsVertexGlobal = 0.0;
-    for (int iDim=0; iDim < spaceDim; ++iDim) {
-      for (int jDim=0; jDim < spaceDim; ++jDim) {
-	initialTractionsVertexGlobal[iDim] += 
-	  orientationVertex[jDim*spaceDim+iDim] *
-	  initialTractionsVertex[jDim];
-      } // for
-    } // for
-
-    assert(initialTractionsVertexGlobal.size() ==
-	   initialTractionsSection->getFiberDimension(v_fault));
-    initialTractionsSection->updatePoint(v_fault, 
-					 &initialTractionsVertexGlobal[0]);
-  } // for
-
-  // Close properties database
-  _dbInitialTract->close();
-
-  //initialTractions.view("INITIAL TRACTIONS"); // DEBUGGING
-} // _setupInitialTractions
-
-// ----------------------------------------------------------------------
 // Compute tractions on fault surface using solution.
 void
 pylith::faults::FaultCohesiveDyn::_calcTractions(

Modified: short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/FaultCohesiveDyn.hh
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/FaultCohesiveDyn.hh	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/FaultCohesiveDyn.hh	2012-05-09 22:48:01 UTC (rev 20059)
@@ -55,11 +55,11 @@
   virtual
   void deallocate(void);
   
-  /** Sets the spatial database for the inital tractions.
+  /** Sets the traction perturbation for prescribed tractions.
    *
-   * @param db spatial database for initial tractions
+   * @param tract Spatial and temporal variation of tractions.
    */
-  void dbInitialTract(spatialdata::spatialdb::SpatialDB* db);
+  void tractPerturbation(TractPerturbation* tract);
   
   /** Set the friction (constitutive) model.
    *
@@ -152,10 +152,6 @@
   // PRIVATE METHODS ////////////////////////////////////////////////////
 private :
 
-  /** Get initial tractions using a spatial database.
-   */
-  void _setupInitialTractions(void);
-
   /** Compute tractions on fault surface using solution.
    *
    * @param tractions Field for tractions.
@@ -283,8 +279,8 @@
   /// Minimum resolvable value accounting for roundoff errors
   PylithScalar _zeroTolerance;
 
-  /// Database for initial tractions.
-  spatialdata::spatialdb::SpatialDB* _dbInitialTract;
+  /// Prescribed traction variation.
+  TractPerturbation* _tractPerturbation;
 
   /// To identify constitutive model
   friction::FrictionModel* _friction;

Modified: short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/Makefile.am
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/Makefile.am	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/Makefile.am	2012-05-09 22:48:01 UTC (rev 20059)
@@ -26,6 +26,14 @@
 	ConstRateSlipFn.icc \
 	CohesiveTopology.hh \
 	EqKinSrc.hh \
+	LiuCosSlipFn.hh \
+	LiuCosSlipFn.icc \
+	SlipTimeFn.hh \
+	StepSlipFn.hh \
+	StepSlipFn.icc \
+	TimeHistorySlipFn.hh \
+	TimeHistorySlipFn.icc \
+	TractPerturbation.hh \
 	Fault.hh \
 	Fault.icc \
 	FaultCohesive.hh \
@@ -35,14 +43,6 @@
 	FaultCohesiveDyn.hh \
 	FaultCohesiveKin.hh \
 	FaultCohesiveImpulses.hh \
-	LiuCosSlipFn.hh \
-	LiuCosSlipFn.icc \
-	SlipTimeFn.hh \
-	StepSlipFn.hh \
-	StepSlipFn.icc \
-	TimeHistorySlipFn.hh \
-	TimeHistorySlipFn.icc \
-	TractPerturbation.hh \
 	faultsfwd.hh
 
 noinst_HEADERS = \

Modified: short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/TractPerturbation.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/TractPerturbation.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/TractPerturbation.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -75,6 +75,14 @@
 } // label
 
 // ----------------------------------------------------------------------
+// Get parameter fields.
+const pylith::topology::FieldsNew<pylith::topology::SubMesh>*
+pylith::faults::TractPerturbation::parameterFields(void) const
+{ // parameterFields
+  return _parameters;
+} // parameterFields
+
+// ----------------------------------------------------------------------
 // Initialize traction perturbation function.
 void
 pylith::faults::TractPerturbation::initialize(const topology::SubMesh& faultMesh,
@@ -127,8 +135,8 @@
 	break;
       } // case 2
       case 3 : {
-	const char* valueNames[] = {"traction-shear-horiz",
-				    "traction-shear-vert",
+	const char* valueNames[] = {"traction-shear-leftlateral",
+				    "traction-shear-updip",
 				    "traction-normal"};
 	_dbInitial->queryVals(valueNames, 3);
 	break;
@@ -160,8 +168,8 @@
 	break;
       } // case 2
       case 3 : {
-	const char* valueNames[] = {"traction-rate-shear-horiz",
-				    "traction-rate-shear-vert",
+	const char* valueNames[] = {"traction-rate-shear-leftlateral",
+				    "traction-rate-shear-updip",
 				    "traction-rate-normal"};
 	_dbRate->queryVals(valueNames, 3);
 	break;
@@ -196,8 +204,8 @@
 	break;
       } // case 2
       case 3 : {
-	const char* valueNames[] = {"traction-shear-horiz",
-				    "traction-shear-vert",
+	const char* valueNames[] = {"traction-shear-leftlateral",
+				    "traction-shear-updip",
 				    "traction-normal"};
 	_dbChange->queryVals(valueNames, 3);
 	break;
@@ -224,83 +232,149 @@
 } // initialize
 
 // ----------------------------------------------------------------------
-// Get traction perturbation on fault surface at time t.
+// Calculate temporal and spatial variation of value over the list of Submesh.
 void
-pylith::faults::TractPerturbation::traction(topology::Field<topology::SubMesh>* const tractionField,
-					    const PylithScalar t)
-{ // traction
-  assert(tractionField);
+pylith::faults::TractPerturbation::calculate(const PylithScalar t)
+{ // calculate
   assert(_parameters);
 
-  _calculateValue(t);
+  const PylithScalar timeScale = _timeScale;
 
-  const spatialdata::geocoords::CoordSys* cs = tractionField->mesh().coordsys();
-  assert(cs);
-  const int spaceDim = cs->spaceDim();
-
-  // Get vertices in fault mesh
-  const ALE::Obj<SieveMesh>& sieveMesh = tractionField->mesh().sieveMesh();
+  // Get vertices.
+  const ALE::Obj<SieveSubMesh>& sieveMesh = _parameters->mesh().sieveMesh();
   assert(!sieveMesh.isNull());
   const ALE::Obj<SieveSubMesh::label_sequence>& vertices = sieveMesh->depthStratum(0);
   assert(!vertices.isNull());
   const SieveSubMesh::label_sequence::iterator verticesBegin = vertices->begin();
   const SieveSubMesh::label_sequence::iterator verticesEnd = vertices->end();
 
-  // Get sections
+  const spatialdata::geocoords::CoordSys* cs = _parameters->mesh().coordsys();
+  assert(cs);
+  const int spaceDim = cs->spaceDim();
+
   const ALE::Obj<SubRealUniformSection>& parametersSection = _parameters->section();
   assert(!parametersSection.isNull());
   const int parametersFiberDim = _parameters->fiberDim();
+  scalar_array parametersVertex(parametersFiberDim);
+  
   const int valueIndex = _parameters->sectionIndex("value");
   const int valueFiberDim = _parameters->sectionFiberDim("value");
-  assert(valueIndex+valueFiberDim <= parametersFiberDim);
+  assert(spaceDim == valueFiberDim);
 
-  const ALE::Obj<RealSection>& tractionSection = tractionField->section();
-  assert(!tractionSection.isNull());
+  const int initialIndex = (_dbInitial) ? _parameters->sectionIndex("initial") : -1;
+  const int initialFiberDim = (_dbInitial) ? _parameters->sectionFiberDim("initial") : 0;
 
-  for (SieveSubMesh::label_sequence::iterator v_iter=verticesBegin; v_iter != verticesEnd; ++v_iter) {
+  const int rateIndex = (_dbRate) ? _parameters->sectionIndex("rate") : -1;
+  const int rateFiberDim = (_dbRate) ? _parameters->sectionFiberDim("rate") : 0;
+  const int rateTimeIndex = (_dbRate) ? _parameters->sectionIndex("rate time") : -1;
+  const int rateTimeFiberDim = (_dbRate) ? _parameters->sectionFiberDim("rate time") : 0;
+
+  const int changeIndex = (_dbChange) ? _parameters->sectionIndex("change") : -1;
+  const int changeFiberDim = (_dbChange) ? _parameters->sectionFiberDim("change") : 0;
+  const int changeTimeIndex = (_dbChange) ? _parameters->sectionIndex("change time") : -1;
+  const int changeTimeFiberDim = (_dbChange) ? _parameters->sectionFiberDim("change time") : 0;
+
+  for(SieveSubMesh::label_sequence::iterator v_iter = verticesBegin; v_iter != verticesEnd; ++v_iter) {
     assert(parametersFiberDim == parametersSection->getFiberDimension(*v_iter));
-    const PylithScalar* parametersVertex = parametersSection->restrictPoint(*v_iter);
-    assert(parametersVertex);
-    const PylithScalar* tractionVertex = &parametersVertex[valueIndex];
-    assert(tractionVertex);
+    parametersSection->restrictPoint(*v_iter, &parametersVertex[0], parametersVertex.size());
+    for (int i=0; i < valueFiberDim; ++i)
+      parametersVertex[valueIndex+i] = 0.0;
 
-    // Update field
-    assert(valueFiberDim == tractionSection->getFiberDimension(*v_iter));
-    tractionSection->updateAddPoint(*v_iter, tractionVertex);
+    // Contribution from initial value
+    if (_dbInitial) {
+      assert(initialIndex >= 0);
+      assert(initialFiberDim == valueFiberDim);
+      for (int i=0; i < initialFiberDim; ++i)
+	parametersVertex[valueIndex+i] += parametersVertex[initialIndex+i];
+    } // if
+    
+    // Contribution from rate of change of value
+    if (_dbRate) {
+      assert(rateIndex >= 0);
+      assert(rateFiberDim == valueFiberDim);
+      assert(rateTimeIndex >= 0);
+      assert(rateTimeFiberDim == 1);
+      
+      const PylithScalar tRel = t - parametersVertex[rateTimeIndex];
+      if (tRel > 0.0)  // rate of change integrated over time
+	for (int iDim=0; iDim < spaceDim; ++iDim) {
+	  parametersVertex[valueIndex+iDim] += parametersVertex[rateIndex+iDim] * tRel;
+	} // for
+    } // if
+    
+    // Contribution from change of value
+    if (_dbChange) {
+      assert(changeIndex >= 0);
+      assert(changeFiberDim == valueFiberDim);
+      assert(changeTimeIndex >= 0);
+      assert(changeTimeFiberDim == 1);
+
+      const PylithScalar tRel = t - parametersVertex[changeTimeIndex];
+      if (tRel >= 0) { // change in value over time
+	PylithScalar scale = 1.0;
+	if (_dbTimeHistory) {
+	  PylithScalar tDim = tRel*timeScale;
+	  const int err = _dbTimeHistory->query(&scale, tDim);
+	  if (err) {
+	    std::ostringstream msg;
+	    msg << "Error querying for time '" << tDim 
+		<< "' in time history database "
+		<< _dbTimeHistory->label() << ".";
+	    throw std::runtime_error(msg.str());
+	  } // if
+	} // if
+	for (int iDim=0; iDim < spaceDim; ++iDim) {
+	  parametersVertex[valueIndex+iDim] += parametersVertex[changeIndex+iDim] * scale;
+	} // for
+      } // if
+    } // if
+    
+    parametersSection->updatePoint(*v_iter, &parametersVertex[0]);
   } // for
+}  // calculate
 
-} // traction
-  
+
 // ----------------------------------------------------------------------
-// Get parameter fields.
-const pylith::topology::FieldsNew<pylith::topology::SubMesh>*
-pylith::faults::TractPerturbation::parameterFields(void) const
-{ // parameterFields
-  return _parameters;
-} // parameterFields
+// Determine if perturbation has a given parameter.
+bool
+pylith::faults::TractPerturbation::hasParameter(const char* name) const
+{ // hasParameter
+  if (0 == strcasecmp(name, "initial_traction"))
+    return (0 != _dbInitial);
+  else if (0 == strcasecmp(name, "rate_traction"))
+    return (0 != _dbRate);
+  else if (0 == strcasecmp(name, "change_traction"))
+    return (0 != _dbChange);
+  else if (0 == strcasecmp(name, "rate_time_traction"))
+    return (0 != _dbRate);
+  else if (0 == strcasecmp(name, "change_time_traction"))
+    return (0 != _dbChange);
+  else
+    return false;
+} // hasParameter
 
 // ----------------------------------------------------------------------
 // Get vertex field with traction perturbation information.
 const pylith::topology::Field<pylith::topology::SubMesh>&
 pylith::faults::TractPerturbation::vertexField(const char* name,
-					       topology::SolutionFields* const fields)
+					       const topology::SolutionFields* const fields)
 { // vertexField
   assert(_parameters);
   assert(name);
 
-  if (0 == strcasecmp(name, "initial-value"))
+  if (0 == strcasecmp(name, "initial_traction"))
     return _parameters->get("initial");
 
-  else if (0 == strcasecmp(name, "rate-of-change"))
+  else if (0 == strcasecmp(name, "rate_traction"))
     return _parameters->get("rate");
 
-  else if (0 == strcasecmp(name, "change-in-value"))
+  else if (0 == strcasecmp(name, "change_traction"))
     return _parameters->get("change");
 
-  else if (0 == strcasecmp(name, "rate-start-time"))
+  else if (0 == strcasecmp(name, "rate_time_traction"))
     return _parameters->get("rate time");
 
-  else if (0 == strcasecmp(name, "change-start-time"))
+  else if (0 == strcasecmp(name, "change_time_traction"))
     return _parameters->get("change time");
 
   else {
@@ -395,107 +469,4 @@
   } // for
 } // _queryDB
 
-// ----------------------------------------------------------------------
-// Calculate temporal and spatial variation of value over the list of Submesh.
-void
-pylith::faults::TractPerturbation::_calculateValue(const PylithScalar t)
-{ // _calculateValue
-  assert(_parameters);
-
-  const PylithScalar timeScale = _timeScale;
-
-  // Get vertices.
-  const ALE::Obj<SieveSubMesh>& sieveMesh = _parameters->mesh().sieveMesh();
-  assert(!sieveMesh.isNull());
-  const ALE::Obj<SieveSubMesh::label_sequence>& vertices = sieveMesh->depthStratum(0);
-  assert(!vertices.isNull());
-  const SieveSubMesh::label_sequence::iterator verticesBegin = vertices->begin();
-  const SieveSubMesh::label_sequence::iterator verticesEnd = vertices->end();
-
-  const spatialdata::geocoords::CoordSys* cs = _parameters->mesh().coordsys();
-  assert(cs);
-  const int spaceDim = cs->spaceDim();
-
-  const ALE::Obj<SubRealUniformSection>& parametersSection = _parameters->section();
-  assert(!parametersSection.isNull());
-  const int parametersFiberDim = _parameters->fiberDim();
-  scalar_array parametersVertex(parametersFiberDim);
-  
-  const int valueIndex = _parameters->sectionIndex("value");
-  const int valueFiberDim = _parameters->sectionFiberDim("value");
-  assert(spaceDim == valueFiberDim);
-
-  const int initialIndex = (_dbInitial) ? _parameters->sectionIndex("initial") : -1;
-  const int initialFiberDim = (_dbInitial) ? _parameters->sectionFiberDim("initial") : 0;
-
-  const int rateIndex = (_dbRate) ? _parameters->sectionIndex("rate") : -1;
-  const int rateFiberDim = (_dbRate) ? _parameters->sectionFiberDim("rate") : 0;
-  const int rateTimeIndex = (_dbRate) ? _parameters->sectionIndex("rate time") : -1;
-  const int rateTimeFiberDim = (_dbRate) ? _parameters->sectionFiberDim("rate time") : 0;
-
-  const int changeIndex = (_dbChange) ? _parameters->sectionIndex("change") : -1;
-  const int changeFiberDim = (_dbChange) ? _parameters->sectionFiberDim("change") : 0;
-  const int changeTimeIndex = (_dbChange) ? _parameters->sectionIndex("change time") : -1;
-  const int changeTimeFiberDim = (_dbChange) ? _parameters->sectionFiberDim("change time") : 0;
-
-  for(SieveSubMesh::label_sequence::iterator v_iter = verticesBegin; v_iter != verticesEnd; ++v_iter) {
-    assert(parametersFiberDim == parametersSection->getFiberDimension(*v_iter));
-    parametersSection->restrictPoint(*v_iter, &parametersVertex[0], parametersVertex.size());
-    for (int i=0; i < valueFiberDim; ++i)
-      parametersVertex[valueIndex+i] = 0.0;
-
-    // Contribution from initial value
-    if (_dbInitial) {
-      assert(initialIndex >= 0);
-      assert(initialFiberDim == valueFiberDim);
-      for (int i=0; i < initialFiberDim; ++i)
-	parametersVertex[valueIndex+i] += parametersVertex[initialIndex+i];
-    } // if
-    
-    // Contribution from rate of change of value
-    if (_dbRate) {
-      assert(rateIndex >= 0);
-      assert(rateFiberDim == valueFiberDim);
-      assert(rateTimeIndex >= 0);
-      assert(rateTimeFiberDim == 1);
-      
-      const PylithScalar tRel = t - parametersVertex[rateTimeIndex];
-      if (tRel > 0.0)  // rate of change integrated over time
-	for (int iDim=0; iDim < spaceDim; ++iDim) {
-	  parametersVertex[valueIndex+iDim] += parametersVertex[rateIndex+iDim] * tRel;
-	} // for
-    } // if
-    
-    // Contribution from change of value
-    if (_dbChange) {
-      assert(changeIndex >= 0);
-      assert(changeFiberDim == valueFiberDim);
-      assert(changeTimeIndex >= 0);
-      assert(changeTimeFiberDim == 1);
-
-      const PylithScalar tRel = t - parametersVertex[changeTimeIndex];
-      if (tRel >= 0) { // change in value over time
-	PylithScalar scale = 1.0;
-	if (_dbTimeHistory) {
-	  PylithScalar tDim = tRel*timeScale;
-	  const int err = _dbTimeHistory->query(&scale, tDim);
-	  if (err) {
-	    std::ostringstream msg;
-	    msg << "Error querying for time '" << tDim 
-		<< "' in time history database "
-		<< _dbTimeHistory->label() << ".";
-	    throw std::runtime_error(msg.str());
-	  } // if
-	} // if
-	for (int iDim=0; iDim < spaceDim; ++iDim) {
-	  parametersVertex[valueIndex+iDim] += parametersVertex[changeIndex+iDim] * scale;
-	} // for
-      } // if
-    } // if
-    
-    parametersSection->updatePoint(*v_iter, &parametersVertex[0]);
-  } // for
-}  // _calculateValue
-
-
 // End of file

Modified: short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/TractPerturbation.hh
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/TractPerturbation.hh	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/libsrc/pylith/faults/TractPerturbation.hh	2012-05-09 22:48:01 UTC (rev 20059)
@@ -62,6 +62,12 @@
    */
   void label(const char* value);
 
+  /** Get parameter fields.
+   *
+   * @returns Parameter fields.
+   */
+  const topology::FieldsNew<topology::SubMesh>* parameterFields(void) const;
+  
   /** Initialize slip time function.
    *
    * @param faultMesh Finite-element mesh of fault.
@@ -72,20 +78,19 @@
 		  const topology::Field<topology::SubMesh>& faultOrientation,
 		  const spatialdata::units::Nondimensional& normalizer);
 
-  /** Get traction perturbation on fault surface at time t.
+  /** Calculate spatial and temporal variation of value.
    *
-   * @param tractionField Traction field over fault surface [output].
-   * @param t Time t.
+   * @param t Current time.
    */
-  void traction(topology::Field<topology::SubMesh>* const tractionField,
-		const PylithScalar t);
-  
-  /** Get parameter fields.
+  void calculate(const PylithScalar t);
+
+  /** Determine if perturbation has a given parameter.
    *
-   * @returns Parameter fields.
+   * @param name Name of parameter field.
+   * @returns True if perturbation has parameter field, false otherwise.
    */
-  const topology::FieldsNew<topology::SubMesh>* parameterFields(void) const;
-  
+  bool hasParameter(const char* name) const;
+
   /** Get vertex field with traction perturbation information.
    *
    * @param name Name of field.
@@ -95,7 +100,7 @@
    */
   const topology::Field<topology::SubMesh>&
   vertexField(const char* name,
-	      topology::SolutionFields* const fields =0);
+	      const topology::SolutionFields* const fields =0);
 
   // PROTECTED METHODS //////////////////////////////////////////////////
 protected :
@@ -120,12 +125,6 @@
 		const PylithScalar scale,
 		const spatialdata::units::Nondimensional& normalizer);
 
-  /** Calculate spatial and temporal variation of value.
-   *
-   * @param t Current time.
-   */
-  void _calculateValue(const PylithScalar t);
-
 // PRIVATE MEMBERS //////////////////////////////////////////////////////
 private :
   

Modified: short/3D/PyLith/branches/v1.7-trunk/modulesrc/bc/TimeDependent.i
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/modulesrc/bc/TimeDependent.i	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/modulesrc/bc/TimeDependent.i	2012-05-09 22:48:01 UTC (rev 20059)
@@ -24,7 +24,7 @@
 namespace pylith {
   namespace bc {
 
-    class pylith::bc::TimeDependent
+    class TimeDependent
     { // class TimeDependent
 
       // PUBLIC METHODS /////////////////////////////////////////////////
@@ -81,13 +81,6 @@
       virtual
       const char* _getLabel(void) const = 0;
       
-      /** Get manager of scales used to nondimensionalize problem.
-       *
-       * @returns Nondimensionalizer.
-       */
-      virtual
-      const spatialdata::units::Nondimensional& _getNormalizer(void) const = 0;
-      
     }; // class TimeDependent
 
   } // bc

Modified: short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/FaultCohesiveDyn.i
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/FaultCohesiveDyn.i	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/FaultCohesiveDyn.i	2012-05-09 22:48:01 UTC (rev 20059)
@@ -41,11 +41,11 @@
       virtual
       void deallocate(void);
       
-      /** Sets the spatial database for the inital tractions.
+      /** Sets the traction perturbation for prescribed tractions.
        *
-       * @param db spatial database for initial tractions
+       * @param tract Spatial and temporal variation of tractions.
        */
-      void dbInitialTract(spatialdata::spatialdb::SpatialDB* db);
+      void tractPerturbation(TractPerturbation* tract);
   
       /** Set the friction (constitutive) model.
        *

Modified: short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/Makefile.am
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/Makefile.am	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/Makefile.am	2012-05-09 22:48:01 UTC (rev 20059)
@@ -32,6 +32,7 @@
 	LiuCosSlipFn.i \
 	TimeHistorySlipFn.i \
 	EqKinSrc.i \
+	TractPerturbation.i \
 	Fault.i \
 	FaultCohesive.i \
 	FaultCohesiveLagrange.i \

Added: short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/TractPerturbation.i
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/TractPerturbation.i	                        (rev 0)
+++ short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/TractPerturbation.i	2012-05-09 22:48:01 UTC (rev 20059)
@@ -0,0 +1,105 @@
+// -*- 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-2012 University of California, Davis
+//
+// See COPYING for license information.
+//
+// ----------------------------------------------------------------------
+//
+
+/** @file modulesrc/faults/TractPerturbation.i
+ *
+ * @brief Python interface to C++ TractPerturbation object.
+ */
+
+namespace pylith {
+  namespace faults {
+
+    class TractPerturbation : public pylith::bc::TimeDependent
+    { // class TractPerturbation
+
+      // PUBLIC METHODS /////////////////////////////////////////////////
+    public :
+
+      /// Default constructor.
+      TractPerturbation(void);
+      
+      /// Destructor.
+      virtual
+      ~TractPerturbation(void);
+      
+      /// Deallocate PETSc and local data structures.
+      virtual
+      void deallocate(void);
+      
+      /** Set label for traction perturbation.
+       *
+       * @param value Label.
+       */
+      void label(const char* value);
+      
+      /** Get parameter fields.
+       *
+       * @returns Parameter fields.
+       */
+      const pylith::topology::FieldsNew<pylith::topology::SubMesh>* parameterFields(void) const;
+      
+      /** Initialize slip time function.
+       *
+       * @param faultMesh Finite-element mesh of fault.
+       * @param faultOrientation Orientation of fault.
+       * @param normalizer Nondimensionalization of scales.
+       */
+      void initialize(const pylith::topology::SubMesh& faultMesh,
+		      const pylith::topology::Field<pylith::topology::SubMesh>& faultOrientation,
+		      const spatialdata::units::Nondimensional& normalizer);
+      
+      /** Calculate spatial and temporal variation of value.
+       *
+       * @param t Current time.
+       */
+      void calculate(const PylithScalar t);
+      
+      /** Determine if perturbation has a given parameter.
+       *
+       * @param name Name of parameter field.
+       * @returns True if perturbation has parameter field, false otherwise.
+       */
+      bool hasParameter(const char* name) const;
+
+      /** Get vertex field with traction perturbation information.
+       *
+       * @param name Name of field.
+       * @param fields Solution fields.
+       *
+       * @returns Traction vector field.
+       */
+      const pylith::topology::Field<pylith::topology::SubMesh>&
+      vertexField(const char* name,
+		  pylith::topology::SolutionFields* const fields =0);
+      
+      // PROTECTED METHODS //////////////////////////////////////////////
+    protected :
+
+      /** Get label of boundary condition surface.
+       *
+       * @returns Label of surface (from mesh generator).
+       */
+      const char* _getLabel(void) const;
+
+    }; // class TractPerturbation
+    
+  } // faults
+} // pylith
+
+
+// End of file 

Modified: short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/faults.i
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/faults.i	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/modulesrc/faults/faults.i	2012-05-09 22:48:01 UTC (rev 20059)
@@ -28,6 +28,7 @@
 #include "pylith/faults/LiuCosSlipFn.hh"
 #include "pylith/faults/TimeHistorySlipFn.hh"
 #include "pylith/faults/EqKinSrc.hh"
+#include "pylith/faults/TractPerturbation.hh"
 #include "pylith/faults/Fault.hh"
 #include "pylith/faults/FaultCohesive.hh"
 #include "pylith/faults/FaultCohesiveLagrange.hh"
@@ -70,6 +71,7 @@
 %include "../topology/SubMesh.i" // ISA Integrator<Quadrature<SubMesh> >
 %include "../feassemble/Quadrature.i" // ISA Integrator<Quadrature<SubMesh> >
 %include "../feassemble/Integrator.i" // ISA Integrator<Quadrature<SubMesh> >
+%include "../bc/TimeDependent.i" // ISA TimeDependent
 
 // Template instatiation
 %template(SubMeshIntegrator) pylith::feassemble::Integrator<pylith::feassemble::Quadrature<pylith::topology::SubMesh > >;
@@ -81,6 +83,7 @@
 %include "LiuCosSlipFn.i"
 %include "TimeHistorySlipFn.i"
 %include "EqKinSrc.i"
+%include "TractPerturbation.i"
 %include "Fault.i"
 %include "FaultCohesive.i"
 %include "FaultCohesiveLagrange.i"

Modified: short/3D/PyLith/branches/v1.7-trunk/pylith/Makefile.am
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/pylith/Makefile.am	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/pylith/Makefile.am	2012-05-09 22:48:01 UTC (rev 20059)
@@ -36,17 +36,18 @@
 	faults/BruneSlipFn.py \
 	faults/ConstRateSlipFn.py \
 	faults/EqKinSrc.py \
+	faults/LiuCosSlipFn.py \
+	faults/SingleRupture.py \
+	faults/SlipTimeFn.py \
+	faults/StepSlipFn.py \
+	faults/TimeHistorySlipFn.py \
+	faults/TractPerturbation.py \
 	faults/Fault.py \
 	faults/FaultCohesive.py \
 	faults/FaultCohesiveKin.py \
 	faults/FaultCohesiveDyn.py \
 	faults/FaultCohesiveImpulses.py \
 	faults/FaultCohesiveTract.py \
-	faults/LiuCosSlipFn.py \
-	faults/SingleRupture.py \
-	faults/SlipTimeFn.py \
-	faults/StepSlipFn.py \
-	faults/TimeHistorySlipFn.py \
 	feassemble/__init__.py \
 	feassemble/Constraint.py \
 	feassemble/ElasticityExplicit.py \

Modified: short/3D/PyLith/branches/v1.7-trunk/pylith/bc/DirichletBoundary.py
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/pylith/bc/DirichletBoundary.py	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/pylith/bc/DirichletBoundary.py	2012-05-09 22:48:01 UTC (rev 20059)
@@ -26,6 +26,8 @@
 from DirichletBC import DirichletBC
 from bc import DirichletBoundary as ModuleDirichletBoundary
 
+from pylith.utils.NullComponent import NullComponent
+
 # DirichletBoundary class
 class DirichletBoundary(DirichletBC, ModuleDirichletBoundary):
   """
@@ -69,12 +71,7 @@
     self._loggingPrefix = "DiBC "
     self.availableFields = \
         {'vertex': \
-           {'info': ["initial-value", 
-                     "rate-of-change", 
-                     "change-in-value", 
-                     "rate-start-time", 
-                     "change-start-time",
-                     ],
+           {'info': [],
             'data': []},
          'cell': \
            {'info': [],
@@ -88,6 +85,15 @@
     """
     DirichletBC.preinitialize(self, mesh)
     self.output.preinitialize(self)
+
+    fields = []
+    if not isinstance(self.inventory.dbInitial, NullComponent):
+      fields += ["initial_displacement"]
+    if not isinstance(self.inventory.dbRate, NullComponent):
+      fields += ["rate_displacement", "rate_time_displacement"]
+    if not isinstance(self.inventory.dbChange, NullComponent):
+      fields += ["change_displacement", "change_time_displacement"]
+    self.availableFields['vertex']['info'] += fields
     return
 
 

Modified: short/3D/PyLith/branches/v1.7-trunk/pylith/bc/Neumann.py
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/pylith/bc/Neumann.py	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/pylith/bc/Neumann.py	2012-05-09 22:48:01 UTC (rev 20059)
@@ -27,6 +27,8 @@
 from pylith.feassemble.Integrator import Integrator
 from bc import Neumann as ModuleNeumann
 
+from pylith.utils.NullComponent import NullComponent
+
 # Neumann class
 class Neumann(BoundaryCondition, 
               TimeDependent,
@@ -68,12 +70,7 @@
            {'info': [],
             'data': []},
          'cell': \
-           {'info': ["initial-value",
-                     "rate-of-change",
-                     "rate-start-time",
-                     "change-in-value",
-                     "change-start-time",
-                     ],
+           {'info': [],
             'data': []}}
     return
 
@@ -88,6 +85,15 @@
     self.quadrature(self.bcQuadrature)
     self.createSubMesh(mesh)
     self.output.preinitialize(self)
+
+    fields = []
+    if not isinstance(self.inventory.dbInitial, NullComponent):
+      fields += ["initial_traction"]
+    if not isinstance(self.inventory.dbRate, NullComponent):
+      fields += ["rate_traction", "rate_time_traction"]
+    if not isinstance(self.inventory.dbChange, NullComponent):
+      fields += ["change_traction", "change_time_traction"]
+    self.availableFields['cell']['info'] += fields
     return
 
 

Modified: short/3D/PyLith/branches/v1.7-trunk/pylith/faults/FaultCohesiveDyn.py
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/pylith/faults/FaultCohesiveDyn.py	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/pylith/faults/FaultCohesiveDyn.py	2012-05-09 22:48:01 UTC (rev 20059)
@@ -48,7 +48,7 @@
     fault opens.
   
   \b Facilities
-  @li \b db_initial_tractions Spatial database for initial tractions.
+  @li \b tract_perturbation Prescribed perturbation in fault tractions.
   @li \b friction Fault constitutive model.
   @li \b output Output manager associated with fault data.
 
@@ -68,9 +68,9 @@
     "the fault opens, otherwise use initial tractions even when the " \
     "fault opens."
 
-  db = pyre.inventory.facility("db_initial_tractions", family="spatial_database",
+  tract = pyre.inventory.facility("traction_perturbation", family="traction_perturbation",
                                factory=NullComponent)
-  db.meta['tip'] = "Spatial database for initial tractions."
+  tract.meta['tip'] = "Prescribed perturbation in fault tractions."
 
   from pylith.friction.StaticFriction import StaticFriction
   friction = pyre.inventory.facility("friction", family="friction_model",
@@ -115,6 +115,7 @@
       self._info.log("Pre-initializing fault '%s'." % self.label())
     FaultCohesive.preinitialize(self, mesh)
     Integrator.preinitialize(self, mesh)
+    self.tract.preinitialize(mesh)
 
     ModuleFaultCohesiveDyn.quadrature(self, self.faultQuadrature)
 
@@ -124,8 +125,8 @@
       self.availableFields['vertex']['info'] += ["strike_dir",
                                                  "dip_dir"]
 
-    if not isinstance(self.inventory.db, NullComponent):
-      self.availableFields['vertex']['info'] += ["initial_traction"]
+    if not isinstance(self.tract, NullComponent):
+      self.availableFields['vertex']['info'] += self.tract.availableFields['vertex']['info']
 
     self.availableFields['vertex']['info'] += \
         self.friction.availableFields['vertex']['info']
@@ -209,8 +210,8 @@
     Setup members using inventory.
     """
     FaultCohesive._configure(self)
-    if not isinstance(self.inventory.db, NullComponent):
-      ModuleFaultCohesiveDyn.dbInitialTract(self, self.inventory.db)
+    if not isinstance(self.inventory.tract, NullComponent):
+      ModuleFaultCohesiveDyn.tractPerturbation(self, self.inventory.tract)
     ModuleFaultCohesiveDyn.frictionModel(self, self.inventory.friction)
     ModuleFaultCohesiveDyn.zeroTolerance(self, self.inventory.zeroTolerance)
     ModuleFaultCohesiveDyn.openFreeSurf(self, self.inventory.openFreeSurf)

Added: short/3D/PyLith/branches/v1.7-trunk/pylith/faults/TractPerturbation.py
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/pylith/faults/TractPerturbation.py	                        (rev 0)
+++ short/3D/PyLith/branches/v1.7-trunk/pylith/faults/TractPerturbation.py	2012-05-09 22:48:01 UTC (rev 20059)
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+#
+# ----------------------------------------------------------------------
+#
+# 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-2012 University of California, Davis
+#
+# See COPYING for license information.
+#
+# ----------------------------------------------------------------------
+#
+
+## @file pylith/faults/TractPerturbation.py
+##
+
+## @brief Python object for managing parameters for a kinematic
+## earthquake sources.
+##
+## TractPerturbation is responsible for providing the value of
+## specified traction at time t over a fault surface.
+##
+## Factory: eq_kinematic_src
+
+from pylith.bc.TimeDependent import TimeDependent
+from faults import TractPerturbation as ModuleTractPerturbation
+
+from pylith.utils.NullComponent import NullComponent
+
+# TractPerturbation class
+class TractPerturbation(TimeDependent, ModuleTractPerturbation):
+  """
+  Python object for managing specified tractions on a fault surface.
+
+  Factory: traction_perturbation
+  """
+
+  # PUBLIC METHODS /////////////////////////////////////////////////////
+
+  def __init__(self, name="tractperturbation"):
+    """
+    Constructor.
+    """
+    TimeDependent.__init__(self, name)
+    self._createModuleObj()
+    self._loggingPrefix = "TrPt "
+    return
+
+
+  def preinitialize(self, mesh):
+    """
+    Do pre-initialization setup.
+    """
+    fields = []
+    if not isinstance(self.inventory.dbInitial, NullComponent):
+      fields += ["initial_traction"]
+    if not isinstance(self.inventory.dbRate, NullComponent):
+      fields += ["rate_traction", "rate_time_traction"]
+    if not isinstance(self.inventory.dbChange, NullComponent):
+      fields += ["change_traction", "change_time_traction"]
+
+    self.availableFields = \
+        {'vertex': {'info': fields,
+                    'data': []},
+         'cell': {'info': [],
+                  'data': []}}
+    return
+  
+
+  # PRIVATE METHODS ////////////////////////////////////////////////////
+
+  def _createModuleObj(self):
+    """
+    Create handle to corresponding C++ object.
+    """
+    ModuleTractPerturbation.__init__(self)
+    return
+  
+
+# FACTORIES ////////////////////////////////////////////////////////////
+
+def traction_perturbation():
+  """
+  Factory associated with TractPerturbation.
+  """
+  return TractPerturbation()
+
+
+# End of file 

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestFaultCohesiveDyn.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestFaultCohesiveDyn.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestFaultCohesiveDyn.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -21,6 +21,7 @@
 #include "TestFaultCohesiveDyn.hh" // Implementation of class methods
 
 #include "pylith/faults/FaultCohesiveDyn.hh" // USES FaultCohesiveDyn
+#include "pylith/faults/TractPerturbation.hh" // USES TractPerturbation
 
 #include "data/CohesiveDynData.hh" // USES CohesiveDynData
 
@@ -54,7 +55,7 @@
   _data = 0;
   _quadrature = new feassemble::Quadrature<topology::SubMesh>();
   CPPUNIT_ASSERT(0 != _quadrature);
-  _dbInitialTract = 0;
+  _tractPerturbation = 0;
   _friction = 0;
   _dbFriction = 0;
   _flipFault = false;
@@ -67,7 +68,7 @@
 { // tearDown
   delete _data; _data = 0;
   delete _quadrature; _quadrature = 0;
-  delete _dbInitialTract; _dbInitialTract = 0;
+  delete _tractPerturbation; _tractPerturbation = 0;
   delete _friction; _friction = 0;
   delete _dbFriction; _dbFriction = 0;
 } // tearDown
@@ -81,19 +82,18 @@
 } // testConstructor
 
 // ----------------------------------------------------------------------
-// Test dbInitialTract().
+// Test tractPerturbation().
 void
-pylith::faults::TestFaultCohesiveDyn::testDBInitialTract(void)
-{ // testDBInitialTract
+pylith::faults::TestFaultCohesiveDyn::testTractPerturbation(void)
+{ // testTractPerturbation
   FaultCohesiveDyn fault;
 
   const std::string& label = "test database";
-  spatialdata::spatialdb::SimpleDB db;
-  db.label(label.c_str());
-  fault.dbInitialTract(&db);
-  CPPUNIT_ASSERT(0 != fault._dbInitialTract);
-  CPPUNIT_ASSERT_EQUAL(label, std::string(fault._dbInitialTract->label()));
- } // testDBInitialTract
+  TractPerturbation tract;
+  tract.label(label.c_str());
+  fault.tractPerturbation(&tract);
+  CPPUNIT_ASSERT(fault._tractPerturbation);
+ } // testTractPerturbation
 
 // ----------------------------------------------------------------------
 // Test zeroTolerance().
@@ -128,7 +128,7 @@
 void
 pylith::faults::TestFaultCohesiveDyn::testInitialize(void)
 { // testInitialize
-  CPPUNIT_ASSERT(0 != _data);
+  CPPUNIT_ASSERT(_data);
 
   topology::Mesh mesh;
   FaultCohesiveDyn fault;
@@ -181,12 +181,15 @@
     } // for
   } // for
 
-  // Initial tractions
-  if (0 != fault._dbInitialTract) {
-    //fault._fields->get("initial traction").view("INITIAL TRACTIONS"); // DEBUGGING
+  // Prescribed traction perturbation
+  if (fault._tractPerturbation) {
+    // :KLUDGE: Only check initial value
     const ALE::Obj<RealSection>& initialTractionsSection = 
-      fault._fields->get("initial traction").section();
+      fault.vertexField("initial_traction").section();
     CPPUNIT_ASSERT(!initialTractionsSection.isNull());
+
+    //initialTractionsSection->view("INITIAL TRACTIONS"); // DEBUGGING
+
     const int spaceDim = _data->spaceDim;
     iVertex = 0;
     for (SieveSubMesh::label_sequence::iterator v_iter = verticesBegin;
@@ -719,15 +722,17 @@
 			  _data->quadWts, _data->numQuadPts,
 			  _data->spaceDim);
   
-  // Setup initial tractions
-  spatialdata::spatialdb::SimpleDB* db =
-      new spatialdata::spatialdb::SimpleDB("initial tractions");
-  CPPUNIT_ASSERT(0 != db);
+  // Setup prescribed traction perturbation
+  delete _tractPerturbation; _tractPerturbation = new TractPerturbation();
+  _tractPerturbation->label("traction perturbation");
+  spatialdata::spatialdb::SimpleDB* db = new spatialdata::spatialdb::SimpleDB("initial tractions");
+  CPPUNIT_ASSERT(db);
   spatialdata::spatialdb::SimpleIOAscii ioInitialTract;
   ioInitialTract.filename(_data->initialTractFilename);
   db->ioHandler(&ioInitialTract);
   delete _dbInitialTract; _dbInitialTract = db;
-  fault->dbInitialTract(db);
+  _tractPerturbation->dbInitial(db);
+  fault->tractPerturbation(_tractPerturbation);
 
   // Setup friction
   spatialdata::spatialdb::SimpleDB* dbFriction =

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestFaultCohesiveDyn.hh
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestFaultCohesiveDyn.hh	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestFaultCohesiveDyn.hh	2012-05-09 22:48:01 UTC (rev 20059)
@@ -52,7 +52,7 @@
   CPPUNIT_TEST_SUITE( TestFaultCohesiveDyn );
 
   CPPUNIT_TEST( testConstructor );
-  CPPUNIT_TEST( testDBInitialTract );
+  CPPUNIT_TEST( testTractPerturbation );
   CPPUNIT_TEST( testZeroTolerance );
   CPPUNIT_TEST( testOpenFreeSurf );
 
@@ -71,6 +71,7 @@
 
   CohesiveDynData* _data; ///< Data for testing
   feassemble::Quadrature<topology::SubMesh>* _quadrature; ///< Fault quad.
+  TractPerturbation* _tractPerturbation; ///< Initial tractions.
   spatialdata::spatialdb::SpatialDB* _dbInitialTract; ///< Initial tractions.
   friction::FrictionModel* _friction; ///< Friction model
   spatialdata::spatialdb::SpatialDB* _dbFriction; ///< Friction parameters.
@@ -88,8 +89,8 @@
   /// Test constructor.
   void testConstructor(void);
 
-  /// Test dbInitialTract().
-  void testDBInitialTract(void);
+  /// Test tractPerturbation().
+  void testTractPerturbation(void);
 
   /// Test zeroTolerance().
   void testZeroTolerance(void);

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestTractPerturbation.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestTractPerturbation.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestTractPerturbation.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -64,6 +64,48 @@
 } // testLabel
 
 // ----------------------------------------------------------------------
+// Test hasParameter().
+void
+pylith::faults::TestTractPerturbation::testHasParameter(void)
+{ // testHasParameter
+  spatialdata::spatialdb::SimpleDB db;
+  
+  TractPerturbation tract;
+
+  // no values
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("initial_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("rate_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("change_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("rate_time_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("change_time_traction"));
+
+  // initial value
+  tract.dbInitial(&db);
+  CPPUNIT_ASSERT_EQUAL(true, tract.hasParameter("initial_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("rate_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("change_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("rate_time_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("change_time_traction"));
+
+  // change value
+  tract.dbChange(&db);
+  CPPUNIT_ASSERT_EQUAL(true, tract.hasParameter("initial_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("rate_traction"));
+  CPPUNIT_ASSERT_EQUAL(true, tract.hasParameter("change_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("rate_time_traction"));
+  CPPUNIT_ASSERT_EQUAL(true, tract.hasParameter("change_time_traction"));
+
+  // rate value, remove change
+  tract.dbRate(&db);
+  tract.dbChange(0);
+  CPPUNIT_ASSERT_EQUAL(true, tract.hasParameter("initial_traction"));
+  CPPUNIT_ASSERT_EQUAL(true, tract.hasParameter("rate_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("change_traction"));
+  CPPUNIT_ASSERT_EQUAL(true, tract.hasParameter("rate_time_traction"));
+  CPPUNIT_ASSERT_EQUAL(false, tract.hasParameter("change_time_traction"));
+} // testHasParameter
+
+// ----------------------------------------------------------------------
 // Test initialize() using 2-D mesh.
 void
 pylith::faults::TestTractPerturbation::testInitialize(void)
@@ -77,10 +119,10 @@
 } // testInitialize
 
 // ----------------------------------------------------------------------
-// Test traction() using 2-D mesh().
+// Test calculate() using 2-D mesh().
 void
-pylith::faults::TestTractPerturbation::testTraction(void)
-{ // testTraction
+pylith::faults::TestTractPerturbation::testCalculate(void)
+{ // testCalculate
   const PylithScalar tractionE[4] = { 
     -1.0*(-2.0+1.0), -1.0*(1.0-0.5), // initial + change
     -1.0*(-2.1), -1.0*(1.1), // initial
@@ -91,40 +133,44 @@
   TractPerturbation tract;
   _initialize(&mesh, &faultMesh, &tract);
   
+  const PylithScalar t = 2.134;
+  tract.calculate(t);
+
+
   const spatialdata::geocoords::CoordSys* cs = faultMesh.coordsys();
   CPPUNIT_ASSERT(cs);
+  const int spaceDim = cs->spaceDim();
 
-  const int spaceDim = cs->spaceDim();
   const ALE::Obj<SieveSubMesh>& faultSieveMesh = faultMesh.sieveMesh();
   CPPUNIT_ASSERT(!faultSieveMesh.isNull());
   const ALE::Obj<SieveMesh::label_sequence>& vertices = faultSieveMesh->depthStratum(0);
   const SieveMesh::label_sequence::iterator verticesEnd = vertices->end();
-  topology::Field<topology::SubMesh> traction(faultMesh);
-  traction.newSection(vertices, spaceDim);
-  traction.allocate();
 
-  const PylithScalar t = 2.134;
-  tract.traction(&traction, t);
-
   //traction.view("TRACTION"); // DEBUGGING
 
   const PylithScalar tolerance = 1.0e-06;
   int iPoint = 0;
 
-  const ALE::Obj<RealSection>& tractionSection = traction.section();
-  CPPUNIT_ASSERT(!tractionSection.isNull());
+  CPPUNIT_ASSERT(tract._parameters);
+  const ALE::Obj<RealUniformSection>& paramsSection = tract._parameters->section();
+  CPPUNIT_ASSERT(!paramsSection.isNull());
+  const int fiberDim = tract._parameters->fiberDim();
+  const int valueIndex = tract._parameters->sectionIndex("value");
+  const int valueFiberDim = tract._parameters->sectionFiberDim("value");
+  CPPUNIT_ASSERT_EQUAL(spaceDim, valueFiberDim);
+  CPPUNIT_ASSERT(valueIndex + valueFiberDim < fiberDim);
+  
   for (SieveMesh::label_sequence::iterator v_iter=vertices->begin(); v_iter != verticesEnd; ++v_iter, ++iPoint) {
-    const int fiberDim = tractionSection->getFiberDimension(*v_iter);
-    CPPUNIT_ASSERT_EQUAL(spaceDim, fiberDim);
-    const PylithScalar* vals = tractionSection->restrictPoint(*v_iter);
+    CPPUNIT_ASSERT_EQUAL(fiberDim, paramsSection->getFiberDimension(*v_iter));
+    const PylithScalar* vals = paramsSection->restrictPoint(*v_iter);
     CPPUNIT_ASSERT(vals);
-
-    for (int iDim=0; iDim < fiberDim; ++iDim) {
+    
+    for (int iDim=0; iDim < spaceDim; ++iDim) {
       const PylithScalar valueE = tractionE[iPoint*spaceDim+iDim];
-      CPPUNIT_ASSERT_DOUBLES_EQUAL(valueE, vals[iDim], tolerance);
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(valueE, vals[valueIndex+iDim], tolerance);
     } // for
   } // for
-} // testTraction
+} // testCalculate
 
 // ----------------------------------------------------------------------
 // Test parameterFields() using 2-D mesh.
@@ -176,7 +222,7 @@
     1.5,
     2.5,
   };
-  const char* label = "change-start-time";
+  const char* label = "change_time_traction";
 
   topology::Mesh mesh;
   topology::SubMesh faultMesh;

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestTractPerturbation.hh
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestTractPerturbation.hh	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/TestTractPerturbation.hh	2012-05-09 22:48:01 UTC (rev 20059)
@@ -48,8 +48,9 @@
 
   CPPUNIT_TEST( testConstructor );
   CPPUNIT_TEST( testLabel );
+  CPPUNIT_TEST( testHasParameter );
   CPPUNIT_TEST( testInitialize );
-  CPPUNIT_TEST( testTraction );
+  CPPUNIT_TEST( testCalculate );
   CPPUNIT_TEST( testParameterFields );
   CPPUNIT_TEST( testVertexField );
 
@@ -64,11 +65,14 @@
   /// Test label().
   void testLabel(void);
 
+  /// Test hasParameter().
+  void testHasParameter(void);
+
   /// Test initialize() with 2-D mesh.
   void testInitialize(void);
 
-  /// Test traction() with 2-D mesh.
-  void testTraction(void);
+  /// Test calculate() with 2-D mesh.
+  void testCalculate(void);
 
   /// Test parameterFields() with 2-D mesh.
   void testParameterFields(void);

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataHex8.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataHex8.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataHex8.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -1340,10 +1340,11 @@
 };
 
 const PylithScalar pylith::faults::CohesiveDynDataHex8::_initialTractions[] = {
-  +3.0, -1.0, +2.0,
-  +3.1, -1.1, +2.1,
-  +3.2, -1.2, +2.2,
-  +3.3, -1.3, +2.3,
+  // Fault coordinate frame
+  +1.0, +2.0, -3.0,
+  +1.1, +2.1, -3.1,
+  +1.2, +2.2, -3.2,
+  +1.3, +2.3, -3.3,
 };
 
 

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataQuad4.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataQuad4.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataQuad4.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -281,8 +281,9 @@
 };
 
 const PylithScalar pylith::faults::CohesiveDynDataQuad4::_initialTractions[] = {
-  2.0, -1.0,
-  2.1, -1.1,
+  // Fault coordinate frame
+  1.0, -2.0,
+  1.1, -2.1,
 };
 
 

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTet4.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTet4.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTet4.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -485,9 +485,10 @@
 };
 
 const PylithScalar pylith::faults::CohesiveDynDataTet4::_initialTractions[] = {
-  +3.0, -1.0, +2.0, 
-  +3.1, -1.1, +2.1, 
-  +3.2, -1.2, +2.2, 
+  // Fault coordinate frame
+  +1.0, +2.0, -3.0,
+  +1.1, +2.1, -3.1,
+  +1.2, +2.2, -3.2,
 };
 
 

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTri3.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTri3.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTri3.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -251,8 +251,9 @@
 };
 
 const PylithScalar pylith::faults::CohesiveDynDataTri3::_initialTractions[] = {
-  2.0, -1.0,
-  2.1, -1.1,
+  // Fault coordinate frame
+  1.0, -2.0,
+  1.1, -2.1,
 };
 
 

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTri3d.cc
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTri3d.cc	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/libtests/faults/data/CohesiveDynDataTri3d.cc	2012-05-09 22:48:01 UTC (rev 20059)
@@ -437,9 +437,10 @@
 };
 
 const PylithScalar pylith::faults::CohesiveDynDataTri3d::_initialTractions[] = {
-  3.0*0.70710678118654757, 0.70710678118654757,
-  2.1, -1.1,
-  1.2,  2.2,
+  // Fault coordinate frame
+  1.0, -2.0,
+  1.1, -2.1,
+  1.2, -2.2,
 };
 
 

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/TestFaultCohesiveDyn.py
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/TestFaultCohesiveDyn.py	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/TestFaultCohesiveDyn.py	2012-05-09 22:48:01 UTC (rev 20059)
@@ -268,7 +268,7 @@
     quadrature.inventory.cell = cell
     quadrature._configure()
 
-    # Setup earthquake source
+    # Setup rupture info
     from spatialdata.spatialdb.SimpleDB import SimpleDB
     from spatialdata.spatialdb.SimpleIOAscii import SimpleIOAscii
     ioTractions = SimpleIOAscii()
@@ -278,7 +278,11 @@
     dbTractions.inventory.iohandler = ioTractions
     dbTractions.inventory.label = "initial tractions"
     dbTractions._configure()
-    
+    from pylith.faults.TractPerturbation import TractPerturbation
+    tract = TractPerturbation()
+    tract.inventory.dbInitial = dbTractions
+    tract._configure()
+
     ioFriction = SimpleIOAscii()
     ioFriction.inventory.filename = "data/tri3_staticfriction.spatialdb"
     ioFriction._configure()
@@ -301,6 +305,7 @@
     fault.inventory.faultLabel = "fault"
     fault.inventory.upDir = [0, 0, 1]
     fault.inventory.faultQuadrature = quadrature
+    fault.inventory.tract = tract
     fault.inventory.friction = friction
     fault._configure()
 

Added: short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/TestTractPerturbation.py
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/TestTractPerturbation.py	                        (rev 0)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/TestTractPerturbation.py	2012-05-09 22:48:01 UTC (rev 20059)
@@ -0,0 +1,81 @@
+#!/usr/bin/env python
+#
+# ======================================================================
+#
+# 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-2012 University of California, Davis
+#
+# See COPYING for license information.
+#
+# ======================================================================
+#
+
+## @file unittests/pytests/faults/TestTractPerturbation.py
+
+## @brief Unit testing of TractPerturbation object.
+
+import unittest
+
+from pylith.faults.TractPerturbation import TractPerturbation
+
+# ----------------------------------------------------------------------
+class TestTractPerturbation(unittest.TestCase):
+  """
+  Unit testing of TractPerturbation object.
+  """
+
+  def test_constructor(self):
+    """
+    Test constructor.
+    """
+    tract = TractPerturbation()
+    return
+
+
+  def test_configure(self):
+    """
+    Test initialize().
+    """
+    from spatialdata.spatialdb.SimpleDB import SimpleDB
+    from spatialdata.spatialdb.SimpleIOAscii import SimpleIOAscii
+    from pyre.units.time import second
+
+    ioInitial = SimpleIOAscii()
+    ioInitial.inventory.filename = "tri3_initialtractions.spatialdb"
+    ioInitial._configure()
+    dbInitial = SimpleDB()
+    dbInitial.inventory.iohandler = ioInitial
+    dbInitial.inventory.label = "initial tractions"
+    dbInitial._configure()
+    
+    ioChange = SimpleIOAscii()
+    ioChange.inventory.filename = "tri3_changetractions.spatialdb"
+    ioChange._configure()
+    dbChange = SimpleDB()
+    dbChange.inventory.iohandler = ioChange
+    dbChange.inventory.label = "traction change"
+    dbChange._configure()
+    
+    tract = TractPerturbation()
+    tract.inventory.dbInitial = dbInitial
+    tract.inventory.dbChange = dbChange
+    tract._configure()
+    return
+
+
+  def test_factory(self):
+    """
+    Test factory method.
+    """
+    from pylith.faults.TractPerturbation import traction_perturbation
+    fn = traction_perturbation()
+    return
+
+
+# End of file 

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/data/Makefile.am
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/data/Makefile.am	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/data/Makefile.am	2012-05-09 22:48:01 UTC (rev 20059)
@@ -23,6 +23,7 @@
 	tri3_sliptime.spatialdb \
 	tri3_peakrate.spatialdb \
 	tri3_initialtractions.spatialdb \
+	tri3_changetractions.spatialdb \
 	tri3_staticfriction.spatialdb \
 	tri3_impulses.spatialdb \
 	slipfn.timedb

Modified: short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/testfaults.py
===================================================================
--- short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/testfaults.py	2012-05-09 17:25:43 UTC (rev 20058)
+++ short/3D/PyLith/branches/v1.7-trunk/unittests/pytests/faults/testfaults.py	2012-05-09 22:48:01 UTC (rev 20059)
@@ -80,6 +80,9 @@
     from TestEqKinSrc import TestEqKinSrc
     suite.addTest(unittest.makeSuite(TestEqKinSrc))
 
+    from TestTractPerturbation import TestTractPerturbation
+    suite.addTest(unittest.makeSuite(TestTractPerturbation))
+
     from TestFaultCohesiveKin import TestFaultCohesiveKin
     suite.addTest(unittest.makeSuite(TestFaultCohesiveKin))
 



More information about the CIG-COMMITS mailing list