Skip to content

Commit 5f126c0

Browse files
Merge pull request #667 from baagaard-usgs/feature-output-traction-change
Add output of fault traction changes and boundary and fault orientation information
2 parents 57359a4 + 7ceb311 commit 5f126c0

File tree

113 files changed

+2449
-726
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

113 files changed

+2449
-726
lines changed

CHANGES.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
See <https://github.com/geodynamics/pylith/commits/main> for the complete log of changes made to PyLith.
22

3+
:::{note}
4+
Starting with v3.0.0, we strictly follow the [semantic versioning guidelines](https://semver.org/).
5+
The version numbers are in the form `MAJOR.MINOR.PATCH`, where major releases indicate changes to the public API (parameters), minor releases indicate new functionality that is backward compatible, and patch releases indicate backward compatible bug fixes.
6+
:::
7+
38
## Version 4.0.0
49

10+
### Changes in user parameters
11+
12+
* Changed name of fault Lagrange multiplier field for solution component in Python from `lagrange_fault` to `lagrange_multiplier_fault` to match name of solution field in C++.
513
* Removed support for importing meshes from LaGriT.
6-
* Add output of change in fault tractions for prescribed slip.
14+
15+
### Other changes
16+
17+
* Change in fault tractions are now included in the fault `data_fields` for prescribed slip.
18+
* Fault and boundary orientation directions are now included in the `info_fields` for simulation output.
719
* State variables are now included in the default `data_fields` for simulation output.
820
* The default solver settings use the PETSc proper orthogonal decomposition (POD) methodology for initial guess of solutions to improve convergence.
9-
* Changed name of fault Lagrange multiplier field for solution component in Python from `lagrange_fault` to `lagrange_multiplier_fault` to match name of solution field in C++.
1021
* Add demonstration of `pylith_powerlaw_gendb` in Step 8 of `examples/reverse-2d`.
1122
* Add demonstration of using poroelasticity with porosity as a state variable to `examples/magma-2d`.
1223
* Switched from CppUnit to Catch2 as the C++ testing framework.
13-
* Update to PETSc 3.19.5
24+
* Update to PETSc 3.20.2
1425
* Improve integration with VSCode for testing and debugging (see Developer Guide)
1526
* Bug fixes
1627
* Fix errors in KinSrcTimeHistory.py

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ AC_CHECK_HEADER([mpi.h], [], [AC_MSG_ERROR([header 'mpi.h' not found])])
109109

110110
dnl PETSC
111111
AC_LANG(C)
112-
CIT_PATH_PETSC([3.19.5])
112+
CIT_PATH_PETSC([3.20.2])
113113
CIT_HEADER_PETSC
114114
CIT_CHECK_LIB_PETSC
115115

docs/intro/development-plan.md

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,48 +6,53 @@ Future implementation of features is guided by several target applications, incl
66
* Inversion of geodetic data for slow slip events, fault creep, and long-term fault slip rates.
77
* Quasistatic and dynamic modeling of fluids and faulting.
88

9-
## Version 3.0.4 (September 2023)
9+
:::{note}
10+
Because we strictly follow the [semantic versioning guidelines](https://semver.org/), a minor release may get promoted to a major releases if we make changes to the public API (parameters).
11+
This can happen if realize that we should modify the parameters to improve maintainability or prepare for future changes.
12+
:::
1013

11-
Updates for examples and documentation along with bugfixes.
14+
## Version 4.0.0 (December 2023)
1215

1316
* Analytical function spatial database ![easy](images/easy.png)[100%]
1417
* Use `pod` initial guess to improve convergence ![easy](images/easy.png) [100%]
15-
* Dynamic prescribed slip with diagonal Jacobian for explicit part of IMEX formulation ![expert](images/expert.png)[75%]
16-
* Output of fault tractions ![expert](images/expert.png) [75%]
17-
* Update coordinates with solution ![intermediate](images/intermediate.png) [50%]
18-
* Convert from CppUnit to Catch2 ![easy](images/easy.png) [40%]
18+
* Output of fault tractions ![expert](images/expert.png) [100%]
19+
* Output of boundary and fault orientation ![export](images/expert.png) [100%]
20+
* Convert from CppUnit to Catch2 ![easy](images/easy.png) [100%]
21+
22+
## Version 4.1.0 (March 2024)
23+
24+
* Output of fault rupture auxiliary subfields ![intermediate](images/intermediate.png) [0%]
25+
* Dynamic prescribed slip with diagonal Jacobian for explicit part of IMEX formulation ![expert](images/expert.png) [75%]
26+
* Parallel mesh loading ![expert](images/expert.png) [15%]
27+
* Add 2D and 3D examples for crustal faults with complex fault geometry ![easy](images/easy.png) [50%]
1928
* Better preconditioners ![expert](images/expert.png) [25%]
2029
* elasticity with fault
2130
* incompressible elasticity
2231
* poroelasticity
23-
* Finish updating `examples/subduction-3d` ![intermediate](images/intermediate.png) [20%]
24-
* Add `examples/barwaves-2d` ![expert](images/expert.png) [15%]
25-
* Parallel mesh loading ![expert](images/expert.png) [15%]
26-
* Elasticity with self-gravitation ![intermediate](images/intermediate.png) [0%]
27-
* Add 2D and 3D examples for crustal faults with complex fault geometry ![easy](images/easy.png) [0%]
32+
* Update VTK output to use `vtu` files rather than legacy `vtk` files ![easy](images/easy.png) [0%]
33+
* Finish updating `examples/subduction-3d` ![intermediate](images/intermediate.png) [40%]
2834

29-
## Version 3.1.0 (December 2023)
35+
## Version 5.0.0 (June 2024)
3036

31-
* Spontaneous rupture for quasistatic simulations ![expert](images/expert.png) [20%]
37+
* Spontaneous rupture for quasistatic and dynamic simulations ![expert](images/expert.png) [20%]
38+
* Convert from SWIG to pybind11 ![intermediate](images/intermediate.png) [0%]
39+
* Reimplementation of Drucker-Prager elastoplastic bulk rheology ![intermediate](images/intermediate.png) [0%]
3240
* Add support for GeoModelGrids implementation of spatial databases for 3D seismic velocity models. ![intermediate](images/intermediate.png) [0%]
3341
* Improve robustness of HDF5 output by opening/closing at each time step ![easy](images/easy.png)[0%]
34-
* Dirichlet boundary conditions with constraints on normal and tangential components. ![difficult](images/difficult.png) [0%]
35-
* Additional minor cleanup of code internals to improve maintainability.
36-
* Refactor auxiliary field and derived field output (initial/timestep/final)
37-
* Output of fault rupture auxiliary fields
38-
* VTK output (vtk -> vtu)
39-
* Reimplementation of Drucker-Prager elastoplastic bulk rheology ![intermediate](images/intermediate.png) [0%]
40-
* Convert from SWIG to pybind11 ![intermediate](images/intermediate.png) [0%]
42+
* Add `examples/barwaves-2d` ![expert](images/expert.png) [15%]
43+
* Update coordinates with solution ![intermediate](images/intermediate.png) [50%]
4144

42-
## Version 4.0 (June 2024)
45+
## Version 6.0.0 (TBD)
4346

44-
* Spontaneous rupture for dynamic simulations ![expert](images/expert.png) [10%]
4547
* Migrate examples to Jupyter notebooks ![intermediate](images/intermediate.png)
4648
* Update to current version of Pyre ![difficult](images/difficult.png)
4749
* More flexible specification of time-dependent boundary conditions. ![difficult](images/difficult.png) [0%]
50+
* Dirichlet boundary conditions with constraints on normal and tangential components. ![difficult](images/difficult.png) [0%]
4851
* Integration with libCEED for fast high order residual evaluation ![expert](images/expert.png)\
4952
Contribution led by Jed Brown.
5053
* Add ability to output residual field during nonlinear solve for debugging ![easy](images/easy.png) [0%]
54+
* Elasticity with self-gravitation ![intermediate](images/intermediate.png) [0%]
55+
5156

5257
## Features for Future Releases
5358

@@ -59,7 +64,7 @@ Updates for examples and documentation along with bugfixes.
5964
* Adaptive mesh refinement ![expert](images/expert.png)
6065
* Line/point fluid sources in poroelasticity ![expert](images/expert.png) [20%]
6166
* Consolidate HDF5 output into a single file ![difficult](images/difficult.png)
62-
* Drucker-Prager bulk rheology with relaxation to yield surface ![intermediate](images/intermediate.png)
67+
* Drucker-Prager bulk rheology with relaxation to yield surface ![intermediate](images/intermediate.png)
6368
* Drucker-Prager bulk rheology with strain hardening/softening ![intermediate](images/intermediate.png)
6469
* Adjoint for data assimilation ![difficult](images/difficult.png)
6570
* Fault with both prescribed slip and spontaneous rupture ![difficult](images/difficult.png)\

docs/user/physics/bc/index.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ bc.y_pos = pylith.bc.AbsorbingDampers
3737
bc.z_neg = pylith.bc.NeumannTimeDependent
3838
```
3939

40+
## Diagnostic Information
41+
42+
The diagnostic information includes the outward normal direction (`normal_dir`) and the two tangential directions (`horizontal_tangential_dir` and `vertical_tangential_dir`).
43+
The default basis order for discretizing these directions is 1, so these produce `vertex_fields` as opposed to `cell_fields` (basis order of 0).
44+
4045
## Boundary Condition Implementations
4146

4247
:::{toctree}

docs/user/physics/faults/index.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,12 @@ The default value of [0, 0, 1] is appropriate for most 3D problems.
6868

6969
By default the output observers write both diagnostic information (for example, fault orientation directions) and the slip at each time step.
7070
The fault coordinate system is shown in {numref}`fig:fault:slip:motions`.
71-
The vectors in the fault coordinate system can be transformed to the global coordinate system using the direction vectors in the diagnostic output.
71+
The vectors in the fault coordinate system can be transformed to the global coordinate system using the direction vectors in the diagnostic output ({ref}`sec-user-output-observers`).
72+
73+
:::{important}
74+
The normal direction is chosen based on how the cells are split to create cohesive cells.
75+
If the normal direction contains a positive z component, then the directions conform to traditional seismologic conventions (along strike and up dip); however, if the normal direction contains a negative z component, then the directions correspond to along strike and down dip directions.
76+
:::
7277

7378
:::{toctree}
7479
prescribed-slip.md

docs/user/physics/faults/prescribed-slip.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,18 @@ The slip and slip initiation times are specified using spatial databases, so the
284284
:::{seealso}
285285
See [`KinSrcTimeHistory` Component](../components/faults/../../../components/faults/KinSrcTimeHistory.md) for the Pyre properties and facilities and configuration examples.
286286
:::
287+
288+
## Output
289+
290+
The derived subfield available for prescribed slip is the change in tractions on the fault surface.
291+
292+
:::{tip}
293+
To compute the change in tractions on a locked fault, prescribe zero slip on the fault.
294+
:::
295+
296+
```{table} Derived subfields that are available for output for prescribed slip.
297+
:name: tab:fault:prescribed_slip:derived:subfields
298+
| Subfield | Components |
299+
|:--------------|:-----------------------|
300+
| `traction_change` | normal, along strike, up dip |
301+
```

docs/user/physics/faults/slip-impulses.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,14 @@ Impulses will be applied at any point on the fault with a slip component greater
2525
:class: seealso
2626
See [`FaultCohesiveImpulses` Component](../../components/faults/FaultCohesiveImpulses.md) for the Pyre properties and facilities and configuration examples.
2727
:::
28+
29+
## Output
30+
31+
The derived subfield available for Green's functions is the change in tractions on the fault surface.
32+
33+
```{table} Derived subfields that are available for output for Green's functions.
34+
:name: tab:fault:prescribed_slip:derived:subfields
35+
| Subfield | Components |
36+
|:--------------|:-----------------------|
37+
| `traction_change` | normal, along strike, up dip |
38+
```

docs/user/problems/output.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,9 @@ The monitor calculates the percent completed based on the number of steps (e.g.,
3636
## Observers
3737

3838
Observer objects manage transferring the solution and state variables to other objects, including output and external software.
39-
Currently, PyLith only includes observers for output.
39+
Currently, the only type of observers implemented in PyLith are ones that produce output.
4040

41+
(sec-user-output-observers)=
4142
### Output Observers
4243

4344
PyLith currently supports output to HDF5/Xdmf and VTK files, which can be imported directly into a number of visualization tools, such as ParaView, Visit, and MayaVi.
@@ -55,6 +56,27 @@ Fields with a basis order of 0 are kept at a basis order of 0 when output.
5556
Fields with a basis order of 1 or more can be output with a basis order of 0 or 1.
5657
:::
5758

59+
The output observers produce files with either diagnostic information (`info` files) or solution and state variable information (`data` files).
60+
The default behavior is the files include all available information.
61+
The `info` files include the auxiliary subfields at the beginning of the simulation along with surface orientation information for faults and boundary conditions.
62+
The `data` files include all solution subfields, state variables, and derived fields (fields computed from the solution, such as Cauchy stress and strain).
63+
64+
For boundary conditions the orientation information is provided in terms of x, y, and z components of the unit vectors for the surface normal and tangential directions.
65+
In 3D the "vertical" tangential direction is the cross product of the surface normal and horizontal tangential direction; it is in the +z direction for a vertical boundary.
66+
In the case of the horizontal boundary, the horizontal tangential direction is in the +x direction and the "vertical" tangential direction is in the +y direction.
67+
For a fault surface the horizontal tangential direction generally corresponds to the along-strike direction and the "vertical" tangential direction generally corresponds to the up-dip direction; the exception is a 2D simulation for a vertical cross-section in which the "horizontal" tangential direction corresponds to the dip direction.
68+
69+
The orientation information is useful for transforming from components written in terms of a surface (for example, left lateral, reverse, and opening fault tractions), into the model coordinate system (for example, the global Cartesian coordinate system).
70+
Given unit vector components $n_x$, $n_y$, $n_z$ (normal direction), $h_x$, $h_y$, $h_z$ (horizontal tangential direction or along-strike direction), and $v_x$, $v_y$, $v_z$ (vertical tangential direction or up-dip direction), we can transform a vector in the boundary (or fault) coordinate system ($a_n$, $a_h$, $a_v$) into the global coordinate system using
71+
72+
\begin{align}
73+
a_x &= a_n n_x + a_h h_x + a_v v_x \\
74+
a_y &= a_n n_y + a_h h_y + a_v v_y \\
75+
a_z &= a_n n_z + a_h h_z + a_v v_z
76+
\end{align}
77+
78+
This transformation is useful for plotting fault tractions and slip in 3D visualization tools such as ParaView that require vectors in the model coordinate system.
79+
5880
(sec-user-solution-observers)=
5981
### Solution Observers
6082

libsrc/pylith/Makefile.am

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ lib_LTLIBRARIES = libpylith.la
3333

3434
libpylith_la_SOURCES = \
3535
bc/BoundaryCondition.cc \
36+
bc/DiagnosticFieldFactory.cc \
3637
bc/TimeDependentAuxiliaryFactory.cc \
3738
bc/DirichletTimeDependent.cc \
3839
bc/DirichletUserFn.cc \
@@ -43,7 +44,9 @@ libpylith_la_SOURCES = \
4344
faults/FaultCohesive.cc \
4445
faults/FaultCohesiveKin.cc \
4546
faults/FaultCohesiveImpulses.cc \
46-
faults/AuxiliaryFactoryKinematic.cc \
47+
faults/AuxiliaryFieldFactory.cc \
48+
faults/DiagnosticFieldFactory.cc \
49+
faults/DerivedFieldFactory.cc \
4750
faults/KinSrc.cc \
4851
faults/KinSrcStep.cc \
4952
faults/KinSrcRamp.cc \
@@ -120,6 +123,7 @@ libpylith_la_SOURCES = \
120123
problems/ObserverSoln.cc \
121124
problems/ObserversSoln.cc \
122125
problems/Physics.cc \
126+
problems/Observer.cc \
123127
problems/ObserverPhysics.cc \
124128
problems/ObserversPhysics.cc \
125129
problems/InitialCondition.cc \

libsrc/pylith/bc/AbsorbingDampers.cc

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ pylith::bc::AbsorbingDampers::createIntegrator(const pylith::topology::Field& so
131131
integrator->setLabelValue(getLabelValue());
132132

133133
_AbsorbingDampers::setKernelsResidual(integrator, *this, solution);
134+
BoundaryCondition::_setKernelsDiagnosticField(integrator, solution);
134135

135136
PYLITH_METHOD_RETURN(integrator);
136137
} // createIntegrator
@@ -188,18 +189,6 @@ pylith::bc::AbsorbingDampers::createAuxiliaryField(const pylith::topology::Field
188189
} // createAuxiliaryField
189190

190191

191-
// ---------------------------------------------------------------------------------------------------------------------
192-
// Create derived field.
193-
pylith::topology::Field*
194-
pylith::bc::AbsorbingDampers::createDerivedField(const pylith::topology::Field& solution,
195-
const pylith::topology::Mesh& domainMesh) {
196-
PYLITH_METHOD_BEGIN;
197-
PYLITH_COMPONENT_DEBUG("createDerivedField(solution="<<solution.getLabel()<<", domainMesh=)"<<typeid(domainMesh).name()<<") empty method");
198-
199-
PYLITH_METHOD_RETURN(NULL);
200-
} // createDerivedField
201-
202-
203192
// ---------------------------------------------------------------------------------------------------------------------
204193
// Get auxiliary field factory associated with physics.
205194
pylith::feassemble::AuxiliaryFactory*
@@ -208,25 +197,6 @@ pylith::bc::AbsorbingDampers::_getAuxiliaryFactory(void) {
208197
} // _getAuxiliaryFactory
209198

210199

211-
// ---------------------------------------------------------------------------------------------------------------------
212-
// Update kernel constants.
213-
void
214-
pylith::bc::AbsorbingDampers::_updateKernelConstants(const PylithReal dt) {
215-
PYLITH_METHOD_BEGIN;
216-
PYLITH_COMPONENT_DEBUG("_setKernelConstants(dt="<<dt<<")");
217-
218-
if (6 != _kernelConstants.size()) { _kernelConstants.resize(6);}
219-
_kernelConstants[0] = _refDir1[0];
220-
_kernelConstants[1] = _refDir1[1];
221-
_kernelConstants[2] = _refDir1[2];
222-
_kernelConstants[3] = _refDir2[0];
223-
_kernelConstants[4] = _refDir2[1];
224-
_kernelConstants[5] = _refDir2[2];
225-
226-
PYLITH_METHOD_END;
227-
} // _updateKernelConstants
228-
229-
230200
// ---------------------------------------------------------------------------------------------------------------------
231201
// Set kernels for residual.
232202
void

0 commit comments

Comments
 (0)