diff --git a/configure.ac b/configure.ac index c9b8ee33b1..3a8d2a0df4 100644 --- a/configure.ac +++ b/configure.ac @@ -114,7 +114,7 @@ AC_CHECK_HEADER([mpi.h], [], [AC_MSG_ERROR([header 'mpi.h' not found])]) dnl PETSC AC_LANG(C) -CIT_PATH_PETSC([3.23.5]) +CIT_PATH_PETSC([3.24.0]) CIT_HEADER_PETSC CIT_CHECK_LIB_PETSC @@ -205,6 +205,7 @@ AC_CONFIG_FILES([Makefile libsrc/pylith/problems/Makefile libsrc/pylith/topology/Makefile libsrc/pylith/utils/Makefile + libsrc/pylith/scales/Makefile libsrc/pylith/testing/Makefile modulesrc/Makefile modulesrc/include/Makefile @@ -216,6 +217,7 @@ AC_CONFIG_FILES([Makefile modulesrc/meshio/Makefile modulesrc/mpi/Makefile modulesrc/problems/Makefile + modulesrc/scales/Makefile modulesrc/topology/Makefile modulesrc/utils/Makefile tests/Makefile @@ -233,6 +235,7 @@ AC_CONFIG_FILES([Makefile tests/libtests/problems/Makefile tests/libtests/problems/data/Makefile tests/libtests/meshio/data/Makefile + tests/libtests/scales/Makefile tests/libtests/topology/Makefile tests/libtests/topology/data/Makefile tests/libtests/testing/Makefile diff --git a/developer/uncrustify.cfg b/developer/uncrustify.cfg index 9eb18da2ad..22c03da1bb 100644 --- a/developer/uncrustify.cfg +++ b/developer/uncrustify.cfg @@ -51,8 +51,8 @@ sp_endif_cmt = Add sp_after_new = Add sp_paren_brace = Add sp_fparen_brace = Add -sp_before_tr_emb_cmt = Force -sp_num_before_tr_emb_cmt = 1 +sp_before_tr_cmt = Force +sp_num_before_tr_cmt = 1 # Align align_left_shift = True @@ -98,7 +98,7 @@ nl_if_leave_one_liners = True nl_after_brace_open = False nl_after_brace_close = False nl_after_brace_open_cmt = False -nl_max = 2 +nl_max = 3 nl_after_func_proto = 2 nl_after_func_body = 3 nl_after_func_body_class = 2 diff --git a/docs/Makefile.am b/docs/Makefile.am index 41f8108fd2..8aeefe692a 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -679,6 +679,7 @@ dist_noinst_DATA = \ user/problems/figs/hdf5layout.svg \ user/problems/figs/hdf5layout.tex \ user/problems/index.md \ + user/problems/nondimensionalization.md \ user/problems/output.md \ user/problems/problems.md \ user/run-pylith/figs/cells2d.pdf \ diff --git a/docs/developer/implementation/figs/classdiagram_problem.tex b/docs/developer/implementation/figs/classdiagram_problem.tex index b97e87215e..c66c977237 100644 --- a/docs/developer/implementation/figs/classdiagram_problem.tex +++ b/docs/developer/implementation/figs/classdiagram_problem.tex @@ -19,7 +19,7 @@ \node (pyre-component) [abstract-class, anchor=west] at ($(pythia-component.east)+(2em,0)$) {\umlemptyclass{PyreComponent}}; \node (python-problem) [abstract-class] at ($(petsc-component.south)-(0,4em)$) {\umlclass{Python Problem}{% - normalizer\\ + scales\\ materials\\ bc\\ interfaces\\ @@ -28,7 +28,7 @@ observers }}; \node (cxx-problem) [abstract-class, anchor=north] at ($(python-problem.north)+(12em,0)$) {\umlclass{C++ Problem}{% - normalizer\\ + scales\\ materials\\ bc\\ interfaces\\ @@ -53,8 +53,8 @@ }}; - \node (normalizer) [abstract-class, anchor=west] at ($(cxx-problem.east)+(12em,12em)$) {\umlemptyclass{spatialdata::units::Nondimensional}}; - \node (material) [abstract-class] at ($(normalizer.south)-(0,1em)$) {\umlemptyclass{Material}}; + \node (scales) [abstract-class, anchor=west] at ($(cxx-problem.east)+(12em,12em)$) {\umlemptyclass{pylith::scales::Scales}}; + \node (material) [abstract-class] at ($(scales.south)-(0,1em)$) {\umlemptyclass{Material}}; \node (bc) [abstract-class] at ($(material.south)-(0,1em)$) {\umlemptyclass{BoundaryCondition}}; \node (interface) [abstract-class] at ($(bc.south)-(0,1em)$) {\umlemptyclass{FaultCohesive}}; \node (gravity-field) [concrete-class] at ($(interface.south)-(0,1em)$) {\umlemptyclass{spatialdata::spatialdb::GravityField}}; @@ -76,7 +76,7 @@ \draw[inherit] (cxx-problem) -- (pyre-component); \draw[inherit] (cxx-time-dependent) -- (cxx-problem); - \draw[aggregate] ($(cxx-problem.east)+(0,8ex)$) -- (normalizer.west); + \draw[aggregate] ($(cxx-problem.east)+(0,8ex)$) -- (scales.west); \draw[aggregate] ($(cxx-problem.east)+(0,5.5ex)$) -- (material.west); \draw[aggregate] ($(cxx-problem.east)+(0,3.0ex)$) -- (bc.west); \draw[aggregate] ($(cxx-problem.east)+(0,0.5ex)$) -- (interface.west); diff --git a/docs/developer/testing/libtests.md b/docs/developer/testing/libtests.md index a5e67d8b3d..699892c4ef 100644 --- a/docs/developer/testing/libtests.md +++ b/docs/developer/testing/libtests.md @@ -60,7 +60,7 @@ namespace pylith { class pylith::problems::TestPhysics : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(TestPhysics); // CppUnit macro used to define the `TestPhysics` test suite. - CPPUNIT_TEST(testSetNormalizer); // CppUnit macro to add test implemented by class method. + CPPUNIT_TEST(testSetScales); // CppUnit macro to add test implemented by class method. CPPUNIT_TEST(testSetAuxiliaryFieldDB); CPPUNIT_TEST(testSetAuxiliarySubfieldDiscretization); CPPUNIT_TEST(testObservers); @@ -81,7 +81,7 @@ public: // Methods that implement tests. The naming convention is testMethodName. // All test methods must return void and not have any arguments. - void testSetNormalizer(void); + void testSetScales(void); void testSetAuxiliaryFieldDB(void); void testSetAuxiliarySubfieldDiscretization(void); void testObservers(void); @@ -129,20 +129,20 @@ pylith::problems::TestPhysics::tearDown(void) { void -pylith::problems::TestPhysics::testSetNormalizer(void) { +pylith::problems::TestPhysics::testSetScales(void) { PYLITH_METHOD_BEGIN; - spatialdata::units::Nondimensional normalizer; + pylith::scales::Scales scales; const PylithReal lengthScale = 3.0; - normalizer.setLengthScale(lengthScale); + scales.setLengthScale(lengthScale); CPPUNIT_ASSERT(_physics); - _physics->setNormalizer(normalizer); + _physics->setScales(scales); - CPPUNIT_ASSERT_DOUBLES_EQUAL(lengthScale, _physics->_normalizer->getLengthScale(), 1.0e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(lengthScale, _physics->_scales->getLengthScale(), 1.0e-6); PYLITH_METHOD_END; -} // testSetNormalizer +} // testSetScales void diff --git a/docs/user/components/problems/GreensFns.md b/docs/user/components/problems/GreensFns.md index 539a753062..7972677129 100644 --- a/docs/user/components/problems/GreensFns.md +++ b/docs/user/components/problems/GreensFns.md @@ -25,9 +25,9 @@ Implements `Problem`. * `materials`: Materials in problem. - **current value**: 'homogeneous', from {default} - **configurable as**: homogeneous, materials -* `normalizer`: Nondimensionalizer for problem. +* `scales`: Nondimensionalizer for problem. - **current value**: 'nondimelasticquasistatic', from {default} - - **configurable as**: nondimelasticquasistatic, normalizer + - **configurable as**: nondimelasticquasistatic, scales * `petsc_defaults`: Flags controlling which default PETSc options to use. - **current value**: 'petscdefaults', from {default} - **configurable as**: petscdefaults, petsc_defaults diff --git a/docs/user/components/problems/Problem.md b/docs/user/components/problems/Problem.md index 2a57621629..622cf5157e 100644 --- a/docs/user/components/problems/Problem.md +++ b/docs/user/components/problems/Problem.md @@ -29,9 +29,9 @@ If the nonlinear (SNES) solver requires multiple iterations to converge for thes * `materials`: Materials in problem. - **current value**: 'homogeneous', from {default} - **configurable as**: homogeneous, materials -* `normalizer`: Nondimensionalizer for problem. +* `scales`: Nondimensionalizer for problem. - **current value**: 'nondimelasticquasistatic', from {default} - - **configurable as**: nondimelasticquasistatic, normalizer + - **configurable as**: nondimelasticquasistatic, scales * `petsc_defaults`: Flags controlling which default PETSc options to use. - **current value**: 'petscdefaults', from {default} - **configurable as**: petscdefaults, petsc_defaults diff --git a/docs/user/components/problems/TimeDependent.md b/docs/user/components/problems/TimeDependent.md index e8f8d40d12..2a89c4fa0d 100644 --- a/docs/user/components/problems/TimeDependent.md +++ b/docs/user/components/problems/TimeDependent.md @@ -28,9 +28,9 @@ Implements `Problem`. * `materials`: Materials in problem. - **current value**: 'homogeneous', from {default} - **configurable as**: homogeneous, materials -* `normalizer`: Nondimensionalizer for problem. +* `scales`: Nondimensionalizer for problem. - **current value**: 'nondimelasticquasistatic', from {default} - - **configurable as**: nondimelasticquasistatic, normalizer + - **configurable as**: nondimelasticquasistatic, scales * `petsc_defaults`: Flags controlling which default PETSc options to use. - **current value**: 'petscdefaults', from {default} - **configurable as**: petscdefaults, petsc_defaults @@ -89,8 +89,8 @@ ic = [domain] # Turn on gravitational body forces gravity_field = spatialdata.spatialdb.GravityField -# Set the normalizer for nondimensionalizing the problem -normalizer = spatialdata.units.NondimElasticQuasistatic +# Set the scales for nondimensionalizing the problem +scales = pylith.scales.NondimElasticQuasistatic # Set the subfields in the solution solution = = pylith.problems.SolnDispLagrange diff --git a/docs/user/examples/box-2d/step05-sheardisptractrate.md b/docs/user/examples/box-2d/step05-sheardisptractrate.md index b6a35f1b1e..b56506d58a 100644 --- a/docs/user/examples/box-2d/step05-sheardisptractrate.md +++ b/docs/user/examples/box-2d/step05-sheardisptractrate.md @@ -34,7 +34,7 @@ start_time = -1.0*year end_time = 5.0*year initial_dt = 1.0*year -[pylithapp.problem.normalizer] +[pylithapp.problem.scales] relaxation_time = 10.0*year ``` diff --git a/docs/user/examples/box-3d/step05-sheardisptractrate.md b/docs/user/examples/box-3d/step05-sheardisptractrate.md index d55e2bc357..7079563e39 100644 --- a/docs/user/examples/box-3d/step05-sheardisptractrate.md +++ b/docs/user/examples/box-3d/step05-sheardisptractrate.md @@ -34,7 +34,7 @@ initial_dt = 1.0*year start_time = -1.0*year end_time = 5.0*year -[pylithapp.problem.normalizer] +[pylithapp.problem.scales] relaxation_time = 10.0*year ``` diff --git a/docs/user/examples/magma-2d/common-information.md b/docs/user/examples/magma-2d/common-information.md index 1188903a29..05010c41ca 100644 --- a/docs/user/examples/magma-2d/common-information.md +++ b/docs/user/examples/magma-2d/common-information.md @@ -38,10 +38,10 @@ pressure.basis_order = 1 trace_strain.basis_order = 1 [pylithapp.problem] -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 100.0*m -normalizer.relaxation_time = 0.2*year -normalizer.shear_modulus = 10.0*GPa +scales = pylith.scales.NondimElasticQuasistatic +scales.length_scale = 100.0*m +scales.relaxation_time = 0.2*year +scales.shear_modulus = 10.0*GPa ``` We use the material properties in all of the simulations in this directory, so we specify them in `pylithapp.cfg` to avoid repeating the information in the file with parameters for each simulation. diff --git a/docs/user/examples/poroelastic-outerrise-2d/common-information.md b/docs/user/examples/poroelastic-outerrise-2d/common-information.md index b54500d330..86a01f269b 100644 --- a/docs/user/examples/poroelastic-outerrise-2d/common-information.md +++ b/docs/user/examples/poroelastic-outerrise-2d/common-information.md @@ -50,10 +50,10 @@ auxiliary_subfields.isotropic_permeability.basis_order = 2 caption: Nondimensionalization parameters for the 2D outer-rise examples with poroelasticity. --- [pylithapp.problem] -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 100.0*m -normalizer.relaxation_time = 1*year -normalizer.shear_modulus = 10.0*GPa +scales = pylith.scales.NondimElasticQuasistatic +scales.length_scale = 100.0*m +scales.relaxation_time = 1*year +scales.shear_modulus = 10.0*GPa ``` ```{code-block} cfg diff --git a/docs/user/examples/reverse-2d/step07-twofaults-maxwell.md b/docs/user/examples/reverse-2d/step07-twofaults-maxwell.md index 85dc84dbec..4828bb912e 100644 --- a/docs/user/examples/reverse-2d/step07-twofaults-maxwell.md +++ b/docs/user/examples/reverse-2d/step07-twofaults-maxwell.md @@ -22,7 +22,7 @@ initial_dt = 4.0*year start_time = -4.0*year end_time = 100.0*year -normalizer.relaxation_time = 20.0*year +scales.relaxation_time = 20.0*year ``` ```{code-block} cfg diff --git a/docs/user/governingeqns/elasticity/index.md b/docs/user/governingeqns/elasticity/index.md index b4cc6b17d5..959589bcd8 100644 --- a/docs/user/governingeqns/elasticity/index.md +++ b/docs/user/governingeqns/elasticity/index.md @@ -3,6 +3,7 @@ :::{toctree} derivation.md +nondimensionalization.md infinitesimal-strain.md prescribed-slip.md bulk-rheologies/index.md diff --git a/docs/user/governingeqns/elasticity/nondimensionalization.md b/docs/user/governingeqns/elasticity/nondimensionalization.md new file mode 100644 index 0000000000..fba4a89d69 --- /dev/null +++ b/docs/user/governingeqns/elasticity/nondimensionalization.md @@ -0,0 +1,125 @@ +# Nondimensionalization + +Starting with the elasticity equation, +% +\begin{gather} +\rho(\vec{x})\frac{\partial^{2}\vec{u}}{\partial t^{2}}-\vec{f}(\vec{x},t)-\boldsymbol{\nabla}\cdot\boldsymbol{\sigma}=\vec{0}\text{ in }\Omega,\\ +\boldsymbol{\sigma}(\vec{u})\cdot\vec{n}=\vec{\tau}(\vec{x},t)\text{ on }\Gamma_{\tau}\text{,}\\ +\vec{u}^{+}-\vec{u}^{-}=\vec{d}\text{ on }\Gamma_{f}. +\end{gather} +% +we define nondimensional values: +% +\begin{align} +\vec{x}^* &= \frac{\vec{x}}{x_o}, \\ +\vec{u}^* &= \frac{\vec{u}}{u_o}, \\ +\rho^* &= \frac{\rho}{\rho_o}, \\ +\vec{f}^* &= \frac{\vec{f}}{f_o}, \\ +\boldsymbol{\sigma}^* &= \frac{\boldsymbol{\sigma}}{\sigma_o}, \\ +\vec{\tau}^* &= \frac{\vec{\tau}}{\sigma_o}. +\end{align} +% +We also recognize that +% +\begin{equation} +\boldsymbol{\nabla}^* = x_o \boldsymbol{\nabla}. +\end{equation} + +Substituting into the equations, we have +% +\begin{gather} +\rho_o \rho^*(\vec{x}^*) \frac{u_o}{t_o^2} \frac{\partial^{2}\vec{u}^*}{\partial {t^*}^{2}} - f_o \vec{f}^*(\vec{x}^*,t^*) - \frac{\sigma_o}{x_o} \boldsymbol{\nabla}^*\cdot\boldsymbol{\sigma}^* = \vec{0}\text{ in }\Omega,\\ +\sigma_o \boldsymbol{\sigma}^*(\vec{u^*}) \cdot \vec{n} = \sigma_o \vec{\tau}^*(\vec{x}^*,t^*)\text{ on }\Gamma_{\tau}\text{,}\\ +u_o \left(\vec{u}^{*^{+}}-\vec{u}^{*^{-}}\right) = u_o \vec{d}^* \text{ on }\Gamma_{f}. +\end{gather} + +For the second two equations, the nondimensional scales in for the terms in each equation are consistent, so we will limit our discussion to the first equation. +Grouping terms and multiplying by $\frac{x_o}{\sigma_o}$, we have +% +\begin{equation} +\left( \rho_o \frac{u_o}{t_o^2}\frac{x_o}{\sigma_o}\right) \rho^*(\vec{x}^*) \frac{\partial^{2}\vec{u}^*}{\partial {t^*}^{2}} - \left(f_o \frac{x_o}{\sigma_o}\right) \vec{f}^*(\vec{x}^*,t^*) - \boldsymbol{\nabla}^*\cdot\boldsymbol{\sigma}^* = \vec{0}\text{ in }\Omega. +\end{equation} +% +All terms should be nondimensional, which implies +% +\begin{align} +f_o &= \frac{\sigma_o}{x_o}, \\ +\rho_o &= \frac{t_o^2 \sigma_o}{u_o x_o}. +\end{align} + +We want to determine the stress scale, $\sigma_o$. +Considering isotropic, linear elasticity we have +% +\begin{equation} +\boldsymbol{\sigma} = \boldsymbol{C} : \boldsymbol{\epsilon} = \boldsymbol{C} : \frac{1}{2}\left(\boldsymbol{\nabla} + \boldsymbol{\nabla}^T \right) \vec{u}. +\end{equation} +% +Substituting in our nondimensional values yields +% +\begin{equation} +\sigma_o \boldsymbol{\sigma}^* = \mu_o \boldsymbol{C}^* : \frac{u_o}{x_o} \frac{1}{2}\left(\boldsymbol{\nabla}^* + \boldsymbol{\nabla}^{*^T}\right) \vec{u}^*. +\end{equation} +% +We recognize that for the equation to be nondimensional, +\begin{equation} +\sigma_o = \mu_o \frac{u_o}{x_o}. +\end{equation} + +Returning to the expression for $\rho_o$ and substituting in the expression for $\sigma_o$, we have +\begin{align} +\rho_o &= \frac{t_o^2 \sigma_o}{u_o x_o}, \\ +\rho_o &= \mu_o \frac{t_o^2}{x_o^2}. +\end{align} + +## Inertia + +The scale of the inertial term is $\Pi_\mathit{inertia} = \frac{\rho_o x_o^2}{\mu_o t_o^2}$. +If this term is O(1), then we should include inertia and solve the dynamic form of the elasticity equation. +If this term is very small, then we can neglect inertia and solve the quasistatic form of the elasticity equation. + +**If the time scale equals the time it takes the shear wave ($v_o^2 = \frac{\mu_o}{\rho_o}$) to propagate over the length scale**, then +\begin{align} +t_o &= \frac{x_o}{v_o}, \\ +t_o^2 &= \frac{x_o^2}{v_o^2}, \\ +t_o^2 &= \frac{x_o^2 \rho_o}{\mu_o}. +\end{align} +Substituting into the expression for $\Pi_\mathit{inertia}$, we have +\begin{align} +\Pi_\mathit{inertia} &= \frac{\rho_o x_o^2}{\mu_o t_o^2}, \\ +\Pi_\mathit{inertia} &= \frac{\rho_o x_o^2}{\mu_o} \frac{\mu_o}{\rho_o x_o^2}, \\ +\Pi_\mathit{inertia} &= 1. +\end{align} +In this case, the inertial term is important, and we have the dynamic case with propagating seismic waves. + +**If the time scale is much larger than the time it takes the shear wave to propagate over the length scale**, then +\begin{align} +t_o &\gg \frac{x_o}{v_o}, \\ +t_o^2 &\gg \frac{x_o^2 \rho_o}{\mu_o}. +\end{align} +Substituting into the expression for $\Pi_\mathit{inertia}$, we have +\begin{align} +\Pi_\mathit{inertia} &= \frac{\rho_o x_o^2}{\mu_o t_o^2}, \\ +\Pi_\mathit{inertia} &\ll \frac{\rho_o x_o^2}{\mu_o} \frac{\mu_o}{\rho_o x_o^2}, \\ +\Pi_\mathit{inertia} &\ll 1. +\end{align} +In this case, the inertial term is negligible, and we have quasistatic elasticity. +::: + +:::{note} +In PyLith v4 and earlier, we used a displacement scale equal to the length scale. +Using separate length and displacement scales facilitates accurately solving for displacements many orders of magnitude smaller than the length scale. +It also separates the stress scale used to nondimensionalize stress, tractions, and fluid pressure from the rigidity scale. +::: + +```{table} Nondimensionalization of elasticity. +:name: tab:elasticity:scales +| **Quantity** | **Scale** | +| :---------: | :------------------ | +| $x_o$ | Length scale | +| $u_o$ | Displacement scale | +| $\mu_o$ | Rigidity scale | +| $t_o$ | Time scale | +| $\sigma_o = \mu_o \frac{u_o}{x_o}$ | Stress scale | +| $f_o = \frac{\sigma_o}{x_o}$ | Body force scale | +| $\rho_o = \mu_o \frac{t_o^2}{x_o^2}$ | Density scale | +``` diff --git a/docs/user/governingeqns/incompressible-elasticity/index.md b/docs/user/governingeqns/incompressible-elasticity/index.md index a4d37f9671..b9849c9174 100644 --- a/docs/user/governingeqns/incompressible-elasticity/index.md +++ b/docs/user/governingeqns/incompressible-elasticity/index.md @@ -3,5 +3,6 @@ :::{toctree} infinitesimal-strain.md +nondimensionalization.md bulk-rheologies/index.md ::: diff --git a/docs/user/governingeqns/incompressible-elasticity/infinitesimal-strain.md b/docs/user/governingeqns/incompressible-elasticity/infinitesimal-strain.md index d5ae065e13..7a0e5b85a4 100644 --- a/docs/user/governingeqns/incompressible-elasticity/infinitesimal-strain.md +++ b/docs/user/governingeqns/incompressible-elasticity/infinitesimal-strain.md @@ -15,7 +15,7 @@ The strong form is % Solution \vec{s}^T = \left( \vec{u} \quad \ p \right)^T, \\ % Elasticity -\rho \frac{\partial^2\vec{u}}{\partial t^2} - \vec{f}(\vec{x},t) - \left(\boldsymbol{\sigma}^\mathit{dev}(\vec{u}) - p\boldsymbol{I}\right) = \vec{0} \text{ in }\Omega, +\rho \frac{\partial^2\vec{u}}{\partial t^2} - \vec{f}(\vec{x},t) - \left(\boldsymbol{\sigma}^\mathit{dev}(\vec{u}) - p\boldsymbol{I}\right) = \vec{0} \text{ in }\Omega, \\ % Pressure \vec{\nabla} \cdot \vec{u} + \frac{p}{K} = 0 \text{ in }\Omega, \\ % Neumann diff --git a/docs/user/governingeqns/incompressible-elasticity/nondimensionalization.md b/docs/user/governingeqns/incompressible-elasticity/nondimensionalization.md new file mode 100644 index 0000000000..cfc2993421 --- /dev/null +++ b/docs/user/governingeqns/incompressible-elasticity/nondimensionalization.md @@ -0,0 +1,75 @@ +# Nondimensionalization + +Starting with the incompressible elasticity equation, +% +\begin{gather} +% Elasticity +\rho(\vec{x})\frac{\partial^{2}\vec{u}}{\partial t^{2}}-\vec{f}(\vec{x},t)-\boldsymbol{\nabla}\cdot\boldsymbol{\sigma}=\vec{0}\text{ in }\Omega, \\ +% Pressure +\vec{\nabla} \cdot \vec{u} + \frac{p}{K} = 0 \text{ in }\Omega, \text{ where}\\ +% Stress +\boldsymbol{\sigma} = \boldsymbol{\sigma}^{\mathit{dev}} - p \boldsymbol{I}. +\end{gather} +% +we define nondimensional values: +% +\begin{align} +\vec{x}^* &= \frac{\vec{x}}{x_o}, \\ +\vec{u}^* &= \frac{\vec{u}}{u_o}, \\ +p^* &= \frac{p}{p_o}, \\ +\rho^* &= \frac{\rho}{\rho_o}, \\ +\vec{f}^* &= \frac{\vec{f}}{f_o}, \\ +\boldsymbol{\sigma}^* &= \frac{\boldsymbol{\sigma}}{\sigma_o}, \\ +\vec{\tau}^* &= \frac{\vec{\tau}}{\sigma_o}. +\end{align} +% +As in the case of the elasticity equation, we also recognize that +% +\begin{equation} +\boldsymbol{\nabla}^* = x_o \boldsymbol{\nabla}. +\end{equation} + +Substituting into the equations, we have +% +\begin{gather} +% Elasticity +\rho_o \rho^*(\vec{x}^*) \frac{u_o}{t_o^2} \frac{\partial^{2}\vec{u}^*}{\partial {t^*}^{2}} - f_o \vec{f}^*(\vec{x}^*,t^*) - \frac{\sigma_o}{x_o} \boldsymbol{\nabla}^*\cdot\boldsymbol{\sigma}^* = \vec{0}\text{ in }\Omega,\\ +% Pressure +\frac{u_o}{x_o}\left( \vec{\nabla}^* \cdot \vec{u}^*\right) + \frac{p_o}{\mu_o} \frac{p^*}{K^*} = 0 \text{ in }\Omega. +\end{gather} + +Grouping terms we have +% +\begin{gather} +% Elasticity +\left( \rho_o \frac{u_o}{t_o^2}\frac{x_o}{\sigma_o}\right) \rho^*(\vec{x}^*) \frac{\partial^{2}\vec{u}^*}{\partial {t^*}^{2}} - \left(f_o \frac{x_o}{\sigma_o}\right) \vec{f}^*(\vec{x}^*,t^*) - \boldsymbol{\nabla}^*\cdot\boldsymbol{\sigma}^* = \vec{0}\text{ in }\Omega, \\ +% Pressure +\vec{\nabla}^* \cdot \vec{u}^* + \frac{p_o u_o}{\mu_o x_o} \frac{p^*}{K^*} = 0 \text{ in }\Omega. +\end{gather} +% +All terms should be nondimensional, which implies +% +\begin{align} +f_o &= \frac{\sigma_o}{x_o}, \\ +\rho_o &= \frac{t_o^2 \sigma_o}{u_o x_o}, \\ +p_o &= \mu_o \frac{x_o}{u_o}. +\end{align} + +:::{note} +In PyLith v4 and earlier, we used a displacement scale equal to the length scale. +Using separate length and displacement scales facilitates accurately solving for displacements many orders of magnitude smaller than the length scale. +It also separates the stress scale used to nondimensionalize stress, tractions, and pressure from the rigidity scale. +::: + +```{table} Nondimensionalization of incompressible elasticity. +:name: tab:incompressible:elasticity:scales +| **Quantity** | **Scale** | +| :---------: | :------------------ | +| $x_o$ | Length scale | +| $u_o$ | Displacement scale | +| $\mu_o$ | Rigidity scale | +| $t_o$ | Time scale | +| $\sigma_o = p_o = \mu_o \frac{u_o}{x_o}$ | Stress scale | +| $f_o = \frac{\sigma_o}{x_o}$ | Body force scale | +| $\rho_o = \mu_o \frac{t_o^2}{x_o^2}$ | Density scale | +``` diff --git a/docs/user/governingeqns/poroelasticity/index.md b/docs/user/governingeqns/poroelasticity/index.md index e3ed8b0f0e..f038c37dce 100644 --- a/docs/user/governingeqns/poroelasticity/index.md +++ b/docs/user/governingeqns/poroelasticity/index.md @@ -3,6 +3,7 @@ :::{toctree} infinitesimal-strain.md +nondimensionalization.md prescribed-slip.md bulk-rheologies/index.md ::: diff --git a/docs/user/governingeqns/poroelasticity/nondimensionalization.md b/docs/user/governingeqns/poroelasticity/nondimensionalization.md new file mode 100644 index 0000000000..d0deaf3cb0 --- /dev/null +++ b/docs/user/governingeqns/poroelasticity/nondimensionalization.md @@ -0,0 +1,144 @@ +# Nondimensionalization + +Starting with the equations governing poroelasticity, +% +\begin{gather} +% Elasticity + \rho_s\frac{\partial^2 \vec{u}}{\partial t^2} - \vec{f}(t) - \nabla \cdot \boldsymbol{\sigma}(\vec{u},p) = \vec{0} \text{ in } \Omega, \\ +% Fluid mass balance + \frac{\partial \zeta(\vec{u},p)}{\partial t} + \nabla \cdot \vec{q}(p) - \gamma(\vec{x},t) = 0 \text{ in } \Omega, \\ +% Darcy flow + \vec{q}(p) = -\frac{\boldsymbol{k}}{\mu_{f}}(\nabla p - \vec{f}_f), +\end{gather} +% +we define nondimensional values: +% +\begin{align} +\vec{x}^* &= \frac{\vec{x}}{x_o}, \\ +\vec{u}^* &= \frac{\vec{u}}{u_o}, \\ +p^* &= \frac{p}{p_o}, \\ +\rho_s^* &= \frac{\rho_s}{\rho_o}, \\ +\rho_f^* &= \frac{\rho_f}{\rho_o}, \\ +\vec{f}^* &= \frac{\vec{f}}{f_o}, \\ +\zeta^* &= \frac{\zeta}{\zeta_o}, \\ +\vec{q}* &= \frac{\vec{q}}{q_o}, \\ +\gamma* &= \frac{\gamma}{\gamma_o}, \\ +\boldsymbol{\sigma}^* &= \frac{\boldsymbol{\sigma}}{\sigma_o}, \\ +\vec{\tau}^* &= \frac{\vec{\tau}}{\sigma_o}. +\end{align} +% +We also recognize that +% +\begin{equation} +\boldsymbol{\nabla}^* = x_o \boldsymbol{\nabla}. +\end{equation} + +Substituting into the equations, we have +% +\begin{gather} +% Elasticity +\rho_o \rho^*(\vec{x}^*) \frac{u_o}{t_o^2} \frac{\partial^{2}\vec{u}^*}{\partial {t^*}^{2}} - f_o \vec{f}^*(\vec{x}^*,t^*) - \frac{\sigma_o}{x_o} \boldsymbol{\nabla}^*\cdot\boldsymbol{\sigma}^* = \vec{0}\text{ in }\Omega,\\ +% Fluid mass balance +\frac{\zeta_o}{t_o} \frac{\partial \zeta^*(\vec{u},p)}{\partial t^*} + \frac{q_o}{x_o} \left( \nabla^* \cdot \vec{q^*}(p)\right) - \gamma_o \gamma^*(\vec{x},t) = 0 \text{ in } \Omega, \\ +% Darcy flow +q_o \vec{q^*}(p) = -\frac{\boldsymbol{k}}{\mu_{f}}(\frac{p_o}{x_o} \nabla^* p^* - f_o \vec{f^*}_f). +\end{gather} + +Grouping terms we have +% +\begin{gather} +% Elasticity +\left( \rho_o \frac{u_o}{t_o^2}\frac{x_o}{\sigma_o}\right) \rho^*(\vec{x}^*) \frac{\partial^{2}\vec{u}^*}{\partial {t^*}^{2}} - \left(f_o \frac{x_o}{\sigma_o}\right) \vec{f}^*(\vec{x}^*,t^*) - \boldsymbol{\nabla}^*\cdot\boldsymbol{\sigma}^* = \vec{0}\text{ in }\Omega, \\ +% Fluid mass balance +\left(\frac{\zeta_o}{t_o}\right) \frac{\partial \zeta^*(\vec{u},p)}{\partial t^*} + \left(\frac{q_o}{x_o}\right) \left( \nabla^* \cdot \vec{q^*}(p)\right) - \gamma_o \gamma^*(\vec{x},t) = 0 \text{ in } \Omega, \\ +% Darcy flow +q_o \vec{q^*}(p) = -\left(\frac{p_o}{x_o} \frac{\boldsymbol{k}}{\mu_{f}}\right) ( \nabla^* p^* - f_o \frac{x_o}{p_o} \vec{f^*}_f). +\end{gather} + +We also have +\begin{equation} + \zeta(\vec{u},p) = \alpha (\nabla \cdot \vec{u}) + \frac{p}{M}, +\end{equation} +% +and substituting in the nondimensionalized values leads to +% +\begin{equation} + \zeta_o \zeta^*(\vec{u},p) = \alpha \frac{u_o}{x_o} (\nabla^* \cdot \vec{u}^*) + \frac{p_o}{\mu_o} \frac{p^*}{M^*}, +\end{equation} +where $M^* = \frac{M}{\mu_o}$. +% +Grouping terms and recognizing that $p_o = \mu_o \frac{u_o}{x_o}$, we have +\begin{equation} + \zeta_o \zeta^*(\vec{u},p) = \left(\alpha \frac{u_o}{x_o}\right) (\nabla^* \cdot \vec{u}^*) + \frac{u_o}{x_o} \frac{p^*}{M^*}. +\end{equation} +All terms should be nondimensional, which implies +% +\begin{align} +\zeta_o &= \frac{u_o}{x_o}. +\end{align} + +Returning to the fluid mass balance, we have +% +\begin{equation} +\left(\frac{u_o}{t_o x_o}\right) \frac{\partial \zeta^*(\vec{u},p)}{\partial t^*} + \left(\frac{q_o}{x_o}\right) \left( \nabla^* \cdot \vec{q^*}(p)\right) - \gamma_o \gamma^*(\vec{x},t) = 0 \text{ in } \Omega, \\ +\end{equation} +% +All terms should be nondimensional, which implies +% +\begin{align} +q_o &= \frac{u_o}{t_o}, \\ +\gamma_o &= \frac{1}{t_o} \frac{u_o}{x_o}. +\end{align} + +Regrouping terms leads to +% +\begin{equation} +\left(\frac{u_o}{t_o x_o}\right) \frac{\partial \zeta^*(\vec{u},p)}{\partial t^*} + \left( \nabla^* \cdot \vec{q^*}(p)\right) - \gamma^*(\vec{x},t) = 0 \text{ in } \Omega. +\end{equation} + +Returning to the equation for Darcy flow, we have +% +\begin{equation} +\frac{u_o}{t_o} \vec{q^*}(p) = -\left(\frac{\sigma_o}{x_o} \frac{\boldsymbol{k}}{\mu_{f}}\right) ( \nabla^* p^* - \vec{f^*}_f), +\end{equation} +where we have made use of $q_o = \frac{u_o}{t_o}$, $\sigma_o = p_o$ and $f_o = \frac{\sigma_o}{x_p}$. +Rearranging we have, +\begin{align} +\vec{q^*}(p) &= -\left(\frac{\sigma_o t_o}{u_o x_o} \frac{\boldsymbol{k}}{\mu_{f}}\right) ( \nabla^* p^* - \vec{f^*}_f), \\ +\vec{q^*}(p) &= -\left(\frac{\mu_o t_o}{x_o^2} \frac{\boldsymbol{k}}{\mu_{f}}\right) ( \nabla^* p^* - \vec{f^*}_f). +\end{align} +% +This implies +% +\begin{align} +\boldsymbol{k^*} = \frac{\boldsymbol{k}}{x_o^2}, \\ +\mu_f^* = \frac{\mu_f}{\mu_o t_o}. +\end{align} +% +We also find that the time scale is given by +\begin{equation} +t_o = \frac{\mu_{f_o}}{\boldsymbol{k}_o} \frac{x_o^2}{\mu_o}. +\end{equation} + +:::{note} +In PyLith v4 and earlier, we used a displacement scale equal to the length scale. +Using separate length and displacement scales facilitates accurately solving for displacements many orders of magnitude smaller than the length scale. +It also separates the stress scale used to nondimensionalize stress, tractions, and fluid pressure from the rigidity scale. +::: + +```{table} Nondimensionalization of poroelasticity/ +:name: tab:poroelasticity:scales +| **Quantity** | **Scale** | +| :-----------------------------------------------------------: | :----------------- | +| $x_o$ | Length scale | +| $u_o$ | Displacement scale | +| $\mu_o$ | Rigidity scale | +| $t_o= \frac{\mu_{f_o}}{\boldsymbol{k}_o} \frac{x_o^2}{\mu_o}$ | Time scale | +| $\sigma_o = p_o = \mu_o \frac{u_o}{x_o}$ | Stress scale | +| $f_o = \frac{\sigma_o}{x_o}$ | Body force scale | +| $\rho_o = \mu_o \frac{t_o^2}{x_o^2}$ | Density scale | +| $q_o = \frac{u_o}{t_o} $ | Flow scale | +| $\gamma_o = \frac{1}{t_o} \frac{u_o}{x_o}$ | Source scale | +| $\mu_f^* = \frac{\mu_f}{\mu_o t_o}$ | Viscosity scale | +| $\boldsymbol{k}_o = \frac{\boldsymbol{k}}{x_o^2}$ | Permeability scale | +``` diff --git a/docs/user/problems/index.md b/docs/user/problems/index.md index 09ac17ca12..daf85cc6e8 100644 --- a/docs/user/problems/index.md +++ b/docs/user/problems/index.md @@ -3,5 +3,6 @@ :::{toctree} problems.md +nondimensionalization.md output.md ::: diff --git a/docs/user/problems/nondimensionalization.md b/docs/user/problems/nondimensionalization.md new file mode 100644 index 0000000000..568cd78f28 --- /dev/null +++ b/docs/user/problems/nondimensionalization.md @@ -0,0 +1,127 @@ +# Nondimensionalization + +Nondimensionalization permits solving a system equations across a vast range of scales. +We are primarily interested in elasticity-related boundary value problems, so we define displacement, length, rigidity, time, and temperature scales. + +:::{seealso} +In the governing equations section, we discuss the nondimensionalization of each governing equation. + +- [Elasticity](../governingeqns/elasticity/nondimensionalization.md) +- [Incompressible elasticity](../governingeqns/incompressible-elasticity/nondimensionalization.md) +- [Poroelasticity](../governingeqns/poroelasticity/nondimensionalization.md) +::: + +## Scales + +The Python `General` object is the generic interfaces to the underlying C++ `Scales` object that manages the scales used to nondimensionalize values. + +:::{tip} +The default nondimensionalization is reasonable for many problems; however, it may be necessary to change the default values in some cases. +::: + +## QuasistaticElasticity + +`QuasistaticElasticity` provides convenient scales for nondimensionalizing quasistatic elasticity and incompressible elsticity boundary values problems. +The scales are specified in terms of the displacement scale, length scale, shear modulus, and time scale. + +`displacement_scale` +: Nominal size of the displacment + +`length_scale` +: Nominal size of the geometry controlling the deformation (for example, fault dimension or size of the domain) + +`shear_modulus` +: Nominal shear modulus + +`time_scale` +: Time scale of deformation (for example, viscoelastic relaxation time) + +```{table} Nondimensional scales for quasistatic elasticity boundary value problems. +:name: tab:nondimensional:quasistatic:elasticity:scales +| Scale | Name | Default Value | +| :------: | :-------------: | :-----------: | +| length | displacement_scale | 1 m | +| length | length_scale | 100 km | +| pressure | shear_modulus | 10 GPa | +| time | time_scale | 100 years | +``` + +:::{admonition} Pyre User Interface +See [QuasistaticElasticity component](components/scales/QuasistaticElasticity.md). +::: + +## DynamicElasticity + +`DynamicElasticity` provides convenient scales for nondimensionalizing dynamic elasticity boundary values problems. +The scales are specified in terms of the displacement scale, length scale, shear modulus, and shear wave speed. +The time scale is computed based on the time it takes a shear wave ($v_s$)to propagate the length scale ($l_o$). + +```{math} +t_o = l_o / v_s +``` + +`displacement_scale` +: Nominal size of the displacment + +`length_scale` +: Nominal size of the geometry controlling the deformation (for example, fault dimension or size of the domain) + +`shear_modulus` +: Nominal shear modulus + +`shear_wave_speed` +: Nominal shear wave speed + +```{table} Nondimensional scales for dynamic elasticity boundary value problems. +:name: tab:nondimensional:dynamic:elasticity:scales +| Scale | Name | Default Value | +| :------: | :-------------: | :-----------: | +| length | displacement_scale | 1 m | +| length | length_scale | 100 km | +| pressure | shear_modulus | 10 GPa | +| -- | shear_wave_speed | 3 km/s | +``` + +:::{admonition} Pyre User Interface +See [DynamicElasticity component](components/scales/DynamicElasticity.md). +::: + +## QuasistaticPoroelasticity + +`QuasistaticPoroelasticity` provides convenient scales for nondimensionalizing quasistatic poroelasticity boundary values problems. +The scales are specified in terms of the displacement scale, length scale, shear modulus, viscosity, and permeability. +The time scale is computed based on the length scale ($l_o$), rigidity ($\mu_o$), viscosity ($\mu_{f_o}$), and permability ($k_o$). + +```{math} +t_o = \frac{\mu_{f_o}}{k_o} \frac{l_o^2}{\mu_o} +``` + +`displacement_scale` +: Nominal size of the displacment + +`length_scale` +: Nominal size of the geometry controlling the deformation (for example, fault dimension or size of the domain) + +`shear_modulus` +: Nominal shear modulus + +`viscosity` +: Nominal viscosity + +`permeability` +: Nominal permeability + +```{table} Nondimensional scales for quasistatic poroelasticity boundary value problems. +:name: tab:nondimensional:quasistatic:poroelasticity:scales +| Scale | Name | Default Value | +| :------: | :-------------: | :-----------: | +| length | displacement_scale | 1 m | +| length | length_scale | 100 km | +| pressure | shear_modulus | 10 GPa | +| -- | viscosity | 0.001 Pa-s | +| -- | permeability | 1.0e-13 m$^2$ | +``` + +:::{admonition} Pyre User Interface +See [QuasistaticPoroelasticity component](components/scales/QuasistaticPoroelasticity.md). +::: diff --git a/docs/user/run-pylith/overview.md b/docs/user/run-pylith/overview.md index 489b4fbfb8..1f01263c4d 100644 --- a/docs/user/run-pylith/overview.md +++ b/docs/user/run-pylith/overview.md @@ -235,7 +235,7 @@ Post-processing is generally done using the HDF5 files with Python or Matlab scr PyLith scales all parameters provided by the user so that the simulation solves the equations using nondimensional quantities. This permits application of PyLith to problems across a vast range of spatial and temporal scales. -The scales used to nondimensionalize the problem are length, pressure, density, and time. SpatialData provides two normalizer objects to make it easy to provide reasonable scales for quasi-static and dynamic elasticity boundary value problems. +The scales used to nondimensionalize the problem are length, pressure, density, and time. SpatialData provides two scales objects to make it easy to provide reasonable scales for quasi-static and dynamic elasticity boundary value problems. See for details. ## Finite-Element Implementation User Interface diff --git a/docs/user/run-pylith/utilities.md b/docs/user/run-pylith/utilities.md index 0c6aade12a..5490cfc014 100644 --- a/docs/user/run-pylith/utilities.md +++ b/docs/user/run-pylith/utilities.md @@ -155,9 +155,9 @@ facilities of 'problem': materials=: Materials in problem. current value: 'homogeneous', from {default} configurable as: homogeneous, materials - normalizer=: Nondimensionalizer for problem. + scales=: Nondimensionalizer for problem. current value: 'nondimelasticquasistatic', from {default} - configurable as: nondimelasticquasistatic, normalizer + configurable as: nondimelasticquasistatic, scales solution=: Solution field for problem. current value: 'solution', from {default} configurable as: solution diff --git a/examples/barwaves-2d/pylithapp.cfg b/examples/barwaves-2d/pylithapp.cfg index 1935de8c99..273a176403 100644 --- a/examples/barwaves-2d/pylithapp.cfg +++ b/examples/barwaves-2d/pylithapp.cfg @@ -14,7 +14,7 @@ features = [ pylith.materials.IsotropicLinearElasticity, spatialdata.spatialdb.UniformDB, pylith.meshio.DataWriterHDF5, - spatialdata.units.NondimElasticDynamic + pylith.scales.NondimElasticDynamic ] # ---------------------------------------------------------------------- @@ -53,10 +53,10 @@ solver = linear formulation = dynamic # Nondimensionalize problem using wave propagation parameters. -normalizer = spatialdata.units.NondimElasticDynamic -normalizer.mass_density = 2500.0*kg/m**3 -normalizer.shear_wave_speed = 1.0*km/s -normalizer.wave_period = 2.0*s +scales = pylith.scales.NondimElasticDynamic +scales.mass_density = 2500.0*kg/m**3 +scales.shear_wave_speed = 1.0*km/s +scales.wave_period = 2.0*s defaults.quadrature_order = 1 diff --git a/examples/box-2d/step05_sheardisptractrate.cfg b/examples/box-2d/step05_sheardisptractrate.cfg index 4bed723d71..47e7e0b124 100644 --- a/examples/box-2d/step05_sheardisptractrate.cfg +++ b/examples/box-2d/step05_sheardisptractrate.cfg @@ -72,10 +72,10 @@ start_time = -1.0*year end_time = 5.0*year initial_dt = 1.0*year -[pylithapp.problem.normalizer] +[pylithapp.problem.scales] # We specify a time scale using a fake relaxation time that corresponds # to the time scale of the simulation. -relaxation_time = 10.0*year +time_scale = 10.0*year # ---------------------------------------------------------------------- # boundary conditions diff --git a/examples/box-3d/step05_sheardisptractrate.cfg b/examples/box-3d/step05_sheardisptractrate.cfg index ef4e1f0c34..7153b2e2f4 100644 --- a/examples/box-3d/step05_sheardisptractrate.cfg +++ b/examples/box-3d/step05_sheardisptractrate.cfg @@ -73,8 +73,8 @@ initial_dt = 1.0*year start_time = -1.0*year end_time = 5.0*year -[pylithapp.problem.normalizer] -relaxation_time = 10.0*year +[pylithapp.problem.scales] +time_scale = 10.0*year # ---------------------------------------------------------------------- diff --git a/examples/magma-2d/pylithapp.cfg b/examples/magma-2d/pylithapp.cfg index 1d9e58f502..67fb36e9b9 100644 --- a/examples/magma-2d/pylithapp.cfg +++ b/examples/magma-2d/pylithapp.cfg @@ -59,10 +59,12 @@ trace_strain.basis_order = 1 [pylithapp.problem] # Scales for nondimensionalization -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 100.0*m -normalizer.relaxation_time = 0.02*year -normalizer.shear_modulus = 10.0*GPa +scales = pylith.scales.QuasistaticPoroelasticity +scales.length_scale = 5.0*km +scales.displacement_scale = 10.0*m +scales.shear_modulus = 22.5*GPa +scales.viscosity = 0.001*Pa*s +scales.permeability = 1e-13*m**2 # ---------------------------------------------------------------------- # materials @@ -87,7 +89,7 @@ label_value = 1 db_auxiliary_field = spatialdata.spatialdb.UniformDB db_auxiliary_field.description = Poroelastic properties for the crust db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 0.001*Pa*s, 0.01, 6.0*GPa, 10.0*GPa, 1.0, 2.0*GPa, 1e-15*m**2] +db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 0.001*Pa*s, 0.01, 22.5*GPa, 35.5*GPa, 0.8, 2.2*GPa, 1e-13*m**2] # Set basis order to 0 for uniform properties and a basis order of 1 for Cauchy stress and strain. auxiliary_subfields.body_force.basis_order = 0 diff --git a/examples/meshing-cubit/surface-nurbs/merge-surfs/pylithapp.cfg b/examples/meshing-cubit/surface-nurbs/merge-surfs/pylithapp.cfg index 2a82354b77..030b856798 100644 --- a/examples/meshing-cubit/surface-nurbs/merge-surfs/pylithapp.cfg +++ b/examples/meshing-cubit/surface-nurbs/merge-surfs/pylithapp.cfg @@ -122,49 +122,5 @@ observers.observer.data_fields = [displacement] auxiliary_subfields.initial_amplitude.basis_order = 0 auxiliary_subfields.initial_amplitude.quadrature_order = 1 -# ---------------------------------------------------------------------- -# PETSc -# ---------------------------------------------------------------------- -[pylithapp.petsc] -ts_type = beuler - -pc_type = fieldsplit -pc_use_amat = true -pc_fieldsplit_type = schur -pc_fieldsplit_schur_factorization_type = full -pc_fieldsplit_dm_splits = true -fieldsplit_displacement_ksp_type = preonly -fieldsplit_displacement_pc_type = lu -fieldsplit_lagrange_multiplier_fault_pc_type = jacobi -fieldsplit_lagrange_multiplier_fault_ksp_type = gmres -fieldsplit_lagrange_multiplier_fault_ksp_rtol = 1.0e-11 -fieldsplit_lagrange_multiplier_fault_ksp_converged_reason = true - -ksp_rtol = 1.0e-8 -ksp_atol = 1.0e-12 -ksp_max_it = 1000 -ksp_gmres_restart = 50 -# ksp_error_if_not_converged = true - -snes_rtol = 1.0e-10 -snes_atol = 1.0e-10 -snes_max_it = 4 -# snes_error_if_not_converged = true - -# Monitors for debugging -ts_monitor = true -ksp_monitor = true -ksp_converged_reason = true -snes_monitor = true -snes_converged_reason = true -snes_linesearch_monitor = true -#snes_fd = true -#dm_plex_print_fem = 2 -#dm_plex_print_l2 = 2 - -ts_error_if_step_fails = true - -#ksp_view = true -#snes_view = true # End of file diff --git a/examples/poroelastic-outerrise-2d/pylithapp.cfg b/examples/poroelastic-outerrise-2d/pylithapp.cfg index 66dcb34cd0..6b557c03dd 100644 --- a/examples/poroelastic-outerrise-2d/pylithapp.cfg +++ b/examples/poroelastic-outerrise-2d/pylithapp.cfg @@ -60,10 +60,10 @@ trace_strain_t.basis_order = 1 [pylithapp.problem] # Scales for nondimensionalization -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 100.0*m -normalizer.relaxation_time = 0.01*year -normalizer.shear_modulus = 10.0*GPa +scales = pylith.scales.ElasticityScales +scales.length_scale = 1.0*m +scales.time_scale = 0.01*year +scales.pressure_scale = 1.0*MPa # For time-dependent problems, we specify start and end times and an initial # time step. With an initial time step of 0.2 yr, we use a start time of diff --git a/examples/reverse-2d/step07_twofaults_maxwell.cfg b/examples/reverse-2d/step07_twofaults_maxwell.cfg index 2a87464868..8a9b0d6c4b 100644 --- a/examples/reverse-2d/step07_twofaults_maxwell.cfg +++ b/examples/reverse-2d/step07_twofaults_maxwell.cfg @@ -61,7 +61,7 @@ start_time = -4.0*year end_time = 100.0*year # Use a relaxation time of 20 years to nondimensionalize time. -normalizer.relaxation_time = 20.0*year +scales.time_scale = 20.0*year # ---------------------------------------------------------------------- # solution diff --git a/examples/reverse-2d/step08_twofaults_powerlaw.cfg b/examples/reverse-2d/step08_twofaults_powerlaw.cfg index 07daabf962..746ce44837 100644 --- a/examples/reverse-2d/step08_twofaults_powerlaw.cfg +++ b/examples/reverse-2d/step08_twofaults_powerlaw.cfg @@ -61,7 +61,7 @@ start_time = -4.0*year end_time = 100.0*year # Use a relaxation time of 20 years to nondimensionalize time. -normalizer.relaxation_time = 20.0*year +scales.time_scale = 20.0*year # ---------------------------------------------------------------------- # solution diff --git a/examples/subduction-3d/step08a_gravity_refstate.cfg b/examples/subduction-3d/step08a_gravity_refstate.cfg index f374675a0a..1a38527c3e 100644 --- a/examples/subduction-3d/step08a_gravity_refstate.cfg +++ b/examples/subduction-3d/step08a_gravity_refstate.cfg @@ -38,11 +38,6 @@ defaults.name = step08a_gravity_refstate # problem # ---------------------------------------------------------------------- [pylithapp.problem] -# Quasi-static problems do not have a well-defined density (inertia) -# scale. For this static simulation, we adjust the time scale and time -# step to give a density scale close to unity. -normalizer.relaxation_time = 1.0*s - # We use higher basis and quadrature orders for this problem since # gravitational stress varies linearly as a function of depth. # this means the displacement field will vary quadratically. diff --git a/examples/subduction-3d/step08b_gravity_incompressible.cfg b/examples/subduction-3d/step08b_gravity_incompressible.cfg index db962d0540..8331b59911 100644 --- a/examples/subduction-3d/step08b_gravity_incompressible.cfg +++ b/examples/subduction-3d/step08b_gravity_incompressible.cfg @@ -36,11 +36,6 @@ defaults.name = step08b_gravity_incompressible # problem # ---------------------------------------------------------------------- [pylithapp.problem] -# Quasi-static problems do not have a well-defined density (inertia) -# scale. For this static simulation, we adjust the time scale and time -# step to give a density scale close to unity. -normalizer.relaxation_time = 1.0*s - gravity_field = spatialdata.spatialdb.GravityField # We use the predefined container with displacement and pressure (mean diff --git a/libsrc/pylith/Makefile.am b/libsrc/pylith/Makefile.am index 8a9ef484b5..c575311c28 100644 --- a/libsrc/pylith/Makefile.am +++ b/libsrc/pylith/Makefile.am @@ -10,6 +10,7 @@ SUBDIRS = \ + scales \ utils \ topology \ feassemble \ @@ -138,6 +139,8 @@ libpylith_la_SOURCES = \ topology/ReverseCuthillMcKee.cc \ topology/RefineUniform.cc \ topology/RefineInterpolator.cc \ + scales/ElasticityScales.cc \ + scales/Scales.cc \ utils/EventLogger.cc \ utils/PyreComponent.cc \ utils/GenericComponent.cc \ @@ -145,6 +148,7 @@ libpylith_la_SOURCES = \ utils/PylithVersion.cc \ utils/PetscVersion.cc \ utils/DependenciesVersion.cc \ + utils/TSAdaptImpulse.cc \ utils/TestArray.cc diff --git a/libsrc/pylith/bc/AbsorbingDampers.cc b/libsrc/pylith/bc/AbsorbingDampers.cc index 7ed2f0640f..457002b46a 100644 --- a/libsrc/pylith/bc/AbsorbingDampers.cc +++ b/libsrc/pylith/bc/AbsorbingDampers.cc @@ -20,7 +20,7 @@ #include "pylith/topology/Mesh.hh" // USES Mesh #include "pylith/topology/Field.hh" // USES Field #include "pylith/topology/FieldOps.hh" // USES FieldOps -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_METHOD_* #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* @@ -154,8 +154,8 @@ pylith::bc::AbsorbingDampers::createAuxiliaryField(const pylith::topology::Field auxiliaryField->setLabel("auxiliary field"); assert(_auxiliaryFactory); - assert(_normalizer); - _auxiliaryFactory->initialize(auxiliaryField, *_normalizer, domainMesh.getDimension()); + assert(_scales); + _auxiliaryFactory->initialize(auxiliaryField, *_scales, domainMesh.getDimension()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the FE kernels. diff --git a/libsrc/pylith/bc/AbsorbingDampersAuxiliaryFactory.cc b/libsrc/pylith/bc/AbsorbingDampersAuxiliaryFactory.cc index d95dd4ef02..376af0c6b0 100644 --- a/libsrc/pylith/bc/AbsorbingDampersAuxiliaryFactory.cc +++ b/libsrc/pylith/bc/AbsorbingDampersAuxiliaryFactory.cc @@ -15,7 +15,8 @@ #include "pylith/topology/Field.hh" // HOLDSA AuxiliaryField #include "pylith/topology/FieldQuery.hh" // USES FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -42,7 +43,7 @@ pylith::bc::AbsorbingDampersAuxiliaryFactory::addDensity(void) { PYLITH_JOURNAL_DEBUG("addDensity(void)"); const char* subfieldName = "density"; - const PylithReal densityScale = _normalizer->getDensityScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -69,7 +70,7 @@ pylith::bc::AbsorbingDampersAuxiliaryFactory::addVs(void) { PYLITH_JOURNAL_DEBUG("addVs(void)"); const char* subfieldName = "vs"; - const PylithReal velocityScale = _normalizer->getLengthScale() / _normalizer->getTimeScale(); + const PylithReal velocityScale = _scales->getLengthScale() / _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -96,7 +97,7 @@ pylith::bc::AbsorbingDampersAuxiliaryFactory::addVp(void) { PYLITH_JOURNAL_DEBUG("addVp(void)"); const char* subfieldName = "vp"; - const PylithReal velocityScale = _normalizer->getLengthScale() / _normalizer->getTimeScale(); + const PylithReal velocityScale = _scales->getLengthScale() / _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; diff --git a/libsrc/pylith/bc/BoundaryCondition.cc b/libsrc/pylith/bc/BoundaryCondition.cc index e5139fae7d..cb43ffff15 100644 --- a/libsrc/pylith/bc/BoundaryCondition.cc +++ b/libsrc/pylith/bc/BoundaryCondition.cc @@ -161,7 +161,7 @@ pylith::bc::BoundaryCondition::createDiagnosticField(const pylith::topology::Fie PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("createDiagnosticField(solution="<setLabel("diagnostic field"); @@ -176,8 +176,8 @@ pylith::bc::BoundaryCondition::createDiagnosticField(const pylith::topology::Fie discretization.isBasisContinuous); assert(_diagnosticFactory); - assert(_normalizer); - _diagnosticFactory->initialize(diagnosticField, *_normalizer, solution.getSpaceDim()); + assert(_scales); + _diagnosticFactory->initialize(diagnosticField, *_scales, solution.getSpaceDim()); _diagnosticFactory->addNormalDir(); // 0 _diagnosticFactory->addTangentialDirHoriz(); // 1 diff --git a/libsrc/pylith/bc/DiagnosticFieldFactory.cc b/libsrc/pylith/bc/DiagnosticFieldFactory.cc index 99050e4ff9..ee5023fb76 100644 --- a/libsrc/pylith/bc/DiagnosticFieldFactory.cc +++ b/libsrc/pylith/bc/DiagnosticFieldFactory.cc @@ -14,7 +14,7 @@ #include "pylith/topology/Field.hh" // USES Field -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* diff --git a/libsrc/pylith/bc/DirichletTimeDependent.cc b/libsrc/pylith/bc/DirichletTimeDependent.cc index a60cbf2aa4..b09515a038 100644 --- a/libsrc/pylith/bc/DirichletTimeDependent.cc +++ b/libsrc/pylith/bc/DirichletTimeDependent.cc @@ -21,7 +21,7 @@ #include "pylith/fekernels/TimeDependentFn.hh" // USES TimeDependentFn kernels #include "spatialdata/spatialdb/TimeHistory.hh" // USES TimeHistory -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN/END #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* @@ -265,8 +265,8 @@ pylith::bc::DirichletTimeDependent::createAuxiliaryField(const pylith::topology: auxiliaryField->setLabel("auxiliary field"); assert(_auxiliaryFactory); - assert(_normalizer); - _auxiliaryFactory->initialize(auxiliaryField, *_normalizer, solution.getSpaceDim(), + assert(_scales); + _auxiliaryFactory->initialize(auxiliaryField, *_scales, solution.getSpaceDim(), &solution.getSubfieldInfo(_subfieldName.c_str()).description); // :ATTENTION: The order of the factory methods must match the order of the auxiliary subfields in the FE kernels. @@ -309,8 +309,8 @@ pylith::bc::DirichletTimeDependent::updateAuxiliaryField(pylith::topology::Field PYLITH_COMPONENT_DEBUG("updateAuxiliaryField(auxiliaryField="<getTimeScale(); + assert(_scales); + const PylithScalar timeScale = _scales->getTimeScale(); TimeDependentAuxiliaryFactory::updateAuxiliaryField(auxiliaryField, t, timeScale, _dbTimeHistory); } // if diff --git a/libsrc/pylith/bc/DirichletUserFn.cc b/libsrc/pylith/bc/DirichletUserFn.cc index 7ef83cc142..c828aacf65 100644 --- a/libsrc/pylith/bc/DirichletUserFn.cc +++ b/libsrc/pylith/bc/DirichletUserFn.cc @@ -17,7 +17,7 @@ #include "pylith/topology/FieldOps.hh" // USES FieldOps #include "pylith/topology/Mesh.hh" // USES Mesh -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN/END #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* diff --git a/libsrc/pylith/bc/NeumannTimeDependent.cc b/libsrc/pylith/bc/NeumannTimeDependent.cc index 956cfb2ee4..0bdc186fcf 100644 --- a/libsrc/pylith/bc/NeumannTimeDependent.cc +++ b/libsrc/pylith/bc/NeumannTimeDependent.cc @@ -22,7 +22,8 @@ #include "pylith/topology/Mesh.hh" // USES Mesh #include "spatialdata/spatialdb/TimeHistory.hh" // USES TimeHistory -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN/END #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* @@ -176,11 +177,8 @@ void pylith::bc::NeumannTimeDependent::setScaleName(const char* value) { PYLITH_COMPONENT_DEBUG("setScaleName(value"<setLabel("auxiliary field"); + assert(_scales); + const PylithReal displacementScale = _scales->getLengthScale(); + const PylithReal stressScale = pylith::scales::ElasticityScales::getStressScale(*_scales); + assert(_auxiliaryFactory); - assert(_normalizer); pylith::topology::Field::Description description = solution.getSubfieldInfo(_subfieldName.c_str()).description; - if (_scaleName == std::string("pressure")) { - description.scale = _normalizer->getPressureScale(); - } else if (_scaleName == std::string("velocity")) { - description.scale = sqrt(_normalizer->getPressureScale() / _normalizer->getDensityScale()); - } else if (_scaleName == std::string("length")) { - description.scale = _normalizer->getLengthScale(); - } else if (_scaleName == std::string("time")) { - description.scale = sqrt(_normalizer->getDensityScale() / _normalizer->getPressureScale()) * _normalizer->getLengthScale(); - } else if (_scaleName == std::string("density")) { - description.scale = _normalizer->getDensityScale(); + if (_scaleName == std::string("stress")) { + description.scale = stressScale; + } else if (_scaleName == std::string("displacement")) { + description.scale = displacementScale; } else { std::ostringstream msg; msg << "Unknown name of scale ("<<_scaleName<<") for Neumann boundary condition for '" << getLabelName() << "'."; PYLITH_COMPONENT_ERROR(msg.str()); throw std::logic_error(msg.str()); } // if/else - _auxiliaryFactory->initialize(auxiliaryField, *_normalizer, solution.getSpaceDim(), &description); + _auxiliaryFactory->initialize(auxiliaryField, *_scales, solution.getSpaceDim(), &description); // :ATTENTION: The order of the factory methods must match the order of the auxiliary subfields in the FE kernels. @@ -300,8 +295,8 @@ pylith::bc::NeumannTimeDependent::updateAuxiliaryField(pylith::topology::Field* PYLITH_COMPONENT_DEBUG("updateAuxiliaryField(auxiliaryField="<getTimeScale(); + assert(_scales); + const PylithScalar timeScale = _scales->getTimeScale(); TimeDependentAuxiliaryFactory::updateAuxiliaryField(auxiliaryField, t, timeScale, _dbTimeHistory); } // if diff --git a/libsrc/pylith/bc/NeumannUserFn.cc b/libsrc/pylith/bc/NeumannUserFn.cc index fd1ec4705a..c389634520 100644 --- a/libsrc/pylith/bc/NeumannUserFn.cc +++ b/libsrc/pylith/bc/NeumannUserFn.cc @@ -19,7 +19,7 @@ #include "pylith/topology/FieldOps.hh" // USES FieldOps #include "pylith/topology/Mesh.hh" // USES Mesh -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN/END #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* diff --git a/libsrc/pylith/bc/TimeDependentAuxiliaryFactory.cc b/libsrc/pylith/bc/TimeDependentAuxiliaryFactory.cc index 08ae777998..5e27a10922 100644 --- a/libsrc/pylith/bc/TimeDependentAuxiliaryFactory.cc +++ b/libsrc/pylith/bc/TimeDependentAuxiliaryFactory.cc @@ -17,7 +17,7 @@ #include "pylith/topology/VisitorMesh.hh" // USES VecVisitorMesh #include "spatialdata/spatialdb/TimeHistory.hh" // USES TimeHistory -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -144,11 +144,11 @@ pylith::bc::TimeDependentAuxiliaryFactory::addRateAmplitude(void) { const char* subfieldName = "rate_amplitude"; assert(_defaultDescription); - assert(_normalizer); + assert(_scales); pylith::topology::FieldBase::Description subfieldDescription(*_defaultDescription); subfieldDescription.label = subfieldName; subfieldDescription.alias = subfieldName; - subfieldDescription.scale = _defaultDescription->scale / _normalizer->getTimeScale(); + subfieldDescription.scale = _defaultDescription->scale / _scales->getTimeScale(); subfieldDescription.validator = NULL; switch (subfieldDescription.vectorFieldType) { case pylith::topology::FieldBase::SCALAR: { @@ -184,7 +184,7 @@ pylith::bc::TimeDependentAuxiliaryFactory::addRateStartTime(void) { const char* subfieldName = "rate_start_time"; assert(_defaultDescription); - assert(_normalizer); + assert(_scales); pylith::topology::FieldBase::Description subfieldDescription(*_defaultDescription); subfieldDescription.label = subfieldName; subfieldDescription.alias = subfieldName; @@ -192,7 +192,7 @@ pylith::bc::TimeDependentAuxiliaryFactory::addRateStartTime(void) { subfieldDescription.numComponents = 1; subfieldDescription.componentNames.resize(1); subfieldDescription.componentNames[0] = subfieldName; - subfieldDescription.scale = _normalizer->getTimeScale(); + subfieldDescription.scale = _scales->getTimeScale(); subfieldDescription.validator = NULL; _field->subfieldAdd(subfieldDescription, getSubfieldDiscretization(subfieldName)); @@ -250,7 +250,7 @@ pylith::bc::TimeDependentAuxiliaryFactory::addTimeHistoryStartTime(void) { const char* subfieldName = "time_history_start_time"; assert(_defaultDescription); - assert(_normalizer); + assert(_scales); pylith::topology::FieldBase::Description subfieldDescription(*_defaultDescription); subfieldDescription.label = subfieldName; subfieldDescription.alias = subfieldName; @@ -258,7 +258,7 @@ pylith::bc::TimeDependentAuxiliaryFactory::addTimeHistoryStartTime(void) { subfieldDescription.numComponents = 1; subfieldDescription.componentNames.resize(1); subfieldDescription.componentNames[0] = subfieldName; - subfieldDescription.scale = _normalizer->getTimeScale(); + subfieldDescription.scale = _scales->getTimeScale(); subfieldDescription.validator = NULL; _field->subfieldAdd(subfieldDescription, getSubfieldDiscretization(subfieldName)); @@ -278,7 +278,7 @@ pylith::bc::TimeDependentAuxiliaryFactory::addTimeHistoryValue(void) { const char* subfieldName = "time_history_value"; assert(_defaultDescription); - assert(_normalizer); + assert(_scales); pylith::topology::FieldBase::Description subfieldDescription(*_defaultDescription); subfieldDescription.label = subfieldName; subfieldDescription.alias = subfieldName; diff --git a/libsrc/pylith/faults/AuxiliaryFieldFactory.cc b/libsrc/pylith/faults/AuxiliaryFieldFactory.cc index 3cd3f39fdd..79b3b33bb2 100644 --- a/libsrc/pylith/faults/AuxiliaryFieldFactory.cc +++ b/libsrc/pylith/faults/AuxiliaryFieldFactory.cc @@ -15,7 +15,8 @@ #include "pylith/topology/Field.hh" // USES Field #include "pylith/topology/FieldQuery.hh" // HOLDSA FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -45,7 +46,7 @@ pylith::faults::AuxiliaryFieldFactory::addSlip(void) { const char* fieldName = "slip"; const char* componentNames[3] = { "slip_opening", "slip_left_lateral", "slip_reverse" }; - const PylithReal lengthScale = _normalizer->getLengthScale(); + const PylithReal displacementScale = _scales->getDisplacementScale(); pylith::topology::Field::Description description; description.label = fieldName; @@ -56,7 +57,7 @@ pylith::faults::AuxiliaryFieldFactory::addSlip(void) { for (int i = 0; i < _spaceDim; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = lengthScale; + description.scale = displacementScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(fieldName)); @@ -76,7 +77,7 @@ pylith::faults::AuxiliaryFieldFactory::addSlipRate(void) { const char* fieldName = "slip_rate"; const char* componentNames[3] = { "slip_rate_opening", "slip_rate_left_lateral", "slip_rate_reverse" }; - const PylithReal velocityScale = _normalizer->getLengthScale() / _normalizer->getTimeScale(); + const PylithReal velocityScale = pylith::scales::ElasticityScales::getVelocityScale(*_scales); pylith::topology::Field::Description description; description.label = fieldName; @@ -110,8 +111,7 @@ pylith::faults::AuxiliaryFieldFactory::addSlipAcceleration(void) { "slip_acceleration_left_lateral", "slip_acceleration_reverse", }; - - const PylithReal accelerationScale = _normalizer->getLengthScale() / pow(_normalizer->getTimeScale(), 2); + const PylithReal accelerationScale = pylith::scales::ElasticityScales::getAccelerationScale(*_scales); pylith::topology::Field::Description description; description.label = fieldName; diff --git a/libsrc/pylith/faults/DerivedFieldFactory.cc b/libsrc/pylith/faults/DerivedFieldFactory.cc index d06944fc1c..f40c9ef7c9 100644 --- a/libsrc/pylith/faults/DerivedFieldFactory.cc +++ b/libsrc/pylith/faults/DerivedFieldFactory.cc @@ -14,7 +14,8 @@ #include "pylith/topology/Field.hh" // USES Field -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -42,7 +43,7 @@ pylith::faults::DerivedFieldFactory::addTractionChange(void) { const char* fieldName = "traction_change"; const char* componentNames[3] = { "traction_change_opening", "traction_change_left_lateral", "traction_change_reverse" }; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal stressScale = pylith::scales::ElasticityScales::getStressScale(*_scales); pylith::topology::Field::Description description; description.label = fieldName; @@ -53,7 +54,7 @@ pylith::faults::DerivedFieldFactory::addTractionChange(void) { for (int i = 0; i < _spaceDim; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = pressureScale; + description.scale = stressScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(fieldName)); diff --git a/libsrc/pylith/faults/DiagnosticFieldFactory.cc b/libsrc/pylith/faults/DiagnosticFieldFactory.cc index 3fbd3bbc62..4e215e761d 100644 --- a/libsrc/pylith/faults/DiagnosticFieldFactory.cc +++ b/libsrc/pylith/faults/DiagnosticFieldFactory.cc @@ -14,7 +14,7 @@ #include "pylith/topology/Field.hh" // USES Field -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* diff --git a/libsrc/pylith/faults/FaultCohesive.cc b/libsrc/pylith/faults/FaultCohesive.cc index 9587aee14d..15451d04fa 100644 --- a/libsrc/pylith/faults/FaultCohesive.cc +++ b/libsrc/pylith/faults/FaultCohesive.cc @@ -299,7 +299,7 @@ pylith::faults::FaultCohesive::createDiagnosticField(const pylith::topology::Fie PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("createDiagnosticField(solution="<setLabel("diagnostic field"); @@ -314,8 +314,8 @@ pylith::faults::FaultCohesive::createDiagnosticField(const pylith::topology::Fie discretization.isBasisContinuous); assert(_diagnosticFactory); - assert(_normalizer); - _diagnosticFactory->initialize(diagnosticField, *_normalizer, solution.getSpaceDim()); + assert(_scales); + _diagnosticFactory->initialize(diagnosticField, *_scales, solution.getSpaceDim()); _diagnosticFactory->addNormalDir(); // 0 _diagnosticFactory->addStrikeDir(); // 1 @@ -341,7 +341,7 @@ pylith::faults::FaultCohesive::createDerivedField(const pylith::topology::Field& PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("createDerivedField(solution="<setLabel("derived field"); @@ -368,8 +368,8 @@ pylith::faults::FaultCohesive::createDerivedField(const pylith::topology::Field& discretization.isBasisContinuous); assert(_derivedFactory); - assert(_normalizer); - _derivedFactory->initialize(derivedField, *_normalizer, solution.getSpaceDim()); + assert(_scales); + _derivedFactory->initialize(derivedField, *_scales, solution.getSpaceDim()); _derivedFactory->addTractionChange(); // 0 diff --git a/libsrc/pylith/faults/FaultCohesiveImpulses.cc b/libsrc/pylith/faults/FaultCohesiveImpulses.cc index 6eba81743a..5ebe1817be 100644 --- a/libsrc/pylith/faults/FaultCohesiveImpulses.cc +++ b/libsrc/pylith/faults/FaultCohesiveImpulses.cc @@ -28,7 +28,7 @@ #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensionalizer +#include "pylith/scales/Scales.hh" // USES Nondimensionalizer #include "spatialdata/spatialdb/SpatialDB.hh" // USES SpatialDB #include // USES pow(), sqrt() @@ -123,8 +123,8 @@ pylith::faults::FaultCohesiveImpulses::setThreshold(const double value) { msg << "Threshold ("<< value << ") for impulse amplitude must be nonnegative."; throw std::out_of_range(msg.str()); } // if - assert(_normalizer); - _threshold = value / _normalizer->getLengthScale(); + assert(_scales); + _threshold = value / _scales->getDisplacementScale(); } // setThreshold @@ -166,7 +166,7 @@ pylith::faults::FaultCohesiveImpulses::createAuxiliaryField(const pylith::topolo PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("createAuxiliaryField(solution="<setLabel("auxiliary field"); @@ -180,8 +180,8 @@ pylith::faults::FaultCohesiveImpulses::createAuxiliaryField(const pylith::topolo isFaultOnly, discretization.cellBasis, discretization.feSpace, discretization.isBasisContinuous); - assert(_normalizer); - _auxiliaryFactory->initialize(auxiliaryField, *_normalizer, solution.getSpaceDim()); + assert(_scales); + _auxiliaryFactory->initialize(auxiliaryField, *_scales, solution.getSpaceDim()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the FE kernels. @@ -228,7 +228,7 @@ pylith::faults::FaultCohesiveImpulses::updateAuxiliaryField(pylith::topology::Fi PYLITH_COMPONENT_DEBUG("updateAuxiliaryField(auxiliaryField="<getLengthScale(); + auxiliaryArray[slipOff+dof] = 1.0 / _scales->getDisplacementScale(); } // if pythia::journal::debug_t debug(pylith::utils::PyreComponent::getName()); diff --git a/libsrc/pylith/faults/FaultCohesiveKin.cc b/libsrc/pylith/faults/FaultCohesiveKin.cc index 55bba4376d..ca212f89ec 100644 --- a/libsrc/pylith/faults/FaultCohesiveKin.cc +++ b/libsrc/pylith/faults/FaultCohesiveKin.cc @@ -32,7 +32,7 @@ #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensionalizer +#include "pylith/scales/Scales.hh" // USES Nondimensionalizer #include "spatialdata/spatialdb/SpatialDB.hh" // USES SpatialDB #include // USES pow(), sqrt() @@ -166,7 +166,7 @@ pylith::faults::FaultCohesiveKin::createAuxiliaryField(const pylith::topology::F PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("createAuxiliaryField(solution="<setLabel("auxiliary field"); @@ -181,8 +181,8 @@ pylith::faults::FaultCohesiveKin::createAuxiliaryField(const pylith::topology::F discretization.isBasisContinuous); assert(_auxiliaryFactory); - assert(_normalizer); - _auxiliaryFactory->initialize(auxiliaryField, *_normalizer, solution.getSpaceDim()); + assert(_scales); + _auxiliaryFactory->initialize(auxiliaryField, *_scales, solution.getSpaceDim()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the FE kernels. @@ -216,7 +216,7 @@ pylith::faults::FaultCohesiveKin::createAuxiliaryField(const pylith::topology::F for (srcs_type::iterator r_iter = _ruptures.begin(); r_iter != rupturesEnd; ++r_iter) { KinSrc* src = r_iter->second; assert(src); - src->initialize(*auxiliaryField, *_normalizer, solution.getMesh().getCoordSys()); + src->initialize(*auxiliaryField, *_scales, solution.getMesh().getCoordSys()); } // for // Create local PETSc vector to hold current slip. @@ -237,7 +237,7 @@ pylith::faults::FaultCohesiveKin::updateAuxiliaryField(pylith::topology::Field* PYLITH_COMPONENT_DEBUG("updateAuxiliaryField(auxiliaryField="<second;assert(src); - src->getSlipSubfields(_slipVecRupture, auxiliaryField, t, _normalizer->getTimeScale(), bitSlipSubfields); + src->getSlipSubfields(_slipVecRupture, auxiliaryField, t, _scales->getTimeScale(), bitSlipSubfields); err = VecAYPX(_slipVecTotal, 1.0, _slipVecRupture); } // for diff --git a/libsrc/pylith/faults/KinSrc.cc b/libsrc/pylith/faults/KinSrc.cc index e16698e983..f9c26d9293 100644 --- a/libsrc/pylith/faults/KinSrc.cc +++ b/libsrc/pylith/faults/KinSrc.cc @@ -19,7 +19,7 @@ #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES typeid() #include // USES assert() @@ -101,10 +101,10 @@ pylith::faults::KinSrc::auxFieldDB(spatialdata::spatialdb::SpatialDB* value) { // Initialize kinematic (prescribed slip) earthquake source. void pylith::faults::KinSrc::initialize(const pylith::topology::Field& faultAuxField, - const spatialdata::units::Nondimensional& normalizer, + const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) { PYLITH_METHOD_BEGIN; - PYLITH_COMPONENT_DEBUG("initialize(faultAuxField"<setLabel("auxiliary field"); - _auxiliaryFieldSetup(normalizer, cs); + _auxiliaryFieldSetup(scales, cs); _auxiliaryField->subfieldsSetup(); _auxiliaryField->createDiscretization(); pylith::topology::FieldOps::checkDiscretization(faultAuxField, *_auxiliaryField); diff --git a/libsrc/pylith/faults/KinSrc.hh b/libsrc/pylith/faults/KinSrc.hh index aa4157598c..a9ef978a43 100644 --- a/libsrc/pylith/faults/KinSrc.hh +++ b/libsrc/pylith/faults/KinSrc.hh @@ -19,7 +19,7 @@ #include "spatialdata/geocoords/geocoordsfwd.hh" // USES CoordSys #include "spatialdata/spatialdb/spatialdbfwd.hh" // USES SpatialDB -#include "spatialdata/units/unitsfwd.hh" // USES Nondimensional +#include "pylith/scales/scalesfwd.hh" // USES Scales // KinSrc ------------------------------------------------------------- /** @brief Kinematic earthquake source. @@ -80,11 +80,11 @@ public: /** Initialize kinematic (prescribed slip) earthquake source. * * @param[in] auxField Auxiliary field associated with fault finite-element integration. - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ void initialize(const pylith::topology::Field& auxField, - const spatialdata::units::Nondimensional& normalizer, + const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); /** Get requested slip subfields at time t. @@ -115,11 +115,11 @@ protected: * @attention The order of the calls to subfieldAdd() must match the * order of the auxiliary fields in the FE kernels. * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ virtual - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) = 0; /** Set constants used in finite-element integrations. diff --git a/libsrc/pylith/faults/KinSrcAuxiliaryFactory.cc b/libsrc/pylith/faults/KinSrcAuxiliaryFactory.cc index 2a869061af..c3727103fc 100644 --- a/libsrc/pylith/faults/KinSrcAuxiliaryFactory.cc +++ b/libsrc/pylith/faults/KinSrcAuxiliaryFactory.cc @@ -17,7 +17,7 @@ #include "pylith/topology/VisitorMesh.hh" // USES VecVisitorMesh #include "spatialdata/spatialdb/TimeHistory.hh" // USES TimeHistory -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -43,7 +43,7 @@ pylith::faults::KinSrcAuxiliaryFactory::addInitiationTime(void) { PYLITH_JOURNAL_DEBUG("addInitiationTime(void)"); const char* subfieldName = "initiation_time"; - const PylithReal timeScale = _normalizer->getTimeScale(); + const PylithReal timeScale = _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -70,7 +70,7 @@ pylith::faults::KinSrcAuxiliaryFactory::addRiseTime(void) { PYLITH_JOURNAL_DEBUG("addRiseTime(void)"); const char* subfieldName = "rise_time"; - const PylithReal timeScale = _normalizer->getTimeScale(); + const PylithReal timeScale = _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -97,7 +97,7 @@ pylith::faults::KinSrcAuxiliaryFactory::addImpulseDuration(void) { PYLITH_JOURNAL_DEBUG("addImpulseDuration(void)"); const char* subfieldName = "impulse_duration"; - const PylithReal timeScale = _normalizer->getTimeScale(); + const PylithReal timeScale = _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -126,7 +126,7 @@ pylith::faults::KinSrcAuxiliaryFactory::addFinalSlip(void) { const char* subfieldName = "final_slip"; const char* componentNames[3] = { "final_slip_opening", "final_slip_left_lateral", "final_slip_reverse" }; - const PylithReal lengthScale = _normalizer->getLengthScale(); + const PylithReal displacementScale = _scales->getDisplacementScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -137,7 +137,7 @@ pylith::faults::KinSrcAuxiliaryFactory::addFinalSlip(void) { for (int i = 0; i < _spaceDim; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = lengthScale; + description.scale = displacementScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -157,8 +157,8 @@ pylith::faults::KinSrcAuxiliaryFactory::addSlipRate(void) { const char* subfieldName = "slip_rate"; const char* componentNames[3] = { "slip_rate_opening", "slip_rate_left_lateral", "slip_rate_reverse" }; - const PylithReal lengthScale = _normalizer->getLengthScale(); - const PylithReal timeScale = _normalizer->getTimeScale(); + const PylithReal displacementScale = _scales->getDisplacementScale(); + const PylithReal timeScale = _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -169,7 +169,7 @@ pylith::faults::KinSrcAuxiliaryFactory::addSlipRate(void) { for (int i = 0; i < _spaceDim; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = lengthScale / timeScale; + description.scale = displacementScale / timeScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); diff --git a/libsrc/pylith/faults/KinSrcBrune.cc b/libsrc/pylith/faults/KinSrcBrune.cc index 8841622b06..398748d3d4 100644 --- a/libsrc/pylith/faults/KinSrcBrune.cc +++ b/libsrc/pylith/faults/KinSrcBrune.cc @@ -206,14 +206,14 @@ pylith::faults::KinSrcBrune::slipAccFn(const PylithInt dim, // ------------------------------------------------------------------------------------------------ // Preinitialize earthquake source. Set names/sizes of auxiliary subfields. void -pylith::faults::KinSrcBrune::_auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, +pylith::faults::KinSrcBrune::_auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) { PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("_auxiliaryFieldSetup()"); assert(_auxiliaryFactory); assert(cs); - _auxiliaryFactory->initialize(_auxiliaryField, normalizer, cs->getSpaceDim()); + _auxiliaryFactory->initialize(_auxiliaryField, scales, cs->getSpaceDim()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the slip time // function diff --git a/libsrc/pylith/faults/KinSrcBrune.hh b/libsrc/pylith/faults/KinSrcBrune.hh index c55a385dfe..29ce56c740 100644 --- a/libsrc/pylith/faults/KinSrcBrune.hh +++ b/libsrc/pylith/faults/KinSrcBrune.hh @@ -167,10 +167,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); // NOT IMPLEMENTED ////////////////////////////////////////////////////// diff --git a/libsrc/pylith/faults/KinSrcConstRate.cc b/libsrc/pylith/faults/KinSrcConstRate.cc index 10ba97f546..f72984e348 100644 --- a/libsrc/pylith/faults/KinSrcConstRate.cc +++ b/libsrc/pylith/faults/KinSrcConstRate.cc @@ -169,14 +169,14 @@ pylith::faults::KinSrcConstRate::slipAccFn(const PylithInt dim, // ------------------------------------------------------------------------------------------------ // Preinitialize earthquake source. Set names/sizes of auxiliary subfields. void -pylith::faults::KinSrcConstRate::_auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, +pylith::faults::KinSrcConstRate::_auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) { PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("_auxiliaryFieldSetup()"); assert(_auxiliaryFactory); assert(cs); - _auxiliaryFactory->initialize(_auxiliaryField, normalizer, cs->getSpaceDim()); + _auxiliaryFactory->initialize(_auxiliaryField, scales, cs->getSpaceDim()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the slip time function // kernel. diff --git a/libsrc/pylith/faults/KinSrcConstRate.hh b/libsrc/pylith/faults/KinSrcConstRate.hh index 28694053c4..2ab99ba2c7 100644 --- a/libsrc/pylith/faults/KinSrcConstRate.hh +++ b/libsrc/pylith/faults/KinSrcConstRate.hh @@ -169,10 +169,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); // NOT IMPLEMENTED //////////////////////////////////////////////////////////////////////////// diff --git a/libsrc/pylith/faults/KinSrcLiuCos.cc b/libsrc/pylith/faults/KinSrcLiuCos.cc index 3187ef2801..1c23735eba 100644 --- a/libsrc/pylith/faults/KinSrcLiuCos.cc +++ b/libsrc/pylith/faults/KinSrcLiuCos.cc @@ -270,14 +270,14 @@ pylith::faults::KinSrcLiuCos::slipAccFn(const PylithInt dim, // --------------------------------------------------------------------------------------------------------------------- // Preinitialize earthquake source. Set names/sizes of auxiliary subfields. void -pylith::faults::KinSrcLiuCos::_auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, +pylith::faults::KinSrcLiuCos::_auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) { PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("_auxiliaryFieldSetup()"); assert(_auxiliaryFactory); assert(cs); - _auxiliaryFactory->initialize(_auxiliaryField, normalizer, cs->getSpaceDim()); + _auxiliaryFactory->initialize(_auxiliaryField, scales, cs->getSpaceDim()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the slip time function // kernel. diff --git a/libsrc/pylith/faults/KinSrcLiuCos.hh b/libsrc/pylith/faults/KinSrcLiuCos.hh index c8c386379e..39e1a821f2 100644 --- a/libsrc/pylith/faults/KinSrcLiuCos.hh +++ b/libsrc/pylith/faults/KinSrcLiuCos.hh @@ -162,10 +162,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); // NOT IMPLEMENTED ////////////////////////////////////////////////////// diff --git a/libsrc/pylith/faults/KinSrcRamp.cc b/libsrc/pylith/faults/KinSrcRamp.cc index f9bf3f2bc9..232dd0a786 100644 --- a/libsrc/pylith/faults/KinSrcRamp.cc +++ b/libsrc/pylith/faults/KinSrcRamp.cc @@ -298,14 +298,14 @@ pylith::faults::KinSrcRamp::slipAccFn(const PylithInt dim, // ------------------------------------------------------------------------------------------------ // Preinitialize earthquake source. Set names/sizes of auxiliary subfields. void -pylith::faults::KinSrcRamp::_auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, +pylith::faults::KinSrcRamp::_auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) { PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("_auxiliaryFieldSetup()"); assert(_auxiliaryFactory); assert(cs); - _auxiliaryFactory->initialize(_auxiliaryField, normalizer, cs->getSpaceDim()); + _auxiliaryFactory->initialize(_auxiliaryField, scales, cs->getSpaceDim()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the slip time // function. diff --git a/libsrc/pylith/faults/KinSrcRamp.hh b/libsrc/pylith/faults/KinSrcRamp.hh index d8df44db95..3e8e718e59 100644 --- a/libsrc/pylith/faults/KinSrcRamp.hh +++ b/libsrc/pylith/faults/KinSrcRamp.hh @@ -170,10 +170,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); // NOT IMPLEMENTED ////////////////////////////////////////////////////// diff --git a/libsrc/pylith/faults/KinSrcStep.cc b/libsrc/pylith/faults/KinSrcStep.cc index 4e6ce4903c..3631b63870 100644 --- a/libsrc/pylith/faults/KinSrcStep.cc +++ b/libsrc/pylith/faults/KinSrcStep.cc @@ -87,14 +87,14 @@ pylith::faults::KinSrcStep::slipFn(const PylithInt dim, // --------------------------------------------------------------------------------------------------------------------- // Preinitialize earthquake source. Set names/sizes of auxiliary subfields. void -pylith::faults::KinSrcStep::_auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, +pylith::faults::KinSrcStep::_auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) { PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("_auxiliaryFieldSetup()"); assert(_auxiliaryFactory); assert(cs); - _auxiliaryFactory->initialize(_auxiliaryField, normalizer, cs->getSpaceDim()); + _auxiliaryFactory->initialize(_auxiliaryField, scales, cs->getSpaceDim()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the slip time function // kernel. diff --git a/libsrc/pylith/faults/KinSrcStep.hh b/libsrc/pylith/faults/KinSrcStep.hh index 8524f58d0f..9f0528864a 100644 --- a/libsrc/pylith/faults/KinSrcStep.hh +++ b/libsrc/pylith/faults/KinSrcStep.hh @@ -81,10 +81,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); // NOT IMPLEMENTED ///////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/libsrc/pylith/faults/KinSrcTimeHistory.cc b/libsrc/pylith/faults/KinSrcTimeHistory.cc index 59fa28f8d8..2be190e19d 100644 --- a/libsrc/pylith/faults/KinSrcTimeHistory.cc +++ b/libsrc/pylith/faults/KinSrcTimeHistory.cc @@ -231,14 +231,14 @@ pylith::faults::KinSrcTimeHistory::slipAccFn(const PylithInt dim, // ------------------------------------------------------------------------------------------------ // Preinitialize earthquake source. Set names/sizes of auxiliary subfields. void -pylith::faults::KinSrcTimeHistory::_auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, +pylith::faults::KinSrcTimeHistory::_auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) { PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("_auxiliaryFieldSetup()"); assert(_auxiliaryFactory); assert(cs); - _auxiliaryFactory->initialize(_auxiliaryField, normalizer, cs->getSpaceDim()); + _auxiliaryFactory->initialize(_auxiliaryField, scales, cs->getSpaceDim()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the slip time function // kernel. diff --git a/libsrc/pylith/faults/KinSrcTimeHistory.hh b/libsrc/pylith/faults/KinSrcTimeHistory.hh index 43f3f09649..9cb20b11fe 100644 --- a/libsrc/pylith/faults/KinSrcTimeHistory.hh +++ b/libsrc/pylith/faults/KinSrcTimeHistory.hh @@ -183,10 +183,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); // PRIVATE MEMBERS //////////////////////////////////////////////////////////////////////////// diff --git a/libsrc/pylith/feassemble/AuxiliaryFactory.cc b/libsrc/pylith/feassemble/AuxiliaryFactory.cc index b9a954644c..6d19429f94 100644 --- a/libsrc/pylith/feassemble/AuxiliaryFactory.cc +++ b/libsrc/pylith/feassemble/AuxiliaryFactory.cc @@ -15,7 +15,7 @@ #include "pylith/topology/Field.hh" // HOLDSA AuxiliaryField #include "pylith/topology/FieldQuery.hh" // USES FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -60,13 +60,13 @@ pylith::feassemble::AuxiliaryFactory::getQueryDB(void) const { // Initialie factory for setting up auxiliary subfields. void pylith::feassemble::AuxiliaryFactory::initialize(pylith::topology::Field* field, - const spatialdata::units::Nondimensional& normalizer, + const pylith::scales::Scales& scales, const int spaceDim, const pylith::topology::FieldBase::Description* defaultDescription) { PYLITH_METHOD_BEGIN; - PYLITH_JOURNAL_DEBUG("initialize(field="<openDB(_queryDB, _normalizer->getLengthScale()); + _fieldQuery->openDB(_queryDB, _scales->getLengthScale()); _fieldQuery->queryDB(); _fieldQuery->closeDB(_queryDB); } else { diff --git a/libsrc/pylith/feassemble/AuxiliaryFactory.hh b/libsrc/pylith/feassemble/AuxiliaryFactory.hh index a72fa3aaeb..f05b29b8da 100644 --- a/libsrc/pylith/feassemble/AuxiliaryFactory.hh +++ b/libsrc/pylith/feassemble/AuxiliaryFactory.hh @@ -16,7 +16,7 @@ #include "pylith/topology/FieldQuery.hh" // USES FieldQuery::queryfn_type #include "spatialdata/spatialdb/spatialdbfwd.hh" // USES SpatialDB -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Normalizer +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales class pylith::feassemble::AuxiliaryFactory : public pylith::topology::FieldFactory { friend class TestAuxiliaryFactory; // unit testing @@ -45,12 +45,12 @@ public: /** Initialize factory for setting up auxiliary subfields. * * @param[inout] field Auxiliary field for which subfields are to be created. - * @param[in] normalizer Scales for nondimensionalization. + * @param[in] scales Scales for nondimensionalization. * @param[in] spaceDim Spatial dimension of problem. * @param[in] defaultDescription Default description for new subfields. */ void initialize(pylith::topology::Field* field, - const spatialdata::units::Nondimensional& normalizer, + const pylith::scales::Scales& scales, const int spaceDim, const pylith::topology::FieldBase::Description* defaultDescription=NULL); diff --git a/libsrc/pylith/feassemble/Constraint.cc b/libsrc/pylith/feassemble/Constraint.cc index f9873c541a..644096d562 100644 --- a/libsrc/pylith/feassemble/Constraint.cc +++ b/libsrc/pylith/feassemble/Constraint.cc @@ -22,7 +22,7 @@ #include "pylith/utils/EventLogger.hh" // USES EventLogger #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL_* -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES assert() #include // USES std::runtime_error @@ -190,7 +190,7 @@ pylith::feassemble::Constraint::initialize(const pylith::topology::Field& soluti _observers = _physics->getObservers(); // Memory managed by Physics if (_observers) { _observers->setPhysicsImplementation(this); - _observers->setTimeScale(_physics->getNormalizer().getTimeScale()); + _observers->setTimeScale(_physics->getScales().getTimeScale()); } // if PYLITH_METHOD_END; diff --git a/libsrc/pylith/feassemble/ConstraintSimple.cc b/libsrc/pylith/feassemble/ConstraintSimple.cc index c5c9bdb49f..a12a771aac 100644 --- a/libsrc/pylith/feassemble/ConstraintSimple.cc +++ b/libsrc/pylith/feassemble/ConstraintSimple.cc @@ -12,8 +12,6 @@ #include "pylith/feassemble/ConstraintSimple.hh" // implementation of object methods -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional - #include "pylith/topology/Mesh.hh" // USES Mesh #include "pylith/topology/Field.hh" // USES Field #include "pylith/feassemble/IntegrationData.hh" // USES IntegrationData @@ -24,6 +22,8 @@ #include "pylith/utils/error.hh" // USES PYLITH_METHOD_* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL_* +#include "pylith/scales/Scales.hh" // USES Scales + #include // USES assert() #include // USES std::runtime_error @@ -32,7 +32,7 @@ pylith::feassemble::ConstraintSimple::ConstraintSimple(pylith::problems::Physics* const physics) : Constraint(physics), _fn(NULL) { - GenericComponent::setName("constraintSimple"); + GenericComponent::setName("constraintSimple "); } // constructor @@ -56,7 +56,7 @@ pylith::feassemble::ConstraintSimple::setUserFn(const PetscUserFieldFunc fn) { void pylith::feassemble::ConstraintSimple::initialize(const pylith::topology::Field& solution) { PYLITH_METHOD_BEGIN; - PYLITH_JOURNAL_DEBUG("initialize(solution="<getField(pylith::feassemble::IntegrationData::solution); assert(solution); @@ -169,8 +169,8 @@ pylith::feassemble::ConstraintSimple::setSolution(pylith::feassemble::Integratio pythia::journal::debug_t debug(GenericComponent::getName()); if (debug.state()) { - PYLITH_JOURNAL_DEBUG("Displaying solution field"); - solution->view("solution field"); + PYLITH_JOURNAL_DEBUG("Displaying solution field "); + solution->view("solution field "); } // if PYLITH_METHOD_END; diff --git a/libsrc/pylith/feassemble/Integrator.cc b/libsrc/pylith/feassemble/Integrator.cc index a21e666827..f5d55eff6b 100644 --- a/libsrc/pylith/feassemble/Integrator.cc +++ b/libsrc/pylith/feassemble/Integrator.cc @@ -22,7 +22,7 @@ #include "pylith/utils/error.hh" // USES PYLITH_METHOD_* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL_* -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES assert() #include // USES typeid() @@ -211,7 +211,7 @@ pylith::feassemble::Integrator::initialize(const pylith::topology::Field& soluti _observers = _physics->getObservers(); // Memory managed by Physics if (_observers) { _observers->setPhysicsImplementation(this); - _observers->setTimeScale(_physics->getNormalizer().getTimeScale()); + _observers->setTimeScale(_physics->getScales().getTimeScale()); const pylith::problems::Observer::NotificationType notification = pylith::problems::ObserverPhysics::DIAGNOSTIC; _observers->notifyObservers(0.0, 0, solution, notification); diff --git a/libsrc/pylith/fekernels/IncompressibleElasticity.hh b/libsrc/pylith/fekernels/IncompressibleElasticity.hh index 5dba9910ac..dff76830cc 100644 --- a/libsrc/pylith/fekernels/IncompressibleElasticity.hh +++ b/libsrc/pylith/fekernels/IncompressibleElasticity.hh @@ -56,12 +56,12 @@ public: const pylith::fekernels::TensorOps&, PylithScalar*); - // PUBLIC MEMBERS ////////////////////////////////////////////////////////////////////////////////////////////////// + // PUBLIC MEMBERS ///////////////////////////////////////////////////////////////////////////// public: - // =========================================================================================== + // ============================================================================================ // Kernels for elasticity equation - // =========================================================================================== + // ============================================================================================ // -------------------------------------------------------------------------------------------- // f0p helper function. @@ -179,9 +179,9 @@ public: } // for } // Jf2up - // =========================================================================================== + // ============================================================================================ // Helper functions - // =========================================================================================== + // ============================================================================================ // -------------------------------------------------------------------------------------------- /** Calculate mean stress for isotropic linear incompressible elasticity WITHOUT reference stress diff --git a/libsrc/pylith/materials/AuxiliaryFactoryElastic.cc b/libsrc/pylith/materials/AuxiliaryFactoryElastic.cc index 5a35f3d6c0..4bd0e3f169 100644 --- a/libsrc/pylith/materials/AuxiliaryFactoryElastic.cc +++ b/libsrc/pylith/materials/AuxiliaryFactoryElastic.cc @@ -17,7 +17,8 @@ #include "pylith/topology/Field.hh" // USES Field #include "pylith/topology/FieldQuery.hh" // HOLDSA FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -44,7 +45,7 @@ pylith::materials::AuxiliaryFactoryElastic::addShearModulus(void) { PYLITH_JOURNAL_DEBUG("addShearModulus(void)"); const char* subfieldName = "shear_modulus"; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal rigidityScale = _scales->getRigidityScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -53,9 +54,8 @@ pylith::materials::AuxiliaryFactoryElastic::addShearModulus(void) { description.numComponents = 1; description.componentNames.resize(1); description.componentNames[0] = subfieldName; - description.scale = pressureScale; + description.scale = rigidityScale; description.validator = pylith::topology::FieldQuery::validatorNonnegative; - description.validatorTolerance = 100.0; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); pylith::materials::Query::shearModulusFromVM(subfieldName, this); @@ -72,7 +72,7 @@ pylith::materials::AuxiliaryFactoryElastic::addBulkModulus(void) { PYLITH_JOURNAL_DEBUG("addBulkModulus(void)"); const char* subfieldName = "bulk_modulus"; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal rigidityScale = _scales->getRigidityScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -81,7 +81,7 @@ pylith::materials::AuxiliaryFactoryElastic::addBulkModulus(void) { description.numComponents = 1; description.componentNames.resize(1); description.componentNames[0] = subfieldName; - description.scale = pressureScale; + description.scale = rigidityScale; description.validator = pylith::topology::FieldQuery::validatorPositive; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -107,7 +107,7 @@ pylith::materials::AuxiliaryFactoryElastic::addReferenceStress(void) { "reference_stress_yz", "reference_stress_xz" }; const int stressSize = (3 == _spaceDim) ? 6 : (2 == _spaceDim) ? 4 : 1; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal stressScale = pylith::scales::ElasticityScales::getStressScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -118,7 +118,7 @@ pylith::materials::AuxiliaryFactoryElastic::addReferenceStress(void) { for (int i = 0; i < stressSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = pressureScale; + description.scale = stressScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -145,6 +145,7 @@ pylith::materials::AuxiliaryFactoryElastic::addReferenceStrain(void) { "reference_strain_xz" }; const int strainSize = (3 == _spaceDim) ? 6 : (2 == _spaceDim) ? 4 : 1; + const PylithReal strainScale = pylith::scales::ElasticityScales::getStrainScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -155,7 +156,7 @@ pylith::materials::AuxiliaryFactoryElastic::addReferenceStrain(void) { for (int i = 0; i < strainSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = 1.0; + description.scale = strainScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); diff --git a/libsrc/pylith/materials/AuxiliaryFactoryElasticity.cc b/libsrc/pylith/materials/AuxiliaryFactoryElasticity.cc index 676bdbc6f7..f91d96a1f7 100644 --- a/libsrc/pylith/materials/AuxiliaryFactoryElasticity.cc +++ b/libsrc/pylith/materials/AuxiliaryFactoryElasticity.cc @@ -17,7 +17,7 @@ #include "pylith/topology/Field.hh" // USES Field #include "pylith/topology/FieldQuery.hh" // HOLDSA FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField #include "pylith/utils/error.hh" // USES PYLITH_METHOD* @@ -45,7 +45,7 @@ pylith::materials::AuxiliaryFactoryElasticity::addDensity(void) { PYLITH_JOURNAL_DEBUG("addDensity(void)"); const char* subfieldName = "density"; - const PylithReal densityScale = _normalizer->getDensityScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -78,7 +78,7 @@ pylith::materials::AuxiliaryFactoryElasticity::addBodyForce(void) { "body_force_z", }; - const PylithReal forceScale = _normalizer->getPressureScale() / _normalizer->getLengthScale(); + const PylithReal bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -89,7 +89,7 @@ pylith::materials::AuxiliaryFactoryElasticity::addBodyForce(void) { for (int i = 0; i < _spaceDim; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = forceScale; + description.scale = bodyForceScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -113,9 +113,7 @@ pylith::materials::AuxiliaryFactoryElasticity::addGravityField(spatialdata::spat "gravitational_acceleration_z", }; - const PylithReal lengthScale = _normalizer->getLengthScale(); - const PylithReal timeScale = _normalizer->getTimeScale(); - const PylithReal accelerationScale = lengthScale / (timeScale * timeScale); + const PylithReal accelerationScale = pylith::scales::ElasticityScales::getAccelerationScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; diff --git a/libsrc/pylith/materials/AuxiliaryFactoryPoroelastic.cc b/libsrc/pylith/materials/AuxiliaryFactoryPoroelastic.cc index 9ac8431f82..1d72e85ec8 100644 --- a/libsrc/pylith/materials/AuxiliaryFactoryPoroelastic.cc +++ b/libsrc/pylith/materials/AuxiliaryFactoryPoroelastic.cc @@ -17,7 +17,8 @@ #include "pylith/topology/Field.hh" // USES Field #include "pylith/topology/FieldQuery.hh" // HOLDSA FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -44,9 +45,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addIsotropicPermeability(void) { PYLITH_JOURNAL_DEBUG("addIsotropicPermeability(void)"); const char* subfieldName = "isotropic_permeability"; - - const PylithReal lengthScale = _normalizer->getLengthScale(); - const PylithReal permeabilityScale = lengthScale*lengthScale; + const PylithReal permeabilityScale = pylith::scales::ElasticityScales::getPermeabilityScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -56,8 +55,6 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addIsotropicPermeability(void) { description.componentNames.resize(1); description.componentNames[0] = subfieldName; description.scale = permeabilityScale; - // description.validator = pylith::topology::FieldQuery::validatorScale; - // description.validatorTolerance = 10.0; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); this->setSubfieldQuery(subfieldName); @@ -83,8 +80,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addTensorPermeability(void) { "permeability_xz" }; const int tensorSize = (3 == _spaceDim) ? 6 : (2 == _spaceDim) ? 4 : 1; - const PylithReal lengthScale = _normalizer->getLengthScale(); - const PylithReal permeabilityScale = lengthScale*lengthScale; + const PylithReal permeabilityScale = pylith::scales::ElasticityScales::getPermeabilityScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -96,8 +92,6 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addTensorPermeability(void) { description.componentNames[i] = componentNames[i]; } // for description.scale = permeabilityScale; - // description.validator = pylith::topology::FieldQuery::validatorScale; - // description.validatorTolerance = 10.0; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); this->setSubfieldQuery(subfieldName); @@ -114,7 +108,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addDrainedBulkModulus(void) { PYLITH_JOURNAL_DEBUG("addDrainedBulkModulus(void)"); const char* subfieldName = "drained_bulk_modulus"; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal rigidityScale = _scales->getRigidityScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -123,9 +117,8 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addDrainedBulkModulus(void) { description.numComponents = 1; description.componentNames.resize(1); description.componentNames[0] = subfieldName; - description.scale = pressureScale; + description.scale = rigidityScale; description.validator = pylith::topology::FieldQuery::validatorPositive; - description.validatorTolerance = 100.0; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); this->setSubfieldQuery(subfieldName); @@ -142,6 +135,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addBiotCoefficient(void) { PYLITH_JOURNAL_DEBUG("addBiotCoefficient(void)"); const char* subfieldName = "biot_coefficient"; + const PylithReal scale = 1.0; pylith::topology::Field::Description description; description.label = subfieldName; @@ -150,9 +144,8 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addBiotCoefficient(void) { description.numComponents = 1; description.componentNames.resize(1); description.componentNames[0] = subfieldName; - description.scale = 1.0; + description.scale = scale; description.validator = pylith::topology::FieldQuery::validatorPositive; - description.validatorTolerance = 10.0; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); this->setSubfieldQuery(subfieldName); @@ -169,7 +162,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addBiotModulus(void) { PYLITH_JOURNAL_DEBUG("addBiotModulus(void)"); const char* subfieldName = "biot_modulus"; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal rigidityScale = _scales->getRigidityScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -178,9 +171,8 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addBiotModulus(void) { description.numComponents = 1; description.componentNames.resize(1); description.componentNames[0] = subfieldName; - description.scale = pressureScale; + description.scale = rigidityScale; description.validator = pylith::topology::FieldQuery::validatorPositive; - description.validatorTolerance = 100.0; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); pylith::materials::Query::biotModulusFromInput(subfieldName, this); @@ -206,7 +198,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addReferenceStress(void) { "reference_stress_xz" }; const int stressSize = (3 == _spaceDim) ? 6 : (2 == _spaceDim) ? 4 : 1; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal stressScale = pylith::scales::ElasticityScales::getStressScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -217,7 +209,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addReferenceStress(void) { for (int i = 0; i < stressSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = pressureScale; + description.scale = stressScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -244,6 +236,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addReferenceStrain(void) { "reference_strain_xz" }; const int strainSize = (3 == _spaceDim) ? 6 : (2 == _spaceDim) ? 4 : 1; + const PylithReal strainScale = pylith::scales::ElasticityScales::getStrainScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -254,7 +247,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addReferenceStrain(void) { for (int i = 0; i < strainSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = 1.0; + description.scale = strainScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -272,7 +265,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addShearModulus(void) { PYLITH_JOURNAL_DEBUG("addShearModulus(void)"); const char* subfieldName = "shear_modulus"; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal rigidityScale = _scales->getRigidityScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -281,7 +274,7 @@ pylith::materials::AuxiliaryFactoryPoroelastic::addShearModulus(void) { description.numComponents = 1; description.componentNames.resize(1); description.componentNames[0] = subfieldName; - description.scale = pressureScale; + description.scale = rigidityScale; description.validator = pylith::topology::FieldQuery::validatorNonnegative; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); diff --git a/libsrc/pylith/materials/AuxiliaryFactoryPoroelasticity.cc b/libsrc/pylith/materials/AuxiliaryFactoryPoroelasticity.cc index 5c3b99adfc..1b4a0fdf6b 100644 --- a/libsrc/pylith/materials/AuxiliaryFactoryPoroelasticity.cc +++ b/libsrc/pylith/materials/AuxiliaryFactoryPoroelasticity.cc @@ -17,7 +17,8 @@ #include "pylith/topology/Field.hh" // USES Field #include "pylith/topology/FieldQuery.hh" // HOLDSA FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField #include "pylith/utils/error.hh" // USES PYLITH_METHOD* @@ -51,7 +52,7 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addBodyForce(void) { "body_force_z" }; - const PylithReal forceScale = _normalizer->getPressureScale() / _normalizer->getLengthScale(); + const PylithReal bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -62,7 +63,7 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addBodyForce(void) { for (int i = 0; i < _spaceDim; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = forceScale; + description.scale = bodyForceScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -85,9 +86,7 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addGravityField(spatialdata:: "gravitational_acceleration_y", "gravitational_acceleration_z" }; - const PylithReal lengthScale = _normalizer->getLengthScale(); - const PylithReal timeScale = _normalizer->getTimeScale(); - const PylithReal accelerationScale = lengthScale / (timeScale * timeScale); + const PylithReal accelerationScale = pylith::scales::ElasticityScales::getAccelerationScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -116,7 +115,7 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addPorosity(void) { // porosi PYLITH_JOURNAL_DEBUG("addPorosity(void)"); const char* subfieldName = "porosity"; - const PylithReal noScale = 1.0; + const PylithReal porosityScale = 1.0; pylith::topology::Field::Description description; description.label = subfieldName; @@ -127,7 +126,7 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addPorosity(void) { // porosi description.historySize = 1; description.componentNames.resize(1); description.componentNames[0] = subfieldName; - description.scale = noScale; + description.scale = porosityScale; description.validator = pylith::topology::FieldQuery::validatorNonnegative; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -145,7 +144,7 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addSolidDensity(void) { PYLITH_JOURNAL_DEBUG("addSolidDensity(void)"); const char* subfieldName = "solid_density"; - const PylithReal densityScale = _normalizer->getDensityScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -172,7 +171,7 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addFluidDensity(void) { // fl PYLITH_JOURNAL_DEBUG("addFluidDensity(void)"); const char* subfieldName = "fluid_density"; - const PylithReal densityScale = _normalizer->getDensityScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -194,14 +193,12 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addFluidDensity(void) { // fl // ---------------------------------------------------------------------- // Add fluid viscosity subfield to auxiliary fields. void -pylith::materials::AuxiliaryFactoryPoroelasticity::addFluidViscosity(void) { // fluidViscosity +pylith::materials::AuxiliaryFactoryPoroelasticity::addFluidViscosity(void) { PYLITH_METHOD_BEGIN; PYLITH_JOURNAL_DEBUG("addFluidViscosity(void)"); const char* subfieldName = "fluid_viscosity"; - const PylithReal pressureScale = _normalizer->getPressureScale(); - const PylithReal timeScale = _normalizer->getTimeScale(); - const PylithReal viscosityScale = pressureScale*timeScale; + const PylithReal viscosityScale = pylith::scales::ElasticityScales::getViscosityScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -229,9 +226,8 @@ pylith::materials::AuxiliaryFactoryPoroelasticity::addSourceDensity(void) { // s PYLITH_JOURNAL_DEBUG("addSourceDensity(void)"); const char* subfieldName = "source_density"; - const PylithReal lengthScale = _normalizer->getLengthScale(); - const PylithReal timeScale = _normalizer->getTimeScale(); - const PylithReal sourceDensityScale = lengthScale/timeScale; + const PylithReal timeScale = _scales->getTimeScale(); + const PylithReal sourceDensityScale = 1.0 / timeScale; pylith::topology::Field::Description description; description.label = subfieldName; diff --git a/libsrc/pylith/materials/AuxiliaryFactoryViscoelastic.cc b/libsrc/pylith/materials/AuxiliaryFactoryViscoelastic.cc index 8669261f6a..09bc8b6070 100644 --- a/libsrc/pylith/materials/AuxiliaryFactoryViscoelastic.cc +++ b/libsrc/pylith/materials/AuxiliaryFactoryViscoelastic.cc @@ -18,7 +18,8 @@ #include "pylith/topology/Field.hh" // USES Field #include "pylith/topology/FieldQuery.hh" // HOLDSA FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField #include "pylith/utils/error.hh" // USES PYLITH_METHOD* @@ -46,7 +47,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addMaxwellTime(void) { PYLITH_JOURNAL_DEBUG("addMaxwellTime(void)"); const char* subfieldName = "maxwell_time"; - const PylithReal timeScale = _normalizer->getTimeScale(); + const PylithReal timeScale = _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -78,7 +79,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addMaxwellTimeGeneralizedMaxwel "maxwell_time_2", "maxwell_time_3" }; - const PylithReal timeScale = _normalizer->getTimeScale(); + const PylithReal timeScale = _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -140,7 +141,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addPowerLawReferenceStrainRate( PYLITH_JOURNAL_DEBUG("addPowerLawReferenceStrainRate(void)"); const char* subfieldName = "power_law_reference_strain_rate"; - const PylithReal strainRateScale = 1.0/_normalizer->getTimeScale(); + const PylithReal strainRateScale = pylith::scales::ElasticityScales::getStrainScale(*_scales) / _scales->getTimeScale(); pylith::topology::Field::Description description; description.label = subfieldName; @@ -167,7 +168,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addPowerLawReferenceStress(void PYLITH_JOURNAL_DEBUG("addPowerLawReferenceStress(void)"); const char* subfieldName = "power_law_reference_stress"; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal stressScale = pylith::scales::ElasticityScales::getStressScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -176,7 +177,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addPowerLawReferenceStress(void description.numComponents = 1; description.componentNames.resize(1); description.componentNames[0] = subfieldName; - description.scale = pressureScale; + description.scale = stressScale; description.validator = pylith::topology::FieldQuery::validatorPositive; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -241,7 +242,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addTotalStrain(void) { for (int i = 0; i < strainSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = 1.0; + description.scale = pylith::scales::ElasticityScales::getStrainScale(*_scales); description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -268,7 +269,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addDeviatoricStress(void) { "deviatoric_stress_xz" }; const int stressSize = (3 == _spaceDim) ? 6 : (2 == _spaceDim) ? 4 : 1; - const PylithReal pressureScale = _normalizer->getPressureScale(); + const PylithReal stressScale = pylith::scales::ElasticityScales::getStressScale(*_scales); pylith::topology::Field::Description description; description.label = subfieldName; @@ -281,7 +282,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addDeviatoricStress(void) { for (int i = 0; i < stressSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = pressureScale; + description.scale = stressScale; description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -320,7 +321,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addViscousStrain(void) { for (int i = 0; i < strainSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = 1.0; + description.scale = pylith::scales::ElasticityScales::getStrainScale(*_scales); description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); @@ -355,7 +356,7 @@ pylith::materials::AuxiliaryFactoryViscoelastic::addViscousStrainGeneralizedMaxw description.componentNames[iname] = std::string(subfieldName) + std::string(componentElementNumbers[j]) + std::string(componentSuffixes[i]); } // for i } // for j - description.scale = 1.0; + description.scale = pylith::scales::ElasticityScales::getStrainScale(*_scales); description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(subfieldName)); diff --git a/libsrc/pylith/materials/DerivedFactoryElasticity.cc b/libsrc/pylith/materials/DerivedFactoryElasticity.cc index 8f103505d3..dd32efbe6d 100644 --- a/libsrc/pylith/materials/DerivedFactoryElasticity.cc +++ b/libsrc/pylith/materials/DerivedFactoryElasticity.cc @@ -14,7 +14,7 @@ #include "pylith/topology/Field.hh" // USES Field -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -43,7 +43,6 @@ pylith::materials::DerivedFactoryElasticity::addCauchyStress(void) { const char* fieldName = "cauchy_stress"; const char* componentNames[6] = { "stress_xx", "stress_yy", "stress_zz", "stress_xy", "stress_yz", "stress_xz" }; const int stressSize = (3 == _spaceDim) ? 6 : (2 == _spaceDim) ? 4 : 1; - const PylithReal pressureScale = _normalizer->getPressureScale(); pylith::topology::Field::Description description; description.label = fieldName; @@ -54,7 +53,7 @@ pylith::materials::DerivedFactoryElasticity::addCauchyStress(void) { for (int i = 0; i < stressSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = pressureScale; + description.scale = pylith::scales::ElasticityScales::getStressScale(*_scales); description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(fieldName)); @@ -83,7 +82,7 @@ pylith::materials::DerivedFactoryElasticity::addCauchyStrain(void) { for (int i = 0; i < strainSize; ++i) { description.componentNames[i] = componentNames[i]; } // for - description.scale = 1.0; + description.scale = pylith::scales::ElasticityScales::getStrainScale(*_scales); description.validator = NULL; _field->subfieldAdd(description, getSubfieldDiscretization(fieldName)); diff --git a/libsrc/pylith/materials/DerivedFactoryPoroelasticity.cc b/libsrc/pylith/materials/DerivedFactoryPoroelasticity.cc index ca478a9f55..3d8f5e6b08 100644 --- a/libsrc/pylith/materials/DerivedFactoryPoroelasticity.cc +++ b/libsrc/pylith/materials/DerivedFactoryPoroelasticity.cc @@ -16,7 +16,8 @@ #include "pylith/topology/FieldQuery.hh" // HOLDSA FieldQuery -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -43,7 +44,7 @@ pylith::materials::DerivedFactoryPoroelasticity::addBulkDensity(void) { PYLITH_JOURNAL_DEBUG("addBulkDensity(void)"); const char* fieldName = "bulk_density"; - const PylithReal densityScale = _normalizer->getDensityScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_scales); pylith::topology::Field::Description description; description.label = fieldName; diff --git a/libsrc/pylith/materials/Elasticity.cc b/libsrc/pylith/materials/Elasticity.cc index e39bd63d26..6373b9dcc7 100644 --- a/libsrc/pylith/materials/Elasticity.cc +++ b/libsrc/pylith/materials/Elasticity.cc @@ -33,7 +33,7 @@ #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES typeid() @@ -220,8 +220,8 @@ pylith::materials::Elasticity::createAuxiliaryField(const pylith::topology::Fiel assert(_rheology); pylith::materials::AuxiliaryFactoryElasticity* auxiliaryFactory = _rheology->getAuxiliaryFactory();assert(auxiliaryFactory); - assert(_normalizer); - auxiliaryFactory->initialize(auxiliaryField, *_normalizer, domainMesh.getDimension()); + assert(_scales); + auxiliaryFactory->initialize(auxiliaryField, *_scales, domainMesh.getDimension()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the FE kernels. @@ -249,7 +249,7 @@ pylith::materials::Elasticity::createAuxiliaryField(const pylith::topology::Fiel assert(auxiliaryFactory); auxiliaryFactory->setValuesFromDB(); - pythia::journal::debug_t debug("elasticity.view_auxiliary_field"); + pythia::journal::debug_t debug("elasticity_view_auxiliary_field"); if (debug.state()) { auxiliaryField->view("Elasticity auxiliary field"); } // if @@ -276,8 +276,8 @@ pylith::materials::Elasticity::createDerivedField(const pylith::topology::Field& pylith::topology::Field* derivedField = new pylith::topology::Field(domainMesh);assert(derivedField); derivedField->setLabel("derived field"); - assert(_normalizer); - _derivedFactory->initialize(derivedField, *_normalizer, domainMesh.getDimension()); + assert(_scales); + _derivedFactory->initialize(derivedField, *_scales, domainMesh.getDimension()); _derivedFactory->addSubfields(); derivedField->subfieldsSetup(); @@ -306,6 +306,9 @@ pylith::materials::Elasticity::getSolverDefaults(const bool isParallel, options->add("-ts_type", "beuler"); options->add("-pc_type", "gamg"); + options->add("-pc_gamg_coarse_eq_limit", "200"); + options->add("-mg_fine_ksp_max_it", "5"); + options->add("-mg_levels_pc_type", "pbjacobi"); if (hasFault) { options->add("-dm_reorder_section"); diff --git a/libsrc/pylith/materials/IncompressibleElasticity.cc b/libsrc/pylith/materials/IncompressibleElasticity.cc index 51b276826b..756ebbd3a4 100644 --- a/libsrc/pylith/materials/IncompressibleElasticity.cc +++ b/libsrc/pylith/materials/IncompressibleElasticity.cc @@ -29,7 +29,7 @@ #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES typeid() @@ -160,8 +160,8 @@ pylith::materials::IncompressibleElasticity::createAuxiliaryField(const pylith:: assert(_rheology); pylith::materials::AuxiliaryFactoryElasticity* auxiliaryFactory = _rheology->getAuxiliaryFactory();assert(auxiliaryFactory); - assert(_normalizer); - auxiliaryFactory->initialize(auxiliaryField, *_normalizer, domainMesh.getDimension()); + assert(_scales); + auxiliaryFactory->initialize(auxiliaryField, *_scales, domainMesh.getDimension()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the FE kernels. @@ -209,8 +209,8 @@ pylith::materials::IncompressibleElasticity::createDerivedField(const pylith::to pylith::topology::Field* derivedField = new pylith::topology::Field(domainMesh);assert(derivedField); derivedField->setLabel("derived field"); - assert(_normalizer); - _derivedFactory->initialize(derivedField, *_normalizer, domainMesh.getDimension()); + assert(_scales); + _derivedFactory->initialize(derivedField, *_scales, domainMesh.getDimension()); _derivedFactory->addSubfields(); derivedField->subfieldsSetup(); diff --git a/libsrc/pylith/materials/Poroelasticity.cc b/libsrc/pylith/materials/Poroelasticity.cc index f2270021a6..eab419a331 100644 --- a/libsrc/pylith/materials/Poroelasticity.cc +++ b/libsrc/pylith/materials/Poroelasticity.cc @@ -29,7 +29,7 @@ #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES typeid() @@ -214,17 +214,11 @@ pylith::materials::Poroelasticity::createAuxiliaryField(const pylith::topology:: assert(_rheology); pylith::materials::AuxiliaryFactoryPoroelasticity* auxiliaryFactory = _rheology->getAuxiliaryFactory();assert(auxiliaryFactory); - assert(_normalizer); - auxiliaryFactory->initialize(auxiliaryField, *_normalizer, domainMesh.getDimension()); + assert(_scales); + auxiliaryFactory->initialize(auxiliaryField, *_scales, domainMesh.getDimension()); // :ATTENTION: The order for adding subfields must match the order of the auxiliary fields in the FE kernels. - // :ATTENTION: In quasi-static problems, the time scale is usually quite large - // (order of tens to hundreds of years), which means that the density scale is very large, - // and the acceleration scale is very small. Nevertheless, density times gravitational - // acceleration will have a scale of pressure divided by length and should be within a few orders - // of magnitude of 1. - // --------------------------------- // Required Auxiliary auxiliaryFactory->addSolidDensity(); // 0 Rock Density @@ -235,13 +229,13 @@ pylith::materials::Poroelasticity::createAuxiliaryField(const pylith::topology:: // --------------------------------- // Optional Auxiliary if (_useBodyForce) { - auxiliaryFactory->addBodyForce(); // +1 + auxiliaryFactory->addBodyForce(); } // if if (_gravityField) { - auxiliaryFactory->addGravityField(_gravityField); // +1 + auxiliaryFactory->addGravityField(_gravityField); } // if if (_useSourceDensity) { - auxiliaryFactory->addSourceDensity(); // +1 + auxiliaryFactory->addSourceDensity(); } // if _rheology->addAuxiliarySubfields(); @@ -279,8 +273,8 @@ pylith::materials::Poroelasticity::createDerivedField(const pylith::topology::Fi pylith::topology::Field* derivedField = new pylith::topology::Field(domainMesh);assert(derivedField); derivedField->setLabel("derived field"); - assert(_normalizer); - _derivedFactory->initialize(derivedField, *_normalizer, domainMesh.getDimension()); + assert(_scales); + _derivedFactory->initialize(derivedField, *_scales, domainMesh.getDimension()); _derivedFactory->addSubfields(); derivedField->subfieldsSetup(); @@ -529,6 +523,8 @@ pylith::materials::Poroelasticity::_setKernelsJacobian(pylith::feassemble::Integ const spatialdata::geocoords::CoordSys* coordsys = solution.getMesh().getCoordSys(); std::vector kernels(7); + integrator->setLHSJacobianTriggers(pylith::feassemble::Integrator::NEW_JACOBIAN_TIME_STEP_CHANGE); + switch (_formulation) { case QUASISTATIC: { const EquationPart equationPart = pylith::feassemble::Integrator::LHS; @@ -705,8 +701,6 @@ pylith::materials::Poroelasticity::_setKernelsJacobian(pylith::feassemble::Integ PetscPointJacFn* Jf2vv = NULL; PetscPointJacFn* Jf3vv = NULL; - integrator->setLHSJacobianTriggers(pylith::feassemble::Integrator::NEW_JACOBIAN_TIME_STEP_CHANGE); - const EquationPart equationPart = pylith::feassemble::Integrator::LHS_LUMPED_INV; kernels[0] = JacobianKernels("displacement", "displacement", equationPart, Jf0uu, Jf1uu, Jf2uu, Jf3uu); kernels[1] = JacobianKernels("displacement", "pressure", equationPart, Jf0up, Jf1up, Jf2up, Jf3up); diff --git a/libsrc/pylith/materials/Query.cc b/libsrc/pylith/materials/Query.cc index 68797ac866..c4c63e8e62 100644 --- a/libsrc/pylith/materials/Query.cc +++ b/libsrc/pylith/materials/Query.cc @@ -17,7 +17,7 @@ #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN/END, PYLITH_ERROR_RETURN #include "pylith/utils/array.hh" // USES scalar_array, int_array #include "pylith/utils/types.hh" // USES PylithScalar -#include "pylith/utils/constdefs.h" // USES PYLITH_MAXSCALAR +#include "pylith/utils/constants.hh" // USES pylith::max_real #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField @@ -341,13 +341,13 @@ pylith::materials::_Query::vmToGeneralizedMaxwellTimes(PylithScalar valueSubfiel const PylithScalar shearModulus = density * vs * vs; const PylithScalar shearModulus1 = shearModulusRatio1 * shearModulus; - valueSubfield[0] = (shearModulus1 > 0.0) ? viscosity1 / shearModulus1 : PYLITH_MAXSCALAR; + valueSubfield[0] = (shearModulus1 > 0.0) ? viscosity1 / shearModulus1 : pylith::max_real; const PylithReal shearModulus2 = shearModulusRatio2 * shearModulus; - valueSubfield[1] = (shearModulus2 > 0.0) ? viscosity2 / shearModulus2 : PYLITH_MAXSCALAR; + valueSubfield[1] = (shearModulus2 > 0.0) ? viscosity2 / shearModulus2 : pylith::max_real; const PylithReal shearModulus3 = shearModulusRatio3 * shearModulus; - valueSubfield[2] = (shearModulus3 > 0.0) ? viscosity3 / shearModulus3 : PYLITH_MAXSCALAR; + valueSubfield[2] = (shearModulus3 > 0.0) ? viscosity3 / shearModulus3 : pylith::max_real; std::ostringstream msg; if (density <= 0) { @@ -491,8 +491,8 @@ pylith::materials::_Query::inputToBiotModulus(PylithScalar valueSubfield[], const PylithScalar biot_coefficient = dbValues[dbIndices[i_biot_coefficient]]; const PylithScalar porosity = dbValues[dbIndices[i_porosity]]; - const PylithScalar solid_bulk_modulus = drained_bulk_modulus / (1.0 - biot_coefficient); - PylithScalar biot_modulus = 1.0 / ( porosity / fluid_bulk_modulus + (biot_coefficient - porosity) / solid_bulk_modulus ); + const PylithScalar solid_bulk_modulus = (biot_coefficient < 1.0) ? drained_bulk_modulus / (1.0 - biot_coefficient) : pylith::max_real; + PylithScalar biot_modulus = fluid_bulk_modulus / ( porosity + (biot_coefficient - porosity) * fluid_bulk_modulus / solid_bulk_modulus); valueSubfield[0] = biot_modulus; std::ostringstream msg; @@ -505,7 +505,7 @@ pylith::materials::_Query::inputToBiotModulus(PylithScalar valueSubfield[], // Debug if (biot_modulus <= 0) { - msg << "biot modulus (" << biot_modulus << ") wrong. K_f: " << fluid_bulk_modulus << " Ksg: " << solid_bulk_modulus << " phi: " << porosity << " alpha: " << biot_coefficient; + msg << "Found negative Biot modulus (" << biot_modulus << "). K_f: " << fluid_bulk_modulus << " Ksg: " << solid_bulk_modulus << " phi: " << porosity << " alpha: " << biot_coefficient; } // if PYLITH_METHOD_RETURN(msg.str()); diff --git a/libsrc/pylith/meshio/MeshBuilder.cc b/libsrc/pylith/meshio/MeshBuilder.cc index 452668b6e1..35867aeded 100644 --- a/libsrc/pylith/meshio/MeshBuilder.cc +++ b/libsrc/pylith/meshio/MeshBuilder.cc @@ -20,7 +20,7 @@ #include "pylith/utils/error.hh" // USES PYLITH_CHECK_ERROR #include "pylith/utils/EventLogger.hh" // USES EventLogger -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "petscdmlabel.h" // USES PetscDMLabel diff --git a/libsrc/pylith/meshio/MeshIO.hh b/libsrc/pylith/meshio/MeshIO.hh index 1987812f0d..52b36ef864 100644 --- a/libsrc/pylith/meshio/MeshIO.hh +++ b/libsrc/pylith/meshio/MeshIO.hh @@ -16,7 +16,7 @@ #include "pylith/meshio/MeshBuilder.hh" // USES MeshBuilder::GroupPtType #include "pylith/topology/topologyfwd.hh" // forward declarations -#include "spatialdata/units/unitsfwd.hh" // forward declarations +#include "pylith/scales/scalesfwd.hh" // forward declarations #include "pylith/utils/arrayfwd.hh" // USES scalar_array, int_array, string_vector // ------------------------------------------------------------------------------------------------ diff --git a/libsrc/pylith/meshio/OutputObserver.cc b/libsrc/pylith/meshio/OutputObserver.cc index 25ae96a226..f1c6cfe9b1 100644 --- a/libsrc/pylith/meshio/OutputObserver.cc +++ b/libsrc/pylith/meshio/OutputObserver.cc @@ -20,7 +20,7 @@ #include "pylith/topology/Field.hh" // USES Field #include "pylith/topology/FieldOps.hh" // USES FieldOps -#include "pylith/utils/constdefs.h" // USES PYLITH_MAXSCALAR +#include "pylith/utils/constants.hh" // USES pylith::max_real #include "pylith/utils/error.hh" // USES PYLITH_METHOD_* #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* #include "pylith/utils/EventLogger.hh" // USES EventLogger diff --git a/libsrc/pylith/meshio/OutputSolnPoints.cc b/libsrc/pylith/meshio/OutputSolnPoints.cc index 5b9db5d9b9..1c3c68d301 100644 --- a/libsrc/pylith/meshio/OutputSolnPoints.cc +++ b/libsrc/pylith/meshio/OutputSolnPoints.cc @@ -28,7 +28,7 @@ #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys #include "spatialdata/geocoords/Converter.hh" // USES Converter -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES assert() diff --git a/libsrc/pylith/meshio/OutputTriggerStep.cc b/libsrc/pylith/meshio/OutputTriggerStep.cc index 4d4af610e6..364fdbf922 100644 --- a/libsrc/pylith/meshio/OutputTriggerStep.cc +++ b/libsrc/pylith/meshio/OutputTriggerStep.cc @@ -12,7 +12,7 @@ #include "pylith/meshio/OutputTriggerStep.hh" // Implementation of class methods -#include "pylith/utils/constdefs.h" // USES PYLITH_MAXSCALAR +#include "pylith/utils/constants.hh" // USES pylith::min_int #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN/END #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* @@ -20,7 +20,7 @@ // Constructor pylith::meshio::OutputTriggerStep::OutputTriggerStep(void) : _numStepsSkip(0), - _stepWrote(PYLITH_MININT+10) { // constructor + _stepWrote(pylith::min_int+10) { // constructor PyreComponent::setName("outputtriggerstep"); } // constructor diff --git a/libsrc/pylith/meshio/OutputTriggerTime.cc b/libsrc/pylith/meshio/OutputTriggerTime.cc index 25c0552ea4..93859ebed0 100644 --- a/libsrc/pylith/meshio/OutputTriggerTime.cc +++ b/libsrc/pylith/meshio/OutputTriggerTime.cc @@ -12,7 +12,7 @@ #include "pylith/meshio/OutputTriggerTime.hh" // Implementation of class methods -#include "pylith/utils/constdefs.h" // USES PYLITH_MAXSCALAR +#include "pylith/utils/constants.hh" // USES pylith::max_real #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN/END #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* @@ -20,7 +20,7 @@ // Constructor pylith::meshio::OutputTriggerTime::OutputTriggerTime(void) : _timeSkip(0.0), - _timeNondimWrote(-PYLITH_MAXSCALAR) { + _timeNondimWrote(-pylith::max_real) { PyreComponent::setName("outputtriggertime"); } // constructor diff --git a/libsrc/pylith/problems/GreensFns.cc b/libsrc/pylith/problems/GreensFns.cc index e4bbca4f3f..047f39c430 100644 --- a/libsrc/pylith/problems/GreensFns.cc +++ b/libsrc/pylith/problems/GreensFns.cc @@ -23,7 +23,7 @@ #include "pylith/problems/ProgressMonitorStep.hh" // USES ProgressMonitorStep #include "pylith/utils/PetscOptions.hh" // USES SolverDefaults -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "petscsnes.h" // USES PetscSNES @@ -346,7 +346,7 @@ pylith::problems::GreensFns::poststep(const size_t impulse, PYLITH_COMPONENT_DEBUG("poststep(impulse"<getTimeScale(); + const PetscReal t = impulse / _scales->getTimeScale(); const PetscReal dt = 1.0; const pylith::problems::Observer::NotificationType notification = pylith::problems::Observer::SOLUTION; @@ -372,7 +372,7 @@ pylith::problems::GreensFns::poststep(const size_t impulse, // Update number of impulses for monitor if (_monitor) { - assert(_normalizer); + assert(_scales); _monitor->update(impulse, 0, numImpulses); } // if diff --git a/libsrc/pylith/problems/InitialCondition.hh b/libsrc/pylith/problems/InitialCondition.hh index 186886871a..51043eb322 100644 --- a/libsrc/pylith/problems/InitialCondition.hh +++ b/libsrc/pylith/problems/InitialCondition.hh @@ -16,7 +16,7 @@ #include "pylith/utils/arrayfwd.hh" // USES string_vector #include "pylith/topology/topologyfwd.hh" // USES Field -#include "spatialdata/units/unitsfwd.hh" // HASA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HASA Scales class pylith::problems::InitialCondition : public pylith::utils::PyreComponent { friend class TestInitialCondition; // unit testing @@ -51,11 +51,11 @@ public: /** Set solution to values for initial condition. * * @param[out] solution Solution field. - * @param[in] normalizer Nondimensionalization. + * @param[in] scales Nondimensionalization. */ virtual void setValues(pylith::topology::Field* solution, - const spatialdata::units::Nondimensional& normalizer) = 0; + const pylith::scales::Scales& scales) = 0; // PROTECTED MEMBERS /////////////////////////////////////////////////////////////////////////////////////////////// protected: diff --git a/libsrc/pylith/problems/InitialConditionDomain.cc b/libsrc/pylith/problems/InitialConditionDomain.cc index 8c195ec28a..eabfd73fda 100644 --- a/libsrc/pylith/problems/InitialConditionDomain.cc +++ b/libsrc/pylith/problems/InitialConditionDomain.cc @@ -16,7 +16,7 @@ #include "pylith/topology/Field.hh" // USES Field #include "spatialdata/spatialdb/SpatialDB.hh" // USES SpatialDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_CHECK_ERROR #include "pylith/utils/journals.hh" // USES PYLITH_COMPONENT_* @@ -66,9 +66,9 @@ pylith::problems::InitialConditionDomain::setDB(spatialdata::spatialdb::SpatialD // Set solver type. void pylith::problems::InitialConditionDomain::setValues(pylith::topology::Field* solution, - const spatialdata::units::Nondimensional& normalizer) { + const pylith::scales::Scales& scales) { PYLITH_METHOD_BEGIN; - PYLITH_COMPONENT_DEBUG("setValues(solution="<registerObserver(observer); - _observers->setTimeScale(_normalizer->getTimeScale()); + _observers->setTimeScale(_scales->getTimeScale()); PYLITH_METHOD_END; } // registerObserver @@ -374,12 +374,12 @@ pylith::problems::Problem::preinitialize(const pylith::topology::Mesh& mesh) { PYLITH_COMPONENT_DEBUG("Problem::preinitialzie(mesh="<setNormalizer(*_normalizer); + _materials[i]->setScales(*_scales); _materials[i]->setGravityField(_gravityField); _materials[i]->setFormulation(_formulation); } // for @@ -387,14 +387,14 @@ pylith::problems::Problem::preinitialize(const pylith::topology::Mesh& mesh) { const size_t numInterfaces = _interfaces.size(); for (size_t i = 0; i < numInterfaces; ++i) { assert(_interfaces[i]); - _interfaces[i]->setNormalizer(*_normalizer); + _interfaces[i]->setScales(*_scales); _interfaces[i]->setFormulation(_formulation); } // for const size_t numBC = _bc.size(); for (size_t i = 0; i < numBC; ++i) { assert(_bc[i]); - _bc[i]->setNormalizer(*_normalizer); + _bc[i]->setScales(*_scales); _bc[i]->setFormulation(_formulation); } // for diff --git a/libsrc/pylith/problems/Problem.hh b/libsrc/pylith/problems/Problem.hh index e39a406b03..32f6ee9158 100644 --- a/libsrc/pylith/problems/Problem.hh +++ b/libsrc/pylith/problems/Problem.hh @@ -28,7 +28,7 @@ #include "spatialdata/spatialdb/spatialdbfwd.hh" // HASA GravityField #include "pylith/topology/topologyfwd.hh" // USES Mesh, Field -#include "spatialdata/units/unitsfwd.hh" // HASA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HASA Scales #include "pylith/utils/petscfwd.h" // USES PetscVec, PetscMat @@ -94,7 +94,7 @@ public: * * @param[in] dim Nondimensionalizer. */ - void setNormalizer(const spatialdata::units::Nondimensional& dim); + void setScales(const pylith::scales::Scales& dim); /** Set gravity field. * @@ -178,7 +178,7 @@ protected: pylith::feassemble::IntegrationData* _integrationData; /// > Data needed to integrate PDE. - spatialdata::units::Nondimensional* _normalizer; ///< Nondimensionalization of scales. + pylith::scales::Scales* _scales; ///< Nondimensionalization of scales. spatialdata::spatialdb::GravityField* _gravityField; ///< Gravity field. std::vector _materials; ///< Array of materials. diff --git a/libsrc/pylith/problems/SolutionFactory.cc b/libsrc/pylith/problems/SolutionFactory.cc index bc9b2bbfd2..9c5c04288c 100644 --- a/libsrc/pylith/problems/SolutionFactory.cc +++ b/libsrc/pylith/problems/SolutionFactory.cc @@ -20,7 +20,8 @@ #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "spatialdata/spatialdb/SpatialDB.hh" // USES SpatialDB #include // USES "<getMesh(); err = TSCreate(mesh.getComm(), &_ts);PYLITH_CHECK_ERROR(err);assert(_ts); - err = TSSetType(_ts, TSBEULER);PYLITH_CHECK_ERROR(err); // Backward Euler is default time stepping method. + // err = TSSetType(_ts, TSBEULER);PYLITH_CHECK_ERROR(err); // Backward Euler is default time stepping method. err = TSSetExactFinalTime(_ts, TS_EXACTFINALTIME_STEPOVER);PYLITH_CHECK_ERROR(err); // Ok to step over final time. err = TSSetApplicationContext(_ts, (void*)this);PYLITH_CHECK_ERROR(err); @@ -376,8 +377,8 @@ pylith::problems::TimeDependent::initialize(void) { <<", maxTimeSteps="<<_maxTimeSteps <<", endTime="<<_endTime); - assert(_normalizer); - const PylithReal timeScale = _normalizer->getTimeScale(); + assert(_scales); + const PylithReal timeScale = _scales->getTimeScale(); err = TSSetTime(_ts, _startTime / timeScale);PYLITH_CHECK_ERROR(err); err = TSSetTimeStep(_ts, _dtInitial / timeScale);PYLITH_CHECK_ERROR(err); err = TSSetMaxSteps(_ts, _maxTimeSteps);PYLITH_CHECK_ERROR(err); @@ -390,7 +391,7 @@ pylith::problems::TimeDependent::initialize(void) { const size_t numIC = _ic.size(); for (size_t i = 0; i < numIC; ++i) { assert(_ic[i]); - _ic[i]->setValues(solution, *_normalizer); + _ic[i]->setValues(solution, *_scales); } // for PetscVec solutionVector = solution->getGlobalVector(); solution->scatterLocalToVector(solutionVector); @@ -441,19 +442,11 @@ pylith::problems::TimeDependent::initialize(void) { } // switch err = TSSetFromOptions(_ts);PYLITH_CHECK_ERROR(err); + if (_petscDefaults & pylith::utils::PetscDefaults::TS_ADAPT) { + pylith::utils::TSAdaptImpulse::set(_ts); + } // if err = TSSetUp(_ts);PYLITH_CHECK_ERROR(err); -#if 0 - // Set solve type for solution fields defined over the domain (not Lagrange multipliers). - PetscDS dsSoln = NULL; - err = DMGetDS(solution->getDM(), &dsSoln);PYLITH_CHECK_ERROR(err); - PetscInt numFields = 0; - err = PetscDSGetNumFields(dsSoln, &numFields);PYLITH_CHECK_ERROR(err); - for (PetscInt iField = 0; iField < numFields; ++iField) { - err = PetscDSSetImplicit(dsSoln, iField, (_formulation == pylith::problems::Physics::QUASISTATIC) ? PETSC_TRUE : PETSC_FALSE); - } // for -#endif - pythia::journal::debug_t debug(pylith::utils::PyreComponent::getName()); if (debug.state()) { PetscDS prob = NULL; @@ -533,8 +526,8 @@ pylith::problems::TimeDependent::poststep(void) { _observers->notifyObservers(t, tindex, *solution, notification); if (_monitor) { - assert(_normalizer); - const PylithReal timeScale = _normalizer->getTimeScale(); + assert(_scales); + const PylithReal timeScale = _scales->getTimeScale(); _monitor->update(t*timeScale, _startTime, _endTime); } // if @@ -962,8 +955,8 @@ pylith::problems::TimeDependent::_notifyObserversInitialSoln(void) { PYLITH_METHOD_BEGIN; PYLITH_COMPONENT_DEBUG("_notifyObserversInitialSoln()"); - assert(_normalizer); - const PylithReal timeScale = _normalizer->getTimeScale(); + assert(_scales); + const PylithReal timeScale = _scales->getTimeScale(); const PylithReal tStartNondim = _startTime / timeScale; const PylithInt tindex = 0; const pylith::problems::Observer::NotificationType notification = pylith::problems::Observer::SOLUTION; diff --git a/libsrc/pylith/scales/ElasticityScales.cc b/libsrc/pylith/scales/ElasticityScales.cc new file mode 100644 index 0000000000..a818a3115a --- /dev/null +++ b/libsrc/pylith/scales/ElasticityScales.cc @@ -0,0 +1,170 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= + +#include + +#include "ElasticityScales.hh" // implementation of class methods + +#include "Scales.hh" // USES Scales + +// ------------------------------------------------------------------------------------------------ +// Set defaults scales for quasi-static elasticity. +void +pylith::scales::ElasticityScales::setQuasistaticElasticity(pylith::scales::Scales* scales, + const double lengthScale, + const double timeScale) { + const double length = lengthScale; + const double displacement = 1.0; + const double rigidity = 2.5e+10; + + scales->setLengthScale(length); + scales->setDisplacementScale(displacement); + scales->setRigidityScale(rigidity); + scales->setTimeScale(timeScale); +} + + +// ------------------------------------------------------------------------------------------------ +// Set defaults scales for dynamic elasticity. +void +pylith::scales::ElasticityScales::setDynamicElasticity(pylith::scales::Scales* scales, + const double lengthScale, + const double velocityScale) { + const double displacement = 1.0; + const double rigidity = 2.25e+10; + const double time = lengthScale / velocityScale; + + scales->setLengthScale(lengthScale); + scales->setDisplacementScale(displacement); + scales->setRigidityScale(rigidity); + scales->setTimeScale(time); +} + + +// ------------------------------------------------------------------------------------------------ +// Set defaults scales for quasi-static poroelasticity. +void +pylith::scales::ElasticityScales::setQuasistaticPoroelasticity(pylith::scales::Scales* scales, + const double lengthScale, + const double permeability, + const double viscosity, + const double rigidity) { + const double length = lengthScale; + const double displacement = 1.0; + const double time = computePoroelasticityTimeScale(viscosity, permeability, length, rigidity); + + scales->setLengthScale(length); + scales->setDisplacementScale(displacement); + scales->setRigidityScale(rigidity); + scales->setTimeScale(time); +} + + +// ------------------------------------------------------------------------------------------------ +// Compute time scale for poroelasticity. +double +pylith::scales::ElasticityScales::computePoroelasticityTimeScale(const double viscosity, + const double permeability, + const double length, + const double rigidity) { + return (viscosity / permeability) * (length * length / rigidity); +} // computePoroelasticityTimeScale + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize stress. +double +pylith::scales::ElasticityScales::getStressScale(const pylith::scales::Scales& scales) { + const double rigidity = scales.getRigidityScale(); + const double displacement = scales.getDisplacementScale(); + const double length = scales.getLengthScale(); + return rigidity * displacement / length; +} + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize pressure. +double +pylith::scales::ElasticityScales::getFluidPressureScale(const pylith::scales::Scales& scales) { + return getStressScale(scales); +} + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize strain. +double +pylith::scales::ElasticityScales::getStrainScale(const pylith::scales::Scales& scales) { + const double displacement = scales.getDisplacementScale(); + const double length = scales.getLengthScale(); + return displacement / length; +} + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize body force. +double +pylith::scales::ElasticityScales::getBodyForceScale(const pylith::scales::Scales& scales) { + const double stress = getStressScale(scales); + const double length = scales.getLengthScale(); + return stress / length; +} + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize density. +double +pylith::scales::ElasticityScales::getDensityScale(const pylith::scales::Scales& scales) { + const double rigidity = scales.getRigidityScale(); + const double length = scales.getLengthScale(); + const double time = scales.getTimeScale(); + return (rigidity * time * time) / (length * length); +} + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize velocity. +double +pylith::scales::ElasticityScales::getVelocityScale(const pylith::scales::Scales& scales) { + const double time = scales.getTimeScale(); + const double displacement = scales.getDisplacementScale(); + return displacement / time; +} + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize acceleration. +double +pylith::scales::ElasticityScales::getAccelerationScale(const pylith::scales::Scales& scales) { + const double time = scales.getTimeScale(); + const double displacement = scales.getDisplacementScale(); + return displacement / (time * time); +} + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize viscosity. +double +pylith::scales::ElasticityScales::getViscosityScale(const pylith::scales::Scales& scales) { + const double rigidityScale = scales.getRigidityScale(); + const double time = scales.getTimeScale(); + return rigidityScale * time; +} + + +// ------------------------------------------------------------------------------------------------ +// Get value to nondimensionalize permability. +double +pylith::scales::ElasticityScales::getPermeabilityScale(const pylith::scales::Scales& scales) { + const double length = scales.getLengthScale(); + return length * length; +} + + +// End of file diff --git a/libsrc/pylith/scales/ElasticityScales.hh b/libsrc/pylith/scales/ElasticityScales.hh new file mode 100644 index 0000000000..e94e96a267 --- /dev/null +++ b/libsrc/pylith/scales/ElasticityScales.hh @@ -0,0 +1,150 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= +#pragma once + +#include "scalesfwd.hh" + +/// C++ object for scales related to elasticity. +class pylith::scales::ElasticityScales { + friend class TestElasticityScales; // Unit testing + +public: + + // PUBLIC METHODS ///////////////////////////////////////////////////// + + /** Set defaults scales for quasi-static elasticity. + * + * @param[inout] Scales for nondimensionalization. + * @param[in] lengthScale Default length scale in meters. + * @param[in] timeScale Default time scale in seconds. + * + */ + static + void setQuasistaticElasticity(pylith::scales::Scales* scales, + const double lengthScale=100.0e+3, + const double timeScale=31557600.0e+2); + + /** Set defaults scales for dynamic elasticity. + * + * @param[inout] Scales for nondimensionalization. + * @param[in] lengthScale Default length scale in meters. + * @param[in] velocityScale Default velocity scale in m/s. + * + */ + static + void setDynamicElasticity(pylith::scales::Scales* scales, + const double lengthScale=100.0e+3, + const double velocityScale=3.0e+3); + + /** Set defaults scales for quasi-static poroelasticity. + * + * @param[inout] Scales for nondimensionalization. + * @param[in] lengthScale Default length scale in meters. + * @param[in] permeability Default permeability scale in m^2. + * @param[in] viscosity Default viscosity scale in Pa*s. + * @param[in] rigidity Default rigidity scale in Pa. + */ + static + void setQuasistaticPoroelasticity(pylith::scales::Scales* scales, + const double lengthScale=100.0e+3, + const double permeability=1.0e-12, + const double viscosity=1.0e-3, + const double rigidity=25.0e+9); + + /** Set time scale for poroelasticity. + * + * @param[in] lengthScale Default length scale in meters. + * @param[in] permeability Default permeability scale in m^2. + * @param[in] viscosity Default viscosity scale in Pa*s. + * @param[in] rigidity Default rigidity scale in Pa. + * + * @returns Time scale in seconds. + */ + static + double computePoroelasticityTimeScale(const double viscosity, + const double permeability, + const double length, + const double rigidity); + + /** Get value to nondimensionalize stress. + * + * @param[in] Scales for nondimensionalization. + * @returns Stress scale in Pa (SI units). + */ + static + double getStressScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize pressure. + * + * @param[in] Scales for nondimensionalization. + * @returns Fluid pressure scale in Pascals (SI units). + */ + static + double getFluidPressureScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize strain. + * + * @param[in] Scales for nondimensionalization. + * @returns Strain scale. + */ + static + double getStrainScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize body force. + * + * @param[in] Scales for nondimensionalization. + * @returns Body force scale in Pa/m (SI units). + */ + static + double getBodyForceScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize density. + * + * @param[in] Scales for nondimensionalization. + * @returns Density scale in kg/m^3 (SI units). + */ + static + double getDensityScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize velocity. + * + * @param[in] Scales for nondimensionalization. + * @returns Velocity scale in m/s (SI units). + */ + static + double getVelocityScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize acceleration. + * + * @param[in] Scales for nondimensionalization. + * @returns Acceleration scale in m/s^2 (SI units). + */ + static + double getAccelerationScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize fluid viscosity. + * + * @param[in] Scales for nondimensionalization. + * @returns Fluid viscosity scale in Pa*s (SI units). + */ + static + double getViscosityScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize permeability. + * + * @param[in] Scales for nondimensionalization. + * @returns Permeability scale in m/s^2 (SI units). + */ + static + double getPermeabilityScale(const pylith::scales::Scales& scales); + +}; // class ElasticityScales + +// End of file diff --git a/libsrc/pylith/scales/Makefile.am b/libsrc/pylith/scales/Makefile.am new file mode 100644 index 0000000000..c1c51046f6 --- /dev/null +++ b/libsrc/pylith/scales/Makefile.am @@ -0,0 +1,23 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +subpackage = scales +include $(top_srcdir)/subpackage.am + +subpkginclude_HEADERS = \ + Scales.hh \ + Scales.icc \ + ElasticityScales.hh \ + scalesfwd.hh + +noinst_HEADERS = + + +# End of file diff --git a/libsrc/pylith/scales/Scales.cc b/libsrc/pylith/scales/Scales.cc new file mode 100644 index 0000000000..d7bc0ee411 --- /dev/null +++ b/libsrc/pylith/scales/Scales.cc @@ -0,0 +1,125 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= + +#include + +#include "Scales.hh" // implementation of class methods + +#include // USES std::ostringstream +#include // USES std::runtime_error +#include // USES assert() + +// ---------------------------------------------------------------------- +// Default constructor +pylith::scales::Scales::Scales(void) : + _length(1.0), + _displacement(1.0), + _rigidity(1.0), + _time(1.0), + _temperature(1.0) {} + + +// ---------------------------------------------------------------------- +// Default destructor +pylith::scales::Scales::~Scales(void) {} + + +// ---------------------------------------------------------------------- +// Copy constructor. +pylith::scales::Scales::Scales(const Scales& dim) : + _length(dim._length), + _displacement(dim._displacement), + _rigidity(dim._rigidity), + _time(dim._time), + _temperature(dim._temperature) {} + + +// ---------------------------------------------------------------------- +// Assignment operator. +const pylith::scales::Scales& +pylith::scales::Scales::operator=(const Scales& dim) { + if (this != &dim) { + _length = dim._length; + _displacement = dim._displacement; + _rigidity = dim._rigidity; + _time = dim._time; + _temperature = dim._temperature; + } // if + + return *this; +} // operator= + + +// ---------------------------------------------------------------------- +// Set value to nondimensionalize position. +void +pylith::scales::Scales::setLengthScale(const double value) { + if (value <= 0.0) { + std::ostringstream msg; + msg << "Length scale (" << value << ") must be positive."; + throw std::invalid_argument(msg.str()); + } // if + _length = value; +} // setLengthScale + + +// ---------------------------------------------------------------------- +// Set value to nondimensionalize displacement. +void +pylith::scales::Scales::setDisplacementScale(const double value) { + if (value <= 0.0) { + std::ostringstream msg; + msg << "Displacement scale (" << value << ") must be positive."; + throw std::invalid_argument(msg.str()); + } // if + _displacement = value; +} // setDisplacementScale + + +// ---------------------------------------------------------------------- +// Set value to nondimensionalize rigidity (elastic moduli). +void +pylith::scales::Scales::setRigidityScale(const double value) { + if (value <= 0.0) { + std::ostringstream msg; + msg << "Rigidity scale (" << value << ") must be positive."; + throw std::invalid_argument(msg.str()); + } // if + _rigidity = value; +} // setRigidityScale + + +// ---------------------------------------------------------------------- +// Set value to nondimensionalize time scale in seconds (SI units). +void +pylith::scales::Scales::setTimeScale(const double value) { + if (value <= 0.0) { + std::ostringstream msg; + msg << "Time scale (" << value << ") must be positive."; + throw std::invalid_argument(msg.str()); + } // if + _time = value; +} // setTimeScale + + +// ---------------------------------------------------------------------- +// Set value to nondimensionalize temperature scale in Kelvin (SI units). +void +pylith::scales::Scales::setTemperatureScale(const double value) { + if (value <= 0.0) { + std::ostringstream msg; + msg << "Temperature scale (" << value << ") must be positive."; + throw std::invalid_argument(msg.str()); + } // if + _temperature = value; +} // setTemperatureScale + + +// End of file diff --git a/libsrc/pylith/scales/Scales.hh b/libsrc/pylith/scales/Scales.hh new file mode 100644 index 0000000000..cf1faeceaa --- /dev/null +++ b/libsrc/pylith/scales/Scales.hh @@ -0,0 +1,175 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= +#pragma once + +#include "scalesfwd.hh" + +#include // USES size_t + +/// C++ object for managing parameters for nondimensionalization. +class pylith::scales::Scales { + friend class TestScales; // Unit testing + +public: + + // PUBLIC METHODS ///////////////////////////////////////////////////// + + /// Default constructor + Scales(void); + + /// Default destructor + ~Scales(void); + + /** Copy constructor. + * + * @param dim Object to copy. + */ + Scales(const Scales& dim); + + /** Assignment operator. + * + * @param dim Object to copy. + * @returns Copy of this. + */ + const Scales& operator = (const Scales& dim); + + /** Set value to nondimensionalize position. + * + * @param value Length scale in meters (SI units). + */ + void setLengthScale(const double value); + + /** Get value to nondimensionalize position. + * + * @returns Length scale in meters (SI units). + */ + double getLengthScale(void) const; + + /** Set value to nondimensionalize displacement. + * + * @param value Displacement scale in meters (SI units). + */ + void setDisplacementScale(const double value); + + /** Get value to nondimensionalize displacement. + * + * @returns Displacement scale in meters (SI units). + */ + double getDisplacementScale(void) const; + + /** Set value to nondimensionalize rigidity (e.g., elastic moduli). + * + * @param value Rigidity scale in Pascals (SI units). + */ + void setRigidityScale(const double value); + + /** Get value to nondimensionalize rigidity (e.g., elastic moduli). + * + * @returns Rigidity scale in Pascals (SI units). + */ + double getRigidityScale(void) const; + + /** Set value to nondimensionalize time. + * + * @param value Time scale in seconds (SI units). + */ + void setTimeScale(const double value); + + /** Get value to nondimensionalize time. + * + * @returns Time scale in seconds (SI units). + */ + double getTimeScale(void) const; + + /** Set value to nondimensionalize temperature. + * + * @param value Temperature scale in Kelvin (SI units). + */ + void setTemperatureScale(const double value); + + /** Get value to nondimensionalize temperature. + * + * @returns Temperature scale in Kelvin (SI units). + */ + double getTemperatureScale(void) const; + + /** Make value dimensionless. + * + * @param value Value with dimensions in SI units. + * @param scale Scale used to nondimensionalize value. + * @returns Dimensionless value. + */ + double nondimensionalize(const double value, + const double scale) const; + + /** Make value dimensionless. + * + * @param value Dimensionless value. + * @param value Value with dimensions in SI units. + * @returns Scale used to nondimensionalize value. + */ + double dimensionalize(const double value, + const double scale) const; + + /** Make values dimensionless. + * + * @param values Array of values with dimensions in SI units. + * @param nvalues Number of values. + * @param scale Scale used to nondimensionalize value. + */ + void nondimensionalize(double* const values, + const size_t nvalues, + const double scale) const; + + /** Make values dimensionless. + * + * @param values Array of values with dimensions in SI units. + * @param nvalues Number of values. + * @param scale Scale used to nondimensionalize value. + */ + void nondimensionalize(float* const values, + const size_t nvalues, + const double scale) const; + + /** Make value dimensionless. + * + * @param values Array of dimensionless values. + * @param nvalues Number of values. + * @param scale Scale used to nondimensionalize value. + */ + void dimensionalize(double* const values, + const size_t nvalues, + const double scale) const; + + /** Make value dimensionless. + * + * @param values Array of dimensionless values. + * @param nvalues Number of values. + * @param scale Scale used to nondimensionalize value. + */ + void dimensionalize(float* const values, + const size_t nvalues, + const double scale) const; + +private: + + // PRIVATE MEMBERS //////////////////////////////////////////////////// + + double _length; ///< Length scale + double _displacement; ///< Displacement scale + double _rigidity; ///< Rigidity scale + double _time; ///< Time scale + double _temperature; ///< Temperature scale + +}; // class Scales + +#include "Scales.icc" // inline methods + +// End of file diff --git a/libsrc/pylith/scales/Scales.icc b/libsrc/pylith/scales/Scales.icc new file mode 100644 index 0000000000..352b614f31 --- /dev/null +++ b/libsrc/pylith/scales/Scales.icc @@ -0,0 +1,132 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= +#pragma once + +#include // USES assert() + +// Get value to nondimensionalize position in meters (SI units). +inline +double +pylith::scales::Scales::getLengthScale(void) const { + return _length; +} + + +// Get value to nondimensionalize displacement in meters (SI units). +inline +double +pylith::scales::Scales::getDisplacementScale(void) const { + return _displacement; +} + + +// Get value to nondimensionalize rigidity (elastic moduli). +inline +double +pylith::scales::Scales::getRigidityScale(void) const { + return _rigidity; +} + + +// Get value to nondimensionalize time scale in seconds (SI units). +inline +double +pylith::scales::Scales::getTimeScale(void) const { + return _time; +} + + +// Get value to nondimensionalize temperature scale in Kelvin (SI units). +inline +double +pylith::scales::Scales::getTemperatureScale(void) const { + return _temperature; +} + + +// Make value dimensionless. +inline +double +pylith::scales::Scales::nondimensionalize(const double value, + const double scale) const { + return value / scale; +} + + +// Make values dimensionless. +inline +void +pylith::scales::Scales::nondimensionalize(double* const values, + const size_t nvalues, + const double scale) const { + assert( (0 < nvalues && values) || + (0 == nvalues && !values) ); + + for (size_t i = 0; i < nvalues; ++i) { + values[i] /= scale; + } +} // nondimensionalize + + +// Make values dimensionless. +inline +void +pylith::scales::Scales::nondimensionalize(float* const values, + const size_t nvalues, + const double scale) const { + assert( (0 < nvalues && values) || + (0 == nvalues && !values) ); + + for (size_t i = 0; i < nvalues; ++i) { + values[i] /= scale; + } +} // nondimensionalize + + +// Make value dimensionless. +inline +double +pylith::scales::Scales::dimensionalize(const double value, + const double scale) const { + return value * scale; +} + + +// Make value dimensionless. +inline +void +pylith::scales::Scales::dimensionalize(double* const values, + const size_t nvalues, + const double scale) const { + assert( (0 < nvalues && values) || + (0 == nvalues && !values) ); + + for (size_t i = 0; i < nvalues; ++i) { + values[i] *= scale; + } +} // dimensionalize + + +// Make value dimensionless. +inline +void +pylith::scales::Scales::dimensionalize(float* const values, + const size_t nvalues, + const double scale) const { + assert( (0 < nvalues && values) || + (0 == nvalues && !values) ); + + for (size_t i = 0; i < nvalues; ++i) { + values[i] *= scale; + } +} // dimensionalize + + +// End of file diff --git a/libsrc/pylith/scales/scalesfwd.hh b/libsrc/pylith/scales/scalesfwd.hh new file mode 100644 index 0000000000..b290651d4b --- /dev/null +++ b/libsrc/pylith/scales/scalesfwd.hh @@ -0,0 +1,20 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= +#pragma once + +namespace pylith { + namespace scales { + class Scales; + class ElasticityScales; + class PoroelasticityScales; + } // units +} // spatialdata + +// End of file diff --git a/libsrc/pylith/topology/FieldFactory.cc b/libsrc/pylith/topology/FieldFactory.cc index 7e444bcc63..c954dda40b 100644 --- a/libsrc/pylith/topology/FieldFactory.cc +++ b/libsrc/pylith/topology/FieldFactory.cc @@ -14,7 +14,7 @@ #include "pylith/topology/Field.hh" // HOLDSA AuxiliaryField -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* @@ -26,7 +26,7 @@ pylith::topology::FieldFactory::FieldFactory(void) : _field(NULL), _defaultDescription(NULL), - _normalizer(new spatialdata::units::Nondimensional), + _scales(new pylith::scales::Scales), _spaceDim(0) { GenericComponent::setName("auxiliaryfactory"); _subfieldDiscretizations["default"] = pylith::topology::FieldBase::Discretization(); @@ -39,7 +39,7 @@ pylith::topology::FieldFactory::~FieldFactory(void) { _field = NULL; // :TODO: use shared pointer delete _defaultDescription;_defaultDescription = NULL; - delete _normalizer;_normalizer = NULL; + delete _scales;_scales = NULL; } // destructor @@ -105,11 +105,11 @@ pylith::topology::FieldFactory::getSubfieldDiscretization(const char* subfieldNa // Initialie factory for setting up auxiliary subfields. void pylith::topology::FieldFactory::initialize(pylith::topology::Field* field, - const spatialdata::units::Nondimensional& normalizer, + const pylith::scales::Scales& scales, const int spaceDim, const pylith::topology::FieldBase::Description* defaultDescription) { PYLITH_METHOD_BEGIN; - PYLITH_JOURNAL_DEBUG("initialize(field="<converter) { - const std::string& invalidMsg = queryctx->converter(values, nvalues, queryctx->queryValues, queryctx->queryIndices); + const std::string& invalidMsg = queryctx->converter(values, numValues, queryctx->queryValues, queryctx->queryIndices); if (invalidMsg.length() > 0) { std::ostringstream msg; msg << "Error converting spatial database values for " << queryctx->description << " at ("; @@ -334,14 +334,14 @@ pylith::topology::FieldQuery::queryDBPointFn(PylithInt dim, PYLITH_ERROR_RETURN(PETSC_COMM_SELF, PETSC_ERR_LIB, msg.str().c_str()); } } else { - for (PylithInt i = 0; i < nvalues; ++i) { + for (PylithInt i = 0; i < numValues; ++i) { values[i] = queryctx->queryValues[queryctx->queryIndices[i]]; } // for } // if/else // Validate subfield values if validator function was specified. if (queryctx->validator) { - for (PylithInt i = 0; i < nvalues; ++i) { + for (PylithInt i = 0; i < numValues; ++i) { const std::string& invalidMsg = queryctx->validator(values[i], queryctx->valueScale, queryctx->validatorTolerance); if (invalidMsg.length() > 0) { std::ostringstream msg; @@ -359,7 +359,7 @@ pylith::topology::FieldQuery::queryDBPointFn(PylithInt dim, // Nondimensionalize values assert(queryctx->valueScale > 0); - for (int i = 0; i < nvalues; ++i) { + for (int i = 0; i < numValues; ++i) { values[i] /= queryctx->valueScale; } // for diff --git a/libsrc/pylith/topology/FieldQuery.hh b/libsrc/pylith/topology/FieldQuery.hh index bc5a9a85e7..2f466a2d2f 100644 --- a/libsrc/pylith/topology/FieldQuery.hh +++ b/libsrc/pylith/topology/FieldQuery.hh @@ -44,7 +44,7 @@ public: /** Function prototype for converter functions. * * @param[out] values Values for subfield. - * @param[in] nvalues Number of values for subfield. + * @param[in] numValues Number of values for subfield. * @param[in] Array of values from spatial database query. * @param[in] Indices of values from spatial database to use for computing subfield values. */ @@ -123,7 +123,7 @@ public: * @param[in] dim Spatial dimension. * @param[in] t Current time. * @param[in] x Coordinates (nondimensioned) of point location for query. - * @param[in] nvalues Size of values array. + * @param[in] numValues Size of values array. * @param[out] values Array of values to be returned. * @param[in] context Query context. * @returns PETSc error code (0 for success). @@ -132,7 +132,7 @@ public: PetscErrorCode queryDBPointFn(PylithInt dim, PylithReal t, const PylithReal x[], - PylithInt nvalues, + PylithInt numValues, PylithScalar* values, void* context); diff --git a/libsrc/pylith/topology/MeshOps.cc b/libsrc/pylith/topology/MeshOps.cc index 64901eec20..fe1cfa7642 100644 --- a/libsrc/pylith/topology/MeshOps.cc +++ b/libsrc/pylith/topology/MeshOps.cc @@ -19,7 +19,7 @@ #include "pylith/utils/journals.hh" // USES PYLITH_JOURNAL* #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES std::runtime_error #include // USES std::ostringstream @@ -28,7 +28,6 @@ #include // USES std::sort, std::find #include // USES std::map -// --------------------------------------------------------------------------------------------------------------------- namespace pylith { namespace topology { class _MeshOps { @@ -90,7 +89,7 @@ pylith::topology::_MeshOps::Events::init(void) { } -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Create subdomain mesh using label. pylith::topology::Mesh* pylith::topology::MeshOps::createSubdomainMesh(const pylith::topology::Mesh& mesh, @@ -161,7 +160,7 @@ pylith::topology::MeshOps::createSubdomainMesh(const pylith::topology::Mesh& mes } // createSubdomainMesh -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Create lower dimension mesh using label. pylith::topology::Mesh* pylith::topology::MeshOps::createLowerDimMesh(const pylith::topology::Mesh& mesh, @@ -283,7 +282,7 @@ pylith::topology::MeshOps::createLowerDimMesh(const pylith::topology::Mesh& mesh } // createLowerDimMesh -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Create 0-dimension mesh from points. pylith::topology::Mesh* pylith::topology::MeshOps::createFromPoints(const PylithReal* points, @@ -340,11 +339,11 @@ pylith::topology::MeshOps::createFromPoints(const PylithReal* points, } // createFromPoints -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Nondimensionalize the finite-element mesh. void pylith::topology::MeshOps::nondimensionalize(Mesh* const mesh, - const spatialdata::units::Nondimensional& normalizer) { + const pylith::scales::Scales& scales) { PYLITH_METHOD_BEGIN; _MeshOps::Events::init(); _MeshOps::Events::logger.eventBegin(_MeshOps::Events::nondimensionalize); @@ -352,7 +351,7 @@ pylith::topology::MeshOps::nondimensionalize(Mesh* const mesh, assert(mesh); PetscVec coordVec = NULL; - const PylithScalar lengthScale = normalizer.getLengthScale(); + const PylithScalar lengthScale = scales.getLengthScale(); PetscErrorCode err = 0; PetscDM dmMesh = mesh->getDM();assert(dmMesh); @@ -362,34 +361,25 @@ pylith::topology::MeshOps::nondimensionalize(Mesh* const mesh, err = DMViewFromOptions(dmMesh, NULL, "-pylith_nondim_dm_view");PYLITH_CHECK_ERROR(err); const PetscInt dim = mesh->getDimension(); - if (dim < 1) { - PYLITH_METHOD_END; + if (dim >= 1) { + const PylithReal avgDomainDim = computeAvgDomainDim(*mesh); + const PylithReal avgDimTolerance = 0.01; + if (avgDomainDim < avgDimTolerance) { + std::ostringstream msg; + msg << "Average domain dimension (" << avgDomainDim << ") is less than minimum tolerance (" + << avgDimTolerance << "). This usually means the length scale (" << lengthScale << ") used in the " + << "nondimensionalization needs to be smaller. The length scale should be on the order of the size " + << "of the features controlling the displacement variations (fault length or domain size)."; + throw std::runtime_error(msg.str()); + } // if/else } // if - PylithReal coordMin[3]; - PylithReal coordMax[3]; - err = DMGetBoundingBox(dmMesh, coordMin, coordMax); - PylithReal volume = 1.0; - for (int i = 0; i < dim; ++i) { - volume *= coordMax[i] - coordMin[i]; - } // for - assert(dim > 0); - const PylithReal avgCellDim = pow(volume / MeshOps::getNumCells(*mesh), 1.0/dim); - const PylithReal avgDimTolerance = 0.02; - if (avgCellDim < avgDimTolerance) { - std::ostringstream msg; - msg << "Nondimensional average cell dimension (" << avgCellDim << ") is less than minimum tolerance (" - << avgDimTolerance << "). This usually means the length scale (" << lengthScale << ") used in the " - << "nondimensionalization needs to be smaller. Based on the average cell size, a value of about " - << pow(10, int(log10(avgCellDim*lengthScale))) << " should be appropriate."; - throw std::runtime_error(msg.str()); - } // if/else _MeshOps::Events::logger.eventEnd(_MeshOps::Events::nondimensionalize); PYLITH_METHOD_END; } // nondimensionalize -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Strip out "ghost" cells hanging off mesh PetscDM pylith::topology::MeshOps::removeHangingCells(const PetscDM& dmMesh) { @@ -442,7 +432,7 @@ pylith::topology::MeshOps::removeHangingCells(const PetscDM& dmMesh) { } -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Check topology of mesh. void pylith::topology::MeshOps::checkTopology(const Mesh& mesh) { @@ -484,7 +474,7 @@ pylith::topology::MeshOps::checkTopology(const Mesh& mesh) { } // checkTopology -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ bool pylith::topology::MeshOps::isSimplexMesh(const Mesh& mesh) { PYLITH_METHOD_BEGIN; @@ -523,7 +513,7 @@ pylith::topology::MeshOps::isSimplexMesh(const Mesh& mesh) { } // isSimplexMesh -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ bool pylith::topology::MeshOps::isCohesiveCell(const PetscDM dm, const PetscInt cell) { @@ -539,7 +529,7 @@ pylith::topology::MeshOps::isCohesiveCell(const PetscDM dm, } // isCohesiveCell -// ---------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Get number of vertices in mesh. PylithInt pylith::topology::MeshOps::getNumVertices(const pylith::topology::Mesh& mesh) { @@ -555,7 +545,7 @@ pylith::topology::MeshOps::getNumVertices(const pylith::topology::Mesh& mesh) { } -// ---------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Get number of cells in mesh. PylithInt pylith::topology::MeshOps::getNumCells(const pylith::topology::Mesh& mesh) { @@ -572,7 +562,7 @@ pylith::topology::MeshOps::getNumCells(const pylith::topology::Mesh& mesh) { } -// ---------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ // Get number of vertices in a cell. PylithInt pylith::topology::MeshOps::getNumCorners(const pylith::topology::Mesh& mesh) { @@ -598,7 +588,36 @@ pylith::topology::MeshOps::getNumCorners(const pylith::topology::Mesh& mesh) { } -// --------------------------------------------------------------------------------------------------------------------- +// ------------------------------------------------------------------------------------------------ +/** Compute nominal dimension of domain based on mesh bounding box. + * + * @param[in] mesh Finite-element mesh. + * @returns Average cell size. + */ +PylithReal +pylith::topology::MeshOps::computeAvgDomainDim(const pylith::topology::Mesh& mesh) { + PYLITH_METHOD_BEGIN; + const PetscInt dim = mesh.getDimension(); + if (dim < 1) { + PYLITH_METHOD_RETURN(0.0); + } // if + PylithReal coordMin[3]; + PylithReal coordMax[3]; + + PetscErrorCode err = PETSC_SUCCESS; + err = DMGetBoundingBox(mesh.getDM(), coordMin, coordMax);PYLITH_CHECK_ERROR(err); + PylithReal volume = 1.0; + for (int i = 0; i < dim; ++i) { + volume *= coordMax[i] - coordMin[i]; + } // for + assert(dim > 0); + const PylithReal avgDomainDim = pow(volume, 1.0/dim); + + PYLITH_METHOD_RETURN(avgDomainDim); +} // computeAvgDomainDim + + +// ------------------------------------------------------------------------------------------------ void pylith::topology::MeshOps::checkMaterialLabels(const pylith::topology::Mesh& mesh, pylith::int_array& labelValues) { diff --git a/libsrc/pylith/topology/MeshOps.hh b/libsrc/pylith/topology/MeshOps.hh index 86d9396e4a..4de3028fad 100644 --- a/libsrc/pylith/topology/MeshOps.hh +++ b/libsrc/pylith/topology/MeshOps.hh @@ -15,7 +15,7 @@ #include "pylith/utils/array.hh" // USES int_array #include "spatialdata/geocoords/geocoordsfwd.hh" -#include "spatialdata/units/unitsfwd.hh" +#include "pylith/scales/scalesfwd.hh" class pylith::topology::MeshOps { friend class TestMeshOps; // unit testing @@ -82,11 +82,11 @@ public: /** Nondimensionalize the finite-element mesh. * * @param[in] mesh Finite-element mesh. - * @param[in] normalizer Nondimensionalizer. + * @param[in] scales Nondimensionalizer. */ static void nondimensionalize(Mesh* const mesh, - const spatialdata::units::Nondimensional& normalizer); + const pylith::scales::Scales& scales); /** Check topology of mesh. * @@ -137,6 +137,14 @@ public: static PylithInt getNumCorners(const pylith::topology::Mesh& mesh); + /** Compute nominal dimension of domain based on mesh bounding box. + * + * @param[in] mesh Finite-element mesh. + * @returns Average domain dimension. + */ + static + PylithReal computeAvgDomainDim(const pylith::topology::Mesh& mesh); + /** Check to make sure material label value for every cell matches the label value of * one of the materials. * diff --git a/libsrc/pylith/utils/Makefile.am b/libsrc/pylith/utils/Makefile.am index 5951ea1841..8b086c6ded 100644 --- a/libsrc/pylith/utils/Makefile.am +++ b/libsrc/pylith/utils/Makefile.am @@ -22,11 +22,12 @@ subpkginclude_HEADERS = \ PylithVersion.hh \ PetscVersion.hh \ DependenciesVersion.hh \ + TSAdaptImpulse.hh \ TestArray.hh \ array.hh \ mpi.hh \ arrayfwd.hh \ - constdefs.h \ + constants.hh \ lapack.h \ macrodefs.h \ petscfwd.h \ diff --git a/libsrc/pylith/utils/PetscOptions.cc b/libsrc/pylith/utils/PetscOptions.cc index a172d3a457..0df9f459cc 100644 --- a/libsrc/pylith/utils/PetscOptions.cc +++ b/libsrc/pylith/utils/PetscOptions.cc @@ -73,9 +73,11 @@ namespace pylith { /** Add default solver tolerances to options. * * @param[in] options PETSc options. + * @param[in] solution Solution field for problem. */ static - void addSolverTolerances(PetscOptions* options); + void addSolverTolerances(PetscOptions* options, + const pylith::topology::Field& solution); /** Add initial guess options. * @@ -96,6 +98,7 @@ const int pylith::utils::PetscDefaults::PARALLEL = 0x4; const int pylith::utils::PetscDefaults::INITIAL_GUESS = 0x8; const int pylith::utils::PetscDefaults::TESTING = 0x10; const int pylith::utils::PetscDefaults::COLLECTIVE_IO = 0x20; +const int pylith::utils::PetscDefaults::TS_ADAPT = 0x40; // ------------------------------------------------------------------------------------------------ // Set default PETSc solver options based on solution field and material. @@ -121,7 +124,7 @@ pylith::utils::PetscDefaults::set(const pylith::topology::Field& solution, } // if assert(options); - _PetscOptions::addSolverTolerances(options); + _PetscOptions::addSolverTolerances(options, solution); if (flags & INITIAL_GUESS) { _PetscOptions::addInitialGuess(options); } // if @@ -141,19 +144,16 @@ pylith::utils::PetscDefaults::set(const pylith::topology::Field& solution, PYLITH_METHOD_END; } // setDefaults - // ------------------------------------------------------------------------------------------------ // Constructor pylith::utils::PetscOptions::PetscOptions(void) { GenericComponent::setName("petscoptions"); } // constructor - // ------------------------------------------------------------------------------------------------ // Destructor pylith::utils::PetscOptions::~PetscOptions(void) {} - // ------------------------------------------------------------------------------------------------ // Add PETSc option. void @@ -162,7 +162,6 @@ pylith::utils::PetscOptions::add(const char* name, _options[std::string(name)] = value; } // add - // ------------------------------------------------------------------------------------------------ // Remove PETSc option. void @@ -173,7 +172,6 @@ pylith::utils::PetscOptions::remove(const char* name) { } // if } // remove - // ------------------------------------------------------------------------------------------------ // Clear PETSc options. void @@ -181,7 +179,6 @@ pylith::utils::PetscOptions::clear(void) { _options.clear(); } // clear - // ------------------------------------------------------------------------------------------------ // Set PETSc options. void @@ -216,7 +213,6 @@ pylith::utils::PetscOptions::set(void) { PYLITH_METHOD_END; } // set - // ------------------------------------------------------------------------------------------------ // Set PETSc options, overriding any previously set options with the same name. void @@ -265,7 +261,6 @@ pylith::utils::_PetscOptions::write(pythia::journal::info_t& info, PYLITH_METHOD_END; } // write - // ------------------------------------------------------------------------------------------------ // Check if simulation is running in parallel. bool @@ -279,7 +274,6 @@ pylith::utils::_PetscOptions::isParallel(const pylith::topology::Field& solution PYLITH_METHOD_RETURN(numProcs > 1); } // isParallel - // ------------------------------------------------------------------------------------------------ // Check if simulation is has a fault. bool @@ -287,7 +281,6 @@ pylith::utils::_PetscOptions::hasFault(const pylith::topology::Field& solution) return solution.hasSubfield("lagrange_multiplier_fault"); } // hasFault - // ------------------------------------------------------------------------------------------------ // Add debugging options. void @@ -298,7 +291,6 @@ pylith::utils::_PetscOptions::addTesting(PetscOptions* options) { options->add("-malloc_dump"); } // setDebugging - // ------------------------------------------------------------------------------------------------ // Add monitoring options. void @@ -317,7 +309,6 @@ pylith::utils::_PetscOptions::addMonitoring(PetscOptions* options) { } // addMonitoring - // ------------------------------------------------------------------------------------------------ // Add collective I/O options. void @@ -328,22 +319,20 @@ pylith::utils::_PetscOptions::addCollectiveIO(PetscOptions* options) { } // addMonitoring - // ------------------------------------------------------------------------------------------------ // Add default solver tolerances to options. void -pylith::utils::_PetscOptions::addSolverTolerances(PetscOptions* options) { +pylith::utils::_PetscOptions::addSolverTolerances(PetscOptions* options, + const pylith::topology::Field& solution) { assert(options); options->add("-ksp_rtol", "1.0e-12"); - options->add("-ksp_atol", "1.0e-12"); + options->add("-ksp_atol", "1.0e-7"); options->add("-snes_rtol", "1.0e-12"); - options->add("-snes_atol", "1.0e-9"); - + options->add("-snes_atol", "4.0e-7"); } // addSolverTolerances - // ------------------------------------------------------------------------------------------------ // Add initial guess defaults. void @@ -355,5 +344,4 @@ pylith::utils::_PetscOptions::addInitialGuess(PetscOptions* options) { } // addInitialGuess - // End of file diff --git a/libsrc/pylith/utils/PetscOptions.hh b/libsrc/pylith/utils/PetscOptions.hh index ec0d297979..7a680f5342 100644 --- a/libsrc/pylith/utils/PetscOptions.hh +++ b/libsrc/pylith/utils/PetscOptions.hh @@ -32,6 +32,7 @@ public: static const int INITIAL_GUESS; static const int TESTING; static const int COLLECTIVE_IO; + static const int TS_ADAPT; // :KLUDGE: Flag indicating use of TSAdaptImpulse (full-scale testing) // PUBLIC METHODS ///////////////////////////////////////////////////////////////////////////// public: diff --git a/libsrc/pylith/utils/TSAdaptImpulse.cc b/libsrc/pylith/utils/TSAdaptImpulse.cc new file mode 100644 index 0000000000..23ee58987c --- /dev/null +++ b/libsrc/pylith/utils/TSAdaptImpulse.cc @@ -0,0 +1,87 @@ +// ================================================================================================= +// This code is part of PyLith, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/pylith). +// +// Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= + +#include + +#include "pylith/utils/error.hh" + +#include "pylith/utils/TSAdaptImpulse.hh" // implementation of class methods + +#include "petscts.h" +#include "petsc/private/tsimpl.h" + +// ------------------------------------------------------------------------------------------------ +double pylith::utils::TSAdaptImpulse::_impulseStep = 1.0e-6; + +// ------------------------------------------------------------------------------------------------ +// Set time step for impulse portion. +void +pylith::utils::TSAdaptImpulse::setImpulseTimeStep(const double timestep) { + _impulseStep = timestep; +} + + +// ------------------------------------------------------------------------------------------------ +// Get time step for impulse portion. +double +pylith::utils::TSAdaptImpulse::getImpulseTimeStep(void) { + return _impulseStep; +} + + +// ------------------------------------------------------------------------------------------------ +// Set PETSc TS adapt. +void +pylith::utils::TSAdaptImpulse::set(PetscTS ts) { + TSAdapt adapt; + + PetscErrorCode err = TSGetAdapt(ts, &adapt);PYLITH_CHECK_ERROR(err); + adapt->ops->choose = TSAdaptChoose; +} + + +// ------------------------------------------------------------------------------------------------ +// PETSc adaptive time stepper. +PetscErrorCode +pylith::utils::TSAdaptImpulse::TSAdaptChoose(TSAdapt adapt, + TS ts, + PetscReal h, + PetscInt *next_sc, + PetscReal *next_h, + PetscBool *accept, + PetscReal *wlte, + PetscReal *wltea, + PetscReal *wlter) { + static PetscReal dtTarget = -1.0; + PetscReal dtInitial = TSAdaptImpulse::getImpulseTimeStep(); + PetscInt step; + + PetscFunctionBeginUser; + PetscCall(TSGetStepNumber(ts, &step)); + if (!step) { + if (PetscAbsReal(dtInitial - h) > PETSC_SMALL) { + *accept = PETSC_FALSE; + *next_h = dtInitial; + dtTarget = h; + } else { + *accept = PETSC_TRUE; + *next_h = dtTarget < 0.0 ? dtInitial : dtTarget; + dtTarget = -1.0; + } + } else { + *accept = PETSC_TRUE; + *next_h = h; + } + *next_sc = 0; /* Reuse the same order scheme */ + *wlte = -1; /* Weighted local truncation error was not evaluated */ + *wltea = -1; /* Weighted absolute local truncation error was not evaluated */ + *wlter = -1; /* Weighted relative local truncation error was not evaluated */ + PetscFunctionReturn(PETSC_SUCCESS); +} diff --git a/libsrc/pylith/utils/TSAdaptImpulse.hh b/libsrc/pylith/utils/TSAdaptImpulse.hh new file mode 100644 index 0000000000..c081e45c01 --- /dev/null +++ b/libsrc/pylith/utils/TSAdaptImpulse.hh @@ -0,0 +1,68 @@ +// ================================================================================================= +// This code is part of PyLith, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/pylith). +// +// Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= +#pragma once + +#include "pylith/utils/utilsfwd.hh" // forward declarations + +#include "pylith/utils/petscfwd.h" + +#include "petscts.h" + +class pylith::utils::TSAdaptImpulse { + friend class TestTSAdapImpulse; // unit testing + + // PUBLIC METHODS ///////////////////////////////////////////////////////////////////////////// +public: + + /** Set time step for impulse portion. + * + * @param[in] timestep Time step (nondimensional). + */ + static + void setImpulseTimeStep(const double timestep); + + /** Get time step for impulse portion. + * + * @returns Time step (nondimensional). + */ + static + double getImpulseTimeStep(void); + + /** Set PETSc TS adapt. + * + * @param[inout] ts PETSc TS. + */ + static + void set(PetscTS ts); + + /** PETSc adaptive time stepper. + * + */ + static + PetscErrorCode TSAdaptChoose(TSAdapt adapt, + PetscTS ts, + PetscReal h, + PetscInt *next_sc, + PetscReal *next_h, + PetscBool *accept, + PetscReal *wlte, + PetscReal *wltea, + PetscReal *wlter); + + // PRIVATE MEMBERS //////////////////////////////////////////////////////////////////////////// +private: + + static double _impulseStep; ///< Time step for impulse portion. + + // Not impemented ///////////////////////////////////////////////////////////////////////////// +private: + + TSAdaptImpulse(void); ///< Not implemented. +}; diff --git a/libsrc/pylith/utils/constdefs.h b/libsrc/pylith/utils/constants.hh similarity index 61% rename from libsrc/pylith/utils/constdefs.h rename to libsrc/pylith/utils/constants.hh index 9ce303c9e9..d93acc04a3 100644 --- a/libsrc/pylith/utils/constdefs.h +++ b/libsrc/pylith/utils/constants.hh @@ -11,12 +11,17 @@ #include "pylith/utils/types.hh" // HASA PylithScalar +#include + namespace pylith { - static const double PYLITH_MAXDOUBLE = 1.0e+99; - static const float PYLITH_MAXFLOAT = 1.0e+30; - static const PylithInt PYLITH_MAXINT = PETSC_MAX_INT; - static const PylithInt PYLITH_MININT = PETSC_MIN_INT; - static const PylithScalar PYLITH_MAXSCALAR = (sizeof(PylithScalar) == sizeof(double)) ? PYLITH_MAXDOUBLE : PYLITH_MAXFLOAT; + static const double g_acc = 9.80665; + + static const double max_double = std::numeric_limits::max(); + static const float max_float = std::numeric_limits::max(); + static const PylithInt max_int = PETSC_MAX_INT; + static const PylithInt min_int = PETSC_MIN_INT; + static const PylithReal max_real = (sizeof(PylithReal) == sizeof(double)) ? max_double : max_float; + } // End of file diff --git a/libsrc/pylith/utils/utilsfwd.hh b/libsrc/pylith/utils/utilsfwd.hh index 278c2ba1f3..8940a661af 100644 --- a/libsrc/pylith/utils/utilsfwd.hh +++ b/libsrc/pylith/utils/utilsfwd.hh @@ -23,6 +23,7 @@ namespace pylith { class DependenciesVersion; class TestArray; + class TSAdaptImpulse; } // utils } // pylith diff --git a/modulesrc/Makefile.am b/modulesrc/Makefile.am index d2d8be8fe4..148f94b645 100644 --- a/modulesrc/Makefile.am +++ b/modulesrc/Makefile.am @@ -18,6 +18,7 @@ SUBDIRS = \ meshio \ mpi \ problems \ + scales \ topology \ utils diff --git a/modulesrc/faults/KinSrc.i b/modulesrc/faults/KinSrc.i index 16e899efe5..e3501ef615 100644 --- a/modulesrc/faults/KinSrc.i +++ b/modulesrc/faults/KinSrc.i @@ -55,11 +55,11 @@ public: /** Initialize kinematic (prescribed slip) earthquake source. * * @param[in] auxField Auxiliary field associated with fault finite-element integration. - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ void initialize(const pylith::topology::Field& auxField, - const spatialdata::units::Nondimensional& normalizer, + const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); /** Get requested slip subfields at time t. @@ -90,11 +90,11 @@ protected: * @attention The order of the calls to subfieldAdd() must match the * order of the auxiliary fields in the FE kernels. * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ virtual - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs) = 0; }; // class KinSrc diff --git a/modulesrc/faults/KinSrcBrune.i b/modulesrc/faults/KinSrcBrune.i index b8f87fce49..a2328201ed 100644 --- a/modulesrc/faults/KinSrcBrune.i +++ b/modulesrc/faults/KinSrcBrune.i @@ -29,10 +29,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); }; // class KinSrcBrune diff --git a/modulesrc/faults/KinSrcConstRate.i b/modulesrc/faults/KinSrcConstRate.i index 40214080d6..acfd301fa4 100644 --- a/modulesrc/faults/KinSrcConstRate.i +++ b/modulesrc/faults/KinSrcConstRate.i @@ -29,10 +29,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); }; // class KinSrcConstRate diff --git a/modulesrc/faults/KinSrcLiuCos.i b/modulesrc/faults/KinSrcLiuCos.i index 55c5093f5d..cf2345e6ec 100644 --- a/modulesrc/faults/KinSrcLiuCos.i +++ b/modulesrc/faults/KinSrcLiuCos.i @@ -29,10 +29,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); }; // class KinSrcLiuCos diff --git a/modulesrc/faults/KinSrcRamp.i b/modulesrc/faults/KinSrcRamp.i index a3a4afe082..b8d85e2d1f 100644 --- a/modulesrc/faults/KinSrcRamp.i +++ b/modulesrc/faults/KinSrcRamp.i @@ -29,10 +29,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); }; // class KinSrcRamp diff --git a/modulesrc/faults/KinSrcStep.i b/modulesrc/faults/KinSrcStep.i index 2a55fe313b..afa0489fe3 100644 --- a/modulesrc/faults/KinSrcStep.i +++ b/modulesrc/faults/KinSrcStep.i @@ -29,10 +29,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); }; // class KinSrcStep diff --git a/modulesrc/faults/KinSrcTimeHistory.i b/modulesrc/faults/KinSrcTimeHistory.i index 21bf5d6695..a918554044 100644 --- a/modulesrc/faults/KinSrcTimeHistory.i +++ b/modulesrc/faults/KinSrcTimeHistory.i @@ -55,10 +55,10 @@ protected: /** Setup auxiliary subfields (discretization and query fns). * - * @param[in] normalizer Normalizer for nondimensionalizing values. + * @param[in] scales Scales for nondimensionalizing values. * @param[in] cs Coordinate system for problem. */ - void _auxiliaryFieldSetup(const spatialdata::units::Nondimensional& normalizer, + void _auxiliaryFieldSetup(const pylith::scales::Scales& scales, const spatialdata::geocoords::CoordSys* cs); }; // class KinSrcTimeHistory diff --git a/modulesrc/problems/InitialCondition.i b/modulesrc/problems/InitialCondition.i index 3f8a748d19..574151a847 100644 --- a/modulesrc/problems/InitialCondition.i +++ b/modulesrc/problems/InitialCondition.i @@ -5,7 +5,7 @@ // Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. // All rights reserved. // -// See https://mit-license.org/ and LICENSE.md and for license information. +// See https://mit-license.org/ and LICENSE.md and for license information. // ================================================================================================= /** @@ -16,7 +16,7 @@ namespace pylith { namespace problems { - class InitialCondition : public pylith::utils::PyreComponent { + class InitialCondition: public pylith::utils::PyreComponent { // PUBLIC MEMBERS ////////////////////////////////////////////////////////////////////////////////////////// public: @@ -29,26 +29,27 @@ public: /// Deallocate PETSc and local data structures. void deallocate(void); - /** Set fields for initial condition. - * - * @param[in] subfields Array of names of solution subfields. - * @param[in] numSubfields Number of subfields. - */ - %apply(const char* const* string_list, const int list_len){ - (const char* subfields[], const int numSubfields) - }; - void setSubfields(const char* subfields[], - const int numSubfields); - %clear(const char* subfields[], const int numSubfields); + /** Set fields for initial condition. + * + * @param[in] subfields Array of names of solution subfields. + * @param[in] numSubfields Number of subfields. + */ + %apply(const char* const* string_list, const int list_len) { + (const char* subfields[], const int numSubfields) + }; + void setSubfields(const char* subfields[], + const int numSubfields); + + %clear(const char* subfields[], const int numSubfields); /** Set solver type. * * @param[out] solution Solution field. - * @param[in] normalizer Nondimensionalization. + * @param[in] scales Nondimensionalization. */ virtual void setValues(pylith::topology::Field* solution, - const spatialdata::units::Nondimensional& normalizer) = 0; + const pylith::scales::Scales& scales) = 0; }; // InitialCondition diff --git a/modulesrc/problems/InitialConditionDomain.i b/modulesrc/problems/InitialConditionDomain.i index 6817275b01..334d52c190 100644 --- a/modulesrc/problems/InitialConditionDomain.i +++ b/modulesrc/problems/InitialConditionDomain.i @@ -38,10 +38,10 @@ public: /** Set solver type. * * @param[out] solution Solution field. - * @param[in] normalizer Nondimensionalization. + * @param[in] scales Nondimensionalization. */ void setValues(pylith::topology::Field* solution, - const spatialdata::units::Nondimensional& normalizer); + const pylith::scales::Scales& scales); }; // InitialConditionDomain diff --git a/modulesrc/problems/InitialConditionPatch.i b/modulesrc/problems/InitialConditionPatch.i index 7593c1bd0e..3bbf60e787 100644 --- a/modulesrc/problems/InitialConditionPatch.i +++ b/modulesrc/problems/InitialConditionPatch.i @@ -62,10 +62,10 @@ public: /** Set solver type. * * @param[out] solution Solution field. - * @param[in] normalizer Nondimensionalization. + * @param[in] scales Nondimensionalization. */ void setValues(pylith::topology::Field* solution, - const spatialdata::units::Nondimensional& normalizer); + const pylith::scales::Scales& scales); }; // InitialConditionPatch diff --git a/modulesrc/problems/Physics.i b/modulesrc/problems/Physics.i index bb2acd403f..19968f5003 100644 --- a/modulesrc/problems/Physics.i +++ b/modulesrc/problems/Physics.i @@ -67,13 +67,13 @@ public: * * @param dim Nondimensionalizer. */ - void setNormalizer(const spatialdata::units::Nondimensional& dim); + void setScales(const pylith::scales::Scales& dim); /** Get manager of scales used to nondimensionalize problem. * * @param dim Nondimensionalizer. */ - const spatialdata::units::Nondimensional& getNormalizer(void) const; + const pylith::scales::Scales& getScales(void) const; /** Set formulation for equations. * diff --git a/modulesrc/problems/Problem.i b/modulesrc/problems/Problem.i index 0fc6b7e52b..0f69b249b2 100644 --- a/modulesrc/problems/Problem.i +++ b/modulesrc/problems/Problem.i @@ -71,7 +71,7 @@ public: * * @param[in] dim Nondimensionalizer. */ - void setNormalizer(const spatialdata::units::Nondimensional& dim); + void setScales(const pylith::scales::Scales& dim); /** Set gravity field. * diff --git a/modulesrc/scales/ElasticityScales.i b/modulesrc/scales/ElasticityScales.i new file mode 100644 index 0000000000..00040992a4 --- /dev/null +++ b/modulesrc/scales/ElasticityScales.i @@ -0,0 +1,154 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= + +/** @file modulesrc/units/Scales.i + * + * @brief SWIG interface for C++ Scales object. + */ + +namespace pylith { + namespace scales { + class ElasticityScales { +public: + + // PUBLIC METHODS ///////////////////////////////////////////////// + + /** Set defaults scales for quasi-static elasticity. + * + * @param[inout] Scales for nondimensionalization. + * @param[in] lengthScale Default length scale in meters. + * @param[in] timeScale Default time scale in seconds. + * + */ + static + void setQuasistaticElasticity(pylith::scales::Scales* scales, + const double lengthScale=100.0e+3, + const double timeScale=31557600.0e+2); + + /** Set defaults scales for dynamic elasticity. + * + * @param[inout] Scales for nondimensionalization. + * @param[in] lengthScale Default length scale in meters. + * @param[in] velocityScale Default velocity scale in m/s. + * + */ + static + void setDynamicElasticity(pylith::scales::Scales* scales, + const double lengthScale=100.0e+3, + const double velocityScale=3.0e+3); + + /** Set defaults scales for quasi-static poroelasticity. + * + * @param[inout] Scales for nondimensionalization. + * @param[in] lengthScale Default length scale in meters. + * @param[in] permeability Default permeability scale in m^2. + * @param[in] viscosity Default viscosity scale in Pa*s. + * @param[in] rigidity Default rigidity scale in Pa. + */ + static + void setQuasistaticPoroelasticity(pylith::scales::Scales* scales, + const double lengthScale=100.0e+3, + const double permeability=1.0e-12, + const double viscosity=1.0e-3, + const double rigidity=25.0e+9); + + /** Set time scale for poroelasticity. + * + * @param[in] lengthScale Default length scale in meters. + * @param[in] permeability Default permeability scale in m^2. + * @param[in] viscosity Default viscosity scale in Pa*s. + * @param[in] rigidity Default rigidity scale in Pa. + * + * @returns Time scale in seconds. + */ + static + double computePoroelasticityTimeScale(const double viscosity, + const double permeability, + const double length, + const double rigidity); + + /** Get value to nondimensionalize stress. + * + * @param[in] Scales for nondimensionalization. + * @returns Stress scale in Pa (SI units). + */ + static + double getStressScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize pressure. + * + * @param[in] Scales for nondimensionalization. + * @returns Fluid pressure scale in Pascals (SI units). + */ + static + double getFluidPressureScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize strain. + * + * @param[in] Scales for nondimensionalization. + * @returns Strain scale. + */ + static + double getStrainScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize body force. + * + * @param[in] Scales for nondimensionalization. + * @returns Body force scale in Pa/m (SI units). + */ + static + double getBodyForceScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize density. + * + * @param[in] Scales for nondimensionalization. + * @returns Density scale in kg/m^3 (SI units). + */ + static + double getDensityScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize velocity. + * + * @param[in] Scales for nondimensionalization. + * @returns Velocity scale in m/s (SI units). + */ + static + double getVelocityScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize acceleration. + * + * @param[in] Scales for nondimensionalization. + * @returns Acceleration scale in m/s^2 (SI units). + */ + static + double getAccelerationScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize fluid viscosity. + * + * @param[in] Scales for nondimensionalization. + * @returns Fluid viscosity scale in Pa*s (SI units). + */ + static + double getViscosityScale(const pylith::scales::Scales& scales); + + /** Get value to nondimensionalize permeability. + * + * @param[in] Scales for nondimensionalization. + * @returns Permeability scale in m/s^2 (SI units). + */ + static + double getPermeabilityScale(const pylith::scales::Scales& scales); + + }; // class ElasticityScales + + } // units +} // spatialdata + +// End of file diff --git a/modulesrc/scales/Makefile.am b/modulesrc/scales/Makefile.am new file mode 100644 index 0000000000..ab6d74a328 --- /dev/null +++ b/modulesrc/scales/Makefile.am @@ -0,0 +1,50 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +subpackage = scales +include $(top_srcdir)/subpackage.am +include $(top_srcdir)/modulesrc/module.am + +subpkgpython_LTLIBRARIES = _scales.la +subpkgpython_PYTHON = scales.py + +swig_sources = \ + scales.i \ + ScalesObj.i \ + ElasticityScales.i + +swig_generated = \ + scales_wrap.cxx \ + scales.py + +_scales_la_LDFLAGS = -module -avoid-version \ + $(AM_LDFLAGS) $(PYTHON_LA_LDFLAGS) + +dist__scales_la_SOURCES = $(swig_sources) $(swig_generated) + +_scales_la_LIBADD = \ + $(top_builddir)/libsrc/pylith/libpylith.la \ + $(PYTHON_BLDLIBRARY) $(PYTHON_LIBS) $(PYTHON_SYSLIBS) + +if ENABLE_SWIG +$(srcdir)/scales_wrap.cxx $(srcdir)/scales.py: $(swig_sources) + $(SWIG) -Wall -c++ -python $< +else +$(srcdir)/scales_wrap.cxx $(srcdir)/scales.py: + $(error Missing SWIG generated files. Make sure SWIG is installed and reconfigure with --enable-swig) +endif + + +MAINTAINERCLEANFILES = \ + $(srcdir)/scales_wrap.cxx \ + $(srcdir)/scales.py + + +# End of file diff --git a/modulesrc/scales/ScalesObj.i b/modulesrc/scales/ScalesObj.i new file mode 100644 index 0000000000..e7ad2f3f8f --- /dev/null +++ b/modulesrc/scales/ScalesObj.i @@ -0,0 +1,133 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= + +/** @file modulesrc/units/Scales.i + * + * @brief SWIG interface for C++ Scales object. + */ + +namespace pylith { + namespace scales { + class Scales + { // class Scales +public: + + // PUBLIC METHODS ///////////////////////////////////////////////// + + /// Default constructor + Scales(void); + + /// Default destructor + ~Scales(void); + + /** Set value to nondimensionalize position. + * + * @param value Length scale in meters (SI units). + */ + void setLengthScale(const double value); + + /** Get value to nondimensionalize position. + * + * @returns Length scale in meters (SI units). + */ + double getLengthScale(void) const; + + /** Set value to nondimensionalize displacement. + * + * @param value Displacement scale in meters (SI units). + */ + void setDisplacementScale(const double value); + + /** Get value to nondimensionalize displacement. + * + * @returns Displacement scale in meters (SI units). + */ + double getDisplacementScale(void) const; + + /** Set value to nondimensionalize rigidity (elastic moduli). + * + * @param value Rigidity scale in Pascals (SI units). + */ + void setRigidityScale(const double value); + + /** Get value to nondimensionalize rigidity. + * + * @returns Rigidity scale in Pascals (SI units). + */ + double getRigidityScale(void) const; + + /** Set value to nondimensionalize time. + * + * @param value Time scale in seconds (SI units). + */ + void setTimeScale(const double value); + + /** Get value to nondimensionalize time. + * + * @returns Time scale in seconds (SI units). + */ + double getTimeScale(void) const; + + /** Set value to nondimensionalize temperature. + * + * @param value Temperature scale in Kelvin (SI units). + */ + void setTemperatureScale(const double value); + + /** Get value to nondimensionalize temperature. + * + * @returns Temperature scale in Kelvin (SI units). + */ + double getTemperatureScale(void) const; + + /** Make value dimensionless. + * + * @param value Value with dimensions in SI units. + * @param scale Scale used to nondimensionalize value. + * @returns Dimensionless value. + */ + double nondimensionalize(const double value, + const double scale) const; + + /** Make value dimensionless. + * + * @param value Dimensionless value. + * @param value Value with dimensions in SI units. + * @returns Scale used to nondimensionalize value. + */ + double dimensionalize(const double value, + const double scale) const; + + /** Make values dimensionless. + * + * @param values Array of values with dimensions in SI units. + * @param nvalues Number of values. + * @param scale Scale used to nondimensionalize value. + */ + void nondimensionalize(double* const values, + const size_t nvalues, + const double scale) const; + + /** Make value dimensionless. + * + * @param values Array of dimensionless values. + * @param nvalues Number of values. + * @param scale Scale used to nondimensionalize value. + */ + void dimensionalize(double* const values, + const size_t nvalues, + const double scale) const; + + }; // class Scales + + } // units +} // spatialdata + +// End of file diff --git a/modulesrc/scales/scales.i b/modulesrc/scales/scales.i new file mode 100644 index 0000000000..c586af82f2 --- /dev/null +++ b/modulesrc/scales/scales.i @@ -0,0 +1,32 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= +// SWIG interface +%module scales + +// Header files for module C++ code +%{ +#include "pylith/scales/Scales.hh" +#include "pylith/scales/ElasticityScales.hh" +%} + +%include "exception.i" +%exception { + try { + $action + } catch (const std::exception& err) { + SWIG_exception(SWIG_RuntimeError, err.what()); + } // try/catch +} // exception + +%include "ScalesObj.i" +%include "ElasticityScales.i" + + +// End of file diff --git a/modulesrc/topology/MeshOps.i b/modulesrc/topology/MeshOps.i index 0d885590aa..0f66163431 100644 --- a/modulesrc/topology/MeshOps.i +++ b/modulesrc/topology/MeshOps.i @@ -5,7 +5,7 @@ // Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. // All rights reserved. // -// See https://mit-license.org/ and LICENSE.md and for license information. +// See https://mit-license.org/ and LICENSE.md and for license information. // ================================================================================================= /** @@ -18,12 +18,12 @@ /** Nondimensionalize the finite-element mesh. * * @param mesh Finite-element mesh. - * @param normalizer Nondimensionalizer. + * @param scales Nondimensionalizer. */ void MeshOps_nondimensionalize(pylith::topology::Mesh* const mesh, - const spatialdata::units::Nondimensional& normalizer) { - pylith::topology::MeshOps::nondimensionalize(mesh, normalizer); + const pylith::scales::Scales& scales) { + pylith::topology::MeshOps::nondimensionalize(mesh, scales); } // nondimensionalize %} diff --git a/modulesrc/utils/Makefile.am b/modulesrc/utils/Makefile.am index c5f710bfcf..93112df5de 100644 --- a/modulesrc/utils/Makefile.am +++ b/modulesrc/utils/Makefile.am @@ -40,7 +40,7 @@ utils_swig_sources = \ PyreComponent.i \ PetscOptions.i \ TestArray.i \ - constdefs.i + constants.i utils_swig_generated = \ utils_wrap.cxx \ diff --git a/modulesrc/utils/PetscOptions.i b/modulesrc/utils/PetscOptions.i index dee0955c24..b20e0e8662 100644 --- a/modulesrc/utils/PetscOptions.i +++ b/modulesrc/utils/PetscOptions.i @@ -27,6 +27,7 @@ public: static const int INITIAL_GUESS; static const int TESTING; static const int COLLECTIVE_IO; + static const int TS_ADAPT; // NOT IMPLEMENTED //////////////////////////////////////////////////////////////////// private: diff --git a/modulesrc/utils/constdefs.i b/modulesrc/utils/constants.i similarity index 69% rename from modulesrc/utils/constdefs.i rename to modulesrc/utils/constants.i index e9817bd1f1..78d5e5798b 100644 --- a/modulesrc/utils/constdefs.i +++ b/modulesrc/utils/constants.i @@ -9,42 +9,39 @@ // ================================================================================================= /** - * @file modulesrc/utils/constdefs.i + * @file modulesrc/utils/constants.i * * @brief PyLith constants. */ // ---------------------------------------------------------------------- -// PYLITH_MAXDOUBLE +// pylith::g_acc %inline %{ double - maxdouble(void) - { // maxdouble - return pylith::PYLITH_MAXDOUBLE; - } // maxdouble -%} // inline + g_acc(void) { + return pylith::g_acc; + } +%} // ---------------------------------------------------------------------- -// PYLITH_MAXFLOAT +// pylith::max_double %inline %{ - float - maxfloat(void) - { // maxfloat - return pylith::PYLITH_MAXFLOAT; - } // maxfloat -%} // inline + double + max_double(void) { + return pylith::max_double; + } +%} // ---------------------------------------------------------------------- -// PYLITH_MAXSCALAR +// pylith::max_float %inline %{ - double - maxscalar(void) - { // maxscalar - return pylith::PYLITH_MAXSCALAR; - } // maxscalar -%} // inline + float + max_float(void) { + return pylith::max_float; + } +%} // End of file diff --git a/modulesrc/utils/utils.i b/modulesrc/utils/utils.i index 2b9d29f838..26236f3917 100644 --- a/modulesrc/utils/utils.i +++ b/modulesrc/utils/utils.i @@ -5,7 +5,7 @@ // Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. // All rights reserved. // -// See https://mit-license.org/ and LICENSE.md and for license information. +// See https://mit-license.org/ and LICENSE.md and for license information. // ================================================================================================= // SWIG interface %module utils @@ -19,7 +19,7 @@ #include "pylith/utils/PetscVersion.hh" #include "pylith/utils/DependenciesVersion.hh" #include "pylith/utils/TestArray.hh" -#include "pylith/utils/constdefs.h" +#include "pylith/utils/constants.hh" #include // USES PetscLogEventBegin/End() in inline methods #include "pylith/utils/arrayfwd.hh" // USES scalar_array @@ -27,12 +27,12 @@ %include "exception.i" %exception { - try { - $action - } catch (const std::exception& err) { - SWIG_exception(SWIG_RuntimeError, err.what()); - } // try/catch - } // exception + try { + $action + } catch (const std::exception& err) { + SWIG_exception (SWIG_RuntimeError, err.what ()); + } // try/catch +} // exception %include "typemaps.i" %include "../include/scalartypemaps.i" @@ -43,7 +43,7 @@ %} %include "../include/numpy.i" %init %{ -import_array(); + import_array(); %} // Interfaces @@ -55,6 +55,6 @@ import_array(); %include "PetscVersion.i" %include "DependenciesVersion.i" %include "TestArray.i" -%include "constdefs.i" +%include "constants.i" // End of file diff --git a/playpen/test_new_powerlaw/pylithapp.cfg b/playpen/test_new_powerlaw/pylithapp.cfg index 80b90b8dbc..91d8d484c1 100644 --- a/playpen/test_new_powerlaw/pylithapp.cfg +++ b/playpen/test_new_powerlaw/pylithapp.cfg @@ -22,14 +22,6 @@ integratordomain = 1 [pylithapp.mesh_generator] reader = pylith.meshio.MeshIOCubit -# ---------------------------------------------------------------------- -# Normalization -# ---------------------------------------------------------------------- -[pylithapp.problem.normalizer] -length_scale = 1.0*km -shear_modulus = 2.88*GPa -relaxation_time = 5.0*year - # ---------------------------------------------------------------------- # solution # ---------------------------------------------------------------------- @@ -97,40 +89,5 @@ auxiliary_subfields.reference_stress.quadrature_order = 2 auxiliary_subfields.reference_strain.basis_order = 0 auxiliary_subfields.reference_strain.quadrature_order = 2 -# ---------------------------------------------------------------------- -# PETSc -# ---------------------------------------------------------------------- -[pylithapp.petsc] - -# Preconditioner settings. -pc_type = lu - -# Convergence parameters. -ksp_rtol = 1.0e-12 -ksp_atol = 1.0e-20 -ksp_max_it = 10000 -ksp_gmres_restart = 50 - -# Linear solver monitoring options. -ksp_converged_reason = true -ksp_error_if_not_converged = true - -# Nonlinear solver monitoring options. -snes_rtol = 1.0e-10 -snes_atol = 1.0e-14 -snes_max_it = 2 -snes_converged_reason = true -snes_error_if_not_converged = true -snes_view = true - -ts_monitor = true -ksp_monitor = true -snes_monitor = true -snes_linesearch_monitor = true - - -#log_view = true - -# start_in_debugger = lldb-mp-7.0 # End of file diff --git a/playpen/viscorestart/pylithapp.cfg b/playpen/viscorestart/pylithapp.cfg index 84c0d8e7d8..9deaf66c7d 100644 --- a/playpen/viscorestart/pylithapp.cfg +++ b/playpen/viscorestart/pylithapp.cfg @@ -29,7 +29,7 @@ reader = pylith.meshio.MeshIOAscii # ---------------------------------------------------------------------- # Normalization # ---------------------------------------------------------------------- -[pylithapp.timedependent.normalizer] +[pylithapp.timedependent.scales] length_scale = 1.0*m # ---------------------------------------------------------------------- @@ -77,29 +77,5 @@ vertex_data_fields = [displacement,velocity] cell_filter = pylith.meshio.CellFilterAvg writer = pylith.meshio.DataWriterHDF5 -# ---------------------------------------------------------------------- -# PETSc -# ---------------------------------------------------------------------- -# Set the solver options. - -[pylithapp.petsc] - -# Preconditioner settings. -pc_type = lu - -# Convergence parameters. -ksp_rtol = 1.0e-12 -ksp_atol = 1.0e-15 - -# Linear solver monitoring options. -ksp_monitor = true -ksp_converged_reason = true - -# Nonlinear solver monitoring options. -snes_rtol = 1.0e-12 -snes_atol = 1.0e-14 -snes_max_it = 100 -snes_monitor = true -snes_converged_reason = true # End of file diff --git a/pylith/Makefile.am b/pylith/Makefile.am index cd1821f951..9ed0b30bc9 100644 --- a/pylith/Makefile.am +++ b/pylith/Makefile.am @@ -133,6 +133,12 @@ EXTRA_DIST = \ problems/SubfieldVelocity.py \ problems/TimeDependent.py \ problems/__init__.py \ + scales/General.py \ + scales/ElasticityScales.py \ + scales/DynamicElasticity.py \ + scales/QuasistaticPoroelasticity.py \ + scales/QuasistaticElasticity.py \ + scales/__init__.py \ testing/FullTestApp.py \ testing/SolutionPoints.py \ testing/TestCases.py \ diff --git a/pylith/bc/NeumannTimeDependent.py b/pylith/bc/NeumannTimeDependent.py index a0194ee21a..a79563e5b5 100644 --- a/pylith/bc/NeumannTimeDependent.py +++ b/pylith/bc/NeumannTimeDependent.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= # @file pylith/bc/NeumannTimeDependent.py # @@ -19,8 +19,7 @@ def validateDir(value): - """Validate direction. - """ + """Validate direction.""" msg = "Direction must be a 3 component vector (list)." if not isinstance(value, list): raise ValueError(msg) @@ -50,13 +49,14 @@ class NeumannTimeDependent(BoundaryCondition, ModuleNeumannTimeDependent): See [`AuxSubfieldsTimeDependent` Component](AuxSubfieldsTimeDependent.md) for the functional form of the time depenence. ::: """ + DOC_CONFIG = { "cfg": """ # Neumann (traction) boundary condition in 2D on -y boundary. [pylithapp.problem.bc.bc_yneg] label = boundary_yneg field = displacement - scale_name = pressure + scale_name = stress use_initial = False use_time_history = True @@ -71,48 +71,66 @@ class NeumannTimeDependent(BoundaryCondition, ModuleNeumannTimeDependent): """, } - import pythia.pyre.inventory - scaleName = pythia.pyre.inventory.str("scale_name", default="pressure", - validator=pythia.pyre.inventory.choice(["length", "time", "pressure", "density", "velocity"])) - scaleName.meta['tip'] = "Type of scale for nondimensionalizing Neumann boundary condition ('pressure' for elasticity)." + scaleName = pythia.pyre.inventory.str( + "scale_name", + default="stress", + validator=pythia.pyre.inventory.choice(["displacement", "stress"]), + ) + scaleName.meta["tip"] = ( + "Type of scale for nondimensionalizing Neumann boundary condition ('stress' for elasticity)." + ) useInitial = pythia.pyre.inventory.bool("use_initial", default=True) - useInitial.meta['tip'] = "Use initial term in time-dependent expression." + useInitial.meta["tip"] = "Use initial term in time-dependent expression." useRate = pythia.pyre.inventory.bool("use_rate", default=False) - useRate.meta['tip'] = "Use rate term in time-dependent expression." + useRate.meta["tip"] = "Use rate term in time-dependent expression." useTimeHistory = pythia.pyre.inventory.bool("use_time_history", default=False) - useTimeHistory.meta['tip'] = "Use time history term in time-dependent expression." - - dbTimeHistory = pythia.pyre.inventory.facility("time_history", factory=NullComponent, family="temporal_database") - dbTimeHistory.meta['tip'] = "Time history with normalized amplitude as a function of time." - - refDir1 = pythia.pyre.inventory.list("ref_dir_1", default=[0.0, 0.0, 1.0], validator=validateDir) - refDir1.meta['tip'] = "First choice for reference direction to discriminate among tangential directions in 3D." - - refDir2 = pythia.pyre.inventory.list("ref_dir_2", default=[0.0, 1.0, 0.0], validator=validateDir) - refDir2.meta['tip'] = "Second choice for reference direction to discriminate among tangential directions in 3D." + useTimeHistory.meta["tip"] = "Use time history term in time-dependent expression." + + dbTimeHistory = pythia.pyre.inventory.facility( + "time_history", factory=NullComponent, family="temporal_database" + ) + dbTimeHistory.meta["tip"] = ( + "Time history with normalized amplitude as a function of time." + ) + + refDir1 = pythia.pyre.inventory.list( + "ref_dir_1", default=[0.0, 0.0, 1.0], validator=validateDir + ) + refDir1.meta["tip"] = ( + "First choice for reference direction to discriminate among tangential directions in 3D." + ) + + refDir2 = pythia.pyre.inventory.list( + "ref_dir_2", default=[0.0, 1.0, 0.0], validator=validateDir + ) + refDir2.meta["tip"] = ( + "Second choice for reference direction to discriminate among tangential directions in 3D." + ) def __init__(self, name="neumanntimedependent"): - """Constructor. - """ + """Constructor.""" BoundaryCondition.__init__(self, name) return def _defaults(self): from .AuxSubfieldsTimeDependent import AuxSubfieldsTimeDependent + self.auxiliarySubfields = AuxSubfieldsTimeDependent("auxiliary_subfields") def preinitialize(self, problem): - """Do pre-initialization setup. - """ + """Do pre-initialization setup.""" from pylith.mpi.Communicator import mpi_is_root + if mpi_is_root(): self._info.log( - "Performing minimal initialization of time-dependent Neumann boundary condition '%s'." % self.aliases[-1]) + "Performing minimal initialization of time-dependent Neumann boundary condition '%s'." + % self.aliases[-1] + ) BoundaryCondition.preinitialize(self, problem) @@ -127,38 +145,45 @@ def preinitialize(self, problem): return def _validate(self, context): - if self.inventory.useTimeHistory and isinstance(self.inventory.dbTimeHistory, NullComponent): + if self.inventory.useTimeHistory and isinstance( + self.inventory.dbTimeHistory, NullComponent + ): trait = self.inventory.getTrait("time_history") - self._validationError(context, trait, - f"Missing time history database for time-dependent Neumann boundary condition '{self.aliases[-1]}'.") - if not self.inventory.useTimeHistory and not isinstance(self.inventory.dbTimeHistory, NullComponent): + self._validationError( + context, + trait, + f"Missing time history database for time-dependent Neumann boundary condition '{self.aliases[-1]}'.", + ) + if not self.inventory.useTimeHistory and not isinstance( + self.inventory.dbTimeHistory, NullComponent + ): self._warning.log( - f"Time history for time-dependent Neumann boundary condition '{self.aliases[-1]}' not enabled. Ignoring provided time history database.") + f"Time history for time-dependent Neumann boundary condition '{self.aliases[-1]}' not enabled. Ignoring provided time history database." + ) def _validationError(self, context, trait, msg): from pythia.pyre.inventory.Item import Item + error = ValueError(msg) descriptor = self.getTraitDescriptor(trait.name) context.error(error, items=[Item(trait, descriptor)]) def _configure(self): - """Setup members using inventory. - """ + """Setup members using inventory.""" BoundaryCondition._configure(self) return def _createModuleObj(self): - """Create handle to corresponding C++ object. - """ + """Create handle to corresponding C++ object.""" ModuleNeumannTimeDependent.__init__(self) return # Factories + def boundary_condition(): - """Factory associated with NeumannTimeDependent. - """ + """Factory associated with NeumannTimeDependent.""" return NeumannTimeDependent() diff --git a/pylith/faults/KinSrc.py b/pylith/faults/KinSrc.py index efa941a757..3e7ac58782 100644 --- a/pylith/faults/KinSrc.py +++ b/pylith/faults/KinSrc.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from pylith.utils.PetscComponent import PetscComponent @@ -20,49 +20,49 @@ class KinSrc(PetscComponent, ModuleKinSrc): import pythia.pyre.inventory from spatialdata.spatialdb.SimpleDB import SimpleDB - auxFieldDB = pythia.pyre.inventory.facility("db_auxiliary_field", family="spatial_database", factory=SimpleDB) - auxFieldDB.meta['tip'] = "Database for slip time function parameters." + + auxFieldDB = pythia.pyre.inventory.facility( + "db_auxiliary_field", family="spatial_database", factory=SimpleDB + ) + auxFieldDB.meta["tip"] = "Database for slip time function parameters." from pythia.pyre.units.time import second - originTime = pythia.pyre.inventory.dimensional("origin_time", default=0.0 * second) - originTime.meta['tip'] = "Origin time for slip source." + originTime = pythia.pyre.inventory.dimensional("origin_time", default=0.0 * second) + originTime.meta["tip"] = "Origin time for slip source." def __init__(self, name="kinsrc"): - """Constructor. - """ + """Constructor.""" PetscComponent.__init__(self, name, facility="eq_kinematic_src") return def preinitialize(self, problem): - """Do pre-initialization setup. - """ + """Do pre-initialization setup.""" self._createModuleObj() ModuleKinSrc.setIdentifier(self, self.aliases[-1]) ModuleKinSrc.auxFieldDB(self, self.auxFieldDB) - originTimeN = self.originTime / problem.normalizer.getTimeScale() + originTimeN = self.originTime / problem.scales.getTimeScale() ModuleKinSrc.setOriginTime(self, originTimeN) return def verifyConfiguration(self): - """Verify compatibility of configuration. - """ + """Verify compatibility of configuration.""" return # PRIVATE METHODS //////////////////////////////////////////////////// def _configure(self): - """Setup members using inventory. - """ + """Setup members using inventory.""" PetscComponent._configure(self) return def _createModuleObj(self): - """Call constructor for module object for access to C++ object. - """ - raise NotImplementedError("Please implement _createModuleOb() in derived class.") + """Call constructor for module object for access to C++ object.""" + raise NotImplementedError( + "Please implement _createModuleOb() in derived class." + ) return diff --git a/pylith/meshio/OutputSolnPoints.py b/pylith/meshio/OutputSolnPoints.py index 8b7aef0d85..924e9e8067 100644 --- a/pylith/meshio/OutputSolnPoints.py +++ b/pylith/meshio/OutputSolnPoints.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .OutputSoln import OutputSoln @@ -22,6 +22,7 @@ class OutputSolnPoints(OutputSoln, ModuleOutputSolnPoints): Implements `OutputSoln`. """ + DOC_CONFIG = { "cfg": """ [observer] @@ -47,66 +48,77 @@ class OutputSolnPoints(OutputSoln, ModuleOutputSolnPoints): import pythia.pyre.inventory label = pythia.pyre.inventory.str("label", default="points") - label.meta['tip'] = "Label identifier for points (used in constructing default filenames)." + label.meta["tip"] = ( + "Label identifier for points (used in constructing default filenames)." + ) from .PointsList import PointsList - reader = pythia.pyre.inventory.facility("reader", factory=PointsList, family="points_list") - reader.meta['tip'] = "Reader for points list." + + reader = pythia.pyre.inventory.facility( + "reader", factory=PointsList, family="points_list" + ) + reader.meta["tip"] = "Reader for points list." # PUBLIC METHODS ///////////////////////////////////////////////////// def __init__(self, name="outputsolnpoints"): - """Constructor. - """ + """Constructor.""" OutputSoln.__init__(self, name) return def preinitialize(self, problem): - """Do mimimal initialization. - """ + """Do mimimal initialization.""" OutputSoln.preinitialize(self, problem) stationNames, stationCoords = self.reader.read() # Convert to mesh coordinate system from spatialdata.geocoords.Converter import convert + convert(stationCoords, problem.mesh().getCoordSys(), self.reader.coordsys) # Nondimensionalize - stationCoords /= problem.normalizer.lengthScale.value + stationCoords /= problem.scales.lengthScale.value ModuleOutputSolnPoints.setPoints(self, stationCoords, stationNames) identifier = self.aliases[-1] - self.writer.setFilename(problem.defaults.outputDir, problem.defaults.simName, identifier) + self.writer.setFilename( + problem.defaults.outputDir, problem.defaults.simName, identifier + ) return # PRIVATE METHODS //////////////////////////////////////////////////// def _validate(self, context): from .DataWriterVTK import DataWriterVTK + if isinstance(self.inventory.writer, DataWriterVTK): trait = self.inventory.getTrait("writer") - self._validationError(context, trait, "PETSc VTK writer using the VTU format does not support output at points. Use the default DataWriterHDF5 writer.") + self._validationError( + context, + trait, + "PETSc VTK writer using the VTU format does not support output at points. Use the default DataWriterHDF5 writer.", + ) def _validationError(self, context, trait, msg): from pythia.pyre.inventory.Item import Item + error = ValueError(msg) descriptor = self.getTraitDescriptor(trait.name) context.error(error, items=[Item(trait, descriptor)]) def _createModuleObj(self): - """Create handle to C++ object. - """ + """Create handle to C++ object.""" ModuleOutputSolnPoints.__init__(self) return + # FACTORIES //////////////////////////////////////////////////////////// def observer(): - """Factory associated with OutputSoln. - """ + """Factory associated with OutputSoln.""" return OutputSolnPoints() diff --git a/pylith/problems/Physics.py b/pylith/problems/Physics.py index e2fae7e184..a8eecfe7f1 100644 --- a/pylith/problems/Physics.py +++ b/pylith/problems/Physics.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from pylith.utils.PetscComponent import PetscComponent @@ -16,10 +16,10 @@ def observerFactory(name): - """Factory for output items. - """ + """Factory for output items.""" from pythia.pyre.inventory import facility from pylith.meshio.OutputPhysics import OutputPhysics + return facility(name, family="observer", factory=OutputPhysics) @@ -27,41 +27,48 @@ class Physics(PetscComponent, ModulePhysics): """ Abstract base class for objects defining physics. """ + import pythia.pyre.inventory from pylith.topology.Subfield import subfieldFactory from pylith.utils.EmptyBin import EmptyBin auxiliarySubfields = pythia.pyre.inventory.facilityArray( - "auxiliary_subfields", itemFactory=subfieldFactory, factory=EmptyBin) - auxiliarySubfields.meta['tip'] = "Discretization information for auxiliary subfields." + "auxiliary_subfields", itemFactory=subfieldFactory, factory=EmptyBin + ) + auxiliarySubfields.meta["tip"] = ( + "Discretization information for auxiliary subfields." + ) derivedSubfields = pythia.pyre.inventory.facilityArray( - "derived_subfields", itemFactory=subfieldFactory, factory=EmptyBin) - derivedSubfields.meta['tip'] = "Discretization of derived subfields." + "derived_subfields", itemFactory=subfieldFactory, factory=EmptyBin + ) + derivedSubfields.meta["tip"] = "Discretization of derived subfields." from spatialdata.spatialdb.SimpleDB import SimpleDB + auxiliaryFieldDB = pythia.pyre.inventory.facility( - "db_auxiliary_field", family="spatial_database", factory=SimpleDB) - auxiliaryFieldDB.meta['tip'] = "Database for physical property parameters." + "db_auxiliary_field", family="spatial_database", factory=SimpleDB + ) + auxiliaryFieldDB.meta["tip"] = "Database for physical property parameters." from pylith.problems.SingleObserver import SinglePhysicsObserver + observers = pythia.pyre.inventory.facilityArray( - "observers", itemFactory=observerFactory, factory=SinglePhysicsObserver) - observers.meta['tip'] = "Observers (e.g., output)." + "observers", itemFactory=observerFactory, factory=SinglePhysicsObserver + ) + observers.meta["tip"] = "Observers (e.g., output)." def __init__(self, name="physics", facility="physics"): - """Constructor. - """ + """Constructor.""" PetscComponent.__init__(self, name, facility) def preinitialize(self, problem): - """Do pre-initialization setup. - """ + """Do pre-initialization setup.""" self._createModuleObj() identifier = self.aliases[-1] ModulePhysics.setIdentifier(self, identifier) - ModulePhysics.setNormalizer(self, problem.normalizer) + ModulePhysics.setScales(self, problem.scales) if not isinstance(self.auxiliaryFieldDB, NullComponent): ModulePhysics.setAuxiliaryFieldDB(self, self.auxiliaryFieldDB) @@ -69,34 +76,54 @@ def preinitialize(self, problem): for subfield in self.auxiliarySubfields.components(): fieldName = subfield.aliases[-1] descriptor = subfield.getTraitDescriptor("quadrature_order") - if hasattr(descriptor.locator, "source") and descriptor.locator.source == "default": + if ( + hasattr(descriptor.locator, "source") + and descriptor.locator.source == "default" + ): quadOrder = problem.defaults.quadOrder else: quadOrder = subfield.quadOrder - ModulePhysics.setAuxiliarySubfieldDiscretization(self, fieldName, subfield.basisOrder, quadOrder, - subfield.dimension, subfield.cellBasis, - subfield.feSpace, subfield.isBasisContinuous) + ModulePhysics.setAuxiliarySubfieldDiscretization( + self, + fieldName, + subfield.basisOrder, + quadOrder, + subfield.dimension, + subfield.cellBasis, + subfield.feSpace, + subfield.isBasisContinuous, + ) for subfield in self.derivedSubfields.components(): fieldName = subfield.aliases[-1] descriptor = subfield.getTraitDescriptor("quadrature_order") - if hasattr(descriptor.locator, "source") and descriptor.locator.source == "default": + if ( + hasattr(descriptor.locator, "source") + and descriptor.locator.source == "default" + ): quadOrder = problem.defaults.quadOrder else: quadOrder = subfield.quadOrder - ModulePhysics.setDerivedSubfieldDiscretization(self, fieldName, subfield.basisOrder, quadOrder, - subfield.dimension, subfield.cellBasis, - subfield.feSpace, subfield.isBasisContinuous) + ModulePhysics.setDerivedSubfieldDiscretization( + self, + fieldName, + subfield.basisOrder, + quadOrder, + subfield.dimension, + subfield.cellBasis, + subfield.feSpace, + subfield.isBasisContinuous, + ) for observer in self.observers.components(): observer.preinitialize(problem, identifier) ModulePhysics.registerObserver(self, observer) def _createModuleObj(self): - """Call constructor for module object for access to C++ object. - """ + """Call constructor for module object for access to C++ object.""" raise NotImplementedError( - "Please implement _createModuleOb() in derived class.") + "Please implement _createModuleOb() in derived class." + ) # End of file diff --git a/pylith/problems/Problem.py b/pylith/problems/Problem.py index 0a8acce296..e63213fbf1 100644 --- a/pylith/problems/Problem.py +++ b/pylith/problems/Problem.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from pylith.utils.PetscComponent import PetscComponent @@ -17,34 +17,34 @@ def materialFactory(name): - """Factory for material items. - """ + """Factory for material items.""" from pythia.pyre.inventory import facility from pylith.materials.Elasticity import Elasticity + return facility(name, family="material", factory=Elasticity) def bcFactory(name): - """Factory for boundary condition items. - """ + """Factory for boundary condition items.""" from pythia.pyre.inventory import facility from pylith.bc.DirichletTimeDependent import DirichletTimeDependent + return facility(name, family="boundary_condition", factory=DirichletTimeDependent) def faultFactory(name): - """Factory for fault items. - """ + """Factory for fault items.""" from pythia.pyre.inventory import facility from pylith.faults.FaultCohesiveKin import FaultCohesiveKin + return facility(name, family="fault", factory=FaultCohesiveKin) def observerFactory(name): - """Factory for output items. - """ + """Factory for output items.""" from pythia.pyre.inventory import facility from pylith.meshio.OutputSolnDomain import OutputSolnDomain + return facility(name, family="observer", factory=OutputSolnDomain) @@ -62,58 +62,90 @@ class Problem(PetscComponent, ModuleProblem): import pythia.pyre.inventory from pylith.utils.EmptyBin import EmptyBin - defaults = pythia.pyre.inventory.facility("defaults", family="problem_defaults", factory=ProblemDefaults) - defaults.meta['tip'] = "Default options for problem." - - formulation = pythia.pyre.inventory.str("formulation", default="quasistatic", - validator=pythia.pyre.inventory.choice(["quasistatic", "dynamic", "dynamic_imex"])) - formulation.meta['tip'] = "Formulation for equations." + defaults = pythia.pyre.inventory.facility( + "defaults", family="problem_defaults", factory=ProblemDefaults + ) + defaults.meta["tip"] = "Default options for problem." + + formulation = pythia.pyre.inventory.str( + "formulation", + default="quasistatic", + validator=pythia.pyre.inventory.choice( + ["quasistatic", "dynamic", "dynamic_imex"] + ), + ) + formulation.meta["tip"] = "Formulation for equations." + + solverChoice = pythia.pyre.inventory.str( + "solver", + default="nonlinear", + validator=pythia.pyre.inventory.choice(["linear", "nonlinear"]), + ) + solverChoice.meta["tip"] = "Type of solver to use ['linear', 'nonlinear']." + + petscDefaults = pythia.pyre.inventory.facility( + "petsc_defaults", family="petsc_defaults", factory=PetscDefaults + ) + petscDefaults.meta["tip"] = "Flags controlling which default PETSc options to use." - solverChoice = pythia.pyre.inventory.str("solver", default="nonlinear", - validator=pythia.pyre.inventory.choice(["linear", "nonlinear"])) - solverChoice.meta['tip'] = "Type of solver to use ['linear', 'nonlinear']." + from .Solution import Solution - petscDefaults = pythia.pyre.inventory.facility("petsc_defaults", family="petsc_defaults", factory=PetscDefaults) - petscDefaults.meta['tip'] = "Flags controlling which default PETSc options to use." + solution = pythia.pyre.inventory.facility( + "solution", family="solution", factory=Solution + ) + solution.meta["tip"] = "Solution field for problem." - from .Solution import Solution - solution = pythia.pyre.inventory.facility("solution", family="solution", factory=Solution) - solution.meta['tip'] = "Solution field for problem." + from pylith.scales.QuasistaticElasticity import QuasistaticElasticity - from spatialdata.units.NondimElasticQuasistatic import NondimElasticQuasistatic - normalizer = pythia.pyre.inventory.facility("normalizer", family="nondimensional", factory=NondimElasticQuasistatic) - normalizer.meta['tip'] = "Nondimensionalizer for problem." + scales = pythia.pyre.inventory.facility( + "scales", family="scales", factory=QuasistaticElasticity + ) + scales.meta["tip"] = "Scales for nondimensionalizing boundary value problem." from pylith.materials.Homogeneous import Homogeneous - materials = pythia.pyre.inventory.facilityArray("materials", itemFactory=materialFactory, factory=Homogeneous) - materials.meta['tip'] = "Materials in problem." - bc = pythia.pyre.inventory.facilityArray("bc", itemFactory=bcFactory, factory=EmptyBin) - bc.meta['tip'] = "Boundary conditions." + materials = pythia.pyre.inventory.facilityArray( + "materials", itemFactory=materialFactory, factory=Homogeneous + ) + materials.meta["tip"] = "Materials in problem." + + bc = pythia.pyre.inventory.facilityArray( + "bc", itemFactory=bcFactory, factory=EmptyBin + ) + bc.meta["tip"] = "Boundary conditions." - interfaces = pythia.pyre.inventory.facilityArray("interfaces", itemFactory=faultFactory, factory=EmptyBin) - interfaces.meta['tip'] = "Interior surfaces with constraints or constitutive models." + interfaces = pythia.pyre.inventory.facilityArray( + "interfaces", itemFactory=faultFactory, factory=EmptyBin + ) + interfaces.meta["tip"] = ( + "Interior surfaces with constraints or constitutive models." + ) from pylith.problems.SingleObserver import SingleSolnObserver + observers = pythia.pyre.inventory.facilityArray( - "solution_observers", itemFactory=observerFactory, factory=SingleSolnObserver) - observers.meta['tip'] = "Observers (e.g., output) for solution." + "solution_observers", itemFactory=observerFactory, factory=SingleSolnObserver + ) + observers.meta["tip"] = "Observers (e.g., output) for solution." - gravityField = pythia.pyre.inventory.facility("gravity_field", family="spatial_database", factory=NullComponent) - gravityField.meta['tip'] = "Database used for gravity field." + gravityField = pythia.pyre.inventory.facility( + "gravity_field", family="spatial_database", factory=NullComponent + ) + gravityField.meta["tip"] = "Database used for gravity field." def __init__(self, name="problem"): - """Constructor. - """ + """Constructor.""" PetscComponent.__init__(self, name, facility="problem") self.mesh = None def preinitialize(self, mesh): - """Do minimal initialization. - """ + """Do minimal initialization.""" from pylith.mpi.Communicator import mpi_is_root + if mpi_is_root(): - self._info.log("Performing minimal initialization before verifying configuration.") + self._info.log( + "Performing minimal initialization before verifying configuration." + ) self._createModuleObj() ModuleProblem.setIdentifier(self, self.aliases[-1]) @@ -135,8 +167,8 @@ def preinitialize(self, mesh): ModuleProblem.setSolverType(self, ModuleProblem.NONLINEAR) else: raise ValueError("Unknown solver choice '%s'." % self.solverChoice) - ModuleProblem.setPetscDefaults(self, self.petscDefaults.flags()); - ModuleProblem.setNormalizer(self, self.normalizer) + ModuleProblem.setPetscDefaults(self, self.petscDefaults.flags()) + ModuleProblem.setScales(self, self.scales) if not isinstance(self.gravityField, NullComponent): ModuleProblem.setGravityField(self, self.gravityField) @@ -167,9 +199,9 @@ def preinitialize(self, mesh): ModuleProblem.preinitialize(self, mesh) def verifyConfiguration(self): - """Verify compatibility of configuration. - """ + """Verify compatibility of configuration.""" from pylith.mpi.Communicator import mpi_is_root + if mpi_is_root(): self._info.log("Verifying compatibility of problem configuration.") @@ -178,53 +210,52 @@ def verifyConfiguration(self): self._printInfo() def initialize(self): - """Initialize integrators and constraints. - """ + """Initialize integrators and constraints.""" from pylith.mpi.Communicator import mpi_is_root + if mpi_is_root(): - self._info.log(f"Initializing {self.name} problem with {self.formulation} formulation.") + self._info.log( + f"Initializing {self.name} problem with {self.formulation} formulation." + ) ModuleProblem.initialize(self) def run(self, app): - """Solve the problem. - """ + """Solve the problem.""" raise NotImplementedError("run() not implemented.") def finalize(self): - """Cleanup after running problem. - """ + """Cleanup after running problem.""" from pylith.mpi.Communicator import mpi_is_root + if mpi_is_root(): self._info.log("Finalizing problem.") def checkpoint(self): - """Save problem state for restart. - """ + """Save problem state for restart.""" raise NotImplementedError("checkpoint() not implemented.") # PRIVATE METHODS //////////////////////////////////////////////////// def _printInfo(self): - """Write overview of problem to info journal. - """ + """Write overview of problem to info journal.""" msg = ( "Scales for nondimensionalization:", - " Length scale: {}".format(self.normalizer.getLengthScale()), - " Time scale: {}".format(self.normalizer.getTimeScale()), - " Pressure scale: {}".format(self.normalizer.getPressureScale()), - " Density scale: {}".format(self.normalizer.getDensityScale()), - " Temperature scale: {}".format(self.normalizer.getTemperatureScale()), + " Length scale: {}".format(self.scales.getLengthScale()), + " Displacement scale: {}".format(self.scales.getDisplacementScale()), + " Time scale: {}".format(self.scales.getTimeScale()), + " Rigidity scale: {}".format(self.scales.getRigidityScale()), + " Temperature scale: {}".format(self.scales.getTemperatureScale()), ) self._info.log("\n".join(msg)) def _setupLogging(self): - """Setup event logging. - """ + """Setup event logging.""" if not "_loggingPrefix" in dir(self): self._loggingPrefix = "PL.Problem." from pylith.utils.EventLogger import EventLogger + logger = EventLogger() logger.setClassName("Problem") logger.initialize() diff --git a/pylith/problems/Solution.py b/pylith/problems/Solution.py index ca7a04a888..9c27171a72 100644 --- a/pylith/problems/Solution.py +++ b/pylith/problems/Solution.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from pylith.utils.PetscComponent import PetscComponent @@ -20,58 +20,77 @@ class Solution(PetscComponent): from .SolnDisp import SolnDisp from .SolutionSubfield import subfieldFactory - subfields = pythia.pyre.inventory.facilityArray("subfields", family="soln_subfields", - itemFactory=subfieldFactory, factory=SolnDisp) - subfields.meta['tip'] = "Subfields in solution." + + subfields = pythia.pyre.inventory.facilityArray( + "subfields", + family="soln_subfields", + itemFactory=subfieldFactory, + factory=SolnDisp, + ) + subfields.meta["tip"] = "Subfields in solution." def __init__(self, name="solution"): - """Constructor. - """ + """Constructor.""" PetscComponent.__init__(self, name, facility="solution") self.field = None def preinitialize(self, problem, mesh): - """Do minimal initialization of solution. - """ + """Do minimal initialization of solution.""" from pylith.mpi.Communicator import mpi_is_root + isRoot = mpi_is_root() if isRoot: self._info.log("Performing minimal initialization of solution.") from pylith.topology.Field import Field + self.field = Field(mesh) self.field.setLabel("solution") spaceDim = mesh.getCoordSys().getSpaceDim() for subfield in self.subfields.components(): - subfield.initialize(problem.normalizer, spaceDim) + subfield.initialize(problem.scales, spaceDim) if isRoot: - self._debug.log("Adding subfield '%s' as '%s' with components %s to solution." % - (subfield.fieldName, subfield.userAlias, subfield.componentNames)) + self._debug.log( + "Adding subfield '%s' as '%s' with components %s to solution." + % (subfield.fieldName, subfield.userAlias, subfield.componentNames) + ) descriptor = subfield.getTraitDescriptor("quadrature_order") - if hasattr(descriptor.locator, "source") and descriptor.locator.source == "default": + if ( + hasattr(descriptor.locator, "source") + and descriptor.locator.source == "default" + ): quadOrder = problem.defaults.quadOrder else: quadOrder = subfield.quadOrder - self.field.subfieldAdd(subfield.fieldName, subfield.userAlias, subfield.vectorFieldType, - subfield.componentNames, subfield.scale.value, subfield.basisOrder, - quadOrder, subfield.dimension, subfield.isFaultOnly, - subfield.cellBasis, subfield.feSpace, subfield.isBasisContinuous) + self.field.subfieldAdd( + subfield.fieldName, + subfield.userAlias, + subfield.vectorFieldType, + subfield.componentNames, + subfield.scale.value, + subfield.basisOrder, + quadOrder, + subfield.dimension, + subfield.isFaultOnly, + subfield.cellBasis, + subfield.feSpace, + subfield.isBasisContinuous, + ) def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" PetscComponent._configure(self) def _cleanup(self): if self.field: self.field.deallocate() + # FACTORIES //////////////////////////////////////////////////////////// def solution(): - """Factory associated with Solution. - """ + """Factory associated with Solution.""" return Solution() diff --git a/pylith/problems/SolutionSubfield.py b/pylith/problems/SolutionSubfield.py index ccc374c1e1..7eb045a83c 100644 --- a/pylith/problems/SolutionSubfield.py +++ b/pylith/problems/SolutionSubfield.py @@ -5,18 +5,18 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from pylith.topology.Subfield import Subfield def validateAlias(value): - """Validate user alias for subfield. - """ + """Validate user alias for subfield.""" if 0 == len(value): raise ValueError("User-specified alias for subfield not specified.") import re + if re.search(r"\s", value): raise ValueError("User-specified alias for subfield cannot contain whitespace.") return value @@ -31,11 +31,10 @@ class SolutionSubfield(Subfield): # Set appropriate default in derived class using _defaults(). userAlias = pythia.pyre.inventory.str("alias", default="", validator=validateAlias) - userAlias.meta['tip'] = "Name for subfield." + userAlias.meta["tip"] = "Name for subfield." def __init__(self, name="solution_subfield"): - """Constructor. - """ + """Constructor.""" Subfield.__init__(self, name) # Set in derived class initialize(). @@ -44,43 +43,48 @@ def __init__(self, name="solution_subfield"): self.scale = None self.isFaultOnly = False - def initialize(self, normalizer, spaceDim): - """Initialize subfield metadata. - """ + def initialize(self, scales, spaceDim): + """Initialize subfield metadata.""" raise NotImplementedError("Implement in derived class.") def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" from pylith.topology.topology import FieldBase + Subfield._configure(self) def _setComponents(self, spaceDim): from pylith.topology.Field import Field + self.componentNames = [] if self.vectorFieldType == Field.SCALAR: self.componentNames = [self.fieldName] elif self.vectorFieldType == Field.VECTOR: labels = ["x", "y", "z"] - self.componentNames = ["{}_{}".format(self.userAlias, label) for label in labels[:spaceDim]] + self.componentNames = [ + "{}_{}".format(self.userAlias, label) for label in labels[:spaceDim] + ] else: - raise NotImplementedError("Not implemented for vector field type %d" % self.vectorFieldType) + raise NotImplementedError( + "Not implemented for vector field type %d" % self.vectorFieldType + ) # ITEM FACTORIES /////////////////////////////////////////////////////// + def subfieldFactory(name): - """Factory for subfield items. - """ + """Factory for subfield items.""" from pythia.pyre.inventory import facility + return facility(name, family="soln_subfield", factory=SolutionSubfield) # FACTORIES //////////////////////////////////////////////////////////// + def soln_subfield(): - """Factory associated with SolutionSubfield. - """ + """Factory associated with SolutionSubfield.""" return SolutionSubfield() diff --git a/pylith/problems/SubfieldDisplacement.py b/pylith/problems/SubfieldDisplacement.py index 2d9f035e4b..9bb69aa3b2 100644 --- a/pylith/problems/SubfieldDisplacement.py +++ b/pylith/problems/SubfieldDisplacement.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .SolutionSubfield import SolutionSubfield @@ -17,6 +17,7 @@ class SubfieldDisplacement(SolutionSubfield): Implements `SolutionSubfield`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.problems.solution.subfields.displacement] @@ -28,32 +29,30 @@ class SubfieldDisplacement(SolutionSubfield): fieldName = "displacement" def __init__(self, name="subfielddisplacement"): - """Constructor. - """ + """Constructor.""" SolutionSubfield.__init__(self, name) def _defaults(self): self.userAlias = self.fieldName - def initialize(self, normalizer, spaceDim): - """Initialize subfield metadata. - """ + def initialize(self, scales, spaceDim): + """Initialize subfield metadata.""" from pylith.topology.Field import Field + self.vectorFieldType = Field.VECTOR - self.scale = normalizer.getLengthScale() + self.scale = scales.getDisplacementScale() self._setComponents(spaceDim) def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" SolutionSubfield._configure(self) + # FACTORIES //////////////////////////////////////////////////////////// def soln_subfield(): - """Factory associated with SubfieldDisplacement. - """ + """Factory associated with SubfieldDisplacement.""" return SubfieldDisplacement() diff --git a/pylith/problems/SubfieldLagrangeFault.py b/pylith/problems/SubfieldLagrangeFault.py index 482f29d1cd..1ea4e2409a 100644 --- a/pylith/problems/SubfieldLagrangeFault.py +++ b/pylith/problems/SubfieldLagrangeFault.py @@ -5,10 +5,11 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .SolutionSubfield import SolutionSubfield +from pylith.scales.ElasticityScales import ElasticityScales class SubfieldLagrangeFault(SolutionSubfield): @@ -17,6 +18,7 @@ class SubfieldLagrangeFault(SolutionSubfield): Implements `SolutionSubfield`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.problems.solution.subfields.lagrange_multiplier_fault] @@ -28,34 +30,32 @@ class SubfieldLagrangeFault(SolutionSubfield): fieldName = "lagrange_multiplier_fault" def __init__(self, name="subfieldlagrangefault"): - """Constructor. - """ + """Constructor.""" SolutionSubfield.__init__(self, name) def _defaults(self): self.userAlias = self.fieldName - def initialize(self, normalizer, spaceDim): - """Initialize subfield metadata. - """ + def initialize(self, scales, spaceDim): + """Initialize subfield metadata.""" from pylith.topology.Field import Field + self.dimension = spaceDim - 1 self.vectorFieldType = Field.VECTOR - self.scale = normalizer.getPressureScale() + self.scale = ElasticityScales.getStressScale(scales) self._setComponents(spaceDim) self.isFaultOnly = True def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" SolutionSubfield._configure(self) + # FACTORIES //////////////////////////////////////////////////////////// def soln_subfield(): - """Factory associated with SubfieldLagrangeFault. - """ + """Factory associated with SubfieldLagrangeFault.""" return SubfieldLagrangeFault() diff --git a/pylith/problems/SubfieldPressure.py b/pylith/problems/SubfieldPressure.py index 85a2350811..497e613485 100644 --- a/pylith/problems/SubfieldPressure.py +++ b/pylith/problems/SubfieldPressure.py @@ -5,10 +5,11 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .SolutionSubfield import SolutionSubfield +from pylith.scales.ElasticityScales import ElasticityScales class SubfieldPressure(SolutionSubfield): @@ -17,6 +18,7 @@ class SubfieldPressure(SolutionSubfield): Implements `SolutionSubfield`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.problems.solution.subfields.pressure] @@ -28,37 +30,35 @@ class SubfieldPressure(SolutionSubfield): fieldName = "pressure" def __init__(self, name="subfieldpressure"): - """Constructor. - """ + """Constructor.""" SolutionSubfield.__init__(self, name) return def _defaults(self): self.userAlias = self.fieldName - def initialize(self, normalizer, spaceDim): - """Initialize subfield metadata. - """ + def initialize(self, scales, spaceDim): + """Initialize subfield metadata.""" from pylith.topology.Field import Field + self.vectorFieldType = Field.SCALAR - self.scale = normalizer.getPressureScale() + self.scale = ElasticityScales.getFluidPressureScale(scales) self._setComponents(spaceDim) return # PRIVATE METHODS //////////////////////////////////////////////////// def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" SolutionSubfield._configure(self) return + # FACTORIES //////////////////////////////////////////////////////////// def soln_subfield(): - """Factory associated with SubfieldPressure. - """ + """Factory associated with SubfieldPressure.""" return SubfieldPressure() diff --git a/pylith/problems/SubfieldPressureDot.py b/pylith/problems/SubfieldPressureDot.py index d9a5ffbb11..ce00ba7ea0 100644 --- a/pylith/problems/SubfieldPressureDot.py +++ b/pylith/problems/SubfieldPressureDot.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= # @file pylith/problems/SubfieldPressureDot.py # @@ -14,6 +14,7 @@ # Factory: subfield. from .SolutionSubfield import SolutionSubfield +from pylith.scales.ElasticityScales import ElasticityScales class SubfieldPressureDot(SolutionSubfield): @@ -22,6 +23,7 @@ class SubfieldPressureDot(SolutionSubfield): Implements `SolutionSubfield`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.problems.solution.subfields.pressure_t] @@ -41,13 +43,16 @@ def __init__(self, name="subfieldpressure_t"): def _defaults(self): self.userAlias = self.fieldName - def initialize(self, normalizer, spaceDim): + def initialize(self, scales, spaceDim): """ Initialize subfield metadata. """ from pylith.topology.Field import Field + self.vectorFieldType = Field.SCALAR - self.scale = normalizer.getPressureScale() / normalizer.getTimeScale() + self.scale = ( + ElasticityScales.getFluidPressureScale(scales) / scales.getTimeScale() + ) self._setComponents(spaceDim) def _configure(self): @@ -56,6 +61,7 @@ def _configure(self): """ SolutionSubfield._configure(self) + # FACTORIES //////////////////////////////////////////////////////////// @@ -66,4 +72,4 @@ def soln_subfield(): return SubfieldPressureDot() -# End of file \ No newline at end of file +# End of file diff --git a/pylith/problems/SubfieldTemperature.py b/pylith/problems/SubfieldTemperature.py index 74b6ea9bcd..c9e8131873 100644 --- a/pylith/problems/SubfieldTemperature.py +++ b/pylith/problems/SubfieldTemperature.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .SolutionSubfield import SolutionSubfield @@ -17,6 +17,7 @@ class SubfieldTemperature(SolutionSubfield): Implements `SolutionSubfield`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.problems.solution.subfields.temperature] @@ -28,32 +29,30 @@ class SubfieldTemperature(SolutionSubfield): fieldName = "temperature" def __init__(self, name="subfieldtemperature"): - """Constructor. - """ + """Constructor.""" SolutionSubfield.__init__(self, name) def _defaults(self): self.userAlias = self.fieldName - def initialize(self, normalizer, spaceDim): - """Initialize subfield metadata. - """ + def initialize(self, scales, spaceDim): + """Initialize subfield metadata.""" from pylith.topology.Field import Field + self.vectorFieldType = Field.SCALAR - self.scale = normalizer.getTemperatureScale() + self.scale = scales.getTemperatureScale() self._setComponents(spaceDim) def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" SolutionSubfield._configure(self) + # FACTORIES //////////////////////////////////////////////////////////// def soln_subfield(): - """Factory associated with SubfieldTemperature. - """ + """Factory associated with SubfieldTemperature.""" return SubfieldTemperature() diff --git a/pylith/problems/SubfieldTraceStrain.py b/pylith/problems/SubfieldTraceStrain.py index f2d9688bf0..ed7aa3ebb2 100644 --- a/pylith/problems/SubfieldTraceStrain.py +++ b/pylith/problems/SubfieldTraceStrain.py @@ -5,10 +5,11 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .SolutionSubfield import SolutionSubfield +from pylith.scales.ElasticityScales import ElasticityScales class SubfieldTraceStrain(SolutionSubfield): @@ -17,6 +18,7 @@ class SubfieldTraceStrain(SolutionSubfield): Implements `SolutionSubfield`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.problems.solution.subfields.trace_strain] @@ -28,38 +30,35 @@ class SubfieldTraceStrain(SolutionSubfield): fieldName = "trace_strain" def __init__(self, name="subfieldtracestrain"): - """Constructor. - """ + """Constructor.""" SolutionSubfield.__init__(self, name) return def _defaults(self): self.userAlias = self.fieldName - def initialize(self, normalizer, spaceDim): - """Initialize subfield metadata. - """ + def initialize(self, scales, spaceDim): + """Initialize subfield metadata.""" from pylith.topology.Field import Field - from pythia.pyre.units.unit import one + self.vectorFieldType = Field.SCALAR - self.scale = one + self.scale = ElasticityScales.getStrainScale(scales) self._setComponents(spaceDim) return # PRIVATE METHODS //////////////////////////////////////////////////// def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" SolutionSubfield._configure(self) return + # FACTORIES //////////////////////////////////////////////////////////// def soln_subfield(): - """Factory associated with SubfieldTraceStrain. - """ + """Factory associated with SubfieldTraceStrain.""" return SubfieldTraceStrain() diff --git a/pylith/problems/SubfieldTraceStrainDot.py b/pylith/problems/SubfieldTraceStrainDot.py index 0edad84657..63e9f2750b 100644 --- a/pylith/problems/SubfieldTraceStrainDot.py +++ b/pylith/problems/SubfieldTraceStrainDot.py @@ -5,10 +5,11 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .SolutionSubfield import SolutionSubfield +from pylith.scales.ElasticityScales import ElasticityScales class SubfieldTraceStrainDot(SolutionSubfield): @@ -17,6 +18,7 @@ class SubfieldTraceStrainDot(SolutionSubfield): Implements `SolutionSubfield`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.problems.solution.subfields.trace_strain_t] @@ -36,14 +38,15 @@ def __init__(self, name="subfieldtracestrain_t"): def _defaults(self): self.userAlias = self.fieldName - def initialize(self, normalizer, spaceDim): + def initialize(self, scales, spaceDim): """ Initialize subfield metadata. """ from pylith.topology.Field import Field from pythia.pyre.units.unit import one + self.vectorFieldType = Field.SCALAR - self.scale = one / normalizer.getTimeScale() + self.scale = ElasticityScales.getStrainScale(scales) / scales.getTimeScale() self._setComponents(spaceDim) def _configure(self): @@ -52,6 +55,7 @@ def _configure(self): """ SolutionSubfield._configure(self) + # FACTORIES //////////////////////////////////////////////////////////// @@ -62,4 +66,4 @@ def soln_subfield(): return SubfieldTraceStrainDot() -# End of file \ No newline at end of file +# End of file diff --git a/pylith/problems/SubfieldVelocity.py b/pylith/problems/SubfieldVelocity.py index 6abc7a24f6..5967c7eddf 100644 --- a/pylith/problems/SubfieldVelocity.py +++ b/pylith/problems/SubfieldVelocity.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .SolutionSubfield import SolutionSubfield @@ -17,6 +17,7 @@ class SubfieldVelocity(SolutionSubfield): Implements `SolutionSubfield`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.problems.solution.subfields.velocity] @@ -28,32 +29,30 @@ class SubfieldVelocity(SolutionSubfield): fieldName = "velocity" def __init__(self, name="subfieldvelocity"): - """Constructor. - """ + """Constructor.""" SolutionSubfield.__init__(self, name) def _defaults(self): self.userAlias = self.fieldName - def initialize(self, normalizer, spaceDim): - """Initialize subfield metadata. - """ + def initialize(self, scales, spaceDim): + """Initialize subfield metadata.""" from pylith.topology.Field import Field + self.vectorFieldType = Field.VECTOR - self.scale = normalizer.getLengthScale() / normalizer.getTimeScale() + self.scale = scales.getDisplacementScale() / scales.getTimeScale() self._setComponents(spaceDim) def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" SolutionSubfield._configure(self) + # FACTORIES //////////////////////////////////////////////////////////// def soln_subfield(): - """Factory associated with SubfieldVelocity. - """ + """Factory associated with SubfieldVelocity.""" return SubfieldVelocity() diff --git a/pylith/problems/TimeDependent.py b/pylith/problems/TimeDependent.py index 6ac26267a5..644fe819ba 100644 --- a/pylith/problems/TimeDependent.py +++ b/pylith/problems/TimeDependent.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .Problem import Problem @@ -13,10 +13,10 @@ def icFactory(name): - """Factory for initial conditions items. - """ + """Factory for initial conditions items.""" from pythia.pyre.inventory import facility from pylith.problems.InitialConditionDomain import InitialConditionDomain + return facility(name, family="initial_conditions", factory=InitialConditionDomain) @@ -26,6 +26,7 @@ class TimeDependent(Problem, ModuleTimeDependent): Implements `Problem`. """ + DOC_CONFIG = { "cfg": """ # Set boundary conditions, faults, and materials @@ -39,8 +40,8 @@ class TimeDependent(Problem, ModuleTimeDependent): # Turn on gravitational body forces gravity_field = spatialdata.spatialdb.GravityField - # Set the normalizer for nondimensionalizing the problem - normalizer = spatialdata.units.NondimElasticQuasistatic + # Set the scales for nondimensionalizing the problem + scales = pylith.scales.QuasistaticElasticity # Set the subfields in the solution solution = = pylith.problems.SolnDispLagrange @@ -69,34 +70,45 @@ class TimeDependent(Problem, ModuleTimeDependent): from pythia.pyre.units.time import year from pylith.utils.EmptyBin import EmptyBin - dtInitial = pythia.pyre.inventory.dimensional("initial_dt", default=1.0 * year, - validator=pythia.pyre.inventory.greater(0.0 * year)) - dtInitial.meta['tip'] = "Initial time step." + dtInitial = pythia.pyre.inventory.dimensional( + "initial_dt", + default=1.0 * year, + validator=pythia.pyre.inventory.greater(0.0 * year), + ) + dtInitial.meta["tip"] = "Initial time step." startTime = pythia.pyre.inventory.dimensional("start_time", default=0.0 * year) - startTime.meta['tip'] = "Start time for problem." + startTime.meta["tip"] = "Start time for problem." - endTime = pythia.pyre.inventory.dimensional("end_time", default=0.1 * year, - validator=pythia.pyre.inventory.greaterEqual(0.0 * year)) - endTime.meta['tip'] = "End time for problem." + endTime = pythia.pyre.inventory.dimensional( + "end_time", + default=0.1 * year, + validator=pythia.pyre.inventory.greaterEqual(0.0 * year), + ) + endTime.meta["tip"] = "End time for problem." - maxTimeSteps = pythia.pyre.inventory.int("max_timesteps", default=20000, validator=pythia.pyre.inventory.greater(0)) - maxTimeSteps.meta['tip'] = "Maximum number of time steps." + maxTimeSteps = pythia.pyre.inventory.int( + "max_timesteps", default=20000, validator=pythia.pyre.inventory.greater(0) + ) + maxTimeSteps.meta["tip"] = "Maximum number of time steps." - ic = pythia.pyre.inventory.facilityArray("ic", itemFactory=icFactory, factory=EmptyBin) - ic.meta['tip'] = "Initial conditions." + ic = pythia.pyre.inventory.facilityArray( + "ic", itemFactory=icFactory, factory=EmptyBin + ) + ic.meta["tip"] = "Initial conditions." shouldNotifyIC = pythia.pyre.inventory.bool("notify_observers_ic", default=False) shouldNotifyIC.meta["tip"] = "Notify observers of solution with initial conditions." from .ProgressMonitorTime import ProgressMonitorTime + progressMonitor = pythia.pyre.inventory.facility( - "progress_monitor", family="progress_monitor", factory=ProgressMonitorTime) - progressMonitor.meta['tip'] = "Simple progress monitor via text file." + "progress_monitor", family="progress_monitor", factory=ProgressMonitorTime + ) + progressMonitor.meta["tip"] = "Simple progress monitor via text file." def __init__(self, name="timedependent"): - """Constructor. - """ + """Constructor.""" Problem.__init__(self, name) def preinitialize(self, mesh): @@ -106,6 +118,7 @@ def preinitialize(self, mesh): self._setupLogging() import weakref + self.mesh = weakref.ref(mesh) Problem.preinitialize(self, mesh) @@ -125,32 +138,34 @@ def preinitialize(self, mesh): ModuleTimeDependent.setProgressMonitor(self, self.progressMonitor) def run(self, app): - """Solve time dependent problem. - """ + """Solve time dependent problem.""" from pylith.mpi.Communicator import mpi_is_root + if mpi_is_root(): self._info.log("Solving problem.") ModuleTimeDependent.solve(self) def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" Problem._configure(self) if self.startTime > self.endTime: - raise ValueError("End time {} must be later than start time {}.".format(self.startTime, self.endTime)) + raise ValueError( + "End time {} must be later than start time {}.".format( + self.startTime, self.endTime + ) + ) def _createModuleObj(self): - """Create handle to C++ object. - """ + """Create handle to C++ object.""" ModuleTimeDependent.__init__(self) # FACTORIES //////////////////////////////////////////////////////////// + def problem(): - """Factory associated with TimeDependent. - """ + """Factory associated with TimeDependent.""" return TimeDependent() diff --git a/pylith/scales/DynamicElasticity.py b/pylith/scales/DynamicElasticity.py new file mode 100644 index 0000000000..c1238d1494 --- /dev/null +++ b/pylith/scales/DynamicElasticity.py @@ -0,0 +1,105 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +from .General import General + + +class DynamicElasticity(General): + """ + Convenience object for nondimensionalizing dynamic elasticity problems. + + Implements `General`. + """ + + DOC_CONFIG = { + "cfg": """ + [normalizer] + length_scale = 100.0*km + displacement_scale = 50.0*km + shear_modulus = 25.0*GPa + velocity_scale = 3.0*km/s + """, + } + + import pythia.pyre.inventory + + from pythia.pyre.units.pressure import pascal, GPa + from pythia.pyre.units.length import meter, km + from pythia.pyre.units.time import second + + lengthScale = pythia.pyre.inventory.dimensional("length_scale", default=100.0 * km) + lengthScale.validator = pythia.pyre.inventory.greater(0.0 * meter) + lengthScale.meta["tip"] = ( + "Length scale in boundary value problem (size of feature controlling displacement, fault)." + ) + + displacementScale = pythia.pyre.inventory.dimensional( + "displacement_scale", default=1.0 * meter + ) + displacementScale.validator = pythia.pyre.inventory.greater(0.0 * meter) + displacementScale.meta["tip"] = ( + "Nominal displacement scale in boundary value problem." + ) + + shearModulus = pythia.pyre.inventory.dimensional( + "shear_modulus", default=10.0 * GPa + ) + shearModulus.validator = pythia.pyre.inventory.greater(0.0 * pascal) + shearModulus.meta["tip"] = "Nominal shear modulus in boundary value problem." + + shearWaveSpeed = pythia.pyre.inventory.dimensional( + "shear_wave_speed", default=3.0 * km / second + ) + shearWaveSpeed.validator = pythia.pyre.inventory.greater(0.0 * second) + shearWaveSpeed.meta["tip"] = ( + "Time scale of boundary value problem (for example, viscoelastic relaxation time)." + ) + + # PUBLIC METHODS ///////////////////////////////////////////////////// + + def __init__(self, name="dynamicelasticity"): + """ + Constructor. + """ + Scales.__init__(self, name) + + # PRIVATE METHODS //////////////////////////////////////////////////// + + def _configure(self): + """ + Setup members using inventory. + """ + Scales._configure(self) + + displacement = self.inventory.displacementScale + length = self.inventory.lengthScale + shearModulus = self.inventory.shearModulus + shearWaveSpeed = self.inventory.shearWaveSpeed + + rigidityScale = displacement / length * shearModulus + timeScale = length / shearWaveSpeed + + self.setLengthScale(length) + self.setDisplacementScale(displacement) + self.setRigidityScale(rigidityScale) + self.setTimeScale(timeScale) + + +# FACTORIES //////////////////////////////////////////////////////////// + + +def scales(): + """ + Factory associated with DynamicElasticity. + """ + return DynamicElasticity() + + +# End of file diff --git a/pylith/scales/ElasticityScales.py b/pylith/scales/ElasticityScales.py new file mode 100644 index 0000000000..0863f14874 --- /dev/null +++ b/pylith/scales/ElasticityScales.py @@ -0,0 +1,99 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +from .scales import ElasticityScales as ModuleElasticityScales + +from pythia.pyre.units.length import km, meter +from pythia.pyre.units.time import year, second +from pythia.pyre.units.pressure import pascal +from pythia.pyre.units.mass import kg +from pythia.pyre.units.unit import one + + +class ElasticityScales(ModuleElasticityScales): + """ + Nondimensionalization for elasticity related boundary value problems. + """ + + @staticmethod + def setQuasistaticElasticity(scales, lengthScale=100.0 * km, timeScale=year): + ModuleElasticityScales.setQuasistaticElasticity( + scales, lengthScale.value, timeScale.value + ) + + @staticmethod + def setDynamicElasticity( + scales, lengthScale=100.0 * km, velocityScale=3.0 * km / second + ): + ModuleElasticityScales.setDynamicElasticity( + scales, lengthScale.value, velocityScale.value + ) + + @staticmethod + def setQuasistaticPoroelasticity( + scales, + lengthScale=100.0 * km, + permeability=1.0e-12 * meter**2, + viscosity=1.0e-3 * pascal * second, + rigidity=25.0e9 * pascal, + ): + ModuleElasticityScales.setQuasistaticPoroelasticity( + scales, + lengthScale.value, + permeability.value, + viscosity.value, + rigidity.value, + ) + + @staticmethod + def computePoroelasticityTimeScale(viscosity, permeability, length, rigidity): + timeScale = ModuleElasticityScales.computePoroelasticityTimeScale( + viscosity.value, permeability.value, length.value, rigidity.value + ) + return timeScale * second + + @staticmethod + def getStressScale(scales): + return ModuleElasticityScales.getStressScale(scales) * pascal + + @staticmethod + def getFluidPressureScale(scales): + return ModuleElasticityScales.getFluidPressureScale(scales) * pascal + + @staticmethod + def getStrainScale(scales): + return ModuleElasticityScales.getStrainScale(scales) * one + + @staticmethod + def getBodyForceScale(scales): + return ModuleElasticityScales.getBodyForceScale(scales) * pascal / meter + + @staticmethod + def getDensityScale(scales): + return ModuleElasticityScales.getDensityScale(scales) * kg / meter**3 + + @staticmethod + def getVelocityScale(scales): + return ModuleElasticityScales.getVelocityScale(scales) * meter / second + + @staticmethod + def getAccelerationScale(scales): + return ModuleElasticityScales.getAccelerationScale(scales) * meter / second**2 + + @staticmethod + def getViscosityScale(scales): + return ModuleElasticityScales.getViscosityScale(scales) * pascal * second + + @staticmethod + def getPermeabilityScale(scales): + return ModuleElasticityScales.getPermeabilityScale(scales) * meter**2 + + +# End of file diff --git a/pylith/scales/General.py b/pylith/scales/General.py new file mode 100644 index 0000000000..0c5177c4b3 --- /dev/null +++ b/pylith/scales/General.py @@ -0,0 +1,133 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +from pythia.pyre.components.Component import Component +from .scales import Scales as ModuleScales + + +class General(Component, ModuleScales): + """ + Abstract base class for nondimensionalizing problems. + """ + + # PUBLIC METHODS ///////////////////////////////////////////////////// + + def __init__(self, name="scales"): + """ + Constructor. + """ + Component.__init__(self, name, facility="scales") + + def _configure(self): + Component._configure(self) + self._createModuleObj() + + def setLengthScale(self, value): + """ + Set length scale. + """ + return ModuleScales.setLengthScale(self, value.value) + + def getLengthScale(self): + """ + Get length scale. + """ + from pythia.pyre.units.length import meter + + return ModuleScales.getLengthScale(self) * meter + + def setDisplacementScale(self, value): + """ + Set displacement scale. + """ + return ModuleScales.setDisplacementScale(self, value.value) + + def getDisplacementScale(self): + """ + Get displacement scale. + """ + from pythia.pyre.units.length import meter + + return ModuleScales.getDisplacementScale(self) * meter + + def setRigidityScale(self, value): + """ + Set pressure scale. + """ + return ModuleScales.setRigidityScale(self, value.value) + + def getRigidityScale(self): + """ + Get pressure scale. + """ + from pythia.pyre.units.pressure import pascal + + return ModuleScales.getRigidityScale(self) * pascal + + def setTimeScale(self, value): + """ + Get time scale. + """ + return ModuleScales.setTimeScale(self, value.value) + + def getTimeScale(self): + """ + Get time scale. + """ + from pythia.pyre.units.time import second + + return ModuleScales.getTimeScale(self) * second + + def setTemperatureScale(self, value): + """ + Get temperature scale. + """ + return ModuleScales.setTemperatureScale(self, value.value) + + def getTemperatureScale(self): + """ + Get temperature scale. + """ + from pythia.pyre.units.temperature import kelvin + + return ModuleScales.getTemperatureScale(self) * kelvin + + def nondimensionalize(self, value, scale): + """ + Make value dimensionless. + """ + return value / scale + + def dimensionalize(self, value, scale): + """ + Make value dimensional. + """ + return value * scale + + # PRIVATE METHODS //////////////////////////////////////////////////// + + def _createModuleObj(self): + """ + Create Python module object. + """ + ModuleScales.__init__(self) + + +# FACTORIES //////////////////////////////////////////////////////////// + + +def scales(): + """ + Factory associated with Scales. + """ + return General() + + +# End of file diff --git a/pylith/scales/QuasistaticElasticity.py b/pylith/scales/QuasistaticElasticity.py new file mode 100644 index 0000000000..b9156a08d2 --- /dev/null +++ b/pylith/scales/QuasistaticElasticity.py @@ -0,0 +1,101 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +from .General import General + + +class QuasistaticElasticity(General): + """ + Convenience object for nondimensionalizing quasi-static elasticity problems. + + Implements `General`. + """ + + DOC_CONFIG = { + "cfg": """ + [normalizer] + length_scale = 100.0*km + displacement_scale = 50.0*km + shear_modulus = 25.0*GPa + time_scale = 100.0*year + """, + } + + import pythia.pyre.inventory + + from pythia.pyre.units.pressure import pascal, GPa + from pythia.pyre.units.length import meter, km + from pythia.pyre.units.time import year + + lengthScale = pythia.pyre.inventory.dimensional("length_scale", default=100.0 * km) + lengthScale.validator = pythia.pyre.inventory.greater(0.0 * meter) + lengthScale.meta["tip"] = ( + "Length scale in boundary value problem (size of feature controlling displacement, fault)." + ) + + displacementScale = pythia.pyre.inventory.dimensional( + "displacement_scale", default=1.0 * meter + ) + displacementScale.validator = pythia.pyre.inventory.greater(0.0 * meter) + displacementScale.meta["tip"] = ( + "Nominal displacement scale in boundary value problem." + ) + + shearModulus = pythia.pyre.inventory.dimensional( + "shear_modulus", default=10.0 * GPa + ) + shearModulus.validator = pythia.pyre.inventory.greater(0.0 * pascal) + shearModulus.meta["tip"] = "Nominal shear modulus in boundary value problem." + + timeScale = pythia.pyre.inventory.dimensional("time_scale", default=100.0 * year) + timeScale.validator = pythia.pyre.inventory.greater(0.0 * year) + timeScale.meta["tip"] = ( + "Time scale of boundary value problem (for example, viscoelastic relaxation time)." + ) + + # PUBLIC METHODS ///////////////////////////////////////////////////// + + def __init__(self, name="quasistaticelasticity"): + """ + Constructor. + """ + General.__init__(self, name) + + # PRIVATE METHODS //////////////////////////////////////////////////// + + def _configure(self): + """ + Setup members using inventory. + """ + General._configure(self) + + displacement = self.inventory.displacementScale + length = self.inventory.lengthScale + shearModulus = self.inventory.shearModulus + + rigidityScale = shearModulus + + self.setLengthScale(length) + self.setDisplacementScale(displacement) + self.setRigidityScale(rigidityScale) + self.setTimeScale(self.inventory.timeScale) + + +# FACTORIES //////////////////////////////////////////////////////////// + + +def scales(): + """ + Factory associated with QuasistaticElasticity. + """ + return QuasistaticElasticity() + + +# End of file diff --git a/pylith/scales/QuasistaticPoroelasticity.py b/pylith/scales/QuasistaticPoroelasticity.py new file mode 100644 index 0000000000..1f5bbc9ef3 --- /dev/null +++ b/pylith/scales/QuasistaticPoroelasticity.py @@ -0,0 +1,109 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +from .General import General + + +class QuasistaticPoroelasticity(General): + """ + Convenience object for nondimensionalizing quasi-static poroelasticity problems. + + Implements `General`. + """ + + DOC_CONFIG = { + "cfg": """ + [normalizer] + length_scale = 100.0*km + displacement_scale = 50.0*km + shear_modulus = 25.0*GPa + viscosity = 0.001*Pa*s + permeability = 1.0e-12*m**2 + """, + } + + import pythia.pyre.inventory + + from pythia.pyre.units.pressure import pascal, GPa + from pythia.pyre.units.length import meter, km + from pythia.pyre.units.time import year, second + + lengthScale = pythia.pyre.inventory.dimensional("length_scale", default=100.0 * km) + lengthScale.validator = pythia.pyre.inventory.greater(0.0 * meter) + lengthScale.meta["tip"] = ( + "Length scale in boundary value problem (size of feature controlling displacement, fault)." + ) + + displacementScale = pythia.pyre.inventory.dimensional( + "displacement_scale", default=1.0 * meter + ) + displacementScale.validator = pythia.pyre.inventory.greater(0.0 * meter) + displacementScale.meta["tip"] = ( + "Nominal displacement scale in boundary value problem." + ) + + shearModulus = pythia.pyre.inventory.dimensional( + "shear_modulus", default=10.0 * GPa + ) + shearModulus.validator = pythia.pyre.inventory.greater(0.0 * pascal) + shearModulus.meta["tip"] = "Nominal shear modulus in boundary value problem." + + viscosity = pythia.pyre.inventory.dimensional( + "viscosity", default=0.001 * pascal * second + ) + viscosity.validator = pythia.pyre.inventory.greater(0.0 * pascal) + viscosity.meta["tip"] = "Nominal fluid viscosity in boundary value problem." + + permeability = pythia.pyre.inventory.dimensional( + "permeability", default=1.0e-13 * meter**2 + ) + permeability.validator = pythia.pyre.inventory.greater(0.0 * pascal) + permeability.meta["tip"] = "Nominal permeability in boundary value problem." + + # PUBLIC METHODS ///////////////////////////////////////////////////// + + def __init__(self, name="quasistaticporoelasticity"): + """ + Constructor. + """ + General.__init__(self, name) + + # PRIVATE METHODS //////////////////////////////////////////////////// + + def _configure(self): + """ + Setup members using inventory. + """ + from .ElasticityScales import ElasticityScales + + General._configure(self) + + ElasticityScales.setQuasistaticPoroelasticity( + self, + lengthScale=self.inventory.lengthScale, + permeability=self.inventory.permeability, + viscosity=self.inventory.viscosity, + rigidity=self.inventory.shearModulus, + ) + + self.setDisplacementScale(self.inventory.displacementScale) + + +# FACTORIES //////////////////////////////////////////////////////////// + + +def scales(): + """ + Factory associated with QuasistaticPoroelasticity. + """ + return QuasistaticPoroelasticity() + + +# End of file diff --git a/pylith/scales/__init__.py b/pylith/scales/__init__.py new file mode 100644 index 0000000000..9e48d1a3bc --- /dev/null +++ b/pylith/scales/__init__.py @@ -0,0 +1,22 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= +# +# @file pylith/scales/__init__.py +# +# @brief Python spatialdata units module initialization. + +__all__ = [ + "General", + "QuasistaticElasticity", + "DynamicElasticity", +] + + +# End of file diff --git a/pylith/topology/MeshGenerator.py b/pylith/topology/MeshGenerator.py index 75d7dca409..fa5d048399 100644 --- a/pylith/topology/MeshGenerator.py +++ b/pylith/topology/MeshGenerator.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from pylith.utils.PetscComponent import PetscComponent @@ -17,30 +17,25 @@ class MeshGenerator(PetscComponent): """ def __init__(self, name="meshgenerator"): - """Constructor. - """ + """Constructor.""" PetscComponent.__init__(self, name, facility="meshgenerator") def preinitialize(self, problem): - """Do minimal initialization. - """ + """Do minimal initialization.""" - def create(self, normalizer, faults=None): - """Generate a Mesh. - """ + def create(self, scales, faults=None): + """Generate a Mesh.""" # Need to nondimensionalize coordinates. - raise NotImplementedError("MeshGenerator.create() not implemented.") + raise NotImplementedError("MeshGenerator.create() not implemented.") def _configure(self): - """Set members based using inventory. - """ + """Set members based using inventory.""" PetscComponent._configure(self) def _adjustTopology(self, mesh, interfaces, problem): - """Adjust topology for interface implementation. - """ + """Adjust topology for interface implementation.""" logEvent = f"{self._loggingPrefix}adjTopo" self._eventLogger.eventBegin(logEvent) @@ -50,10 +45,12 @@ def _adjustTopology(self, mesh, interfaces, problem): cohesiveLabelValue = 100 for material in problem.materials.components(): labelValue = material.labelValue - cohesiveLabelValue = max(cohesiveLabelValue, labelValue+1) + cohesiveLabelValue = max(cohesiveLabelValue, labelValue + 1) for interface in interfaces: if mpi_is_root(): - self._info.log("Adjusting topology for fault '%s'." % interface.labelName) + self._info.log( + "Adjusting topology for fault '%s'." % interface.labelName + ) interface.preinitialize(problem) interface.setCohesiveLabelValue(cohesiveLabelValue) interface.adjustTopology(mesh) @@ -62,18 +59,17 @@ def _adjustTopology(self, mesh, interfaces, problem): self._eventLogger.eventEnd(logEvent) def _setupLogging(self): - """Setup event logging. - """ + """Setup event logging.""" if not "_loggingPrefix" in dir(self): self._loggingPrefix = "PL.MeshGenerator." from pylith.utils.EventLogger import EventLogger + logger = EventLogger() logger.setClassName("MeshGenerator") logger.initialize() - events = ["create", - "adjTopo"] + events = ["create", "adjTopo"] for event in events: logger.registerEvent(f"{self._loggingPrefix}{event}") diff --git a/pylith/topology/MeshImporter.py b/pylith/topology/MeshImporter.py index 44c1273857..f221670c69 100644 --- a/pylith/topology/MeshImporter.py +++ b/pylith/topology/MeshImporter.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .MeshGenerator import MeshGenerator @@ -17,6 +17,7 @@ class MeshImporter(MeshGenerator): Implements `MeshGenerator`. """ + DOC_CONFIG = { "cfg": """ [pylithapp.meshimporter] @@ -30,32 +31,41 @@ class MeshImporter(MeshGenerator): import pythia.pyre.inventory reorderMesh = pythia.pyre.inventory.bool("reorder_mesh", default=True) - reorderMesh.meta['tip'] = "Reorder mesh using reverse Cuthill-McKee." + reorderMesh.meta["tip"] = "Reorder mesh using reverse Cuthill-McKee." checkTopology = pythia.pyre.inventory.bool("check_topology", default=True) - checkTopology.meta['tip'] = "Check topology of imported mesh." + checkTopology.meta["tip"] = "Check topology of imported mesh." from pylith.meshio.MeshIOAscii import MeshIOAscii - reader = pythia.pyre.inventory.facility("reader", family="mesh_input", factory=MeshIOAscii) - reader.meta['tip'] = "Reader for mesh file." + + reader = pythia.pyre.inventory.facility( + "reader", family="mesh_input", factory=MeshIOAscii + ) + reader.meta["tip"] = "Reader for mesh file." from .Distributor import Distributor - distributor = pythia.pyre.inventory.facility("distributor", family="mesh_distributor", factory=Distributor) - distributor.meta['tip'] = "Distributes mesh among processes." + + distributor = pythia.pyre.inventory.facility( + "distributor", family="mesh_distributor", factory=Distributor + ) + distributor.meta["tip"] = "Distributes mesh among processes." from .MeshRefiner import MeshRefiner - refiner = pythia.pyre.inventory.facility("refiner", family="mesh_refiner", factory=MeshRefiner) - refiner.meta['tip'] = "Performs uniform global mesh refinement after distribution among processes (default is no refinement)." + + refiner = pythia.pyre.inventory.facility( + "refiner", family="mesh_refiner", factory=MeshRefiner + ) + refiner.meta["tip"] = ( + "Performs uniform global mesh refinement after distribution among processes (default is no refinement)." + ) def __init__(self, name="meshimporter"): - """Constructor. - """ + """Constructor.""" MeshGenerator.__init__(self, name) self._loggingPrefix = "PL.MeshImporter." def preinitialize(self, problem): - """Do minimal initialization. - """ + """Do minimal initialization.""" MeshGenerator.preinitialize(self, problem) self.reader.preinitialize() @@ -63,10 +73,10 @@ def preinitialize(self, problem): self.refiner.preinitialize() def create(self, problem, faults=None): - """Hook for creating mesh. - """ + """Hook for creating mesh.""" from pylith.utils.profiling import resourceUsageString from pylith.mpi.Communicator import mpi_is_root + isRoot = mpi_is_root() self._setupLogging() @@ -84,6 +94,7 @@ def create(self, problem, faults=None): if isRoot: self._info.log("Reordering cells and vertices.") from pylith.topology.ReverseCuthillMcKee import ReverseCuthillMcKee + ordering = ReverseCuthillMcKee() ordering.reorder(mesh) self._eventLogger.eventEnd(logEvent2) @@ -96,6 +107,7 @@ def create(self, problem, faults=None): # Distribute mesh from pylith.mpi.Communicator import mpi_comm_world + comm = mpi_comm_world() if comm.size > 1: if isRoot: @@ -113,28 +125,27 @@ def create(self, problem, faults=None): # Nondimensionalize mesh (coordinates of vertices). from pylith.topology.topology import MeshOps_nondimensionalize - MeshOps_nondimensionalize(newMesh, problem.normalizer) + + MeshOps_nondimensionalize(newMesh, problem.scales) self._eventLogger.eventEnd(logEvent) return newMesh def _configure(self): - """Set members based on inventory. - """ + """Set members based on inventory.""" MeshGenerator._configure(self) def _setupLogging(self): - """Setup event logging. - """ + """Setup event logging.""" MeshGenerator._setupLogging(self) self._eventLogger.registerEvent(f"{self._loggingPrefix}reorder") # FACTORIES //////////////////////////////////////////////////////////// + def mesh_generator(): - """Factory associated with MeshImporter. - """ + """Factory associated with MeshImporter.""" return MeshImporter() diff --git a/pylith/topology/MeshImporterDist.py b/pylith/topology/MeshImporterDist.py index 252b854a42..bf7147bcec 100644 --- a/pylith/topology/MeshImporterDist.py +++ b/pylith/topology/MeshImporterDist.py @@ -5,7 +5,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= from .MeshGenerator import MeshGenerator @@ -23,22 +23,26 @@ class MeshImporterDist(MeshGenerator): import pythia.pyre.inventory from pylith.meshio.MeshIOAscii import MeshIOAscii - reader = pythia.pyre.inventory.facility("reader", family="mesh_io", factory=MeshIOAscii) - reader.meta['tip'] = "Mesh reader." + + reader = pythia.pyre.inventory.facility( + "reader", family="mesh_io", factory=MeshIOAscii + ) + reader.meta["tip"] = "Mesh reader." from .MeshRefiner import MeshRefiner - refiner = pythia.pyre.inventory.facility("refiner", family="mesh_refiner", factory=MeshRefiner) - refiner.meta['tip'] = "Mesh refiner." + + refiner = pythia.pyre.inventory.facility( + "refiner", family="mesh_refiner", factory=MeshRefiner + ) + refiner.meta["tip"] = "Mesh refiner." def __init__(self, name="meshimporter"): - """Constructor. - """ + """Constructor.""" MeshGenerator.__init__(self, name) self._loggingPrefix = "MeIm " - def create(self, normalizer, faults=None): - """Hook for creating mesh. - """ + def create(self, scales, faults=None): + """Hook for creating mesh.""" from pylith.utils.profiling import resourceUsageString self._setupLogging() @@ -55,16 +59,18 @@ def create(self, normalizer, faults=None): # Nondimensionalize mesh (coordinates of vertices). from pylith.topology.topology import MeshOps_nondimensionalize - MeshOps_nondimensionalize(mesh, normalizer) + + MeshOps_nondimensionalize(mesh, scales) self._eventLogger.eventEnd(logEvent) return mesh + # FACTORIES //////////////////////////////////////////////////////////// + def mesh_generator(): - """Factory associated with MeshImporterDist. - """ + """Factory associated with MeshImporterDist.""" return MeshImporterDist() diff --git a/pylith/utils/PetscDefaults.py b/pylith/utils/PetscDefaults.py index 49d5a42e41..97ccb54922 100644 --- a/pylith/utils/PetscDefaults.py +++ b/pylith/utils/PetscDefaults.py @@ -49,6 +49,9 @@ class PetscDefaults(Component): testing = pythia.pyre.inventory.bool("testing", default=False) testing.meta["tip"] = "Use default PETSc testing options." + impulse_ts = pythia.pyre.inventory.bool("impulse_ts", default=False) + impulse_ts.meta["tip"] = "Use custom PETSc TS for impulses." + def __init__(self, name="petscdefaults"): """Constructor.""" Component.__init__(self, name) @@ -69,6 +72,8 @@ def flags(self): value |= ModuleDefaults.COLLECTIVE_IO if self.testing: value |= ModuleDefaults.TESTING + if self.impulse_ts: + value |= ModuleDefaults.TS_ADAPT return value diff --git a/share/settings/petsc_solver_tolerances.cfg b/share/settings/petsc_solver_tolerances.cfg index 035b067373..4e8b4244f3 100644 --- a/share/settings/petsc_solver_tolerances.cfg +++ b/share/settings/petsc_solver_tolerances.cfg @@ -1,7 +1,7 @@ # Default KSP and SNES tolerances ksp_rtol = 1.0e-12 -ksp_atol = 1.0e-12 +ksp_atol = 1.0e-7 -snes_rtol = 1.0e-12 -snes_atol = 1.0e-9 +snes_rtol = 5.0e-6 +snes_atol = 5.0e-2 diff --git a/share/settings/solver_elasticity.cfg b/share/settings/solver_elasticity.cfg index 86f532a65f..0485be6550 100644 --- a/share/settings/solver_elasticity.cfg +++ b/share/settings/solver_elasticity.cfg @@ -3,3 +3,7 @@ [pylithapp.petsc] ts_type = beuler pc_type = gamg + +pc_gamg_coarse_eq_limit = 200 +mg_fine_ksp_max_it = 5 +mg_levels_pc_type = pbjacobi diff --git a/share/settings/solver_elasticity_fault_vpbjacobi.cfg b/share/settings/solver_elasticity_fault_vpbjacobi.cfg index 0bc5b3d4b3..d3154357f2 100644 --- a/share/settings/solver_elasticity_fault_vpbjacobi.cfg +++ b/share/settings/solver_elasticity_fault_vpbjacobi.cfg @@ -6,4 +6,8 @@ pc_type = gamg dm_reorder_section = True dm_reorder_section_type = cohesive + +pc_gamg_coarse_eq_limit = 200 mg_fine_pc_type = vpbjacobi +mg_fine_ksp_max_it = 5 +mg_levels_pc_type = pbjacobi diff --git a/templates/friction/ViscousFriction.cc b/templates/friction/ViscousFriction.cc index 3302d8697e..b1e975fee7 100644 --- a/templates/friction/ViscousFriction.cc +++ b/templates/friction/ViscousFriction.cc @@ -18,9 +18,9 @@ #include "pylith/materials/Metadata.hh" // USES Metadata #include "pylith/utils/array.hh" // USES scaary_array -#include "pylith/utils/constdefs.h" // USES PYLITH_MAXSCALAR +#include "pylith/utils/constants.hh" // USES PYLITH_MAXSCALAR -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES assert() #include // USES std::ostringstream @@ -167,22 +167,22 @@ void contrib::friction::ViscousFriction::_nondimProperties(PylithScalar* const values, const int nvalues) const { // _nondimProperties // Check consistency of arguments. - assert(_normalizer); + assert(_scales); assert(values); assert(nvalues == _ViscousFriction::numProperties); // Get scales needed to nondimensional parameters from the - // Nondimensional object. - const PylithScalar lengthScale = _normalizer->getLengthScale(); - const PylithScalar timeScale = _normalizer->getTimeScale(); - const PylithScalar pressureScale = _normalizer->getPressureScale(); + // Scales object. + const PylithScalar lengthScale = _scales->getLengthScale(); + const PylithScalar timeScale = _scales->getTimeScale(); + const PylithScalar rigidityScale = _scales->getRigidityScale(); const PylithScalar velocityScale = lengthScale / timeScale; - // Use the Nondimensional::nondimensionalize() function to + // Use the Scales::nondimensionalize() function to // nondimensionalize the quantities using the appropriate scale. - values[p_v0] = _normalizer->nondimensionalize(values[p_v0], velocityScale); + values[p_v0] = _scales->nondimensionalize(values[p_v0], velocityScale); values[p_cohesion] = - _normalizer->nondimensionalize(values[p_cohesion], pressureScale); + _scales->nondimensionalize(values[p_cohesion], rigidityScale); } // _nondimProperties @@ -192,22 +192,22 @@ void contrib::friction::ViscousFriction::_dimProperties(PylithScalar* const values, const int nvalues) const { // _dimProperties // Check consistency of arguments. - assert(_normalizer); + assert(_scales); assert(values); assert(nvalues == _ViscousFriction::numProperties); // Get scales needed to dimensional parameters from the - // Nondimensional object. - const PylithScalar lengthScale = _normalizer->getLengthScale(); - const PylithScalar timeScale = _normalizer->getTimeScale(); - const PylithScalar pressureScale = _normalizer->getPressureScale(); + // Scales object. + const PylithScalar lengthScale = _scales->getLengthScale(); + const PylithScalar timeScale = _scales->getTimeScale(); + const PylithScalar rigidityScale = _scales->getRigidityScale(); const PylithScalar velocityScale = lengthScale / timeScale; - // Use the Nondimensional::dimensionalize() function to + // Use the Scales::dimensionalize() function to // dimensionalize the quantities using the appropriate scale. - values[p_v0] = _normalizer->dimensionalize(values[p_v0], velocityScale); + values[p_v0] = _scales->dimensionalize(values[p_v0], velocityScale); values[p_cohesion] = - _normalizer->dimensionalize(values[p_cohesion], pressureScale); + _scales->dimensionalize(values[p_cohesion], rigidityScale); } // _dimProperties @@ -237,20 +237,20 @@ void contrib::friction::ViscousFriction::_nondimStateVars(PylithScalar* const values, const int nvalues) const { // _nondimStateVars // Check consistency of arguments. - assert(_normalizer); + assert(_scales); assert(values); assert(nvalues == _ViscousFriction::numStateVars); // Get scales needed to nondimensional parameters from the - // Nondimensional object. - const PylithScalar lengthScale = _normalizer->getLengthScale(); - const PylithScalar timeScale = _normalizer->getTimeScale(); + // Scales object. + const PylithScalar lengthScale = _scales->getLengthScale(); + const PylithScalar timeScale = _scales->getTimeScale(); const PylithScalar velocityScale = lengthScale / timeScale; - // Use the Nondimensional::dimensionalize() function to + // Use the Scales::dimensionalize() function to // dimensionalize the quantities using the appropriate scale. values[s_slipRate] = - _normalizer->nondimensionalize(values[s_slipRate], velocityScale); + _scales->nondimensionalize(values[s_slipRate], velocityScale); } // _nondimStateVars @@ -260,20 +260,20 @@ void contrib::friction::ViscousFriction::_dimStateVars(PylithScalar* const values, const int nvalues) const { // _dimStateVars // Check consistency of arguments. - assert(_normalizer); + assert(_scales); assert(values); assert(nvalues == _ViscousFriction::numStateVars); // Get scales needed to dimensional parameters from the - // Nondimensional object. - const PylithScalar lengthScale = _normalizer->getLengthScale(); - const PylithScalar timeScale = _normalizer->getTimeScale(); + // Scales object. + const PylithScalar lengthScale = _scales->getLengthScale(); + const PylithScalar timeScale = _scales->getTimeScale(); const PylithScalar velocityScale = lengthScale / timeScale; - // Use the Nondimensional::dimensionalize() function to + // Use the Scales::dimensionalize() function to // dimensionalize the quantities using the appropriate scale. values[s_slipRate] = - _normalizer->dimensionalize(values[s_slipRate], velocityScale); + _scales->dimensionalize(values[s_slipRate], velocityScale); } // _dimStateVars diff --git a/templates/friction/frictioncontrib.i b/templates/friction/frictioncontrib.i index 1dab28f76b..848c7c900d 100644 --- a/templates/friction/frictioncontrib.i +++ b/templates/friction/frictioncontrib.i @@ -19,7 +19,7 @@ #include "pylith/friction/frictionfwd.hh" // forward declarations #include "spatialdata/spatialdb/spatialdbfwd.hh" // forward declarations -#include "spatialdata/units/unitsfwd.hh" // forward declarations +#include "pylith/scales/scalesfwd.hh" // forward declarations #include "ViscousFriction.hh" diff --git a/templates/materials/PlaneStrainState.cc b/templates/materials/PlaneStrainState.cc index 6d26e1bf0c..8fc0a9fb49 100644 --- a/templates/materials/PlaneStrainState.cc +++ b/templates/materials/PlaneStrainState.cc @@ -18,9 +18,9 @@ #include "pylith/materials/Metadata.hh" // USES Metadata #include "pylith/utils/array.hh" // USES scalar_array -#include "pylith/utils/constdefs.h" // USES MAXDOUBLE +#include "pylith/utils/constants.hh" // USES pylith::max_double -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES assert() #include // USES std::ostringstream @@ -191,23 +191,23 @@ void contrib::materials::PlaneStrainState::_nondimProperties(PylithScalar* const values, const int nvalues) const { // _nondimProperties // Check consistency of arguments. - assert(_normalizer); + assert(_scales); assert(values); assert(nvalues == _PlaneStrainState::numProperties); // Get scales needed to nondimensional parameters from the - // Nondimensional object. - const PylithScalar densityScale = _normalizer->getDensityScale(); - const PylithScalar pressureScale = _normalizer->getPressureScale(); + // Scales object. + const PylithScalar densityScale = _scales->getDensityScale(); + const PylithScalar rigidityScale = _scales->getRigidityScale(); - // Use the Nondimensional::nondimensionalize() function to + // Use the Scales::nondimensionalize() function to // nondimensionalize the quantities using the appropriate scale. values[p_density] = - _normalizer->nondimensionalize(values[p_density], densityScale); + _scales->nondimensionalize(values[p_density], densityScale); values[p_mu] = - _normalizer->nondimensionalize(values[p_mu], pressureScale); + _scales->nondimensionalize(values[p_mu], rigidityScale); values[p_lambda] = - _normalizer->nondimensionalize(values[p_lambda], pressureScale); + _scales->nondimensionalize(values[p_lambda], rigidityScale); } // _nondimProperties @@ -217,23 +217,23 @@ void contrib::materials::PlaneStrainState::_dimProperties(PylithScalar* const values, const int nvalues) const { // _dimProperties // Check consistency of arguments - assert(_normalizer); + assert(_scales); assert(values); assert(nvalues == _PlaneStrainState::numProperties); // Get scales needed to dimensional parameters from the - // Nondimensional object. - const PylithScalar densityScale = _normalizer->getDensityScale(); - const PylithScalar pressureScale = _normalizer->getPressureScale(); + // Scales object. + const PylithScalar densityScale = _scales->getDensityScale(); + const PylithScalar rigidityScale = _scales->getRigidityScale(); - // Use the Nondimensional::dimensionalize() function to + // Use the Scales::dimensionalize() function to // dimensionalize the quantities using the appropriate scale. values[p_density] = - _normalizer->dimensionalize(values[p_density], densityScale); + _scales->dimensionalize(values[p_density], densityScale); values[p_mu] = - _normalizer->dimensionalize(values[p_mu], pressureScale); + _scales->dimensionalize(values[p_mu], rigidityScale); values[p_lambda] = - _normalizer->dimensionalize(values[p_lambda], pressureScale); + _scales->dimensionalize(values[p_lambda], rigidityScale); } // _dimProperties diff --git a/templates/materials/PlaneStrainState.hh b/templates/materials/PlaneStrainState.hh index ee02b7b19d..ab78b2964c 100644 --- a/templates/materials/PlaneStrainState.hh +++ b/templates/materials/PlaneStrainState.hh @@ -58,7 +58,7 @@ public: /** Get stable time step for implicit time integration. * - * Default is MAXDOUBLE (or 1.0e+30 if MAXFLOAT is not defined in math.h). + * Default is pylith::max_double. * * This function is optional but provides an optimized * implementation of the more general diff --git a/templates/materials/PlaneStrainState.i b/templates/materials/PlaneStrainState.i index fa397a34aa..e867cc8a26 100644 --- a/templates/materials/PlaneStrainState.i +++ b/templates/materials/PlaneStrainState.i @@ -36,8 +36,7 @@ public: /** Get stable time step for implicit time integration. * - * Default is MAXDOUBLE (or 1.0e+30 if MAXFLOAT is not defined - * in math.h). + * Default is pylith::max_double. * * This function is optional but provides an optimized * implementation of the more general diff --git a/templates/materials/materialscontrib.i b/templates/materials/materialscontrib.i index a0d20d4c38..cd027b9085 100644 --- a/templates/materials/materialscontrib.i +++ b/templates/materials/materialscontrib.i @@ -19,7 +19,7 @@ #include "pylith/materials/materialsfwd.hh" // forward declarations #include "spatialdata/spatialdb/spatialdbfwd.hh" // forward declarations -#include "spatialdata/units/unitsfwd.hh" // forward declarations +#include "pylith/scales/scalesfwd.hh" // forward declarations #include "PlaneStrainState.hh" diff --git a/tests/fullscale/cornercases/faults-2d/pylithapp.cfg b/tests/fullscale/cornercases/faults-2d/pylithapp.cfg index 830c113b4c..1ef6528279 100644 --- a/tests/fullscale/cornercases/faults-2d/pylithapp.cfg +++ b/tests/fullscale/cornercases/faults-2d/pylithapp.cfg @@ -47,6 +47,8 @@ coordsys.space_dim = 2 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km + solution = pylith.problems.SolnDispLagrange # ---------------------------------------------------------------------- diff --git a/tests/fullscale/cornercases/nofaults-2d/pylithapp.cfg b/tests/fullscale/cornercases/nofaults-2d/pylithapp.cfg index 3d6bb48bf9..eaeb902193 100644 --- a/tests/fullscale/cornercases/nofaults-2d/pylithapp.cfg +++ b/tests/fullscale/cornercases/nofaults-2d/pylithapp.cfg @@ -45,6 +45,8 @@ coordsys.space_dim = 2 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km + defaults.quadrature_order = 1 solver = nonlinear diff --git a/tests/fullscale/cornercases/nofaults-3d/pylithapp.cfg b/tests/fullscale/cornercases/nofaults-3d/pylithapp.cfg index 2c5fc58c1d..c4531b854b 100644 --- a/tests/fullscale/cornercases/nofaults-3d/pylithapp.cfg +++ b/tests/fullscale/cornercases/nofaults-3d/pylithapp.cfg @@ -45,6 +45,8 @@ coordsys.space_dim = 3 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km + defaults.quadrature_order = 1 solver = nonlinear diff --git a/tests/fullscale/incompressibleelasticity/nofaults-2d/pylithapp.cfg b/tests/fullscale/incompressibleelasticity/nofaults-2d/pylithapp.cfg index a19804e6ac..6ac3e0041f 100644 --- a/tests/fullscale/incompressibleelasticity/nofaults-2d/pylithapp.cfg +++ b/tests/fullscale/incompressibleelasticity/nofaults-2d/pylithapp.cfg @@ -45,6 +45,8 @@ coordsys.space_dim = 2 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km + defaults.quadrature_order = 1 # Use nonlinear solver to ensure residual and Jacobian are consistent. diff --git a/tests/fullscale/incompressibleelasticity/nofaults-3d/pylithapp.cfg b/tests/fullscale/incompressibleelasticity/nofaults-3d/pylithapp.cfg index 9be58350c8..97c2d2f7b3 100644 --- a/tests/fullscale/incompressibleelasticity/nofaults-3d/pylithapp.cfg +++ b/tests/fullscale/incompressibleelasticity/nofaults-3d/pylithapp.cfg @@ -46,6 +46,8 @@ coordsys.space_dim = 3 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 6.0*km + defaults.quadrature_order = 1 # Use nonlinear solver to ensure residual and Jacobian are consistent. diff --git a/tests/fullscale/linearelasticity/faults-2d/pylithapp.cfg b/tests/fullscale/linearelasticity/faults-2d/pylithapp.cfg index b930bba144..325545243d 100644 --- a/tests/fullscale/linearelasticity/faults-2d/pylithapp.cfg +++ b/tests/fullscale/linearelasticity/faults-2d/pylithapp.cfg @@ -48,6 +48,8 @@ coordsys.space_dim = 2 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km + solution = pylith.problems.SolnDispLagrange [pylithapp.problem] @@ -149,13 +151,11 @@ observers.observer.data_fields = [slip, traction_change, lagrange_multiplier_fau [pylithapp.problem.petsc_defaults] solver = True testing = True -monitors = False +monitors = True [pylithapp.petsc] -ksp_rtol = 1.0e-15 -ksp_atol = 1.0e-15 - snes_max_it = 1 +ksp_monitor = # End of file diff --git a/tests/fullscale/linearelasticity/faults-3d-buried/pylithapp.cfg b/tests/fullscale/linearelasticity/faults-3d-buried/pylithapp.cfg index 6fcf1eb671..dea9f17af7 100644 --- a/tests/fullscale/linearelasticity/faults-3d-buried/pylithapp.cfg +++ b/tests/fullscale/linearelasticity/faults-3d-buried/pylithapp.cfg @@ -50,6 +50,8 @@ coordsys.space_dim = 3 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 10.0*km + defaults.quadrature_order = 1 # Use nonlinear solver to ensure residual and Jacobian are consistent. @@ -101,13 +103,6 @@ testing = True monitors = True [pylithapp.petsc] -ksp_rtol = 1.0e-15 -ksp_atol = 1.0e-15 -ksp_max_it = 100 -ksp_gmres_restart = 50 - -snes_atol = 1.0e-12 - snes_max_it = 1 diff --git a/tests/fullscale/linearelasticity/faults-3d/TestTwoBlocks.py b/tests/fullscale/linearelasticity/faults-3d/TestTwoBlocks.py index d57bece0cd..299225b3db 100644 --- a/tests/fullscale/linearelasticity/faults-3d/TestTwoBlocks.py +++ b/tests/fullscale/linearelasticity/faults-3d/TestTwoBlocks.py @@ -6,12 +6,12 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= import unittest -from pylith.testing.FullTestApp import (FullTestCase, Check) +from pylith.testing.FullTestApp import FullTestCase, Check import meshes import twoblocks_soln @@ -35,25 +35,30 @@ def setUp(self): Check( mesh_entities=["mat_elastic"], filename="output/{name}-{mesh_entity}_info.h5", - cell_fields = ["density", "bulk_modulus", "shear_modulus"], + cell_fields=["density", "bulk_modulus", "shear_modulus"], defaults=defaults, ), Check( mesh_entities=["mat_elastic"], - vertex_fields = ["displacement"], - cell_fields = ["cauchy_strain"], + vertex_fields=["displacement"], + cell_fields=["cauchy_strain"], defaults=defaults, ), Check( mesh_entities=["mat_elastic"], - cell_fields = ["cauchy_stress"], - scale = 1.0e+6, + cell_fields=["cauchy_stress"], + scale=1.0e6, defaults=defaults, ), Check( mesh_entities=["bc_xneg", "bc_xpos"], filename="output/{name}-{mesh_entity}_info.h5", - vertex_fields=["initial_amplitude", "normal_dir", "horizontal_tangential_dir", "vertical_tangential_dir"], + vertex_fields=[ + "initial_amplitude", + "normal_dir", + "horizontal_tangential_dir", + "vertical_tangential_dir", + ], defaults=defaults, ), Check( @@ -69,7 +74,7 @@ def setUp(self): Check( mesh_entities=["fault"], vertex_fields=["traction_change"], - scale = 1.0e+6, + scale=1.0e6, defaults=defaults, ), ] @@ -86,7 +91,12 @@ def setUp(self): self.mesh = meshes.HexGmsh() super().setUp() - TestCase.run_pylith(self, self.name, ["twoblocks.cfg", "twoblocks_hex.cfg", "solver_fault_fieldsplit.cfg"], nprocs=2) + TestCase.run_pylith( + self, + self.name, + ["twoblocks.cfg", "twoblocks_hex.cfg", "solver_fault_fieldsplit.cfg"], + nprocs=2, + ) return @@ -98,7 +108,12 @@ def setUp(self): self.mesh = meshes.TetGmsh() super().setUp() - TestCase.run_pylith(self, self.name, ["twoblocks.cfg", "twoblocks_tet.cfg", "solver_fault_fieldsplit.cfg"], nprocs=3) + TestCase.run_pylith( + self, + self.name, + ["twoblocks.cfg", "twoblocks_tet.cfg", "solver_fault_fieldsplit.cfg"], + nprocs=3, + ) return @@ -111,7 +126,7 @@ def test_cases(): # ------------------------------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": FullTestCase.parse_args() suite = unittest.TestSuite() diff --git a/tests/fullscale/linearelasticity/faults-3d/pylithapp.cfg b/tests/fullscale/linearelasticity/faults-3d/pylithapp.cfg index 6a38ebea06..93fe58b99f 100644 --- a/tests/fullscale/linearelasticity/faults-3d/pylithapp.cfg +++ b/tests/fullscale/linearelasticity/faults-3d/pylithapp.cfg @@ -50,6 +50,8 @@ coordsys.space_dim = 3 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km + defaults.quadrature_order = 1 # Use nonlinear solver to ensure residual and Jacobian are consistent. @@ -107,9 +109,6 @@ testing = True monitors = False [pylithapp.petsc] -ksp_rtol = 1.0e-15 -ksp_atol = 1.0e-15 - snes_max_it = 1 diff --git a/tests/fullscale/linearelasticity/faults-3d/solver_fault_fieldsplit.cfg b/tests/fullscale/linearelasticity/faults-3d/solver_fault_fieldsplit.cfg index b67ff9f955..ee78ef7ee5 100644 --- a/tests/fullscale/linearelasticity/faults-3d/solver_fault_fieldsplit.cfg +++ b/tests/fullscale/linearelasticity/faults-3d/solver_fault_fieldsplit.cfg @@ -16,10 +16,5 @@ fieldsplit_displacement_pc_type = ml fieldsplit_lagrange_multiplier_fault_ksp_type = preonly fieldsplit_lagrange_multiplier_fault_pc_type = ml -ksp_rtol = 1.0e-12 -ksp_atol = 1.0e-12 ksp_error_if_not_converged = true - -snes_rtol = 1.0e-12 -snes_atol = 1.0e-9 snes_error_if_not_converged = true diff --git a/tests/fullscale/linearelasticity/greensfns-2d/pylithapp.cfg b/tests/fullscale/linearelasticity/greensfns-2d/pylithapp.cfg index 16d446bd6a..50b504cbeb 100644 --- a/tests/fullscale/linearelasticity/greensfns-2d/pylithapp.cfg +++ b/tests/fullscale/linearelasticity/greensfns-2d/pylithapp.cfg @@ -57,6 +57,8 @@ coordsys.space_dim = 2 problem = pylith.problems.GreensFns [pylithapp.greensfns] +scales.length_scale = 8.0*km + label = fault label_value = 20 @@ -149,9 +151,6 @@ testing = True monitors = False [pylithapp.petsc] -ksp_max_it = 100 -ksp_gmres_restart = 50 - snes_max_it = 1 diff --git a/tests/fullscale/linearelasticity/nofaults-2d/TestShearTractionRate.py b/tests/fullscale/linearelasticity/nofaults-2d/TestShearTractionRate.py index ac9f303bf2..f90c495328 100644 --- a/tests/fullscale/linearelasticity/nofaults-2d/TestShearTractionRate.py +++ b/tests/fullscale/linearelasticity/nofaults-2d/TestShearTractionRate.py @@ -6,12 +6,12 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= import unittest -from pylith.testing.FullTestApp import (FullTestCase, Check) +from pylith.testing.FullTestApp import FullTestCase, Check import meshes import sheartraction_rate_soln @@ -36,19 +36,23 @@ def setUp(self): Check( mesh_entities=["elastic_xpos", "elastic_xneg"], filename="output/{name}-{mesh_entity}_info.h5", - cell_fields = ["density", "bulk_modulus", "shear_modulus"], + cell_fields=["density", "bulk_modulus", "shear_modulus"], defaults=defaults, ), Check( mesh_entities=["elastic_xpos", "elastic_xneg"], - vertex_fields = ["displacement"], - cell_fields = ["cauchy_strain", "cauchy_stress"], + vertex_fields=["displacement"], + cell_fields=["cauchy_strain", "cauchy_stress"], defaults=defaults, ), Check( mesh_entities=["bc_xneg", "bc_xpos", "bc_yneg", "bc_ypos"], filename="output/{name}-{mesh_entity}_info.h5", - vertex_fields=["initial_amplitude", "rate_start_time", "rate_amplitude"], + vertex_fields=[ + "initial_amplitude", + "rate_start_time", + "rate_amplitude", + ], defaults=defaults, ), Check( @@ -59,7 +63,9 @@ def setUp(self): ] def run_pylith(self, testName, args): - FullTestCase.run_pylith(self, testName, args, sheartraction_rate_gendb.GenerateDB) + FullTestCase.run_pylith( + self, testName, args, sheartraction_rate_gendb.GenerateDB + ) # ------------------------------------------------------------------------------------------------- @@ -70,7 +76,9 @@ def setUp(self): self.mesh = meshes.QuadGmsh() super().setUp() - TestCase.run_pylith(self, self.name, ["sheartraction_rate.cfg", "sheartraction_rate_quad.cfg"]) + TestCase.run_pylith( + self, self.name, ["sheartraction_rate.cfg", "sheartraction_rate_quad.cfg"] + ) return @@ -82,7 +90,9 @@ def setUp(self): self.mesh = meshes.TriGmsh() super().setUp() - TestCase.run_pylith(self, self.name, ["sheartraction_rate.cfg", "sheartraction_rate_tri.cfg"]) + TestCase.run_pylith( + self, self.name, ["sheartraction_rate.cfg", "sheartraction_rate_tri.cfg"] + ) return @@ -95,7 +105,7 @@ def test_cases(): # ------------------------------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": FullTestCase.parse_args() suite = unittest.TestSuite() diff --git a/tests/fullscale/linearelasticity/nofaults-2d/bodyforce.cfg b/tests/fullscale/linearelasticity/nofaults-2d/bodyforce.cfg index 9ba9f16d11..2a32b9a087 100644 --- a/tests/fullscale/linearelasticity/nofaults-2d/bodyforce.cfg +++ b/tests/fullscale/linearelasticity/nofaults-2d/bodyforce.cfg @@ -136,22 +136,5 @@ output.writer.filename = output/bodyforce-yneg.h5 # ---------------------------------------------------------------------- # PETSc # ---------------------------------------------------------------------- -[pylithapp.petsc] -pc_type = ilu - -ksp_rtol = 1.0e-8 -ksp_atol = 1.0e-12 -ksp_max_it = 1000 -ksp_gmres_restart = 50 - -ts_monitor = true -ksp_monitor = true -ksp_view = true ; :DEBUGGING: -ksp_converged_reason = true - -#snes_view = true ; :DEBUGGING: -snes_monitor = true -snes_converged_reason = true -snes_linesearch_monitor = true ; :DEBUGGING: - -# start_in_debugger = true +#[pylithapp.petsc] +#pc_type = ilu diff --git a/tests/fullscale/linearelasticity/nofaults-2d/pylithapp.cfg b/tests/fullscale/linearelasticity/nofaults-2d/pylithapp.cfg index 6b1f7a7e67..e0607839ee 100644 --- a/tests/fullscale/linearelasticity/nofaults-2d/pylithapp.cfg +++ b/tests/fullscale/linearelasticity/nofaults-2d/pylithapp.cfg @@ -19,6 +19,7 @@ command = mpiexec -np ${nodes} #timedependent = 1 #solution = 1 #petsc = 1 +#petscoptions = 1 #meshio = 1 #isotropiclinearelasticity = 1 #dirichlettimedependent = 1 @@ -31,6 +32,7 @@ command = mpiexec -np ${nodes} #constraintspatialdb = 1 #outputphysics = 1 #outputsolndomain = 1 +#timedependent.view_residual = 1 # ---------------------------------------------------------------------- # mesh_generator @@ -39,13 +41,14 @@ command = mpiexec -np ${nodes} reader = pylith.meshio.MeshIOPetsc [pylithapp.mesh_generator.reader] -# filename = mesh_CELL.exo coordsys.space_dim = 2 # ---------------------------------------------------------------------- # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km + defaults.quadrature_order = 1 # Use nonlinear solver to ensure residual and Jacobian are consistent. @@ -97,10 +100,7 @@ testing = True monitors = False [pylithapp.petsc] -ksp_max_it = 1000 -ksp_gmres_restart = 50 - -snes_atol = 1.0e-10 +snes_max_it = 1 # End of file diff --git a/tests/fullscale/linearelasticity/nofaults-2d/sheartraction_rate.cfg b/tests/fullscale/linearelasticity/nofaults-2d/sheartraction_rate.cfg index 30390203e2..cf5113dacb 100644 --- a/tests/fullscale/linearelasticity/nofaults-2d/sheartraction_rate.cfg +++ b/tests/fullscale/linearelasticity/nofaults-2d/sheartraction_rate.cfg @@ -27,8 +27,8 @@ initial_dt = 1.0*year start_time = -1.0*year end_time = 5.0*year -[pylithapp.problem.normalizer] -relaxation_time = 10.0*year +[pylithapp.problem.scales] +time_scale = 10.0*year # ---------------------------------------------------------------------- # solution diff --git a/tests/fullscale/linearelasticity/nofaults-3d/pylithapp.cfg b/tests/fullscale/linearelasticity/nofaults-3d/pylithapp.cfg index 5d1dfb57d9..4fe37d66b5 100644 --- a/tests/fullscale/linearelasticity/nofaults-3d/pylithapp.cfg +++ b/tests/fullscale/linearelasticity/nofaults-3d/pylithapp.cfg @@ -46,6 +46,8 @@ coordsys.space_dim = 3 # problem # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km + defaults.quadrature_order = 1 # Use nonlinear solver to ensure residual and Jacobian are consistent. @@ -95,8 +97,7 @@ testing = True monitors = False [pylithapp.petsc] -ksp_max_it = 100 -ksp_gmres_restart = 50 +snes_max_it = 1 # End of file diff --git a/tests/fullscale/linearelasticity/nofaults-3d/sheartraction_rate.cfg b/tests/fullscale/linearelasticity/nofaults-3d/sheartraction_rate.cfg index a483b2f619..d0de42c92d 100644 --- a/tests/fullscale/linearelasticity/nofaults-3d/sheartraction_rate.cfg +++ b/tests/fullscale/linearelasticity/nofaults-3d/sheartraction_rate.cfg @@ -27,8 +27,8 @@ initial_dt = 1.0*year start_time = -1.0*year end_time = 5.0*year -[pylithapp.problem.normalizer] -relaxation_time = 10.0*year +[pylithapp.problem.scales] +time_scale = 10.0*year # ---------------------------------------------------------------------- # solution diff --git a/tests/fullscale/poroelasticity/cryer/Makefile.am b/tests/fullscale/poroelasticity/cryer/Makefile.am index 9cc2f4dbd0..eaef285b21 100644 --- a/tests/fullscale/poroelasticity/cryer/Makefile.am +++ b/tests/fullscale/poroelasticity/cryer/Makefile.am @@ -13,24 +13,17 @@ TESTS = test_pylith.py dist_check_SCRIPTS = test_pylith.py dist_noinst_PYTHON = \ + generate_gmsh.py \ meshes.py \ TestCryer.py \ cryer_soln.py dist_noinst_DATA = \ - geometry.jou \ - bc.jou \ - mesh_tet.jou \ - mesh_tet.exo \ - mesh_hex.jou \ - mesh_hex.exo \ - cryer.cfg \ + pylithapp.cfg \ + mesh_tet.msh \ cryer_tet.cfg \ cryer_hex.cfg -noinst_TMP = \ - cryer_bc.spatialdb \ - cryer_ic.spatialdb export_datadir = $(abs_builddir) include $(top_srcdir)/tests/data.am diff --git a/tests/fullscale/poroelasticity/cryer/TestCryer.py b/tests/fullscale/poroelasticity/cryer/TestCryer.py index 2ce84a1fb7..a32f533de0 100644 --- a/tests/fullscale/poroelasticity/cryer/TestCryer.py +++ b/tests/fullscale/poroelasticity/cryer/TestCryer.py @@ -35,15 +35,10 @@ def setUp(self): self.checks = [ Check( mesh_entities=["domain"], - vertex_fields=["displacement"], + vertex_fields=["displacement", "pressure"], + final_time_only=True, + tolerance=0.09, defaults=defaults, - tolerance=0.5, - ), - Check( - mesh_entities=["domain"], - vertex_fields=["pressure"], - defaults=defaults, - scale=1.0e+6, ), Check( mesh_entities=["poroelastic"], @@ -62,34 +57,16 @@ def setUp(self): defaults=defaults, ), Check( - mesh_entities=["poroelastic"], - vertex_fields = ["displacement"], - defaults=defaults, - tolerance=0.5, - ), - Check( - mesh_entities=["poroelastic"], - vertex_fields = ["pressure"], - defaults=defaults, - scale=1.0e+6, - ), - Check( - mesh_entities=["x_neg", "y_neg", "z_neg", "surface_pressure"], + mesh_entities=["bc_xneg", "bc_yneg", "bc_zneg", "bc_shell_pressure"], filename="output/{name}-{mesh_entity}_info.h5", vertex_fields=["initial_amplitude"], defaults=defaults, ), Check( - mesh_entities=["x_neg", "y_neg", "z_neg", "surface_pressure"], - vertex_fields=["displacement"], - defaults=defaults, - tolerance=0.5, - ), - Check( - mesh_entities=["x_neg", "y_neg", "z_neg", "surface_pressure"], - vertex_fields=["pressure"], + mesh_entities=["bc_shell_traction"], + filename="output/{name}-{mesh_entity}_info.h5", + cell_fields=["initial_amplitude"], defaults=defaults, - scale=1.0e+6, ), ] @@ -105,7 +82,7 @@ def setUp(self): self.mesh = meshes.Hex() super().setUp() - TestCase.run_pylith(self, self.name, ["cryer.cfg", "cryer_hex.cfg"]) + TestCase.run_pylith(self, self.name, ["cryer_hex.cfg"]) return @@ -117,14 +94,14 @@ def setUp(self): self.mesh = meshes.Tet() super().setUp() - TestCase.run_pylith(self, self.name, ["cryer.cfg", "cryer_tet.cfg"]) + TestCase.run_pylith(self, self.name, ["cryer_tet.cfg"]) return # ------------------------------------------------------------------------------------------------- def test_cases(): return [ - TestHex, + #TestHex, TestTet, ] diff --git a/tests/fullscale/poroelasticity/cryer/bc.jou b/tests/fullscale/poroelasticity/cryer/bc.jou deleted file mode 100644 index d4593a3857..0000000000 --- a/tests/fullscale/poroelasticity/cryer/bc.jou +++ /dev/null @@ -1,35 +0,0 @@ -# ---------------------------------------------------------------------- -# Create nodeset for curved edge Neumann -# ---------------------------------------------------------------------- -group "surface_traction" add node in surface 37 -nodeset 1 group surface_traction -nodeset 1 name "surface_traction" - -# ---------------------------------------------------------------------- -# Create nodeset for curved edge Dirichlet -# ---------------------------------------------------------------------- -group "surface_pressure" add node in surface 37 -nodeset 2 group surface_pressure -nodeset 2 name "surface_pressure" - -# ---------------------------------------------------------------------- -# Create nodeset for -x edge Dirichlet -# ---------------------------------------------------------------------- -group "x_neg" add node in surface 35 -nodeset 3 group x_neg -nodeset 3 name "x_neg" - -# ---------------------------------------------------------------------- -# Create nodeset for -y edge Dirichlet -# ---------------------------------------------------------------------- -group "y_neg" add node in surface 36 -nodeset 4 group y_neg -nodeset 4 name "y_neg" - -# ---------------------------------------------------------------------- -# Create nodeset for -z edge Dirichlet -# ---------------------------------------------------------------------- -group "z_neg" add node in surface 34 -nodeset 5 group z_neg -nodeset 5 name "z_neg" - diff --git a/tests/fullscale/poroelasticity/cryer/cryer_hex.cfg b/tests/fullscale/poroelasticity/cryer/cryer_hex.cfg index 80a7ff661b..9fc1866202 100644 --- a/tests/fullscale/poroelasticity/cryer/cryer_hex.cfg +++ b/tests/fullscale/poroelasticity/cryer/cryer_hex.cfg @@ -1,7 +1,7 @@ [pylithapp.metadata] base = [cryer.cfg] keywords = [hexahedral cells] -arguments = [cryer.cfg, cryer_hex.cfg] +arguments = [cryer_hex.cfg] [pylithapp.problem] defaults.name = cryer_hex @@ -10,7 +10,7 @@ defaults.name = cryer_hex # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator.reader] -filename = mesh_hex.exo +filename = mesh_hex.msh # End of file diff --git a/tests/fullscale/poroelasticity/cryer/cryer_soln.py b/tests/fullscale/poroelasticity/cryer/cryer_soln.py index df87fa8588..d6ee7cd2ed 100644 --- a/tests/fullscale/poroelasticity/cryer/cryer_soln.py +++ b/tests/fullscale/poroelasticity/cryer/cryer_soln.py @@ -13,59 +13,54 @@ # Owing to the symmetry of the problem, we only need consider the quarter # domain case. # -# -F -# ---------- -# | | -# Ux=0 | | P=0 -# | | -# | | -# ---------- -# Uy=0 +# This is based on Cheng (Poroelasticity, Section 7.10) and its implementation in PETSc tutorial +# src/ts/tutorials/ex53.c. +# +# Notes: +# - The traction loading is impulsive, so we use a custom PETSc TS (pylith/utils/TSAdaptImpulse), +# which uses a very small time step for the first step before using the user-specified time step. +# - The accuracy of the solution is poor in the first few time steps due to the impulsive loading +# so we only check the last time step in the simulation, which is more accurate and select a +# a tolerance appropriate for the discretization size. # # Dirichlet boundary conditions -# Ux(0,y) = 0 -# Uy(x,0) = 0 +# Ux(0,y,z) = 0 +# Uy(x,0,z) = 0 +# Uy(x,y,0) = 0 # Neumann boundary conditions -# \tau_normal(x,ymax) = -1*Pa +# \tau_normal(rmax) = -1*Pa import numpy # Physical properties -G = 3.0 +G = 30.0e+9 rho_s = 2500 rho_f = 1000 -K_fl = 8.0 -K_sg = 10.0 -K_d = 4.0 +K_fl = 80.0e+9 +K_sg = 100.0e+9 +K_d = 40.0e+9 alpha = 0.6 phi = 0.1 -k = 1.5 -mu_f = 1.0 -P_0 = 1.0 -R_0 = 1.0 -ndim = 3 +k = 1.5e-13 +mu_f = 0.001 +P_0 = 10.0e+3 +R_0 = 10.0e+3 -M = 1.0 / ( phi / K_fl + (alpha - phi) /K_sg) +M = 1.0 / ( phi / K_fl + (alpha - phi) /K_sg) kappa = k/mu_f K_u = K_d + alpha*alpha*M S = (3*K_u + 4*G) / (M*(3*K_d + 4*G)) #(1/M) + ( (3*alpha*alpha) / (3*K_d + 4*G) )# c = kappa / S nu = (3*K_d - 2*G) / (2*(3*K_d + G)) nu_u = (3*K_u - 2*G) / (2*(3*K_u + G)) -U_R_inf = -1.*(P_0*R_0*(1.-2.*nu))/(2.*G*(1.+nu)) +U_R_inf = -(P_0*R_0*(1-2*nu))/(2*G*(1+nu)) eta = (alpha*(1-2*nu))/(2*(1-nu)) -xmin = 0.0 # m -xmax = 1.0 # m -ymin = 0.0 # m -ymax = 1.0 # m -zmin = 0.0 # m -zmax = 1.0 # m - -# Time steps -ts = 0.0028666667 # sec -nts = 2 -tsteps = numpy.arange(0.0, ts * nts, ts) + ts # sec +dt0 = 1.0e-6 * 1.0e+8 +dt = 5.0e+4 +t_end = 100.0e+4 +time = numpy.concatenate((numpy.array([dt0]), dt0+numpy.arange(dt, t_end+0.5*dt, dt))) +tsteps = numpy.array([time[-1]]) # ---------------------------------------------------------------------- class AnalyticalSoln(object): @@ -74,30 +69,27 @@ class AnalyticalSoln(object): """ SPACE_DIM = 3 TENSOR_SIZE = 4 - ITERATIONS = 50 - EPS = 1e-25 + ITERATIONS = 100 def __init__(self): self.fields = { "displacement": self.displacement, "pressure": self.pressure, - #"trace_strain": self.trace_strain, "porosity": self.porosity, "solid_density": self.solid_density, "fluid_density": self.fluid_density, "fluid_viscosity": self.fluid_viscosity, "shear_modulus": self.shear_modulus, - "undrained_bulk_modulus": self.undrained_bulk_modulus, "drained_bulk_modulus": self.drained_bulk_modulus, "biot_coefficient": self.biot_coefficient, "biot_modulus": self.biot_modulus, "isotropic_permeability": self.isotropic_permeability, "initial_amplitude": { - "x_neg": self.zero_vector, - "y_neg": self.zero_vector, - "z_neg": self.zero_vector, - "surface_traction": self.surface_traction, - "surface_pressure": self.zero_scalar + "bc_xneg": self.zero_vector, + "bc_yneg": self.zero_vector, + "bc_zneg": self.zero_vector, + "bc_shell_traction": self.surface_traction, + "bc_shell_pressure": self.zero_scalar } } return @@ -157,14 +149,6 @@ def fluid_viscosity(self, locs): fluid_viscosity = mu_f * numpy.ones((1, npts, 1), dtype=numpy.float64) return fluid_viscosity - def undrained_bulk_modulus(self, locs): - """ - Compute undrained bulk modulus field at locations. - """ - (npts, dim) = locs.shape - undrained_bulk_modulus = K_u * numpy.ones((1, npts, 1), dtype=numpy.float64) - return undrained_bulk_modulus - def drained_bulk_modulus(self, locs): """ Compute undrained bulk modulus field at locations. @@ -206,30 +190,26 @@ def displacement(self, locs): displacement = numpy.zeros((ntpts, npts, dim), dtype=numpy.float64) x_n = self.cryerZeros() - center = numpy.where(~locs.any(axis=1))[0] R = numpy.sqrt(locs[:,0]*locs[:,0] + locs[:,1]*locs[:,1] + locs[:,2]*locs[:,2]) theta = numpy.nan_to_num( numpy.arctan( numpy.nan_to_num( numpy.sqrt(locs[:,0]**2 + locs[:,1]**2) / locs[:,2] ) ) ) - phi = numpy.nan_to_num( numpy.arctan( numpy.nan_to_num( locs[:,1] / locs[:,0] ) ) ) - R_star = R.reshape([R.size,1]) / R_0 + R_star = R.reshape((R.size,1)) / R_0 - x_n.reshape([1,x_n.size]) - - E = numpy.square(1-nu)*numpy.square(1+nu_u)*x_n - 18*(1+nu)*(nu_u-nu)*(1-nu_u) + x_n.reshape((1,x_n.size)) + sqrt_xn = numpy.sqrt(x_n) - t_track = 0 + E = (1-nu)**2*(1+nu_u)**2*x_n - 18*(1+nu)*(nu_u-nu)*(1-nu_u) - for t in tsteps: + for i_t, t in enumerate(tsteps): t_star = (c*t)/(R_0**2) r_exact_N = R_star.ravel() - numpy.nan_to_num(numpy.sum(((12*(1 + nu)*(nu_u - nu)) / \ - ((1 - 2*nu)*E*R_star*R_star*x_n*numpy.sin(numpy.sqrt(x_n))) ) * \ - (3*(nu_u - nu) * (numpy.sin(R_star*numpy.sqrt(x_n)) - R_star*numpy.sqrt(x_n)*numpy.cos(R_star*numpy.sqrt(x_n))) + \ - (1 - nu)*(1 - 2*nu)*R_star*R_star*R_star*x_n*numpy.sin(numpy.sqrt(x_n))) * \ + ((1 - 2*nu)*E*R_star**2*x_n*numpy.sin(sqrt_xn)) ) * \ + (3*(nu_u - nu) * (numpy.sin(R_star*sqrt_xn) - R_star*sqrt_xn*numpy.cos(R_star*sqrt_xn)) + \ + (1 - nu)*(1 - 2*nu)*R_star**3*x_n*numpy.sin(sqrt_xn)) * \ numpy.exp(-x_n*t_star),axis=1)) - displacement[t_track, :, 0] = (r_exact_N*U_R_inf)*numpy.cos(phi)*numpy.sin(theta) - displacement[t_track, :, 1] = (r_exact_N*U_R_inf)*numpy.sin(phi)*numpy.sin(theta) - displacement[t_track, :, 2] = (r_exact_N*U_R_inf)*numpy.cos(theta) - t_track += 1 + displacement[i_t, :, 0] = (r_exact_N*U_R_inf)*numpy.cos(phi)*numpy.sin(theta) + displacement[i_t, :, 1] = (r_exact_N*U_R_inf)*numpy.sin(phi)*numpy.sin(theta) + displacement[i_t, :, 2] = (r_exact_N*U_R_inf)*numpy.cos(theta) return displacement @@ -244,6 +224,7 @@ def pressure(self, locs): center = numpy.where(~locs.any(axis=1))[0] x_n = self.cryerZeros() + sqrt_xn = numpy.sqrt(x_n) R = numpy.sqrt(locs[:,0]*locs[:,0] + locs[:,1]*locs[:,1] + locs[:,2]*locs[:,2]) R_star = R.reshape([R.size,1]) / R_0 @@ -251,30 +232,24 @@ def pressure(self, locs): E = (1-nu)**2 * (1+nu_u)**2 * x_n - 18*(1+nu)*(nu_u-nu)*(1-nu_u) - t_track = 0 - - for t in tsteps: + for i_t, t in enumerate(tsteps): t_star = (c*t)/(R_0**2) - pressure[t_track,:,0] = numpy.sum( ( (18*numpy.square(nu_u-nu) ) / (eta*E) ) * \ - ( (numpy.sin(R_star*numpy.sqrt(x_n))) / (R_star*numpy.sin(numpy.sqrt(x_n)) ) - 1 ) * \ + pressure[i_t,:,0] = P_0*numpy.sum( ( (18*numpy.square(nu_u-nu) ) / (eta*E) ) * \ + ( (numpy.sin(R_star*sqrt_xn)) / (R_star*numpy.sin(sqrt_xn) ) - 1 ) * \ numpy.exp(-x_n*t_star) , axis=1) - # Account for center value - #pressure[t_track,center] = numpy.sum( (8*eta*(numpy.sqrt(x_n) - numpy.sin(numpy.sqrt(x_n)))) / ( (x_n - 12*eta + 16*eta*eta)*numpy.sin(numpy.sqrt(x_n)) ) * numpy.exp(-x_n * t_star) ) - pressure[t_track,center,0] = numpy.sum( ( (18*numpy.square(nu_u-nu) ) / (eta*E) ) * \ - ( (numpy.sqrt(x_n)) / (numpy.sin(numpy.sqrt(x_n)) ) - 1 ) * \ + pressure[i_t,center,0] = P_0*numpy.sum( ( (18*numpy.square(nu_u-nu) ) / (eta*E) ) * \ + ( sqrt_xn / (numpy.sin(sqrt_xn) ) - 1 ) * \ numpy.exp(-x_n*t_star)) - t_track += 1 - return pressure - # Series functions + # Series functions def cryerZeros(self): - f = lambda x: numpy.tan(numpy.sqrt(x)) - (6*(nu_u - nu)*numpy.sqrt(x))/(6*(nu_u - nu) - (1 - nu)*(1 + nu_u)*x) # Compressible Constituents + f = lambda x: numpy.tan(numpy.sqrt(x)) - (6*(nu_u - nu)*numpy.sqrt(x))/(6*(nu_u - nu) - (1 - nu)*(1 + nu_u)*x) # Compressible Constituents n_series = self.ITERATIONS a_n = numpy.zeros(n_series) # initializing roots array @@ -326,7 +301,9 @@ def cryerZeros(self): def surface_traction(self, locs): (npts, dim) = locs.shape traction = numpy.zeros((1, npts, self.SPACE_DIM), dtype=numpy.float64) - traction[:,:,-1] = -1.0 + traction[:,:,-1] = -P_0 return traction + + # End of file diff --git a/tests/fullscale/poroelasticity/cryer/cryer_tet.cfg b/tests/fullscale/poroelasticity/cryer/cryer_tet.cfg index ffe1c46232..20ab528856 100644 --- a/tests/fullscale/poroelasticity/cryer/cryer_tet.cfg +++ b/tests/fullscale/poroelasticity/cryer/cryer_tet.cfg @@ -1,7 +1,7 @@ [pylithapp.metadata] base = [cryer.cfg] keywords = [tetrahedral cells] -arguments = [cryer.cfg, cryer_tet.cfg] +arguments = [cryer_tet.cfg] [pylithapp.problem] defaults.name = cryer_tet @@ -10,7 +10,7 @@ defaults.name = cryer_tet # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator.reader] -filename = mesh_tet.exo +filename = mesh_tet.msh # End of file diff --git a/tests/fullscale/poroelasticity/cryer/generate_gmsh.py b/tests/fullscale/poroelasticity/cryer/generate_gmsh.py new file mode 100755 index 0000000000..7dce9c3b86 --- /dev/null +++ b/tests/fullscale/poroelasticity/cryer/generate_gmsh.py @@ -0,0 +1,87 @@ +#!/usr/bin/env nemesis + +import math + +import gmsh +from pylith.meshio.gmsh_utils import BoundaryGroup, MaterialGroup, GenerateMesh + + +class App(GenerateMesh): + """ + Domain is a sphere with radius RADIUS and finest discretization size DX. + """ + + RADIUS = 10.0e+3 + DX = 1.0e+3 + + def __init__(self): + self.cell_choices = { + "required": False, + "choices": ["tet"], + } + self.filename = "mesh_tet.msh" + + def create_geometry(self): + """Create geometry.""" + x0 = 0.0 + y0 = 0.0 + z0 = 0.0 + + self.v_domain = gmsh.model.occ.add_sphere(x0, y0, z0, radius=self.RADIUS, angle1=0, angle3=math.pi/2) + self.s_shell = 1 + self.s_zneg = 2 + self.s_yneg = 3 + self.s_xneg = 4 + gmsh.model.occ.synchronize() + + def mark(self): + """Mark geometry for materials, boundary conditions, faults, etc.""" + materials = (MaterialGroup(tag=1, entities=[self.v_domain]),) + for material in materials: + material.create_physical_group() + + face_groups = ( + BoundaryGroup( + name="boundary_shell", + tag=10, + dim=2, + entities=[self.s_shell], + ), + BoundaryGroup( + name="boundary_shell_copy", + tag=11, + dim=2, + entities=[self.s_shell], + ), + BoundaryGroup( + name="boundary_zneg", + tag=12, + dim=2, + entities=[self.s_zneg], + ), + BoundaryGroup( + name="boundary_yneg", + tag=13, + dim=2, + entities=[self.s_yneg], + ), + BoundaryGroup( + name="boundary_xneg", + tag=14, + dim=2, + entities=[self.s_xneg], + ), + ) + for group in face_groups: + group.create_physical_group() + + def generate_mesh(self, cell): + """Generate the mesh. Should also include optimizing the mesh quality.""" + gmsh.option.setNumber("Mesh.MeshSizeMin", self.DX) + gmsh.option.setNumber("Mesh.MeshSizeMax", self.DX) + gmsh.model.mesh.generate(3) + gmsh.model.mesh.optimize("Laplace2D") + + +if __name__ == "__main__": + App().main() diff --git a/tests/fullscale/poroelasticity/cryer/geometry.jou b/tests/fullscale/poroelasticity/cryer/geometry.jou deleted file mode 100644 index 494da55707..0000000000 --- a/tests/fullscale/poroelasticity/cryer/geometry.jou +++ /dev/null @@ -1,13 +0,0 @@ -# ---------------------------------------------------------------------- -# Create surface using vertices -# ---------------------------------------------------------------------- - -# Sphere is 1m in radius - -create sphere radius 1 - -webcut body all xplane -webcut body all yplane -webcut body all zplane -delete volume 1 2 4 5 6 7 8 - diff --git a/tests/fullscale/poroelasticity/cryer/mesh_hex.exo b/tests/fullscale/poroelasticity/cryer/mesh_hex.exo deleted file mode 100644 index e74fb16cc4..0000000000 Binary files a/tests/fullscale/poroelasticity/cryer/mesh_hex.exo and /dev/null differ diff --git a/tests/fullscale/poroelasticity/cryer/mesh_hex.jou b/tests/fullscale/poroelasticity/cryer/mesh_hex.jou deleted file mode 100644 index c57a41bd56..0000000000 --- a/tests/fullscale/poroelasticity/cryer/mesh_hex.jou +++ /dev/null @@ -1,42 +0,0 @@ -# ---------------------------------------------------------------------- -# Reset geometry. -# ---------------------------------------------------------------------- -reset - -# ---------------------------------------------------------------------- -# Generate geometry -# ---------------------------------------------------------------------- -playback 'geometry.jou' - -# ---------------------------------------------------------------------- -# Set discretization size -# ---------------------------------------------------------------------- -volume all size 0.1 - -# ---------------------------------------------------------------------- -# Generate the mesh -# ---------------------------------------------------------------------- -volume all scheme tetprimitive -mesh volume all - -# ---------------------------------------------------------------------- -# Create blocks for materials -# ---------------------------------------------------------------------- -block 1 volume 3 -block 1 name "poroelastic" -block 1 element type hex8 - -# ---------------------------------------------------------------------- -# Mark entities for boundary conditions, etc. -# ---------------------------------------------------------------------- -playback 'bc.jou' - -# ---------------------------------------------------------------------- -# Export exodus file -# ---------------------------------------------------------------------- -export mesh "mesh_hex.exo" dimension 3 overwrite - - - - - diff --git a/tests/fullscale/poroelasticity/cryer/mesh_tet.exo b/tests/fullscale/poroelasticity/cryer/mesh_tet.exo deleted file mode 100644 index 912b63a395..0000000000 Binary files a/tests/fullscale/poroelasticity/cryer/mesh_tet.exo and /dev/null differ diff --git a/tests/fullscale/poroelasticity/cryer/mesh_tet.jou b/tests/fullscale/poroelasticity/cryer/mesh_tet.jou deleted file mode 100644 index 3d8b516760..0000000000 --- a/tests/fullscale/poroelasticity/cryer/mesh_tet.jou +++ /dev/null @@ -1,37 +0,0 @@ -# ---------------------------------------------------------------------- -# Reset geometry. -# ---------------------------------------------------------------------- -reset - -# ---------------------------------------------------------------------- -# Generate geometry -# ---------------------------------------------------------------------- -playback 'geometry.jou' - -# ---------------------------------------------------------------------- -# Set discretization size -# ---------------------------------------------------------------------- -volume all size 0.1 - -# ---------------------------------------------------------------------- -# Generate the mesh -# ---------------------------------------------------------------------- -volume all scheme tetmesh -mesh volume all - -# ---------------------------------------------------------------------- -# Create blocks for materials -# ---------------------------------------------------------------------- -block 1 volume 3 -block 1 name "poroelastic" -block 1 element type tetra4 - -# ---------------------------------------------------------------------- -# Mark entities for boundary conditions, etc. -# ---------------------------------------------------------------------- -playback 'bc.jou' - -# ---------------------------------------------------------------------- -# Export exodus file -# ---------------------------------------------------------------------- -export mesh "mesh_tet.exo" dimension 3 overwrite diff --git a/tests/fullscale/poroelasticity/cryer/mesh_tet.msh b/tests/fullscale/poroelasticity/cryer/mesh_tet.msh new file mode 100644 index 0000000000..e442c72f05 Binary files /dev/null and b/tests/fullscale/poroelasticity/cryer/mesh_tet.msh differ diff --git a/tests/fullscale/poroelasticity/cryer/meshes.py b/tests/fullscale/poroelasticity/cryer/meshes.py index 3741940714..82c11e3f0d 100644 --- a/tests/fullscale/poroelasticity/cryer/meshes.py +++ b/tests/fullscale/poroelasticity/cryer/meshes.py @@ -19,17 +19,17 @@ class Tet(object): Mesh information for tet mesh. """ ENTITIES = { - "domain": MeshEntity(ncells=5398, ncorners=4, nvertices=1150), + "domain": MeshEntity(ncells=2735, ncorners=4, nvertices=718), # Materials - "poroelastic": MeshEntity(ncells=5398, ncorners=4, nvertices=1150), + "poroelastic": MeshEntity(ncells=2735, ncorners=4, nvertices=718), # Boundaries - "surface_traction": MeshEntity(ncells=374, ncorners=3, nvertices=212), - "surface_pressure": MeshEntity(ncells=374, ncorners=3, nvertices=212), - "x_neg": MeshEntity(ncells=184, ncorners=3, nvertices=111), - "y_neg": MeshEntity(ncells=184, ncorners=3, nvertices=111), - "z_neg": MeshEntity(ncells=184, ncorners=3, nvertices=111), + "bc_shell_traction": MeshEntity(ncells=404, ncorners=3, nvertices=227), + "bc_shell_pressure": MeshEntity(ncells=404, ncorners=3, nvertices=227), + "bc_xneg": MeshEntity(ncells=198, ncorners=3, nvertices=118), + "bc_yneg": MeshEntity(ncells=196, ncorners=3, nvertices=117), + "bc_zneg": MeshEntity(ncells=196, ncorners=3, nvertices=117), } @@ -44,8 +44,8 @@ class Hex(object): "poroelastic": MeshEntity(ncells=896, ncorners=8, nvertices=1163), # Boundaries - "surface_traction": MeshEntity(ncells=192, ncorners=4, nvertices=217), - "surface_pressure": MeshEntity(ncells=192, ncorners=4, nvertices=217), + "bc_shell_traction": MeshEntity(ncells=192, ncorners=4, nvertices=217), + "bc_shell_pressure": MeshEntity(ncells=192, ncorners=4, nvertices=217), "x_neg": MeshEntity(ncells=96, ncorners=4, nvertices=115), "y_neg": MeshEntity(ncells=96, ncorners=4, nvertices=115), "z_neg": MeshEntity(ncells=96, ncorners=4, nvertices=115), diff --git a/tests/fullscale/poroelasticity/cryer/cryer.cfg b/tests/fullscale/poroelasticity/cryer/pylithapp.cfg similarity index 74% rename from tests/fullscale/poroelasticity/cryer/cryer.cfg rename to tests/fullscale/poroelasticity/cryer/pylithapp.cfg index ee7a4a3b3e..18753c8a0d 100644 --- a/tests/fullscale/poroelasticity/cryer/cryer.cfg +++ b/tests/fullscale/poroelasticity/cryer/pylithapp.cfg @@ -8,7 +8,7 @@ pylith_version = [>=3.0, <6.0] features = [ Quasistatic problem, pylith.materials.Poroelasticity, - pylith.meshio.MeshIOCubit, + pylith.meshio.MeshIOPetsc, pylith.problems.TimeDependent, pylith.problems.SolnDispPresTracStrain, pylith.bc.DirichletTimeDependent, @@ -26,25 +26,9 @@ command = mpiexec -np ${nodes} # journal # ---------------------------------------------------------------------- [pylithapp.journal.info] -#timedependent = 1 +timedependent = 1 #solution = 1 #petsc = 1 -#meshio = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#faultcohesivekin = 1 - -[pylithapp.journal.debug] -#timedependent = 1 -#solution = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#constraintspatialdb = 1 -#faultcohesivekin = 1 -#integratorinterface = 1 -#kinsrcstep = 1 -#outputphysics = 1 -#outputsolndomain = 1 # ---------------------------------------------------------------------- # problem @@ -57,13 +41,15 @@ solution = pylith.problems.SolnDispPresTracStrain [pylithapp.timedependent] start_time = 0.0*s -initial_dt = 0.0028666667*s # sec -end_time = 0.0057333334*s +initial_dt = 5.0e+4*s +end_time = 100.0e+4*s -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 1.0*m -normalizer.relaxation_time = 1.0*s -normalizer.shear_modulus = 1.0*m**-1*kg*s**-2 +scales = pylith.scales.QuasistaticPoroelasticity +scales.displacement_scale = 1.0*mm +scales.length_scale = 10.0*km +scales.shear_modulus = 10.0*GPa +scales.viscosity = 0.001*Pa*s +scales.permeability = 1.0e-13*m**2 [pylithapp.problem.solution.subfields] displacement.basis_order = 2 @@ -77,7 +63,7 @@ solution_observers = [domain] # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator] -reader = pylith.meshio.MeshIOCubit +reader = pylith.meshio.MeshIOPetsc [pylithapp.mesh_generator.reader] coordsys.space_dim = 3 @@ -86,7 +72,6 @@ coordsys.space_dim = 3 # materials # ---------------------------------------------------------------------- [pylithapp.problem] -# Create an array of one material materials = [poroelastic] materials.poroelastic = pylith.materials.Poroelasticity @@ -96,9 +81,9 @@ label_value = 1 db_auxiliary_field = spatialdata.spatialdb.UniformDB db_auxiliary_field.description = Poroelastic properties db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 1.0*Pa*s, 0.1, 3.0*Pa, 4.0*Pa, 0.6, 8.0*Pa, 1.5*m**2] +db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 0.001*Pa*s, 0.1, 30.0*GPa, 40.0*GPa, 0.6, 80.0*GPa, 1.5e-13*m**2] -observers.observer.data_fields = [displacement,pressure,trace_strain] +observers.observer.data_fields = [displacement, pressure, trace_strain] auxiliary_subfields.body_force.basis_order = 0 auxiliary_subfields.solid_density.basis_order = 0 @@ -121,57 +106,65 @@ auxiliary_subfields.isotropic_permeability.basis_order = 0 # boundary conditions # ---------------------------------------------------------------------- [pylithapp.problem] -bc = [surface_traction, surface_pressure, x_neg, y_neg, z_neg] +bc = [bc_shell_traction, bc_shell_pressure, bc_xneg, bc_yneg, bc_zneg] -bc.surface_traction = pylith.bc.NeumannTimeDependent -bc.surface_pressure = pylith.bc.DirichletTimeDependent -bc.x_neg = pylith.bc.DirichletTimeDependent -bc.y_neg = pylith.bc.DirichletTimeDependent -bc.z_neg = pylith.bc.DirichletTimeDependent +bc.bc_shell_traction = pylith.bc.NeumannTimeDependent +bc.bc_shell_pressure = pylith.bc.DirichletTimeDependent +bc.bc_xneg = pylith.bc.DirichletTimeDependent +bc.bc_yneg = pylith.bc.DirichletTimeDependent +bc.bc_zneg = pylith.bc.DirichletTimeDependent # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.surface_pressure] +[pylithapp.problem.bc.bc_shell_pressure] +label = boundary_shell +label_value = 10 constrained_dof = [0] -label = surface_pressure field = pressure + db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on surface # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.surface_traction] -label = surface_traction +[pylithapp.problem.bc.bc_shell_traction] +label = boundary_shell_copy +label_value = 11 field = displacement -scale_name = pressure -use_initial = True +scale_name = stress + db_auxiliary_field = spatialdata.spatialdb.UniformDB db_auxiliary_field.description = Neumann BC surface - db_auxiliary_field.values = [initial_amplitude_tangential_1, initial_amplitude_tangential_2, initial_amplitude_normal] -db_auxiliary_field.data = [0.0*Pa, 0.0*Pa, -1.0*Pa] +db_auxiliary_field.data = [0.0*Pa, 0.0*Pa, -10.0*kPa] -auxiliary_subfields.initial_amplitude.basis_order = 1 +auxiliary_subfields.initial_amplitude.basis_order = 0 # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_neg] -constrained_dof = [0] -label = x_neg +[pylithapp.problem.bc.bc_xneg] +label = boundary_xneg +label_value = 14 field = displacement +constrained_dof = [0] + db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on -x # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_neg] -constrained_dof = [1] -label = y_neg +[pylithapp.problem.bc.bc_yneg] +label = boundary_yneg +label_value = 13 field = displacement +constrained_dof = [1] + db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on -y # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.z_neg] -constrained_dof = [2] -label = z_neg +[pylithapp.problem.bc.bc_zneg] +label = boundary_zneg +label_value = 12 field = displacement +constrained_dof = [2] + db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on -z @@ -181,8 +174,9 @@ db_auxiliary_field.description = Dirichlet BC on -z [pylithapp.problem.petsc_defaults] solver = True testing = True -monitors = False +monitors = True initial_guess = False +impulse_ts = True # End of file diff --git a/tests/fullscale/poroelasticity/faults-2d/pressuregradient.cfg b/tests/fullscale/poroelasticity/faults-2d/pressuregradient.cfg index 52a9ccc30e..5dc0584104 100644 --- a/tests/fullscale/poroelasticity/faults-2d/pressuregradient.cfg +++ b/tests/fullscale/poroelasticity/faults-2d/pressuregradient.cfg @@ -20,9 +20,9 @@ features = [ # problem # ---------------------------------------------------------------------- [pylithapp.problem] -initial_dt = 10.0*year -start_time = -10.0*year -end_time = 40.0*year +initial_dt = 1.0*year +start_time = -1.0*year +end_time = 10.0*year # ---------------------------------------------------------------------- diff --git a/tests/fullscale/poroelasticity/faults-2d/pressuregradient_soln.py b/tests/fullscale/poroelasticity/faults-2d/pressuregradient_soln.py index c338a329bc..fbcc38dd3e 100644 --- a/tests/fullscale/poroelasticity/faults-2d/pressuregradient_soln.py +++ b/tests/fullscale/poroelasticity/faults-2d/pressuregradient_soln.py @@ -19,10 +19,10 @@ p_fluid_viscosity = 1.0e-3 p_porosity = 0.02 -p_shear_modulus = 3.0e10 -p_drained_bulk_modulus = 8.0e10 -p_fluid_bulk_modulus = 1.0e10 -p_biot_coefficient = 0.2 +p_shear_modulus = 30.0e9 +p_drained_bulk_modulus = 80.0e9 +p_fluid_bulk_modulus = 10.0e9 +p_biot_coefficient = 0.7 p_isotropic_permeability = 1.0e-14 @@ -31,7 +31,7 @@ p0 = 4.0e4 -s0 = -1.0e8 +s0 = -1.0e6 domain_x = 8.0e3 p_alpha = p_biot_coefficient u0 = 1.0 / (p_lambda + 2.0 * p_mu) * domain_x * (-s0 - 0.5 * p_alpha * p0) diff --git a/tests/fullscale/poroelasticity/faults-2d/pylithapp.cfg b/tests/fullscale/poroelasticity/faults-2d/pylithapp.cfg index 2d18dadb64..992c6fccb7 100644 --- a/tests/fullscale/poroelasticity/faults-2d/pylithapp.cfg +++ b/tests/fullscale/poroelasticity/faults-2d/pylithapp.cfg @@ -50,12 +50,13 @@ coordsys.space_dim = 2 # ---------------------------------------------------------------------- [pylithapp.problem] # Scales for nondimensionalization -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 4.0*km -normalizer.relaxation_time = 10.0*year -normalizer.shear_modulus = 10.0*GPa +scales = pylith.scales.QuasistaticPoroelasticity +scales.length_scale = 1.0*km +scales.displacement_scale = 1.0*m +scales.shear_modulus = 30.0*GPa +scales.viscosity = 0.001*Pa*s +scales.permeability = 1.0e-14*m**2 -[pylithapp.problem] solution = pylith.problems.SolnDispPresTracStrainLagrange [pylithapp.problem.solution.subfields] @@ -80,7 +81,7 @@ label_value = 1 db_auxiliary_field = spatialdata.spatialdb.UniformDB db_auxiliary_field.description = Poroelastic properties db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [2500*kg/m**3, 1000*kg/m**3, 1.0e-3*Pa*s, 0.02, 30.0*GPa, 80.0*GPa, 0.2, 10.0*GPa, 1.0e-14*m**2] +db_auxiliary_field.data = [2500*kg/m**3, 1000*kg/m**3, 1.0e-3*Pa*s, 0.02, 30.0*GPa, 80.0*GPa, 0.7, 10.0*GPa, 1.0e-14*m**2] auxiliary_subfields.solid_density.basis_order = 0 auxiliary_subfields.fluid_density.basis_order = 0 @@ -119,9 +120,8 @@ testing = True monitors = False [pylithapp.petsc] -ksp_rtol = 1.0e-15 -ksp_atol = 1.0e-13 - -snes_max_it = 1 +ksp_atol = 1.0e-9 +snes_atol = 2.0e-8 +snes_max_it = 4 # End of file diff --git a/tests/fullscale/poroelasticity/mandel/Makefile.am b/tests/fullscale/poroelasticity/mandel/Makefile.am index 0cad049227..583e6ace01 100644 --- a/tests/fullscale/poroelasticity/mandel/Makefile.am +++ b/tests/fullscale/poroelasticity/mandel/Makefile.am @@ -13,34 +13,21 @@ TESTS = test_pylith.py dist_check_SCRIPTS = test_pylith.py dist_noinst_PYTHON = \ + generate_gmsh.py \ meshes.py \ TestMandel.py \ mandel_soln.py \ - mandel_gendb.py \ - TestMandelCompaction.py \ - mandel_compaction_soln.py \ - mandel_compaction_gendb.py + mandel_gendb.py dist_noinst_DATA = \ - geometry.jou \ - bc.jou \ - mesh_tri.jou \ - mesh_tri.exo \ - mesh_quad.jou \ - mesh_quad.exo \ - mandel.cfg \ + pylithapp.cfg \ + mesh_tri.msh \ + mesh_quad.msh \ mandel_tri.cfg \ - mandel_quad.cfg \ - mandel_compaction.cfg \ - mandel_compaction_tri.cfg \ - mandel_compaction_quad.cfg + mandel_quad.cfg noinst_TMP = \ - mandel_bc.spatialdb \ - mandel_ic.spatialdb \ - mandel_compaction_bc.spatialdb \ - mandel_compaction_ic.spatialdb - + mandel_disp.timedb export_datadir = $(abs_builddir) diff --git a/tests/fullscale/poroelasticity/mandel/TestMandel.py b/tests/fullscale/poroelasticity/mandel/TestMandel.py index c405ef84d2..8efac96bec 100644 --- a/tests/fullscale/poroelasticity/mandel/TestMandel.py +++ b/tests/fullscale/poroelasticity/mandel/TestMandel.py @@ -17,7 +17,7 @@ import unittest -from pylith.testing.FullTestApp import (FullTestCase, Check, check_data) +from pylith.testing.FullTestApp import (FullTestCase, Check) import meshes import mandel_soln @@ -35,15 +35,10 @@ def setUp(self): self.checks = [ Check( mesh_entities=["domain"], - vertex_fields=["displacement"], + vertex_fields=["displacement", "pressure", "trace_strain"], + final_time_only=True, defaults=defaults, - tolerance=0.5, - ), - Check( - mesh_entities=["domain"], - vertex_fields=["pressure"], - defaults=defaults, - scale=1.0e+6, + tolerance=0.01, ), Check( mesh_entities=["poroelastic"], @@ -62,35 +57,11 @@ def setUp(self): defaults=defaults, ), Check( - mesh_entities=["poroelastic"], - vertex_fields = ["displacement"], - defaults=defaults, - tolerance=0.5, - ), - Check( - mesh_entities=["poroelastic"], - vertex_fields = ["pressure"], - defaults=defaults, - scale=1.0e+6, - ), - Check( - mesh_entities=["x_neg", "x_pos", "y_neg", "y_pos"], + mesh_entities=["bc_xneg", "bc_xpos", "bc_yneg"], filename="output/{name}-{mesh_entity}_info.h5", vertex_fields=["initial_amplitude"], defaults=defaults, ), - Check( - mesh_entities=["x_neg", "x_pos", "y_neg", "y_pos"], - vertex_fields=["displacement"], - defaults=defaults, - tolerance=0.5, - ), - Check( - mesh_entities=["x_neg", "x_pos", "y_neg", "y_pos"], - vertex_fields=["pressure"], - defaults=defaults, - scale=1.0e+6, - ), ] def run_pylith(self, testName, args): @@ -105,7 +76,7 @@ def setUp(self): self.mesh = meshes.Quad() super().setUp() - TestCase.run_pylith(self, self.name, ["mandel.cfg", "mandel_quad.cfg"]) + TestCase.run_pylith(self, self.name, ["mandel_quad.cfg"]) return @@ -117,7 +88,7 @@ def setUp(self): self.mesh = meshes.Tri() super().setUp() - TestCase.run_pylith(self, self.name, ["mandel.cfg", "mandel_tri.cfg"]) + TestCase.run_pylith(self, self.name, ["mandel_tri.cfg"]) return diff --git a/tests/fullscale/poroelasticity/mandel/TestMandelCompaction.py b/tests/fullscale/poroelasticity/mandel/TestMandelCompaction.py deleted file mode 100644 index d71e0b547a..0000000000 --- a/tests/fullscale/poroelasticity/mandel/TestMandelCompaction.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env nemesis -# ================================================================================================= -# This code is part of PyLith, developed through the Computational Infrastructure -# for Geodynamics (https://github.com/geodynamics/pylith). -# -# Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. -# All rights reserved. -# -# See https://mit-license.org/ and LICENSE.md and for license information. -# ================================================================================================= -# @file tests/fullscale/poroelasticity/mandel_compaction/TestMandelCompaction.py -# -# @brief Test suite for testing pylith with Mandel's problem. - -import unittest - -from pylith.testing.FullTestApp import (FullTestCase, Check, check_data) - -import meshes -import mandel_compaction_soln -import mandel_compaction_gendb - -# We do not include trace_strain in the check of the solution fields, because of the -# poor convergence of the series solution. -SOLUTION_FIELDS = ["displacement", "pressure"] -SOLUTION_TOLERANCE = 0.2 - -# ------------------------------------------------------------------------------------------------- -class TestCase(FullTestCase): - - def setUp(self): - defaults = { - "filename": "output/{name}-{mesh_entity}.h5", - "exact_soln": mandel_compaction_soln.AnalyticalSoln(), - "mesh": self.mesh, - } - self.checks = [ - Check( - mesh_entities=["domain"], - vertex_fields=SOLUTION_FIELDS, - defaults=defaults, - tolerance=SOLUTION_TOLERANCE, - ), - Check( - mesh_entities=["poroelastic"], - filename="output/{name}-{mesh_entity}_info.h5", - cell_fields=[ - "biot_coefficient", - "biot_modulus", - "drained_bulk_modulus", - "fluid_density", - "fluid_viscosity", - "isotropic_permeability", - "porosity", - "shear_modulus", - "solid_density", - ], - defaults=defaults, - ), - Check( - mesh_entities=["poroelastic"], - vertex_fields = SOLUTION_FIELDS, - defaults=defaults, - tolerance=SOLUTION_TOLERANCE, - ), - Check( - mesh_entities=["x_neg", "x_pos", "y_neg", "y_pos"], - filename="output/{name}-{mesh_entity}_info.h5", - vertex_fields=["initial_amplitude"], - defaults=defaults, - ), - Check( - mesh_entities=["x_neg", "x_pos", "y_neg", "y_pos"], - vertex_fields=SOLUTION_FIELDS, - defaults=defaults, - tolerance=SOLUTION_TOLERANCE, - ), - ] - - def run_pylith(self, testName, args): - FullTestCase.run_pylith(self, testName, args, mandel_compaction_gendb.GenerateDB) - - -# ------------------------------------------------------------------------------------------------- -class TestQuad(TestCase): - - def setUp(self): - self.name = "mandel_compaction_quad" - self.mesh = meshes.Quad() - super().setUp() - - TestCase.run_pylith(self, self.name, ["mandel_compaction.cfg", "mandel_compaction_quad.cfg"]) - return - - -# ------------------------------------------------------------------------------------------------- -class TestTri(TestCase): - - def setUp(self): - self.name = "mandel_compaction_tri" - self.mesh = meshes.Tri() - super().setUp() - - TestCase.run_pylith(self, self.name, ["mandel_compaction.cfg", "mandel_compaction_tri.cfg"]) - return - - -# ---------------------------------------------------------------------------------------------------------------------- -def test_cases(): - return [ - TestQuad, - TestTri, - ] - - -# ---------------------------------------------------------------------------------------------------------------------- -if __name__ == '__main__': - FullTestCase.parse_args() - - suite = unittest.TestSuite() - for test in test_cases(): - suite.addTest(unittest.makeSuite(test)) - unittest.TextTestRunner(verbosity=2).run(suite) - - -# End of file diff --git a/tests/fullscale/poroelasticity/mandel/bc.jou b/tests/fullscale/poroelasticity/mandel/bc.jou deleted file mode 100644 index 7323338589..0000000000 --- a/tests/fullscale/poroelasticity/mandel/bc.jou +++ /dev/null @@ -1,34 +0,0 @@ -# ---------------------------------------------------------------------- -# Create blocks for materials -# ---------------------------------------------------------------------- -block 1 surface 1 -block 1 name "poroelastic" -block 1 element type tri - -# ---------------------------------------------------------------------- -# Create nodeset for -x edge -# ---------------------------------------------------------------------- -group "x_neg" add node in curve 1 -nodeset 1 group x_neg -nodeset 1 name "x_neg" - -# ---------------------------------------------------------------------- -# Create nodeset for +y edge -# ---------------------------------------------------------------------- -group "y_pos" add node in curve 2 -nodeset 2 group y_pos -nodeset 2 name "y_pos" - -# ---------------------------------------------------------------------- -# Create nodeset for +x edge -# ---------------------------------------------------------------------- -group "x_pos" add node in curve 3 -nodeset 3 group x_pos -nodeset 3 name "x_pos" - -# ---------------------------------------------------------------------- -# Create nodeset for -y edge Dirichlet -# ---------------------------------------------------------------------- -group "y_neg" add node in curve 4 -nodeset 4 group y_neg -nodeset 4 name "y_neg" diff --git a/tests/fullscale/poroelasticity/mandel/generate_gmsh.py b/tests/fullscale/poroelasticity/mandel/generate_gmsh.py new file mode 100755 index 0000000000..97a779fd34 --- /dev/null +++ b/tests/fullscale/poroelasticity/mandel/generate_gmsh.py @@ -0,0 +1,106 @@ +#!/usr/bin/env nemesis + +import gmsh +from pylith.meshio.gmsh_utils import BoundaryGroup, MaterialGroup, GenerateMesh + + +class App(GenerateMesh): + """ + Block is DOMAIN_X by DOMAIN_Y with discretization size DX. + + p4------------p3 + | | + | | + | | + | | + | | + p1------------p2 + """ + + DOMAIN_X = 8.0e+3 + DOMAIN_Y = 1.0e+3 + DX = 0.2e+3 + + def __init__(self): + self.cell_choices = { + "required": True, + "choices": ["tri", "quad"], + } + self.filename = "mesh.msh" + + def create_geometry(self): + """Create geometry.""" + lx = self.DOMAIN_X + ly = self.DOMAIN_Y + x0 = 0.0 + y0 = 0.0 + + p1 = gmsh.model.geo.add_point(x0, y0, 0.0) + p2 = gmsh.model.geo.add_point(x0 + lx, y0, 0.0) + p3 = gmsh.model.geo.add_point(x0 + lx, y0 + ly, 0.0) + p4 = gmsh.model.geo.add_point(x0, y0 + ly, 0.0) + + self.l_yneg = gmsh.model.geo.add_line(p1, p2) + self.l_xpos = gmsh.model.geo.add_line(p2, p3) + self.l_ypos = gmsh.model.geo.add_line(p3, p4) + self.l_xneg = gmsh.model.geo.add_line(p4, p1) + + c1 = gmsh.model.geo.add_curve_loop( + [self.l_yneg, self.l_xpos, self.l_ypos, self.l_xneg] + ) + self.s_domain = gmsh.model.geo.add_plane_surface([c1]) + + gmsh.model.geo.synchronize() + + def mark(self): + """Mark geometry for materials, boundary conditions, faults, etc.""" + materials = (MaterialGroup(tag=1, entities=[self.s_domain]),) + for material in materials: + material.create_physical_group() + + face_groups = ( + BoundaryGroup( + name="boundary_xneg", + tag=10, + dim=1, + entities=[self.l_xneg], + ), + BoundaryGroup( + name="boundary_xpos", + tag=11, + dim=1, + entities=[self.l_xpos], + ), + BoundaryGroup( + name="boundary_yneg", + tag=12, + dim=1, + entities=[self.l_yneg], + ), + BoundaryGroup( + name="boundary_ypos", + tag=13, + dim=1, + entities=[self.l_ypos], + ), + ) + for group in face_groups: + group.create_physical_group() + + def generate_mesh(self, cell): + """Generate the mesh. Should also include optimizing the mesh quality.""" + gmsh.option.setNumber("Mesh.MeshSizeMin", self.DX) + gmsh.option.setNumber("Mesh.MeshSizeMax", self.DX) + if cell == "quad": + # Generate a tri mesh and then recombine cells to form quadrilaterals. + # We use the Frontal-Delaunay for Quads algorithm. + gmsh.option.setNumber("Mesh.Algorithm", 8) + gmsh.model.mesh.generate(2) + gmsh.model.mesh.recombine() + else: + gmsh.model.mesh.generate(2) + gmsh.model.mesh.optimize("Laplace2D") + + +if __name__ == "__main__": + App().main() diff --git a/tests/fullscale/poroelasticity/mandel/geometry.jou b/tests/fullscale/poroelasticity/mandel/geometry.jou deleted file mode 100644 index c8da2d71cc..0000000000 --- a/tests/fullscale/poroelasticity/mandel/geometry.jou +++ /dev/null @@ -1,14 +0,0 @@ -# ---------------------------------------------------------------------- -# Create surface using vertices -# ---------------------------------------------------------------------- - -# Block is 10.0m x 1.0m -# 0 m <= x <= 10.0 m -# 0 m <= y <= 1.0 m -reset -create vertex 0.0 0.0 0.0 -create vertex 0.0 +1.0 0.0 -create vertex +10.0 +1.0 0.0 -create vertex +10.0 0.0 0.0 -create surface vertex 1 2 3 4 -delete vertex all diff --git a/tests/fullscale/poroelasticity/mandel/mandel_compaction.cfg b/tests/fullscale/poroelasticity/mandel/mandel_compaction.cfg deleted file mode 100644 index 14c1db6b25..0000000000 --- a/tests/fullscale/poroelasticity/mandel/mandel_compaction.cfg +++ /dev/null @@ -1,205 +0,0 @@ -[pylithapp.metadata] -description = Compression of a homogeneous, isotropic slab between two rigid, friction plates loaded by a compressive vertical force, resulting in a non-monotonic pore pressure build up. -authors = [Robert Walker] -keywords = [full-scale test, 2D, poroelasticity, Mandel] -version = 1.0.0 -pylith_version = [>=3.0, <6.0] - -features = [ - Quasistatic problem, - pylith.materials.Poroelasticity, - pylith.meshio.MeshIOCubit, - pylith.problems.TimeDependent, - pylith.problems.SolnDispPresTracStrain, - pylith.bc.DirichletTimeDependent, - pylith.bc.NeumannTimeDependent, - pylith.meshio.DataWriterHDF5, - spatialdata.spatialdb.UniformDB, - pylith.bc.ZeroDB - ] - -[pylithapp.launcher] # WARNING: THIS IS NOT PORTABLE -command = mpiexec -np ${nodes} - -# ---------------------------------------------------------------------- -# journal -# ---------------------------------------------------------------------- -[pylithapp.journal.info] -#timedependent = 1 -#solution = 1 -#petsc = 1 -#meshio = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#faultcohesivekin = 1 - -[pylithapp.journal.debug] -#timedependent = 1 -#solution = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#constraintspatialdb = 1 -#faultcohesivekin = 1 -#integratorinterface = 1 -#kinsrcstep = 1 -#outputphysics = 1 -#outputsolndomain = 1 - -# ---------------------------------------------------------------------- -# mesh_generator -# ---------------------------------------------------------------------- -[pylithapp.mesh_generator] -reader = pylith.meshio.MeshIOCubit - -[pylithapp.mesh_generator.reader] -coordsys.space_dim = 2 - -# ---------------------------------------------------------------------- -# problem -# ---------------------------------------------------------------------- -[pylithapp.problem] -defaults.quadrature_order = 2 - -# Use nonlinear solver to ensure residual and Jacobian are consistent. -solver = nonlinear -solution = pylith.problems.SolnDispPresTracStrainVelPdotTdot - -[pylithapp.timedependent] -start_time = 0.0*s -initial_dt = 0.0028666667*s -end_time = 0.0057333334*s - -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 0.25*m -normalizer.relaxation_time = 0.01*s -normalizer.shear_modulus = 1.0*m**-1*kg*s**-2 - -[pylithapp.problem.solution.subfields] -displacement.basis_order = 2 -pressure.basis_order = 1 -trace_strain.basis_order = 1 -velocity.basis_order = 2 -pressure_t.basis_order = 1 -trace_strain_t.basis_order = 1 - -[pylithapp.problem] -solution_observers = [domain] - -# ---------------------------------------------------------------------- -# materials -# ---------------------------------------------------------------------- -[pylithapp.problem] -# Create an array of one material -materials = [poroelastic] -materials.poroelastic = pylith.materials.Poroelasticity - -[pylithapp.problem.materials] -poroelastic.bulk_rheology = pylith.materials.IsotropicLinearPoroelasticity -poroelastic.use_state_variables = True - -[pylithapp.problem.materials.poroelastic] -label_value = 1 - -# We will use uniform material properties, so we use the UniformDB spatial database. -db_auxiliary_field = spatialdata.spatialdb.UniformDB -db_auxiliary_field.description = Poroelastic properties -db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 1.0*Pa*s, 0.1, 3.0*Pa, 4.0*Pa, 0.6, 8.0*Pa, 1.5*m**2] - -observers.observer.data_fields = [displacement,pressure,trace_strain, velocity, pressure_t, trace_strain_t] - -auxiliary_subfields.body_force.basis_order = 0 -auxiliary_subfields.solid_density.basis_order = 0 -auxiliary_subfields.fluid_density.basis_order = 0 -auxiliary_subfields.fluid_viscosity.basis_order = 0 -auxiliary_subfields.gravitational_acceleration.basis_order = 0 -auxiliary_subfields.porosity.basis_order = 0 -derived_subfields.cauchy_strain.basis_order = 1 -derived_subfields.cauchy_stress.basis_order = 1 - -[pylithapp.problem.materials.poroelastic.bulk_rheology] - -auxiliary_subfields.drained_bulk_modulus.basis_order = 0 -auxiliary_subfields.shear_modulus.basis_order = 0 -auxiliary_subfields.biot_coefficient.basis_order = 0 -auxiliary_subfields.biot_modulus.basis_order = 0 -auxiliary_subfields.isotropic_permeability.basis_order = 0 - -# # ---------------------------------------------------------------------- -# # initial conditions -# # ---------------------------------------------------------------------- -# [pylithapp.problem] -# ic = [domain] - -# ic.domain.db = spatialdata.spatialdb.SimpleGridDB -# ic.domain.db.description = Initial conditions for domain -# ic.domain.db.filename = mandel_compaction_ic.spatialdb -# ic.domain.db.query_type = linear - -# ---------------------------------------------------------------------- -# boundary conditions -# ---------------------------------------------------------------------- -[pylithapp.problem] -bc = [x_neg,x_pos,y_neg,y_pos] - -bc.x_pos = pylith.bc.DirichletTimeDependent -bc.x_neg = pylith.bc.DirichletTimeDependent -bc.y_neg = pylith.bc.DirichletTimeDependent -bc.y_pos = pylith.bc.NeumannTimeDependent - -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_pos] -constrained_dof = [0] -label = x_pos -field = pressure -db_auxiliary_field = pylith.bc.ZeroDB -db_auxiliary_field.description = Dirichlet BC on +x boundary - -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_neg] -constrained_dof = [0] -label = x_neg -field = displacement -db_auxiliary_field = pylith.bc.ZeroDB -db_auxiliary_field.description = Dirichlet BC on -x boundary - -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_pos] -# Neumann Case -label = y_pos -field = displacement -scale_name = pressure -use_initial = True -db_auxiliary_field = spatialdata.spatialdb.UniformDB -db_auxiliary_field.description = Neumann BC +y edge -db_auxiliary_field.values = [initial_amplitude_tangential, initial_amplitude_normal] -db_auxiliary_field.data = [0.0*Pa, -1.0*Pa] - -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_neg] -constrained_dof = [1] -label = y_neg -field = displacement -db_auxiliary_field = pylith.bc.ZeroDB -db_auxiliary_field.description = Dirichlet BC on -y boundary - -# ---------------------------------------------------------------------- -# PETSc -# ---------------------------------------------------------------------- -[pylithapp.problem.petsc_defaults] -solver = True -testing = True -monitors = False - -[pylithapp.petsc] -ksp_max_it = 200 -ksp_gmres_restart = 200 - -ksp_rtol = 1.0e-8 -ksp_atol = 1.0e-12 - -snes_rtol = 1.0e-10 -snes_atol = 1.0e-10 - - -# End of file diff --git a/tests/fullscale/poroelasticity/mandel/mandel_compaction_gendb.py b/tests/fullscale/poroelasticity/mandel/mandel_compaction_gendb.py deleted file mode 100755 index 94189dc3e2..0000000000 --- a/tests/fullscale/poroelasticity/mandel/mandel_compaction_gendb.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env nemesis -# ================================================================================================= -# This code is part of PyLith, developed through the Computational Infrastructure -# for Geodynamics (https://github.com/geodynamics/pylith). -# -# Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. -# All rights reserved. -# -# See https://mit-license.org/ and LICENSE.md and for license information. -# ================================================================================================= -# @file tests/fullscale/poroelasticity/mandel_compaction/mandel_compaction_gendb.py -# -# @brief Python script to generate spatial database with displacement -# boundary conditions for the mandel test. - -import numpy - - -class GenerateDB(object): - """Python object to generate spatial database with displacement - boundary conditions for the axial displacement test. - """ - - def run(self): - """Generate the database. - """ - # Domain - x1 = numpy.arange(-0.1, 10.1, 0.1) - y1 = numpy.arange(-0.1, 1.01, 0.1) - x, y = numpy.meshgrid(x1, y1) - - xy = numpy.zeros((len(x1) * len(y1), 2), dtype=numpy.float64) - xy[:, 0] = x.ravel() - xy[:, 1] = y.ravel() - - from mandel_compaction_soln import AnalyticalSoln - soln = AnalyticalSoln() - disp = soln.initial_displacement(xy) - pres = soln.initial_pressure(xy) - trace_strain = soln.initial_trace_strain(xy) - vel = soln.zero_array_dim(xy) - pres_t = soln.zero_array(xy) - trace_strain_t = soln.zero_array(xy) - - from spatialdata.geocoords.CSCart import CSCart - cs = CSCart() - cs.inventory.spaceDim = 2 - cs._configure() - data = { - 'x': x1, - 'y': y1, - 'points': xy, - 'coordsys': cs, - 'data_dim': 2, - 'values': [{'name': "displacement_x", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 0])}, - {'name': "displacement_y", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 1])}, - {'name': "pressure", - 'units': "Pa", - 'data': numpy.ravel(pres[0, :])}, - {'name': "trace_strain", - 'units': "none", - 'data': numpy.ravel(trace_strain[0, :])}, - {'name': "velocity_x", - 'units': "m/s", - 'data': numpy.ravel(vel[0, :, 0])}, - {'name': "velocity_y", - 'units': "m/s", - 'data': numpy.ravel(vel[0, :, 1])}, - {'name': "pressure_t", - 'units': "Pa/s", - 'data': numpy.ravel(pres_t[0, :])}, - {'name': "trace_strain_t", - 'units': "1/s", - 'data': numpy.ravel(trace_strain_t[0, :])}]} - - from spatialdata.spatialdb.SimpleGridAscii import SimpleGridAscii - io = SimpleGridAscii() - io.inventory.filename = "mandel_compaction_bc.spatialdb" - io._configure() - io.write(data) - data["values"] = [ - { - 'name': "displacement_x", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 0]) - }, { - 'name': "displacement_y", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 1]) - }, { - 'name': "pressure", - 'units': "Pa", - 'data': numpy.ravel(pres[0, :]) - }, { - 'name': "trace_strain", - 'units': "none", - 'data': numpy.ravel(trace_strain[0, :]) - }, { - 'name': "velocity_x", - 'units': "m/s", - 'data': numpy.ravel(vel[0, :, 0]) - }, { - 'name': "velocity_y", - 'units': "m/s", - 'data': numpy.ravel(vel[0, :, 1]) - }, { - 'name': "pressure_t", - 'units': "Pa/s", - 'data': numpy.ravel(pres_t[0, :]) - }, { - 'name': "trace_strain_t", - 'units': "1/s", - 'data': numpy.ravel(trace_strain_t[0, :]) - }] - io.inventory.filename = "mandel_compaction_ic.spatialdb" - io._configure() - io.write(data) - return - - -# ====================================================================== -if __name__ == "__main__": - GenerateDB().run() - - -# End of file diff --git a/tests/fullscale/poroelasticity/mandel/mandel_compaction_quad.cfg b/tests/fullscale/poroelasticity/mandel/mandel_compaction_quad.cfg deleted file mode 100644 index 71bb484f4d..0000000000 --- a/tests/fullscale/poroelasticity/mandel/mandel_compaction_quad.cfg +++ /dev/null @@ -1,16 +0,0 @@ -[pylithapp.metadata] -base = [mandel_compaction.cfg] -keywords = [quadrilateral cells] -arguments = [mandel_compaction.cfg, mandel_compaction_quad.cfg] - -[pylithapp.problem] -defaults.name = mandel_compaction_quad - -# ---------------------------------------------------------------------- -# mesh_generator -# ---------------------------------------------------------------------- -[pylithapp.mesh_generator.reader] -filename = mesh_quad.exo - - -# End of file diff --git a/tests/fullscale/poroelasticity/mandel/mandel_compaction_soln.py b/tests/fullscale/poroelasticity/mandel/mandel_compaction_soln.py deleted file mode 100644 index 2bf8aa2852..0000000000 --- a/tests/fullscale/poroelasticity/mandel/mandel_compaction_soln.py +++ /dev/null @@ -1,479 +0,0 @@ -# ================================================================================================= -# This code is part of PyLith, developed through the Computational Infrastructure -# for Geodynamics (https://github.com/geodynamics/pylith). -# -# Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. -# All rights reserved. -# -# See https://mit-license.org/ and LICENSE.md and for license information. -# ================================================================================================= -# @file tests/fullscale/poroelasticity/mandel_compaction/mandel_compaction_soln.py -# -# @brief Analytical solution to Mandel's problem. -# Owing to the symmetry of the problem, we only need consider the quarter -# domain case. -# -# -F -# ---------- -# | | -# Ux=0 | | P=0 -# | | -# | | -# ---------- -# Uy=0 -# -# Dirichlet boundary conditions -# Ux(0,y) = 0 -# Uy(x,0) = 0 -# Neumann boundary conditions -# \tau_normal(x,ymax) = -1*Pa - -import numpy - -# Physical properties -rho_s = 2500 # kg / m**3 -rho_f = 1000 # kg / m**3 -mu_f = 1.0 # Pa*s -G = 3.0 # Pa -K_sg = 10.0 # Pa -K_fl = 8.0 # Pa -K_d = 4.0 # Pa -# K_u = 2.6941176470588233 # Pa -alpha = 0.6 # - -phi = 0.1 -# M = 4.705882352941176 # Pa -k = 1.5 # m**2 - -xmin = 0.0 # m -xmax = 10.0 # m -ymin = 0.0 # m -ymax = 1.0 # m - - -# Height of column, m -a = (xmax - xmin) -b = (ymax - ymin) - - -vertical_stress = 1.0 # Pa -F = vertical_stress*a - -M = 1.0 / (phi / K_fl + (alpha - phi) / K_sg) # Pa -K_u = K_d + alpha * alpha * M # Pa, Cheng (B.5) -# K_d = K_u - alpha*alpha*M # Pa, Cheng (B.5) -nu = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G)) # -, Cheng (B.8) -nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)) # -, Cheng (B.9) -eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G) # -, Cheng (B.11) -S = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)) # Pa^{-1}, Cheng (B.14) -c = (k / mu_f) / S # m^2 / s, Cheng (B.16) -B = (3. * (nu_u - nu)) / (alpha * (1. - 2. * nu) * (1. + nu_u)) - -# Time steps -ts = 0.0028666667 # sec -nts = 2 -tsteps = numpy.arange(0.0, ts * nts, ts) + ts # sec - - -# ---------------------------------------------------------------------- -class AnalyticalSoln(object): - """Analytical solution to Mandel's problem - """ - SPACE_DIM = 2 - TENSOR_SIZE = 4 - ITERATIONS = 300 - EPS = 1e-25 - - def __init__(self): - self.fields = { - "displacement": self.displacement, - "pressure": self.pressure, - "trace_strain": self.trace_strain, - "porosity": self.porosity, - "solid_density": self.solid_density, - "fluid_density": self.fluid_density, - "fluid_viscosity": self.fluid_viscosity, - "shear_modulus": self.shear_modulus, - "undrained_bulk_modulus": self.undrained_bulk_modulus, - "drained_bulk_modulus": self.drained_bulk_modulus, - "biot_coefficient": self.biot_coefficient, - "biot_modulus": self.biot_modulus, - "isotropic_permeability": self.isotropic_permeability, - "initial_amplitude": { - "x_neg": self.zero_vector, - "x_pos": self.zero_scalar, - "y_neg": self.zero_vector, - "y_pos": self.initial_displacement, - } - } - return - - def getField(self, name, mesh_entity, pts): - if name in "initial_amplitude": - field = self.fields[name][mesh_entity](pts) - else: - field = self.fields[name](pts) - return field - - def zero_scalar(self, locs): - (npts, dim) = locs.shape - return numpy.zeros((1, npts, 1), dtype=numpy.float64) - - def zero_vector(self, locs): - (npts, dim) = locs.shape - return numpy.zeros((1, npts, self.SPACE_DIM), dtype=numpy.float64) - - def solid_density(self, locs): - """Compute solid_density field at locations. - """ - (npts, dim) = locs.shape - solid_density = rho_s * numpy.ones((1, npts, 1), dtype=numpy.float64) - return solid_density - - def fluid_density(self, locs): - """Compute fluid density field at locations. - """ - (npts, dim) = locs.shape - fluid_density = rho_f * numpy.ones((1, npts, 1), dtype=numpy.float64) - return fluid_density - - def porosity(self, locs): - """Compute solid_density field at locations. - """ - (npts, dim) = locs.shape - porosity = phi * numpy.ones((1, npts, 1), dtype=numpy.float64) - return porosity - - def shear_modulus(self, locs): - """Compute shear modulus field at locations. - """ - (npts, dim) = locs.shape - shear_modulus = G * numpy.ones((1, npts, 1), dtype=numpy.float64) - return shear_modulus - - def fluid_viscosity(self, locs): - """Compute fluid_viscosity field at locations. - """ - (npts, dim) = locs.shape - fluid_viscosity = mu_f * numpy.ones((1, npts, 1), dtype=numpy.float64) - return fluid_viscosity - - def undrained_bulk_modulus(self, locs): - """Compute undrained bulk modulus field at locations. - """ - (npts, dim) = locs.shape - undrained_bulk_modulus = K_u * numpy.ones((1, npts, 1), dtype=numpy.float64) - return undrained_bulk_modulus - - def drained_bulk_modulus(self, locs): - """Compute undrained bulk modulus field at locations. - """ - (npts, dim) = locs.shape - drained_bulk_modulus = K_d * numpy.ones((1, npts, 1), dtype=numpy.float64) - return drained_bulk_modulus - - def biot_coefficient(self, locs): - """Compute biot coefficient field at locations. - """ - (npts, dim) = locs.shape - biot_coefficient = alpha * numpy.ones((1, npts, 1), dtype=numpy.float64) - return biot_coefficient - - def biot_modulus(self, locs): - """Compute biot modulus field at locations. - """ - (npts, dim) = locs.shape - biot_modulus = M * numpy.ones((1, npts, 1), dtype=numpy.float64) - return biot_modulus - - def isotropic_permeability(self, locs): - """Compute isotropic permeability field at locations. - """ - (npts, dim) = locs.shape - isotropic_permeability = k * numpy.ones((1, npts, 1), dtype=numpy.float64) - return isotropic_permeability - - def y_pos(self, locs): - """Compute initial traction at locations. - - :TODO: If this is the initial traction, then it should be a single time point (0). - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - t_track = 0 - - displacement = numpy.zeros((ntpts, npts, self.SPACE_DIM), dtype=numpy.float64) - displacement[:, :, 0] = 0.0 - for t in tsteps: - displacement[t_track, :, 1] = F - t_track += 1 - return traction - - def displacement(self, locs): - """Compute displacement field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - displacement = numpy.zeros((ntpts, npts, dim), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t_track = 0 - zeroArray = self.mandelZeros() - - for t in tsteps: - A_x = 0.0 - B_x = 0.0 - - for n in numpy.arange(1, self.ITERATIONS + 1, 1): - a_n = zeroArray[n - 1] - A_x += (numpy.sin(a_n) * numpy.cos(a_n) / (a_n - numpy.sin(a_n) * numpy.cos(a_n))) * \ - numpy.exp(-1.0 * (a_n * a_n * c * t) / (a * a)) - B_x += (numpy.cos(a_n) / (a_n - numpy.sin(a_n) * numpy.cos(a_n))) * \ - numpy.sin((a_n * x) / a) * numpy.exp(-1.0 * (a_n * a_n * c * t) / (a * a)) - - displacement[t_track, :, 0] = ((F * nu) / (2.0 * G * a) - (F * nu_u) / (G * a) * A_x) * x + F / G * B_x - displacement[t_track, :, 1] = (-1 * (F * (1.0 - nu)) / (2 * G * a) + (F * (1 - nu_u)) / (G * a) * A_x) * z - t_track += 1 - - return displacement - - def pressure(self, locs): - """Compute pressure field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - pressure = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t_track = 0 - zeroArray = self.mandelZeros() - - for t in tsteps: - - if t == 0.0: - pressure[t_track, :] = (1. / (3. * a)) * (B * (1. + nu_u)) * F - else: - p = 0.0 - for n in numpy.arange(1, self.ITERATIONS + 1, 1): - x_n = zeroArray[n - 1] - p += (numpy.sin(x_n) / (x_n - numpy.sin(x_n) * numpy.cos(x_n))) * \ - (numpy.cos((x_n * x) / a) - numpy.cos(x_n)) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - pressure[t_track, :, 0] = ((2.0 * (F * B * (1.0 + nu_u))) / (3.0 * a)) * p - t_track += 1 - - return pressure - - def trace_strain(self, locs): - """Compute trace strain field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - trace_strain = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t_track = 0 - zeroArray = self.mandelZeros() - - for t in tsteps: - - eps_A = 0.0 - eps_B = 0.0 - eps_C = 0.0 - - for i in numpy.arange(1, self.ITERATIONS+1,1): - x_n = zeroArray[i-1] - eps_A += (x_n * numpy.exp( (-1.0*x_n*x_n*c*t)/(a*a)) * numpy.cos(x_n)*numpy.cos( (x_n*x)/a)) / (a * (x_n - numpy.sin(x_n)*numpy.cos(x_n))) - eps_B += ( numpy.exp( (-1.0*x_n*x_n*c*t)/(a*a)) * numpy.sin(x_n)*numpy.cos(x_n)) / (x_n - numpy.sin(x_n)*numpy.cos(x_n)) - eps_C += ( numpy.exp( (-1.0*x_n*x_n*c*t)/(x_n*x_n)) * numpy.sin(x_n)*numpy.cos(x_n)) / (x_n - numpy.sin(x_n)*numpy.cos(x_n)) - - trace_strain[t_track,:,0] = (F/G)*eps_A + ( (F*nu)/(2.0*G*a)) - eps_B/(G*a) - (F*(1.0-nu))/(2/0*G*a) + eps_C/(G*a) - t_track += 1 - - return trace_strain - - def zero_array_dim(self, locs): - """ Return zero valued array, dimension = ndim - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - zero_array_dim = numpy.zeros((ntpts, npts, dim), dtype=numpy.float64) - - return zero_array_dim - - def zero_array(self, locs): - """ Return zero valued array - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - zero_array = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) - - return zero_array - - # Series functions - - def mandelZeros(self): - """Compute roots for analytical mandel problem solutions - """ - zeroArray = numpy.zeros(self.ITERATIONS) - x0 = 0 - - for i in numpy.arange(1, self.ITERATIONS + 1, 1): - a1 = x0 + numpy.pi/4 - a2 = x0 + numpy.pi/2 - 10000*2.2204e-16 - am = a1 - for j in numpy.arange(0, self.ITERATIONS, 1): - y1 = numpy.tan(a1) - ((1.0 - nu) / (nu_u - nu)) * a1 - y2 = numpy.tan(a2) - ((1.0 - nu) / (nu_u - nu)) * a2 - am = (a1 + a2) / 2.0 - ym = numpy.tan(am) - (1 - nu) / (nu_u - nu) * am - if ((ym * y1) > 0): - a1 = am - else: - a2 = am - if (numpy.abs(y2) < self.EPS): - am = a2 - zeroArray[i - 1] = am - x0 += numpy.pi - return zeroArray - - def strain(self, locs): - """Compute strain field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - e_xx = 0.0 - e_yy = self.trace_strain(locs) - e_zz = 0.0 - e_xy = 0.0 - - strain = numpy.zeros((ntpts, npts, self.TENSOR_SIZE), dtype=numpy.float64) - strain[:, :, 0] = exx - strain[:, :, 1] = eyy - strain[:, :, 2] = ezz - strain[:, :, 3] = exy - return strain - - def stress(self, locs): - """Compute stress field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - p_poisson_ratio = (3 * p_K_d - 2 * p_G) / (2 * (3 * p_K_d + p_G)) - trace_strain = self.trace_strain(locs) - pressure = self.pressure(locs) - e_xx = 0.0 - e_yy = self.trace_strain(locs) - e_xy = 0.0 - - stress = numpy.zeros((ntpts, npts, self.TENSOR_SIZE), dtype=numpy.float64) - stress[:, :, 0] = ((2 * p_G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * \ - trace_strain + 2 * p_G * e_xx - p_alpha * pressure - stress[:, :, 1] = ((2 * p_G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * \ - trace_strain + 2 * p_G * e_yy - p_alpha * pressure - stress[:, :, 2] = ((2 * p_G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * trace_strain - p_alpha * pressure - stress[:, :, 3] = 2 * p_G * e_xy - return stress - - def initial_traction(self, locs): - """Compute traction at locations. - - :TODO: If this is the initial traction, then it should be a single time point (0). - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - traction = numpy.zeros((ntpts, npts, self.SPACE_DIM), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t_track = 0 - zeroArray = self.mandelZeros() - - for t in tsteps: - - sigma_zz_A = 0.0 - sigma_zz_B = 0.0 - - for i in np.arange(1, self.ITERATIONS + 1, 1): - x_n = zeroArray[i - 1] - sigma_zz_A += (numpy.sin(x_n) / (x_n - numpy.sin(x_n) * numpy.cos(x_n))) * \ - numpy.cos((x_n * x) / a) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - sigma_zz_B += ((numpy.sin(x_n) * numpy.cos(x_n)) / (x_n - numpy.sin(x_n) * - numpy.cos(x_n))) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - - traction[t_track, :, 0] = 0.0 - traction[t_track, :, 1] = -(F / a) - ((2.0 * F * (nu_u - nu)) / (a * (1.0 - nu)) - ) * sigma_zz_A + ((2.0 * F) / a) * sigma_zz_B - t_track += 1 - - return traction - - def initial_displacement(self, locs): - """Compute initial displacement at locations - """ - (npts, dim) = locs.shape - displacement = numpy.zeros((1, npts, dim), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - - displacement[0, :, 0] = 0.0 # (F*nu_u*x)/(2.*G*a) - displacement[0, :, 1] = -1.0 # -1.*(F*(1.-nu_u)*z)/(2.*G*a) - - return displacement - - def initial_pressure(self, locs): - """Compute initial pressure at locations - """ - (npts, dim) = locs.shape - pressure = numpy.zeros((1, npts), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t = 0.0 - - pressure[0, :] = (1. / (3. * a)) * B * (1. + nu_u) * F - - return pressure - - def initial_trace_strain(self, locs): - """Compute initial trace strain field at locations. - """ - (npts, dim) = locs.shape - zeroArray = self.mandelZeros() - trace_strain = numpy.zeros((1, npts), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t = 0.0 - - trace_strain[0, :] = 0.0 - - return trace_strain - - def sigma_zz(self, locs): - """Compute traction at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - traction = numpy.zeros((ntpts, npts, self.SPACE_DIM), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t_track = 0 - zeroArray = self.mandelZeros() - - for t in tsteps: - - sigma_zz_A = 0.0 - sigma_zz_B = 0.0 - - for i in np.arange(1, self.ITERATIONS + 1, 1): - x_n = zeroArray[i - 1] - sigma_zz_A += (numpy.sin(x_n) / (x_n - numpy.sin(x_n) * numpy.cos(x_n))) * \ - numpy.cos((x_n * x) / a) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - sigma_zz_B += ((numpy.sin(x_n) * numpy.cos(x_n)) / (x_n - numpy.sin(x_n) * - numpy.cos(x_n))) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - - traction[t_track, :, 0] = 0.0 - traction[t_track, :, 1] = -(F / a) - ((2.0 * F * (nu_u - nu)) / (a * (1.0 - nu)) - ) * sigma_zz_A + ((2.0 * F) / a) * sigma_zz_B - t_track += 1 - - return traction - - -# End of file diff --git a/tests/fullscale/poroelasticity/mandel/mandel_compaction_tri.cfg b/tests/fullscale/poroelasticity/mandel/mandel_compaction_tri.cfg deleted file mode 100644 index 11b58336b3..0000000000 --- a/tests/fullscale/poroelasticity/mandel/mandel_compaction_tri.cfg +++ /dev/null @@ -1,16 +0,0 @@ -[pylithapp.metadata] -base = [mandel_compaction.cfg] -keywords = [triangular cells] -arguments = [mandel_compaction.cfg, mandel_compaction_tri.cfg] - -[pylithapp.problem] -defaults.name = mandel_compaction_tri - -# ---------------------------------------------------------------------- -# mesh_generator -# ---------------------------------------------------------------------- -[pylithapp.mesh_generator.reader] -filename = mesh_tri.exo - - -# End of file diff --git a/tests/fullscale/poroelasticity/mandel/mandel_gendb.py b/tests/fullscale/poroelasticity/mandel/mandel_gendb.py index 81fffc78ad..d3063c5284 100755 --- a/tests/fullscale/poroelasticity/mandel/mandel_gendb.py +++ b/tests/fullscale/poroelasticity/mandel/mandel_gendb.py @@ -24,71 +24,19 @@ class GenerateDB(object): def run(self): """Generate the database. """ - # Domain - x1 = numpy.arange(-0.1, 10.1, 0.1) - y1 = numpy.arange(-0.1, 1.01, 0.1) - x, y = numpy.meshgrid(x1, y1) - - xy = numpy.zeros((len(x1) * len(y1), 2), dtype=numpy.float64) - xy[:, 0] = x.ravel() - xy[:, 1] = y.ravel() - - from mandel_soln import AnalyticalSoln - soln = AnalyticalSoln() - disp = soln.initial_displacement(xy) - pres = soln.initial_pressure(xy) - trace_strain = soln.initial_trace_strain(xy) - - from spatialdata.geocoords.CSCart import CSCart - cs = CSCart() - cs.inventory.spaceDim = 2 - cs._configure() - data = { - 'x': x1, - 'y': y1, - 'points': xy, - 'coordsys': cs, - 'data_dim': 2, - 'values': [{'name': "initial_amplitude_x", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 0])}, - {'name': "initial_amplitude_y", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 1])}, - {'name': "initial_pressure", - 'units': "Pa", - 'data': numpy.ravel(pres[0, :])}, - {'name': "initial_trace_strain", - 'units': "none", - 'data': numpy.ravel(trace_strain[0, :])}]} - - from spatialdata.spatialdb.SimpleGridAscii import SimpleGridAscii - io = SimpleGridAscii() - io.inventory.filename = "mandel_bc.spatialdb" - io._configure() - io.write(data) - data["values"] = [ - { - 'name': "displacement_x", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 0]) - }, { - 'name': "displacement_y", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 1]) - }, { - 'name': "pressure", - 'units': "Pa", - 'data': numpy.ravel(pres[0, :]) - }, { - 'name': "trace_strain", - 'units': "none", - 'data': numpy.ravel(trace_strain[0, :]) - }] - io.inventory.filename = "mandel_ic.spatialdb" - io._configure() - io.write(data) - return + import mandel_soln + soln = mandel_soln.AnalyticalSoln() + locs = numpy.array([[0, mandel_soln.y_max]]) + t_steps = numpy.arange(0.0, 100.0e+5, 1.0e+4) + + # Need to restore tsteps in mandel_soln for checking fields + soln_tsteps = mandel_soln.tsteps + mandel_soln.tsteps = t_steps + displacement = soln.displacement(locs) + + from spatialdata.spatialdb.TimeHistoryIO import write + write(t_steps, displacement[:,0,1], units="m", filename="mandel_disp.timedb") + mandel_soln.tsteps = soln_tsteps # ====================================================================== diff --git a/tests/fullscale/poroelasticity/mandel/mandel_quad.cfg b/tests/fullscale/poroelasticity/mandel/mandel_quad.cfg index 4d02bb69ae..eab6db3ebb 100644 --- a/tests/fullscale/poroelasticity/mandel/mandel_quad.cfg +++ b/tests/fullscale/poroelasticity/mandel/mandel_quad.cfg @@ -1,7 +1,7 @@ [pylithapp.metadata] base = [mandel.cfg] keywords = [quadrilateral cells] -arguments = [mandel.cfg, mandel_quad.cfg] +arguments = [mandel_quad.cfg] [pylithapp.problem] defaults.name = mandel_quad @@ -10,7 +10,7 @@ defaults.name = mandel_quad # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator.reader] -filename = mesh_quad.exo +filename = mesh_quad.msh # End of file diff --git a/tests/fullscale/poroelasticity/mandel/mandel_soln.py b/tests/fullscale/poroelasticity/mandel/mandel_soln.py index ce5c08558d..b22a4fdc91 100644 --- a/tests/fullscale/poroelasticity/mandel/mandel_soln.py +++ b/tests/fullscale/poroelasticity/mandel/mandel_soln.py @@ -13,6 +13,18 @@ # Owing to the symmetry of the problem, we only need consider the quarter # domain case. # +# This is based on Cheng (Poroelasticity, Section 7.4) and its implementation in PETSc tutorial +# src/ts/tutorials/ex53.c. +# +# Notes: +# - The surface loading is impulsive, so we use a custom PETSc TS (pylith/utils/TSAdaptImpulse), +# which uses a very small time step for the first step before using the user-specified time step. +# - The accuracy of the solution is poor in the first few time steps due to the impulsive loading +# so we only check the last time step in the simulation, which is more accurate and select a +# a tolerance appropriate for the discretization size. +# - We use a Dirichlet BC for displacement on the top surface, because the boundary value problem +# assumes loading via a rigid plate (uniform displacement) with a total load that is not uniform. +# # -F # ---------- # | | @@ -33,34 +45,33 @@ # Physical properties rho_s = 2500 # kg / m**3 rho_f = 1000 # kg / m**3 -mu_f = 1.0 # Pa*s -G = 3.0 # Pa -K_sg = 10.0 # Pa -K_fl = 8.0 # Pa -K_d = 4.0 # Pa -# K_u = 2.6941176470588233 # Pa -alpha = 0.6 # - +mu_f = 1.0e-3 # Pa*s +G = 30.0e+9 # Pa +K_sg = 100.0e+9 # Pa +K_fl = 80.0e+9 # Pa +K_d = 40.0e+9 # Pa +alpha = 0.6 phi = 0.1 -# M = 4.705882352941176 # Pa -k = 1.5 # m**2 - -xmin = 0.0 # m -xmax = 10.0 # m -ymin = 0.0 # m -ymax = 1.0 # m +k = 1.5e-13 # m**2 +x_min = 0.0e+3 # m +x_max = 8.0e+3 # m +y_min = 0.0 +y_max = 1.0e+3 +l_x = x_max - x_min -# Height of column, m -a = (xmax - xmin) -b = (ymax - ymin) +P_0 = 10.0e+3 # Pa +F = l_x*P_0 +dt0 = 1.0e-6 * 1.0e+8 +dt = 5.0e+4 +t_end = 100.0e+4 +time = numpy.concatenate((numpy.array([dt0]), dt0+numpy.arange(dt, t_end+0.5*dt, dt))) +tsteps = numpy.array([time[-1]]) -vertical_stress = 1.0 # Pa -F = vertical_stress*a M = 1.0 / (phi / K_fl + (alpha - phi) / K_sg) # Pa K_u = K_d + alpha * alpha * M # Pa, Cheng (B.5) -# K_d = K_u - alpha*alpha*M # Pa, Cheng (B.5) nu = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G)) # -, Cheng (B.8) nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)) # -, Cheng (B.9) eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G) # -, Cheng (B.11) @@ -68,11 +79,6 @@ c = (k / mu_f) / S # m^2 / s, Cheng (B.16) B = (3. * (nu_u - nu)) / (alpha * (1. - 2. * nu) * (1. + nu_u)) -# Time steps -ts = 0.0028666667 # sec -nts = 2 -tsteps = numpy.arange(0.0, ts * nts, ts) + ts # sec - # ---------------------------------------------------------------------- class AnalyticalSoln(object): @@ -81,7 +87,7 @@ class AnalyticalSoln(object): SPACE_DIM = 2 TENSOR_SIZE = 4 ITERATIONS = 300 - EPS = 1e-25 + SMALL = 1e-25 def __init__(self): self.fields = { @@ -93,16 +99,14 @@ def __init__(self): "fluid_density": self.fluid_density, "fluid_viscosity": self.fluid_viscosity, "shear_modulus": self.shear_modulus, - "undrained_bulk_modulus": self.undrained_bulk_modulus, "drained_bulk_modulus": self.drained_bulk_modulus, "biot_coefficient": self.biot_coefficient, "biot_modulus": self.biot_modulus, "isotropic_permeability": self.isotropic_permeability, "initial_amplitude": { - "x_neg": self.zero_vector, - "x_pos": self.zero_scalar, - "y_neg": self.zero_vector, - "y_pos": self.initial_displacement, + "bc_xneg": self.zero_vector, + "bc_xpos": self.zero_scalar, + "bc_yneg": self.zero_vector, } } return @@ -157,13 +161,6 @@ def fluid_viscosity(self, locs): fluid_viscosity = mu_f * numpy.ones((1, npts, 1), dtype=numpy.float64) return fluid_viscosity - def undrained_bulk_modulus(self, locs): - """Compute undrained bulk modulus field at locations. - """ - (npts, dim) = locs.shape - undrained_bulk_modulus = K_u * numpy.ones((1, npts, 1), dtype=numpy.float64) - return undrained_bulk_modulus - def drained_bulk_modulus(self, locs): """Compute undrained bulk modulus field at locations. """ @@ -192,22 +189,6 @@ def isotropic_permeability(self, locs): isotropic_permeability = k * numpy.ones((1, npts, 1), dtype=numpy.float64) return isotropic_permeability - def y_pos(self, locs): - """Compute initial traction at locations. - - :TODO: If this is the initial traction, then it should be a single time point (0). - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - t_track = 0 - - displacement = numpy.zeros((ntpts, npts, self.SPACE_DIM), dtype=numpy.float64) - displacement[:, :, 0] = 0.0 - for t in tsteps: - displacement[t_track, :, 1] = F - t_track += 1 - return traction - def displacement(self, locs): """Compute displacement field at locations. """ @@ -215,25 +196,22 @@ def displacement(self, locs): ntpts = tsteps.shape[0] displacement = numpy.zeros((ntpts, npts, dim), dtype=numpy.float64) x = locs[:, 0] - z = locs[:, 1] - t_track = 0 + y = locs[:, 1] zeroArray = self.mandelZeros() - for t in tsteps: - A_x = 0.0 - B_x = 0.0 - - for n in numpy.arange(1, self.ITERATIONS + 1, 1): + n = numpy.arange(1, self.ITERATIONS+1, 1) + a_n = zeroArray[n - 1] + for i_t, t in enumerate(tsteps): + A_s = numpy.sum((numpy.sin(a_n) * numpy.cos(a_n) / (a_n - numpy.sin(a_n) * numpy.cos(a_n))) * \ + numpy.exp(-1.0 * (a_n * a_n * c * t) / (l_x * l_x))) + B_s = numpy.zeros(x.shape) + for i_x, x_pt in enumerate(x): a_n = zeroArray[n - 1] - A_x += (numpy.sin(a_n) * numpy.cos(a_n) / (a_n - numpy.sin(a_n) * numpy.cos(a_n))) * \ - numpy.exp(-1.0 * (a_n * a_n * c * t) / (a * a)) - B_x += (numpy.cos(a_n) / (a_n - numpy.sin(a_n) * numpy.cos(a_n))) * \ - numpy.sin((a_n * x) / a) * numpy.exp(-1.0 * (a_n * a_n * c * t) / (a * a)) - - displacement[t_track, :, 0] = ((F * nu) / (2.0 * G * a) - (F * nu_u) / (G * a) * A_x) * x + F / G * B_x - displacement[t_track, :, 1] = (-1 * (F * (1.0 - nu)) / (2 * G * a) + (F * (1 - nu_u)) / (G * a) * A_x) * z - t_track += 1 + B_s[i_x] = numpy.sum((numpy.cos(a_n) / (a_n - numpy.sin(a_n) * numpy.cos(a_n))) * \ + numpy.sin((a_n * x_pt) / l_x) * numpy.exp(-1.0 * (a_n * a_n * c * t) / (l_x * l_x))) + displacement[i_t, :, 0] = ((F * nu) / (2.0 * G * l_x) - (F * nu_u) / (G * l_x) * A_s) * x + F / G * B_s + displacement[i_t, :, 1] = (-1 * (F * (1.0 - nu)) / (2.0 * G * l_x) + (F * (1 - nu_u)) / (G * l_x) * A_s) * y return displacement def pressure(self, locs): @@ -243,23 +221,16 @@ def pressure(self, locs): ntpts = tsteps.shape[0] pressure = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) x = locs[:, 0] - z = locs[:, 1] - t_track = 0 zeroArray = self.mandelZeros() - for t in tsteps: - - if t == 0.0: - pressure[t_track, :] = (1. / (3. * a)) * (B * (1. + nu_u)) * F - else: - p = 0.0 - for n in numpy.arange(1, self.ITERATIONS + 1, 1): - x_n = zeroArray[n - 1] - p += (numpy.sin(x_n) / (x_n - numpy.sin(x_n) * numpy.cos(x_n))) * \ - (numpy.cos((x_n * x) / a) - numpy.cos(x_n)) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - pressure[t_track, :, 0] = ((2.0 * (F * B * (1.0 + nu_u))) / (3.0 * a)) * p - t_track += 1 - + for i_t, t in enumerate(tsteps): + n = numpy.arange(1, self.ITERATIONS+1, 1) + a_n = zeroArray[n-1] + p = numpy.zeros(x.shape) + for i_x, x_pt in enumerate(x): + p[i_x] = numpy.sum((numpy.sin(a_n) / (a_n - numpy.sin(a_n) * numpy.cos(a_n))) * \ + (numpy.cos((a_n * x_pt) / l_x) - numpy.cos(a_n)) * numpy.exp(-1.0 * (a_n * a_n * c * t) / (l_x * l_x))) + pressure[i_t, :, 0] = (2 * F * B * (1.0 + nu_u)) / (3.0 * l_x) * p return pressure def trace_strain(self, locs): @@ -269,31 +240,24 @@ def trace_strain(self, locs): ntpts = tsteps.shape[0] trace_strain = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) x = locs[:, 0] - z = locs[:, 1] - t_track = 0 zeroArray = self.mandelZeros() - for t in tsteps: - - eps_A = 0.0 - eps_B = 0.0 - eps_C = 0.0 - - for i in numpy.arange(1, self.ITERATIONS+1,1): - x_n = zeroArray[i-1] - eps_A += (x_n * numpy.exp( (-1.0*x_n*x_n*c*t)/(a*a)) * numpy.cos(x_n)*numpy.cos( (x_n*x)/a)) / (a * (x_n - numpy.sin(x_n)*numpy.cos(x_n))) - eps_B += ( numpy.exp( (-1.0*x_n*x_n*c*t)/(a*a)) * numpy.sin(x_n)*numpy.cos(x_n)) / (x_n - numpy.sin(x_n)*numpy.cos(x_n)) - eps_C += ( numpy.exp( (-1.0*x_n*x_n*c*t)/(x_n*x_n)) * numpy.sin(x_n)*numpy.cos(x_n)) / (x_n - numpy.sin(x_n)*numpy.cos(x_n)) - - trace_strain[t_track,:,0] = (F/G)*eps_A + ( (F*nu)/(2.0*G*a)) - eps_B/(G*a) - (F*(1.0-nu))/(2/0*G*a) + eps_C/(G*a) - t_track += 1 + for i_t, t in enumerate(tsteps): + n = numpy.arange(1, self.ITERATIONS+1, 1) + a_n = zeroArray[n-1] + eps_B = numpy.sum((numpy.exp((-1.0*a_n*a_n*c*t)/(l_x*l_x)) * numpy.sin(a_n)*numpy.cos(a_n)) / (a_n - numpy.sin(a_n)*numpy.cos(a_n))) + eps_C = numpy.sum((numpy.exp((-1.0*a_n*a_n*c*t)/(a_n*a_n)) * numpy.sin(a_n)*numpy.cos(a_n)) / (a_n - numpy.sin(a_n)*numpy.cos(a_n))) + eps_A = numpy.zeros(x.shape) + for i_x, x_pt in enumerate(x): + eps_A[i_x] = numpy.sum((a_n * numpy.exp((-1.0*a_n*a_n*c*t)/(l_x*l_x)) * numpy.cos(a_n)*numpy.cos( (a_n*x_pt)/l_x)) / (l_x * (a_n - numpy.sin(a_n)*numpy.cos(a_n)))) + trace_strain[i_t, :, 0] = (F/G)*eps_A + ( (F*nu)/(2.0*G*l_x)) - eps_B/(G*l_x) - (F*(1.0-nu))/(2.0*G*l_x) + eps_C/(G*l_x) return trace_strain # Series functions def mandelZeros(self): - """Compute roots for analytical mandel problem solutions + """Compute roots for analytical Mandel problem solutions """ zeroArray = numpy.zeros(self.ITERATIONS) x0 = 0 @@ -311,7 +275,7 @@ def mandelZeros(self): a1 = am else: a2 = am - if (numpy.abs(y2) < self.EPS): + if (numpy.abs(y2) < self.SMALL): am = a2 zeroArray[i - 1] = am x0 += numpy.pi @@ -328,10 +292,10 @@ def strain(self, locs): e_xy = 0.0 strain = numpy.zeros((ntpts, npts, self.TENSOR_SIZE), dtype=numpy.float64) - strain[:, :, 0] = exx - strain[:, :, 1] = eyy - strain[:, :, 2] = ezz - strain[:, :, 3] = exy + strain[:, :, 0] = e_xx + strain[:, :, 1] = e_yy + strain[:, :, 2] = e_zz + strain[:, :, 3] = e_xy return strain def stress(self, locs): @@ -339,7 +303,7 @@ def stress(self, locs): """ (npts, dim) = locs.shape ntpts = tsteps.shape[0] - p_poisson_ratio = (3 * p_K_d - 2 * p_G) / (2 * (3 * p_K_d + p_G)) + p_poisson_ratio = (3 * K_d - 2 * G) / (2 * (3 * K_d + G)) trace_strain = self.trace_strain(locs) pressure = self.pressure(locs) e_xx = 0.0 @@ -347,115 +311,13 @@ def stress(self, locs): e_xy = 0.0 stress = numpy.zeros((ntpts, npts, self.TENSOR_SIZE), dtype=numpy.float64) - stress[:, :, 0] = ((2 * p_G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * \ - trace_strain + 2 * p_G * e_xx - p_alpha * pressure - stress[:, :, 1] = ((2 * p_G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * \ - trace_strain + 2 * p_G * e_yy - p_alpha * pressure - stress[:, :, 2] = ((2 * p_G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * trace_strain - p_alpha * pressure - stress[:, :, 3] = 2 * p_G * e_xy + stress[:, :, 0] = ((2 * G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * \ + trace_strain + 2 * G * e_xx - alpha * pressure + stress[:, :, 1] = ((2 * G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * \ + trace_strain + 2 * G * e_yy - alpha * pressure + stress[:, :, 2] = ((2 * G * p_poisson_ratio) / (1 - 2 * p_poisson_ratio)) * trace_strain - alpha * pressure + stress[:, :, 3] = 2 * G * e_xy return stress - def initial_traction(self, locs): - """Compute traction at locations. - - :TODO: If this is the initial traction, then it should be a single time point (0). - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - traction = numpy.zeros((ntpts, npts, self.SPACE_DIM), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t_track = 0 - zeroArray = self.mandelZeros() - - for t in tsteps: - - sigma_zz_A = 0.0 - sigma_zz_B = 0.0 - - for i in np.arange(1, self.ITERATIONS + 1, 1): - x_n = zeroArray[i - 1] - sigma_zz_A += (numpy.sin(x_n) / (x_n - numpy.sin(x_n) * numpy.cos(x_n))) * \ - numpy.cos((x_n * x) / a) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - sigma_zz_B += ((numpy.sin(x_n) * numpy.cos(x_n)) / (x_n - numpy.sin(x_n) * - numpy.cos(x_n))) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - - traction[t_track, :, 0] = 0.0 - traction[t_track, :, 1] = -(F / a) - ((2.0 * F * (nu_u - nu)) / (a * (1.0 - nu)) - ) * sigma_zz_A + ((2.0 * F) / a) * sigma_zz_B - t_track += 1 - - return traction - - def initial_displacement(self, locs): - """Compute initial displacement at locations - """ - (npts, dim) = locs.shape - displacement = numpy.zeros((1, npts, dim), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - - displacement[0, :, 0] = 0.0 # (F*nu_u*x)/(2.*G*a) - displacement[0, :, 1] = -1.0 # -1.*(F*(1.-nu_u)*z)/(2.*G*a) - - return displacement - - def initial_pressure(self, locs): - """Compute initial pressure at locations - """ - (npts, dim) = locs.shape - pressure = numpy.zeros((1, npts), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t = 0.0 - - pressure[0, :] = (1. / (3. * a)) * B * (1. + nu_u) * F - - return pressure - - def initial_trace_strain(self, locs): - """Compute initial trace strain field at locations. - """ - (npts, dim) = locs.shape - zeroArray = self.mandelZeros() - trace_strain = numpy.zeros((1, npts), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t = 0.0 - - trace_strain[0, :] = 0.0 - - return trace_strain - - def sigma_zz(self, locs): - """Compute traction at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - traction = numpy.zeros((ntpts, npts, self.SPACE_DIM), dtype=numpy.float64) - x = locs[:, 0] - z = locs[:, 1] - t_track = 0 - zeroArray = self.mandelZeros() - - for t in tsteps: - - sigma_zz_A = 0.0 - sigma_zz_B = 0.0 - - for i in np.arange(1, self.ITERATIONS + 1, 1): - x_n = zeroArray[i - 1] - sigma_zz_A += (numpy.sin(x_n) / (x_n - numpy.sin(x_n) * numpy.cos(x_n))) * \ - numpy.cos((x_n * x) / a) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - sigma_zz_B += ((numpy.sin(x_n) * numpy.cos(x_n)) / (x_n - numpy.sin(x_n) * - numpy.cos(x_n))) * numpy.exp(-1.0 * (x_n * x_n * c * t) / (a * a)) - - traction[t_track, :, 0] = 0.0 - traction[t_track, :, 1] = -(F / a) - ((2.0 * F * (nu_u - nu)) / (a * (1.0 - nu)) - ) * sigma_zz_A + ((2.0 * F) / a) * sigma_zz_B - t_track += 1 - - return traction - # End of file diff --git a/tests/fullscale/poroelasticity/mandel/mandel_tri.cfg b/tests/fullscale/poroelasticity/mandel/mandel_tri.cfg index bcb827113e..eec6d59732 100644 --- a/tests/fullscale/poroelasticity/mandel/mandel_tri.cfg +++ b/tests/fullscale/poroelasticity/mandel/mandel_tri.cfg @@ -1,7 +1,7 @@ [pylithapp.metadata] base = [mandel.cfg] keywords = [triangular cells] -arguments = [mandel.cfg, mandel_tri.cfg] +arguments = [mandel_tri.cfg] [pylithapp.problem] defaults.name = mandel_tri @@ -10,7 +10,7 @@ defaults.name = mandel_tri # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator.reader] -filename = mesh_tri.exo +filename = mesh_tri.msh # End of file diff --git a/tests/fullscale/poroelasticity/mandel/mesh_quad.exo b/tests/fullscale/poroelasticity/mandel/mesh_quad.exo deleted file mode 100644 index a3d8a84b23..0000000000 Binary files a/tests/fullscale/poroelasticity/mandel/mesh_quad.exo and /dev/null differ diff --git a/tests/fullscale/poroelasticity/mandel/mesh_quad.jou b/tests/fullscale/poroelasticity/mandel/mesh_quad.jou deleted file mode 100644 index f59e5661b1..0000000000 --- a/tests/fullscale/poroelasticity/mandel/mesh_quad.jou +++ /dev/null @@ -1,25 +0,0 @@ -# ---------------------------------------------------------------------- -# Generate geometry -# ---------------------------------------------------------------------- -playback 'geometry.jou' - -# ---------------------------------------------------------------------- -# Set discretization size -# ---------------------------------------------------------------------- -surface all size 0.25 - -# ---------------------------------------------------------------------- -# Generate the mesh -# ---------------------------------------------------------------------- -surface all scheme submap -mesh surface all - -# ---------------------------------------------------------------------- -# Mark entities for boundary conditions, etc. -# ---------------------------------------------------------------------- -playback 'bc.jou' - -# ---------------------------------------------------------------------- -# Export exodus file -# ---------------------------------------------------------------------- -export mesh "mesh_quad.exo" dimension 2 overwrite diff --git a/tests/fullscale/poroelasticity/mandel/mesh_quad.msh b/tests/fullscale/poroelasticity/mandel/mesh_quad.msh new file mode 100644 index 0000000000..d953b0639e Binary files /dev/null and b/tests/fullscale/poroelasticity/mandel/mesh_quad.msh differ diff --git a/tests/fullscale/poroelasticity/mandel/mesh_tri.exo b/tests/fullscale/poroelasticity/mandel/mesh_tri.exo deleted file mode 100644 index 0dd0ab82a5..0000000000 Binary files a/tests/fullscale/poroelasticity/mandel/mesh_tri.exo and /dev/null differ diff --git a/tests/fullscale/poroelasticity/mandel/mesh_tri.jou b/tests/fullscale/poroelasticity/mandel/mesh_tri.jou deleted file mode 100644 index 5d2b546666..0000000000 --- a/tests/fullscale/poroelasticity/mandel/mesh_tri.jou +++ /dev/null @@ -1,25 +0,0 @@ -# ---------------------------------------------------------------------- -# Generate geometry -# ---------------------------------------------------------------------- -playback 'geometry.jou' - -# ---------------------------------------------------------------------- -# Set discretization size -# ---------------------------------------------------------------------- -surface all size 0.25 - -# ---------------------------------------------------------------------- -# Generate the mesh -# ---------------------------------------------------------------------- -surface all scheme trimesh -mesh surface all - -# ---------------------------------------------------------------------- -# Mark entities for boundary conditions, etc. -# ---------------------------------------------------------------------- -playback 'bc.jou' - -# ---------------------------------------------------------------------- -# Export exodus file -# ---------------------------------------------------------------------- -export mesh "mesh_tri.exo" dimension 2 overwrite diff --git a/tests/fullscale/poroelasticity/mandel/mesh_tri.msh b/tests/fullscale/poroelasticity/mandel/mesh_tri.msh new file mode 100644 index 0000000000..6e9594bba0 Binary files /dev/null and b/tests/fullscale/poroelasticity/mandel/mesh_tri.msh differ diff --git a/tests/fullscale/poroelasticity/mandel/meshes.py b/tests/fullscale/poroelasticity/mandel/meshes.py index e4f025c1f1..fdb416cb32 100644 --- a/tests/fullscale/poroelasticity/mandel/meshes.py +++ b/tests/fullscale/poroelasticity/mandel/meshes.py @@ -18,16 +18,16 @@ class Tri(object): """Mesh information for tri mesh. """ ENTITIES = { - "domain": MeshEntity(ncells=320, ncorners=3, nvertices=205), + "domain": MeshEntity(ncells=488, ncorners=3, nvertices=290), # Materials - "poroelastic": MeshEntity(ncells=320, ncorners=3, nvertices=205), + "poroelastic": MeshEntity(ncells=488, ncorners=3, nvertices=290), # Boundaries - "x_neg": MeshEntity(ncells=4, ncorners=2, nvertices=5), - "x_pos": MeshEntity(ncells=4, ncorners=2, nvertices=5), - "y_neg": MeshEntity(ncells=40, ncorners=2, nvertices=41), - "y_pos": MeshEntity(ncells=40, ncorners=2, nvertices=41), + "bc_xneg": MeshEntity(ncells=5, ncorners=2, nvertices=6), + "bc_xpos": MeshEntity(ncells=5, ncorners=2, nvertices=6), + "bc_yneg": MeshEntity(ncells=40, ncorners=2, nvertices=41), + "bc_ypos": MeshEntity(ncells=40, ncorners=2, nvertices=41), } @@ -35,16 +35,16 @@ class Quad(object): """Mesh information for quad mesh. """ ENTITIES = { - "domain": MeshEntity(ncells=160, ncorners=4, nvertices=205), + "domain": MeshEntity(ncells=200, ncorners=4, nvertices=246), # Materials - "poroelastic": MeshEntity(ncells=160, ncorners=4, nvertices=205), + "poroelastic": MeshEntity(ncells=200, ncorners=4, nvertices=246), # Boundaries - "x_neg": MeshEntity(ncells=4, ncorners=2, nvertices=5), - "x_pos": MeshEntity(ncells=4, ncorners=2, nvertices=5), - "y_neg": MeshEntity(ncells=40, ncorners=2, nvertices=41), - "y_pos": MeshEntity(ncells=40, ncorners=2, nvertices=41), + "bc_xneg": MeshEntity(ncells=5, ncorners=2, nvertices=6), + "bc_xpos": MeshEntity(ncells=5, ncorners=2, nvertices=6), + "bc_yneg": MeshEntity(ncells=40, ncorners=2, nvertices=41), + "bc_ypos": MeshEntity(ncells=40, ncorners=2, nvertices=41), } diff --git a/tests/fullscale/poroelasticity/mandel/mandel.cfg b/tests/fullscale/poroelasticity/mandel/pylithapp.cfg similarity index 74% rename from tests/fullscale/poroelasticity/mandel/mandel.cfg rename to tests/fullscale/poroelasticity/mandel/pylithapp.cfg index e1f02eae8a..7e695c5593 100644 --- a/tests/fullscale/poroelasticity/mandel/mandel.cfg +++ b/tests/fullscale/poroelasticity/mandel/pylithapp.cfg @@ -8,7 +8,7 @@ pylith_version = [>=3.0, <6.0] features = [ Quasistatic problem, pylith.materials.Poroelasticity, - pylith.meshio.MeshIOCubit, + pylith.meshio.MeshIOPetsc, pylith.problems.TimeDependent, pylith.problems.SolnDispPresTracStrain, pylith.bc.DirichletTimeDependent, @@ -28,22 +28,6 @@ command = mpiexec -np ${nodes} #timedependent = 1 #solution = 1 #petsc = 1 -#meshio = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#faultcohesivekin = 1 - -[pylithapp.journal.debug] -#timedependent = 1 -#solution = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#constraintspatialdb = 1 -#faultcohesivekin = 1 -#integratorinterface = 1 -#kinsrcstep = 1 -#outputphysics = 1 -#outputsolndomain = 1 # ---------------------------------------------------------------------- # problem @@ -51,20 +35,21 @@ command = mpiexec -np ${nodes} [pylithapp.problem] defaults.quadrature_order = 2 -# Use nonlinear solver to ensure residual and Jacobian are consistent. solver = nonlinear solution = pylith.problems.SolnDispPresTracStrain [pylithapp.timedependent] start_time = 0.0*s -initial_dt = 0.0028666667*s -end_time = 0.0057333334*s +initial_dt = 5.0e+4*s +end_time = 100.0e+4*s -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 0.25*m -normalizer.relaxation_time = 1.0*s -normalizer.shear_modulus = 1.0*m**-1*kg*s**-2 +scales = pylith.scales.QuasistaticPoroelasticity +scales.displacement_scale = 1.0*mm +scales.length_scale = 10.0*km +scales.shear_modulus = 10.0*GPa +scales.viscosity = 0.001*Pa*s +scales.permeability = 1.0e-13*m**2 [pylithapp.problem.solution.subfields] displacement.basis_order = 2 @@ -78,7 +63,7 @@ solution_observers = [domain] # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator] -reader = pylith.meshio.MeshIOCubit +reader = pylith.meshio.MeshIOPetsc [pylithapp.mesh_generator.reader] coordsys.space_dim = 2 @@ -98,9 +83,9 @@ label_value = 1 db_auxiliary_field = spatialdata.spatialdb.UniformDB db_auxiliary_field.description = Poroelastic properties db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 1.0*Pa*s, 0.1, 3.0*Pa, 4.0*Pa, 0.6, 8.0*Pa, 1.5*m**2] +db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 0.001*Pa*s, 0.1, 30.0*GPa, 40.0*GPa, 0.6, 80.0*GPa, 1.5e-13*m**2] -observers.observer.data_fields = [displacement,pressure,trace_strain] +observers.observer.data_fields = [displacement, pressure, trace_strain] auxiliary_subfields.body_force.basis_order = 0 auxiliary_subfields.solid_density.basis_order = 0 @@ -119,50 +104,62 @@ auxiliary_subfields.biot_coefficient.basis_order = 0 auxiliary_subfields.biot_modulus.basis_order = 0 auxiliary_subfields.isotropic_permeability.basis_order = 0 + # ---------------------------------------------------------------------- # boundary conditions # ---------------------------------------------------------------------- [pylithapp.problem] -bc = [x_neg,x_pos,y_neg,y_pos] +bc = [bc_xneg, bc_xpos, bc_yneg, bc_ypos] -bc.x_pos = pylith.bc.DirichletTimeDependent -bc.x_neg = pylith.bc.DirichletTimeDependent -bc.y_neg = pylith.bc.DirichletTimeDependent -bc.y_pos = pylith.bc.NeumannTimeDependent +bc.bc_xpos = pylith.bc.DirichletTimeDependent +bc.bc_xneg = pylith.bc.DirichletTimeDependent +bc.bc_yneg = pylith.bc.DirichletTimeDependent +bc.bc_ypos = pylith.bc.DirichletTimeDependent # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_pos] -constrained_dof = [0] -label = x_pos +[pylithapp.problem.bc.bc_xpos] +label = boundary_xpos +label_value = 11 field = pressure +constrained_dof = [0] + db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on +x boundary # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_neg] -constrained_dof = [0] -label = x_neg +[pylithapp.problem.bc.bc_xneg] +label = boundary_xneg +label_value = 10 field = displacement +constrained_dof = [0] + db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on -x boundary # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_pos] -# Neumann Case -label = y_pos -field = displacement -scale_name = pressure -use_initial = True +[pylithapp.problem.bc.bc_ypos] +label = boundary_ypos +label_value = 13 +constrained_dof = [1] +use_initial = False +use_time_history = True + db_auxiliary_field = spatialdata.spatialdb.UniformDB -db_auxiliary_field.description = Neumann BC +y edge -db_auxiliary_field.values = [initial_amplitude_tangential, initial_amplitude_normal] -db_auxiliary_field.data = [0.0*Pa, -1.0*Pa] +db_auxiliary_field.description = Dirichlet BC on +y boundary +db_auxiliary_field.values = [time_history_amplitude_x, time_history_amplitude_y, time_history_start_time] +db_auxiliary_field.data = [0.0*Pa, 1.0*m, 0.0*s] + +time_history = spatialdata.spatialdb.TimeHistory +time_history.description = Displacement time history +time_history.filename = mandel_disp.timedb # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_neg] -constrained_dof = [1] -label = y_neg +[pylithapp.problem.bc.bc_yneg] +label = boundary_yneg +label_value = 12 field = displacement +constrained_dof = [1] + db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on -y boundary @@ -174,6 +171,7 @@ solver = True testing = True monitors = False initial_guess = False +impulse_ts = True # End of file diff --git a/tests/fullscale/poroelasticity/mandel/test_pylith.py b/tests/fullscale/poroelasticity/mandel/test_pylith.py index 5361e62c74..ac89c2a0c1 100755 --- a/tests/fullscale/poroelasticity/mandel/test_pylith.py +++ b/tests/fullscale/poroelasticity/mandel/test_pylith.py @@ -33,10 +33,6 @@ def _suite(self): for test in TestMandel.test_cases(): suite.addTest(unittest.makeSuite(test)) - import TestMandelCompaction - for test in TestMandelCompaction.test_cases(): - suite.addTest(unittest.makeSuite(test)) - return suite diff --git a/tests/fullscale/poroelasticity/nofaults-2d/TestBodyForce.py b/tests/fullscale/poroelasticity/nofaults-2d/TestBodyForce.py index c9ffa9b52c..b8e1af3b61 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/TestBodyForce.py +++ b/tests/fullscale/poroelasticity/nofaults-2d/TestBodyForce.py @@ -72,17 +72,17 @@ def setUp(self): vertex_fields=["initial_amplitude", "normal_dir", "tangential_dir"], defaults=defaults, ), - # Check( - # mesh_entities=[ - # "bc_disp_xpos", - # "bc_disp_yneg", - # "bc_disp_ypos", - # "bc_press_yneg", - # ], - # vertex_fields=["displacement", "pressure", "trace_strain"], - # final_time_only=True, - # defaults=defaults, - # ), + Check( + mesh_entities=[ + "bc_disp_xpos", + "bc_disp_yneg", + "bc_disp_ypos", + "bc_press_xneg", + ], + vertex_fields=["displacement", "pressure", "trace_strain"], + final_time_only=True, + defaults=defaults, + ), ] def run_pylith(self, testName, args): diff --git a/tests/fullscale/poroelasticity/nofaults-2d/bodyforce.cfg b/tests/fullscale/poroelasticity/nofaults-2d/bodyforce.cfg index ff06024e7f..932427a7b0 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/bodyforce.cfg +++ b/tests/fullscale/poroelasticity/nofaults-2d/bodyforce.cfg @@ -17,9 +17,9 @@ features = [ # problem # ---------------------------------------------------------------------- [pylithapp.problem] -initial_dt = 10.0*year -start_time = -10.0*year -end_time = 50.0*year +initial_dt = 1.0*year +start_time = -1.0*year +end_time = 15.0*year # ---------------------------------------------------------------------- @@ -29,7 +29,7 @@ end_time = 50.0*year use_body_force = True db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability, body_force_x, body_force_y] -db_auxiliary_field.data = [2500*kg/m**3, 1000*kg/m**3, 1.0e-3*Pa*s, 0.02, 30.0*GPa, 80.0*GPa, 0.2, 10.0*GPa, 1.0e-14*m**2, 10.0*kPa/m, 0.0*Pa/m] +db_auxiliary_field.data = [2500*kg/m**3, 1000*kg/m**3, 1.0e-3*Pa*s, 0.02, 30.0*GPa, 80.0*GPa, 0.7, 10.0*GPa, 1.0e-14*m**2, 10.0*kPa/m, 0.0*Pa/m] auxiliary_subfields.body_force.basis_order = 0 @@ -73,5 +73,4 @@ label_value = 10 db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet pressure BC -x edge - # End of file diff --git a/tests/fullscale/poroelasticity/nofaults-2d/bodyforce_soln.py b/tests/fullscale/poroelasticity/nofaults-2d/bodyforce_soln.py index 3e16ab2063..01616fa719 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/bodyforce_soln.py +++ b/tests/fullscale/poroelasticity/nofaults-2d/bodyforce_soln.py @@ -22,7 +22,7 @@ p_shear_modulus = 3.0e10 p_drained_bulk_modulus = 8.0e10 p_fluid_bulk_modulus = 1.0e10 -p_biot_coefficient = 0.2 +p_biot_coefficient = 0.7 p_isotropic_permeability = 1.0e-14 @@ -30,8 +30,8 @@ p_lambda = p_drained_bulk_modulus - 2.0 / 3.0 * p_shear_modulus -xmin = -4.0e3 -xmax = +4.0e3 +x_min = -4.0e3 +x_max = +4.0e3 fx = 10.0e3 # kPa/m @@ -100,7 +100,7 @@ def displacement(self, locs): / (p_lambda + 2 * p_mu) * (1.0 - p_alpha) * fx - * ((xmax - xmin) ** 2 - (x - xmin) ** 2) + * ((x_max - x_min) ** 2 - (x - x_min) ** 2) ) disp[0, :, 0] = ux disp[0, :, 1] = 0.0 @@ -119,7 +119,7 @@ def pressure(self, locs): x = locs[:, 0] pressure = numpy.zeros((1, npts, 1), dtype=numpy.float64) - pressure[0, :, 0] = fx * (x - xmin) + pressure[0, :, 0] = fx * (x - x_min) return pressure def pressure_zero(self, locs): @@ -135,7 +135,7 @@ def trace_strain(self, locs): x = locs[:, 0] p_alpha = p_biot_coefficient - ev = -1.0 / (p_lambda + 2.0 * p_mu) * (1.0 - p_alpha) * fx * (x - xmin) + ev = -1.0 / (p_lambda + 2.0 * p_mu) * (1.0 - p_alpha) * fx * (x - x_min) trace = numpy.zeros((1, npts, 1), dtype=numpy.float64) trace[0, :, 0] = ev @@ -182,10 +182,16 @@ def biot_coefficient(self, locs): def biot_modulus(self, locs): """Compute Biot modulus field at locations.""" (npts, _) = locs.shape - p_solid_bulk_modulus = p_drained_bulk_modulus / (1.0 - p_biot_coefficient) - p_biot_modulus = 1.0 / ( - p_porosity / p_fluid_bulk_modulus - + (p_biot_coefficient - p_porosity) / p_solid_bulk_modulus + p_solid_bulk_modulus = ( + p_drained_bulk_modulus / (1.0 - p_biot_coefficient) + if p_biot_coefficient < 1.0 + else 1.0e50 + ) + p_biot_modulus = p_fluid_bulk_modulus / ( + p_porosity + + (p_biot_coefficient - p_porosity) + * p_fluid_bulk_modulus + / p_solid_bulk_modulus ) modulus = p_biot_modulus * numpy.ones((1, npts, 1), dtype=numpy.float64) return modulus @@ -212,7 +218,7 @@ def strain(self, locs): p_alpha = p_biot_coefficient strain = numpy.zeros((1, npts, self.TENSOR_SIZE), dtype=numpy.float64) - exx = -1.0 / (p_lambda + 2.0 * p_mu) * (1.0 - p_alpha) * fx * (x - xmin) + exx = -1.0 / (p_lambda + 2.0 * p_mu) * (1.0 - p_alpha) * fx * (x - x_min) strain[0, :, 0] = exx strain[0, :, 1] = 0.0 strain[0, :, 2] = 0.0 @@ -225,10 +231,10 @@ def stress(self, locs): x = locs[:, 0] p_alpha = p_biot_coefficient - sxx = -fx * (x - xmin) - syy = szz = -p_lambda / (p_lambda + 2 * p_mu) * fx * (x - xmin) - 2 * p_mu / ( + sxx = -fx * (x - x_min) + syy = szz = -p_lambda / (p_lambda + 2 * p_mu) * fx * (x - x_min) - 2 * p_mu / ( p_lambda + 2 * p_mu - ) * p_alpha * fx * (x - xmin) + ) * p_alpha * fx * (x - x_min) stress = numpy.zeros((1, npts, self.TENSOR_SIZE), dtype=numpy.float64) stress[0, :, 0] = sxx diff --git a/tests/fullscale/poroelasticity/nofaults-2d/gravity.cfg b/tests/fullscale/poroelasticity/nofaults-2d/gravity.cfg index 0eba0aef3b..2702207da6 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/gravity.cfg +++ b/tests/fullscale/poroelasticity/nofaults-2d/gravity.cfg @@ -21,18 +21,15 @@ gravity_field = spatialdata.spatialdb.GravityField gravity_field.gravity_dir = [0.0, -1.0, 0.0] [pylithapp.problem] -initial_dt = 10.0*year -start_time = -10.0*year -end_time = 30.0*year +initial_dt = 1.0*year +start_time = -1.0*year +end_time = 15.0*year # ---------------------------------------------------------------------- # materials # ---------------------------------------------------------------------- [pylithapp.problem.materials.poroelastic] -db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [2500*kg/m**3, 1000*kg/m**3, 1.0e-3*Pa*s, 0.02, 30.0*GPa, 80.0*GPa, 0.2, 10.0*GPa, 1.0e-14*m**2] - auxiliary_subfields.gravitational_acceleration.basis_order = 0 diff --git a/tests/fullscale/poroelasticity/nofaults-2d/gravity_bodyforce.cfg b/tests/fullscale/poroelasticity/nofaults-2d/gravity_bodyforce.cfg index d4c5160567..fecc69f2b7 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/gravity_bodyforce.cfg +++ b/tests/fullscale/poroelasticity/nofaults-2d/gravity_bodyforce.cfg @@ -21,10 +21,12 @@ gravity_field = spatialdata.spatialdb.GravityField gravity_field.gravity_dir = [0.0, -1.0, 0.0] [pylithapp.problem] -initial_dt = 10.0*year -start_time = -10.0*year -end_time = 50.0*year +initial_dt = 1.0*year +start_time = -1.0*year +end_time = 15.0*year +scales = pylith.scales.QuasistaticPoroelasticity +scales.displacement_scale = 1.0*m # ---------------------------------------------------------------------- # materials @@ -79,4 +81,10 @@ db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet pressure BC +y edge +# ---------------------------------------------------------------------- +# PETSc +# ---------------------------------------------------------------------- +[pylithapp.petsc] +ksp_atol = 1.0e-9 + # End of file diff --git a/tests/fullscale/poroelasticity/nofaults-2d/gravity_soln.py b/tests/fullscale/poroelasticity/nofaults-2d/gravity_soln.py index 3bcc3f5a69..5f5a0bdaf4 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/gravity_soln.py +++ b/tests/fullscale/poroelasticity/nofaults-2d/gravity_soln.py @@ -22,7 +22,7 @@ p_shear_modulus = 3.0e10 p_drained_bulk_modulus = 8.0e10 p_fluid_bulk_modulus = 1.0e10 -p_biot_coefficient = 0.2 +p_biot_coefficient = 0.7 p_isotropic_permeability = 1.0e-14 @@ -31,9 +31,9 @@ p_bulk_density = (1.0 - p_porosity) * p_solid_density + p_porosity * p_fluid_density -gacc = 9.80665 # m/s -ymax = 0.0 -ymin = -8000.0 # m +g_acc = 9.80665 # m/s +y_max = 0.0 +y_min = -8000.0 # m # ---------------------------------------------------------------------- @@ -100,8 +100,8 @@ def displacement(self, locs): -0.5 / (p_lambda + 2 * p_mu) * (p_bulk_density - p_alpha * p_fluid_density) - * gacc - * ((ymax - ymin) ** 2 - y**2) + * g_acc + * ((y_max - y_min) ** 2 - y**2) ) disp[0, :, 0] = 0.0 disp[0, :, 1] = uy @@ -120,7 +120,7 @@ def pressure(self, locs): y = locs[:, 1] pressure = numpy.zeros((1, npts, 1), dtype=numpy.float64) - pressure[0, :, 0] = p_fluid_density * gacc * (ymax - y) + pressure[0, :, 0] = p_fluid_density * g_acc * (y_max - y) return pressure def pressure_zero(self, locs): @@ -140,8 +140,8 @@ def trace_strain(self, locs): -1.0 / (p_lambda + 2.0 * p_mu) * (p_bulk_density - p_alpha * p_fluid_density) - * gacc - * (ymax - y) + * g_acc + * (y_max - y) ) trace = numpy.zeros((1, npts, 1), dtype=numpy.float64) @@ -189,10 +189,16 @@ def biot_coefficient(self, locs): def biot_modulus(self, locs): """Compute Biot modulus field at locations.""" (npts, _) = locs.shape - p_solid_bulk_modulus = p_drained_bulk_modulus / (1.0 - p_biot_coefficient) - p_biot_modulus = 1.0 / ( - p_porosity / p_fluid_bulk_modulus - + (p_biot_coefficient - p_porosity) / p_solid_bulk_modulus + p_solid_bulk_modulus = ( + p_drained_bulk_modulus / (1.0 - p_biot_coefficient) + if p_biot_coefficient < 1.0 + else 1.0e50 + ) + p_biot_modulus = p_fluid_bulk_modulus / ( + p_porosity + + (p_biot_coefficient - p_porosity) + * p_fluid_bulk_modulus + / p_solid_bulk_modulus ) modulus = p_biot_modulus * numpy.ones((1, npts, 1), dtype=numpy.float64) return modulus @@ -223,8 +229,8 @@ def strain(self, locs): -1 / (p_lambda + 2 * p_mu) * (p_bulk_density - p_alpha * p_fluid_density) - * gacc - * (ymax - y) + * g_acc + * (y_max - y) ) strain[0, :, 0] = 0.0 strain[0, :, 1] = eyy @@ -238,11 +244,11 @@ def stress(self, locs): y = locs[:, 1] p_alpha = p_biot_coefficient - syy = -p_bulk_density * gacc * (ymax - y) - sxx = szz = -p_lambda / (p_lambda + 2 * p_mu) * p_bulk_density * gacc * ( - ymax - y - ) - 2 * p_mu / (p_lambda + 2 * p_mu) * p_alpha * p_fluid_density * gacc * ( - ymax - y + syy = -p_bulk_density * g_acc * (y_max - y) + sxx = szz = -p_lambda / (p_lambda + 2 * p_mu) * p_bulk_density * g_acc * ( + y_max - y + ) - 2 * p_mu / (p_lambda + 2 * p_mu) * p_alpha * p_fluid_density * g_acc * ( + y_max - y ) stress = numpy.zeros((1, npts, self.TENSOR_SIZE), dtype=numpy.float64) diff --git a/tests/fullscale/poroelasticity/nofaults-2d/meshes.py b/tests/fullscale/poroelasticity/nofaults-2d/meshes.py index 36b0d40c06..8adddff00a 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/meshes.py +++ b/tests/fullscale/poroelasticity/nofaults-2d/meshes.py @@ -24,6 +24,7 @@ class TriGmsh(object): "bc_disp_yneg": MeshEntity(ncells=4, ncorners=2, nvertices=5), "bc_disp_ypos": MeshEntity(ncells=4, ncorners=2, nvertices=5), "bc_press_ypos": MeshEntity(ncells=4, ncorners=2, nvertices=5), + "bc_press_xneg": MeshEntity(ncells=4, ncorners=2, nvertices=5), } @@ -40,6 +41,7 @@ class QuadGmsh(object): "bc_disp_yneg": MeshEntity(ncells=4, ncorners=2, nvertices=5), "bc_disp_ypos": MeshEntity(ncells=4, ncorners=2, nvertices=5), "bc_press_ypos": MeshEntity(ncells=4, ncorners=2, nvertices=5), + "bc_press_xneg": MeshEntity(ncells=4, ncorners=2, nvertices=5), } diff --git a/tests/fullscale/poroelasticity/nofaults-2d/pylithapp.cfg b/tests/fullscale/poroelasticity/nofaults-2d/pylithapp.cfg index 90b15642dc..f8eb90404a 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/pylithapp.cfg +++ b/tests/fullscale/poroelasticity/nofaults-2d/pylithapp.cfg @@ -46,13 +46,13 @@ coordsys.space_dim = 2 # problem # ---------------------------------------------------------------------- [pylithapp.problem] -# Scales for nondimensionalization -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 1.0*km -normalizer.relaxation_time = 1.0*year -normalizer.shear_modulus = 50.0*GPa +scales = pylith.scales.QuasistaticPoroelasticity +scales.length_scale = 1.0*km +scales.displacement_scale = 10.0*m +scales.shear_modulus = 30.0*GPa +scales.viscosity = 0.001*Pa*s +scales.permeability = 1.0e-14*m**2 -[pylithapp.problem] solution = pylith.problems.SolnDispPresTracStrain defaults.quadrature_order = 2 @@ -78,7 +78,7 @@ label_value = 1 db_auxiliary_field = spatialdata.spatialdb.UniformDB db_auxiliary_field.description = Poroelastic properties db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [2500*kg/m**3, 1000*kg/m**3, 1.0e-3*Pa*s, 0.02, 30.0*GPa, 80.0*GPa, 0.2, 10.0*GPa, 1.0e-14*m**2] +db_auxiliary_field.data = [2500*kg/m**3, 1000*kg/m**3, 1.0e-3*Pa*s, 0.02, 30.0*GPa, 80.0*GPa, 0.7, 10.0*GPa, 1.0e-14*m**2] auxiliary_subfields.solid_density.basis_order = 0 auxiliary_subfields.fluid_density.basis_order = 0 @@ -101,12 +101,10 @@ auxiliary_subfields.isotropic_permeability.basis_order = 0 [pylithapp.problem.petsc_defaults] solver = True testing = True -monitors = True +monitors = False [pylithapp.petsc] -#ksp_rtol = 1.0e-12 -#ksp_atol = 1.0e-12 - -snes_max_it = 1 +ksp_atol = 1.0e-8 +snes_max_it = 3 # End of file diff --git a/tests/fullscale/poroelasticity/nofaults-2d/test_cases.ipynb b/tests/fullscale/poroelasticity/nofaults-2d/test_cases.ipynb index f96136e88f..aa10815b72 100644 --- a/tests/fullscale/poroelasticity/nofaults-2d/test_cases.ipynb +++ b/tests/fullscale/poroelasticity/nofaults-2d/test_cases.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "6ac3866e", "metadata": {}, "outputs": [], @@ -48,7 +48,7 @@ " = \\lambda \\boldsymbol{I} \\epsilon_{v} + 2 \\mu \\boldsymbol{\\epsilon} - \\alpha \\boldsymbol{I} p, \\\\\n", "\\lambda = K_{d} - \\frac{2}{3} \\mu, \\\\\n", " \\frac{1}{M} = \\frac{\\alpha-\\phi}{K_s} + \\frac{\\phi}{K_f}, \\\\\n", - " \\alpha = 1 - \\frac{K_d}{K_f}, \\\\\n", + " \\alpha = 1 - \\frac{K_d}{K_s}, \\\\\n", "\\epsilon_{v} = \\nabla \\cdot \\vec{u},\n", "\\end{gather}\n", "\n", @@ -283,8 +283,8 @@ "We consider the steady-state solution for loading from body forces,\n", "\n", "\\begin{gather}\n", - "q_x = q_y = 0 \\Rightarrow \\nabla p + \\vec{f} = 0 \\\\\n", - "p = -\\vec{f}\n", + "q_x = q_y = 0 \\Rightarrow \\nabla p - \\vec{f}_f = 0 \\\\\n", + "p = f_x x\n", "\\end{gather}\n", "\n", "Solving the elasticity equation leads to\n", @@ -293,15 +293,15 @@ "\\sigma_{xx} &= f_x x, \\\\\n", "\\sigma_{yy} &= \\sigma_{zz} = \\frac{\\lambda}{\\lambda+2\\mu} f_x x + \\frac{2\\mu}{\\lambda+2\\mu} \\alpha f_x x, \\\\\n", "\\sigma_{xy} &= 0, \\\\\n", - "\\epsilon_v &= -\\frac{1}{\\lambda + 2\\mu} \\left( 1.0 - \\alpha \\right) f_x x, \\\\\n", - "u_x(x) &= -\\frac{1}{2} \\frac{1}{\\lambda+2\\mu} \\left( 1.0 - \\alpha \\right) f_x (l^2-x^2), \\\\\n", + "\\epsilon_v &= \\frac{1}{\\lambda + 2\\mu} (1 - \\alpha) f_x x, \\\\\n", + "u_x(x) &= \\frac{1}{2} \\frac{1}{\\lambda+2\\mu} (1 - \\alpha) f_x (l^2-x^2), \\\\\n", "u_y &= 0. \\\\\n", "\\end{aligned}" ] }, { "cell_type": "code", - "execution_count": 159, + "execution_count": 36, "id": "77d2f849", "metadata": {}, "outputs": [], @@ -310,33 +310,33 @@ "x, y = sympy.symbols(\"x, y\")\n", "\n", "# Define symbolic constants\n", - "l, fx = sympy.symbols(\"l, fx\")\n", + "l, f_x = sympy.symbols(\"l, f_x\")\n", "\n", "# Material parameters\n", - "λ, μ, ϕ, α, μf, k, ρb, ρf, M = sympy.symbols(\"λ, μ, ϕ, α, μf, k, ρb, ρf, M\")\n", + "λ, μ, ϕ, α, μ_f, k, ρ_b, ρ_f, M = sympy.symbols(\"λ, μ, ϕ, α, μ_f, k, ρ_b, ρ_f, M\")\n", "\n", "# Analytical solution\n", - "ux = 0.5/(λ+2*μ) * (1.0-α) * fx * (l**2-x**2)\n", - "uy = 0*x\n", - "p = fx * x\n", + "u_x = 0.5/(λ+2*μ) * (1.0-α) * f_x * (l**2-x**2)\n", + "u_y = 0*x\n", + "p = f_x * x\n", "\n", "# Derivatives for governing equations\n", - "ux_x = ux.diff(x)\n", - "ux_y = ux.diff(y)\n", - "uy_x = uy.diff(x)\n", - "uy_y = uy.diff(y)\n", + "ux_x = u_x.diff(x)\n", + "ux_y = u_x.diff(y)\n", + "uy_x = u_y.diff(x)\n", + "uy_y = u_y.diff(y)\n", "p_x = p.diff(x)\n", "p_y = p.diff(y)\n", "grad_p = sympy.Matrix([p_x, p_y])\n", "\n", "# Body force for fluid phase\n", - "ff = sympy.Matrix([fx, 0.])\n", + "f_f = sympy.Matrix([f_x, 0.])\n", "\n", "# Body force for solid phase\n", - "fs = sympy.Matrix([fx, 0.])\n", + "f_s = sympy.Matrix([f_x, 0.])\n", "\n", "# Darcy flux; Generalized Dacy's law\n", - "q = -(k/μf)*( grad_p - ff)\n", + "q = -(k/μ_f)*( grad_p - f_f)\n", "\n", "# Strain\n", "ϵxy = (ux_y + uy_x) / 2\n", @@ -358,22 +358,22 @@ }, { "cell_type": "code", - "execution_count": 160, + "execution_count": 37, "id": "4a20b159", "metadata": {}, "outputs": [ { "data": { "text/latex": [ - "$\\displaystyle \\left[\\begin{matrix}- 1.0 fx x & 0\\\\0 & \\frac{fx x \\left(- 2.0 α μ - 1.0 λ\\right)}{1.0 λ + 2.0 μ}\\end{matrix}\\right]$" + "$\\displaystyle \\left[\\begin{matrix}- 1.0 f_{x} x & 0\\\\0 & \\frac{f_{x} x \\left(- 2.0 α μ - 1.0 λ\\right)}{1.0 λ + 2.0 μ}\\end{matrix}\\right]$" ], "text/plain": [ "Matrix([\n", - "[-1.0*fx*x, 0],\n", - "[ 0, fx*x*(-2.0*α*μ - 1.0*λ)/(1.0*λ + 2.0*μ)]])" + "[-1.0*f_x*x, 0],\n", + "[ 0, f_x*x*(-2.0*α*μ - 1.0*λ)/(1.0*λ + 2.0*μ)]])" ] }, - "execution_count": 160, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -384,20 +384,20 @@ }, { "cell_type": "code", - "execution_count": 161, + "execution_count": 38, "id": "dc9637a7", "metadata": {}, "outputs": [ { "data": { "text/latex": [ - "$\\displaystyle - \\frac{1.0 fx x \\left(1.0 - α\\right)}{λ + 2 μ}$" + "$\\displaystyle - \\frac{1.0 f_{x} x \\left(1.0 - α\\right)}{λ + 2 μ}$" ], "text/plain": [ - "-1.0*fx*x*(1.0 - α)/(λ + 2*μ)" + "-1.0*f_x*x*(1.0 - α)/(λ + 2*μ)" ] }, - "execution_count": 161, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -408,7 +408,7 @@ }, { "cell_type": "code", - "execution_count": 162, + "execution_count": 39, "id": "493ef311", "metadata": {}, "outputs": [ @@ -423,7 +423,7 @@ "[0]])" ] }, - "execution_count": 162, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -434,7 +434,7 @@ }, { "cell_type": "code", - "execution_count": 163, + "execution_count": 40, "id": "1fa48ed0", "metadata": {}, "outputs": [ @@ -449,18 +449,18 @@ "[0]])" ] }, - "execution_count": 163, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "sympy.simplify(div_σ + fs)" + "sympy.simplify(div_σ + f_s)" ] }, { "cell_type": "code", - "execution_count": 164, + "execution_count": 41, "id": "47ed0659", "metadata": {}, "outputs": [ @@ -475,13 +475,13 @@ "[0]])" ] }, - "execution_count": 164, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "grad_p - ff" + "grad_p - f_f" ] }, { diff --git a/tests/fullscale/poroelasticity/terzaghi/Makefile.am b/tests/fullscale/poroelasticity/terzaghi/Makefile.am index a6bf72f0e3..d9ac7beb94 100644 --- a/tests/fullscale/poroelasticity/terzaghi/Makefile.am +++ b/tests/fullscale/poroelasticity/terzaghi/Makefile.am @@ -13,34 +13,17 @@ TESTS = test_pylith.py dist_check_SCRIPTS = test_pylith.py dist_noinst_PYTHON = \ + generate_gmsh.py \ meshes.py \ TestTerzaghi.py \ - terzaghi_soln.py \ - terzaghi_gendb.py \ - TestTerzaghiCompaction.py \ - terzaghi_compaction_soln.py \ - terzaghi_compaction_gendb.py + terzaghi_soln.py dist_noinst_DATA = \ - geometry.jou \ - bc.jou \ - mesh_tri.jou \ - mesh_tri.exo \ - mesh_quad.jou \ - mesh_quad.exo \ - terzaghi.cfg \ + mesh_tri.msh \ + mesh_quad.msh \ + pylithapp.cfg \ terzaghi_tri.cfg \ - terzaghi_quad.cfg \ - terzaghi_compaction.cfg \ - terzaghi_compaction_tri.cfg \ - terzaghi_compaction_quad.cfg - -noinst_TMP = \ - terzaghi_bc.spatialdb \ - terzaghi_ic.spatialdb \ - terzaghi_compaction_bc.spatialdb \ - terzaghi_compaction_ic.spatialdb - + terzaghi_quad.cfg export_datadir = $(abs_builddir) diff --git a/tests/fullscale/poroelasticity/terzaghi/TestTerzaghi.py b/tests/fullscale/poroelasticity/terzaghi/TestTerzaghi.py index 7589e98ab2..9e1e63697b 100644 --- a/tests/fullscale/poroelasticity/terzaghi/TestTerzaghi.py +++ b/tests/fullscale/poroelasticity/terzaghi/TestTerzaghi.py @@ -6,7 +6,7 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= # @file tests/fullscale/poroelasticity/terzaghi/TestTerzaghi.py # @@ -17,11 +17,10 @@ import unittest -from pylith.testing.FullTestApp import (FullTestCase, Check, check_data) +from pylith.testing.FullTestApp import FullTestCase, Check import meshes import terzaghi_soln -import terzaghi_gendb # ------------------------------------------------------------------------------------------------- @@ -36,15 +35,16 @@ def setUp(self): self.checks = [ Check( mesh_entities=["domain"], - vertex_fields=["displacement"], + vertex_fields=["displacement", "trace_strain"], + final_time_only=True, defaults=defaults, - tolerance=0.5, ), Check( mesh_entities=["domain"], vertex_fields=["pressure"], + final_time_only=True, defaults=defaults, - scale=1.0e+6, + tolerance=0.02, ), Check( mesh_entities=["poroelastic"], @@ -63,39 +63,21 @@ def setUp(self): defaults=defaults, ), Check( - mesh_entities=["poroelastic"], - vertex_fields = ["displacement"], - defaults=defaults, - tolerance=0.5, - ), - Check( - mesh_entities=["poroelastic"], - vertex_fields = ["pressure"], - defaults=defaults, - scale=1.0e+6, - ), - Check( - mesh_entities=["x_neg", "x_pos", "y_pos_dir", "y_neg", "y_pos_neu"], + mesh_entities=["bc_xneg", "bc_xpos", "bc_ypos_pressure", "bc_yneg"], filename="output/{name}-{mesh_entity}_info.h5", vertex_fields=["initial_amplitude"], defaults=defaults, ), Check( - mesh_entities=["x_neg", "x_pos", "y_pos_dir", "y_neg", "y_pos_neu"], - vertex_fields=["displacement"], - defaults=defaults, - tolerance=0.5, - ), - Check( - mesh_entities=["x_neg", "x_pos", "y_pos_dir", "y_neg", "y_pos_neu"], - vertex_fields=["pressure"], + mesh_entities=["bc_ypos_traction"], + filename="output/{name}-{mesh_entity}_info.h5", + cell_fields=["initial_amplitude"], defaults=defaults, - scale=1.0e+6, ), ] def run_pylith(self, testName, args): - FullTestCase.run_pylith(self, testName, args, terzaghi_gendb.GenerateDB) + FullTestCase.run_pylith(self, testName, args) # ------------------------------------------------------------------------------------------------- @@ -106,7 +88,7 @@ def setUp(self): self.mesh = meshes.Quad() super().setUp() - TestCase.run_pylith(self, self.name, ["terzaghi.cfg", "terzaghi_quad.cfg"]) + TestCase.run_pylith(self, self.name, ["terzaghi_quad.cfg"]) # ------------------------------------------------------------------------------------------------- @@ -117,7 +99,7 @@ def setUp(self): self.mesh = meshes.Tri() super().setUp() - TestCase.run_pylith(self, self.name, ["terzaghi.cfg", "terzaghi_tri.cfg"]) + TestCase.run_pylith(self, self.name, ["terzaghi_tri.cfg"]) # ------------------------------------------------------------------------------------------------- @@ -129,7 +111,7 @@ def test_cases(): # ------------------------------------------------------------------------------------------------- -if __name__ == '__main__': +if __name__ == "__main__": FullTestCase.parse_args() suite = unittest.TestSuite() diff --git a/tests/fullscale/poroelasticity/terzaghi/TestTerzaghiCompaction.py b/tests/fullscale/poroelasticity/terzaghi/TestTerzaghiCompaction.py deleted file mode 100644 index 96341aabf7..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/TestTerzaghiCompaction.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env nemesis -# ================================================================================================= -# This code is part of PyLith, developed through the Computational Infrastructure -# for Geodynamics (https://github.com/geodynamics/pylith). -# -# Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. -# All rights reserved. -# -# See https://mit-license.org/ and LICENSE.md and for license information. -# ================================================================================================= -# @file tests/fullscale/poroelasticity/terzaghi_compaction/TestTerzaghiCompaction.py -# -# @brief Test suite for testing pylith with Terzaghi's problem, involving compaction (change of porosity). - -import unittest - -from pylith.testing.FullTestApp import (FullTestCase, Check, check_data) - -import meshes -import terzaghi_compaction_soln -import terzaghi_compaction_gendb - -# We do not include trace_strain in the solution fields, because of the -# poor convergence of the series solution. -SOLUTION_FIELDS = ["displacement", "pressure"] -SOLUTION_TOLERANCE = 0.2 - -# ------------------------------------------------------------------------------------------------- -class TestCase(FullTestCase): - - def setUp(self): - defaults = { - "filename": "output/{name}-{mesh_entity}.h5", - "exact_soln": terzaghi_compaction_soln.AnalyticalSoln(), - "mesh": self.mesh, - } - self.checks = [ - Check( - mesh_entities=["domain"], - vertex_fields=SOLUTION_FIELDS, - defaults=defaults, - tolerance=SOLUTION_TOLERANCE, - ), - Check( - mesh_entities=["poroelastic"], - filename="output/{name}-{mesh_entity}_info.h5", - cell_fields=[ - "biot_coefficient", - "biot_modulus", - "drained_bulk_modulus", - "fluid_density", - "fluid_viscosity", - "isotropic_permeability", - "porosity", - "shear_modulus", - "solid_density", - ], - defaults=defaults, - ), - Check( - mesh_entities=["poroelastic"], - vertex_fields = SOLUTION_FIELDS, - defaults=defaults, - tolerance=SOLUTION_TOLERANCE, - ), - Check( - mesh_entities=["x_neg", "x_pos", "y_pos_dir", "y_neg", "y_pos_neu"], - filename="output/{name}-{mesh_entity}_info.h5", - vertex_fields=["initial_amplitude"], - defaults=defaults, - ), - Check( - mesh_entities=["x_neg", "x_pos", "y_pos_dir", "y_neg", "y_pos_neu"], - vertex_fields=SOLUTION_FIELDS, - defaults=defaults, - tolerance=SOLUTION_TOLERANCE, - ), - ] - - def run_pylith(self, testName, args): - FullTestCase.run_pylith(self, testName, args, terzaghi_compaction_gendb.GenerateDB) - - -# ------------------------------------------------------------------------------------------------- -class TestQuad(TestCase): - - def setUp(self): - self.name = "terzaghi_compaction_quad" - self.mesh = meshes.Quad() - super().setUp() - - TestCase.run_pylith(self, self.name, ["terzaghi_compaction.cfg", "terzaghi_compaction_quad.cfg"]) - - -# ------------------------------------------------------------------------------------------------- -class TestTri(TestCase): - - def setUp(self): - self.name = "terzaghi_compaction_tri" - self.mesh = meshes.Tri() - super().setUp() - - TestCase.run_pylith(self, self.name, ["terzaghi_compaction.cfg", "terzaghi_compaction_tri.cfg"]) - - -# ------------------------------------------------------------------------------------------------- -def test_cases(): - return [ - TestQuad, - TestTri, - ] - - -# ------------------------------------------------------------------------------------------------- -if __name__ == '__main__': - FullTestCase.parse_args() - - suite = unittest.TestSuite() - for test in test_cases(): - suite.addTest(unittest.makeSuite(test)) - unittest.TextTestRunner(verbosity=2).run(suite) - - -# End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/bc.jou b/tests/fullscale/poroelasticity/terzaghi/bc.jou deleted file mode 100644 index 711ca65c4e..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/bc.jou +++ /dev/null @@ -1,34 +0,0 @@ -# ---------------------------------------------------------------------- -# Create nodeset for -x edge -# ---------------------------------------------------------------------- -group "x_neg" add node in curve 1 -nodeset 1 group x_neg -nodeset 1 name "x_neg" - -# ---------------------------------------------------------------------- -# Create nodeset for -y edge -# ---------------------------------------------------------------------- -group "y_neg" add node in curve 4 -nodeset 2 group y_neg -nodeset 2 name "y_neg" - -# ---------------------------------------------------------------------- -# Create nodeset for +x edge -# ---------------------------------------------------------------------- -group "x_pos" add node in curve 3 -nodeset 3 group x_pos -nodeset 3 name "x_pos" - -# ---------------------------------------------------------------------- -# Create nodeset for +y edge Dirichlet -# ---------------------------------------------------------------------- -group "y_pos_dir" add node in curve 2 -nodeset 4 group y_pos_dir -nodeset 4 name "y_pos_dir" - -# ---------------------------------------------------------------------- -# Create nodeset for +y edge Neumann -# ---------------------------------------------------------------------- -group "y_pos_neu" add node in curve 2 -nodeset 5 group y_pos_neu -nodeset 5 name "y_pos_neu" diff --git a/tests/fullscale/poroelasticity/terzaghi/generate_gmsh.py b/tests/fullscale/poroelasticity/terzaghi/generate_gmsh.py new file mode 100755 index 0000000000..0776ca9127 --- /dev/null +++ b/tests/fullscale/poroelasticity/terzaghi/generate_gmsh.py @@ -0,0 +1,112 @@ +#!/usr/bin/env nemesis + +import gmsh +from pylith.meshio.gmsh_utils import BoundaryGroup, MaterialGroup, GenerateMesh + + +class App(GenerateMesh): + """ + Block is DOMAIN_X by DOMAIN_Y with discretization size DX. + + p4------------p3 + | | + | | + | | + | | + | | + p1------------p2 + """ + + DOMAIN_Y = 10.0e+3 + DX = 0.2e+3 + DOMAIN_X = 2*DX + + def __init__(self): + self.cell_choices = { + "required": True, + "choices": ["tri", "quad"], + } + self.filename = "mesh.msh" + + def create_geometry(self): + """Create geometry.""" + lx = self.DOMAIN_X + ly = self.DOMAIN_Y + x0 = 0.0 + y0 = 0.0 + + p1 = gmsh.model.geo.add_point(x0, y0, 0.0) + p2 = gmsh.model.geo.add_point(x0 + lx, y0, 0.0) + p3 = gmsh.model.geo.add_point(x0 + lx, y0 + ly, 0.0) + p4 = gmsh.model.geo.add_point(x0, y0 + ly, 0.0) + + self.l_yneg = gmsh.model.geo.add_line(p1, p2) + self.l_xpos = gmsh.model.geo.add_line(p2, p3) + self.l_ypos = gmsh.model.geo.add_line(p3, p4) + self.l_xneg = gmsh.model.geo.add_line(p4, p1) + + c1 = gmsh.model.geo.add_curve_loop( + [self.l_yneg, self.l_xpos, self.l_ypos, self.l_xneg] + ) + self.s_domain = gmsh.model.geo.add_plane_surface([c1]) + + gmsh.model.geo.synchronize() + + def mark(self): + """Mark geometry for materials, boundary conditions, faults, etc.""" + materials = (MaterialGroup(tag=1, entities=[self.s_domain]),) + for material in materials: + material.create_physical_group() + + face_groups = ( + BoundaryGroup( + name="boundary_xneg", + tag=10, + dim=1, + entities=[self.l_xneg], + ), + BoundaryGroup( + name="boundary_xpos", + tag=11, + dim=1, + entities=[self.l_xpos], + ), + BoundaryGroup( + name="boundary_yneg", + tag=12, + dim=1, + entities=[self.l_yneg], + ), + BoundaryGroup( + name="boundary_ypos", + tag=13, + dim=1, + entities=[self.l_ypos], + ), + BoundaryGroup( + name="boundary_ypos_copy", + tag=14, + dim=1, + entities=[self.l_ypos], + ), + ) + for group in face_groups: + group.create_physical_group() + + def generate_mesh(self, cell): + """Generate the mesh. Should also include optimizing the mesh quality.""" + gmsh.option.setNumber("Mesh.MeshSizeMin", self.DX) + gmsh.option.setNumber("Mesh.MeshSizeMax", self.DX) + if cell == "quad": + # Generate a tri mesh and then recombine cells to form quadrilaterals. + # We use the Frontal-Delaunay for Quads algorithm. + gmsh.option.setNumber("Mesh.Algorithm", 8) + gmsh.model.mesh.generate(2) + gmsh.model.mesh.recombine() + else: + gmsh.model.mesh.generate(2) + gmsh.model.mesh.optimize("Laplace2D") + + +if __name__ == "__main__": + App().main() diff --git a/tests/fullscale/poroelasticity/terzaghi/geometry.jou b/tests/fullscale/poroelasticity/terzaghi/geometry.jou deleted file mode 100644 index 00de7adfdb..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/geometry.jou +++ /dev/null @@ -1,14 +0,0 @@ -# ---------------------------------------------------------------------- -# Create surface using vertices -# ---------------------------------------------------------------------- - -# Block is 10m x 10m -# 0 m <= x <= 10 m -# 0 m <= y <= 10 m -reset -create vertex 0.0 0.0 0.0 -create vertex 0.0 +10.0 0.0 -create vertex +10.0 +10.0 0.0 -create vertex +10.0 0.0 0.0 -create surface vertex 1 2 3 4 -delete vertex all diff --git a/tests/fullscale/poroelasticity/terzaghi/mesh_quad.exo b/tests/fullscale/poroelasticity/terzaghi/mesh_quad.exo deleted file mode 100644 index 52a1c35f9c..0000000000 Binary files a/tests/fullscale/poroelasticity/terzaghi/mesh_quad.exo and /dev/null differ diff --git a/tests/fullscale/poroelasticity/terzaghi/mesh_quad.jou b/tests/fullscale/poroelasticity/terzaghi/mesh_quad.jou deleted file mode 100644 index 812826154e..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/mesh_quad.jou +++ /dev/null @@ -1,34 +0,0 @@ -# ---------------------------------------------------------------------- -# Generate geometry -# ---------------------------------------------------------------------- -playback 'geometry.jou' - -# ---------------------------------------------------------------------- -# Set discretization size -# ---------------------------------------------------------------------- -surface all size 0.5 - -# ---------------------------------------------------------------------- -# Generate the mesh -# ---------------------------------------------------------------------- -surface all scheme submap -mesh surface all - -# ---------------------------------------------------------------------- -# Create blocks for materials -# ---------------------------------------------------------------------- -block 1 surface 1 -block 1 name "poroelastic" -block 1 element type quad - -# ---------------------------------------------------------------------- -# Mark entities for boundary conditions, etc. -# ---------------------------------------------------------------------- -playback 'bc.jou' - -# ---------------------------------------------------------------------- -# Export exodus file -# ---------------------------------------------------------------------- -export mesh "mesh_quad.exo" dimension 2 overwrite - - diff --git a/tests/fullscale/poroelasticity/terzaghi/mesh_quad.msh b/tests/fullscale/poroelasticity/terzaghi/mesh_quad.msh new file mode 100644 index 0000000000..238db9cf25 Binary files /dev/null and b/tests/fullscale/poroelasticity/terzaghi/mesh_quad.msh differ diff --git a/tests/fullscale/poroelasticity/terzaghi/mesh_tri.exo b/tests/fullscale/poroelasticity/terzaghi/mesh_tri.exo deleted file mode 100644 index 8d0add654c..0000000000 Binary files a/tests/fullscale/poroelasticity/terzaghi/mesh_tri.exo and /dev/null differ diff --git a/tests/fullscale/poroelasticity/terzaghi/mesh_tri.jou b/tests/fullscale/poroelasticity/terzaghi/mesh_tri.jou deleted file mode 100644 index fa38f0cb4f..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/mesh_tri.jou +++ /dev/null @@ -1,34 +0,0 @@ -# ---------------------------------------------------------------------- -# Generate geometry -# ---------------------------------------------------------------------- -playback 'geometry.jou' - -# ---------------------------------------------------------------------- -# Set discretization size -# ---------------------------------------------------------------------- -surface all size 0.5 - -# ---------------------------------------------------------------------- -# Generate the mesh -# ---------------------------------------------------------------------- -surface all scheme trimesh -mesh surface all - -# ---------------------------------------------------------------------- -# Create blocks for materials -# ---------------------------------------------------------------------- -block 1 surface 1 -block 1 name "poroelastic" -block 1 element type tri - -# ---------------------------------------------------------------------- -# Mark entities for boundary conditions, etc. -# ---------------------------------------------------------------------- -playback 'bc.jou' - -# ---------------------------------------------------------------------- -# Export exodus file -# ---------------------------------------------------------------------- -export mesh "mesh_tri.exo" dimension 2 overwrite - - diff --git a/tests/fullscale/poroelasticity/terzaghi/mesh_tri.msh b/tests/fullscale/poroelasticity/terzaghi/mesh_tri.msh new file mode 100644 index 0000000000..43268e50d0 Binary files /dev/null and b/tests/fullscale/poroelasticity/terzaghi/mesh_tri.msh differ diff --git a/tests/fullscale/poroelasticity/terzaghi/meshes.py b/tests/fullscale/poroelasticity/terzaghi/meshes.py index 95b4e0c70d..12169166de 100644 --- a/tests/fullscale/poroelasticity/terzaghi/meshes.py +++ b/tests/fullscale/poroelasticity/terzaghi/meshes.py @@ -5,48 +5,41 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= -# @file tests/fullscale/poroelasticty/terzaghi/meshes.py -# -# @brief Mesh information for test cases. from pylith.testing.FullTestApp import MeshEntity class Tri(object): - """Mesh information for tri mesh. - """ - ENTITIES = { - "domain": MeshEntity(ncells=902, ncorners=3, nvertices=492), + """Mesh information for tri mesh.""" + ENTITIES = { + "domain": MeshEntity(ncells=206, ncorners=3, nvertices=156), # Materials - "poroelastic": MeshEntity(ncells=902, ncorners=3, nvertices=492), - + "poroelastic": MeshEntity(ncells=206, ncorners=3, nvertices=156), # Boundaries - "x_neg": MeshEntity(ncells=20, ncorners=2, nvertices=21), - "x_pos": MeshEntity(ncells=20, ncorners=2, nvertices=21), - "y_neg": MeshEntity(ncells=20, ncorners=2, nvertices=21), - "y_pos_dir": MeshEntity(ncells=20, ncorners=2, nvertices=21), - "y_pos_neu": MeshEntity(ncells=20, ncorners=2, nvertices=21), + "bc_xneg": MeshEntity(ncells=50, ncorners=2, nvertices=51), + "bc_xpos": MeshEntity(ncells=50, ncorners=2, nvertices=51), + "bc_yneg": MeshEntity(ncells=2, ncorners=2, nvertices=3), + "bc_ypos_pressure": MeshEntity(ncells=2, ncorners=2, nvertices=3), + "bc_ypos_traction": MeshEntity(ncells=2, ncorners=2, nvertices=3), } class Quad(object): - """Mesh information for quad mesh. - """ - ENTITIES = { - "domain": MeshEntity(ncells=400, ncorners=4, nvertices=441), + """Mesh information for quad mesh.""" + ENTITIES = { + "domain": MeshEntity(ncells=100, ncorners=4, nvertices=153), # Materials - "poroelastic": MeshEntity(ncells=400, ncorners=4, nvertices=441), - + "poroelastic": MeshEntity(ncells=100, ncorners=4, nvertices=153), # Boundaries - "x_neg": MeshEntity(ncells=20, ncorners=2, nvertices=21), - "x_pos": MeshEntity(ncells=20, ncorners=2, nvertices=21), - "y_neg": MeshEntity(ncells=20, ncorners=2, nvertices=21), - "y_pos_dir": MeshEntity(ncells=20, ncorners=2, nvertices=21), - "y_pos_neu": MeshEntity(ncells=20, ncorners=2, nvertices=21), + "bc_xneg": MeshEntity(ncells=50, ncorners=2, nvertices=51), + "bc_xpos": MeshEntity(ncells=50, ncorners=2, nvertices=51), + "bc_yneg": MeshEntity(ncells=2, ncorners=2, nvertices=3), + "bc_ypos_pressure": MeshEntity(ncells=2, ncorners=2, nvertices=3), + "bc_ypos_traction": MeshEntity(ncells=2, ncorners=2, nvertices=3), } diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi.cfg b/tests/fullscale/poroelasticity/terzaghi/pylithapp.cfg similarity index 68% rename from tests/fullscale/poroelasticity/terzaghi/terzaghi.cfg rename to tests/fullscale/poroelasticity/terzaghi/pylithapp.cfg index ec3f97c70b..f8e8d6ca48 100644 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi.cfg +++ b/tests/fullscale/poroelasticity/terzaghi/pylithapp.cfg @@ -1,5 +1,5 @@ [pylithapp.metadata] -description = A column of porous media resting on a rigid, impermeable base (y-) is compressed by a uniform force, applied at the surface (y+). +description = A column of porous media resting on a rigid, impermeable base (-y) is compressed by a uniform traction applied at the surface (+y). authors = [Robert Walker] keywords = [full-scale test, 2D, poroelasticity, Terzaghi] version = 1.0.0 @@ -8,7 +8,7 @@ pylith_version = [>=3.0, <6.0] features = [ Quasistatic problem, pylith.materials.Poroelasticity, - pylith.meshio.MeshIOCubit, + pylith.meshio.MeshIOPetsc, pylith.problems.TimeDependent, pylith.problems.SolnDispPresTracStrain, pylith.problems.InitialConditionDomain, @@ -29,28 +29,12 @@ command = mpiexec -np ${nodes} #timedependent = 1 #solution = 1 #petsc = 1 -#meshio = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#faultcohesivekin = 1 - -[pylithapp.journal.debug] -#timedependent = 1 -#solution = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#constraintspatialdb = 1 -#faultcohesivekin = 1 -#integratorinterface = 1 -#kinsrcstep = 1 -#outputphysics = 1 -#outputsolndomain = 1 # ---------------------------------------------------------------------- # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator] -reader = pylith.meshio.MeshIOCubit +reader = pylith.meshio.MeshIOPetsc [pylithapp.mesh_generator.reader] # filename = mesh_CELL.exo @@ -69,14 +53,15 @@ solution = pylith.problems.SolnDispPresTracStrain [pylithapp.timedependent] start_time = 0.0*s +initial_dt = 5.0e+4*s +end_time = 100.0e+4*s -initial_dt = 0.0028666667*s -end_time = 0.0057333334*s - -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 1.0*m -normalizer.relaxation_time = 1.0*s -normalizer.shear_modulus = 1.0*m**-1*kg*s**-2 +scales = pylith.scales.QuasistaticPoroelasticity +scales.displacement_scale = 1.0*mm +scales.length_scale = 10.0*km +scales.shear_modulus = 10.0*GPa +scales.viscosity = 0.001*Pa*s +scales.permeability = 1.0e-13*m**2 [pylithapp.problem.solution.subfields] @@ -91,22 +76,19 @@ solution_observers = [domain] # materials # ---------------------------------------------------------------------- [pylithapp.problem] -# Create an array of one material materials = [poroelastic] materials.poroelastic = pylith.materials.Poroelasticity [pylithapp.problem.materials.poroelastic] label_value = 1 -# We will use uniform material properties, so we use the UniformDB -# spatial database. db_auxiliary_field = spatialdata.spatialdb.UniformDB db_auxiliary_field.description = Poroelastic properties db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 1.0*Pa*s, 0.1, 3.0*Pa, 4.0*Pa, 0.6, 8.0*Pa, 1.5*m**2] +db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 0.001*Pa*s, 0.1, 30.0*GPa, 40.0*GPa, 0.6, 80.0*GPa, 1.5e-13*m**2] -observers.observer.data_fields = [displacement,pressure,trace_strain] +observers.observer.data_fields = [displacement, pressure, trace_strain] auxiliary_subfields.body_force.basis_order = 0 auxiliary_subfields.solid_density.basis_order = 0 @@ -125,77 +107,69 @@ auxiliary_subfields.biot_coefficient.basis_order = 0 auxiliary_subfields.biot_modulus.basis_order = 0 auxiliary_subfields.isotropic_permeability.basis_order = 0 -# ---------------------------------------------------------------------- -# initial conditions -# ---------------------------------------------------------------------- -[pylithapp.problem] -ic = [domain] - -ic.domain.db = spatialdata.spatialdb.SimpleGridDB -ic.domain.db.description = Initial conditions for domain -ic.domain.db.filename = terzaghi_ic.spatialdb -ic.domain.db.query_type = linear - # ---------------------------------------------------------------------- # boundary conditions # ---------------------------------------------------------------------- [pylithapp.problem] -bc = [x_neg,x_pos,y_pos_neu,y_pos_dir,y_neg] +bc = [bc_xneg, bc_xpos, bc_ypos_traction, bc_ypos_pressure, bc_yneg] + +bc.bc_xpos = pylith.bc.DirichletTimeDependent +bc.bc_xneg = pylith.bc.DirichletTimeDependent +bc.bc_ypos_traction = pylith.bc.NeumannTimeDependent +bc.bc_ypos_pressure = pylith.bc.DirichletTimeDependent +bc.bc_yneg = pylith.bc.DirichletTimeDependent -bc.x_pos = pylith.bc.DirichletTimeDependent -bc.x_neg = pylith.bc.DirichletTimeDependent -bc.y_pos_neu = pylith.bc.NeumannTimeDependent -bc.y_pos_dir = pylith.bc.DirichletTimeDependent -bc.y_neg = pylith.bc.DirichletTimeDependent # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_pos] -# Set Ux=+2.0*m on the +x boundary. -constrained_dof = [0] -label = x_pos +[pylithapp.problem.bc.bc_xpos] +label = boundary_xpos +label_value = 11 field = displacement -# The spatial database must contain both components even though we do -# not constrain the y component. + +constrained_dof = [0] db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on +x boundary # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_neg] -constrained_dof = [0] -label = x_neg +[pylithapp.problem.bc.bc_xneg] +label = boundary_xneg +label_value = 10 field = displacement + +constrained_dof = [0] db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on -x boundary # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_neg] -constrained_dof = [0,1] -label = y_neg +[pylithapp.problem.bc.bc_yneg] +label = boundary_yneg +label_value = 12 field = displacement + +constrained_dof = [0,1] db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC on -y boundary # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_pos_neu] - -label = y_pos_neu +[pylithapp.problem.bc.bc_ypos_traction] +label = boundary_ypos +label_value = 13 field = displacement -scale_name = pressure -use_initial = True +scale_name = stress + db_auxiliary_field = spatialdata.spatialdb.UniformDB db_auxiliary_field.description = Neumann BC +y edge - db_auxiliary_field.values = [initial_amplitude_tangential, initial_amplitude_normal] -db_auxiliary_field.data = [0.0*Pa, -1.0*Pa] +db_auxiliary_field.data = [0.0*Pa, -10.0*kPa] -auxiliary_subfields.initial_amplitude.basis_order = 1 +auxiliary_subfields.initial_amplitude.basis_order = 0 # ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_pos_dir] -constrained_dof = [0] -label = y_pos_dir +[pylithapp.problem.bc.bc_ypos_pressure] +label = boundary_ypos_copy +label_value = 14 field = pressure -#use_initial = True -#use_time_history = True + +constrained_dof = [0] db_auxiliary_field = pylith.bc.ZeroDB db_auxiliary_field.description = Dirichlet BC for pressure on +y edge @@ -207,6 +181,7 @@ solver = True testing = True monitors = False initial_guess = False +impulse_ts = True # End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction.cfg b/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction.cfg deleted file mode 100644 index c5d96be467..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction.cfg +++ /dev/null @@ -1,219 +0,0 @@ -[pylithapp.metadata] -description = A column of porous media resting on a rigid, impermeable base (y-) is compressed by a uniform force, applied at the surface (y+). -authors = [Robert Walker] -keywords = [full-scale test, 2D, poroelasticity, Terzaghi, compaction] -version = 1.0.0 -pylith_version = [>=3.0, <6.0] - -features = [ - Quasistatic problem, - pylith.materials.Poroelasticity, - pylith.meshio.MeshIOCubit, - pylith.problems.TimeDependent, - pylith.problems.SolnDispPresTracStrain, - pylith.problems.InitialConditionDomain, - pylith.bc.DirichletTimeDependent, - pylith.bc.NeumannTimeDependent, - pylith.meshio.DataWriterHDF5, - spatialdata.spatialdb.SimpleGridDB, - spatialdata.spatialdb.UniformDB - ] - -[pylithapp.launcher] # WARNING: THIS IS NOT PORTABLE -command = mpiexec -np ${nodes} - -# ---------------------------------------------------------------------- -# journal -# ---------------------------------------------------------------------- -[pylithapp.journal.info] -#timedependent = 1 -#solution = 1 -#petsc = 1 -#meshio = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#faultcohesivekin = 1 - -[pylithapp.journal.debug] -#timedependent = 1 -#solution = 1 -#isotropiclinearelasticity = 1 -#dirichlettimedependent = 1 -#constraintspatialdb = 1 -#faultcohesivekin = 1 -#integratorinterface = 1 -#kinsrcstep = 1 -#outputphysics = 1 -#outputsolndomain = 1 - -# ---------------------------------------------------------------------- -# mesh_generator -# ---------------------------------------------------------------------- -[pylithapp.mesh_generator] -reader = pylith.meshio.MeshIOCubit - -[pylithapp.mesh_generator.reader] -# filename = mesh_CELL.exo -coordsys.space_dim = 2 - -# ---------------------------------------------------------------------- -# problem -# ---------------------------------------------------------------------- -[pylithapp.problem] -defaults.quadrature_order = 2 - -# Use nonlinear solver to ensure residual and Jacobian are consistent. -solver = nonlinear -solution = pylith.problems.SolnDispPresTracStrainVelPdotTdot - -[pylithapp.timedependent] -start_time = 0.0*s -initial_dt = 0.0028666667*s -end_time = 0.0057333334*s - -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 1.0*m -normalizer.relaxation_time = 0.01*s -normalizer.shear_modulus = 1.0*m**-1*kg*s**-2 - -[pylithapp.problem.solution.subfields] -displacement.basis_order = 2 -pressure.basis_order = 1 -trace_strain.basis_order = 1 -velocity.basis_order = 2 -pressure_t.basis_order = 1 -trace_strain_t.basis_order = 1 - -[pylithapp.problem] -solution_observers = [domain] - -# ---------------------------------------------------------------------- -# materials -# ---------------------------------------------------------------------- -[pylithapp.problem] -# Create an array of one material -materials = [poroelastic] -materials.poroelastic = pylith.materials.Poroelasticity - -[pylithapp.problem.materials] -poroelastic.bulk_rheology = pylith.materials.IsotropicLinearPoroelasticity -poroelastic.use_state_variables = True - -[pylithapp.problem.materials.poroelastic] -label_value = 1 - -# We will use uniform material properties, so we use the UniformDB -# spatial database. -db_auxiliary_field = spatialdata.spatialdb.UniformDB -db_auxiliary_field.description = Poroelastic properties -db_auxiliary_field.values = [solid_density, fluid_density, fluid_viscosity, porosity, shear_modulus, drained_bulk_modulus, biot_coefficient, fluid_bulk_modulus, isotropic_permeability] -db_auxiliary_field.data = [ 2500*kg/m**3, 1000*kg/m**3, 1.0*Pa*s, 0.1, 3.0*Pa, 4.0*Pa, 0.6, 8.0*Pa, 1.5*m**2] - - -observers.observer.data_fields = [displacement,pressure,trace_strain,velocity,pressure_t,trace_strain_t] - -auxiliary_subfields.body_force.basis_order = 0 -auxiliary_subfields.solid_density.basis_order = 0 -auxiliary_subfields.fluid_density.basis_order = 0 -auxiliary_subfields.fluid_viscosity.basis_order = 0 -auxiliary_subfields.gravitational_acceleration.basis_order = 0 -auxiliary_subfields.porosity.basis_order = 0 -derived_subfields.cauchy_strain.basis_order = 1 -derived_subfields.cauchy_stress.basis_order = 1 - -[pylithapp.problem.materials.poroelastic.bulk_rheology] - -auxiliary_subfields.drained_bulk_modulus.basis_order = 0 -auxiliary_subfields.shear_modulus.basis_order = 0 -auxiliary_subfields.biot_coefficient.basis_order = 0 -auxiliary_subfields.biot_modulus.basis_order = 0 -auxiliary_subfields.isotropic_permeability.basis_order = 0 - -# ---------------------------------------------------------------------- -# initial conditions -# ---------------------------------------------------------------------- -[pylithapp.problem] -ic = [domain] - -ic.domain.db = spatialdata.spatialdb.SimpleGridDB -ic.domain.db.description = Initial conditions for domain -ic.domain.db.filename = terzaghi_compaction_ic.spatialdb -ic.domain.db.query_type = linear - -# ---------------------------------------------------------------------- -# boundary conditions -# ---------------------------------------------------------------------- -[pylithapp.problem] -bc = [x_neg,x_pos,y_pos_neu,y_pos_dir,y_neg] - -bc.x_pos = pylith.bc.DirichletTimeDependent -bc.x_neg = pylith.bc.DirichletTimeDependent -bc.y_pos_neu = pylith.bc.NeumannTimeDependent -bc.y_pos_dir = pylith.bc.DirichletTimeDependent -bc.y_neg = pylith.bc.DirichletTimeDependent -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_pos] -# Set Ux=+2.0*m on the +x boundary. -constrained_dof = [0] -label = x_pos -field = displacement -# The spatial database must contain both components even though we do -# not constrain the y component. -db_auxiliary_field = pylith.bc.ZeroDB -db_auxiliary_field.description = Dirichlet BC on +x boundary - -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.x_neg] -constrained_dof = [0] -label = x_neg -field = displacement -db_auxiliary_field = pylith.bc.ZeroDB -db_auxiliary_field.description = Dirichlet BC on -x boundary - -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_neg] -constrained_dof = [0,1] -label = y_neg -field = displacement -db_auxiliary_field = pylith.bc.ZeroDB -db_auxiliary_field.description = Dirichlet BC on -y boundary - -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_pos_neu] - -label = y_pos_neu -field = displacement -scale_name = pressure -use_initial = True -db_auxiliary_field = spatialdata.spatialdb.UniformDB -db_auxiliary_field.description = Neumann BC +y edge - -db_auxiliary_field.values = [initial_amplitude_tangential, initial_amplitude_normal] -db_auxiliary_field.data = [0.0*Pa, -1.0*Pa] - -auxiliary_subfields.initial_amplitude.basis_order = 1 - -# ------------------------------------------------------------------------------ -[pylithapp.problem.bc.y_pos_dir] -constrained_dof = [0] -label = y_pos_dir -field = pressure -#use_initial = True -#use_time_history = True -db_auxiliary_field = pylith.bc.ZeroDB -db_auxiliary_field.description = Dirichlet BC for pressure on +y edge - -# ---------------------------------------------------------------------- -# PETSc -# ---------------------------------------------------------------------- -[pylithapp.problem.petsc_defaults] -solver = True -testing = True -monitors = False - -[pylithapp.petsc] -ksp_max_it = 200 -ksp_gmres_restart = 50 - - -# End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_gendb.py b/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_gendb.py deleted file mode 100755 index af2c6b3e83..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_gendb.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env nemesis -# ================================================================================================= -# This code is part of PyLith, developed through the Computational Infrastructure -# for Geodynamics (https://github.com/geodynamics/pylith). -# -# Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. -# All rights reserved. -# -# See https://mit-license.org/ and LICENSE.md and for license information. -# ================================================================================================= -# @file tests/fullscale/poroelasticity/terzaghi_compaction/terzaghi_compaction_gendb.py -# -# @brief Python script to generate spatial database with displacement -# boundary conditions for the terzaghi test, with updating porosity (compaction). - -import numpy - - -class GenerateDB(object): - """Python object to generate spatial database with initial conditions - for the terzaghi poroelastic test. - """ - - def run(self): - """Generate the database. - """ - # Domain - x1 = numpy.arange(-1.0, 11.01, 1.0) - y1 = numpy.arange(-1.0, 11.01, 1.0) - x, y = numpy.meshgrid(x1, y1) - - xy = numpy.zeros((len(x1) * len(y1), 2), dtype=numpy.float64) - xy[:, 0] = x.ravel() - xy[:, 1] = y.ravel() - - from terzaghi_compaction_soln import AnalyticalSoln - soln = AnalyticalSoln() - disp = soln.initial_displacement(xy) - pres = soln.initial_pressure(xy) - trace_strain = soln.initial_trace_strain(xy) - vel = soln.zero_array_dim(xy) - pres_t = soln.zero_array(xy) - trace_strain_t = soln.zero_array(xy) - - from spatialdata.geocoords.CSCart import CSCart - cs = CSCart() - cs.inventory.spaceDim = 2 - cs._configure() - data = { - 'x': x1, - 'y': y1, - 'points': xy, - 'coordsys': cs, - 'data_dim': 2, - 'values': [{'name': "displacement_x", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 0])}, - {'name': "displacement_y", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 1])}, - {'name': "pressure", - 'units': "Pa", - 'data': numpy.ravel(pres[0, :])}, - {'name': "trace_strain", - 'units': "none", - 'data': numpy.ravel(trace_strain[0, :])}, - {'name': "velocity_x", - 'units': "m/s", - 'data': numpy.ravel(vel[0, :, 0])}, - {'name': "velocity_y", - 'units': "m/s", - 'data': numpy.ravel(vel[0, :, 1])}, - {'name': "pressure_t", - 'units': "Pa/s", - 'data': numpy.ravel(pres_t[0, :])}, - {'name': "trace_strain_t", - 'units': "1/s", - 'data': numpy.ravel(trace_strain_t[0, :])}]} - - from spatialdata.spatialdb.SimpleGridAscii import SimpleGridAscii - io = SimpleGridAscii() - io.inventory.filename = "terzaghi_compaction_ic.spatialdb" - io._configure() - io.write(data) - - return - - -# ====================================================================== -if __name__ == "__main__": - GenerateDB().run() - - -# End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_quad.cfg b/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_quad.cfg deleted file mode 100644 index 822a4050c8..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_quad.cfg +++ /dev/null @@ -1,16 +0,0 @@ -[pylithapp.metadata] -base = [terzaghi_compaction.cfg] -keywords = [quadrilateral cells] -arguments = [terzaghi_compaction.cfg, terzaghi_compaction_quad.cfg] - -[pylithapp.problem] -defaults.name = terzaghi_compaction_quad - -# ---------------------------------------------------------------------- -# mesh_generator -# ---------------------------------------------------------------------- -[pylithapp.mesh_generator.reader] -filename = mesh_quad.exo - - -# End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_soln.py b/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_soln.py deleted file mode 100644 index 8d37ce046d..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_soln.py +++ /dev/null @@ -1,358 +0,0 @@ -# ================================================================================================= -# This code is part of PyLith, developed through the Computational Infrastructure -# for Geodynamics (https://github.com/geodynamics/pylith). -# -# Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. -# All rights reserved. -# -# See https://mit-license.org/ and LICENSE.md and for license information. -# ================================================================================================= -# @file tests/fullscale/poroelasticity/terzaghi_compaction/terzaghi_compaction_soln.py -# -# @brief Analytical solution to Terzaghi's problem. -# -# Uy=0 -# ---------- -# | | -# Ux=0 | | Ux=0 -# | | -# | | -# ---------- -# +1 Pa -# -# Dirichlet boundary conditions -# Ux(+-1,0) = 0 -# Uy(x,+1) = 0 -# Neumann boundary conditions -# \tau_normal(x,+1) = 1*Pa - -import numpy - -# Physical properties -rho_s = 2500 # kg / m**3 -rho_f = 1000 # kg / m**3 -mu_f = 1.0 # Pa*s -G = 3.0 # Pa -K_sg = 10.0 # Pa -K_fl = 8.0 # Pa -K_d = 4.0 # Pa -# K_u = 2.6941176470588233 # Pa -alpha = 0.6 # - -phi = 0.1 # - -# M = 4.705882352941176# Pa -k = 1.5 # m**2 - -ymax = 10.0 # m -ymin = 0.0 # m -xmax = 10.0 # m -xmin = 0.0 # m -P_0 = -1.0 # Pa - -# Height of column, m -L = ymax - ymin -H = xmax - xmin - -M = 1.0 / (phi / K_fl + (alpha - phi) / K_sg) # Pa -K_u = K_d + alpha * alpha * M # Pa, Cheng (B.5) -nu = (3.0 * K_d - 2.0 * G) / (2.0 * (3.0 * K_d + G)) # -, Cheng (B.8) -nu_u = (3.0 * K_u - 2.0 * G) / (2.0 * (3.0 * K_u + G)) # -, Cheng (B.9) -eta = (3.0 * alpha * G) / (3.0 * K_d + 4.0 * G) # -, Cheng (B.11) -S = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)) # Pa^{-1}, Cheng (B.14) -c = (k / mu_f) / S # m^2 / s, Cheng (B.16) - -# Time steps -ts = 0.0028666667 # sec -nts = 2 -tsteps = numpy.arange(0.0, ts * nts, ts) + ts # sec - -# ---------------------------------------------------------------------- - - -class AnalyticalSoln(object): - """Analytical solution to Terzaghi's problem - """ - SPACE_DIM = 2 - TENSOR_SIZE = 4 - ITERATIONS = 16000 - - def __init__(self): - self.fields = { - "displacement": self.displacement, - "pressure": self.pressure, - "porosity": self.porosity, - "trace_strain": self.trace_strain, - "solid_density": self.solid_density, - "fluid_density": self.fluid_density, - "fluid_viscosity": self.fluid_viscosity, - "shear_modulus": self.shear_modulus, - "drained_bulk_modulus": self.drained_bulk_modulus, - "biot_coefficient": self.biot_coefficient, - "biot_modulus": self.biot_modulus, - "isotropic_permeability": self.isotropic_permeability, - "initial_amplitude": { - "x_neg": self.zero_vector, - "x_pos": self.zero_vector, - "y_pos_neu": self.y_pos_neu, - "y_pos_dir": self.zero_scalar, - "y_neg": self.zero_vector, - } - } - return - - def getField(self, name, mesh_entity, pts): - if name in "initial_amplitude": - field = self.fields[name][mesh_entity](pts) - else: - field = self.fields[name](pts) - return field - - def zero_scalar(self, locs): - (npts, dim) = locs.shape - return numpy.zeros((1, npts, 1), dtype=numpy.float64) - - def zero_vector(self, locs): - (npts, dim) = locs.shape - return numpy.zeros((1, npts, self.SPACE_DIM), dtype=numpy.float64) - - def solid_density(self, locs): - """Compute solid_density field at locations. - """ - (npts, dim) = locs.shape - solid_density = rho_s * numpy.ones((1, npts, 1), dtype=numpy.float64) - return solid_density - - def fluid_density(self, locs): - """Compute fluid density field at locations. - """ - (npts, dim) = locs.shape - fluid_density = rho_f * numpy.ones((1, npts, 1), dtype=numpy.float64) - return fluid_density - - def shear_modulus(self, locs): - """Compute shear modulus field at locations. - """ - (npts, dim) = locs.shape - shear_modulus = G * numpy.ones((1, npts, 1), dtype=numpy.float64) - return shear_modulus - - def porosity(self, locs): - """Compute porosity field at locations. - """ - (npts, dim) = locs.shape - porosity = phi * numpy.ones((1, npts, 1), dtype=numpy.float64) - return porosity - - def fluid_viscosity(self, locs): - """Compute fluid_viscosity field at locations. - """ - (npts, dim) = locs.shape - fluid_viscosity = mu_f * numpy.ones((1, npts, 1), dtype=numpy.float64) - return fluid_viscosity - - def drained_bulk_modulus(self, locs): - """Compute undrained bulk modulus field at locations. - """ - (npts, dim) = locs.shape - undrained_bulk_modulus = K_d * numpy.ones((1, npts, 1), dtype=numpy.float64) - return undrained_bulk_modulus - - def biot_coefficient(self, locs): - """Compute biot coefficient field at locations. - """ - (npts, dim) = locs.shape - biot_coefficient = alpha * numpy.ones((1, npts, 1), dtype=numpy.float64) - return biot_coefficient - - def biot_modulus(self, locs): - """Compute biot modulus field at locations. - """ - (npts, dim) = locs.shape - biot_modulus = M * numpy.ones((1, npts, 1), dtype=numpy.float64) - return biot_modulus - - def isotropic_permeability(self, locs): - """Compute isotropic permeability field at locations. - """ - (npts, dim) = locs.shape - isotropic_permeability = k * numpy.ones((1, npts, 1), dtype=numpy.float64) - return isotropic_permeability - - def displacement(self, locs): - """Compute displacement field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - displacement = numpy.zeros((ntpts, npts, dim), dtype=numpy.float64) - z = locs[:, 1] - t_track = 0 - z_star = 1 - z / L - - for t in tsteps: - if t < 0.0: - displacement[0, :, 1] = ((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - z_star) - else: - t_star = (c * t) / ((2 * L)**2) - displacement[t_track, :, 1] = (((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - z_star) + ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * self.F2(z_star, t_star)) - t_track += 1 - - return displacement - - def pressure(self, locs): - """Compute pressure field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - pressure = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) - z = locs[:, 1] - t_track = 0 - - for t in tsteps: - z_star = 1 - z / L - t_star = (c * t) / (4. * L**2) - pressure[t_track, :, 0] = -((P_0 * eta) / (G * S)) * self.F1(z_star, t_star) - t_track += 1 - - return pressure - - def trace_strain(self, locs): - """Compute trace strain field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - trace_strain = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) - z = locs[:, 1] - t_track = 0 - - for t in tsteps: - z_star = z / L - t_star = (c * t) / (4 * L**2) - trace_strain[t_track, :, 0] = -((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u) * L)) \ - + ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * self.F3(z_star, t_star) - t_track += 1 - - return trace_strain - - def zero_array_dim(self, locs): - """ Return zero valued array, dimension = ndim - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - zero_array_dim = numpy.zeros((ntpts, npts, dim), dtype=numpy.float64) - - return zero_array_dim - - def zero_array(self, locs): - """ Return zero valued array - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - zero_array = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) - - return zero_array - - # Series functions - - def F1(self, z_star, t_star): - F1 = 0. - for m in numpy.arange(1, 2 * self.ITERATIONS + 1, 2): - F1 += 4. / (m * numpy.pi) * numpy.sin(0.5 * m * numpy.pi * z_star) * numpy.exp(-(m * numpy.pi)**2 * t_star) - return F1 - - def F2(self, z_star, t_star): - F2 = 0. - for m in numpy.arange(1, 2 * self.ITERATIONS + 1, 2): - F2 += (8. / (m * numpy.pi)**2) * numpy.cos(0.5 * m * numpy.pi * - z_star) * (1. - numpy.exp(-(m * numpy.pi)**2 * t_star)) - return F2 - - def F3(self, z_star, t_star): - F3 = 0. - for m in numpy.arange(1, 2 * self.ITERATIONS + 1, 2): - F3 += (-4.0 / (m * numpy.pi * L)) * numpy.sin(0.5 * m * numpy.pi * - z_star) * (1.0 - numpy.exp(-(m * numpy.pi)**2 * t_star)) - return F3 - - def strain(self, locs): - """Compute strain field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - e_xx = 0.0 - e_yy = self.trace_strain(locs) - e_zz = 0.0 - e_xy = 0.0 - - strain = numpy.zeros((ntpts, npts, self.TENSOR_SIZE), dtype=numpy.float64) - strain[:, :, 0] = exx - strain[:, :, 1] = eyy - strain[:, :, 2] = ezz - strain[:, :, 3] = exy - return strain - - def stress(self, locs): - """Compute stress field at locations. - """ - (npts, dim) = locs.shape - ntpts = tsteps.shape[0] - poisson_ratio = (3 * K_d - 2 * G) / (2 * (3 * K_d + G)) - trace_strain = self.trace_strain(locs) - pressure = self.pressure(locs) - e_xx = 0.0 - e_yy = self.trace_strain(locs) - e_xy = 0.0 - - stress = numpy.zeros((ntpts, npts, self.TENSOR_SIZE), dtype=numpy.float64) - stress[:, :, 0] = ((2 * G * poisson_ratio) / (1 - 2 * poisson_ratio)) * \ - trace_strain + 2 * G * e_xx - alpha * pressure - stress[:, :, 1] = ((2 * G * poisson_ratio) / (1 - 2 * poisson_ratio)) * \ - trace_strain + 2 * G * e_yy - alpha * pressure - stress[:, :, 2] = ((2 * G * poisson_ratio) / (1 - 2 * poisson_ratio)) * trace_strain - alpha * pressure - stress[:, :, 3] = 2 * G * e_xy - return stress - - def y_pos_neu(self, locs): - """Compute initial traction at locations. - """ - (npts, dim) = locs.shape - traction = numpy.zeros((1, npts, self.SPACE_DIM), dtype=numpy.float64) - traction[:, :, 0] = 0.0 - traction[:, :, 1] = P_0 - return traction - - def initial_displacement(self, locs): - """Compute initial displacement at locations - """ - (npts, dim) = locs.shape - displacement = numpy.zeros((1, npts, dim), dtype=numpy.float64) - z = locs[:, 1] - z_star = 1 - z / L - - displacement[0, :, 1] = ((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - z_star) - return displacement - - def initial_pressure(self, locs): - """Compute initial pressure at locations - """ - (npts, dim) = locs.shape - pressure = numpy.zeros((1, npts), dtype=numpy.float64) - z = locs[:, 1] - - pressure[0, :] = (-P_0 * eta) / (G * S) - - return pressure - - def initial_trace_strain(self, locs): - """Compute initial trace strain field at locations. - """ - (npts, dim) = locs.shape - - trace_strain = numpy.zeros((1, npts), dtype=numpy.float64) - z = locs[:, 1] - z_star = z / L - - trace_strain[0, :] = -(P_0 * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u)) - - return trace_strain - - -# End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_tri.cfg b/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_tri.cfg deleted file mode 100644 index e4971de81e..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_compaction_tri.cfg +++ /dev/null @@ -1,16 +0,0 @@ -[pylithapp.metadata] -base = [terzaghi_compaction.cfg] -keywords = [triangular cells] -arguments = [terzaghi_compaction.cfg, terzaghi_compaction_tri.cfg] - -[pylithapp.problem] -defaults.name = terzaghi_compaction_tri - -# ---------------------------------------------------------------------- -# mesh_generator -# ---------------------------------------------------------------------- -[pylithapp.mesh_generator.reader] -filename = mesh_tri.exo - - -# End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_gendb.py b/tests/fullscale/poroelasticity/terzaghi/terzaghi_gendb.py deleted file mode 100755 index 300993e677..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_gendb.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env nemesis -# ================================================================================================= -# This code is part of PyLith, developed through the Computational Infrastructure -# for Geodynamics (https://github.com/geodynamics/pylith). -# -# Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. -# All rights reserved. -# -# See https://mit-license.org/ and LICENSE.md and for license information. -# ================================================================================================= -# @file tests/fullscale/poroelasticity/terzaghi/terzaghi_gendb.py -# -# @brief Python script to generate spatial database with displacement -# boundary conditions for the terzaghi test. - -import numpy - - -class GenerateDB(object): - """Python object to generate spatial database with initial conditions - for the terzaghi poroelastic test. - """ - - def run(self): - """Generate the database. - """ - # Domain - x1 = numpy.arange(-1.0, 11.01, 1.0) - y1 = numpy.arange(-1.0, 11.01, 1.0) - x, y = numpy.meshgrid(x1, y1) - - xy = numpy.zeros((len(x1) * len(y1), 2), dtype=numpy.float64) - xy[:, 0] = x.ravel() - xy[:, 1] = y.ravel() - - from terzaghi_soln import AnalyticalSoln - soln = AnalyticalSoln() - disp = soln.initial_displacement(xy) - pres = soln.initial_pressure(xy) - trace_strain = soln.initial_trace_strain(xy) - - from spatialdata.geocoords.CSCart import CSCart - cs = CSCart() - cs.inventory.spaceDim = 2 - cs._configure() - data = { - 'x': x1, - 'y': y1, - 'points': xy, - 'coordsys': cs, - 'data_dim': 2, - 'values': [{'name': "displacement_x", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 0])}, - {'name': "displacement_y", - 'units': "m", - 'data': numpy.ravel(disp[0, :, 1])}, - {'name': "pressure", - 'units': "Pa", - 'data': numpy.ravel(pres[0, :])}, - {'name': "trace_strain", - 'units': "none", - 'data': numpy.ravel(trace_strain[0, :])}]} - - from spatialdata.spatialdb.SimpleGridAscii import SimpleGridAscii - io = SimpleGridAscii() - io.inventory.filename = "terzaghi_ic.spatialdb" - io._configure() - io.write(data) - - return - - -# ====================================================================== -if __name__ == "__main__": - GenerateDB().run() - - -# End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_quad.cfg b/tests/fullscale/poroelasticity/terzaghi/terzaghi_quad.cfg index e1d8e8ff02..13a3893517 100644 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_quad.cfg +++ b/tests/fullscale/poroelasticity/terzaghi/terzaghi_quad.cfg @@ -10,7 +10,7 @@ defaults.name = terzaghi_quad # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator.reader] -filename = mesh_quad.exo +filename = mesh_quad.msh # End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_soln.py b/tests/fullscale/poroelasticity/terzaghi/terzaghi_soln.py index cf7493f4a4..35382d24c6 100644 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_soln.py +++ b/tests/fullscale/poroelasticity/terzaghi/terzaghi_soln.py @@ -5,12 +5,22 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= # @file tests/fullscale/poroelasticity/terzaghi/terzaghi_soln.py # # @brief Analytical solution to Terzaghi's problem. # +# This is based on Cheng (Poroelasticity, Section 7.3.1) and its implementation in PETSc tutorial +# src/ts/tutorials/ex53.c. +# +# Notes: +# - The traction loading is impulsive, so we use a custom PETSc TS (pylith/utils/TSAdaptImpulse), +# which uses a very small time step for the first step before using the user-specified time step. +# - The accuracy of the solution is poor in the first few time steps due to the impulsive loading +# so we only check the last time step in the simulation, which is more accurate and select a +# a tolerance appropriate for the discretization size. +# # Uy=0 # ---------- # | | @@ -31,26 +41,21 @@ # Physical properties rho_s = 2500 # kg / m**3 rho_f = 1000 # kg / m**3 -mu_f = 1.0 # Pa*s -G = 3.0 # Pa -K_sg = 10.0 # Pa -K_fl = 8.0 # Pa -K_d = 4.0 # Pa -# K_u = 2.6941176470588233 # Pa -alpha = 0.6 # - -phi = 0.1 # - -# M = 4.705882352941176# Pa -k = 1.5 # m**2 - -ymax = 10.0 # m -ymin = 0.0 # m -xmax = 10.0 # m -xmin = 0.0 # m -P_0 = -1.0 # Pa +mu_f = 1.0e-3 # Pa*s +G = 30.0e+9 # Pa +K_sg = 100.0e+9 # Pa +K_fl = 80.0e+9 # Pa +K_d = 40.0e+9 # Pa +alpha = 0.6 +phi = 0.1 +k = 1.5e-13 # m**2 + +y_max = 10.0e+3 # m +y_min = 0.0 # m +P_0 = 1.0e+4 # Pa # Height of column, m -L = ymax - ymin -H = xmax - xmin +H = y_max - y_min M = 1.0 / (phi / K_fl + (alpha - phi) / K_sg) # Pa K_u = K_d + alpha * alpha * M # Pa, Cheng (B.5) @@ -60,27 +65,28 @@ S = (3.0 * K_u + 4.0 * G) / (M * (3.0 * K_d + 4.0 * G)) # Pa^{-1}, Cheng (B.14) c = (k / mu_f) / S # m^2 / s, Cheng (B.16) -# Time steps -ts = 0.0028666667 # sec -nts = 2 -tsteps = numpy.arange(0.0, ts * nts, ts) + ts # sec +dt0 = 1.0e-6 * 1.0e+8 +dt = 5.0e+4 +t_end = 100.0e+4 +time = numpy.concatenate((numpy.array([dt0]), dt0+numpy.arange(dt, t_end+0.5*dt, dt))) +tsteps = numpy.array([time[-1]]) # ---------------------------------------------------------------------- class AnalyticalSoln(object): - """Analytical solution to Terzaghi's problem - """ + """Analytical solution to Terzaghi's problem""" + SPACE_DIM = 2 TENSOR_SIZE = 4 - ITERATIONS = 16000 + ITERATIONS = 8000 def __init__(self): self.fields = { "displacement": self.displacement, "pressure": self.pressure, - "porosity": self.porosity, "trace_strain": self.trace_strain, + "porosity": self.porosity, "solid_density": self.solid_density, "fluid_density": self.fluid_density, "fluid_viscosity": self.fluid_viscosity, @@ -90,12 +96,12 @@ def __init__(self): "biot_modulus": self.biot_modulus, "isotropic_permeability": self.isotropic_permeability, "initial_amplitude": { - "x_neg": self.zero_vector, - "x_pos": self.zero_vector, - "y_pos_neu": self.y_pos_neu, - "y_pos_dir": self.zero_scalar, - "y_neg": self.zero_vector, - } + "bc_xneg": self.zero_vector, + "bc_xpos": self.zero_vector, + "bc_ypos_traction": self.bc_ypos_traction, + "bc_ypos_pressure": self.zero_scalar, + "bc_yneg": self.zero_vector, + }, } return @@ -115,148 +121,138 @@ def zero_vector(self, locs): return numpy.zeros((1, npts, self.SPACE_DIM), dtype=numpy.float64) def solid_density(self, locs): - """Compute solid_density field at locations. - """ + """Compute solid_density field at locations.""" (npts, dim) = locs.shape solid_density = rho_s * numpy.ones((1, npts, 1), dtype=numpy.float64) return solid_density def fluid_density(self, locs): - """Compute fluid density field at locations. - """ + """Compute fluid density field at locations.""" (npts, dim) = locs.shape fluid_density = rho_f * numpy.ones((1, npts, 1), dtype=numpy.float64) return fluid_density def shear_modulus(self, locs): - """Compute shear modulus field at locations. - """ + """Compute shear modulus field at locations.""" (npts, dim) = locs.shape shear_modulus = G * numpy.ones((1, npts, 1), dtype=numpy.float64) return shear_modulus def porosity(self, locs): - """Compute porosity field at locations. - """ + """Compute porosity field at locations.""" (npts, dim) = locs.shape porosity = phi * numpy.ones((1, npts, 1), dtype=numpy.float64) return porosity def fluid_viscosity(self, locs): - """Compute fluid_viscosity field at locations. - """ + """Compute fluid_viscosity field at locations.""" (npts, dim) = locs.shape fluid_viscosity = mu_f * numpy.ones((1, npts, 1), dtype=numpy.float64) return fluid_viscosity def drained_bulk_modulus(self, locs): - """Compute undrained bulk modulus field at locations. - """ + """Compute undrained bulk modulus field at locations.""" (npts, dim) = locs.shape undrained_bulk_modulus = K_d * numpy.ones((1, npts, 1), dtype=numpy.float64) return undrained_bulk_modulus def biot_coefficient(self, locs): - """Compute biot coefficient field at locations. - """ + """Compute biot coefficient field at locations.""" (npts, dim) = locs.shape biot_coefficient = alpha * numpy.ones((1, npts, 1), dtype=numpy.float64) return biot_coefficient def biot_modulus(self, locs): - """Compute biot modulus field at locations. - """ + """Compute biot modulus field at locations.""" (npts, dim) = locs.shape biot_modulus = M * numpy.ones((1, npts, 1), dtype=numpy.float64) return biot_modulus def isotropic_permeability(self, locs): - """Compute isotropic permeability field at locations. - """ + """Compute isotropic permeability field at locations.""" (npts, dim) = locs.shape isotropic_permeability = k * numpy.ones((1, npts, 1), dtype=numpy.float64) return isotropic_permeability def displacement(self, locs): - """Compute displacement field at locations. - """ + """Compute displacement field at locations.""" (npts, dim) = locs.shape ntpts = tsteps.shape[0] displacement = numpy.zeros((ntpts, npts, dim), dtype=numpy.float64) - z = locs[:, 1] - t_track = 0 - z_star = 1 - z / L + y_star = 1.0 - locs[:, 1] / H - for t in tsteps: + for i_t, t in enumerate(tsteps): if t < 0.0: - displacement[0, :, 1] = ((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - z_star) + displacement[0, :, 1] = ( + -(P_0 * H * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u)) + ) * (1.0 - y_star) else: - t_star = (c * t) / ((2 * L)**2) - displacement[t_track, :, 1] = (((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - z_star) + ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * self.F2(z_star, t_star)) - t_track += 1 + t_star = (c * t) / ((2 * H) ** 2) + displacement[i_t, :, 1] = ( + -(P_0 * H * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u)) + ) * (1.0 - y_star) + ( + -(P_0 * H * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu)) + ) * self.F2( + y_star, t_star + ) return displacement def pressure(self, locs): - """Compute pressure field at locations. - """ + """Compute pressure field at locations.""" (npts, dim) = locs.shape ntpts = tsteps.shape[0] pressure = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) - z = locs[:, 1] - t_track = 0 + y_star = 1.0 - locs[:, 1] / H - for t in tsteps: - z_star = 1 - z / L - t_star = (c * t) / (4. * L**2) - pressure[t_track, :, 0] = -((P_0 * eta) / (G * S)) * self.F1(z_star, t_star) - t_track += 1 + for i_t, t in enumerate(tsteps): + t_star = (c * t) / (4.0 * H**2) + pressure[i_t, :, 0] = ((P_0 * eta) / (G * S)) * self.F1(y_star, t_star) return pressure def trace_strain(self, locs): - """Compute trace strain field at locations. - """ + """Compute trace strain field at locations.""" (npts, dim) = locs.shape ntpts = tsteps.shape[0] trace_strain = numpy.zeros((ntpts, npts, 1), dtype=numpy.float64) - z = locs[:, 1] - t_track = 0 + y_star = 1.0 - locs[:, 1] / H - for t in tsteps: - z_star = z / L - t_star = (c * t) / (4 * L**2) - trace_strain[t_track, :, 0] = -((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u) * L)) \ - + ((P_0 * L * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu))) * self.F3(z_star, t_star) - t_track += 1 + for i_t, t in enumerate(tsteps): + t_star = (c * t) / (4 * H**2) + trace_strain[i_t, :, 0] = ( + -(P_0 * H * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u) * H) + ) + ( + (P_0 * H * (nu_u - nu)) / (2.0 * G * (1.0 - nu_u) * (1.0 - nu)) + ) * self.F3(y_star, t_star) return trace_strain # Series functions - def F1(self, z_star, t_star): - F1 = 0. - for m in numpy.arange(1, 2 * self.ITERATIONS + 1, 2): - F1 += 4. / (m * numpy.pi) * numpy.sin(0.5 * m * numpy.pi * z_star) * numpy.exp(-(m * numpy.pi)**2 * t_star) + def F1(self, y_star, t_star): + m = numpy.arange(1, 2 * self.ITERATIONS + 1, 2) + F1 = numpy.zeros(y_star.shape) + for i_y, y in enumerate(y_star): + F1[i_y] = numpy.sum(4.0 / (m * numpy.pi) * numpy.sin(0.5 * m * numpy.pi * y) * numpy.exp(-((m * numpy.pi) ** 2) * t_star)) return F1 - def F2(self, z_star, t_star): - F2 = 0. - for m in numpy.arange(1, 2 * self.ITERATIONS + 1, 2): - F2 += (8. / (m * numpy.pi)**2) * numpy.cos(0.5 * m * numpy.pi * - z_star) * (1. - numpy.exp(-(m * numpy.pi)**2 * t_star)) + def F2(self, y_star, t_star): + m = numpy.arange(1, 2 * self.ITERATIONS + 1, 2) + F2 = numpy.zeros(y_star.shape) + for i_y, y in enumerate(y_star): + F2[i_y] = numpy.sum((8.0 / (m * numpy.pi) ** 2) * numpy.cos(0.5 * m * numpy.pi * y) * (1.0 - numpy.exp(-((m * numpy.pi) ** 2) * t_star))) return F2 - def F3(self, z_star, t_star): - F3 = 0. - for m in numpy.arange(1, 2 * self.ITERATIONS + 1, 2): - F3 += (-4.0 / (m * numpy.pi * L)) * numpy.sin(0.5 * m * numpy.pi * - z_star) * (1.0 - numpy.exp(-(m * numpy.pi)**2 * t_star)) + def F3(self, y_star, t_star): + m = numpy.arange(1, 2 * self.ITERATIONS + 1, 2) + F3 = numpy.zeros(y_star.shape) + for i_y, y in enumerate(y_star): + F3[i_y] = numpy.sum((-4.0 / (m * numpy.pi * H)) * numpy.sin(0.5 * m * numpy.pi * y) * (1.0 - numpy.exp(-((m * numpy.pi) ** 2) * t_star))) return F3 def strain(self, locs): - """Compute strain field at locations. - """ + """Compute strain field at locations.""" (npts, dim) = locs.shape ntpts = tsteps.shape[0] e_xx = 0.0 @@ -265,15 +261,14 @@ def strain(self, locs): e_xy = 0.0 strain = numpy.zeros((ntpts, npts, self.TENSOR_SIZE), dtype=numpy.float64) - strain[:, :, 0] = exx - strain[:, :, 1] = eyy - strain[:, :, 2] = ezz - strain[:, :, 3] = exy + strain[:, :, 0] = e_xx + strain[:, :, 1] = e_yy + strain[:, :, 2] = e_zz + strain[:, :, 3] = e_xy return strain def stress(self, locs): - """Compute stress field at locations. - """ + """Compute stress field at locations.""" (npts, dim) = locs.shape ntpts = tsteps.shape[0] poisson_ratio = (3 * K_d - 2 * G) / (2 * (3 * K_d + G)) @@ -284,57 +279,29 @@ def stress(self, locs): e_xy = 0.0 stress = numpy.zeros((ntpts, npts, self.TENSOR_SIZE), dtype=numpy.float64) - stress[:, :, 0] = ((2 * G * poisson_ratio) / (1 - 2 * poisson_ratio)) * \ - trace_strain + 2 * G * e_xx - alpha * pressure - stress[:, :, 1] = ((2 * G * poisson_ratio) / (1 - 2 * poisson_ratio)) * \ - trace_strain + 2 * G * e_yy - alpha * pressure - stress[:, :, 2] = ((2 * G * poisson_ratio) / (1 - 2 * poisson_ratio)) * trace_strain - alpha * pressure + stress[:, :, 0] = ( + ((2 * G * poisson_ratio) / (1 - 2 * poisson_ratio)) * trace_strain + + 2 * G * e_xx + - alpha * pressure + ) + stress[:, :, 1] = ( + ((2 * G * poisson_ratio) / (1 - 2 * poisson_ratio)) * trace_strain + + 2 * G * e_yy + - alpha * pressure + ) + stress[:, :, 2] = ( + (2 * G * poisson_ratio) / (1 - 2 * poisson_ratio) + ) * trace_strain - alpha * pressure stress[:, :, 3] = 2 * G * e_xy return stress - def y_pos_neu(self, locs): - """Compute initial traction at locations. - """ + def bc_ypos_traction(self, locs): + """Compute initial traction at locations.""" (npts, dim) = locs.shape traction = numpy.zeros((1, npts, self.SPACE_DIM), dtype=numpy.float64) traction[:, :, 0] = 0.0 - traction[:, :, 1] = P_0 + traction[:, :, 1] = -P_0 return traction - def initial_displacement(self, locs): - """Compute initial displacement at locations - """ - (npts, dim) = locs.shape - displacement = numpy.zeros((1, npts, dim), dtype=numpy.float64) - z = locs[:, 1] - z_star = 1 - z / L - - displacement[0, :, 1] = ((P_0 * L * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u))) * (1.0 - z_star) - return displacement - - def initial_pressure(self, locs): - """Compute initial pressure at locations - """ - (npts, dim) = locs.shape - pressure = numpy.zeros((1, npts), dtype=numpy.float64) - z = locs[:, 1] - - pressure[0, :] = (-P_0 * eta) / (G * S) - - return pressure - - def initial_trace_strain(self, locs): - """Compute initial trace strain field at locations. - """ - (npts, dim) = locs.shape - - trace_strain = numpy.zeros((1, npts), dtype=numpy.float64) - z = locs[:, 1] - z_star = z / L - - trace_strain[0, :] = -(P_0 * (1.0 - 2.0 * nu_u)) / (2.0 * G * (1.0 - nu_u)) - - return trace_strain - # End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/terzaghi_tri.cfg b/tests/fullscale/poroelasticity/terzaghi/terzaghi_tri.cfg index a25ca62793..b07a59a875 100644 --- a/tests/fullscale/poroelasticity/terzaghi/terzaghi_tri.cfg +++ b/tests/fullscale/poroelasticity/terzaghi/terzaghi_tri.cfg @@ -10,7 +10,7 @@ defaults.name = terzaghi_tri # mesh_generator # ---------------------------------------------------------------------- [pylithapp.mesh_generator.reader] -filename = mesh_tri.exo +filename = mesh_tri.msh # End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/test_pylith copy.py b/tests/fullscale/poroelasticity/terzaghi/test_pylith copy.py deleted file mode 100755 index 961f7b91a7..0000000000 --- a/tests/fullscale/poroelasticity/terzaghi/test_pylith copy.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env nemesis -# ================================================================================================= -# This code is part of PyLith, developed through the Computational Infrastructure -# for Geodynamics (https://github.com/geodynamics/pylith). -# -# Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. -# All rights reserved. -# -# See https://mit-license.org/ and LICENSE.md and for license information. -# ================================================================================================= - -from pylith.testing.FullTestApp import TestDriver, FullTestCase - -import unittest - - -class TestApp(TestDriver): - """Driver application for full-scale tests. - """ - - def __init__(self): - """Constructor. - """ - TestDriver.__init__(self) - return - - def _suite(self): - """Create test suite. - """ - suite = unittest.TestSuite() - - import TestTerzaghiCompaction - for test in TestTerzaghiCompaction.test_cases(): - suite.addTest(unittest.makeSuite(test)) - - return suite - - -# ---------------------------------------------------------------------- -if __name__ == '__main__': - FullTestCase.parse_args() - TestApp().main() - - -# End of file diff --git a/tests/fullscale/poroelasticity/terzaghi/test_pylith.py b/tests/fullscale/poroelasticity/terzaghi/test_pylith.py index 1e741704c9..98a7235624 100755 --- a/tests/fullscale/poroelasticity/terzaghi/test_pylith.py +++ b/tests/fullscale/poroelasticity/terzaghi/test_pylith.py @@ -33,10 +33,6 @@ def _suite(self): for test in TestTerzaghi.test_cases(): suite.addTest(unittest.makeSuite(test)) - import TestTerzaghiCompaction - for test in TestTerzaghiCompaction.test_cases(): - suite.addTest(unittest.makeSuite(test)) - return suite diff --git a/tests/fullscale/viscoelasticity/nofaults-2d/axialstrain_genmaxwell.cfg b/tests/fullscale/viscoelasticity/nofaults-2d/axialstrain_genmaxwell.cfg index 9b11207166..1e0ea9e08f 100644 --- a/tests/fullscale/viscoelasticity/nofaults-2d/axialstrain_genmaxwell.cfg +++ b/tests/fullscale/viscoelasticity/nofaults-2d/axialstrain_genmaxwell.cfg @@ -22,7 +22,8 @@ features = [ initial_dt = 0.025*year start_time = 0.0*year end_time = 1.0*year -normalizer.relaxation_time = 1.0*year + +scales.time_scale = 1.0*year # ---------------------------------------------------------------------- # materials diff --git a/tests/fullscale/viscoelasticity/nofaults-2d/axialstrainrate_genmaxwell.cfg b/tests/fullscale/viscoelasticity/nofaults-2d/axialstrainrate_genmaxwell.cfg index e5437b0975..810daf8c26 100644 --- a/tests/fullscale/viscoelasticity/nofaults-2d/axialstrainrate_genmaxwell.cfg +++ b/tests/fullscale/viscoelasticity/nofaults-2d/axialstrainrate_genmaxwell.cfg @@ -22,7 +22,8 @@ features = [ initial_dt = 0.025*year start_time = 0.0*year end_time = 0.5*year -normalizer.relaxation_time = 1.0*year + +scales.time_scale = 1.0*year # ---------------------------------------------------------------------- # materials diff --git a/tests/fullscale/viscoelasticity/nofaults-2d/axialtraction_maxwell.cfg b/tests/fullscale/viscoelasticity/nofaults-2d/axialtraction_maxwell.cfg index 46d28f4c77..baf14cce29 100644 --- a/tests/fullscale/viscoelasticity/nofaults-2d/axialtraction_maxwell.cfg +++ b/tests/fullscale/viscoelasticity/nofaults-2d/axialtraction_maxwell.cfg @@ -25,7 +25,8 @@ features = [ initial_dt = 0.025*year start_time = 0.0*year end_time = 1.0*year -normalizer.relaxation_time = 1.0*year + +scales.time_scale = 1.0*year # ---------------------------------------------------------------------- # materials diff --git a/tests/fullscale/viscoelasticity/nofaults-2d/pylithapp.cfg b/tests/fullscale/viscoelasticity/nofaults-2d/pylithapp.cfg index 6d63874ff8..b941eb2983 100644 --- a/tests/fullscale/viscoelasticity/nofaults-2d/pylithapp.cfg +++ b/tests/fullscale/viscoelasticity/nofaults-2d/pylithapp.cfg @@ -30,6 +30,9 @@ reader.coordsys.space_dim = 2 # solution # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km +scales.time_scale = 1.0*year + # Use nonlinear solver to ensure residual and Jacobian are consistent. solver = nonlinear @@ -54,10 +57,6 @@ testing = True monitors = False [pylithapp.petsc] -ksp_atol = 1.0e-13 -ksp_max_it = 200 -ksp_gmres_restart = 50 - snes_max_it = 3 diff --git a/tests/fullscale/viscoelasticity/nofaults-3d/axialstrain_genmaxwell.cfg b/tests/fullscale/viscoelasticity/nofaults-3d/axialstrain_genmaxwell.cfg index 6a8795480b..b11290e33d 100644 --- a/tests/fullscale/viscoelasticity/nofaults-3d/axialstrain_genmaxwell.cfg +++ b/tests/fullscale/viscoelasticity/nofaults-3d/axialstrain_genmaxwell.cfg @@ -22,7 +22,8 @@ features = [ initial_dt = 0.025*year start_time = 0.0*year end_time = 0.5*year -normalizer.relaxation_time = 1.0*year + +scales.time_scale = 1.0*year # ---------------------------------------------------------------------- # materials diff --git a/tests/fullscale/viscoelasticity/nofaults-3d/axialstrainrate_genmaxwell.cfg b/tests/fullscale/viscoelasticity/nofaults-3d/axialstrainrate_genmaxwell.cfg index 18d5d1710e..17d7bfdfe4 100644 --- a/tests/fullscale/viscoelasticity/nofaults-3d/axialstrainrate_genmaxwell.cfg +++ b/tests/fullscale/viscoelasticity/nofaults-3d/axialstrainrate_genmaxwell.cfg @@ -22,7 +22,8 @@ features = [ initial_dt = 0.025*year start_time = 0.0*year end_time = 0.5*year -normalizer.relaxation_time = 1.0*year + +scales.time_scale = 1.0*year # ---------------------------------------------------------------------- # materials diff --git a/tests/fullscale/viscoelasticity/nofaults-3d/axialtraction_maxwell.cfg b/tests/fullscale/viscoelasticity/nofaults-3d/axialtraction_maxwell.cfg index de6b43a9a5..a70ea8170f 100644 --- a/tests/fullscale/viscoelasticity/nofaults-3d/axialtraction_maxwell.cfg +++ b/tests/fullscale/viscoelasticity/nofaults-3d/axialtraction_maxwell.cfg @@ -25,7 +25,8 @@ features = [ initial_dt = 0.025*year start_time = 0.0*year end_time = 0.5*year -normalizer.relaxation_time = 1.0*year + +scales.time_scale = 1.0*year # ---------------------------------------------------------------------- # materials diff --git a/tests/fullscale/viscoelasticity/nofaults-3d/pylithapp.cfg b/tests/fullscale/viscoelasticity/nofaults-3d/pylithapp.cfg index 8896121e09..94d5e88bbd 100644 --- a/tests/fullscale/viscoelasticity/nofaults-3d/pylithapp.cfg +++ b/tests/fullscale/viscoelasticity/nofaults-3d/pylithapp.cfg @@ -30,6 +30,9 @@ reader.coordsys.space_dim = 3 # solution # ---------------------------------------------------------------------- [pylithapp.problem] +scales.length_scale = 8.0*km +scales.time_scale = 1.0*year + # Use nonlinear solver to ensure residual and Jacobian are consistent. solver = nonlinear @@ -54,10 +57,6 @@ testing = True monitors = False [pylithapp.petsc] -ksp_atol = 1.0e-13 -ksp_max_it = 200 -ksp_gmres_restart = 50 - snes_max_it = 3 diff --git a/tests/libtests/Makefile.am b/tests/libtests/Makefile.am index f6ccf85dc0..08cc441497 100644 --- a/tests/libtests/Makefile.am +++ b/tests/libtests/Makefile.am @@ -16,6 +16,7 @@ SUBDIRS = \ materials \ meshio \ problems \ + scales \ topology \ testing \ utils diff --git a/tests/libtests/bc/TestAbsorbingDampers.cc b/tests/libtests/bc/TestAbsorbingDampers.cc index d631ab6e08..b7a41cc38a 100644 --- a/tests/libtests/bc/TestAbsorbingDampers.cc +++ b/tests/libtests/bc/TestAbsorbingDampers.cc @@ -28,7 +28,7 @@ #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/spatialdb/TimeHistory.hh" // USES TimeHistory -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales const double pylith::bc::TestAbsorbingDampers::FILL_VALUE = -999.0; @@ -167,21 +167,21 @@ pylith::bc::TestAbsorbingDampers::testAuxFieldDB(void) { // ---------------------------------------------------------------------- -// Test normalizer(). +// Test scales(). void -pylith::bc::TestAbsorbingDampers::testNormalizer(void) { +pylith::bc::TestAbsorbingDampers::testScales(void) { PYLITH_METHOD_BEGIN; - spatialdata::units::Nondimensional normalizer; - const double scale = 5.0; - normalizer.setLengthScale(scale); + pylith::scales::Scales scales; + const double scale = 2.0; + scales.setLengthScale(scale); CPPUNIT_ASSERT(_bc); - _bc->normalizer(normalizer); - CPPUNIT_ASSERT_EQUAL(scale, _bc->_normalizer->getLengthScale()); + _bc->scales(scales); + CPPUNIT_ASSERT_EQUAL(scale, _bc->_scales->getLengthScale()); PYLITH_METHOD_END; -} // testNormalizer +} // testScales // ---------------------------------------------------------------------- @@ -240,8 +240,8 @@ pylith::bc::TestAbsorbingDampers::testInitialize(void) { const PetscDM dm = auxField->getDM();CPPUNIT_ASSERT(dm); pylith::topology::FieldQuery query(*auxField); query.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(_data->normalizer); - query.openDB(_data->auxDB, _data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(_data->scales); + query.openDB(_data->auxDB, _data->scales->getLengthScale()); PetscErrorCode err = DMPlexComputeL2DiffLocal(dm, t, query.functions(), (void**)query.contextPtrs(), auxField->localVector(), &norm);CPPUNIT_ASSERT(!err); query.closeDB(_data->auxDB); const PylithReal tolerance = 1.0e-6; @@ -327,7 +327,7 @@ pylith::bc::TestAbsorbingDampers::testAuxFieldSetup(void) { CPPUNIT_ASSERT(_solution); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_data); - CPPUNIT_ASSERT(_data->normalizer); + CPPUNIT_ASSERT(_data->scales); delete _bc->_boundaryMesh;_bc->_boundaryMesh = new pylith::topology::Mesh(_solution->mesh(), _data->bcLabel); CPPUNIT_ASSERT(_bc->_boundaryMesh); @@ -346,7 +346,7 @@ pylith::bc::TestAbsorbingDampers::testAuxFieldSetup(void) { CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(_data->normalizer->getDensityScale(), info.description.scale); + CPPUNIT_ASSERT_EQUAL(_data->scales->getDensityScale(), info.description.scale); CPPUNIT_ASSERT_EQUAL(discretization.basisOrder, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(discretization.quadOrder, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(discretization.isBasisContinuous, info.fe.isBasisContinuous); @@ -354,7 +354,7 @@ pylith::bc::TestAbsorbingDampers::testAuxFieldSetup(void) { ++ifield; } // density - const PylithScalar velocityScale = _data->normalizer->getLengthScale() / _data->normalizer->getTimeScale(); + const PylithScalar velocityScale = _data->scales->getLengthScale() / _data->scales->getTimeScale(); { // vp const char* label = "vp"; @@ -407,13 +407,13 @@ pylith::bc::TestAbsorbingDampers::_initialize(void) { iohandler.filename(_data->meshFilename); iohandler.read(_mesh); _mesh->setCoordSys(_data->cs); - CPPUNIT_ASSERT(_data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->normalizer); + CPPUNIT_ASSERT(_data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->scales); _bc->setLabel(_data->bcLabel); _bc->field(_data->field); _bc->auxFieldDB(_data->auxDB); - _bc->normalizer(*_data->normalizer); + _bc->scales(*_data->scales); for (int ifield = 0; ifield < _data->numAuxSubfields; ++ifield) { const pylith::topology::Field::Discretization& discretization = _data->auxDiscretizations[ifield]; const char* name = _data->auxSubfields[ifield]; @@ -431,10 +431,10 @@ pylith::bc::TestAbsorbingDampers::_setupSolutionField(void) { CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_data); - CPPUNIT_ASSERT(_data->normalizer); + CPPUNIT_ASSERT(_data->scales); delete _solution;_solution = new pylith::topology::Field(*_mesh); - pylith::problems::SolutionFactory factory(*_solution, *_data->normalizer); + pylith::problems::SolutionFactory factory(*_solution, *_data->scales); factory.displacement(_data->solnDiscretizations[0]); factory.velocity(_data->solnDiscretizations[1]); factory.fluidPressure(_data->solnDiscretizations[2]); @@ -449,7 +449,7 @@ pylith::bc::TestAbsorbingDampers::_setupSolutionField(void) { pylith::bc::TestAbsorbingDampers_Data::TestAbsorbingDampers_Data(void) : meshFilename(NULL), bcLabel(NULL), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), field(NULL), vectorFieldType(pylith::topology::Field::OTHER), numAuxSubfields(0), @@ -466,7 +466,7 @@ pylith::bc::TestAbsorbingDampers_Data::TestAbsorbingDampers_Data(void) : // Destructor pylith::bc::TestAbsorbingDampers_Data::~TestAbsorbingDampers_Data(void) { delete cs;cs = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; delete auxDB;auxDB = NULL; delete solnDB;solnDB = NULL; } // destructor diff --git a/tests/libtests/bc/TestAbsorbingDampers.hh b/tests/libtests/bc/TestAbsorbingDampers.hh index 47075ba0db..54d9ed8908 100644 --- a/tests/libtests/bc/TestAbsorbingDampers.hh +++ b/tests/libtests/bc/TestAbsorbingDampers.hh @@ -26,7 +26,7 @@ #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA UserFunctionDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA CoordSys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales /// Namespace for pylith package namespace pylith { @@ -46,7 +46,7 @@ class pylith::bc::TestAbsorbingDampers : public CppUnit::TestFixture { CPPUNIT_TEST(testAccessors); CPPUNIT_TEST(testAuxFieldDiscretization); CPPUNIT_TEST(testAuxFieldDB); - CPPUNIT_TEST(testNormalizer); + CPPUNIT_TEST(testScales); CPPUNIT_TEST(testVerifyConfiguration); CPPUNIT_TEST(testInitialize); CPPUNIT_TEST(testComputeRHSResidual); @@ -75,8 +75,8 @@ public: /// Test auxFieldDB(). void testAuxFieldDB(void); - /// Test normalizer(). - void testNormalizer(void); + /// Test scales(). + void testScales(void); /// Test verifyConfiguration(). void testVerifyConfiguration(void); @@ -130,7 +130,7 @@ public: const char* bcLabel; ///< Label defining cells associated with material. spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. const char* field; ///< Name of solution field constrained. pylith::topology::FieldBase::VectorFieldEnum vectorFieldType; ///< Vector field type for constrained field. diff --git a/tests/libtests/bc/TestAbsorbingDampers_Cases.cc b/tests/libtests/bc/TestAbsorbingDampers_Cases.cc index 380de15b2b..122eab0efb 100644 --- a/tests/libtests/bc/TestAbsorbingDampers_Cases.cc +++ b/tests/libtests/bc/TestAbsorbingDampers_Cases.cc @@ -15,7 +15,7 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ---------------------------------------------------------------------- namespace pylith { @@ -95,11 +95,10 @@ namespace pylith { _data->cs = new spatialdata::geocoords::CSCart();CPPUNIT_ASSERT(_data->cs); _data->cs->setSpaceDim(2); - CPPUNIT_ASSERT(_data->normalizer); - _data->normalizer->setLengthScale(1000.0); - _data->normalizer->setTimeScale(10.0); - _data->normalizer->setPressureScale(0.1); - _data->normalizer->setDensityScale(2.0); + CPPUNIT_ASSERT(_data->scales); + _data->scales->setLengthScale(1.0); + _data->scales->setTimeScale(10.0); + _data->scales->setRigidityScale(2.0e+6); _data->field = "velocity"; _data->vectorFieldType = pylith::topology::Field::VECTOR; diff --git a/tests/libtests/bc/TestBoundaryMesh.cc b/tests/libtests/bc/TestBoundaryMesh.cc index cef19e6e85..fbea8a03bc 100644 --- a/tests/libtests/bc/TestBoundaryMesh.cc +++ b/tests/libtests/bc/TestBoundaryMesh.cc @@ -21,7 +21,7 @@ #include "pylith/meshio/MeshIOAscii.hh" // USES MeshIOAscii #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ---------------------------------------------------------------------- // Setup testing data. @@ -64,10 +64,10 @@ pylith::bc::TestBoundaryMesh::testSubmesh(void) { // testSubmesh // Set up coordinates spatialdata::geocoords::CSCart cs; - spatialdata::units::Nondimensional normalizer; + pylith::scales::Scales scales; cs.setSpaceDim(mesh.getDimension()); mesh.setCoordSys(&cs); - pylith::topology::MeshOps::nondimensionalize(&mesh, normalizer); + pylith::topology::MeshOps::nondimensionalize(&mesh, scales); // Create submesh CPPUNIT_ASSERT(_data->bcLabel); @@ -118,10 +118,10 @@ pylith::bc::TestBoundaryMesh::testSubmeshFault(void) { // testSubmeshFault // Set up coordinates spatialdata::geocoords::CSCart cs; - spatialdata::units::Nondimensional normalizer; + pylith::scales::Scales scales; cs.setSpaceDim(mesh.getDimension()); mesh.setCoordSys(&cs); - pylith::topology::MeshOps::nondimensionalize(&mesh, normalizer); + pylith::topology::MeshOps::nondimensionalize(&mesh, scales); // Adjust topology CPPUNIT_ASSERT(_data->faultLabel); diff --git a/tests/libtests/bc/TestDirichletTimeDependent.cc b/tests/libtests/bc/TestDirichletTimeDependent.cc index 8ec2b1f2ea..f4aab20d19 100644 --- a/tests/libtests/bc/TestDirichletTimeDependent.cc +++ b/tests/libtests/bc/TestDirichletTimeDependent.cc @@ -23,14 +23,14 @@ #include "pylith/topology/Stratum.hh" // USES Stratum #include "pylith/meshio/MeshIOAscii.hh" // USES MeshIOAscii #include "pylith/problems/SolutionFactory.hh" // USES SolutionFactory -#include "pylith/utils/constdefs.h" // USES PYLITH_MAXFLOAT +#include "pylith/utils/constants.hh" // USES PYLITH_MAXFLOAT #include "pylith/utils/error.hh" // USES PYLITH_METHOD_BEGIN/END #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/spatialdb/TimeHistory.hh" // USES TimeHistory -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales const double pylith::bc::TestDirichletTimeDependent::FILL_VALUE = -999.0; @@ -214,21 +214,21 @@ pylith::bc::TestDirichletTimeDependent::testAuxFieldDB(void) { // ---------------------------------------------------------------------- -// Test normalizer(). +// Test scales(). void -pylith::bc::TestDirichletTimeDependent::testNormalizer(void) { +pylith::bc::TestDirichletTimeDependent::testScales(void) { PYLITH_METHOD_BEGIN; - spatialdata::units::Nondimensional normalizer; - const double scale = 5.0; - normalizer.setLengthScale(scale); + pylith::scales::Scales scales; + const double scale = 4.0; + scales.setLengthScale(scale); CPPUNIT_ASSERT(_bc); - _bc->normalizer(normalizer); - CPPUNIT_ASSERT_EQUAL(scale, _bc->_normalizer->getLengthScale()); + _bc->scales(scales); + CPPUNIT_ASSERT_EQUAL(scale, _bc->_scales->getLengthScale()); PYLITH_METHOD_END; -} // testNormalizer +} // testScales // ---------------------------------------------------------------------- @@ -300,8 +300,8 @@ pylith::bc::TestDirichletTimeDependent::testInitialize(void) { const PetscDM dm = auxField->dmMesh();CPPUNIT_ASSERT(dm); pylith::topology::FieldQuery query(*auxField); query.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(_data->normalizer); - query.openDB(_data->auxDB, _data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(_data->scales); + query.openDB(_data->auxDB, _data->scales->getLengthScale()); err = DMPlexComputeL2DiffLocal(dm, t, query.functions(), (void**)query.contextPtrs(), auxField->localVector(), &norm);CPPUNIT_ASSERT(!err); query.closeDB(_data->auxDB); const PylithReal tolerance = 1.0e-6; @@ -344,8 +344,8 @@ pylith::bc::TestDirichletTimeDependent::testPrestep(void) { const PetscDM dm = auxField->dmMesh();CPPUNIT_ASSERT(dm); pylith::topology::FieldQuery query(valueField); query.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(_data->normalizer); - query.openDB(_data->auxDB, _data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(_data->scales); + query.openDB(_data->auxDB, _data->scales->getLengthScale()); PetscErrorCode err = DMPlexComputeL2DiffLocal(dm, t, query.functions(), (void**)query.contextPtrs(), valueField.localVector(), &norm);CPPUNIT_ASSERT(!err); query.closeDB(_data->auxDB); const PylithReal tolerance = 1.0e-6; @@ -398,8 +398,8 @@ pylith::bc::TestDirichletTimeDependent::testSetSolution(void) { const PetscDM dmSoln = _solution->dmMesh();CPPUNIT_ASSERT(dmSoln); pylith::topology::FieldQuery query(*_solution); query.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(_data->normalizer); - query.openDB(_data->solnDB, _data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(_data->scales); + query.openDB(_data->solnDB, _data->scales->getLengthScale()); err = DMProjectFunction(dmSoln, t, query.functions(), (void**)query.contextPtrs(), INSERT_VALUES, _solution->scatterVector("global"));CPPUNIT_ASSERT(!err); query.closeDB(_data->solnDB); _solution->scatterContextToLocal("global", INSERT_VALUES); @@ -413,7 +413,7 @@ pylith::bc::TestDirichletTimeDependent::testSetSolution(void) { #endif // :DEBUG: PylithReal norm = 0.0; - query.openDB(_data->solnDB, _data->normalizer->getLengthScale()); + query.openDB(_data->solnDB, _data->scales->getLengthScale()); err = DMPlexComputeL2DiffLocal(dmSoln, t, query.functions(), (void**)query.contextPtrs(), _solution->localVector(), &norm);CPPUNIT_ASSERT(!err); query.closeDB(_data->solnDB); CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, norm, tolerance); @@ -435,8 +435,8 @@ pylith::bc::TestDirichletTimeDependent::testAuxFieldSetup(void) { CPPUNIT_ASSERT(_solution); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_data); - CPPUNIT_ASSERT(_data->normalizer); - const PylithReal timeScale = _data->normalizer->getTimeScale(); + CPPUNIT_ASSERT(_data->scales); + const PylithReal timeScale = _data->scales->getTimeScale(); delete _bc->_boundaryMesh;_bc->_boundaryMesh = new pylith::topology::Mesh(_solution->mesh(), _data->bcLabel); CPPUNIT_ASSERT(_bc->_boundaryMesh); @@ -575,14 +575,14 @@ pylith::bc::TestDirichletTimeDependent::_initialize(void) { iohandler.filename(_data->meshFilename); iohandler.read(_mesh); _mesh->setCoordSys(_data->cs); - CPPUNIT_ASSERT(_data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->normalizer); + CPPUNIT_ASSERT(_data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->scales); _bc->setLabel(_data->bcLabel); _bc->field(_data->field); _bc->auxFieldDB(_data->auxDB); _bc->constrainedDOF(_data->constrainedDOF, _data->numConstrainedDOF); - _bc->normalizer(*_data->normalizer); + _bc->scales(*_data->scales); for (int ifield = 0; ifield < _data->numAuxSubfields; ++ifield) { const pylith::topology::Field::Discretization& discretization = _data->auxDiscretizations[ifield]; const char* name = _data->auxSubfields[ifield]; @@ -610,10 +610,10 @@ pylith::bc::TestDirichletTimeDependent::_setupSolutionField(void) { CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_data); - CPPUNIT_ASSERT(_data->normalizer); + CPPUNIT_ASSERT(_data->scales); delete _solution;_solution = new pylith::topology::Field(*_mesh); - pylith::problems::SolutionFactory factory(*_solution, *_data->normalizer); + pylith::problems::SolutionFactory factory(*_solution, *_data->scales); factory.displacement(_data->solnDiscretizations[0]); factory.velocity(_data->solnDiscretizations[1]); factory.fluidPressure(_data->solnDiscretizations[2]); @@ -629,7 +629,7 @@ pylith::bc::TestDirichletTimeDependent_Data::TestDirichletTimeDependent_Data(voi meshFilename(NULL), bcLabel(NULL), cs(NULL), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), field(NULL), vectorFieldType(pylith::topology::Field::OTHER), numConstrainedDOF(0), @@ -653,7 +653,7 @@ pylith::bc::TestDirichletTimeDependent_Data::TestDirichletTimeDependent_Data(voi // Destructor pylith::bc::TestDirichletTimeDependent_Data::~TestDirichletTimeDependent_Data(void) { delete cs;cs = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; delete auxDB;auxDB = NULL; delete solnDB;solnDB = NULL; } // destructor diff --git a/tests/libtests/bc/TestDirichletTimeDependent.hh b/tests/libtests/bc/TestDirichletTimeDependent.hh index 0e809a3d76..693779d61e 100644 --- a/tests/libtests/bc/TestDirichletTimeDependent.hh +++ b/tests/libtests/bc/TestDirichletTimeDependent.hh @@ -27,7 +27,7 @@ #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA UserFunctionDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA CoordSys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales /// Namespace for pylith package namespace pylith { @@ -46,7 +46,7 @@ class pylith::bc::TestDirichletTimeDependent : public CppUnit::TestFixture, publ CPPUNIT_TEST(testAccessors); CPPUNIT_TEST(testAuxFieldDiscretization); CPPUNIT_TEST(testAuxFieldDB); - CPPUNIT_TEST(testNormalizer); + CPPUNIT_TEST(testScales); CPPUNIT_TEST(testVerifyConfiguration); CPPUNIT_TEST(testInitialize); CPPUNIT_TEST(testPrestep); @@ -76,8 +76,8 @@ public: /// Test auxFieldDB(). void testAuxFieldDB(void); - /// Test normalizer(). - void testNormalizer(void); + /// Test scales(). + void testScales(void); /// Test verifyConfiguration(). void testVerifyConfiguration(void); @@ -134,7 +134,7 @@ public: const char* bcLabel; ///< Label defining cells associated with material. spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. const char* field; ///< Name of solution field constrained. pylith::topology::FieldBase::VectorFieldEnum vectorFieldType; ///< Vector field type for constrained field. diff --git a/tests/libtests/bc/TestDirichletTimeDependent_Cases.cc b/tests/libtests/bc/TestDirichletTimeDependent_Cases.cc index de70437b25..1593e3c194 100644 --- a/tests/libtests/bc/TestDirichletTimeDependent_Cases.cc +++ b/tests/libtests/bc/TestDirichletTimeDependent_Cases.cc @@ -15,7 +15,7 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ---------------------------------------------------------------------- namespace pylith { @@ -59,15 +59,14 @@ namespace pylith { _data->cs = new spatialdata::geocoords::CSCart();CPPUNIT_ASSERT(_data->cs); _data->cs->setSpaceDim(2); - CPPUNIT_ASSERT(_data->normalizer); - _data->normalizer->setLengthScale(1000.0); - _data->normalizer->setTimeScale(10.0); - _data->normalizer->setPressureScale(0.1); - _data->normalizer->setDensityScale(2.0); + CPPUNIT_ASSERT(_data->scales); + _data->scales->setLengthScale(1.0); + _data->scales->setTimeScale(10.0); + _data->scales->setRigidityScale(3.0e+6); _data->field = "displacement"; _data->vectorFieldType = pylith::topology::Field::VECTOR; - _data->scale = _data->normalizer->getLengthScale(); + _data->scale = _data->scales->getDisplacementScale(); _data->numConstrainedDOF = 1; static const int constrainedDOF[1] = { 1 }; _data->constrainedDOF = const_cast(constrainedDOF); diff --git a/tests/libtests/bc/TestNeumannTimeDependent.cc b/tests/libtests/bc/TestNeumannTimeDependent.cc index 84a99115ee..615a285b21 100644 --- a/tests/libtests/bc/TestNeumannTimeDependent.cc +++ b/tests/libtests/bc/TestNeumannTimeDependent.cc @@ -28,7 +28,7 @@ #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/spatialdb/TimeHistory.hh" // USES TimeHistory -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales const double pylith::bc::TestNeumannTimeDependent::FILL_VALUE = -999.0; @@ -202,21 +202,21 @@ pylith::bc::TestNeumannTimeDependent::testAuxFieldDB(void) { // ---------------------------------------------------------------------- -// Test normalizer(). +// Test scales(). void -pylith::bc::TestNeumannTimeDependent::testNormalizer(void) { +pylith::bc::TestNeumannTimeDependent::testScales(void) { PYLITH_METHOD_BEGIN; - spatialdata::units::Nondimensional normalizer; + pylith::scales::Scales scales; const double scale = 5.0; - normalizer.setLengthScale(scale); + scales.setLengthScale(scale); CPPUNIT_ASSERT(_bc); - _bc->normalizer(normalizer); - CPPUNIT_ASSERT_EQUAL(scale, _bc->_normalizer->getLengthScale()); + _bc->scales(scales); + CPPUNIT_ASSERT_EQUAL(scale, _bc->_scales->getLengthScale()); PYLITH_METHOD_END; -} // testNormalizer +} // testScales // ---------------------------------------------------------------------- @@ -271,8 +271,8 @@ pylith::bc::TestNeumannTimeDependent::testInitialize(void) { const PetscDM dm = auxField->dmMesh();CPPUNIT_ASSERT(dm); pylith::topology::FieldQuery query(*auxField); query.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(_data->normalizer); - query.openDB(_data->auxDB, _data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(_data->scales); + query.openDB(_data->auxDB, _data->scales->getLengthScale()); PetscErrorCode err = DMPlexComputeL2DiffLocal(dm, t, query.functions(), (void**)query.contextPtrs(), auxField->localVector(), &norm);CPPUNIT_ASSERT(!err); query.closeDB(_data->auxDB); const PylithReal tolerance = 1.0e-6; @@ -310,8 +310,8 @@ pylith::bc::TestNeumannTimeDependent::testPrestep(void) { const PetscDM dm = auxField->dmMesh();CPPUNIT_ASSERT(dm); pylith::topology::FieldQuery query(valueField); query.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(_data->normalizer); - query.openDB(_data->auxDB, _data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(_data->scales); + query.openDB(_data->auxDB, _data->scales->getLengthScale()); PetscErrorCode err = DMPlexComputeL2DiffLocal(dm, t, query.functions(), (void**)query.contextPtrs(), valueField.localVector(), &norm);CPPUNIT_ASSERT(!err); query.closeDB(_data->auxDB); const PylithReal tolerance = 1.0e-6; @@ -397,8 +397,8 @@ pylith::bc::TestNeumannTimeDependent::testAuxFieldSetup(void) { CPPUNIT_ASSERT(_solution); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_data); - CPPUNIT_ASSERT(_data->normalizer); - const PylithReal timeScale = _data->normalizer->getTimeScale(); + CPPUNIT_ASSERT(_data->scales); + const PylithReal timeScale = _data->scales->getTimeScale(); delete _bc->_boundaryMesh;_bc->_boundaryMesh = new pylith::topology::Mesh(_solution->mesh(), _data->bcLabel); CPPUNIT_ASSERT(_bc->_boundaryMesh); @@ -537,13 +537,13 @@ pylith::bc::TestNeumannTimeDependent::_initialize(void) { iohandler.filename(_data->meshFilename); iohandler.read(_mesh); _mesh->setCoordSys(_data->cs); - CPPUNIT_ASSERT(_data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->normalizer); + CPPUNIT_ASSERT(_data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->scales); _bc->setLabel(_data->bcLabel); _bc->field(_data->field); _bc->auxFieldDB(_data->auxDB); - _bc->normalizer(*_data->normalizer); + _bc->scales(*_data->scales); for (int ifield = 0; ifield < _data->numAuxSubfields; ++ifield) { const pylith::topology::Field::Discretization& discretization = _data->auxDiscretizations[ifield]; const char* name = _data->auxSubfields[ifield]; @@ -571,11 +571,11 @@ pylith::bc::TestNeumannTimeDependent::_setupSolutionField(void) { CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_data); - CPPUNIT_ASSERT(_data->normalizer); + CPPUNIT_ASSERT(_data->scales); delete _solution;_solution = new pylith::topology::Field(*_mesh); _solution->setLabel("Solution (displacement, velocity, pressure)"); - pylith::problems::SolutionFactory factory(*_solution, *_data->normalizer); + pylith::problems::SolutionFactory factory(*_solution, *_data->scales); factory.displacement(_data->solnDiscretizations[0]); factory.velocity(_data->solnDiscretizations[1]); factory.fluidPressure(_data->solnDiscretizations[2]); @@ -590,7 +590,7 @@ pylith::bc::TestNeumannTimeDependent::_setupSolutionField(void) { pylith::bc::TestNeumannTimeDependent_Data::TestNeumannTimeDependent_Data(void) : meshFilename(NULL), bcLabel(NULL), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), field(NULL), vectorFieldType(pylith::topology::Field::OTHER), useInitial(false), @@ -611,7 +611,7 @@ pylith::bc::TestNeumannTimeDependent_Data::TestNeumannTimeDependent_Data(void) : // Destructor pylith::bc::TestNeumannTimeDependent_Data::~TestNeumannTimeDependent_Data(void) { delete cs;cs = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; delete auxDB;auxDB = NULL; delete solnDB;solnDB = NULL; } // destructor diff --git a/tests/libtests/bc/TestNeumannTimeDependent.hh b/tests/libtests/bc/TestNeumannTimeDependent.hh index 8fd559b353..c49779e0ca 100644 --- a/tests/libtests/bc/TestNeumannTimeDependent.hh +++ b/tests/libtests/bc/TestNeumannTimeDependent.hh @@ -26,7 +26,7 @@ #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA UserFunctionDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA CoordSys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales /// Namespace for pylith package namespace pylith { @@ -46,7 +46,7 @@ class pylith::bc::TestNeumannTimeDependent : public CppUnit::TestFixture { CPPUNIT_TEST(testAccessors); CPPUNIT_TEST(testAuxFieldDiscretization); CPPUNIT_TEST(testAuxFieldDB); - CPPUNIT_TEST(testNormalizer); + CPPUNIT_TEST(testScales); CPPUNIT_TEST(testVerifyConfiguration); CPPUNIT_TEST(testInitialize); CPPUNIT_TEST(testPrestep); @@ -76,8 +76,8 @@ public: /// Test auxFieldDB(). void testAuxFieldDB(void); - /// Test normalizer(). - void testNormalizer(void); + /// Test scales(). + void testScales(void); /// Test verifyConfiguration(). void testVerifyConfiguration(void); @@ -134,7 +134,7 @@ public: const char* bcLabel; ///< Label defining cells associated with material. spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. const char* field; ///< Name of solution field constrained. pylith::topology::FieldBase::VectorFieldEnum vectorFieldType; ///< Vector field type for constrained field. diff --git a/tests/libtests/bc/TestNeumannTimeDependent_Cases.cc b/tests/libtests/bc/TestNeumannTimeDependent_Cases.cc index 563d498a99..2bd61e858c 100644 --- a/tests/libtests/bc/TestNeumannTimeDependent_Cases.cc +++ b/tests/libtests/bc/TestNeumannTimeDependent_Cases.cc @@ -15,7 +15,7 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ---------------------------------------------------------------------- namespace pylith { @@ -87,15 +87,14 @@ namespace pylith { _data->cs = new spatialdata::geocoords::CSCart();CPPUNIT_ASSERT(_data->cs); _data->cs->setSpaceDim(2); - CPPUNIT_ASSERT(_data->normalizer); - _data->normalizer->setLengthScale(1000.0); - _data->normalizer->setTimeScale(10.0); - _data->normalizer->setPressureScale(0.1); - _data->normalizer->setDensityScale(2.0); + CPPUNIT_ASSERT(_data->scales); + _data->scales->setLengthScale(1.0); + _data->scales->setTimeScale(10.0); + _data->scales->setRigidityScale(2.0e+6); _data->field = "displacement"; _data->vectorFieldType = pylith::topology::Field::VECTOR; - _data->scale = _data->normalizer->getPressureScale(); + _data->scale = _data->scales->getRigidityScale(); _data->useInitial = true; _data->useRate = false; diff --git a/tests/libtests/bc/data/AbsorbingDampersData.cc b/tests/libtests/bc/data/AbsorbingDampersData.cc index 80e8f61682..cf83e45df2 100644 --- a/tests/libtests/bc/data/AbsorbingDampersData.cc +++ b/tests/libtests/bc/data/AbsorbingDampersData.cc @@ -14,9 +14,8 @@ // Constructor pylith::bc::AbsorbingDampersData::AbsorbingDampersData(void) : meshFilename(0), - setLengthScale(1.0e+3), - setPressureScale(2.25e+10), - setDensityScale(1.0), + setLengthScale(1.0), + setRigidityScale(2.0e+6), setTimeScale(2.0), numBasis(0), numQuadPts(0), @@ -41,7 +40,7 @@ pylith::bc::AbsorbingDampersData::AbsorbingDampersData(void) : valsResidual(0), valsJacobian(0) { // constructor const PylithScalar velScale = lengthScale / timeScale; - densityScale = pressureScale / (velScale*velScale); + densityScale = rigidityScale / (velScale*velScale); } // constructor diff --git a/tests/libtests/bc/data/AbsorbingDampersData.hh b/tests/libtests/bc/data/AbsorbingDampersData.hh index 5ccf407bca..6ccc4c3b8e 100644 --- a/tests/libtests/bc/data/AbsorbingDampersData.hh +++ b/tests/libtests/bc/data/AbsorbingDampersData.hh @@ -35,7 +35,7 @@ public: /// @name Scales information for nondimensionalization. //@{ PylithScalar lengthScale; ///< Length scale. - PylithScalar pressureScale; ///< Pressure scale. + PylithScalar rigidityScale; ///< Pressure scale. PylithScalar timeScale; ///< Time scale. PylithScalar densityScale; ///< Density scale. //@} diff --git a/tests/libtests/bc/data/DirichletData.cc b/tests/libtests/bc/data/DirichletData.cc index f6aaa6a5d2..78e6caae97 100644 --- a/tests/libtests/bc/data/DirichletData.cc +++ b/tests/libtests/bc/data/DirichletData.cc @@ -25,12 +25,11 @@ pylith::bc::DirichletData::DirichletData(void) : valuesInitial(0), meshFilename(0), dbFilename(0), - setLengthScale(1.0e+3), - setPressureScale(2.25e+10), - setDensityScale(1.0), - setTimeScale(2.0) { // constructor + setLengthScale(1.0), + setRigidityScale(2.0e+6), + setTimeScale(2.0) { const PylithScalar velScale = lengthScale / timeScale; - densityScale = pressureScale / (velScale*velScale); + densityScale = rigidityScale / (velScale*velScale); } // constructor diff --git a/tests/libtests/bc/data/DirichletData.hh b/tests/libtests/bc/data/DirichletData.hh index 696abb7330..c18c360db5 100644 --- a/tests/libtests/bc/data/DirichletData.hh +++ b/tests/libtests/bc/data/DirichletData.hh @@ -50,7 +50,7 @@ public: /// @name Scales information for nondimensionalization. //@{ PylithScalar lengthScale; ///< Length scale. - PylithScalar pressureScale; ///< Pressure scale. + PylithScalar rigidityScale; ///< Pressure scale. PylithScalar timeScale; ///< Time scale. PylithScalar densityScale; ///< Density scale. //@} diff --git a/tests/libtests/bc/data/DirichletDataMulti.cc b/tests/libtests/bc/data/DirichletDataMulti.cc index 94257ab73d..37b2053838 100644 --- a/tests/libtests/bc/data/DirichletDataMulti.cc +++ b/tests/libtests/bc/data/DirichletDataMulti.cc @@ -46,12 +46,11 @@ pylith::bc::DirichletDataMulti::DirichletDataMulti(void) : constraintSizes(0), constrainedDOF(0), meshFilename(0), - setLengthScale(1.0e+3), - setPressureScale(2.25e+10), - setDensityScale(1.0), - setTimeScale(2.0) { // constructor + setLengthScale(1.0), + setRigidityScale(2.0e+6), + setTimeScale(2.0) { const PylithScalar velScale = lengthScale / timeScale; - densityScale = pressureScale / (velScale*velScale); + densityScale = rigidityScale / (velScale*velScale); } // constructor diff --git a/tests/libtests/bc/data/DirichletDataMulti.hh b/tests/libtests/bc/data/DirichletDataMulti.hh index e44c07bc6e..a29b62c28a 100644 --- a/tests/libtests/bc/data/DirichletDataMulti.hh +++ b/tests/libtests/bc/data/DirichletDataMulti.hh @@ -78,7 +78,7 @@ public: /// @name Scales information for nondimensionalization. //@{ PylithScalar lengthScale; ///< Length scale. - PylithScalar pressureScale; ///< Pressure scale. + PylithScalar rigidityScale; ///< Pressure scale. PylithScalar timeScale; ///< Time scale. PylithScalar densityScale; ///< Density scale. //@} diff --git a/tests/libtests/bc/data/NeumannData.cc b/tests/libtests/bc/data/NeumannData.cc index 444ca63aa4..a411e67fd1 100644 --- a/tests/libtests/bc/data/NeumannData.cc +++ b/tests/libtests/bc/data/NeumannData.cc @@ -14,9 +14,8 @@ // Constructor pylith::bc::NeumannData::NeumannData(void) : meshFilename(0), - setLengthScale(1.0e+3), - setPressureScale(2.25e+10), - setDensityScale(1.0), + setLengthScale(1.0), + setRigidityScale(2.0e+6), setTimeScale(2.0), numBasis(0), numQuadPts(0), @@ -36,7 +35,7 @@ pylith::bc::NeumannData::NeumannData(void) : tractionsCell(0), valsResidual(0) { // constructor const PylithScalar velScale = lengthScale / timeScale; - densityScale = pressureScale / (velScale*velScale); + densityScale = rigidityScale / (velScale*velScale); } // constructor diff --git a/tests/libtests/bc/data/NeumannData.hh b/tests/libtests/bc/data/NeumannData.hh index 59c25230e0..b4f0d498cd 100644 --- a/tests/libtests/bc/data/NeumannData.hh +++ b/tests/libtests/bc/data/NeumannData.hh @@ -35,7 +35,7 @@ public: /// @name Scales information for nondimensionalization. //@{ PylithScalar lengthScale; ///< Length scale. - PylithScalar pressureScale; ///< Pressure scale. + PylithScalar rigidityScale; ///< Pressure scale. PylithScalar timeScale; ///< Time scale. PylithScalar densityScale; ///< Density scale. //@} diff --git a/tests/libtests/bc/data/PointForceData.cc b/tests/libtests/bc/data/PointForceData.cc index 3317ae233e..8220282aa7 100644 --- a/tests/libtests/bc/data/PointForceData.cc +++ b/tests/libtests/bc/data/PointForceData.cc @@ -27,12 +27,11 @@ pylith::bc::PointForceData::PointForceData(void) : residual(0), meshFilename(0), dbFilename(0), - setLengthScale(1.0e+3), - setPressureScale(2.25e+10), - setDensityScale(1.0), + setLengthScale(1.0), + setRigidityScale(2.0e+6), setTimeScale(2.0) { // constructor const PylithScalar velScale = lengthScale / timeScale; - densityScale = pressureScale / (velScale*velScale); + densityScale = rigidityScale / (velScale*velScale); } // constructor diff --git a/tests/libtests/bc/data/PointForceData.hh b/tests/libtests/bc/data/PointForceData.hh index 9ecd179d6d..1c4a55e995 100644 --- a/tests/libtests/bc/data/PointForceData.hh +++ b/tests/libtests/bc/data/PointForceData.hh @@ -52,7 +52,7 @@ public: /// @name Scales information for nondimensionalization. //@{ PylithScalar lengthScale; ///< Length scale. - PylithScalar pressureScale; ///< Pressure scale. + PylithScalar rigidityScale; ///< Pressure scale. PylithScalar timeScale; ///< Time scale. PylithScalar densityScale; ///< Density scale. //@} diff --git a/tests/libtests/faults/TestAdjustTopology.cc b/tests/libtests/faults/TestAdjustTopology.cc index c41a684751..78faa8c80d 100644 --- a/tests/libtests/faults/TestAdjustTopology.cc +++ b/tests/libtests/faults/TestAdjustTopology.cc @@ -23,7 +23,7 @@ #include "pylith/utils/journals.hh" // USES journals #include "pylith/meshio/MeshIOAscii.hh" // USES MeshIOAscii -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "spatialdata/geocoords/CSCart.hh" // USES CSCart #include "catch2/catch_test_macros.hpp" diff --git a/tests/libtests/faults/data/CohesiveDynData.cc b/tests/libtests/faults/data/CohesiveDynData.cc index b54a33221f..4cc6be98c9 100644 --- a/tests/libtests/faults/data/CohesiveDynData.cc +++ b/tests/libtests/faults/data/CohesiveDynData.cc @@ -14,9 +14,8 @@ // Constructor pylith::faults::CohesiveDynData::CohesiveDynData(void) : meshFilename(0), - setLengthScale(1.0e+3), - setPressureScale(2.25e+10), - setDensityScale(1.0), + setLengthScale(1.0), + setRigidityScale(2.0e+6), setTimeScale(2.0), spaceDim(0), cellDim(0), @@ -46,7 +45,7 @@ pylith::faults::CohesiveDynData::CohesiveDynData(void) : constraintEdges(0), numConstraintEdges(0) { // constructor const PylithScalar velScale = lengthScale / timeScale; - densityScale = pressureScale / (velScale*velScale); + densityScale = rigidityScale / (velScale*velScale); } // constructor diff --git a/tests/libtests/faults/data/CohesiveDynData.hh b/tests/libtests/faults/data/CohesiveDynData.hh index 2b09963a75..22ddc4d771 100644 --- a/tests/libtests/faults/data/CohesiveDynData.hh +++ b/tests/libtests/faults/data/CohesiveDynData.hh @@ -35,7 +35,7 @@ public: /// @name Scales information for nondimensionalization. //@{ PylithScalar lengthScale; ///< Length scale. - PylithScalar pressureScale; ///< Pressure scale. + PylithScalar rigidityScale; ///< Pressure scale. PylithScalar timeScale; ///< Time scale. PylithScalar densityScale; ///< Density scale. //@} diff --git a/tests/libtests/faults/data/CohesiveImpulsesData.cc b/tests/libtests/faults/data/CohesiveImpulsesData.cc index 96d4fbfa55..ad24b60f51 100644 --- a/tests/libtests/faults/data/CohesiveImpulsesData.cc +++ b/tests/libtests/faults/data/CohesiveImpulsesData.cc @@ -14,9 +14,8 @@ // Constructor pylith::faults::CohesiveImpulsesData::CohesiveImpulsesData(void) : meshFilename(0), - setLengthScale(1.0e+3), - setPressureScale(2.25e+10), - setDensityScale(1.0), + setLengthScale(1.0), + setRigidityScale(2.5e+6), setTimeScale(2.0), spaceDim(0), cellDim(0), @@ -42,7 +41,7 @@ pylith::faults::CohesiveImpulsesData::CohesiveImpulsesData(void) : constraintEdges(0), numConstraintEdges(0) { // constructor const PylithScalar velScale = lengthScale / timeScale; - densityScale = pressureScale / (velScale*velScale); + densityScale = rigidityScale / (velScale*velScale); } // constructor diff --git a/tests/libtests/faults/data/CohesiveImpulsesData.hh b/tests/libtests/faults/data/CohesiveImpulsesData.hh index 3de1e74645..576a249be0 100644 --- a/tests/libtests/faults/data/CohesiveImpulsesData.hh +++ b/tests/libtests/faults/data/CohesiveImpulsesData.hh @@ -35,7 +35,7 @@ public: /// @name Scales information for nondimensionalization. //@{ PylithScalar lengthScale; ///< Length scale. - PylithScalar pressureScale; ///< Pressure scale. + PylithScalar rigidityScale; ///< Pressure scale. PylithScalar timeScale; ///< Time scale. PylithScalar densityScale; ///< Density scale. //@} diff --git a/tests/libtests/faults/data/CohesiveKinData.cc b/tests/libtests/faults/data/CohesiveKinData.cc index a1ee82a463..4319f3f97c 100644 --- a/tests/libtests/faults/data/CohesiveKinData.cc +++ b/tests/libtests/faults/data/CohesiveKinData.cc @@ -14,9 +14,8 @@ // Constructor pylith::faults::CohesiveKinData::CohesiveKinData(void) : meshFilename(0), - setLengthScale(1.0e+3), - setPressureScale(2.25e+10), - setDensityScale(1.0), + setLengthScale(1.0), + setRigidityScale(2.0e+6), setTimeScale(2.0), spaceDim(0), cellDim(0), @@ -50,7 +49,7 @@ pylith::faults::CohesiveKinData::CohesiveKinData(void) : cellMappingFault(0), cellMappingCohesive(0) { // constructor const PylithScalar velScale = lengthScale / timeScale; - densityScale = pressureScale / (velScale*velScale); + densityScale = rigidityScale / (velScale*velScale); } // constructor diff --git a/tests/libtests/faults/data/CohesiveKinData.hh b/tests/libtests/faults/data/CohesiveKinData.hh index 3022ed5150..1b3f5c4649 100644 --- a/tests/libtests/faults/data/CohesiveKinData.hh +++ b/tests/libtests/faults/data/CohesiveKinData.hh @@ -35,7 +35,7 @@ public: /// @name Scales information for nondimensionalization. //@{ PylithScalar lengthScale; ///< Length scale. - PylithScalar pressureScale; ///< Pressure scale. + PylithScalar rigidityScale; ///< Pressure scale. PylithScalar timeScale; ///< Time scale. PylithScalar densityScale; ///< Density scale. //@} diff --git a/tests/libtests/feassemble/TestAuxiliaryFactory.cc b/tests/libtests/feassemble/TestAuxiliaryFactory.cc index c632052e0d..3c4fc4a584 100644 --- a/tests/libtests/feassemble/TestAuxiliaryFactory.cc +++ b/tests/libtests/feassemble/TestAuxiliaryFactory.cc @@ -22,7 +22,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "catch2/catch_test_macros.hpp" #include "catch2/matchers/catch_matchers_floating_point.hpp" @@ -179,8 +180,8 @@ pylith::feassemble::TestAuxiliaryFactory::testInitialize(void) { pylith::topology::Field field(mesh); const int spaceDim = 2; - spatialdata::units::Nondimensional normalizer; - normalizer.setLengthScale(10.0); + pylith::scales::Scales scales; + scales.setLengthScale(2.0); pylith::topology::Field::Description description; description.label = "displacement"; @@ -189,14 +190,14 @@ pylith::feassemble::TestAuxiliaryFactory::testInitialize(void) { description.numComponents = 1; description.componentNames.resize(1); description.componentNames[0] = "displacement_x"; - description.scale = normalizer.getLengthScale(); + description.scale = scales.getDisplacementScale(); assert(_factory); - _factory->initialize(&field, normalizer, spaceDim, &description); + _factory->initialize(&field, scales, spaceDim, &description); CHECK(&field == _factory->_field); CHECK(spaceDim == _factory->_spaceDim); - CHECK(normalizer.getLengthScale() == _factory->_normalizer->getLengthScale()); + CHECK(scales.getDisplacementScale() == _factory->_scales->getDisplacementScale()); const pylith::topology::Field::Description* descriptionTest = _factory->_defaultDescription; CHECK(description.label == descriptionTest->label); @@ -217,9 +218,8 @@ pylith::feassemble::TestAuxiliaryFactory::testInitialize(void) { void pylith::feassemble::TestAuxiliaryFactory::testSetValuesFromDB(void) { const int spaceDim = 2; - spatialdata::units::Nondimensional normalizer; - normalizer.setLengthScale(10.0); - normalizer.setDensityScale(2.0); + pylith::scales::Scales scales; + scales.setLengthScale(1.5); spatialdata::geocoords::CSCart cs; cs.setSpaceDim(spaceDim); @@ -238,7 +238,7 @@ pylith::feassemble::TestAuxiliaryFactory::testSetValuesFromDB(void) { descriptionDensity.numComponents = 1; descriptionDensity.componentNames.resize(1); descriptionDensity.componentNames[0] = "density"; - descriptionDensity.scale = normalizer.getDensityScale(); + descriptionDensity.scale = pylith::scales::ElasticityScales::getDensityScale(scales); pylith::topology::Field::Description descriptionVelocity; descriptionVelocity.label = "velocity"; @@ -248,7 +248,7 @@ pylith::feassemble::TestAuxiliaryFactory::testSetValuesFromDB(void) { descriptionVelocity.componentNames.resize(2); descriptionVelocity.componentNames[0] = "velocity_x"; descriptionVelocity.componentNames[1] = "velocity_y"; - descriptionVelocity.scale = normalizer.getLengthScale() / normalizer.getTimeScale(); + descriptionVelocity.scale = scales.getLengthScale() / scales.getTimeScale(); pylith::topology::Field::Description subfieldDescriptions[2]; subfieldDescriptions[0] = descriptionDensity; @@ -265,7 +265,7 @@ pylith::feassemble::TestAuxiliaryFactory::testSetValuesFromDB(void) { iohandler.setFilename("data/tri.mesh"); iohandler.read(&mesh); mesh.setCoordSys(&cs); - pylith::topology::MeshOps::nondimensionalize(&mesh, normalizer); + pylith::topology::MeshOps::nondimensionalize(&mesh, scales); assert(pylith::topology::MeshOps::getNumCells(mesh) > 0); assert(pylith::topology::MeshOps::getNumVertices(mesh) > 0); @@ -274,7 +274,7 @@ pylith::feassemble::TestAuxiliaryFactory::testSetValuesFromDB(void) { _factory->setQueryDB(&auxiliaryDB); pylith::topology::Field auxiliaryField(mesh); - _factory->initialize(&auxiliaryField, normalizer, spaceDim); + _factory->initialize(&auxiliaryField, scales, spaceDim); for (int i = 0; i < numSubfields; ++i) { auxiliaryField.subfieldAdd(subfieldDescriptions[i], subfieldDiscretizations[i]); _factory->setSubfieldQuery(subfields[i]); @@ -291,7 +291,7 @@ pylith::feassemble::TestAuxiliaryFactory::testSetValuesFromDB(void) { const PetscDM dmField = auxiliaryField.getDM();assert(dmField); pylith::topology::FieldQuery query(auxiliaryField); query.initializeWithDefaultQueries(); - query.openDB(&auxiliaryDB, normalizer.getLengthScale()); + query.openDB(&auxiliaryDB, scales.getLengthScale()); PetscErrorCode err = DMPlexComputeL2DiffLocal(dmField, t, query._functions, (void**)query._contextPtrs, auxiliaryField.getLocalVector(), &norm);assert(!err); query.closeDB(&auxiliaryDB); diff --git a/tests/libtests/feassemble/TestIntegratorDomain.cc b/tests/libtests/feassemble/TestIntegratorDomain.cc index 407a516bc2..75b9612731 100644 --- a/tests/libtests/feassemble/TestIntegratorDomain.cc +++ b/tests/libtests/feassemble/TestIntegratorDomain.cc @@ -28,7 +28,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // --------------------------------------------------------------------------------------------------------------------- // Setup testing data. @@ -123,8 +123,8 @@ pylith::feassemble::TestIntegratorDomain::testInitialize(void) { CPPUNIT_ASSERT_EQUAL(_data->dimension, auxiliaryField->getSpaceDim()); const PylithReal tolerance = 1.0e-6; - CPPUNIT_ASSERT(_data->normalizer); - const PylithReal lengthScale = _data->normalizer->getLengthScale(); + CPPUNIT_ASSERT(_data->scales); + const PylithReal lengthScale = _data->scales->getLengthScale(); PylithReal norm = pylith::testing::FieldTester::checkFieldWithDB(*auxiliaryField, _data->auxiliaryDB, lengthScale); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Values in auxiliary field do not match spatial database.", 0.0, norm, tolerance); @@ -162,8 +162,8 @@ pylith::feassemble::TestIntegratorDomain::testPoststep(void) { _integrator->poststep(_data->t, _data->tindex, _data->dt, perturbation); const PylithReal tolerance = 1.0e-6; - CPPUNIT_ASSERT(_data->normalizer); - const PylithReal lengthScale = _data->normalizer->getLengthScale(); + CPPUNIT_ASSERT(_data->scales); + const PylithReal lengthScale = _data->scales->getLengthScale(); PylithReal norm = pylith::testing::FieldTester::checkFieldWithDB(*_integrator->getAuxiliaryField(), _data->auxiliaryUpdateDB, lengthScale); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Updated auxiliary field values do not match spatial database.", 0.0, norm, tolerance); @@ -372,8 +372,8 @@ pylith::feassemble::TestIntegratorDomain::_initializeMin(void) { // Setup coordinates. _mesh->setCoordSys(_data->cs); - CPPUNIT_ASSERT(_data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->normalizer); + CPPUNIT_ASSERT(_data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->scales); // Setup solution fields. delete _solutionFields;_solutionFields = new pylith::topology::Fields(*_mesh);CPPUNIT_ASSERT(_solutionFields); @@ -412,11 +412,11 @@ pylith::feassemble::TestIntegratorDomain::_setupSolutionFields(void) { CPPUNIT_ASSERT(_solutionFields); CPPUNIT_ASSERT(_data->solutionDiscretizations); - CPPUNIT_ASSERT(_data->normalizer); + CPPUNIT_ASSERT(_data->scales); { // Solution pylith::topology::Field& solution = _solutionFields->get("solution"); - pylith::problems::SolutionFactory factory(solution, *_data->normalizer); + pylith::problems::SolutionFactory factory(solution, *_data->scales); factory.displacement(_data->solutionDiscretizations[0]); if (_data->isExplicit) { factory.velocity(_data->solutionDiscretizations[1]); @@ -429,7 +429,7 @@ pylith::feassemble::TestIntegratorDomain::_setupSolutionFields(void) { { // Time derivative of solution pylith::topology::Field& solutionDot = _solutionFields->get("solution_dot"); - pylith::problems::SolutionFactory factory(solutionDot, *_data->normalizer); + pylith::problems::SolutionFactory factory(solutionDot, *_data->scales); factory.displacementDot(_data->solutionDiscretizations[0]); if (_data->isExplicit) { factory.velocityDot(_data->solutionDiscretizations[1]); @@ -447,7 +447,7 @@ pylith::feassemble::TestIntegratorDomain::_setupSolutionFields(void) { perturbation.createDiscretization(); perturbation.allocate(); perturbation.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbation, *_data->normalizer); + pylith::problems::SolutionFactory factory(perturbation, *_data->scales); factory.setValues(_data->perturbationDB); } // Perturbation @@ -458,7 +458,7 @@ pylith::feassemble::TestIntegratorDomain::_setupSolutionFields(void) { perturbationDot.createDiscretization(); perturbationDot.allocate(); perturbationDot.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbationDot, *_data->normalizer); + pylith::problems::SolutionFactory factory(perturbationDot, *_data->scales); factory.setValues(_data->perturbationDB); } // Time derivative perturbation @@ -519,7 +519,7 @@ pylith::feassemble::TestIntegratorDomain_Data::TestIntegratorDomain_Data(void) : materialId(0), cs(NULL), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), t(0.0), dt(0.0), @@ -538,7 +538,7 @@ pylith::feassemble::TestIntegratorDomain_Data::TestIntegratorDomain_Data(void) : auxiliaryUpdateDB(NULL), hasLHSJacobianLumpedInv(false) { - CPPUNIT_ASSERT(normalizer); + CPPUNIT_ASSERT(scales); CPPUNIT_ASSERT(solutionDB); solutionDB->setLabel("solution"); @@ -555,7 +555,7 @@ pylith::feassemble::TestIntegratorDomain_Data::TestIntegratorDomain_Data(void) : // Destructor pylith::feassemble::TestIntegratorDomain_Data::~TestIntegratorDomain_Data(void) { delete cs;cs = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; delete solutionDB;solutionDB = NULL; delete auxiliaryDB;auxiliaryDB = NULL; delete auxiliaryUpdateDB;auxiliaryUpdateDB = NULL; diff --git a/tests/libtests/feassemble/TestIntegratorDomain.hh b/tests/libtests/feassemble/TestIntegratorDomain.hh index 0eaeb7633c..b8daf0dc2f 100644 --- a/tests/libtests/feassemble/TestIntegratorDomain.hh +++ b/tests/libtests/feassemble/TestIntegratorDomain.hh @@ -18,7 +18,7 @@ #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA UserFunctionDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA CoordSys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales /// Namespace for pylith package namespace pylith { @@ -125,7 +125,7 @@ public: PylithInt materialId; ///< Identifier of cells in integration domain. spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. PylithReal t; ///< Time for solution in simulation. PylithReal dt; ///< Time step in simulation. diff --git a/tests/libtests/feassemble/TestIntegratorDomain_UniformStrain.cc b/tests/libtests/feassemble/TestIntegratorDomain_UniformStrain.cc index 5db2fdb164..73db742c3b 100644 --- a/tests/libtests/feassemble/TestIntegratorDomain_UniformStrain.cc +++ b/tests/libtests/feassemble/TestIntegratorDomain_UniformStrain.cc @@ -15,7 +15,7 @@ #include "pylith/feassemble/IntegratorDomain.hh" // USES IntegratorDomain #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // forward declarations namespace pylith { @@ -157,11 +157,10 @@ class pylith::feassemble::TestIntegratorDomain_UniformStrain2D : _data->cs = new spatialdata::spatialdb::CSCart();CPPUNIT_ASSERT(_data->cs); _data->cs->setSpaceDim(_data->dimension); - CPPUNIT_ASSERT(_data->normalizer); - _data->normalizer->setLengthScale(1.0e+03); - _data->normalizer->setTimeScale(2.0); - _data->normalizer->setDensityScale(3.0e+3); - _data->normalizer->setPressureScale(2.25e+10); + CPPUNIT_ASSERT(_data->scales); + _data->scales->setLengthScale(1.0); + _data->scales->setTimeScale(2.0); + _data->scales->setRigidityScale(2.5e+6); _data->t = 1.0; _data->dt = 0.05; diff --git a/tests/libtests/materials/TestAuxiliaryFactoryElasticity.cc b/tests/libtests/materials/TestAuxiliaryFactoryElasticity.cc index 3da08a8a1c..09fd4ab91b 100644 --- a/tests/libtests/materials/TestAuxiliaryFactoryElasticity.cc +++ b/tests/libtests/materials/TestAuxiliaryFactoryElasticity.cc @@ -24,7 +24,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "catch2/catch_test_macros.hpp" @@ -46,7 +47,7 @@ pylith::materials::TestAuxiliaryFactoryElasticity::TestAuxiliaryFactoryElasticit componentNames, componentNames.size(), pylith::topology::Field::SCALAR, - _data->normalizer->getDensityScale(), + pylith::scales::ElasticityScales::getDensityScale(*_data->scales), 0.0, pylith::topology::FieldQuery::validatorPositive ); @@ -67,7 +68,7 @@ pylith::materials::TestAuxiliaryFactoryElasticity::TestAuxiliaryFactoryElasticit componentNames, componentNames.size(), pylith::topology::Field::VECTOR, - _data->normalizer->getPressureScale() / _data->normalizer->getLengthScale() + pylith::scales::ElasticityScales::getBodyForceScale(*_data->scales) ); info.fe = pylith::topology::Field::Discretization( 2, 2, _data->auxDim, _data->auxDim, false, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POLYNOMIAL_SPACE, false @@ -87,7 +88,7 @@ pylith::materials::TestAuxiliaryFactoryElasticity::TestAuxiliaryFactoryElasticit componentNames, componentNames.size(), pylith::topology::Field::VECTOR, - _data->normalizer->getLengthScale() / pow(_data->normalizer->getTimeScale(), 2) + pylith::scales::ElasticityScales::getAccelerationScale(*_data->scales) ); info.fe = pylith::topology::Field::Discretization( 2, 2, _data->auxDim, _data->auxDim, false, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POLYNOMIAL_SPACE, true @@ -134,7 +135,7 @@ pylith::materials::TestAuxiliaryFactoryElasticity::testAdd(void) { assert(_data->gravityField); _factory->addGravityField(_data->gravityField); - assert(_data->normalizer); + assert(_data->scales); pylith::testing::FieldTester::checkSubfieldInfo(*_auxiliaryField, _data->subfields["density"]); pylith::testing::FieldTester::checkSubfieldInfo(*_auxiliaryField, _data->subfields["body_force"]); @@ -161,9 +162,9 @@ pylith::materials::TestAuxiliaryFactoryElasticity::testSetValuesFromDB(void) { _auxiliaryField->allocate(); assert(_data); - assert(_data->normalizer); + assert(_data->scales); _factory->setValuesFromDB(); - pylith::testing::FieldTester::checkFieldWithDB(*_auxiliaryField, _data->auxiliaryDB, _data->normalizer->getLengthScale()); + pylith::testing::FieldTester::checkFieldWithDB(*_auxiliaryField, _data->auxiliaryDB, _data->scales->getLengthScale()); PYLITH_METHOD_END; } // testSetValues @@ -187,8 +188,8 @@ pylith::materials::TestAuxiliaryFactoryElasticity::_initialize(void) { // Setup coordinates. _mesh->setCoordSys(_data->cs); - assert(_data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->normalizer); + assert(_data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->scales); _auxiliaryField = new pylith::topology::Field(*_mesh);assert(_auxiliaryField); _auxiliaryField->setLabel("auxiliary"); @@ -203,8 +204,8 @@ pylith::materials::TestAuxiliaryFactoryElasticity::_initialize(void) { _factory->setSubfieldDiscretization(subfieldName, fe.basisOrder, fe.quadOrder, fe.dimension, fe.isFaultOnly, fe.cellBasis, fe.feSpace, fe.isBasisContinuous); } // for - assert(_data->normalizer); - _factory->initialize(_auxiliaryField, *_data->normalizer, _data->dimension); + assert(_data->scales); + _factory->initialize(_auxiliaryField, *_data->scales, _data->dimension); PYLITH_METHOD_END; } // _initialize @@ -214,7 +215,7 @@ pylith::materials::TestAuxiliaryFactoryElasticity::_initialize(void) { pylith::materials::TestAuxiliaryFactoryElasticity_Data::TestAuxiliaryFactoryElasticity_Data(void) : meshFilename(NULL), cs(NULL), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), auxiliaryDB(new spatialdata::spatialdb::UserFunctionDB), gravityField(new spatialdata::spatialdb::GravityField) {} @@ -222,7 +223,7 @@ pylith::materials::TestAuxiliaryFactoryElasticity_Data::TestAuxiliaryFactoryElas // ------------------------------------------------------------------------------------------------ pylith::materials::TestAuxiliaryFactoryElasticity_Data::~TestAuxiliaryFactoryElasticity_Data(void) { delete cs;cs = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; delete auxiliaryDB;auxiliaryDB = NULL; delete gravityField;gravityField = NULL; } // destructor diff --git a/tests/libtests/materials/TestAuxiliaryFactoryElasticity.hh b/tests/libtests/materials/TestAuxiliaryFactoryElasticity.hh index b0afffe880..29e86c144e 100644 --- a/tests/libtests/materials/TestAuxiliaryFactoryElasticity.hh +++ b/tests/libtests/materials/TestAuxiliaryFactoryElasticity.hh @@ -15,7 +15,7 @@ #include "pylith/topology/Field.hh" // HOLDSA Field::SubfieldInfo #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA SpatialDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA Coordsys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales #include // USES std::map @@ -78,7 +78,7 @@ public: size_t auxDim; ///< Topological dimension of auxiliary field. const char* meshFilename; ///< Name of file with ASCII mesh. spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. std::map subfields; spatialdata::spatialdb::UserFunctionDB* auxiliaryDB; ///< Spatial database with values for solution. diff --git a/tests/libtests/materials/TestAuxiliaryFactoryElasticity_Cases.cc b/tests/libtests/materials/TestAuxiliaryFactoryElasticity_Cases.cc index df84bc7ce1..2529f511a8 100644 --- a/tests/libtests/materials/TestAuxiliaryFactoryElasticity_Cases.cc +++ b/tests/libtests/materials/TestAuxiliaryFactoryElasticity_Cases.cc @@ -13,10 +13,11 @@ #include "TestAuxiliaryFactoryElasticity.hh" // Implementation of cases #include "pylith/materials/AuxiliaryFactoryElasticity.hh" // USES AuxiliaryFactoryElasticity +#include "pylith/utils/constants.hh" // USES pylith::g_acc #include "spatialdata/geocoords/CSCart.hh" // USES CSCart #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" @@ -42,22 +43,23 @@ class pylith::materials::TestAuxiliaryFactoryElasticity_Cases { static const PylithReal LENGTH_SCALE; static const PylithReal TIME_SCALE; - static const PylithReal PRESSURE_SCALE; + static const PylithReal RIGIDITY_SCALE; static const PylithReal DENSITY_SCALE; + static const PylithReal KM; private: static double density_2d(const double x, const double y) { - return 2500.0 + 3.0*fabs(x)/LENGTH_SCALE + 2.0*fabs(y)/LENGTH_SCALE; + return 2500.0 + 3.0*fabs(x)/KM + 2.0*fabs(y)/KM; } // density static double density_3d(const double x, const double y, const double z) { - return 2500.0 + 3.0*fabs(x) + 2.0*fabs(y)/LENGTH_SCALE + 1.1*fabs(z)/LENGTH_SCALE; + return 2500.0 + 3.0*fabs(x) + 2.0*fabs(y)/KM + 1.1*fabs(z)/KM; } // density static @@ -68,34 +70,34 @@ class pylith::materials::TestAuxiliaryFactoryElasticity_Cases { static double body_force_2d_x(const double x, const double y) { - return -0.3*x*y/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*y/(KM*KM) + 0.2*y*y/(KM*KM); } // body_force_x static double body_force_2d_y(const double x, const double y) { - return +0.3*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*x*y/(LENGTH_SCALE*LENGTH_SCALE); + return +0.3*x*x/(KM*KM) + 0.2*x*y/(KM*KM); } // body_force_y static double body_force_3d_x(const double x, const double y, const double z) { - return -0.3*x*y/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*y/(KM*KM) + 0.2*y*y/(KM*KM); } // body_force_x static double body_force_3d_y(const double x, const double y, const double z) { - return +0.3*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*x*y/(LENGTH_SCALE*LENGTH_SCALE); + return +0.3*x*x/(KM*KM) + 0.2*x*y/(KM*KM); } // body_force_y static double body_force_3d_z(const double x, const double y, const double z) { - return +0.3*x*y/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*x*z/(LENGTH_SCALE*LENGTH_SCALE); + return +0.3*x*y/(KM*KM) + 0.2*x*z/(KM*KM); } // body_force_z static @@ -112,7 +114,7 @@ class pylith::materials::TestAuxiliaryFactoryElasticity_Cases { static double gravity_field_2d_y(const double x, const double y) { - return -9.80665; + return -pylith::g_acc; } // gravity_field_y static @@ -133,7 +135,7 @@ class pylith::materials::TestAuxiliaryFactoryElasticity_Cases { double gravity_field_3d_z(const double x, const double y, const double z) { - return -9.80665; + return -pylith::g_acc; } // gravity_field_z static @@ -158,10 +160,10 @@ TEST_CASE("TestAuxiliaryFactoryElasticity::Hex::testSetValuesFromDB", "[TestAuxi pylith::materials::TestAuxiliaryFactoryElasticity(pylith::materials::TestAuxiliaryFactoryElasticity_Cases::Hex()).testSetValuesFromDB(); } -const PylithReal pylith::materials::TestAuxiliaryFactoryElasticity_Cases::LENGTH_SCALE = 1.0e+3; +const PylithReal pylith::materials::TestAuxiliaryFactoryElasticity_Cases::LENGTH_SCALE = 1.0; const PylithReal pylith::materials::TestAuxiliaryFactoryElasticity_Cases::TIME_SCALE = 2.0; -const PylithReal pylith::materials::TestAuxiliaryFactoryElasticity_Cases::PRESSURE_SCALE = 2.0e+10; -const PylithReal pylith::materials::TestAuxiliaryFactoryElasticity_Cases::DENSITY_SCALE = 3.0e+3; +const PylithReal pylith::materials::TestAuxiliaryFactoryElasticity_Cases::RIGIDITY_SCALE = 2.0e+6; +const PylithReal pylith::materials::TestAuxiliaryFactoryElasticity_Cases::KM = 1.0; // ------------------------------------------------------------------------------------------------ pylith::materials::TestAuxiliaryFactoryElasticity_Data* @@ -175,11 +177,10 @@ pylith::materials::TestAuxiliaryFactoryElasticity_Cases::Tri(void) { data->cs = new spatialdata::geocoords::CSCart();assert(data->cs); data->cs->setSpaceDim(data->dimension); - assert(data->normalizer); - data->normalizer->setLengthScale(LENGTH_SCALE); - data->normalizer->setTimeScale(TIME_SCALE); - data->normalizer->setPressureScale(PRESSURE_SCALE); - data->normalizer->setDensityScale(DENSITY_SCALE); + assert(data->scales); + data->scales->setLengthScale(LENGTH_SCALE); + data->scales->setTimeScale(TIME_SCALE); + data->scales->setRigidityScale(RIGIDITY_SCALE); assert(data->auxiliaryDB); data->auxiliaryDB->addValue("density", density_2d, density_units()); @@ -209,11 +210,10 @@ pylith::materials::TestAuxiliaryFactoryElasticity_Cases::Hex(void) { data->cs = new spatialdata::geocoords::CSCart();assert(data->cs); data->cs->setSpaceDim(data->dimension); - assert(data->normalizer); - data->normalizer->setLengthScale(LENGTH_SCALE); - data->normalizer->setTimeScale(TIME_SCALE); - data->normalizer->setPressureScale(PRESSURE_SCALE); - data->normalizer->setDensityScale(DENSITY_SCALE); + assert(data->scales); + data->scales->setLengthScale(LENGTH_SCALE); + data->scales->setTimeScale(TIME_SCALE); + data->scales->setRigidityScale(RIGIDITY_SCALE); assert(data->auxiliaryDB); data->auxiliaryDB->addValue("density", density_3d, density_units()); diff --git a/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic.cc b/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic.cc index 33499fd86b..381f72b7bc 100644 --- a/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic.cc +++ b/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic.cc @@ -26,7 +26,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales #include "catch2/catch_test_macros.hpp" @@ -48,7 +49,7 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::TestAuxiliaryFactoryLinear componentNames, componentNames.size(), pylith::topology::Field::SCALAR, - _data->normalizer->getDensityScale(), + pylith::scales::ElasticityScales::getDensityScale(*_data->scales), 0.0, pylith::topology::FieldQuery::validatorPositive ); @@ -67,8 +68,8 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::TestAuxiliaryFactoryLinear componentNames, componentNames.size(), pylith::topology::Field::SCALAR, - _data->normalizer->getPressureScale(), - 100.0, + _data->scales->getRigidityScale(), + 0.0, pylith::topology::FieldQuery::validatorNonnegative ); info.fe = pylith::topology::Field::Discretization( @@ -86,7 +87,7 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::TestAuxiliaryFactoryLinear componentNames, componentNames.size(), pylith::topology::Field::SCALAR, - _data->normalizer->getPressureScale(), + _data->scales->getRigidityScale(), 0.0, pylith::topology::FieldQuery::validatorPositive ); @@ -110,7 +111,7 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::TestAuxiliaryFactoryLinear componentNames, componentNames.size(), pylith::topology::Field::TENSOR, - _data->normalizer->getPressureScale() + _data->scales->getRigidityScale() ); info.fe = pylith::topology::Field::Discretization( 2, 2, _data->auxDim, _data->auxDim, false, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POLYNOMIAL_SPACE, false @@ -188,7 +189,7 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::testAdd(void) { _factory->addReferenceStress(); _factory->addReferenceStrain(); - assert(_data->normalizer); + assert(_data->scales); pylith::testing::FieldTester::checkSubfieldInfo(*_auxiliaryField, _data->subfields["density"]); pylith::testing::FieldTester::checkSubfieldInfo(*_auxiliaryField, _data->subfields["shear_modulus"]); @@ -218,9 +219,9 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::testSetValuesFromDB(void) _auxiliaryField->allocate(); assert(_data); - assert(_data->normalizer); + assert(_data->scales); _factory->setValuesFromDB(); - pylith::testing::FieldTester::checkFieldWithDB(*_auxiliaryField, _data->auxiliaryDB, _data->normalizer->getLengthScale()); + pylith::testing::FieldTester::checkFieldWithDB(*_auxiliaryField, _data->auxiliaryDB, _data->scales->getLengthScale()); PYLITH_METHOD_END; } // testSetValues @@ -245,8 +246,8 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::_initialize(void) { // Setup coordinates. _mesh->setCoordSys(_data->cs); - assert(_data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->normalizer); + assert(_data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->scales); _auxiliaryField = new pylith::topology::Field(*_mesh);assert(_auxiliaryField); _auxiliaryField->setLabel("auxiliary"); @@ -261,8 +262,8 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::_initialize(void) { _factory->setSubfieldDiscretization(subfieldName, fe.basisOrder, fe.quadOrder, fe.dimension, fe.isFaultOnly, fe.cellBasis, fe.feSpace, fe.isBasisContinuous); } // for - assert(_data->normalizer); - _factory->initialize(_auxiliaryField, *_data->normalizer, _data->dimension); + assert(_data->scales); + _factory->initialize(_auxiliaryField, *_data->scales, _data->dimension); PYLITH_METHOD_END; } // _initialize @@ -272,14 +273,14 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic::_initialize(void) { pylith::materials::TestAuxiliaryFactoryLinearElastic_Data::TestAuxiliaryFactoryLinearElastic_Data(void) : meshFilename(NULL), cs(NULL), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), auxiliaryDB(new spatialdata::spatialdb::UserFunctionDB) {} // ------------------------------------------------------------------------------------------------ pylith::materials::TestAuxiliaryFactoryLinearElastic_Data::~TestAuxiliaryFactoryLinearElastic_Data(void) { delete cs;cs = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; delete auxiliaryDB;auxiliaryDB = NULL; } // destructor diff --git a/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic.hh b/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic.hh index 4657853ed2..fac7b891ba 100644 --- a/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic.hh +++ b/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic.hh @@ -15,7 +15,7 @@ #include "pylith/topology/Field.hh" // HOLDSA Field::SubfieldInfo #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA SpatialDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA Coordsys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales #include // USES std::map @@ -79,7 +79,7 @@ public: size_t dimension; ///< Spatial dimension. const char* meshFilename; ///< Name of file with ASCII mesh. spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. std::map subfields; spatialdata::spatialdb::UserFunctionDB* auxiliaryDB; ///< Spatial database with values for solution. diff --git a/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic_Cases.cc b/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic_Cases.cc index d8e0002385..5f7a532a2f 100644 --- a/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic_Cases.cc +++ b/tests/libtests/materials/TestAuxiliaryFactoryLinearElastic_Cases.cc @@ -15,7 +15,7 @@ #include "pylith/materials/AuxiliaryFactoryElastic.hh" // USES AuxiliaryFactoryElastic #include "spatialdata/geocoords/CSCart.hh" // USES CSCart #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" @@ -40,8 +40,9 @@ class pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases { private: static const PylithReal LENGTH_SCALE; + static const PylithReal KM; static const PylithReal TIME_SCALE; - static const PylithReal PRESSURE_SCALE; + static const PylithReal RIGIDITY_SCALE; static const PylithReal DENSITY_SCALE; private: @@ -49,7 +50,7 @@ class pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases { static double density_2d(const double x, const double y) { - return 2500.0 + 3.0*fabs(x)/LENGTH_SCALE + 2.0*fabs(y)/LENGTH_SCALE; + return 2500.0 + 3.0*fabs(x)/KM + 2.0*fabs(y)/KM; } // density static @@ -60,7 +61,7 @@ class pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases { static double vs_2d(const double x, const double y) { - return 1000.0 + 30.0*fabs(x)/LENGTH_SCALE + 20.0*fabs(y)/LENGTH_SCALE; + return 1000.0 + 30.0*fabs(x)/KM + 20.0*fabs(y)/KM; } // vs static @@ -71,7 +72,7 @@ class pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases { static double vp_2d(const double x, const double y) { - return 2000.0 + 50.0*fabs(x)/LENGTH_SCALE + 43.0*fabs(y)/LENGTH_SCALE; + return 2000.0 + 50.0*fabs(x)/KM + 43.0*fabs(y)/KM; } // vp static @@ -102,25 +103,25 @@ class pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases { static double reference_stress_2d_xx(const double x, const double y) { - return -0.3*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 0.1*x*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*x/(KM*KM) + 0.1*x*y/(KM*KM); } // reference_stress_xx static double reference_stress_2d_yy(const double x, const double y) { - return -8.0e+6*x*y/(LENGTH_SCALE*LENGTH_SCALE) + 2.0e+6*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -8.0e+6*x*y/(KM*KM) + 2.0e+6*y*y/(KM*KM); } // reference_stress_2d_yy static double reference_stress_2d_zz(const double x, const double y) { - return -3.0e+6*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 5.0e+6*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -3.0e+6*x*x/(KM*KM) + 5.0e+6*y*y/(KM*KM); } // reference_stress_2d_zz static double reference_stress_2d_xy(const double x, const double y) { - return -3.0e+6*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 2.0e+6*x*y/(LENGTH_SCALE*LENGTH_SCALE); + return -3.0e+6*x*x/(KM*KM) + 2.0e+6*x*y/(KM*KM); } // reference_stress_xy static @@ -131,25 +132,25 @@ class pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases { static double reference_strain_2d_xx(const double x, const double y) { - return -0.3*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 0.1*x*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*x/(KM*KM) + 0.1*x*y/(KM*KM); } // reference_strain_2d_xx static double reference_strain_2d_yy(const double x, const double y) { - return -0.8*x*y/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.8*x*y/(KM*KM) + 0.2*y*y/(KM*KM); } // reference_strain_2d_yy static double reference_strain_2d_zz(const double x, const double y) { - return -0.3*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 0.5*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*x/(KM*KM) + 0.5*y*y/(KM*KM); } // reference_strain_2d_zz static double reference_strain_2d_xy(const double x, const double y) { - return -0.3*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*x*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*x/(KM*KM) + 0.2*x*y/(KM*KM); } // reference_strain_xy static @@ -161,21 +162,21 @@ class pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases { double density_3d(const double x, const double y, const double z) { - return 2500.0 + 3.0*fabs(x)/LENGTH_SCALE + 2.0*fabs(z)/LENGTH_SCALE; + return 2500.0 + 3.0*fabs(x)/KM + 2.0*fabs(z)/KM; } // density static double vs_3d(const double x, const double y, const double z) { - return 1000.0 + 300.0*fabs(x)/LENGTH_SCALE + 200.0*fabs(z)/LENGTH_SCALE; + return 1000.0 + 300.0*fabs(x)/KM + 200.0*fabs(z)/KM; } // vs static double vp_3d(const double x, const double y, const double z) { - return 2500.0 + 400.0*fabs(x)/LENGTH_SCALE + 5.3*fabs(z)/LENGTH_SCALE; + return 2500.0 + 400.0*fabs(x)/KM + 5.3*fabs(z)/KM; } // vp static @@ -199,84 +200,84 @@ class pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases { double reference_stress_3d_xx(const double x, const double y, const double z) { - return -3.0e+6*x*z/(LENGTH_SCALE*LENGTH_SCALE) + 1.0e+6*x*z/(LENGTH_SCALE*LENGTH_SCALE); + return -3.0e+6*x*z/(KM*KM) + 1.0e+6*x*z/(KM*KM); } // reference_stress_3d_xx static double reference_stress_3d_yy(const double x, const double y, const double z) { - return -8.0e+6*x*z/(LENGTH_SCALE*LENGTH_SCALE) + 2.0e+6*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -8.0e+6*x*z/(KM*KM) + 2.0e+6*y*y/(KM*KM); } // reference_stress_3d_yy static double reference_stress_3d_zz(const double x, const double y, const double z) { - return -3.0e+6*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 5.0e+6*y*z/(LENGTH_SCALE*LENGTH_SCALE); + return -3.0e+6*x*x/(KM*KM) + 5.0e+6*y*z/(KM*KM); } // reference_stress_3d_zz static double reference_stress_3d_xy(const double x, const double y, const double z) { - return -3.0e+6*x/LENGTH_SCALE + 2.0e+6*x*y/(LENGTH_SCALE*LENGTH_SCALE); + return -3.0e+6*x/KM + 2.0e+6*x*y/(KM*KM); } // reference_stress_3d_xy static double reference_stress_3d_yz(const double x, const double y, const double z) { - return -3.0e+6*x*z/(LENGTH_SCALE*LENGTH_SCALE) + 2.0e+6*x*y/(LENGTH_SCALE*LENGTH_SCALE); + return -3.0e+6*x*z/(KM*KM) + 2.0e+6*x*y/(KM*KM); } // reference_stress_3d_yz static double reference_stress_3d_xz(const double x, const double y, const double z) { - return -3.0e+6*x/LENGTH_SCALE + 2.0e+6*y/LENGTH_SCALE; + return -3.0e+6*x/KM + 2.0e+6*y/KM; } // reference_stress_3d_xz static double reference_strain_3d_xx(const double x, const double y, const double z) { - return -0.3*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 0.1*x*z/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*x/(KM*KM) + 0.1*x*z/(KM*KM); } // reference_strain_3d_xx static double reference_strain_3d_yy(const double x, const double y, const double z) { - return -0.8*x*y/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.8*x*y/(KM*KM) + 0.2*y*y/(KM*KM); } // reference_strain_3d_yy static double reference_strain_3d_zz(const double x, const double y, const double z) { - return -0.3*x*z/(LENGTH_SCALE*LENGTH_SCALE) + 0.5*y*y/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*z/(KM*KM) + 0.5*y*y/(KM*KM); } // reference_strain_3d_zz static double reference_strain_3d_xy(const double x, const double y, const double z) { - return -0.3*x*x/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*x*z/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*x*x/(KM*KM) + 0.2*x*z/(KM*KM); } // reference_strain_3d_xy static double reference_strain_3d_yz(const double x, const double y, const double z) { - return -0.3*y*z/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*x*z/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*y*z/(KM*KM) + 0.2*x*z/(KM*KM); } // reference_strain_3d_yz static double reference_strain_3d_xz(const double x, const double y, const double z) { - return -0.3*y*y/(LENGTH_SCALE*LENGTH_SCALE) + 0.2*x*z/(LENGTH_SCALE*LENGTH_SCALE); + return -0.3*y*y/(KM*KM) + 0.2*x*z/(KM*KM); } // reference_strain_3d_xz }; @@ -296,10 +297,10 @@ TEST_CASE("TestAuxiliaryFactoryLinearElastic::Hex::testSetValuesFromDB", "[TestA pylith::materials::TestAuxiliaryFactoryLinearElastic(pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::Hex()).testSetValuesFromDB(); } -const PylithReal pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::LENGTH_SCALE = 1.0e+3; +const PylithReal pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::LENGTH_SCALE = 1.0; const PylithReal pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::TIME_SCALE = 2.0; -const PylithReal pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::PRESSURE_SCALE = 2.0e+10; -const PylithReal pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::DENSITY_SCALE = 3.0e+3; +const PylithReal pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::RIGIDITY_SCALE = 3.0e+6; +const PylithReal pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::KM = 1.0e+3; // -------------------------------------------------------------------------------------------------------------------- pylith::materials::TestAuxiliaryFactoryLinearElastic_Data* @@ -313,11 +314,10 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::Tri(void) { data->cs = new spatialdata::geocoords::CSCart();assert(data->cs); data->cs->setSpaceDim(data->dimension); - assert(data->normalizer); - data->normalizer->setLengthScale(LENGTH_SCALE); - data->normalizer->setTimeScale(TIME_SCALE); - data->normalizer->setPressureScale(PRESSURE_SCALE); - data->normalizer->setDensityScale(DENSITY_SCALE); + assert(data->scales); + data->scales->setLengthScale(LENGTH_SCALE); + data->scales->setTimeScale(TIME_SCALE); + data->scales->setRigidityScale(RIGIDITY_SCALE); assert(data->auxiliaryDB); data->auxiliaryDB->addValue("density", density_2d, density_units()); @@ -352,11 +352,10 @@ pylith::materials::TestAuxiliaryFactoryLinearElastic_Cases::Hex(void) { data->cs = new spatialdata::geocoords::CSCart();assert(data->cs); data->cs->setSpaceDim(data->dimension); - assert(data->normalizer); - data->normalizer->setLengthScale(LENGTH_SCALE); - data->normalizer->setTimeScale(TIME_SCALE); - data->normalizer->setPressureScale(PRESSURE_SCALE); - data->normalizer->setDensityScale(DENSITY_SCALE); + assert(data->scales); + data->scales->setLengthScale(LENGTH_SCALE); + data->scales->setTimeScale(TIME_SCALE); + data->scales->setRigidityScale(RIGIDITY_SCALE); assert(data->auxiliaryDB); data->auxiliaryDB->addValue("density", density_3d, density_units()); diff --git a/tests/libtests/materials/TestIsotropicLinearElasticity3D.cc b/tests/libtests/materials/TestIsotropicLinearElasticity3D.cc index 16ae50a40f..0cfc1d2587 100644 --- a/tests/libtests/materials/TestIsotropicLinearElasticity3D.cc +++ b/tests/libtests/materials/TestIsotropicLinearElasticity3D.cc @@ -25,7 +25,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ---------------------------------------------------------------------- // Setup testing data. @@ -97,13 +97,13 @@ pylith::materials::TestIsotropicLinearElasticity3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_mydata); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal densityScale = _mydata->normalizer->getDensityScale(); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); - const PylithReal pressureScale = _mydata->normalizer->getPressureScale(); - const PylithReal timeScale = _mydata->normalizer->getTimeScale(); - const PylithReal forceScale = pressureScale / lengthScale; - const PylithReal accelerationScale = lengthScale / (timeScale * timeScale); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); + const PylithReal rigidityScale = _mydata->scales->getRigidityScale(); + const PylithReal timeScale = _mydata->scales->getTimeScale(); + const PylithReal bodyForceScale = pylith::scales::ElasticityScales.getBodyForceScale(*_mydata->scales); + const PylithReal densityScale = pylith::scales::ElasticityScales.getDensityScale(*_mydata->scales); + const PylithReal accelerationScale = pylith::scales::ElasticityScales.getAccelerationScale(*_mydata->scales); delete _mymaterial->_auxiliaryField;_mymaterial->_auxiliaryField = new topology::Field(*_mesh);CPPUNIT_ASSERT(_mymaterial->_auxiliaryField); _mymaterial->_auxiliaryFieldSetup(); @@ -128,7 +128,7 @@ pylith::materials::TestIsotropicLinearElasticity3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -141,7 +141,7 @@ pylith::materials::TestIsotropicLinearElasticity3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -180,7 +180,7 @@ pylith::materials::TestIsotropicLinearElasticity3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT_EQUAL(size_t(6), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::OTHER, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -214,8 +214,8 @@ pylith::materials::TestIsotropicLinearElasticity3D::testGetAuxField(void) { CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); const pylith::topology::Field* auxField = _mymaterial->auxField();CPPUNIT_ASSERT(auxField); { // Test getting density field. @@ -369,11 +369,11 @@ pylith::materials::TestIsotropicLinearElasticity3D::_setupSolutionFields(void) { CPPUNIT_ASSERT( (!_mydata->isExplicit && 1 == _mydata->numSolnSubfields) || (_mydata->isExplicit && 2 == _mydata->numSolnSubfields) ); CPPUNIT_ASSERT(_mydata->solnDiscretizations); - CPPUNIT_ASSERT(_mydata->normalizer); + CPPUNIT_ASSERT(_mydata->scales); { // Solution pylith::topology::Field& solution = _solutionFields->get("solution"); - pylith::problems::SolutionFactory factory(solution, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solution, *_mydata->scales); factory.displacement(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocity(_mydata->solnDiscretizations[1]); @@ -386,7 +386,7 @@ pylith::materials::TestIsotropicLinearElasticity3D::_setupSolutionFields(void) { { // Time derivative of solution pylith::topology::Field& solutionDot = _solutionFields->get("solution_dot"); - pylith::problems::SolutionFactory factory(solutionDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solutionDot, *_mydata->scales); factory.displacementDot(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocityDot(_mydata->solnDiscretizations[1]); @@ -404,7 +404,7 @@ pylith::materials::TestIsotropicLinearElasticity3D::_setupSolutionFields(void) { perturbation.createDiscretization(); perturbation.allocate(); perturbation.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbation, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbation, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Perturbation @@ -415,7 +415,7 @@ pylith::materials::TestIsotropicLinearElasticity3D::_setupSolutionFields(void) { perturbationDot.createDiscretization(); perturbationDot.allocate(); perturbationDot.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Time derivative perturbation diff --git a/tests/libtests/materials/TestIsotropicLinearElasticity3D_UniformStrain.cc b/tests/libtests/materials/TestIsotropicLinearElasticity3D_UniformStrain.cc index b5b3f2c837..553a950f90 100644 --- a/tests/libtests/materials/TestIsotropicLinearElasticity3D_UniformStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearElasticity3D_UniformStrain.cc @@ -15,7 +15,7 @@ #include "pylith/materials/IsotropicLinearElasticity3D.hh" // USES IsotropicLinearElasticity3D #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // forward declarations namespace pylith { @@ -199,11 +199,10 @@ class pylith::materials::TestIsotropicLinearElasticity3D_UniformStrain : // meshFilename set in derived class. _mydata->boundaryLabel = "boundary"; - CPPUNIT_ASSERT(_mydata->normalizer); - _mydata->normalizer->setLengthScale(1.0e+03); - _mydata->normalizer->setTimeScale(2.0); - _mydata->normalizer->setDensityScale(3.0e+3); - _mydata->normalizer->setPressureScale(2.25e+10); + CPPUNIT_ASSERT(_mydata->scales); + _mydata->scales->setLengthScale(1.0); + _mydata->scales->setTimeScale(2.0); + _mydata->scales->setRigidityScale(2.5e+6); _mydata->t = 1.0; _mydata->dt = 0.05; diff --git a/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain.cc b/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain.cc index cce7b1e55e..c607754254 100644 --- a/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain.cc @@ -25,7 +25,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ---------------------------------------------------------------------- // Setup testing data. @@ -98,13 +99,13 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_mydata); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal densityScale = _mydata->normalizer->getDensityScale(); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); - const PylithReal pressureScale = _mydata->normalizer->getPressureScale(); - const PylithReal timeScale = _mydata->normalizer->getTimeScale(); - const PylithReal forceScale = pressureScale / lengthScale; - const PylithReal accelerationScale = lengthScale / (timeScale * timeScale); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); + const PylithReal rigidityScale = _mydata->scales->getRigidityScale(); + const PylithReal timeScale = _mydata->scales->getTimeScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_mydata->scales); + const PylithReal accelerationScale = pylith::scales::ElasticityScales::getAccelerationScale(*_mydata->scales); + const PylithReal bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(*_mydata->scales); delete _mymaterial->_auxiliaryField;_mymaterial->_auxiliaryField = new topology::Field(*_mesh);CPPUNIT_ASSERT(_mymaterial->_auxiliaryField); _mymaterial->_auxiliaryFieldSetup(); @@ -129,7 +130,7 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -142,7 +143,7 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -168,7 +169,7 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT_EQUAL(size_t(2), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::VECTOR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(forceScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(bodyForceScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -181,7 +182,7 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT_EQUAL(size_t(4), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::OTHER, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -215,8 +216,8 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::testGetAuxField(voi CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); const pylith::topology::Field* auxField = _mymaterial->auxField();CPPUNIT_ASSERT(auxField); { // Test getting density field. @@ -322,11 +323,11 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::_setupSolutionField CPPUNIT_ASSERT( (!_mydata->isExplicit && 1 == _mydata->numSolnSubfields) || (_mydata->isExplicit && 2 == _mydata->numSolnSubfields) ); CPPUNIT_ASSERT(_mydata->solnDiscretizations); - CPPUNIT_ASSERT(_mydata->normalizer); + CPPUNIT_ASSERT(_mydata->scales); { // Solution pylith::topology::Field& solution = _solutionFields->get("solution"); - pylith::problems::SolutionFactory factory(solution, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solution, *_mydata->scales); factory.displacement(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocity(_mydata->solnDiscretizations[1]); @@ -339,7 +340,7 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::_setupSolutionField { // Time derivative of solution pylith::topology::Field& solutionDot = _solutionFields->get("solution_dot"); - pylith::problems::SolutionFactory factory(solutionDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solutionDot, *_mydata->scales); factory.displacementDot(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocityDot(_mydata->solnDiscretizations[1]); @@ -357,7 +358,7 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::_setupSolutionField perturbation.createDiscretization(); perturbation.allocate(); perturbation.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbation, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbation, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Perturbation @@ -368,7 +369,7 @@ pylith::materials::TestIsotropicLinearElasticityPlaneStrain::_setupSolutionField perturbationDot.createDiscretization(); perturbationDot.allocate(); perturbationDot.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Time derivative perturbation diff --git a/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain_GravityRefState.cc b/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain_GravityRefState.cc index be5bb78122..64ccbaefeb 100644 --- a/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain_GravityRefState.cc +++ b/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain_GravityRefState.cc @@ -16,7 +16,7 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // forward declarations namespace pylith { @@ -183,11 +183,10 @@ class pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefStat // meshFilename set in derived class. _mydata->boundaryLabel = "boundary"; - CPPUNIT_ASSERT(_mydata->normalizer); - _mydata->normalizer->setLengthScale(1.0e+03); - _mydata->normalizer->setTimeScale(2.0); - _mydata->normalizer->setPressureScale(2.25e+10); - _mydata->normalizer->computeDensityScale(); + CPPUNIT_ASSERT(_mydata->scales); + _mydata->scales->setLengthScale(1.0); + _mydata->scales->setTimeScale(2.0); + _mydata->scales->setRigidityScale(2.5e+6); delete _mydata->gravityField;_mydata->gravityField = new spatialdata::spatialdb::GravityField(); _mydata->gravityField->setGravityDir(0.0, -1.0, 0.0); @@ -208,7 +207,7 @@ class pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefStat pylith::topology::Field::Discretization(0, 1), // bulk_modulus pylith::topology::Field::Discretization(0, 1), // gravitational_acceleration pylith::topology::Field::Discretization(1, 1), // reference_stress - pylith::topology::Field::Discretization(1, 1) // reference_strain + pylith::topology::Field::Discretization(1, 1) // reference_strain }; _mydata->auxDiscretizations = const_cast(_auxDiscretizations); @@ -252,7 +251,6 @@ class pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefStat }; // TestIsotropicLinearElasticityPlaneStrain_GravityRefState const double pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefState::SMALL = 0.1; -const double pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefState::GACC = 9.80665; const double pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefState::YMAX = +4.0e+3; // ---------------------------------------------------------------------- @@ -271,7 +269,7 @@ class pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefStat _mydata->numSolnSubfields = 1; static const pylith::topology::Field::Discretization _solnDiscretizations[1] = { - pylith::topology::Field::Discretization(1, 1) // disp + pylith::topology::Field::Discretization(1, 1) // disp }; _mydata->solnDiscretizations = const_cast(_solnDiscretizations); @@ -493,6 +491,13 @@ CPPUNIT_TEST_SUITE_REGISTRATION(pylith::materials::TestIsotropicLinearElasticity // ---------------------------------------------------------------------- class pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefState_QuadQ4 : public pylith::materials::TestIsotropicLinearElasticityPlaneStrain_GravityRefState { // + // + // + // + // + // + // + // // // // TestIsotropicLinearElasticityPlaneStrain_GravityRefState_QuadQ4 diff --git a/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain_UniformStrain.cc b/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain_UniformStrain.cc index a18d67aae7..db4bfc3b79 100644 --- a/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain_UniformStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearElasticityPlaneStrain_UniformStrain.cc @@ -15,7 +15,7 @@ #include "pylith/materials/IsotropicLinearElasticityPlaneStrain.hh" // USES IsotropicLinearElasticityPlaneStrain #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // forward declarations namespace pylith { @@ -157,11 +157,10 @@ class pylith::materials::TestIsotropicLinearElasticityPlaneStrain_UniformStrain // meshFilename set in derived class. _mydata->boundaryLabel = "boundary"; - CPPUNIT_ASSERT(_mydata->normalizer); - _mydata->normalizer->setLengthScale(1.0e+03); - _mydata->normalizer->setTimeScale(2.0); - _mydata->normalizer->setDensityScale(3.0e+3); - _mydata->normalizer->setPressureScale(2.25e+10); + CPPUNIT_ASSERT(_mydata->scales); + _mydata->scales->setLengthScale(1.0); + _mydata->scales->setTimeScale(2.0); + _mydata->scales->setRigidityScale(2.5e+6); _mydata->t = 1.0; _mydata->dt = 0.05; diff --git a/tests/libtests/materials/TestIsotropicLinearGenMaxwell3D.cc b/tests/libtests/materials/TestIsotropicLinearGenMaxwell3D.cc index 057016aaae..4420eb0576 100644 --- a/tests/libtests/materials/TestIsotropicLinearGenMaxwell3D.cc +++ b/tests/libtests/materials/TestIsotropicLinearGenMaxwell3D.cc @@ -25,7 +25,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ---------------------------------------------------------------------- // Setup testing data. @@ -98,13 +99,13 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_mydata); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal densityScale = _mydata->normalizer->getDensityScale(); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); - const PylithReal timeScale = _mydata->normalizer->getTimeScale(); - const PylithReal pressureScale = _mydata->normalizer->getPressureScale(); - const PylithReal forceScale = pressureScale / lengthScale; - const PylithReal accelerationScale = lengthScale/(timeScale * timeScale); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); + const PylithReal rigidityScale = _mydata->scales->getRigidityScale(); + const PylithReal timeScale = _mydata->scales->getTimeScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_mydata->scales); + const PylithReal accelerationScale = pylith::scales::ElasticityScales::getAccelerationScale(*_mydata->scales); + const PylithReal bodybodyForceScale = pylith::scales::ElasticityScales::getBodybodyForceScale(*_mydata->scales); delete _mymaterial->_auxiliaryField;_mymaterial->_auxiliaryField = new topology::Field(*_mesh);CPPUNIT_ASSERT(_mymaterial->_auxiliaryField); _mymaterial->_auxiliaryFieldSetup(); @@ -129,7 +130,7 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -142,7 +143,7 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -220,7 +221,7 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT_EQUAL(size_t(3), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::VECTOR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(forceScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(bodyForceScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -233,7 +234,7 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::test_auxiliaryFieldSetup(voi CPPUNIT_ASSERT_EQUAL(size_t(6), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::OTHER, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -267,8 +268,8 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::testGetAuxField(void) { CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); const pylith::topology::Field* auxField = _mymaterial->auxField();CPPUNIT_ASSERT(auxField); { // Test getting density field. @@ -494,11 +495,11 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::_setupSolutionFields(void) { CPPUNIT_ASSERT( (!_mydata->isExplicit && 1 == _mydata->numSolnSubfields) || (_mydata->isExplicit && 2 == _mydata->numSolnSubfields) ); CPPUNIT_ASSERT(_mydata->solnDiscretizations); - CPPUNIT_ASSERT(_mydata->normalizer); + CPPUNIT_ASSERT(_mydata->scales); { // Solution pylith::topology::Field& solution = _solutionFields->get("solution"); - pylith::problems::SolutionFactory factory(solution, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solution, *_mydata->scales); factory.displacement(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocity(_mydata->solnDiscretizations[1]); @@ -511,7 +512,7 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::_setupSolutionFields(void) { { // Time derivative of solution pylith::topology::Field& solutionDot = _solutionFields->get("solution_dot"); - pylith::problems::SolutionFactory factory(solutionDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solutionDot, *_mydata->scales); factory.displacementDot(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocityDot(_mydata->solnDiscretizations[1]); @@ -529,7 +530,7 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::_setupSolutionFields(void) { perturbation.createDiscretization(); perturbation.allocate(); perturbation.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbation, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbation, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Perturbation @@ -540,7 +541,7 @@ pylith::materials::TestIsotropicLinearGenMaxwell3D::_setupSolutionFields(void) { perturbationDot.createDiscretization(); perturbationDot.allocate(); perturbationDot.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Time derivative of perturbation diff --git a/tests/libtests/materials/TestIsotropicLinearGenMaxwell3D_LinearStrain.cc b/tests/libtests/materials/TestIsotropicLinearGenMaxwell3D_LinearStrain.cc index 126bf83246..6800aa3728 100644 --- a/tests/libtests/materials/TestIsotropicLinearGenMaxwell3D_LinearStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearGenMaxwell3D_LinearStrain.cc @@ -15,7 +15,7 @@ #include "pylith/materials/IsotropicLinearGenMaxwell3D.hh" // USES IsotropicLinearGenMaxwell3D #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/journals.hh" // :TEMPORARY: USES PYLITH_JOURNAL_ERROR @@ -1005,14 +1005,13 @@ class pylith::materials::TestIsotropicLinearGenMaxwell3D_LinearStrain : // meshFilename set in derived class. _mydata->boundaryLabel = "boundary"; - CPPUNIT_ASSERT(_mydata->normalizer); - _mydata->normalizer->setLengthScale(1.0e+03); - _mydata->normalizer->setTimeScale(2.0e+7); - _mydata->normalizer->setDensityScale(3.0e+3); - _mydata->normalizer->setPressureScale(1.25e+11); + CPPUNIT_ASSERT(_mydata->scales); + _mydata->scales->setLengthScale(1.0); + _mydata->scales->setTimeScale(2.0e+7); + _mydata->scales->setRigidityScale(5.0e+6); - _mydata->t = constants.t/_mydata->normalizer->getTimeScale(); - _mydata->dt = constants.dt/_mydata->normalizer->getTimeScale(); + _mydata->t = constants.t/_mydata->scales->getTimeScale(); + _mydata->dt = constants.dt/_mydata->scales->getTimeScale(); _mydata->s_tshift = 1.0 / _mydata->dt; // solnDiscretizations set in derived class. diff --git a/tests/libtests/materials/TestIsotropicLinearGenMaxwellPlaneStrain.cc b/tests/libtests/materials/TestIsotropicLinearGenMaxwellPlaneStrain.cc index b69e34cbc2..daf96a5781 100644 --- a/tests/libtests/materials/TestIsotropicLinearGenMaxwellPlaneStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearGenMaxwellPlaneStrain.cc @@ -25,7 +25,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ---------------------------------------------------------------------- // Setup testing data. @@ -98,13 +99,13 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_mydata); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal densityScale = _mydata->normalizer->getDensityScale(); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); - const PylithReal timeScale = _mydata->normalizer->getTimeScale(); - const PylithReal pressureScale = _mydata->normalizer->getPressureScale(); - const PylithReal forceScale = pressureScale / lengthScale; - const PylithReal accelerationScale = lengthScale/(timeScale * timeScale); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); + const PylithReal rigidityScale = _mydata->scales->getRigidityScale(); + const PylithReal timeScale = _mydata->scales->getTimeScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_mydata->scales); + const PylithReal accelerationScale = pylith::scales::ElasticityScales::getAccelerationScale(*_mydata->scales); + const PylithReal bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(*_mydata->scales); delete _mymaterial->_auxiliaryField;_mymaterial->_auxiliaryField = new topology::Field(*_mesh);CPPUNIT_ASSERT(_mymaterial->_auxiliaryField); _mymaterial->_auxiliaryFieldSetup(); @@ -129,7 +130,7 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -142,7 +143,7 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -220,7 +221,7 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT_EQUAL(size_t(2), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::VECTOR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(forceScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(bodyForceScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -233,7 +234,7 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::test_auxiliaryField CPPUNIT_ASSERT_EQUAL(size_t(4), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::OTHER, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -267,8 +268,8 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::testGetAuxField(voi CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); const pylith::topology::Field* auxField = _mymaterial->auxField();assert(auxField); { // Test getting density field. @@ -494,11 +495,11 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::_setupSolutionField CPPUNIT_ASSERT( (!_mydata->isExplicit && 1 == _mydata->numSolnSubfields) || (_mydata->isExplicit && 2 == _mydata->numSolnSubfields) ); CPPUNIT_ASSERT(_mydata->solnDiscretizations); - CPPUNIT_ASSERT(_mydata->normalizer); + CPPUNIT_ASSERT(_mydata->scales); { // Solution pylith::topology::Field& solution = _solutionFields->get("solution"); - pylith::problems::SolutionFactory factory(solution, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solution, *_mydata->scales); factory.displacement(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocity(_mydata->solnDiscretizations[1]); @@ -511,7 +512,7 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::_setupSolutionField { // Time derivative of solution pylith::topology::Field& solutionDot = _solutionFields->get("solution_dot"); - pylith::problems::SolutionFactory factory(solutionDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solutionDot, *_mydata->scales); factory.displacementDot(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocityDot(_mydata->solnDiscretizations[1]); @@ -529,7 +530,7 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::_setupSolutionField perturbation.createDiscretization(); perturbation.allocate(); perturbation.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbation, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbation, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Perturbation @@ -540,7 +541,7 @@ pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain::_setupSolutionField perturbationDot.createDiscretization(); perturbationDot.allocate(); perturbationDot.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Time derivative of perturbation diff --git a/tests/libtests/materials/TestIsotropicLinearGenMaxwellPlaneStrain_LinearStrain.cc b/tests/libtests/materials/TestIsotropicLinearGenMaxwellPlaneStrain_LinearStrain.cc index 88f8585f0e..4dbb809d12 100644 --- a/tests/libtests/materials/TestIsotropicLinearGenMaxwellPlaneStrain_LinearStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearGenMaxwellPlaneStrain_LinearStrain.cc @@ -15,7 +15,7 @@ #include "pylith/materials/IsotropicLinearGenMaxwellPlaneStrain.hh" // USES IsotropicLinearGenMaxwellPlaneStrain #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/journals.hh" // :TEMPORARY: USES PYLITH_JOURNAL_ERROR @@ -566,14 +566,13 @@ class pylith::materials::TestIsotropicLinearGenMaxwellPlaneStrain_LinearStrain : // meshFilename set in derived class. _mydata->boundaryLabel = "boundary"; - CPPUNIT_ASSERT(_mydata->normalizer); - _mydata->normalizer->setLengthScale(1.0e+03); - _mydata->normalizer->setTimeScale(2.0e+7); - _mydata->normalizer->setDensityScale(3.0e+3); - _mydata->normalizer->setPressureScale(2.25e+10); + CPPUNIT_ASSERT(_mydata->scales); + _mydata->scales->setLengthScale(1.0); + _mydata->scales->setTimeScale(2.0e+7); + _mydata->scales->setRigidityScale(2.5e+6); - _mydata->t = constants.t/_mydata->normalizer->getTimeScale(); - _mydata->dt = constants.dt/_mydata->normalizer->getTimeScale(); + _mydata->t = constants.t/_mydata->scales->getTimeScale(); + _mydata->dt = constants.dt/_mydata->scales->getTimeScale(); _mydata->s_tshift = 1.0 / _mydata->dt; // solnDiscretizations set in derived class. diff --git a/tests/libtests/materials/TestIsotropicLinearMaxwell3D.cc b/tests/libtests/materials/TestIsotropicLinearMaxwell3D.cc index c809c8c54b..4cb1d34d08 100644 --- a/tests/libtests/materials/TestIsotropicLinearMaxwell3D.cc +++ b/tests/libtests/materials/TestIsotropicLinearMaxwell3D.cc @@ -25,7 +25,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ---------------------------------------------------------------------- // Setup testing data. @@ -98,13 +99,13 @@ pylith::materials::TestIsotropicLinearMaxwell3D::test_auxiliaryFieldSetup(void) CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_mydata); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal densityScale = _mydata->normalizer->getDensityScale(); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); - const PylithReal timeScale = _mydata->normalizer->getTimeScale(); - const PylithReal pressureScale = _mydata->normalizer->getPressureScale(); - const PylithReal forceScale = pressureScale / lengthScale; - const PylithReal accelerationScale = lengthScale/(timeScale * timeScale); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); + const PylithReal rigidityScale = _mydata->scales->getRigidityScale(); + const PylithReal timeScale = _mydata->scales->getTimeScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_mydata->scales); + const PylithReal accelerationScale = pylith::scales::ElasticityScales::getAccelerationScale(*_mydata->scales); + const PylithReal bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(*_mydata->scales); delete _mymaterial->_auxiliaryField;_mymaterial->_auxiliaryField = new topology::Field(*_mesh);CPPUNIT_ASSERT(_mymaterial->_auxiliaryField); _mymaterial->_auxiliaryFieldSetup(); @@ -129,7 +130,7 @@ pylith::materials::TestIsotropicLinearMaxwell3D::test_auxiliaryFieldSetup(void) CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -142,7 +143,7 @@ pylith::materials::TestIsotropicLinearMaxwell3D::test_auxiliaryFieldSetup(void) CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -207,7 +208,7 @@ pylith::materials::TestIsotropicLinearMaxwell3D::test_auxiliaryFieldSetup(void) CPPUNIT_ASSERT_EQUAL(size_t(3), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::VECTOR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(forceScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(bodyForceScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -220,7 +221,7 @@ pylith::materials::TestIsotropicLinearMaxwell3D::test_auxiliaryFieldSetup(void) CPPUNIT_ASSERT_EQUAL(size_t(6), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::OTHER, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -254,8 +255,8 @@ pylith::materials::TestIsotropicLinearMaxwell3D::testGetAuxField(void) { CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); const pylith::topology::Field* auxField = _mymaterial->auxField();CPPUNIT_ASSERT(auxField); { // Test getting density field. @@ -457,11 +458,11 @@ pylith::materials::TestIsotropicLinearMaxwell3D::_setupSolutionFields(void) { CPPUNIT_ASSERT( (!_mydata->isExplicit && 1 == _mydata->numSolnSubfields) || (_mydata->isExplicit && 2 == _mydata->numSolnSubfields) ); CPPUNIT_ASSERT(_mydata->solnDiscretizations); - CPPUNIT_ASSERT(_mydata->normalizer); + CPPUNIT_ASSERT(_mydata->scales); { // Solution pylith::topology::Field& solution = _solutionFields->get("solution"); - pylith::problems::SolutionFactory factory(solution, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solution, *_mydata->scales); factory.displacement(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocity(_mydata->solnDiscretizations[1]); @@ -474,7 +475,7 @@ pylith::materials::TestIsotropicLinearMaxwell3D::_setupSolutionFields(void) { { // Time derivative of solution pylith::topology::Field& solutionDot = _solutionFields->get("solution_dot"); - pylith::problems::SolutionFactory factory(solutionDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solutionDot, *_mydata->scales); factory.displacementDot(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocityDot(_mydata->solnDiscretizations[1]); @@ -492,7 +493,7 @@ pylith::materials::TestIsotropicLinearMaxwell3D::_setupSolutionFields(void) { preturbation.createDiscretization(); perturbation.allocate(); perturbation.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbation, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbation, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Perturbation @@ -503,7 +504,7 @@ pylith::materials::TestIsotropicLinearMaxwell3D::_setupSolutionFields(void) { perturbationDot.createDiscretization(); perturbationDot.allocate(); perturbationDot.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Time derivative perturbation diff --git a/tests/libtests/materials/TestIsotropicLinearMaxwell3D_LinearStrain.cc b/tests/libtests/materials/TestIsotropicLinearMaxwell3D_LinearStrain.cc index 6e9654aabe..545a5c0519 100644 --- a/tests/libtests/materials/TestIsotropicLinearMaxwell3D_LinearStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearMaxwell3D_LinearStrain.cc @@ -15,7 +15,7 @@ #include "pylith/materials/IsotropicLinearMaxwell3D.hh" // USES IsotropicLinearMaxwell3D #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/journals.hh" // :TEMPORARY: USES PYLITH_JOURNAL_ERROR @@ -497,14 +497,13 @@ class pylith::materials::TestIsotropicLinearMaxwell3D_LinearStrain : // meshFilename set in derived class. _mydata->boundaryLabel = "boundary"; - CPPUNIT_ASSERT(_mydata->normalizer); - _mydata->normalizer->setLengthScale(1.0e+03); - _mydata->normalizer->setTimeScale(6.3e+8); - _mydata->normalizer->setDensityScale(4.0e+3); - _mydata->normalizer->setPressureScale(2.5e+11); + CPPUNIT_ASSERT(_mydata->scales); + _mydata->scales->setLengthScale(1.0); + _mydata->scales->setTimeScale(6.3e+8); + _mydata->scales->setRigidityScale(2.5e+6); - _mydata->t = constants.t/_mydata->normalizer->getTimeScale(); - _mydata->dt = constants.dt/_mydata->normalizer->getTimeScale(); + _mydata->t = constants.t/_mydata->scales->getTimeScale(); + _mydata->dt = constants.dt/_mydata->scales->getTimeScale(); _mydata->s_tshift = 1.0 / _mydata->dt; // solnDiscretizations set in derived class. @@ -611,7 +610,7 @@ const pylith::materials::TestIsotropicLinearMaxwell3D_LinearStrain::AuxConstants 4.5e-7, // f 9.0e-8, // g 9.0e+7, // t - 5.0e+7 // dt + 5.0e+7 // dt }; // ---------------------------------------------------------------------- diff --git a/tests/libtests/materials/TestIsotropicLinearMaxwellPlaneStrain.cc b/tests/libtests/materials/TestIsotropicLinearMaxwellPlaneStrain.cc index 603ae9315b..2af04a520d 100644 --- a/tests/libtests/materials/TestIsotropicLinearMaxwellPlaneStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearMaxwellPlaneStrain.cc @@ -25,7 +25,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ---------------------------------------------------------------------- // Setup testing data. @@ -98,13 +99,13 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::test_auxiliaryFieldSet CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); CPPUNIT_ASSERT(_mydata); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal densityScale = _mydata->normalizer->getDensityScale(); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); - const PylithReal timeScale = _mydata->normalizer->getTimeScale(); - const PylithReal pressureScale = _mydata->normalizer->getPressureScale(); - const PylithReal forceScale = pressureScale / lengthScale; - const PylithReal accelerationScale = lengthScale/(timeScale * timeScale); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); + const PylithReal rigidityScale = _mydata->scales->getRigidityScale(); + const PylithReal timeScale = _mydata->scales->getTimeScale(); + const PylithReal densityScale = pylith::scales::ElasticityScales::getDensityScale(*_mydata->scales); + const PylithReal accelerationScale = pylith::scales::ElasticityScales::getAccelerationScale(*_mydata->scales); + const PylithReal bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(*_mydata->scales); delete _mymaterial->_auxiliaryField;_mymaterial->_auxiliaryField = new topology::Field(*_mesh);CPPUNIT_ASSERT(_mymaterial->_auxiliaryField); _mymaterial->_auxiliaryFieldSetup(); @@ -129,7 +130,7 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::test_auxiliaryFieldSet CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -142,7 +143,7 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::test_auxiliaryFieldSet CPPUNIT_ASSERT_EQUAL(size_t(1), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::SCALAR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -207,7 +208,7 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::test_auxiliaryFieldSet CPPUNIT_ASSERT_EQUAL(size_t(2), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::VECTOR, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(forceScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(bodyForceScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -220,7 +221,7 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::test_auxiliaryFieldSet CPPUNIT_ASSERT_EQUAL(size_t(4), info.description.numComponents); CPPUNIT_ASSERT_EQUAL(std::string(label), info.description.label); CPPUNIT_ASSERT_EQUAL(pylith::topology::Field::OTHER, info.description.vectorFieldType); - CPPUNIT_ASSERT_EQUAL(pressureScale, info.description.scale); + CPPUNIT_ASSERT_EQUAL(rigidityScale, info.description.scale); CPPUNIT_ASSERT_EQUAL(1, info.fe.basisOrder); CPPUNIT_ASSERT_EQUAL(1, info.fe.quadOrder); CPPUNIT_ASSERT_EQUAL(true, info.fe.isBasisContinuous); @@ -254,8 +255,8 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::testGetAuxField(void) CPPUNIT_ASSERT(_mymaterial); CPPUNIT_ASSERT(_mesh); - CPPUNIT_ASSERT(_mydata->normalizer); - const PylithReal lengthScale = _mydata->normalizer->getLengthScale(); + CPPUNIT_ASSERT(_mydata->scales); + const PylithReal lengthScale = _mydata->scales->getLengthScale(); const pylith::topology::Field* auxField = _mymaterial->auxField();assert(auxField); { // Test getting density field. @@ -457,11 +458,11 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::_setupSolutionFields(v CPPUNIT_ASSERT( (!_mydata->isExplicit && 1 == _mydata->numSolnSubfields) || (_mydata->isExplicit && 2 == _mydata->numSolnSubfields) ); CPPUNIT_ASSERT(_mydata->solnDiscretizations); - CPPUNIT_ASSERT(_mydata->normalizer); + CPPUNIT_ASSERT(_mydata->scales); { // Solution pylith::topology::Field& solution = _solutionFields->get("solution"); - pylith::problems::SolutionFactory factory(solution, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solution, *_mydata->scales); factory.displacement(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocity(_mydata->solnDiscretizations[1]); @@ -474,7 +475,7 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::_setupSolutionFields(v { // Time derivative of solution pylith::topology::Field& solutionDot = _solutionFields->get("solution_dot"); - pylith::problems::SolutionFactory factory(solutionDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(solutionDot, *_mydata->scales); factory.displacementDot(_mydata->solnDiscretizations[0]); if (_mydata->isExplicit) { factory.velocityDot(_mydata->solnDiscretizations[1]); @@ -492,7 +493,7 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::_setupSolutionFields(v perturbation.createDiscretization(); perturbation.allocate(); perturbation.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbation, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbation, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Perturbation @@ -503,7 +504,7 @@ pylith::materials::TestIsotropicLinearMaxwellPlaneStrain::_setupSolutionFields(v perturbationDot.createDiscretization(); perturbationDot.allocate(); perturbationDot.zeroLocal(); - pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->normalizer); + pylith::problems::SolutionFactory factory(perturbationDot, *_mydata->scales); factory.setValues(_mydata->perturbDB); } // Time derivative perturbation diff --git a/tests/libtests/materials/TestIsotropicLinearMaxwellPlaneStrain_LinearStrain.cc b/tests/libtests/materials/TestIsotropicLinearMaxwellPlaneStrain_LinearStrain.cc index b8a560515a..68863351ce 100644 --- a/tests/libtests/materials/TestIsotropicLinearMaxwellPlaneStrain_LinearStrain.cc +++ b/tests/libtests/materials/TestIsotropicLinearMaxwellPlaneStrain_LinearStrain.cc @@ -15,7 +15,7 @@ #include "pylith/materials/IsotropicLinearMaxwellPlaneStrain.hh" // USES IsotropicLinearMaxwellPlaneStrain #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/utils/journals.hh" // :TEMPORARY: USES PYLITH_JOURNAL_ERROR @@ -368,14 +368,13 @@ class pylith::materials::TestIsotropicLinearMaxwellPlaneStrain_LinearStrain : // meshFilename set in derived class. _mydata->boundaryLabel = "boundary"; - CPPUNIT_ASSERT(_mydata->normalizer); - _mydata->normalizer->setLengthScale(1.0e+03); - _mydata->normalizer->setTimeScale(6.3e+8); - _mydata->normalizer->setDensityScale(4.0e+3); - _mydata->normalizer->setPressureScale(2.5e+11); + CPPUNIT_ASSERT(_mydata->scales); + _mydata->scales->setLengthScale(1.0); + _mydata->scales->setTimeScale(6.3e+8); + _mydata->scales->setRigidityScale(2.5e+6); - _mydata->t = constants.t/_mydata->normalizer->getTimeScale(); - _mydata->dt = constants.dt/_mydata->normalizer->getTimeScale(); + _mydata->t = constants.t/_mydata->scales->getTimeScale(); + _mydata->dt = constants.dt/_mydata->scales->getTimeScale(); _mydata->s_tshift = 1.0 / _mydata->dt; // solnDiscretizations set in derived class. @@ -465,7 +464,7 @@ const pylith::materials::TestIsotropicLinearMaxwellPlaneStrain_LinearStrain::Aux 3.0e-7, // c 9.0e-8, // d 9.0e+7, // t - 5.0e+7 // dt + 5.0e+7 // dt }; // ---------------------------------------------------------------------- diff --git a/tests/libtests/materials/TestMaterial.cc b/tests/libtests/materials/TestMaterial.cc index b8ac2d0a6a..087d0595b7 100644 --- a/tests/libtests/materials/TestMaterial.cc +++ b/tests/libtests/materials/TestMaterial.cc @@ -29,7 +29,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ---------------------------------------------------------------------- // Setup testing data. @@ -144,21 +144,21 @@ pylith::materials::TestMaterial::testAuxFieldDB(void) { // ---------------------------------------------------------------------- -// Test normalizer(). +// Test scales(). void -pylith::materials::TestMaterial::testNormalizer(void) { +pylith::materials::TestMaterial::testScales(void) { PYLITH_METHOD_BEGIN; - spatialdata::units::Nondimensional normalizer; + pylith::scales::Scales scales; const double scale = 5.0; - normalizer.setLengthScale(scale); + scales.setLengthScale(scale); Material* material = _material();CPPUNIT_ASSERT(material); - material->normalizer(normalizer); - CPPUNIT_ASSERT_EQUAL(scale, material->_normalizer->getLengthScale()); + material->scales(scales); + CPPUNIT_ASSERT_EQUAL(scale, material->_scales->getLengthScale()); PYLITH_METHOD_END; -} // testNormalizer +} // testScales // ---------------------------------------------------------------------- @@ -225,8 +225,8 @@ pylith::materials::TestMaterial::testInitialize(void) { const PetscDM dm = auxField->dmMesh();CPPUNIT_ASSERT(dm); pylith::topology::FieldQuery query(*auxField); query.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(data->normalizer); - query.openDB(data->auxDB, data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(data->scales); + query.openDB(data->auxDB, data->scales->getLengthScale()); PetscErrorCode err = DMPlexComputeL2DiffLocal(dm, t, query.functions(), (void**)query.contextPtrs(), auxField->localVector(), &norm);CPPUNIT_ASSERT(!err); query.closeDB(data->auxDB); const PylithReal tolerance = 1.0e-6; @@ -242,8 +242,8 @@ pylith::materials::TestMaterial::testInitialize(void) { const PetscDM dmSoln = solution.dmMesh();CPPUNIT_ASSERT(dmSoln); pylith::topology::FieldQuery solnQuery(solution); solnQuery.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(data->normalizer); - solnQuery.openDB(data->solnDB, data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(data->scales); + solnQuery.openDB(data->solnDB, data->scales->getLengthScale()); err = DMPlexComputeL2DiffLocal(dmSoln, t, solnQuery.functions(), (void**)solnQuery.contextPtrs(), solution.localVector(), &norm);CPPUNIT_ASSERT(!err); solnQuery.closeDB(data->solnDB); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Discretized solution field failed representation test.", 0.0, norm, tolerance); @@ -253,8 +253,8 @@ pylith::materials::TestMaterial::testInitialize(void) { const PetscDM dmPerturb = perturbation.dmMesh();CPPUNIT_ASSERT(dmPerturb); pylith::topology::FieldQuery perturbQuery(perturbation); perturbQuery.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(data->normalizer); - perturbQuery.openDB(data->perturbDB, data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(data->scales); + perturbQuery.openDB(data->perturbDB, data->scales->getLengthScale()); err = DMPlexComputeL2DiffLocal(dmPerturb, t, perturbQuery.functions(), (void**)perturbQuery.contextPtrs(), perturbation.localVector(), &norm);CPPUNIT_ASSERT(!err); perturbQuery.closeDB(data->perturbDB); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Discretized perturbation field failed representation test.", 0.0, norm, tolerance); @@ -596,8 +596,8 @@ pylith::materials::TestMaterial::testUpdateStateVars(void) { const PetscDM dm = auxField->dmMesh();CPPUNIT_ASSERT(dm); pylith::topology::FieldQuery query(*auxField); query.initializeWithDefaultQueryFns(); - CPPUNIT_ASSERT(data->normalizer); - query.openDB(data->auxUpdateDB, data->normalizer->getLengthScale()); + CPPUNIT_ASSERT(data->scales); + query.openDB(data->auxUpdateDB, data->scales->getLengthScale()); #if 0 // :DEBUG: PetscOptionsSetValue(NULL, "-dm_plex_print_l2", "1"); // :DEBUG: DMSetFromOptions(dm); // :DEBUG: @@ -630,11 +630,11 @@ pylith::materials::TestMaterial::_initializeMin(void) { // Setup coordinates. _mesh->setCoordSys(data->cs); - CPPUNIT_ASSERT(data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *data->normalizer); + CPPUNIT_ASSERT(data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *data->scales); // id and label initialized in derived class - material->normalizer(*data->normalizer); + material->scales(*data->scales); material->gravityField(data->gravityField); // Setup solution fields. @@ -726,7 +726,7 @@ pylith::materials::TestMaterial_Data::TestMaterial_Data(void) : cs(NULL), gravityField(NULL), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), t(0.0), dt(0.0), @@ -745,7 +745,7 @@ pylith::materials::TestMaterial_Data::TestMaterial_Data(void) : auxUpdateDB(NULL), isExplicit(false) { // constructor - CPPUNIT_ASSERT(normalizer); + CPPUNIT_ASSERT(scales); CPPUNIT_ASSERT(solnDB); solnDB->setLabel("solution"); @@ -763,7 +763,7 @@ pylith::materials::TestMaterial_Data::TestMaterial_Data(void) : pylith::materials::TestMaterial_Data::~TestMaterial_Data(void) { delete cs;cs = NULL; delete gravityField;gravityField = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; delete solnDB;solnDB = NULL; delete auxDB;auxDB = NULL; delete auxUpdateDB;auxUpdateDB = NULL; diff --git a/tests/libtests/materials/TestMaterial.hh b/tests/libtests/materials/TestMaterial.hh index 5a2cf4b265..ccf801f283 100644 --- a/tests/libtests/materials/TestMaterial.hh +++ b/tests/libtests/materials/TestMaterial.hh @@ -18,7 +18,7 @@ #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA UserFunctionDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA CoordSys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales /// Namespace for pylith package namespace pylith { @@ -37,7 +37,7 @@ class pylith::materials::TestMaterial : public CppUnit::TestFixture, public pyli CPPUNIT_TEST(testAuxField); CPPUNIT_TEST(testAuxSubfieldDiscretization); CPPUNIT_TEST(testAuxFieldDB); - CPPUNIT_TEST(testNormalizer); + CPPUNIT_TEST(testScales); CPPUNIT_TEST(testVerifyConfiguration); @@ -71,8 +71,8 @@ public: /// Test auxFieldDB(). void testAuxFieldDB(void); - /// Test normalizer(). - void testNormalizer(void); + /// Test scales(). + void testScales(void); /// Test verifyConfiguration(). void testVerifyConfiguration(void); @@ -163,7 +163,7 @@ public: spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. spatialdata::spatialdb::GravityField* gravityField; ///< Gravity field. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. PylithReal t; ///< Time for solution in simulation. PylithReal dt; ///< Time step in simulation. diff --git a/tests/libtests/meshio/TestDataWriterHDF5ExtPoints.cc b/tests/libtests/meshio/TestDataWriterHDF5ExtPoints.cc index 7d676d3a1d..f8ef1791da 100644 --- a/tests/libtests/meshio/TestDataWriterHDF5ExtPoints.cc +++ b/tests/libtests/meshio/TestDataWriterHDF5ExtPoints.cc @@ -19,7 +19,7 @@ #include "pylith/meshio/OutputSubfield.hh" // USES OutputSubfield #include "pylith/utils/error.hh" // USES PYLITH_METHOD* -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" #include "catch2/matchers/catch_matchers_floating_point.hpp" diff --git a/tests/libtests/meshio/TestDataWriterHDF5Points.cc b/tests/libtests/meshio/TestDataWriterHDF5Points.cc index 0ff2d89a32..cdf5506f56 100644 --- a/tests/libtests/meshio/TestDataWriterHDF5Points.cc +++ b/tests/libtests/meshio/TestDataWriterHDF5Points.cc @@ -19,7 +19,7 @@ #include "pylith/meshio/OutputSubfield.hh" // USES OutputSubfield #include "pylith/utils/error.hh" // USES PYLITH_METHOD_* -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" #include "catch2/matchers/catch_matchers_floating_point.hpp" diff --git a/tests/libtests/meshio/TestDataWriterMaterial.cc b/tests/libtests/meshio/TestDataWriterMaterial.cc index 2bf614659b..5a1c91f4b4 100644 --- a/tests/libtests/meshio/TestDataWriterMaterial.cc +++ b/tests/libtests/meshio/TestDataWriterMaterial.cc @@ -24,7 +24,7 @@ #include "pylith/meshio/DataWriter.hh" // USES DataWriter #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ------------------------------------------------------------------------------------------------ // Constructor. @@ -55,7 +55,7 @@ pylith::meshio::TestDataWriterMaterial::setDataTri(TestDataWriterMaterial_Data* data->faultLabel = "fault"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -100,7 +100,7 @@ pylith::meshio::TestDataWriterMaterial::setDataQuad(TestDataWriterMaterial_Data* data->meshFilename = "data/quad4.mesh"; data->materialId = 2; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -146,7 +146,7 @@ pylith::meshio::TestDataWriterMaterial::setDataTet(TestDataWriterMaterial_Data* data->faultLabel = "fault"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -195,7 +195,7 @@ pylith::meshio::TestDataWriterMaterial::setDataHex(TestDataWriterMaterial_Data* data->faultLabel = "fault"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -258,9 +258,9 @@ pylith::meshio::TestDataWriterMaterial::_initialize(void) { cs.setSpaceDim(_domainMesh->getDimension()); _domainMesh->setCoordSys(&cs); - spatialdata::units::Nondimensional normalizer; - normalizer.setLengthScale(data->lengthScale); - pylith::topology::MeshOps::nondimensionalize(_domainMesh, normalizer); + pylith::scales::Scales scales; + scales.setLengthScale(data->lengthScale); + pylith::topology::MeshOps::nondimensionalize(_domainMesh, scales); if (data->faultLabel) { pylith::faults::FaultCohesiveStub fault; diff --git a/tests/libtests/meshio/TestDataWriterMesh.cc b/tests/libtests/meshio/TestDataWriterMesh.cc index e502e926ac..a8dd335bea 100644 --- a/tests/libtests/meshio/TestDataWriterMesh.cc +++ b/tests/libtests/meshio/TestDataWriterMesh.cc @@ -24,7 +24,7 @@ #include "pylith/meshio/DataWriter.hh" // USES DataWriter #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ------------------------------------------------------------------------------------------------ // Constructor. @@ -52,7 +52,7 @@ pylith::meshio::TestDataWriterMesh::setDataTri(TestDataWriter_Data* data) { data->faultLabel = "fault"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -97,7 +97,7 @@ pylith::meshio::TestDataWriterMesh::setDataQuad(TestDataWriter_Data* data) { // We do not use a fault in this test case. data->meshFilename = "data/quad4.mesh"; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -143,7 +143,7 @@ pylith::meshio::TestDataWriterMesh::setDataTet(TestDataWriter_Data* data) { data->faultLabel = "fault"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -191,7 +191,7 @@ pylith::meshio::TestDataWriterMesh::setDataHex(TestDataWriter_Data* data) { data->faultLabel = "fault"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -255,9 +255,9 @@ pylith::meshio::TestDataWriterMesh::_initialize(void) { cs.setSpaceDim(_mesh->getDimension()); _mesh->setCoordSys(&cs); - spatialdata::units::Nondimensional normalizer; - normalizer.setLengthScale(data->lengthScale); - pylith::topology::MeshOps::nondimensionalize(_mesh, normalizer); + pylith::scales::Scales scales; + scales.setLengthScale(data->lengthScale); + pylith::topology::MeshOps::nondimensionalize(_mesh, scales); if (data->faultLabel) { pylith::faults::FaultCohesiveStub fault; diff --git a/tests/libtests/meshio/TestDataWriterPoints.cc b/tests/libtests/meshio/TestDataWriterPoints.cc index a40b464107..0818489ddf 100644 --- a/tests/libtests/meshio/TestDataWriterPoints.cc +++ b/tests/libtests/meshio/TestDataWriterPoints.cc @@ -23,7 +23,7 @@ #include "pylith/utils/error.hh" // USES PYLITH_METHOD* #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // ------------------------------------------------------------------------------------------------ // Constructor. @@ -51,7 +51,7 @@ pylith::meshio::TestDataWriterPoints::setDataTri(TestDataWriterPoints_Data* data data->faultLabel = "fault"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -91,7 +91,7 @@ pylith::meshio::TestDataWriterPoints::setDataQuad(TestDataWriterPoints_Data* dat data->meshFilename = "data/quad4.mesh"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -130,7 +130,7 @@ pylith::meshio::TestDataWriterPoints::setDataTet(TestDataWriterPoints_Data* data data->meshFilename = "data/tet4.mesh"; data->faultId = 100; data->spaceDim = 3; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -171,7 +171,7 @@ pylith::meshio::TestDataWriterPoints::setDataHex(TestDataWriterPoints_Data* data data->meshFilename = "data/hex8.mesh"; data->faultId = 100; data->spaceDim = 3; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -219,9 +219,9 @@ pylith::meshio::TestDataWriterPoints::_initialize(void) { delete _pointMesh;_pointMesh = pylith::topology::MeshOps::createFromPoints( data->points, data->numPoints, &cs, data->lengthScale, PETSC_COMM_WORLD, "points"); - spatialdata::units::Nondimensional normalizer; - normalizer.setLengthScale(data->lengthScale); - pylith::topology::MeshOps::nondimensionalize(_pointMesh, normalizer); + pylith::scales::Scales scales; + scales.setLengthScale(data->lengthScale); + pylith::topology::MeshOps::nondimensionalize(_pointMesh, scales); PYLITH_METHOD_END; } // _initialize diff --git a/tests/libtests/meshio/TestDataWriterSubmesh.cc b/tests/libtests/meshio/TestDataWriterSubmesh.cc index 1803730c6f..5bc02b439e 100644 --- a/tests/libtests/meshio/TestDataWriterSubmesh.cc +++ b/tests/libtests/meshio/TestDataWriterSubmesh.cc @@ -24,7 +24,7 @@ #include "pylith/meshio/DataWriter.hh" // USES DataWriter #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES assert() @@ -57,7 +57,7 @@ pylith::meshio::TestDataWriterSubmesh::setDataTri(TestDataWriterSubmesh_Data* da data->faultLabel = "fault"; data->faultId = 100; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -102,7 +102,7 @@ pylith::meshio::TestDataWriterSubmesh::setDataQuad(TestDataWriterSubmesh_Data* d data->meshFilename = "data/quad4.mesh"; data->bcLabel = "bc3"; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -147,7 +147,7 @@ pylith::meshio::TestDataWriterSubmesh::setDataTet(TestDataWriterSubmesh_Data* da data->meshFilename = "data/tet4.mesh"; data->bcLabel = "boundary"; data->spaceDim = 3; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -191,7 +191,7 @@ pylith::meshio::TestDataWriterSubmesh::setDataHex(TestDataWriterSubmesh_Data* da data->meshFilename = "data/hex8.mesh"; data->bcLabel = "top"; data->spaceDim = 2; - data->lengthScale = 10.0; + data->lengthScale = 0.1; data->time = 1.0; data->timeFormat = "%3.1f"; @@ -251,9 +251,9 @@ pylith::meshio::TestDataWriterSubmesh::_initialize(void) { cs.setSpaceDim(_mesh->getDimension()); _mesh->setCoordSys(&cs); - spatialdata::units::Nondimensional normalizer; - normalizer.setLengthScale(data->lengthScale); - pylith::topology::MeshOps::nondimensionalize(_mesh, normalizer); + pylith::scales::Scales scales; + scales.setLengthScale(data->lengthScale); + pylith::topology::MeshOps::nondimensionalize(_mesh, scales); if (data->faultLabel) { pylith::faults::FaultCohesiveStub fault; diff --git a/tests/libtests/meshio/TestDataWriterVTKPoints.cc b/tests/libtests/meshio/TestDataWriterVTKPoints.cc index b26cb37979..95ca3a2d6d 100644 --- a/tests/libtests/meshio/TestDataWriterVTKPoints.cc +++ b/tests/libtests/meshio/TestDataWriterVTKPoints.cc @@ -19,7 +19,7 @@ #include "pylith/meshio/OutputSubfield.hh" // USES OutputSubfield #include "pylith/utils/error.hh" // USES PYLITH_METHOD_* -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" #include "catch2/matchers/catch_matchers_floating_point.hpp" diff --git a/tests/libtests/meshio/TestMeshIO.cc b/tests/libtests/meshio/TestMeshIO.cc index 8fb487c165..23839d88a2 100644 --- a/tests/libtests/meshio/TestMeshIO.cc +++ b/tests/libtests/meshio/TestMeshIO.cc @@ -22,7 +22,7 @@ #include "pylith/utils/journals.hh" // USES journal::debug_t #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" #include "catch2/matchers/catch_matchers_floating_point.hpp" @@ -143,9 +143,9 @@ pylith::meshio::TestMeshIO::_createMesh(void) { cs.setSpaceDim(_data->geometry->spaceDim); _mesh->setCoordSys(&cs); - spatialdata::units::Nondimensional normalizer; - normalizer.setLengthScale(10.0); - topology::MeshOps::nondimensionalize(_mesh, normalizer); + pylith::scales::Scales scales; + scales.setLengthScale(0.01); + topology::MeshOps::nondimensionalize(_mesh, scales); pythia::journal::debug_t debug("TestMeshIO"); if (debug.state()) { diff --git a/tests/libtests/meshio/TestOutputSolnPoints.cc b/tests/libtests/meshio/TestOutputSolnPoints.cc index b821a172f1..40fba15921 100644 --- a/tests/libtests/meshio/TestOutputSolnPoints.cc +++ b/tests/libtests/meshio/TestOutputSolnPoints.cc @@ -22,7 +22,7 @@ #include "pylith/meshio/MeshIOCubit.hh" // USES MeshIOCubit #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "data/OutputSolnPointsDataTri3.hh" #include "data/OutputSolnPointsDataQuad4.hh" @@ -181,7 +181,7 @@ pylith::meshio::TestOutputSolnPoints::_testSetupInterpolator(const OutputSolnPoi topology::Mesh mesh; spatialdata::geocoords::CSCart cs; - spatialdata::units::Nondimensional normalizer; + pylith::scales::Scales scales; cs.setSpaceDim(spaceDim); mesh.setCoordSys(&cs); @@ -191,7 +191,7 @@ pylith::meshio::TestOutputSolnPoints::_testSetupInterpolator(const OutputSolnPoi OutputSolnPoints output; CPPUNIT_ASSERT(data.points); - output.setupInterpolator(&mesh, data.points, numPoints, spaceDim, data.names, numPoints, normalizer); + output.setupInterpolator(&mesh, data.points, numPoints, spaceDim, data.names, numPoints, scales); PetscDM dmMesh = output.pointsMesh().dmMesh();CPPUNIT_ASSERT(dmMesh); @@ -241,7 +241,7 @@ pylith::meshio::TestOutputSolnPoints::_testInterpolate(const OutputSolnPointsDat topology::Mesh mesh; spatialdata::geocoords::CSCart cs; - spatialdata::units::Nondimensional normalizer; + pylith::scales::Scales scales; cs.setSpaceDim(spaceDim); mesh.setCoordSys(&cs); @@ -251,7 +251,7 @@ pylith::meshio::TestOutputSolnPoints::_testInterpolate(const OutputSolnPointsDat OutputSolnPoints output; CPPUNIT_ASSERT(data.points); - output.setupInterpolator(&mesh, data.points, numPoints, spaceDim, data.names, numPoints, normalizer); + output.setupInterpolator(&mesh, data.points, numPoints, spaceDim, data.names, numPoints, scales); // Create field with data. const char* fieldName = "data_field"; diff --git a/tests/libtests/problems/TestPhysics.cc b/tests/libtests/problems/TestPhysics.cc index 5c15ee9c5d..e1a4475ea1 100644 --- a/tests/libtests/problems/TestPhysics.cc +++ b/tests/libtests/problems/TestPhysics.cc @@ -24,7 +24,7 @@ #include "pylith/problems/ObserversPhysics.hh" // USES ObserversPhysics #include "spatialdata/spatialdb/UniformDB.hh" // USES UniformDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales // --------------------------------------------------------------------------------------------------------------------- CPPUNIT_TEST_SUITE_REGISTRATION(pylith::problems::TestPhysics); @@ -51,22 +51,22 @@ pylith::problems::TestPhysics::tearDown(void) { // --------------------------------------------------------------------------------------------------------------------- -// Test setNormalizer(). +// Test setScales(). void -pylith::problems::TestPhysics::testSetNormalizer(void) { +pylith::problems::TestPhysics::testSetScales(void) { PYLITH_METHOD_BEGIN; - spatialdata::units::Nondimensional normalizer; + pylith::scales::Scales scales; const PylithReal lengthScale = 3.0; - normalizer.setLengthScale(lengthScale); + scales.setLengthScale(lengthScale); CPPUNIT_ASSERT(_physics); - _physics->setNormalizer(normalizer); + _physics->setScales(scales); - CPPUNIT_ASSERT_DOUBLES_EQUAL(lengthScale, _physics->_normalizer->getLengthScale(), 1.0e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(lengthScale, _physics->_scales->getLengthScale(), 1.0e-6); PYLITH_METHOD_END; -} // testSetNormalizer +} // testSetScales // --------------------------------------------------------------------------------------------------------------------- diff --git a/tests/libtests/problems/TestPhysics.hh b/tests/libtests/problems/TestPhysics.hh index dd1a8d460a..92e92d42b1 100644 --- a/tests/libtests/problems/TestPhysics.hh +++ b/tests/libtests/problems/TestPhysics.hh @@ -25,7 +25,7 @@ class pylith::problems::TestPhysics : public CppUnit::TestFixture { // CPPUNIT TEST SUITE ////////////////////////////////////////////////////////////////////////////////////////////// CPPUNIT_TEST_SUITE(TestPhysics); - CPPUNIT_TEST(testSetNormalizer); + CPPUNIT_TEST(testSetScales); CPPUNIT_TEST(testSetAuxiliaryFieldDB); CPPUNIT_TEST(testSetAuxiliarySubfieldDiscretization); CPPUNIT_TEST(testObservers); @@ -47,8 +47,8 @@ public: /// Tear down testing data. void tearDown(void); - /// Test setNormalizer(). - void testSetNormalizer(void); + /// Test setScales(). + void testSetScales(void); /// Test setAuxiliaryFieldDB(). void testSetAuxiliaryFieldDB(void); diff --git a/tests/libtests/problems/TestSolutionFactory.cc b/tests/libtests/problems/TestSolutionFactory.cc index 66a2552be1..0d4d8d2d95 100644 --- a/tests/libtests/problems/TestSolutionFactory.cc +++ b/tests/libtests/problems/TestSolutionFactory.cc @@ -23,7 +23,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" @@ -34,11 +34,10 @@ pylith::problems::TestSolutionFactory::TestSolutionFactory(TestSolutionFactory_D PYLITH_METHOD_BEGIN; assert(_data); - assert(_data->normalizer); - _data->normalizer->setLengthScale(1.0e+03); - _data->normalizer->setTimeScale(2.0); - _data->normalizer->setDensityScale(3.0e+3); - _data->normalizer->setPressureScale(2.25e+10); + assert(_data->scales); + _data->scales->setLengthScale(1.0); + _data->scales->setTimeScale(2.0); + _data->scales->setRigidityScale(2.25e+6); pylith::topology::Field::SubfieldInfo info; pylith::string_vector componentNames; @@ -54,7 +53,7 @@ pylith::problems::TestSolutionFactory::TestSolutionFactory(TestSolutionFactory_D componentNames, componentNames.size(), pylith::topology::Field::VECTOR, - _data->normalizer->getLengthScale() + _data->scales->getLengthScale() ); info.fe = pylith::topology::Field::Discretization( 1, 2, -1, -1, false, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POLYNOMIAL_SPACE, true @@ -74,7 +73,7 @@ pylith::problems::TestSolutionFactory::TestSolutionFactory(TestSolutionFactory_D componentNames, componentNames.size(), pylith::topology::Field::VECTOR, - _data->normalizer->getLengthScale() / _data->normalizer->getTimeScale() + _data->scales->getLengthScale() / _data->scales->getTimeScale() ); info.fe = pylith::topology::Field::Discretization( 2, 3, -1, -1, false, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POLYNOMIAL_SPACE, false @@ -92,7 +91,7 @@ pylith::problems::TestSolutionFactory::TestSolutionFactory(TestSolutionFactory_D componentNames, componentNames.size(), pylith::topology::Field::SCALAR, - _data->normalizer->getPressureScale() + _data->scales->getRigidityScale() ); info.fe = pylith::topology::Field::Discretization( 2, 2, -1, -1, false, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POLYNOMIAL_SPACE, true @@ -109,7 +108,7 @@ pylith::problems::TestSolutionFactory::TestSolutionFactory(TestSolutionFactory_D componentNames, componentNames.size(), pylith::topology::Field::SCALAR, - _data->normalizer->getLengthScale() / _data->normalizer->getLengthScale() + _data->scales->getLengthScale() / _data->scales->getLengthScale() ); info.fe = pylith::topology::Field::Discretization( 2, 2, -1, -1, false, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POLYNOMIAL_SPACE, true @@ -128,7 +127,7 @@ pylith::problems::TestSolutionFactory::TestSolutionFactory(TestSolutionFactory_D componentNames, componentNames.size(), pylith::topology::Field::VECTOR, - _data->normalizer->getPressureScale() + _data->scales->getRigidityScale() ); info.fe = pylith::topology::Field::Discretization( 2, 2, -1, -1, true, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POLYNOMIAL_SPACE, true @@ -146,7 +145,7 @@ pylith::problems::TestSolutionFactory::TestSolutionFactory(TestSolutionFactory_D componentNames, componentNames.size(), pylith::topology::Field::SCALAR, - _data->normalizer->getTemperatureScale() + _data->scales->getTemperatureScale() ); info.fe = pylith::topology::Field::Discretization( 2, 3, -1, -1, false, pylith::topology::Field::DEFAULT_BASIS, pylith::topology::Field::POINT_SPACE, true @@ -274,7 +273,7 @@ pylith::problems::TestSolutionFactory::testSetValues(void) { assert(_data->solutionDB); _factory->setValues(_data->solutionDB); - pylith::testing::FieldTester::checkFieldWithDB(*_solution, _data->solutionDB, _data->normalizer->getLengthScale()); + pylith::testing::FieldTester::checkFieldWithDB(*_solution, _data->solutionDB, _data->scales->getLengthScale()); PYLITH_METHOD_END; } // testSetValues @@ -299,12 +298,12 @@ pylith::problems::TestSolutionFactory::_initialize(void) { // Setup coordinates. _mesh->setCoordSys(_data->cs); - assert(_data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->normalizer); + assert(_data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->scales); _solution = new pylith::topology::Field(*_mesh);assert(_solution); _solution->setLabel("solution"); - _factory = new SolutionFactory(*_solution, *_data->normalizer); + _factory = new SolutionFactory(*_solution, *_data->scales); PYLITH_METHOD_END; } // _initialize @@ -314,14 +313,14 @@ pylith::problems::TestSolutionFactory::_initialize(void) { pylith::problems::TestSolutionFactory_Data::TestSolutionFactory_Data(void) : meshFilename(NULL), cs(NULL), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), solutionDB(new spatialdata::spatialdb::UserFunctionDB) {} // ------------------------------------------------------------------------------------------------ pylith::problems::TestSolutionFactory_Data::~TestSolutionFactory_Data(void) { delete cs;cs = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; delete solutionDB;solutionDB = NULL; } diff --git a/tests/libtests/problems/TestSolutionFactory.hh b/tests/libtests/problems/TestSolutionFactory.hh index e44150cc76..30e2793119 100644 --- a/tests/libtests/problems/TestSolutionFactory.hh +++ b/tests/libtests/problems/TestSolutionFactory.hh @@ -15,7 +15,7 @@ #include "pylith/topology/Field.hh" // HOLDSA Field::SubfieldInfo #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA SpatialDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA Coordsys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales #include // USES std::map @@ -87,7 +87,7 @@ public: size_t dimension; ///< Spatial dimension. const char* meshFilename; ///< Name of file with ASCII mesh. spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. std::map subfields; spatialdata::spatialdb::UserFunctionDB* solutionDB; ///< Spatial database with values for solution. diff --git a/tests/libtests/problems/TestSolutionFactory_Cases.cc b/tests/libtests/problems/TestSolutionFactory_Cases.cc index 9f6a070856..8372730f70 100644 --- a/tests/libtests/problems/TestSolutionFactory_Cases.cc +++ b/tests/libtests/problems/TestSolutionFactory_Cases.cc @@ -15,7 +15,7 @@ #include "pylith/problems/SolutionFactory.hh" // USES SolutionFactory #include "spatialdata/geocoords/CSCart.hh" // USES CSCart #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" diff --git a/tests/libtests/scales/Makefile.am b/tests/libtests/scales/Makefile.am new file mode 100644 index 0000000000..d9297012e9 --- /dev/null +++ b/tests/libtests/scales/Makefile.am @@ -0,0 +1,22 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +include $(top_srcdir)/tests/check_catch2.am + +TESTS = libtest_scales + +check_PROGRAMS = libtest_scales + +libtest_scales_SOURCES = \ + TestScales.cc \ + $(top_srcdir)/tests/src/driver_catch2.cc + + +# End of file diff --git a/tests/libtests/scales/TestScales.cc b/tests/libtests/scales/TestScales.cc new file mode 100644 index 0000000000..b1d383b1f8 --- /dev/null +++ b/tests/libtests/scales/TestScales.cc @@ -0,0 +1,203 @@ +// ================================================================================================= +// This code is part of SpatialData, developed through the Computational Infrastructure +// for Geodynamics (https://github.com/geodynamics/spatialdata). +// +// Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +// All rights reserved. +// +// See https://mit-license.org/ and LICENSE.md and for license information. +// ================================================================================================= + +#include + +#include "pylith/scales/Scales.hh" // USES Scales + +#include "catch2/catch_test_macros.hpp" +#include "catch2/matchers/catch_matchers_floating_point.hpp" + +#include // USES fabs() +#include // USES std::valarray + +// ------------------------------------------------------------------------------------------------ +namespace pylith { + namespace scales { + class TestScales; + } // scales +} // pylith + +class pylith::scales::TestScales { + // PUBLIC METHODS ///////////////////////////////////////////////////////////////////////////// +public: + + /// Test constructors. + static + void testConstructors(void); + + /// Test accessors. + static + void testAccessors(void); + + /// Test nondimensionalize() and dimensionalize(). + static + void testNondimensionalize(void); + + /// Test Scalesie() and dimensionalize() with arrays. + static + void testNondimensionalizeArray(void); + +}; // class TestScales + +// ------------------------------------------------------------------------------------------------ +TEST_CASE("TestScales::testConstructors", "[TestScales]") { + pylith::scales::TestScales::testConstructors(); +} +TEST_CASE("TestScales::testAccessors", "[TestScales]") { + pylith::scales::TestScales::testAccessors(); +} +TEST_CASE("TestScales::testNondimensionalize", "[TestScales]") { + pylith::scales::TestScales::testNondimensionalize(); +} +TEST_CASE("TestScales::testNondimensionalizeArray", "[TestScales]") { + pylith::scales::TestScales::testNondimensionalizeArray(); +} + +// ------------------------------------------------------------------------------------------------ +// Test constructor. +void +pylith::scales::TestScales::testConstructors(void) { + const double defaultLength = 1.0; + const double defaultDisplacement = 1.0; + const double defaultPressure = 1.0; + const double defaultTime = 1.0; + const double defaultTemperature = 1.0; + + Scales scales; + CHECK(defaultLength == scales._length); + CHECK(defaultDisplacement == scales._displacement); + CHECK(defaultPressure == scales._rigidity); + CHECK(defaultTime == scales._time); + CHECK(defaultTemperature == scales._temperature); + + scales._length = 2.0; + scales._displacement = 2.1; + scales._rigidity = 3.0; + scales._time = 4.0; + scales._temperature = 5.0; + Scales scalesCopy(scales); + CHECK(scales._length == scalesCopy._length); + CHECK(scales._displacement == scalesCopy._displacement); + CHECK(scales._rigidity == scalesCopy._rigidity); + CHECK(scales._time == scalesCopy._time); + CHECK(scales._temperature == scalesCopy._temperature); + + Scales scalesAssign; + scalesAssign = scales; + CHECK(scales._length == scalesAssign._length); + CHECK(scales._displacement == scalesAssign._displacement); + CHECK(scales._rigidity == scalesAssign._rigidity); + CHECK(scales._time == scalesAssign._time); + CHECK(scales._temperature == scalesAssign._temperature); +} // testConstructors + + +// ------------------------------------------------------------------------------------------------ +// Test accessors. +void +pylith::scales::TestScales::testAccessors(void) { + const double length = 4.0; + const double displacement = 4.1; + const double pressure = 5.0; + const double time = 6.0; + const double temperature = 8.0; + + Scales scales; + + // Length scale + INFO("Testing setting length scale."); + scales.setLengthScale(length); + CHECK(length == scales.getLengthScale()); + CHECK(1.0 == scales.getDisplacementScale()); + CHECK(1.0 == scales.getRigidityScale()); + CHECK(1.0 == scales.getTimeScale()); + CHECK(1.0 == scales.getTemperatureScale()); + + // Displacement scale + INFO("Testing setting displacement scale."); + scales.setDisplacementScale(displacement); + CHECK(length == scales.getLengthScale()); + CHECK(displacement == scales.getDisplacementScale()); + CHECK(1.0 == scales.getRigidityScale()); + CHECK(1.0 == scales.getTimeScale()); + CHECK(1.0 == scales.getTemperatureScale()); + + // Pressure scale + INFO("Testing setting pressure scale."); + scales.setRigidityScale(pressure); + CHECK(length == scales.getLengthScale()); + CHECK(displacement == scales.getDisplacementScale()); + CHECK(pressure == scales.getRigidityScale()); + CHECK(1.0 == scales.getTimeScale()); + CHECK(1.0 == scales.getTemperatureScale()); + + // Time scale + INFO("Testing setting time scale."); + scales.setTimeScale(time); + CHECK(length == scales.getLengthScale()); + CHECK(displacement == scales.getDisplacementScale()); + CHECK(pressure == scales.getRigidityScale()); + CHECK(time == scales.getTimeScale()); + CHECK(1.0 == scales.getTemperatureScale()); + + // Temperature scale + INFO("Testing setting temperature scale."); + scales.setTemperatureScale(temperature); + CHECK(length == scales.getLengthScale()); + CHECK(displacement == scales.getDisplacementScale()); + CHECK(pressure == scales.getRigidityScale()); + CHECK(time == scales.getTimeScale()); + CHECK(temperature == scales.getTemperatureScale()); +} // testAccessors + + +// ------------------------------------------------------------------------------------------------ +// Test nondimensionalize() and dimensionalize(). +void +pylith::scales::TestScales::testNondimensionalize(void) { + const double scale = 4.0; + const double value = 3.0; + const double valueE = 0.75; + + Scales scales; + const double tolerance = 1.0e-6; + CHECK_THAT(scales.nondimensionalize(value, scale), Catch::Matchers::WithinAbs(valueE, tolerance)); + CHECK_THAT(scales.dimensionalize(valueE, scale), Catch::Matchers::WithinAbs(value, tolerance)); +} // testNondimensionalize + + +// ------------------------------------------------------------------------------------------------ +// Test nondimensionalize() and dimensionalize() with arrays. +void +pylith::scales::TestScales::testNondimensionalizeArray(void) { + const double scale = 10.0; + const size_t nvalues = 3; + const double values[nvalues] = { 2.0, 5.0, 7.0 }; + const double valuesE[nvalues] = { 0.2, 0.5, 0.7 }; + + Scales scales; + + std::valarray v(values, nvalues); + scales.nondimensionalize(&v[0], nvalues, scale); + const double tolerance = 1.0e-6; + for (size_t i = 0; i < nvalues; ++i) { + CHECK_THAT(v[i], Catch::Matchers::WithinAbs(valuesE[i], tolerance)); + } // for + + v = std::valarray(valuesE, nvalues); + scales.dimensionalize(&v[0], nvalues, scale); + for (size_t i = 0; i < nvalues; ++i) { + CHECK_THAT(v[i], Catch::Matchers::WithinAbs(values[i], tolerance)); + } // for +} // testNondimensionalizeArray + + +// End of file diff --git a/tests/libtests/topology/TestFieldQuery.cc b/tests/libtests/topology/TestFieldQuery.cc index 6b7fb53f6f..08abcb5bd5 100644 --- a/tests/libtests/topology/TestFieldQuery.cc +++ b/tests/libtests/topology/TestFieldQuery.cc @@ -22,7 +22,7 @@ #include "spatialdata/geocoords/CSCart.hh" // USES CSCart #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" #include "catch2/matchers/catch_matchers_floating_point.hpp" @@ -193,7 +193,7 @@ pylith::topology::TestFieldQuery::testOpenClose(void) { _query->initializeWithDefaultQueries(); // Test with non-NULL database. - _query->openDB(_data->auxDB, _data->normalizer->getLengthScale()); + _query->openDB(_data->auxDB, _data->scales->getLengthScale()); _query->closeDB(_data->auxDB); // Nothing to verify. @@ -214,11 +214,11 @@ pylith::topology::TestFieldQuery::testQuery(void) { assert(_query); assert(_field); assert(_data); - assert(_data->normalizer); + assert(_data->scales); _query->initializeWithDefaultQueries(); - _query->openDB(_data->auxDB, _data->normalizer->getLengthScale()); + _query->openDB(_data->auxDB, _data->scales->getLengthScale()); _query->queryDB(); _query->closeDB(_data->auxDB); @@ -230,7 +230,7 @@ pylith::topology::TestFieldQuery::testQuery(void) { const PylithReal t = 0.0; pylith::topology::FieldQuery query(*_field); query.initializeWithDefaultQueries(); - query.openDB(_data->auxDB, _data->normalizer->getLengthScale()); + query.openDB(_data->auxDB, _data->scales->getLengthScale()); PetscErrorCode err = DMPlexComputeL2DiffLocal(_field->getDM(), t, query._functions, (void**)query._contextPtrs, _field->getLocalVector(), &norm);REQUIRE(!err); query.closeDB(_data->auxDB); @@ -317,8 +317,8 @@ pylith::topology::TestFieldQuery::_initialize(void) { assert(_data->cs); _mesh->setCoordSys(_data->cs); - assert(_data->normalizer); - pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->normalizer); + assert(_data->scales); + pylith::topology::MeshOps::nondimensionalize(_mesh, *_data->scales); // Setup field delete _field;_field = new pylith::topology::Field(*_mesh);assert(_field); @@ -346,7 +346,7 @@ pylith::topology::TestFieldQuery_Data::TestFieldQuery_Data(void) : topology(NULL), geometry(NULL), cs(new spatialdata::geocoords::CSCart), - normalizer(new spatialdata::units::Nondimensional), + scales(new pylith::scales::Scales), numAuxSubfields(0), auxSubfields(NULL), auxDescriptions(NULL), @@ -362,7 +362,7 @@ pylith::topology::TestFieldQuery_Data::~TestFieldQuery_Data(void) { delete geometry;geometry = NULL; delete cs;cs = NULL; - delete normalizer;normalizer = NULL; + delete scales;scales = NULL; auxSubfields = NULL; // Assigned from const. auxDescriptions = NULL; // Assigned from const. diff --git a/tests/libtests/topology/TestFieldQuery.hh b/tests/libtests/topology/TestFieldQuery.hh index df870f7c32..2f07e3a0ca 100644 --- a/tests/libtests/topology/TestFieldQuery.hh +++ b/tests/libtests/topology/TestFieldQuery.hh @@ -18,7 +18,7 @@ #include "spatialdata/spatialdb/spatialdbfwd.hh" // HOLDSA UserFunctionDB #include "spatialdata/geocoords/geocoordsfwd.hh" // HOLDSA CoordSys -#include "spatialdata/units/unitsfwd.hh" // HOLDSA Nondimensional +#include "pylith/scales/scalesfwd.hh" // HOLDSA Scales namespace pylith { namespace topology { @@ -94,7 +94,7 @@ public: pylith::meshio::MeshBuilder::Topology* topology; ///< Topology for domain mesh pylith::meshio::MeshBuilder::Geometry* geometry; ///< Geometry for domain mesh spatialdata::geocoords::CoordSys* cs; ///< Coordinate system. - spatialdata::units::Nondimensional* normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales* scales; ///< Scales for nondimensionalization. /// @defgroup Subfield discretization information /// @{ diff --git a/tests/libtests/topology/TestFieldQuery_Cases.cc b/tests/libtests/topology/TestFieldQuery_Cases.cc index 518f96f830..700e79d3f9 100644 --- a/tests/libtests/topology/TestFieldQuery_Cases.cc +++ b/tests/libtests/topology/TestFieldQuery_Cases.cc @@ -17,7 +17,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "catch2/catch_test_macros.hpp" @@ -120,11 +120,10 @@ TEST_CASE("TestFieldQuery::Quad::testValidatorNonnegative", "[TestFieldQuery][Tr // ------------------------------------------------------------------------------------------------ void pylith::topology::TestFieldQuery_Cases::_setData(TestFieldQuery_Data* data) { - assert(data->normalizer); - data->normalizer->setLengthScale(1.0); - data->normalizer->setTimeScale(10.0); - data->normalizer->setPressureScale(0.1); - data->normalizer->setDensityScale(2.0); + assert(data->scales); + data->scales->setLengthScale(0.02); + data->scales->setTimeScale(10.0); + data->scales->setRigidityScale(1.0e+6); data->numAuxSubfields = 2; static const char* auxSubfields[2] = { "displacement", "temperature" }; diff --git a/tests/libtests/topology/TestMeshOps.cc b/tests/libtests/topology/TestMeshOps.cc index 8fbd3dfd8d..f00ca10a06 100644 --- a/tests/libtests/topology/TestMeshOps.cc +++ b/tests/libtests/topology/TestMeshOps.cc @@ -20,7 +20,7 @@ #include "pylith/meshio/MeshIOAscii.hh" // USES MeshIOAscii #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include // USES std::runtime_error @@ -77,7 +77,7 @@ void pylith::topology::TestMeshOps::testNondimensionalize(void) { PYLITH_METHOD_BEGIN; - const PylithScalar lengthScale = 2.0; + const PylithScalar lengthScale = 0.02; const int spaceDim = 2; const int numVertices = 4; const PylithScalar coordinates[numVertices*spaceDim] = { @@ -95,9 +95,9 @@ pylith::topology::TestMeshOps::testNondimensionalize(void) { spatialdata::geocoords::CSCart cs; cs.setSpaceDim(2); mesh.setCoordSys(&cs); - spatialdata::units::Nondimensional normalizer; - normalizer.setLengthScale(lengthScale); - MeshOps::nondimensionalize(&mesh, normalizer); + pylith::scales::Scales scales; + scales.setLengthScale(lengthScale); + MeshOps::nondimensionalize(&mesh, scales); // Get vertices PetscDM dmMesh = mesh.getDM();assert(dmMesh); diff --git a/tests/manual/2d/faultstrip/pylithapp.cfg b/tests/manual/2d/faultstrip/pylithapp.cfg index 2622ed4804..5eef7c7a26 100644 --- a/tests/manual/2d/faultstrip/pylithapp.cfg +++ b/tests/manual/2d/faultstrip/pylithapp.cfg @@ -42,8 +42,8 @@ dimension = 2 formulation = pylith.problems.Explicit -normalizer = spatialdata.units.NondimElasticDynamic -normalizer.shear_wave_speed = 1.0*km/s +scales = pylith.scales.NondimElasticDynamic +scales.shear_wave_speed = 1.0*km/s [pylithapp.timedependent.formulation.time_step] total_time = 10.0*s diff --git a/tests/manual/2d/frictionslide/pylithapp.cfg b/tests/manual/2d/frictionslide/pylithapp.cfg index c063824762..a9d7b9b188 100644 --- a/tests/manual/2d/frictionslide/pylithapp.cfg +++ b/tests/manual/2d/frictionslide/pylithapp.cfg @@ -37,9 +37,7 @@ dimension = 2 formulation = pylith.problems.Implicit -normalizer = spatialdata.units.NondimElasticQuasistatic -normalizer.length_scale = 1.0*m -normalizer.relaxation_time = 0.1*s +scales.time_scale = 0.1*s [pylithapp.timedependent.implicit] solver = pylith.problems.SolverNonlinear diff --git a/tests/manual/2d/frictionslide/tension.cfg b/tests/manual/2d/frictionslide/tension.cfg index 52a03090ad..70ce28b2ae 100644 --- a/tests/manual/2d/frictionslide/tension.cfg +++ b/tests/manual/2d/frictionslide/tension.cfg @@ -7,7 +7,7 @@ [pylithapp.timedependent] bc = [ypos_shear,ypos_axial,yneg_shear,yneg_axial] -normalizer.length_scale = 1.0*mm +scales.length_scale = 1.0*mm [pylithapp.timedependent.implicit.time_step] total_time = 5.0*s diff --git a/tests/manual/2d/maxwell/pylithapp.cfg b/tests/manual/2d/maxwell/pylithapp.cfg index 8d02556729..9831dc47a8 100644 --- a/tests/manual/2d/maxwell/pylithapp.cfg +++ b/tests/manual/2d/maxwell/pylithapp.cfg @@ -41,7 +41,7 @@ debug = 1 # This is a time-dependent problem, so we select this as our problem type. # We select a total time of 1 year, and a time step size of 0.1 year. [pylithapp.timedependent] -normalizer.length_scale = 1.0*m +scales.length_scale = 1.0*m [pylithapp.timedependent.formulation.time_step] total_time = 100.0*year diff --git a/tests/manual/2d/maxwell_analytic/pylithapp.cfg b/tests/manual/2d/maxwell_analytic/pylithapp.cfg index e4b195b346..ef889254af 100644 --- a/tests/manual/2d/maxwell_analytic/pylithapp.cfg +++ b/tests/manual/2d/maxwell_analytic/pylithapp.cfg @@ -24,7 +24,8 @@ solver = nonlinear ; Use nonlinear solver to ensure residual and Jacobian are co initial_dt = 0.01*s start_time = -0.00*s total_time = 1.0*s -normalizer.relaxation_time = 0.1*s + +scales.time_scale = 0.1*s # Set the discretization and integration for each of the solution subfields. # diff --git a/tests/manual/2d/nonplanar/pylithapp.cfg b/tests/manual/2d/nonplanar/pylithapp.cfg index 4e3801b1ef..f2ba90e15f 100644 --- a/tests/manual/2d/nonplanar/pylithapp.cfg +++ b/tests/manual/2d/nonplanar/pylithapp.cfg @@ -45,7 +45,7 @@ dimension = 2 formulation = pylith.problems.ExplicitTri3 -normalizer = spatialdata.units.NondimElasticDynamic +scales = pylith.scales.NondimElasticDynamic [pylithapp.timedependent.formulation.time_step] total_time = 4.0*s diff --git a/tests/manual/2d/plasticity/compare3d/cyclic/pylithapp.cfg b/tests/manual/2d/plasticity/compare3d/cyclic/pylithapp.cfg index 8d7f654ecb..60476338c7 100644 --- a/tests/manual/2d/plasticity/compare3d/cyclic/pylithapp.cfg +++ b/tests/manual/2d/plasticity/compare3d/cyclic/pylithapp.cfg @@ -17,7 +17,7 @@ fiatlagrange = 1 # problem # ---------------------------------------------------------------------- [pylithapp.timedependent] -normalizer.length_scale = 1.0*m +scales.length_scale = 1.0*m [pylithapp.timedependent.formulation.time_step] total_time = 100.0*year diff --git a/tests/manual/2d/plasticity/compare3d/static/pylithapp.cfg b/tests/manual/2d/plasticity/compare3d/static/pylithapp.cfg index c3e88d1523..9bcf36c931 100644 --- a/tests/manual/2d/plasticity/compare3d/static/pylithapp.cfg +++ b/tests/manual/2d/plasticity/compare3d/static/pylithapp.cfg @@ -42,7 +42,7 @@ fiatlagrange = 1 # We select a total time of 1 year, and a time step size of 0.1 year. [pylithapp.timedependent] implicit.solver = pylith.problems.SolverNonlinear -normalizer.length_scale = 1.0*m +scales.length_scale = 1.0*m [pylithapp.timedependent.formulation.time_step] total_time = 100.0*year diff --git a/tests/manual/2d/stressoutput/pylithapp.cfg b/tests/manual/2d/stressoutput/pylithapp.cfg index e7c167fa9c..9b7172ce13 100644 --- a/tests/manual/2d/stressoutput/pylithapp.cfg +++ b/tests/manual/2d/stressoutput/pylithapp.cfg @@ -29,7 +29,7 @@ coordsys.space_dim = 2 # ---------------------------------------------------------------------- # Specify the problem settings. [pylithapp.timedependent] -normalizer.length_scale = 1.0*m +scales.length_scale = 1.0*m dimension = 2 [pylithapp.timedependent.formulation.time_step] diff --git a/tests/manual/3d/cyclicfriction/pylithapp.cfg b/tests/manual/3d/cyclicfriction/pylithapp.cfg index e810c1433e..01df2d47a7 100644 --- a/tests/manual/3d/cyclicfriction/pylithapp.cfg +++ b/tests/manual/3d/cyclicfriction/pylithapp.cfg @@ -35,9 +35,8 @@ filename = hex8_1000m.exo total_time = 90.0*hour ; total time of simulation dt = 1.0*hour -[pylithapp.timedependent.normalizer] -relaxation_time = 1.0*hour -length_scale = 1.0*km +[pylithapp.timedependent.scales] +time_scale = 1.0*hour [pylithapp.timedependent.implicit] solver = pylith.problems.SolverNonlinear diff --git a/tests/manual/3d/plasticity/dynamic/pylithapp.cfg b/tests/manual/3d/plasticity/dynamic/pylithapp.cfg index 1cc442a736..a3a38b0a12 100644 --- a/tests/manual/3d/plasticity/dynamic/pylithapp.cfg +++ b/tests/manual/3d/plasticity/dynamic/pylithapp.cfg @@ -22,10 +22,10 @@ dimension = 3 formulation = pylith.problems.Explicit formulation.norm_viscosity = 1.0e-30 -normalizer = spatialdata.units.NondimElasticDynamic -normalizer.shear_wave_speed = 3300*m/s -normalizer.wave_period = 0.003*s -normalizer.mass_density = 2716*kg/m**3 +scales = pylith.scales.NondimElasticDynamic +scales.shear_wave_speed = 3300*m/s +scales.wave_period = 0.003*s +scales.mass_density = 2716*kg/m**3 # ---------------------------------------------------------------------- # materials diff --git a/tests/manual/powerlaw-2d/axialtraction_powerlaw.cfg b/tests/manual/powerlaw-2d/axialtraction_powerlaw.cfg index 1585ba70f1..421c467ca4 100644 --- a/tests/manual/powerlaw-2d/axialtraction_powerlaw.cfg +++ b/tests/manual/powerlaw-2d/axialtraction_powerlaw.cfg @@ -28,7 +28,8 @@ features = [ initial_dt = 5.0*year start_time = 0.0*year end_time = 10.0*year -normalizer.relaxation_time = 50.0*year + +scales.time_scale = 50.0*year solution_observers = [domain, boundary] solution_observers.boundary = pylith.meshio.OutputSolnBoundary diff --git a/tests/manual/powerlaw-2d/axialtraction_powerlaw_n1.cfg b/tests/manual/powerlaw-2d/axialtraction_powerlaw_n1.cfg index 2591d7b213..ab2008ef03 100644 --- a/tests/manual/powerlaw-2d/axialtraction_powerlaw_n1.cfg +++ b/tests/manual/powerlaw-2d/axialtraction_powerlaw_n1.cfg @@ -28,7 +28,8 @@ features = [ initial_dt = 0.2*year start_time = 0.0*year end_time = 10.0*year -normalizer.relaxation_time = 1.0*year + +scales.time_scale = 1.0*year solution_observers = [domain, boundary] solution_observers.boundary = pylith.meshio.OutputSolnBoundary diff --git a/tests/manual/powerlaw-2d/sheartraction_powerlaw.cfg b/tests/manual/powerlaw-2d/sheartraction_powerlaw.cfg index ea1423ff76..5603c0a7f9 100644 --- a/tests/manual/powerlaw-2d/sheartraction_powerlaw.cfg +++ b/tests/manual/powerlaw-2d/sheartraction_powerlaw.cfg @@ -28,7 +28,8 @@ features = [ initial_dt = 5.0*year start_time = 0.0*year end_time = 10.0*year -normalizer.relaxation_time = 50.0*year + +scales.time_scale = 50.0*year solution_observers = [domain, boundary] solution_observers.boundary = pylith.meshio.OutputSolnBoundary diff --git a/tests/manual/powerlaw-3d/axialtraction_powerlaw.cfg b/tests/manual/powerlaw-3d/axialtraction_powerlaw.cfg index 9aed6f0b9c..7115052c9e 100644 --- a/tests/manual/powerlaw-3d/axialtraction_powerlaw.cfg +++ b/tests/manual/powerlaw-3d/axialtraction_powerlaw.cfg @@ -28,7 +28,8 @@ features = [ initial_dt = 5.0*year start_time = 0.0*year end_time = 10.0*year -normalizer.relaxation_time = 50.0*year + +scales.time_scale = 50.0*year solution_observers = [domain, boundary] solution_observers.boundary = pylith.meshio.OutputSolnBoundary diff --git a/tests/manual/powerlaw-3d/axialtraction_powerlaw_n1.cfg b/tests/manual/powerlaw-3d/axialtraction_powerlaw_n1.cfg index e1cadff255..b2647eb330 100644 --- a/tests/manual/powerlaw-3d/axialtraction_powerlaw_n1.cfg +++ b/tests/manual/powerlaw-3d/axialtraction_powerlaw_n1.cfg @@ -28,7 +28,8 @@ features = [ initial_dt = 0.2*year start_time = 0.0*year end_time = 10.0*year -normalizer.relaxation_time = 1.0*year + +scales.time_scale = 1.0*year solution_observers = [domain, boundary] solution_observers.boundary = pylith.meshio.OutputSolnBoundary diff --git a/tests/manual/powerlaw-3d/sheartraction_powerlaw.cfg b/tests/manual/powerlaw-3d/sheartraction_powerlaw.cfg index 7244151032..eb3182da64 100644 --- a/tests/manual/powerlaw-3d/sheartraction_powerlaw.cfg +++ b/tests/manual/powerlaw-3d/sheartraction_powerlaw.cfg @@ -28,7 +28,8 @@ features = [ initial_dt = 5.0*year start_time = 0.0*year end_time = 10.0*year -normalizer.relaxation_time = 50.0*year + +scales.time_scale = 50.0*year solution_observers = [domain, boundary] solution_observers.boundary = pylith.meshio.OutputSolnBoundary diff --git a/tests/mmstests/incompressibleelasticity/nofaults-2d/BodyForce2D.cc b/tests/mmstests/incompressibleelasticity/nofaults-2d/BodyForce2D.cc index 2c2e7a5bec..194e0f578e 100644 --- a/tests/mmstests/incompressibleelasticity/nofaults-2d/BodyForce2D.cc +++ b/tests/mmstests/incompressibleelasticity/nofaults-2d/BodyForce2D.cc @@ -15,7 +15,9 @@ #include "pylith/problems/TimeDependent.hh" // USES TimeDependent #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t + #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales namespace pylith { class _BodyForce2D; @@ -25,11 +27,9 @@ namespace pylith { class pylith::_BodyForce2D { private: - static const double LENGTHSCALE; - static const double TIMESCALE; - static const double PRESSURESCALE; - static const double BODYFORCE; - static const double XMAX; + static pylith::scales::Scales scales; + static const double BODY_FORCE; // dimensioned + static const double X_MAX; // dimensioned // Density static double density(const double x, @@ -63,7 +63,7 @@ class pylith::_BodyForce2D { static double bodyforce_x(const double x, const double y) { - return BODYFORCE; + return BODY_FORCE; } // bodyforce_x static double bodyforce_y(const double x, @@ -80,23 +80,22 @@ class pylith::_BodyForce2D { // Displacement static double disp_x(const double x, const double y) { - return 0.0 / LENGTHSCALE; + return 0.0; } // disp_x static double disp_y(const double x, const double y) { - return 0.0 / LENGTHSCALE; + return 0.0; } // disp_y // Pressure static double pressure(const double x, const double y) { - const double velocityScale = LENGTHSCALE / TIMESCALE; - const double densityScale = PRESSURESCALE / (velocityScale * velocityScale); - const double accelerationScale = LENGTHSCALE / (TIMESCALE * TIMESCALE); - const double forceScale = densityScale * accelerationScale; - const double bodyforceN = BODYFORCE / forceScale; - return -bodyforceN * (XMAX/LENGTHSCALE - x); + const double lengthScale = scales.getLengthScale(); + const double bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(scales); + + const double bodyforceN = BODY_FORCE / bodyForceScale; + return -bodyforceN * (X_MAX/lengthScale - x); } // pressure static PetscErrorCode solnkernel_disp(PetscInt spaceDim, @@ -142,10 +141,7 @@ class pylith::_BodyForce2D { data->isJacobianLinear = true; - data->normalizer.setLengthScale(LENGTHSCALE); - data->normalizer.setTimeScale(TIMESCALE); - data->normalizer.setPressureScale(PRESSURESCALE); - data->normalizer.computeDensityScale(); + scales = data->scales; // solnDiscretizations set in derived class. @@ -215,11 +211,9 @@ class pylith::_BodyForce2D { } // createData }; // TestIsotropicLinearIncompElasticity2D_BodyForce -const double pylith::_BodyForce2D::LENGTHSCALE = 1.0e+3; -const double pylith::_BodyForce2D::TIMESCALE = 2.0; -const double pylith::_BodyForce2D::PRESSURESCALE = 2.25e+10; -const double pylith::_BodyForce2D::BODYFORCE = 20.0e+3; -const double pylith::_BodyForce2D::XMAX = +4.0e+3; +pylith::scales::Scales pylith::_BodyForce2D::scales; +const double pylith::_BodyForce2D::BODY_FORCE = 20.0e+3; +const double pylith::_BodyForce2D::X_MAX = +4.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestIncompressibleElasticity_Data* diff --git a/tests/mmstests/incompressibleelasticity/nofaults-2d/Gravity2D.cc b/tests/mmstests/incompressibleelasticity/nofaults-2d/Gravity2D.cc index bc6eadfcb2..e023c9228c 100644 --- a/tests/mmstests/incompressibleelasticity/nofaults-2d/Gravity2D.cc +++ b/tests/mmstests/incompressibleelasticity/nofaults-2d/Gravity2D.cc @@ -15,7 +15,9 @@ #include "pylith/problems/TimeDependent.hh" // USES TimeDependent #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/utils/constants.hh" // USES pylith::g_acc #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales namespace pylith { class _Gravity2D; @@ -25,11 +27,8 @@ namespace pylith { class pylith::_Gravity2D { private: - static const double LENGTHSCALE; - static const double TIMESCALE; - static const double PRESSURESCALE; - static const double GACC; - static const double YMAX; + static pylith::scales::Scales scales; + static const double Y_MAX; // dimensioned // Density static double density(const double x, @@ -68,7 +67,7 @@ class pylith::_Gravity2D { static double setGravityAcc_y(const double x, const double y) { - return -GACC; + return -pylith::g_acc; } // setGravityAcc_y static const char* acc_units(void) { @@ -80,21 +79,21 @@ class pylith::_Gravity2D { // Displacement static double disp_x(const double x, const double y) { - return 0.0 / LENGTHSCALE; + return 0.0; } // disp_x static double disp_y(const double x, const double y) { - return 0.0 / LENGTHSCALE; + return 0.0; } // disp_y // Pressure static double pressure(const double x, const double y) { - const double velocityScale = LENGTHSCALE / TIMESCALE; - const double accelerationScale = LENGTHSCALE / (TIMESCALE * TIMESCALE); - const double densityScale = PRESSURESCALE / (velocityScale * velocityScale); - return density(x,y) / densityScale * GACC / (accelerationScale) * (YMAX/LENGTHSCALE-y); + const double lengthScale = scales.getLengthScale(); + const double bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(scales); + + return density(x,y) * pylith::g_acc / bodyForceScale * (Y_MAX/lengthScale-y); } // pressure static PetscErrorCode solnkernel_disp(PetscInt spaceDim, @@ -140,14 +139,11 @@ class pylith::_Gravity2D { data->isJacobianLinear = true; - data->normalizer.setLengthScale(LENGTHSCALE); - data->normalizer.setTimeScale(TIMESCALE); - data->normalizer.setPressureScale(PRESSURESCALE); - data->normalizer.computeDensityScale(); + scales = data->scales; delete data->gravityField;data->gravityField = new spatialdata::spatialdb::GravityField(); data->gravityField->setGravityDir(0.0, -1.0, 0.0); - data->gravityField->setGravityAcc(GACC); + data->gravityField->setGravityAcc(pylith::g_acc); // solnDiscretizations set in derived class. @@ -215,11 +211,8 @@ class pylith::_Gravity2D { } // createData }; // TestIsotropicLinearIncompElasticity2D_Gravity -const double pylith::_Gravity2D::LENGTHSCALE = 1.0e+3; -const double pylith::_Gravity2D::TIMESCALE = 2.0; -const double pylith::_Gravity2D::PRESSURESCALE = 2.25e+10; -const double pylith::_Gravity2D::GACC = 9.80665; -const double pylith::_Gravity2D::YMAX = +4.0e+3; +pylith::scales::Scales pylith::_Gravity2D::scales; +const double pylith::_Gravity2D::Y_MAX = +4.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestIncompressibleElasticity_Data* diff --git a/tests/mmstests/incompressibleelasticity/nofaults-2d/TestIncompressibleElasticity.cc b/tests/mmstests/incompressibleelasticity/nofaults-2d/TestIncompressibleElasticity.cc index 479a258e8d..0234cac6c5 100644 --- a/tests/mmstests/incompressibleelasticity/nofaults-2d/TestIncompressibleElasticity.cc +++ b/tests/mmstests/incompressibleelasticity/nofaults-2d/TestIncompressibleElasticity.cc @@ -29,6 +29,7 @@ #include "pylith/utils/journals.hh" // pythia::journal #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ------------------------------------------------------------------------------------------------ // Constuctor. @@ -79,7 +80,7 @@ pylith::TestIncompressibleElasticity::_initialize(void) { // Set up coordinates. _mesh->setCoordSys(&_data->cs); - pylith::topology::MeshOps::nondimensionalize(_mesh, _data->normalizer); + pylith::topology::MeshOps::nondimensionalize(_mesh, _data->scales); // Set up material _data->material.setBulkRheology(&_data->rheology); @@ -94,7 +95,7 @@ pylith::TestIncompressibleElasticity::_initialize(void) { // Set up problem. assert(_problem); - _problem->setNormalizer(_data->normalizer); + _problem->setScales(_data->scales); _problem->setGravityField(_data->gravityField); pylith::materials::Material* materials[1] = { &_data->material }; _problem->setMaterials(materials, 1); @@ -108,7 +109,7 @@ pylith::TestIncompressibleElasticity::_initialize(void) { assert(!_solution); _solution = new pylith::topology::Field(*_mesh);assert(_solution); _solution->setLabel("solution"); - pylith::problems::SolutionFactory factory(*_solution, _data->normalizer); + pylith::problems::SolutionFactory factory(*_solution, _data->scales); int iField = 0; factory.addDisplacement(_data->solnDiscretizations[iField++]); factory.addPressure(_data->solnDiscretizations[iField++]); @@ -157,7 +158,7 @@ pylith::TestIncompressibleElasticity_Data::TestIncompressibleElasticity_Data(voi useAsciiMesh(true), jacobianConvergenceRate(1.0), - tolerance(1.0e-9), + tolerance(1.0e-8), isJacobianLinear(true), allowZeroResidual(false), @@ -175,6 +176,9 @@ pylith::TestIncompressibleElasticity_Data::TestIncompressibleElasticity_Data(voi auxDiscretizations(NULL) { auxDB.setDescription("material auxiliary field spatial database"); cs.setSpaceDim(spaceDim); + + const double lengthScale = 8.0e+3; + pylith::scales::ElasticityScales::setQuasistaticElasticity(&scales, lengthScale); } // constructor diff --git a/tests/mmstests/incompressibleelasticity/nofaults-2d/TestIncompressibleElasticity.hh b/tests/mmstests/incompressibleelasticity/nofaults-2d/TestIncompressibleElasticity.hh index 8713ed80fa..1dd59ea6af 100644 --- a/tests/mmstests/incompressibleelasticity/nofaults-2d/TestIncompressibleElasticity.hh +++ b/tests/mmstests/incompressibleelasticity/nofaults-2d/TestIncompressibleElasticity.hh @@ -17,7 +17,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/problems/Physics.hh" // USES FormulationEnum #include "pylith/topology/Field.hh" // HASA FieldBase::Discretization @@ -85,7 +85,7 @@ public: PylithReal t; ///< Time for MMS solution. PylithReal dt; ///< Time step in simulation. spatialdata::geocoords::CSCart cs; ///< Coordinate system. - spatialdata::units::Nondimensional normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales scales; ///< Scales for nondimensionalization. pylith::problems::Physics::FormulationEnum formulation; ///< Time stepping formulation pylith::materials::IncompressibleElasticity material; ///< Materials. diff --git a/tests/mmstests/incompressibleelasticity/nofaults-2d/UniformPressure2D.cc b/tests/mmstests/incompressibleelasticity/nofaults-2d/UniformPressure2D.cc index deb8d69439..835a27b850 100644 --- a/tests/mmstests/incompressibleelasticity/nofaults-2d/UniformPressure2D.cc +++ b/tests/mmstests/incompressibleelasticity/nofaults-2d/UniformPressure2D.cc @@ -16,6 +16,8 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales + namespace pylith { class _UniformPressure2D; } // pylith @@ -24,6 +26,9 @@ namespace pylith { class pylith::_UniformPressure2D { private: + static pylith::scales::Scales scales; + static const double PRESSURE; // nondimensional + // Density static double density(const double x, const double y) { @@ -47,7 +52,7 @@ class pylith::_UniformPressure2D { // Vp static double vp(const double x, const double y) { - return 1.0e+15; + return 1.0e+20; } // vp static const char* vp_units(void) { @@ -59,18 +64,24 @@ class pylith::_UniformPressure2D { // Displacement static double disp_x(const double x, const double y) { - return 0.0; + const double rigidityScale = scales.getRigidityScale(); + const double bulkModulus = density(x, y) * (vp(x,y)*vp(x,y) - 4.0/3.0*vs(x,y)*vs(x,y)) / rigidityScale; + + return -0.5 * PRESSURE / bulkModulus * x; } // disp_x static double disp_y(const double x, const double y) { - return 0.0; + const double rigidityScale = scales.getRigidityScale(); + const double bulkModulus = density(x, y) * (vp(x,y)*vp(x,y) - 4.0/3.0*vs(x,y)*vs(x,y)) / rigidityScale; + + return -0.5 * PRESSURE / bulkModulus * y; } // disp_y // Pressure static double pressure(const double x, const double y) { - return 5.0+6; + return PRESSURE; } // pressure static PetscErrorCode solnkernel_disp(PetscInt spaceDim, @@ -116,14 +127,12 @@ class pylith::_UniformPressure2D { data->isJacobianLinear = true; data->jacobianConvergenceRate = 1.0; + data->tolerance = 2.0e-8; data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); + scales = data->scales; // solnDiscretizations set in derived class. @@ -186,6 +195,8 @@ class pylith::_UniformPressure2D { } // createData }; // _UniformPressure2D +pylith::scales::Scales pylith::_UniformPressure2D::scales; +const double pylith::_UniformPressure2D::PRESSURE = 3.0e+6; // ------------------------------------------------------------------------------------------------ pylith::TestIncompressibleElasticity_Data* @@ -222,7 +233,7 @@ pylith::UniformPressure2D::TriP2(void) { data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { pylith::topology::Field::Discretization(2, 2), // disp - pylith::topology::Field::Discretization(1, 2), // pressure + pylith::topology::Field::Discretization(0, 2), // pressure }; data->solnDiscretizations = const_cast(_solnDiscretizations); @@ -247,7 +258,7 @@ pylith::UniformPressure2D::TriP3(void) { data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { pylith::topology::Field::Discretization(3, 3), // disp - pylith::topology::Field::Discretization(2, 3), // pressure + pylith::topology::Field::Discretization(0, 3), // pressure }; data->solnDiscretizations = const_cast(_solnDiscretizations); @@ -272,7 +283,7 @@ pylith::UniformPressure2D::TriP4(void) { data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { pylith::topology::Field::Discretization(4, 4), // disp - pylith::topology::Field::Discretization(3, 4), // pressure + pylith::topology::Field::Discretization(0, 4), // pressure }; data->solnDiscretizations = const_cast(_solnDiscretizations); @@ -315,7 +326,7 @@ pylith::UniformPressure2D::QuadQ2(void) { data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { pylith::topology::Field::Discretization(2, 2), // disp - pylith::topology::Field::Discretization(1, 2), // pressure + pylith::topology::Field::Discretization(0, 2), // pressure }; data->solnDiscretizations = const_cast(_solnDiscretizations); @@ -340,7 +351,7 @@ pylith::UniformPressure2D::QuadQ3(void) { data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { pylith::topology::Field::Discretization(3, 3), // disp - pylith::topology::Field::Discretization(2, 3), // pressure + pylith::topology::Field::Discretization(0, 3), // pressure }; data->solnDiscretizations = const_cast(_solnDiscretizations); @@ -365,7 +376,7 @@ pylith::UniformPressure2D::QuadQ4(void) { data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { pylith::topology::Field::Discretization(4, 4), // disp - pylith::topology::Field::Discretization(3, 4), // pressure + pylith::topology::Field::Discretization(0, 4), // pressure }; data->solnDiscretizations = const_cast(_solnDiscretizations); diff --git a/tests/mmstests/incompressibleelasticity/nofaults-2d/UniformShear2D.cc b/tests/mmstests/incompressibleelasticity/nofaults-2d/UniformShear2D.cc index a608c36892..4b15a9419b 100644 --- a/tests/mmstests/incompressibleelasticity/nofaults-2d/UniformShear2D.cc +++ b/tests/mmstests/incompressibleelasticity/nofaults-2d/UniformShear2D.cc @@ -128,11 +128,6 @@ class pylith::_UniformShear2D { data->isJacobianLinear = true; data->jacobianConvergenceRate = 1.0; - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); - // solnDiscretizations set in derived class. data->numAuxSubfields = 3; diff --git a/tests/mmstests/linearelasticity/faults-2d/OneFaultShearNoSlip.cc b/tests/mmstests/linearelasticity/faults-2d/OneFaultShearNoSlip.cc index d7f5961de2..83d4a789a0 100644 --- a/tests/mmstests/linearelasticity/faults-2d/OneFaultShearNoSlip.cc +++ b/tests/mmstests/linearelasticity/faults-2d/OneFaultShearNoSlip.cc @@ -32,7 +32,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales namespace pylith { class _OneFaultShearNoSlip; @@ -40,6 +41,8 @@ namespace pylith { // ------------------------------------------------------------------------------------------------ class pylith::_OneFaultShearNoSlip { + static pylith::scales::Scales scales; + // Density static double density(const double x, const double y) { @@ -132,9 +135,10 @@ class pylith::_OneFaultShearNoSlip { static double faulttraction_y(const double x, const double y) { + const double rigidityScale = scales.getRigidityScale(); const double mu = density(x, y) * vs(x, y) * vs(x, y); - return strain_xy() * 2.0 * mu / 2.25e+10; + return strain_xy() * 2.0 * mu / rigidityScale; } // faulttraction_y static @@ -158,10 +162,11 @@ class pylith::_OneFaultShearNoSlip { const PylithScalar constants[], PylithScalar r0[]) { assert(r0); + const double rigidityScale = scales.getRigidityScale(); const double mu = density(x[0], x[1]) * vs(x[0], x[1]) * vs(x[0], x[1]); const PylithScalar tanDir[2] = {-n[1], n[0] }; - const PylithScalar tractionShear = -strain_xy() * 2.0 * mu / 2.25e+10; + const PylithScalar tractionShear = -strain_xy() * 2.0 * mu / rigidityScale; const PylithScalar tractionNormal = 0.0; r0[0] += tractionShear*tanDir[0] + tractionNormal*n[0]; r0[1] += tractionShear*tanDir[1] + tractionNormal*n[1]; @@ -207,16 +212,13 @@ class pylith::_OneFaultShearNoSlip { TestFaultKin_Data* createData(void) { TestFaultKin_Data* data = new TestFaultKin_Data();assert(data); - data->journalName = "OneFaultShearNoSLip"; + data->journalName = "OneFaultShearNoSlip"; data->isJacobianLinear = true; data->meshFilename = ":UNKNOWN:"; // Set in child class. - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); + scales = data->scales; // solnDiscretizations set in derived class. @@ -354,6 +356,7 @@ class pylith::_OneFaultShearNoSlip { } // createData }; // TestFaultKin2D_OneFaultShearNoSlip +pylith::scales::Scales pylith::_OneFaultShearNoSlip::scales; // ------------------------------------------------------------------------------------------------ pylith::TestFaultKin_Data* diff --git a/tests/mmstests/linearelasticity/faults-2d/PlanePWave.cc b/tests/mmstests/linearelasticity/faults-2d/PlanePWave.cc index 01b5c3f056..d3a16e0856 100644 --- a/tests/mmstests/linearelasticity/faults-2d/PlanePWave.cc +++ b/tests/mmstests/linearelasticity/faults-2d/PlanePWave.cc @@ -31,7 +31,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ------------------------------------------------------------------------------------------------ namespace pylith { @@ -39,11 +40,9 @@ namespace pylith { } // pylith class pylith::_PlanePWave { - // Dimensionless - static const double LENGTH_SCALE; - static const double TIME_SCALE; - static const double PRESSURE_SCALE; - static const double SLIPRATE; + static pylith::scales::Scales scales; + + static const double SLIP_RATE; // nondimensional static const double TIME_SNAPSHOT; // nondimensional // Density @@ -96,7 +95,8 @@ class pylith::_PlanePWave { static double finalslip_leftlateral(const double x, const double y) { - return SLIPRATE * TIME_SNAPSHOT * LENGTH_SCALE; + const double displacementScale = scales.getDisplacementScale(); + return SLIP_RATE * TIME_SNAPSHOT * displacementScale; } // finalslip_leftlateral static const char* slip_units(void) { @@ -131,9 +131,9 @@ class pylith::_PlanePWave { PetscInt flag) { double amplitude = 0.0; if (!flag) { - amplitude = x < +2.0 ? -0.5*SLIPRATE : +0.5*SLIPRATE; + amplitude = x < +2.0 ? -0.5*SLIP_RATE : +0.5*SLIP_RATE; } else { - amplitude = flag < 0 ? -0.5*SLIPRATE : +0.5*SLIPRATE; + amplitude = flag < 0 ? -0.5*SLIP_RATE : +0.5*SLIP_RATE; } // if/else return amplitude; } // vel_y @@ -283,10 +283,7 @@ class pylith::_PlanePWave { data->meshFilename = ":UNKNOWN:"; // Set in child class. - data->normalizer.setLengthScale(LENGTH_SCALE); - data->normalizer.setTimeScale(TIME_SCALE); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); + scales = data->scales; data->formulation = pylith::problems::Physics::DYNAMIC_IMEX; data->t = TIME_SNAPSHOT; @@ -440,10 +437,8 @@ class pylith::_PlanePWave { } // createData }; // TestFaultKin2D_PlanePWave -const double pylith::_PlanePWave::LENGTH_SCALE = 1000.0; -const double pylith::_PlanePWave::PRESSURE_SCALE = 2.5e+10; -const double pylith::_PlanePWave::TIME_SCALE = 2.0; -const double pylith::_PlanePWave::SLIPRATE = 3.0; +pylith::scales::Scales pylith::_PlanePWave::scales; +const double pylith::_PlanePWave::SLIP_RATE = 3.0; const double pylith::_PlanePWave::TIME_SNAPSHOT = 5.0; // ------------------------------------------------------------------------------------------------ diff --git a/tests/mmstests/linearelasticity/faults-2d/TestFaultKin.cc b/tests/mmstests/linearelasticity/faults-2d/TestFaultKin.cc index 91e27ea794..5335c971a7 100644 --- a/tests/mmstests/linearelasticity/faults-2d/TestFaultKin.cc +++ b/tests/mmstests/linearelasticity/faults-2d/TestFaultKin.cc @@ -34,7 +34,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CoordSys.hh" // USES CoordSys #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ------------------------------------------------------------------------------------------------ // Constuctor. @@ -65,7 +65,7 @@ pylith::TestFaultKin::_initialize(void) { assert(_mesh); assert(_data); - PetscErrorCode err = 0; + PetscErrorCode err = PETSC_SUCCESS; if (_data->useAsciiMesh) { pylith::meshio::MeshIOAscii iohandler; @@ -85,7 +85,7 @@ pylith::TestFaultKin::_initialize(void) { // Set up coordinates. _mesh->setCoordSys(&_data->cs); - pylith::topology::MeshOps::nondimensionalize(_mesh, _data->normalizer); + pylith::topology::MeshOps::nondimensionalize(_mesh, _data->scales); // Set up materials for (size_t iMat = 0; iMat < _data->materials.size(); ++iMat) { @@ -115,7 +115,7 @@ pylith::TestFaultKin::_initialize(void) { // Set up problem. assert(_problem); - _problem->setNormalizer(_data->normalizer); + _problem->setScales(_data->scales); _problem->setGravityField(_data->gravityField); _problem->setMaterials(_data->materials.data(), _data->materials.size()); _problem->setInterfaces(_data->faults.data(), _data->faults.size()); @@ -129,7 +129,7 @@ pylith::TestFaultKin::_initialize(void) { assert(!_solution); _solution = new pylith::topology::Field(*_mesh);assert(_solution); _solution->setLabel("solution"); - pylith::problems::SolutionFactory factory(*_solution, _data->normalizer); + pylith::problems::SolutionFactory factory(*_solution, _data->scales); int iField = 0; factory.addDisplacement(_data->solnDiscretizations[iField++]); if (pylith::problems::Physics::QUASISTATIC == _data->formulation) { @@ -198,7 +198,7 @@ pylith::TestFaultKin_Data::TestFaultKin_Data(void) : useAsciiMesh(true), jacobianConvergenceRate(1.0), - tolerance(1.0e-9), + tolerance(1.0e-8), isJacobianLinear(true), allowZeroResidual(false), @@ -224,6 +224,9 @@ pylith::TestFaultKin_Data::TestFaultKin_Data(void) : faultAuxDB.setDescription("fault auxiliary field spatial database"); cs.setSpaceDim(spaceDim); + + const double lengthScale = 12.0e+3; + pylith::scales::ElasticityScales::setQuasistaticElasticity(&scales, lengthScale); } // constructor diff --git a/tests/mmstests/linearelasticity/faults-2d/TestFaultKin.hh b/tests/mmstests/linearelasticity/faults-2d/TestFaultKin.hh index 4935d11385..470d80cf9f 100644 --- a/tests/mmstests/linearelasticity/faults-2d/TestFaultKin.hh +++ b/tests/mmstests/linearelasticity/faults-2d/TestFaultKin.hh @@ -18,7 +18,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/problems/Physics.hh" // USES FormulationEnum #include "pylith/topology/Field.hh" // HASA FieldBase::Discretization @@ -86,7 +86,7 @@ public: PylithReal t; ///< Time for MMS solution. PylithReal dt; ///< Time step in simulation. spatialdata::geocoords::CSCart cs; ///< Coordinate system. - spatialdata::units::Nondimensional normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales scales; ///< Scales for nondimensionalization. pylith::problems::Physics::FormulationEnum formulation; ///< Time stepping formulation std::vector materials; ///< Materials. diff --git a/tests/mmstests/linearelasticity/faults-2d/TestFaultKin2D_ConstRateDynamic.cc b/tests/mmstests/linearelasticity/faults-2d/TestFaultKin2D_ConstRateDynamic.cc index 58a90ec166..d9eac85981 100644 --- a/tests/mmstests/linearelasticity/faults-2d/TestFaultKin2D_ConstRateDynamic.cc +++ b/tests/mmstests/linearelasticity/faults-2d/TestFaultKin2D_ConstRateDynamic.cc @@ -31,7 +31,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales namespace pylith { namespace mmstests { @@ -60,7 +60,7 @@ class pylith::mmstests::TestFaultKin2D_ConstRateDynamic : static const double TIMESTAMP; static const double LENGTH_SCALE; static const double TIME_SCALE; - static const double PRESSURE_SCALE; + static const double RIGIDITY_SCALE; static const double DOMAIN_X; // Density @@ -163,7 +163,7 @@ class pylith::mmstests::TestFaultKin2D_ConstRateDynamic : static double faulttraction_y(const double x, const double y) { - const double shearModulusN = density(x,y) * pow(vs(x,y), 2) / PRESSURE_SCALE; + const double shearModulusN = density(x,y) * pow(vs(x,y), 2) / RIGIDITY_SCALE; return shearModulusN * (VELOCITY - 0.5*SLIPRATE) * TIMESTAMP / (0.5*DOMAIN_X); } // faulttraction_y @@ -260,11 +260,10 @@ class pylith::mmstests::TestFaultKin2D_ConstRateDynamic : _data->cs = new spatialdata::geocoords::CSCart;CPPUNIT_ASSERT(_data->cs); _data->cs->setSpaceDim(_data->spaceDim); - CPPUNIT_ASSERT(_data->normalizer); - _data->normalizer->setLengthScale(LENGTH_SCALE); - _data->normalizer->setTimeScale(TIME_SCALE); - _data->normalizer->setPressureScale(2.25e+10); - _data->normalizer->computeDensityScale(); + CPPUNIT_ASSERT(_data->scales); + _data->scales->setLengthScale(LENGTH_SCALE); + _data->scales->setTimeScale(TIME_SCALE); + _data->scales->setRigidityScale(2.25e+10); _data->startTime = 0.0; _data->endTime = 2.0*TIMESTAMP; @@ -406,15 +405,15 @@ const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::SLIPRATE = 1.5; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::VELOCITY = 4.0; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::TIMESTAMP = 10.0; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::LENGTH_SCALE = 1000.0; -const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::PRESSURE_SCALE = 2.5e+10; +const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::RIGIDITY_SCALE = 2.5e+10; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::TIME_SCALE = 2.0; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::DOMAIN_X = 8000.0; #else const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::SLIPRATE = 3.0; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::VELOCITY = 1.5; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::TIMESTAMP = 10.0; -const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::LENGTH_SCALE = 1000.0; -const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::PRESSURE_SCALE = 2.5e+10; +const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::LENGTH_SCALE = 1.0; +const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::RIGIDITY_SCALE = 2.0e+6; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::TIME_SCALE = 2.0; const double pylith::mmstests::TestFaultKin2D_ConstRateDynamic::DOMAIN_X = 8000.0; diff --git a/tests/mmstests/linearelasticity/faults-2d/ThreeBlocksStatic.cc b/tests/mmstests/linearelasticity/faults-2d/ThreeBlocksStatic.cc index fcb6d80fe4..c3147d7e14 100644 --- a/tests/mmstests/linearelasticity/faults-2d/ThreeBlocksStatic.cc +++ b/tests/mmstests/linearelasticity/faults-2d/ThreeBlocksStatic.cc @@ -32,7 +32,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales namespace pylith { class _ThreeBlocksStatic; @@ -40,6 +41,13 @@ namespace pylith { // ------------------------------------------------------------------------------------------------ class pylith::_ThreeBlocksStatic { + static pylith::scales::Scales scales; + static const double X_FAULT_LEFT; // nondimensional + static const double X_FAULT_RIGHT; // nondimensional + static const double Y_DISP_LEFT; // nondimensional + static const double Y_DISP_CENTER; // nondimensional + static const double Y_DISP_RIGHT; // nondimensional + // Density static double density(const double x, const double y) { @@ -90,7 +98,7 @@ class pylith::_ThreeBlocksStatic { static double finalslip_leftlateral(const double x, const double y) { - return +1.5; + return +1.0 * scales.getDisplacementScale(); } // slip_leftlateral static const char* slip_units(void) { @@ -108,23 +116,22 @@ class pylith::_ThreeBlocksStatic { static double disp_y(const double x, const double y, PetscInt flag) { - const double amplitude = 1.5e-3; double disp = 0.0; if (!flag) { - if (x < -2.0) { - disp = -amplitude; - } else if (x < +2.0) { - disp = 0.0; + if (x < X_FAULT_LEFT) { + disp = Y_DISP_LEFT; + } else if (x < X_FAULT_RIGHT) { + disp = Y_DISP_CENTER; } else { - disp = +amplitude; + disp = Y_DISP_RIGHT; } // if/else } else { if (flag == 10) { - disp = -amplitude; + disp = Y_DISP_LEFT; } else if (flag == 20) { - disp = 0.0; + disp = Y_DISP_CENTER; } else { - disp = +amplitude; + disp = Y_DISP_RIGHT; } // if/else } // if return disp; @@ -154,25 +161,21 @@ class pylith::_ThreeBlocksStatic { s[0] = disp_x(x[0], x[1]); PetscInt flag = 0; if (context) { + PetscErrorCode err = PETSC_SUCCESS; + PetscDM dmMesh = PetscDM(context); PetscInt cell = 0; - DMPolytopeType cellType = DM_POLYTOPE_UNKNOWN; - DMPlexGetActivePoint((PetscDM) context, &cell); - DMPlexGetCellType((PetscDM) context, cell, &cellType); - PetscInt maxCellLeft = 0; - PetscInt maxCellMiddle = 0; - switch (cellType) { - case DM_POLYTOPE_TRIANGLE: - maxCellLeft = 6; - maxCellMiddle = 12; - break; - case DM_POLYTOPE_QUADRILATERAL: - maxCellLeft = 3; - maxCellMiddle = 6; - break; - default: - PYLITH_JOURNAL_LOGICERROR("Unknown cell type in solution displacement kernel."); - } - flag = cell < maxCellLeft ? 10 : cell < maxCellMiddle ? 20 : 15; + err = DMPlexGetActivePoint(dmMesh, &cell);PYLITH_CHECK_ERROR(err); + + double centroid[3] = {0.0, 0.0, 0.0}; + err = DMPlexComputeCellGeometryFVM(dmMesh, cell, NULL, centroid, NULL);PYLITH_CHECK_ERROR(err); + flag = 0; + if (centroid[0] < X_FAULT_LEFT) { + flag = 10; + } else if (centroid[0] < X_FAULT_RIGHT) { + flag = 20; + } else { + flag = 15; + } // if/else } // if s[1] = disp_y(x[0], x[1], flag); @@ -209,10 +212,7 @@ class pylith::_ThreeBlocksStatic { data->meshFilename = ":UNKNOWN:"; // Set in child class. - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); + scales = data->scales; // solnDiscretizations set in derived class. @@ -343,6 +343,13 @@ class pylith::_ThreeBlocksStatic { } // ccreateData }; // TestFaultKin2D_ThreeBlocksStatic +pylith::scales::Scales pylith::_ThreeBlocksStatic::scales; + +const double pylith::_ThreeBlocksStatic::X_FAULT_LEFT = -2.0/12.0; +const double pylith::_ThreeBlocksStatic::X_FAULT_RIGHT = +2.0/12.0; +const double pylith::_ThreeBlocksStatic::Y_DISP_LEFT = -1.5; +const double pylith::_ThreeBlocksStatic::Y_DISP_CENTER = -0.5; +const double pylith::_ThreeBlocksStatic::Y_DISP_RIGHT = +0.5; // ------------------------------------------------------------------------------------------------ pylith::TestFaultKin_Data* diff --git a/tests/mmstests/linearelasticity/faults-2d/TwoBlocksStatic.cc b/tests/mmstests/linearelasticity/faults-2d/TwoBlocksStatic.cc index c1c3185b25..c983e3bbee 100644 --- a/tests/mmstests/linearelasticity/faults-2d/TwoBlocksStatic.cc +++ b/tests/mmstests/linearelasticity/faults-2d/TwoBlocksStatic.cc @@ -32,7 +32,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales namespace pylith { class _TwoBlocksStatic; @@ -40,7 +40,11 @@ namespace pylith { // ------------------------------------------------------------------------------------------------ class pylith::_TwoBlocksStatic { -private: + static const double LENGTH_SCALE; + static const double TIME_SCALE; + static const double RIGIDITY_SCALE; + static const double AMPLITUDE; // nondimensional + static const double X_FAULT; // nondimensional // Density static double density(const double x, @@ -92,7 +96,7 @@ class pylith::_TwoBlocksStatic { static double finalslip_leftlateral(const double x, const double y) { - return -1.5; + return -AMPLITUDE * LENGTH_SCALE; } // slip_leftlateral static const char* slip_units(void) { @@ -110,9 +114,9 @@ class pylith::_TwoBlocksStatic { static double disp_y(const double x, const double y, PetscInt flag) { - const double disp = 0.75e-3; + const double disp = 0.5*AMPLITUDE; if (!flag) { - return x < +2.0 ? +disp : -disp; + return x < X_FAULT ? +disp : -disp; } else { return flag < 0 ? +disp : -disp; } // if/else @@ -142,22 +146,14 @@ class pylith::_TwoBlocksStatic { s[0] = disp_x(x[0], x[1]); PetscInt flag = 0; if (context) { + PetscErrorCode err = PETSC_SUCCESS; + PetscDM dmMesh = PetscDM(context); PetscInt cell = 0; - DMPolytopeType cellType = DM_POLYTOPE_UNKNOWN; - DMPlexGetActivePoint((PetscDM) context, &cell); - DMPlexGetCellType((PetscDM) context, cell, &cellType); - PetscInt numCellsLeftFault = 0; - switch (cellType) { - case DM_POLYTOPE_TRIANGLE: - numCellsLeftFault = 12; - break; - case DM_POLYTOPE_QUADRILATERAL: - numCellsLeftFault = 6; - break; - default: - PYLITH_JOURNAL_LOGICERROR("Unknown cell type in solution displacement kernel."); - } - flag = cell < numCellsLeftFault ? -1 : +1; + err = DMPlexGetActivePoint(dmMesh, &cell);PYLITH_CHECK_ERROR(err); + + double centroid[3] = {0.0, 0.0, 0.0}; + err = DMPlexComputeCellGeometryFVM(dmMesh, cell, NULL, centroid, NULL);PYLITH_CHECK_ERROR(err); + flag = centroid[0] < X_FAULT ? -1 : +1; } // if s[1] = disp_y(x[0], x[1], flag); @@ -193,10 +189,9 @@ class pylith::_TwoBlocksStatic { data->meshFilename = ":UNKNOWN:"; // Set in child class. - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); + data->scales.setLengthScale(LENGTH_SCALE); + data->scales.setTimeScale(TIME_SCALE); + data->scales.setRigidityScale(RIGIDITY_SCALE); // solnDiscretizations set in derived class. @@ -317,6 +312,11 @@ class pylith::_TwoBlocksStatic { } // createData }; // _TwoBlocksStatic +const double pylith::_TwoBlocksStatic::LENGTH_SCALE = 1.0; +const double pylith::_TwoBlocksStatic::TIME_SCALE = 2.0; +const double pylith::_TwoBlocksStatic::RIGIDITY_SCALE = 2.0e+6; +const double pylith::_TwoBlocksStatic::AMPLITUDE = 3.0; +const double pylith::_TwoBlocksStatic::X_FAULT = +2.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestFaultKin_Data* diff --git a/tests/mmstests/linearelasticity/faults-2d/TwoFaultsShearNoSlip.cc b/tests/mmstests/linearelasticity/faults-2d/TwoFaultsShearNoSlip.cc index f8dc4b31b9..4c3cb932bf 100644 --- a/tests/mmstests/linearelasticity/faults-2d/TwoFaultsShearNoSlip.cc +++ b/tests/mmstests/linearelasticity/faults-2d/TwoFaultsShearNoSlip.cc @@ -32,7 +32,8 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales namespace pylith { class _TwoFaultsShearNoSlip; @@ -40,6 +41,8 @@ namespace pylith { // --------------------------------------------------------------------------------------------------------------------- class pylith::_TwoFaultsShearNoSlip { + static pylith::scales::Scales scales; + // Density static double density(const double x, const double y) { @@ -132,9 +135,10 @@ class pylith::_TwoFaultsShearNoSlip { static double faulttraction_y(const double x, const double y) { + const double rigidityScale = scales.getRigidityScale(); const double mu = density(x, y) * vs(x, y) * vs(x, y); - return strain_xy() * 2.0 * mu / 2.25e+10; + return strain_xy() * 2.0 * mu / rigidityScale; } // faulttraction_y static @@ -158,10 +162,11 @@ class pylith::_TwoFaultsShearNoSlip { const PylithScalar constants[], PylithScalar r0[]) { assert(r0); + const double rigidityScale = scales.getRigidityScale(); const double mu = density(x[0], x[1]) * vs(x[0], x[1]) * vs(x[0], x[1]); const PylithScalar tanDir[2] = {-n[1], n[0] }; - const PylithScalar tractionShear = -strain_xy() * 2.0 * mu / 2.25e+10; + const PylithScalar tractionShear = -strain_xy() * 2.0 * mu / rigidityScale; const PylithScalar tractionNormal = 0.0; r0[0] += tractionShear*tanDir[0] + tractionNormal*n[0]; r0[0] += tractionShear*tanDir[1] + tractionNormal*n[1]; @@ -213,10 +218,7 @@ class pylith::_TwoFaultsShearNoSlip { data->meshFilename = ":UNKNOWN:"; // Set in child class. - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); + scales = data->scales; // solnDiscretizations set in derived class. @@ -365,6 +367,7 @@ class pylith::_TwoFaultsShearNoSlip { } // createData }; // _TwoFaultsShearNoSlip +pylith::scales::Scales pylith::_TwoFaultsShearNoSlip::scales; // ------------------------------------------------------------------------------------------------ pylith::TestFaultKin_Data* diff --git a/tests/mmstests/linearelasticity/nofaults-2d/BodyForce2D.cc b/tests/mmstests/linearelasticity/nofaults-2d/BodyForce2D.cc index 21f09a1f91..9bba89ed74 100644 --- a/tests/mmstests/linearelasticity/nofaults-2d/BodyForce2D.cc +++ b/tests/mmstests/linearelasticity/nofaults-2d/BodyForce2D.cc @@ -16,17 +16,17 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales + namespace pylith { class _BodyForce2D; } // pylith // ------------------------------------------------------------------------------------------------ class pylith::_BodyForce2D { - static const double LENGTHSCALE; - static const double TIMESCALE; - static const double PRESSURESCALE; - static const double BODYFORCE; - static const double XMAX; + static pylith::scales::Scales scales; + static const double BODY_FORCE; + static const double X_MAX; // Density static double density(const double x, @@ -60,7 +60,7 @@ class pylith::_BodyForce2D { static double bodyforce_x(const double x, const double y) { - return BODYFORCE; + return BODY_FORCE; } // bodyforce_x static double bodyforce_y(const double x, @@ -77,14 +77,13 @@ class pylith::_BodyForce2D { // Displacement static double disp_x(const double x, const double y) { - const double velocityScale = LENGTHSCALE / TIMESCALE; - const double densityScale = PRESSURESCALE / (velocityScale * velocityScale); - const double accelerationScale = LENGTHSCALE / (TIMESCALE * TIMESCALE); - const double forceScale = densityScale * accelerationScale; - const double bodyforceN = BODYFORCE / forceScale; - const double muN = density(x,y) * vs(x,y) * vs(x,y) / PRESSURESCALE; - const double lambdaN = density(x,y) * vp(x,y) * vp(x,y) / PRESSURESCALE - 2.0*muN; - const double xp = x - XMAX / LENGTHSCALE; + const double lengthScale = scales.getLengthScale(); + const double rigidityScale = scales.getRigidityScale(); + const double bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(scales); + const double bodyforceN = BODY_FORCE / bodyForceScale; + const double muN = density(x,y) * vs(x,y) * vs(x,y) / rigidityScale; + const double lambdaN = density(x,y) * vp(x,y) * vp(x,y) / rigidityScale - 2.0*muN; + const double xp = x - X_MAX / lengthScale; return -0.5 * bodyforceN / (lambdaN + 2.0*muN) * (xp*xp); } // disp_x @@ -121,10 +120,8 @@ class pylith::_BodyForce2D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(LENGTHSCALE); - data->normalizer.setTimeScale(TIMESCALE); - data->normalizer.setPressureScale(PRESSURESCALE); - data->normalizer.computeDensityScale(); + data->scales.setDisplacementScale(10.0); + scales = data->scales; // solnDiscretizations set in derived class. @@ -181,11 +178,9 @@ class pylith::_BodyForce2D { } // createData }; // BodyForce2D -const double pylith::_BodyForce2D::LENGTHSCALE = 1.0e+3; -const double pylith::_BodyForce2D::TIMESCALE = 2.0; -const double pylith::_BodyForce2D::PRESSURESCALE = 2.25e+10; -const double pylith::_BodyForce2D::BODYFORCE = 5.0e+3; -const double pylith::_BodyForce2D::XMAX = 4.0e+3; +pylith::scales::Scales pylith::_BodyForce2D::scales; +const double pylith::_BodyForce2D::BODY_FORCE = 5.0e+3; +const double pylith::_BodyForce2D::X_MAX = 4.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestLinearElasticity_Data* diff --git a/tests/mmstests/linearelasticity/nofaults-2d/Gravity2D.cc b/tests/mmstests/linearelasticity/nofaults-2d/Gravity2D.cc index e44eb623cd..314da9e9fd 100644 --- a/tests/mmstests/linearelasticity/nofaults-2d/Gravity2D.cc +++ b/tests/mmstests/linearelasticity/nofaults-2d/Gravity2D.cc @@ -15,8 +15,10 @@ #include "pylith/problems/TimeDependent.hh" // USES TimeDependent #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/utils/constants.hh" // USES pylith::g_acc #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ------------------------------------------------------------------------------------------------ namespace pylith { @@ -25,13 +27,9 @@ namespace pylith { class pylith::_Gravity2D { private: - static const double LENGTHSCALE; - static const double TIMESCALE; - static const double PRESSURESCALE; - static const double BODYFORCE; - static const double GACC; - static const double YMIN; - static const double YMAX; + static pylith::scales::Scales scales; + static const double Y_MIN; + static const double Y_MAX; // Density static double density(const double x, @@ -70,7 +68,7 @@ class pylith::_Gravity2D { static double setGravityAcc_y(const double x, const double y) { - return -GACC; + return -pylith::g_acc; } // setGravityAcc_y static const char* acc_units(void) { @@ -87,16 +85,16 @@ class pylith::_Gravity2D { static double disp_y(const double x, const double y) { - const double velocityScale = LENGTHSCALE / TIMESCALE; - const double densityScale = PRESSURESCALE / (velocityScale * velocityScale); - const double accelerationScale = LENGTHSCALE / (TIMESCALE * TIMESCALE); - const double densityN = density(x,y) / densityScale; - const double muN = density(x,y) * vs(x,y) * vs(x,y) / PRESSURESCALE; - const double lambdaN = density(x,y) * vp(x,y) * vp(x,y) / PRESSURESCALE - 2.0*muN; - const double yminN = YMIN / LENGTHSCALE; - const double ymaxN = YMAX / LENGTHSCALE; - const double gaccN = GACC / accelerationScale; - return densityN * gaccN / (lambdaN + 2.0*muN) * (0.5*(y*y-yminN*yminN) - ymaxN*(y-yminN)); + const double lengthScale = scales.getLengthScale(); + const double rigidityScale = scales.getRigidityScale(); + const double bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(scales); + + const double muN = density(x,y) * vs(x,y) * vs(x,y) / rigidityScale; + const double lambdaN = density(x,y) * vp(x,y) * vp(x,y) / rigidityScale - 2.0*muN; + const double yMinN = Y_MIN / lengthScale; + const double yMaxN = Y_MAX / lengthScale; + const double bodyForceN = pylith::g_acc * density(x, y) / bodyForceScale; + return bodyForceN / (lambdaN + 2.0*muN) * (0.5*(y*y-yMinN*yMinN) - yMaxN*(y-yMinN)); } // disp_y static PetscErrorCode solnkernel_disp(PetscInt spaceDim, @@ -128,14 +126,12 @@ class pylith::_Gravity2D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); + data->scales.setDisplacementScale(10.0); + scales = data->scales; delete data->gravityField;data->gravityField = new spatialdata::spatialdb::GravityField(); data->gravityField->setGravityDir(0.0, -1.0, 0.0); - data->gravityField->setGravityAcc(GACC); + data->gravityField->setGravityAcc(pylith::g_acc); // solnDiscretizations set in derived class. @@ -190,12 +186,9 @@ class pylith::_Gravity2D { } // createData }; // _Gravity2D -const double pylith::_Gravity2D::LENGTHSCALE = 1.0e+3; -const double pylith::_Gravity2D::TIMESCALE = 2.0; -const double pylith::_Gravity2D::PRESSURESCALE = 2.25e+10; -const double pylith::_Gravity2D::GACC = 9.80665; -const double pylith::_Gravity2D::YMIN = -4.0e+3; -const double pylith::_Gravity2D::YMAX = +4.0e+3; +pylith::scales::Scales pylith::_Gravity2D::scales; +const double pylith::_Gravity2D::Y_MIN = -4.0e+3; +const double pylith::_Gravity2D::Y_MAX = +4.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestLinearElasticity_Data* diff --git a/tests/mmstests/linearelasticity/nofaults-2d/GravityRefState2D.cc b/tests/mmstests/linearelasticity/nofaults-2d/GravityRefState2D.cc index 9dcea84f13..849bac8fb8 100644 --- a/tests/mmstests/linearelasticity/nofaults-2d/GravityRefState2D.cc +++ b/tests/mmstests/linearelasticity/nofaults-2d/GravityRefState2D.cc @@ -15,6 +15,7 @@ #include "pylith/problems/TimeDependent.hh" // USES TimeDependent #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/utils/constants.hh" // USES pylith::g_acc #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField @@ -25,8 +26,7 @@ namespace pylith { class pylith::_GravityRefState2D { private: - static const double GACC; - static const double YMAX; + static const double Y_MAX; // Density static double density(const double x, @@ -60,7 +60,7 @@ class pylith::_GravityRefState2D { static double referenceMeanStress(const double x, const double y) { - return density(x,y) * GACC * (y-YMAX); + return density(x,y) * pylith::g_acc * (y-Y_MAX); } // referenceMeanStress static double referenceShearStress(const double x, @@ -88,7 +88,7 @@ class pylith::_GravityRefState2D { static double setGravityAcc_y(const double x, const double y) { - return -GACC; + return -pylith::g_acc; } // setGravityAcc_y static const char* acc_units(void) { @@ -137,14 +137,9 @@ class pylith::_GravityRefState2D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); - delete data->gravityField;data->gravityField = new spatialdata::spatialdb::GravityField(); data->gravityField->setGravityDir(0.0, -1.0, 0.0); - data->gravityField->setGravityAcc(GACC); + data->gravityField->setGravityAcc(pylith::g_acc); // solnDiscretizations set in derived class. @@ -211,8 +206,7 @@ class pylith::_GravityRefState2D { } // createData }; // _GravityRefState2D -const double pylith::_GravityRefState2D::GACC = 9.80665; -const double pylith::_GravityRefState2D::YMAX = +4.0e+3; +const double pylith::_GravityRefState2D::Y_MAX = +4.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestLinearElasticity_Data* diff --git a/tests/mmstests/linearelasticity/nofaults-2d/PlanePWave2D.cc b/tests/mmstests/linearelasticity/nofaults-2d/PlanePWave2D.cc index c0a26d55fd..9163421241 100644 --- a/tests/mmstests/linearelasticity/nofaults-2d/PlanePWave2D.cc +++ b/tests/mmstests/linearelasticity/nofaults-2d/PlanePWave2D.cc @@ -16,16 +16,16 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales + // --------------------------------------------------------------------------------------------------------------------- namespace pylith { class _PlanePWave2D; } // pylith class pylith::_PlanePWave2D { - static const double LENGTH_SCALE; - static const double TIME_SCALE; - static const double WAVELENGTH; // (in terms of LENGTH_SCALE) - static const double PRESSURE_SCALE; + static pylith::scales::Scales scales; + static const double WAVELENGTH; // nondimensional static const double TIME_SNAPSHOT; // nondimensional static const double AMPLITUDE; @@ -67,7 +67,7 @@ class pylith::_PlanePWave2D { const double t) { const double pi = M_PI; const double l = WAVELENGTH; - const double velocityScale = LENGTH_SCALE / TIME_SCALE; + const double velocityScale = scales.getLengthScale() / scales.getTimeScale(); const double c = vp(x,y) / velocityScale; return AMPLITUDE*sin(2.0*pi*(x-c*t)/l); } // disp_x @@ -88,7 +88,7 @@ class pylith::_PlanePWave2D { const double t) { const double pi = M_PI; const double l = WAVELENGTH; - const double velocityScale = LENGTH_SCALE / TIME_SCALE; + const double velocityScale = scales.getLengthScale() / scales.getTimeScale(); const double c = vp(x,y) / velocityScale; return -AMPLITUDE*2.0*pi*c/l * cos(2.0*pi*(x-c*t)/l); } // vel_x @@ -109,7 +109,7 @@ class pylith::_PlanePWave2D { const double t) { const double pi = M_PI; const double l = WAVELENGTH; - const double velocityScale = LENGTH_SCALE / TIME_SCALE; + const double velocityScale = scales.getLengthScale() / scales.getTimeScale(); const double c = vp(x,y) / velocityScale; return -AMPLITUDE*pow(2.0*pi*c/l, 2) * sin(2.0*pi*(x-c*t)/l); } // vel_x @@ -183,14 +183,15 @@ class pylith::_PlanePWave2D { data->journalName = "PlanePWave2D"; data->isJacobianLinear = true; + data->tolerance = 1.0e-8; data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(LENGTH_SCALE); - data->normalizer.setTimeScale(TIME_SCALE); - data->normalizer.setPressureScale(PRESSURE_SCALE); - data->normalizer.computeDensityScale(); + const double lengthScale = data->scales.getLengthScale(); // domain-specific value + const double velocityScale = vs(0.0, 0.0); + pylith::scales::ElasticityScales::setDynamicElasticity(&scales, lengthScale, velocityScale); + data->scales = scales; data->formulation = pylith::problems::Physics::DYNAMIC; data->t = TIME_SNAPSHOT; @@ -261,12 +262,10 @@ class pylith::_PlanePWave2D { }; // PlanePWave2D -const double pylith::_PlanePWave2D::LENGTH_SCALE = 1.0e+3; -const double pylith::_PlanePWave2D::TIME_SCALE = 10.0; -const double pylith::_PlanePWave2D::PRESSURE_SCALE = 3.0e+10; -const double pylith::_PlanePWave2D::WAVELENGTH = 1.0e+4; +pylith::scales::Scales pylith::_PlanePWave2D::scales; +const double pylith::_PlanePWave2D::WAVELENGTH = 1.0e+5; const double pylith::_PlanePWave2D::TIME_SNAPSHOT = 7.657345769747113; -const double pylith::_PlanePWave2D::AMPLITUDE = 1.0e+2; +const double pylith::_PlanePWave2D::AMPLITUDE = 0.1; // ------------------------------------------------------------------------------------------------ pylith::TestLinearElasticity_Data* @@ -275,7 +274,6 @@ pylith::PlanePWave2D::TriP1(void) { data->meshFilename = "data/tri.msh"; data->useAsciiMesh = false; - data->tolerance = 2.0e-4; data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { @@ -293,8 +291,8 @@ pylith::TestLinearElasticity_Data* pylith::PlanePWave2D::TriP2(void) { TestLinearElasticity_Data* data = pylith::_PlanePWave2D::createData();assert(data); - data->meshFilename = "data/tri.mesh"; - data->tolerance = 5.0e-7; + data->meshFilename = "data/tri.msh"; + data->useAsciiMesh = false; static const pylith::topology::Field::Discretization _auxDiscretizations[3] = { pylith::topology::Field::Discretization(0, 2), // density @@ -321,7 +319,6 @@ pylith::PlanePWave2D::TriP3(void) { data->meshFilename = "data/tri.msh"; data->useAsciiMesh = false; - data->tolerance = 1.0e-9; static const pylith::topology::Field::Discretization _auxDiscretizations[3] = { pylith::topology::Field::Discretization(0, 3), // density @@ -347,7 +344,6 @@ pylith::PlanePWave2D::TriP4(void) { TestLinearElasticity_Data* data = pylith::_PlanePWave2D::createData();assert(data); data->meshFilename = "data/tri.mesh"; - data->tolerance = 1.0e-9; static const pylith::topology::Field::Discretization _auxDiscretizations[3] = { pylith::topology::Field::Discretization(0, 4), // density @@ -373,7 +369,6 @@ pylith::PlanePWave2D::QuadQ1(void) { TestLinearElasticity_Data* data = pylith::_PlanePWave2D::createData();assert(data); data->meshFilename = "data/quad.mesh"; - data->tolerance = 1.0e-4; data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { @@ -392,7 +387,6 @@ pylith::PlanePWave2D::QuadQ1Distorted(void) { TestLinearElasticity_Data* data = pylith::_PlanePWave2D::createData();assert(data); data->meshFilename = "data/quad_distorted.mesh"; - data->tolerance = 1.0e-5; data->numSolnSubfields = 2; static const pylith::topology::Field::Discretization _solnDiscretizations[2] = { @@ -412,7 +406,6 @@ pylith::PlanePWave2D::QuadQ2(void) { data->meshFilename = "data/quad.msh"; data->useAsciiMesh = false; - data->tolerance = 2.0e-8; static const pylith::topology::Field::Discretization _auxDiscretizations[3] = { pylith::topology::Field::Discretization(0, 2), // density @@ -438,7 +431,6 @@ pylith::PlanePWave2D::QuadQ3(void) { TestLinearElasticity_Data* data = pylith::_PlanePWave2D::createData();assert(data); data->meshFilename = "data/quad.mesh"; - data->tolerance = 1.0e-9; static const pylith::topology::Field::Discretization _auxDiscretizations[3] = { pylith::topology::Field::Discretization(0, 3), // density diff --git a/tests/mmstests/linearelasticity/nofaults-2d/RigidBodyAcc2D.cc b/tests/mmstests/linearelasticity/nofaults-2d/RigidBodyAcc2D.cc index 86fe7a1e82..247f59224d 100644 --- a/tests/mmstests/linearelasticity/nofaults-2d/RigidBodyAcc2D.cc +++ b/tests/mmstests/linearelasticity/nofaults-2d/RigidBodyAcc2D.cc @@ -17,15 +17,15 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales + // --------------------------------------------------------------------------------------------------------------------- namespace pylith { class _RigidBodyAcc2D; } // pylith class pylith::_RigidBodyAcc2D { - static const double LENGTH_SCALE; - static const double TIME_SCALE; - static const double PRESSURE_SCALE; + static pylith::scales::Scales scales; static const double TIME_SNAPSHOT; // nondimensional // Density @@ -183,8 +183,7 @@ class pylith::_RigidBodyAcc2D { assert(2 == dim); assert(x); assert(f0); - const double velocityScale = LENGTH_SCALE / TIME_SCALE; - const double densityScale = PRESSURE_SCALE / (velocityScale * velocityScale); + const double densityScale = pylith::scales::ElasticityScales::getDensityScale(scales); f0[0] += density(x[0], x[1]) / densityScale * acc_x(x[0], x[1], t); f0[1] += density(x[0], x[1]) / densityScale * acc_y(x[0], x[1], t); } // mmsBodyForceKernel @@ -202,10 +201,10 @@ class pylith::_RigidBodyAcc2D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(LENGTH_SCALE); - data->normalizer.setTimeScale(TIME_SCALE); - data->normalizer.setPressureScale(PRESSURE_SCALE); - data->normalizer.computeDensityScale(); + const double lengthScale = data->scales.getLengthScale(); // domain specific value + const double velocityScale = vs(0.0, 0.0); + pylith::scales::ElasticityScales::setDynamicElasticity(&scales, lengthScale, velocityScale); + data->scales = scales; data->formulation = pylith::problems::Physics::DYNAMIC; // solnDiscretizations set in derived class. @@ -276,10 +275,7 @@ class pylith::_RigidBodyAcc2D { } // createData }; // _RigidBodyAcc2D - -const double pylith::_RigidBodyAcc2D::LENGTH_SCALE = 1.0e+3; -const double pylith::_RigidBodyAcc2D::TIME_SCALE = 15.0; -const double pylith::_RigidBodyAcc2D::PRESSURE_SCALE = 2.0e+10; +pylith::scales::Scales pylith::_RigidBodyAcc2D::scales; // ------------------------------------------------------------------------------------------------ pylith::TestLinearElasticity_Data* diff --git a/tests/mmstests/linearelasticity/nofaults-2d/TestLinearElasticity.cc b/tests/mmstests/linearelasticity/nofaults-2d/TestLinearElasticity.cc index 273a87e1ec..456ae0dd77 100644 --- a/tests/mmstests/linearelasticity/nofaults-2d/TestLinearElasticity.cc +++ b/tests/mmstests/linearelasticity/nofaults-2d/TestLinearElasticity.cc @@ -29,6 +29,7 @@ #include "pylith/utils/journals.hh" // pythia::journal #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ------------------------------------------------------------------------------------------------ // Constuctor. @@ -59,7 +60,7 @@ pylith::TestLinearElasticity::_initialize(void) { assert(_mesh); assert(_data); - PetscErrorCode err = 0; + PetscErrorCode err = PETSC_SUCCESS; if (_data->useAsciiMesh) { pylith::meshio::MeshIOAscii iohandler; @@ -79,7 +80,7 @@ pylith::TestLinearElasticity::_initialize(void) { // Set up coordinates. _mesh->setCoordSys(&_data->cs); - pylith::topology::MeshOps::nondimensionalize(_mesh, _data->normalizer); + pylith::topology::MeshOps::nondimensionalize(_mesh, _data->scales); // Set up material _data->material.setBulkRheology(&_data->rheology); @@ -94,7 +95,7 @@ pylith::TestLinearElasticity::_initialize(void) { // Set up problem. assert(_problem); - _problem->setNormalizer(_data->normalizer); + _problem->setScales(_data->scales); _problem->setGravityField(_data->gravityField); pylith::materials::Material* materials[1] = { &_data->material }; _problem->setMaterials(materials, 1); @@ -108,7 +109,7 @@ pylith::TestLinearElasticity::_initialize(void) { assert(!_solution); _solution = new pylith::topology::Field(*_mesh);assert(_solution); _solution->setLabel("solution"); - pylith::problems::SolutionFactory factory(*_solution, _data->normalizer); + pylith::problems::SolutionFactory factory(*_solution, _data->scales); factory.addDisplacement(_data->solnDiscretizations[0]); if (pylith::problems::Physics::QUASISTATIC == _data->formulation) { assert(1 == _data->numSolnSubfields); @@ -133,7 +134,7 @@ pylith::TestLinearElasticity::_setExactSolution(void) { const pylith::topology::Field* solution = _problem->getSolution();assert(solution); - PetscErrorCode err = 0; + PetscErrorCode err = PETSC_SUCCESS; PetscDS ds = NULL; err = DMGetDS(solution->getDM(), &ds);PYLITH_CHECK_ERROR(err); for (size_t i = 0; i < _data->numSolnSubfields; ++i) { @@ -173,6 +174,9 @@ pylith::TestLinearElasticity_Data::TestLinearElasticity_Data(void) : auxDiscretizations(NULL) { auxDB.setDescription("material auxiliary field spatial database"); cs.setSpaceDim(spaceDim); + + const double lengthScale = 8.0e+3; + pylith::scales::ElasticityScales::setQuasistaticElasticity(&scales, lengthScale); } // constructor diff --git a/tests/mmstests/linearelasticity/nofaults-2d/TestLinearElasticity.hh b/tests/mmstests/linearelasticity/nofaults-2d/TestLinearElasticity.hh index 0a2b7d4368..ef02358b5d 100644 --- a/tests/mmstests/linearelasticity/nofaults-2d/TestLinearElasticity.hh +++ b/tests/mmstests/linearelasticity/nofaults-2d/TestLinearElasticity.hh @@ -17,7 +17,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/problems/Physics.hh" // USES FormulationEnum #include "pylith/topology/Field.hh" // HASA FieldBase::Discretization @@ -86,7 +86,7 @@ public: PylithReal t; ///< Time for MMS solution. PylithReal dt; ///< Time step in simulation. spatialdata::geocoords::CSCart cs; ///< Coordinate system. - spatialdata::units::Nondimensional normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales scales; ///< Scales for nondimensionalization. pylith::problems::Physics::FormulationEnum formulation; ///< Time stepping formulation pylith::materials::Elasticity material; ///< Materials. diff --git a/tests/mmstests/linearelasticity/nofaults-2d/UniformStrain2D.cc b/tests/mmstests/linearelasticity/nofaults-2d/UniformStrain2D.cc index f53077b8d2..d6f20e705f 100644 --- a/tests/mmstests/linearelasticity/nofaults-2d/UniformStrain2D.cc +++ b/tests/mmstests/linearelasticity/nofaults-2d/UniformStrain2D.cc @@ -113,11 +113,6 @@ class pylith::_UniformStrain2D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); - // solnDiscretizations set in derived class. // Material information diff --git a/tests/mmstests/linearelasticity/nofaults-3d/BodyForce3D.cc b/tests/mmstests/linearelasticity/nofaults-3d/BodyForce3D.cc index 173b30bf41..82b7982e5b 100644 --- a/tests/mmstests/linearelasticity/nofaults-3d/BodyForce3D.cc +++ b/tests/mmstests/linearelasticity/nofaults-3d/BodyForce3D.cc @@ -16,17 +16,17 @@ #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales + namespace pylith { class _BodyForce3D; } // pylith // ------------------------------------------------------------------------------------------------ class pylith::_BodyForce3D { - static const double LENGTHSCALE; - static const double TIMESCALE; - static const double PRESSURESCALE; - static const double BODYFORCE; - static const double XMAX; + static pylith::scales::Scales scales; + static const double BODY_FORCE; + static const double X_MAX; /// Spatial database user functions for auxiiliary subfields (includes derived fields). @@ -66,7 +66,7 @@ class pylith::_BodyForce3D { static double bodyforce_x(const double x, const double y, const double z) { - return BODYFORCE; + return BODY_FORCE; } // bodyforce_x static double bodyforce_y(const double x, @@ -91,14 +91,13 @@ class pylith::_BodyForce3D { static double disp_x(const double x, const double y, const double z) { - const double velocityScale = LENGTHSCALE / TIMESCALE; - const double densityScale = PRESSURESCALE / (velocityScale * velocityScale); - const double accelerationScale = LENGTHSCALE / (TIMESCALE * TIMESCALE); - const double forceScale = densityScale * accelerationScale; - const double bodyforceN = BODYFORCE / forceScale; - const double muN = density(x,y,z) * vs(x,y,z) * vs(x,y,z) / PRESSURESCALE; - const double lambdaN = density(x,y,z) * vp(x,y,z) * vp(x,y,z) / PRESSURESCALE - 2.0*muN; - const double xp = x - XMAX / LENGTHSCALE; + const double lengthScale = scales.getLengthScale(); + const double rigidityScale = scales.getRigidityScale(); + const double bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(scales); + const double bodyforceN = BODY_FORCE / bodyForceScale; + const double muN = density(x,y,z) * vs(x,y,z) * vs(x,y,z) / rigidityScale; + const double lambdaN = density(x,y,z) * vp(x,y,z) * vp(x,y,z) / rigidityScale - 2.0*muN; + const double xp = x - X_MAX / lengthScale; return -0.5 * bodyforceN / (lambdaN + 2.0*muN) * (xp*xp); } // disp_x @@ -144,10 +143,8 @@ class pylith::_BodyForce3D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(LENGTHSCALE); - data->normalizer.setTimeScale(TIMESCALE); - data->normalizer.setPressureScale(PRESSURESCALE); - data->normalizer.computeDensityScale(); + data->scales.setDisplacementScale(10.0); + scales = data->scales; // solnDiscretizations set in derived class. @@ -205,11 +202,9 @@ class pylith::_BodyForce3D { } // createData }; // BodyForce3D -const double pylith::_BodyForce3D::LENGTHSCALE = 1.0e+3; -const double pylith::_BodyForce3D::TIMESCALE = 2.0; -const double pylith::_BodyForce3D::PRESSURESCALE = 2.25e+10; -const double pylith::_BodyForce3D::BODYFORCE = 5.0e+3; -const double pylith::_BodyForce3D::XMAX = 4.0e+3; +pylith::scales::Scales pylith::_BodyForce3D::scales; +const double pylith::_BodyForce3D::BODY_FORCE = 5.0e+3; +const double pylith::_BodyForce3D::X_MAX = 4.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestLinearElasticity_Data* diff --git a/tests/mmstests/linearelasticity/nofaults-3d/Gravity3D.cc b/tests/mmstests/linearelasticity/nofaults-3d/Gravity3D.cc index 2a58e74999..5502ad8117 100644 --- a/tests/mmstests/linearelasticity/nofaults-3d/Gravity3D.cc +++ b/tests/mmstests/linearelasticity/nofaults-3d/Gravity3D.cc @@ -15,8 +15,10 @@ #include "pylith/problems/TimeDependent.hh" // USES TimeDependent #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/utils/constants.hh" // USES pylith::g_acc #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ------------------------------------------------------------------------------------------------ namespace pylith { @@ -24,13 +26,10 @@ namespace pylith { } // pylith class pylith::_Gravity3D { - static const double LENGTHSCALE; - static const double TIMESCALE; - static const double PRESSURESCALE; - static const double BODYFORCE; - static const double GACC; - static const double ZMIN; - static const double ZMAX; + static pylith::scales::Scales scales; + static const double BODY_FORCE; + static const double Z_MIN; + static const double Z_MAX; /// Spatial database user functions for auxiiliary subfields (includes derived fields). @@ -85,17 +84,17 @@ class pylith::_Gravity3D { static double disp_z(const double x, const double y, const double z) { - const double velocityScale = LENGTHSCALE / TIMESCALE; - const double densityScale = PRESSURESCALE / (velocityScale * velocityScale); - const double accelerationScale = LENGTHSCALE / (TIMESCALE * TIMESCALE); - const double densityN = density(x,y,z) / densityScale; - const double muN = density(x,y,z) * vs(x,y,z) * vs(x,y,z) / PRESSURESCALE; - const double lambdaN = density(x,y,z) * vp(x,y,z) * vp(x,y,z) / PRESSURESCALE - 2.0*muN; - const double zminN = ZMIN / LENGTHSCALE; - const double zmaxN = ZMAX / LENGTHSCALE; - const double gaccN = GACC / accelerationScale; - return densityN * gaccN / (lambdaN + 2.0*muN) * (0.5*(z*z-zminN*zminN) - zmaxN*(z-zminN)); - } // disp_y + const double lengthScale = scales.getLengthScale(); + const double rigidityScale = scales.getRigidityScale(); + const double bodyForceScale = pylith::scales::ElasticityScales::getBodyForceScale(scales); + + const double muN = density(x,y,z) * vs(x,y,z) * vs(x,y,z) / rigidityScale; + const double lambdaN = density(x,y,z) * vp(x,y,z) * vp(x,y,z) / rigidityScale - 2.0*muN; + const double zminN = Z_MIN / lengthScale; + const double zmaxN = Z_MAX / lengthScale; + const double bodyForceN = pylith::g_acc * density(x, y, z) / bodyForceScale; + return bodyForceN / (lambdaN + 2.0*muN) * (0.5*(z*z-zminN*zminN) - zmaxN*(z-zminN)); + } // disp_z static PetscErrorCode solnkernel_disp(PetscInt spaceDim, PetscReal t, @@ -128,14 +127,12 @@ class pylith::_Gravity3D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); + data->scales.setDisplacementScale(10.0); + scales = data->scales; delete data->gravityField;data->gravityField = new spatialdata::spatialdb::GravityField(); data->gravityField->setGravityDir(0.0, 0.0, -1.0); - data->gravityField->setGravityAcc(GACC); + data->gravityField->setGravityAcc(pylith::g_acc); // solnDiscretizations set in derived class. @@ -190,12 +187,9 @@ class pylith::_Gravity3D { } // createData }; // Gravity3D -const double pylith::_Gravity3D::LENGTHSCALE = 1.0e+3; -const double pylith::_Gravity3D::TIMESCALE = 2.0; -const double pylith::_Gravity3D::PRESSURESCALE = 2.25e+10; -const double pylith::_Gravity3D::GACC = 9.80665; -const double pylith::_Gravity3D::ZMIN = -4.0e+3; -const double pylith::_Gravity3D::ZMAX = +4.0e+3; +pylith::scales::Scales pylith::_Gravity3D::scales; +const double pylith::_Gravity3D::Z_MIN = -4.0e+3; +const double pylith::_Gravity3D::Z_MAX = +4.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestLinearElasticity_Data* diff --git a/tests/mmstests/linearelasticity/nofaults-3d/GravityRefState3D.cc b/tests/mmstests/linearelasticity/nofaults-3d/GravityRefState3D.cc index d3f232d754..29b6b899a4 100644 --- a/tests/mmstests/linearelasticity/nofaults-3d/GravityRefState3D.cc +++ b/tests/mmstests/linearelasticity/nofaults-3d/GravityRefState3D.cc @@ -15,6 +15,7 @@ #include "pylith/problems/TimeDependent.hh" // USES TimeDependent #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization #include "pylith/utils/journals.hh" // USES pythia::journal::debug_t +#include "pylith/utils/constants.hh" // USES pylith::g_acc #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField @@ -25,8 +26,7 @@ namespace pylith { // ------------------------------------------------------------------------------------------------ class pylith::_GravityRefState3D { /// Spatial database user functions for auxiiliary subfields (includes derived fields). - static const double GACC; - static const double ZMAX; + static const double Z_MAX; // Density static double density(const double x, @@ -64,7 +64,7 @@ class pylith::_GravityRefState3D { static double referenceMeanStress(const double x, const double y, const double z) { - return density(x,y,z) * GACC * (z-ZMAX); + return density(x,y,z) * pylith::g_acc * (z-Z_MAX); } // referenceMeanStress static double referenceShearStress(const double x, @@ -139,14 +139,9 @@ class pylith::_GravityRefState3D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); - delete data->gravityField;data->gravityField = new spatialdata::spatialdb::GravityField(); data->gravityField->setGravityDir(0.0, 0.0, -1.0); - data->gravityField->setGravityAcc(GACC); + data->gravityField->setGravityAcc(pylith::g_acc); // solnDiscretizations set in derived class. @@ -217,8 +212,7 @@ class pylith::_GravityRefState3D { } // createData }; // GravityRefState3D -const double pylith::_GravityRefState3D::GACC = 9.80665; -const double pylith::_GravityRefState3D::ZMAX = +4.0e+3; +const double pylith::_GravityRefState3D::Z_MAX = +4.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestLinearElasticity_Data* diff --git a/tests/mmstests/linearelasticity/nofaults-3d/TestLinearElasticity.cc b/tests/mmstests/linearelasticity/nofaults-3d/TestLinearElasticity.cc index 3dc65c3c7f..234703adca 100644 --- a/tests/mmstests/linearelasticity/nofaults-3d/TestLinearElasticity.cc +++ b/tests/mmstests/linearelasticity/nofaults-3d/TestLinearElasticity.cc @@ -29,6 +29,7 @@ #include "pylith/utils/journals.hh" // pythia::journal #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ------------------------------------------------------------------------------------------------ // Constuctor. @@ -72,7 +73,7 @@ pylith::TestLinearElasticity::_initialize(void) { // Set up coordinates. _mesh->setCoordSys(&_data->cs); - pylith::topology::MeshOps::nondimensionalize(_mesh, _data->normalizer); + pylith::topology::MeshOps::nondimensionalize(_mesh, _data->scales); // Set up material _data->material.setBulkRheology(&_data->rheology); @@ -87,7 +88,7 @@ pylith::TestLinearElasticity::_initialize(void) { // Set up problem. assert(_problem); - _problem->setNormalizer(_data->normalizer); + _problem->setScales(_data->scales); _problem->setGravityField(_data->gravityField); pylith::materials::Material* materials[1] = { &_data->material }; _problem->setMaterials(materials, 1); @@ -101,7 +102,7 @@ pylith::TestLinearElasticity::_initialize(void) { assert(!_solution); _solution = new pylith::topology::Field(*_mesh);assert(_solution); _solution->setLabel("solution"); - pylith::problems::SolutionFactory factory(*_solution, _data->normalizer); + pylith::problems::SolutionFactory factory(*_solution, _data->scales); factory.addDisplacement(_data->solnDiscretizations[0]); if (pylith::problems::Physics::QUASISTATIC == _data->formulation) { assert(1 == _data->numSolnSubfields); @@ -165,6 +166,9 @@ pylith::TestLinearElasticity_Data::TestLinearElasticity_Data(void) : auxDiscretizations(NULL) { auxDB.setDescription("material auxiliary field spatial database"); cs.setSpaceDim(spaceDim); + + const double lengthScale = 8.0e+3; + pylith::scales::ElasticityScales::setQuasistaticElasticity(&scales, lengthScale); } // constructor diff --git a/tests/mmstests/linearelasticity/nofaults-3d/TestLinearElasticity.hh b/tests/mmstests/linearelasticity/nofaults-3d/TestLinearElasticity.hh index 9337693eea..6c782e6c4e 100644 --- a/tests/mmstests/linearelasticity/nofaults-3d/TestLinearElasticity.hh +++ b/tests/mmstests/linearelasticity/nofaults-3d/TestLinearElasticity.hh @@ -17,7 +17,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/problems/Physics.hh" // USES FormulationEnum #include "pylith/topology/Field.hh" // HASA FieldBase::Discretization @@ -85,7 +85,7 @@ public: PylithReal t; ///< Time for MMS solution. PylithReal dt; ///< Time step in simulation. spatialdata::geocoords::CSCart cs; ///< Coordinate system. - spatialdata::units::Nondimensional normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales scales; ///< Scales for nondimensionalization. pylith::problems::Physics::FormulationEnum formulation; ///< Time stepping formulation pylith::materials::Elasticity material; ///< Materials. diff --git a/tests/mmstests/linearelasticity/nofaults-3d/UniformStrain3D.cc b/tests/mmstests/linearelasticity/nofaults-3d/UniformStrain3D.cc index 6a3fb42b26..63e55232c5 100644 --- a/tests/mmstests/linearelasticity/nofaults-3d/UniformStrain3D.cc +++ b/tests/mmstests/linearelasticity/nofaults-3d/UniformStrain3D.cc @@ -137,11 +137,6 @@ class pylith::_UniformStrain3D { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(1.0e+03); - data->normalizer.setTimeScale(2.0); - data->normalizer.setPressureScale(2.25e+10); - data->normalizer.computeDensityScale(); - // solnDiscretizations set in derived class. // Material information diff --git a/tests/mmstests/poroelasticity/nofaults-2d/PressureGradient.cc b/tests/mmstests/poroelasticity/nofaults-2d/PressureGradient.cc index 74f100d9ba..d62dbc7210 100644 --- a/tests/mmstests/poroelasticity/nofaults-2d/PressureGradient.cc +++ b/tests/mmstests/poroelasticity/nofaults-2d/PressureGradient.cc @@ -15,18 +15,17 @@ #include "pylith/problems/TimeDependent.hh" // USES TimeDependent #include "pylith/topology/Field.hh" // USES pylith::topology::Field::Discretization +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales + namespace pylith { class _PressureGradient; } // pylith // ------------------------------------------------------------------------------------------------ class pylith::_PressureGradient { - static const double LENGTH_SCALE; - static const double TIME_SCALE; - static const double PRESSURE_SCALE; - - static const double PRESSURE0; // dimensional - static const double XMAX; // dimensional + static pylith::scales::Scales scales; + static const double PRESSURE; // dimensional + static const double X_MAX; // dimensional // Density static double solid_density(const double x, @@ -92,7 +91,7 @@ class pylith::_PressureGradient { // Fluid modulus static double fluid_bulk_modulus(const double x, const double y) { - return 1.0e+10; + return 2.0e+9; } // fluid_bulk_modulus // Permeability @@ -110,10 +109,14 @@ class pylith::_PressureGradient { // Displacement static double disp_x(const double x, const double y) { - const double muN = shear_modulus(x, y) / PRESSURE_SCALE; - const double lambdaN = drained_bulk_modulus(x, y) / PRESSURE_SCALE - 2.0/3.0 * muN; + const PylithReal lengthScale = scales.getLengthScale(); + const PylithReal rigidityScale = scales.getRigidityScale(); + const PylithReal fluidPressureScale = pylith::scales::ElasticityScales::getFluidPressureScale(scales); + + const double muN = shear_modulus(x, y) / rigidityScale; + const double lambdaN = drained_bulk_modulus(x, y) / rigidityScale - 2.0/3.0 * muN; const double alpha = biot_coefficient(x, y); - return -0.5 * alpha * (PRESSURE0 / PRESSURE_SCALE) / (lambdaN + 2.0*muN) * (x*x / (XMAX / LENGTH_SCALE)); + return -0.5 * alpha * (PRESSURE / fluidPressureScale) / (lambdaN + 2.0*muN) * (x*x / (X_MAX / lengthScale)); } // disp_x static double disp_y(const double x, @@ -124,16 +127,23 @@ class pylith::_PressureGradient { // Pressure static double fluid_pressure(const double x, const double y) { - return (PRESSURE0 / PRESSURE_SCALE) * (1.0 - x / (XMAX / LENGTH_SCALE)); + const PylithReal lengthScale = scales.getLengthScale(); + const PylithReal fluidPressureScale = pylith::scales::ElasticityScales::getFluidPressureScale(scales); + + return (PRESSURE / fluidPressureScale) * (1.0 - x / (X_MAX / lengthScale)); } // fluid_pressure // Trace strain static double trace_strain(const double x, const double y) { - const double muN = shear_modulus(x, y) / PRESSURE_SCALE; - const double lambdaN = drained_bulk_modulus(x, y) / PRESSURE_SCALE - 2.0/3.0 * muN; + const PylithReal lengthScale = scales.getLengthScale(); + const PylithReal rigidityScale = scales.getRigidityScale(); + const PylithReal fluidPressureScale = pylith::scales::ElasticityScales::getFluidPressureScale(scales); + + const double muN = shear_modulus(x, y) / rigidityScale; + const double lambdaN = drained_bulk_modulus(x, y) / rigidityScale - 2.0/3.0 * muN; const double alpha = biot_coefficient(x, y); - return -alpha * (PRESSURE0 / PRESSURE_SCALE) / (lambdaN + 2.0*muN) * (x / (XMAX / LENGTH_SCALE)); + return -alpha * (PRESSURE / fluidPressureScale) / (lambdaN + 2.0*muN) * (x / (X_MAX / lengthScale)); } // trace_strain static PetscErrorCode solnkernel_disp(PetscInt spaceDim, @@ -182,12 +192,12 @@ class pylith::_PressureGradient { return 0; } // solnkernel_trace_strain - static PetscErrorCode solnkernel_vel(PetscInt spaceDim, - PetscReal t, - const PetscReal x[], - PetscInt numComponents, - PetscScalar* s, - void* context) { + static PetscErrorCode solnkernel_velocity(PetscInt spaceDim, + PetscReal t, + const PetscReal x[], + PetscInt numComponents, + PetscScalar* s, + void* context) { assert(2 == spaceDim); assert(2 == numComponents); assert(s); @@ -196,7 +206,7 @@ class pylith::_PressureGradient { s[1] = 0.0; return 0; - } // solnkernel_vel + } // solnkernel_velocity static PetscErrorCode solnkernel_fluid_pressure_dot(PetscInt spaceDim, PetscReal t, @@ -240,10 +250,7 @@ class pylith::_PressureGradient { data->meshFilename = ":UNKNOWN:"; // Set in child class. data->boundaryLabel = "boundary"; - data->normalizer.setLengthScale(LENGTH_SCALE); - data->normalizer.setTimeScale(TIME_SCALE); - data->normalizer.setPressureScale(PRESSURE_SCALE); - data->normalizer.computeDensityScale(); + scales = data->scales; // solnDiscretizations set in derived class. @@ -372,7 +379,7 @@ class pylith::_PressureGradient { solnkernel_disp, solnkernel_fluid_pressure, solnkernel_trace_strain, - solnkernel_vel, + solnkernel_velocity, solnkernel_fluid_pressure_dot, solnkernel_trace_strain_dot, }; @@ -382,12 +389,9 @@ class pylith::_PressureGradient { } // createDataStateVars }; // PressureGradient -const double pylith::_PressureGradient::LENGTH_SCALE = 1.0e+3; -const double pylith::_PressureGradient::TIME_SCALE = 2.0; -const double pylith::_PressureGradient::PRESSURE_SCALE = 2.25e+10; - -const double pylith::_PressureGradient::PRESSURE0 = 4.0e+6; -const double pylith::_PressureGradient::XMAX = 8.0e+3; +pylith::scales::Scales pylith::_PressureGradient::scales; +const double pylith::_PressureGradient::PRESSURE = 4.0e+6; +const double pylith::_PressureGradient::X_MAX = 8.0e+3; // ------------------------------------------------------------------------------------------------ pylith::TestLinearPoroelasticity_Data* diff --git a/tests/mmstests/poroelasticity/nofaults-2d/TestLinearPoroelasticity.cc b/tests/mmstests/poroelasticity/nofaults-2d/TestLinearPoroelasticity.cc index da2df51d9a..f55696a1a0 100644 --- a/tests/mmstests/poroelasticity/nofaults-2d/TestLinearPoroelasticity.cc +++ b/tests/mmstests/poroelasticity/nofaults-2d/TestLinearPoroelasticity.cc @@ -29,6 +29,7 @@ #include "pylith/utils/journals.hh" // pythia::journal #include "spatialdata/spatialdb/GravityField.hh" // USES GravityField +#include "pylith/scales/ElasticityScales.hh" // USES ElasticityScales // ------------------------------------------------------------------------------------------------ // Constuctor. @@ -79,7 +80,7 @@ pylith::TestLinearPoroelasticity::_initialize(void) { // Set up coordinates. _mesh->setCoordSys(&_data->cs); - pylith::topology::MeshOps::nondimensionalize(_mesh, _data->normalizer); + pylith::topology::MeshOps::nondimensionalize(_mesh, _data->scales); // Set up material _data->material.setBulkRheology(&_data->rheology); @@ -94,7 +95,7 @@ pylith::TestLinearPoroelasticity::_initialize(void) { // Set up problem. assert(_problem); - _problem->setNormalizer(_data->normalizer); + _problem->setScales(_data->scales); pylith::materials::Material* materials[1] = { &_data->material }; _problem->setMaterials(materials, 1); _problem->setBoundaryConditions(_data->bcs.data(), _data->bcs.size()); @@ -107,7 +108,7 @@ pylith::TestLinearPoroelasticity::_initialize(void) { assert(!_solution); _solution = new pylith::topology::Field(*_mesh);assert(_solution); _solution->setLabel("solution"); - pylith::problems::SolutionFactory factory(*_solution, _data->normalizer); + pylith::problems::SolutionFactory factory(*_solution, _data->scales); factory.addDisplacement(_data->solnDiscretizations[0]); factory.addPressure(_data->solnDiscretizations[1]); factory.addTraceStrain(_data->solnDiscretizations[2]); @@ -160,12 +161,12 @@ pylith::TestLinearPoroelasticity_Data::TestLinearPoroelasticity_Data(void) : useAsciiMesh(true), jacobianConvergenceRate(1.0), - tolerance(1.0e-9), + tolerance(4.0e-9), isJacobianLinear(true), allowZeroResidual(false), t(0.0), - dt(0.05), + dt(0.0), formulation(pylith::problems::Physics::QUASISTATIC), numSolnSubfields(0), @@ -176,6 +177,10 @@ pylith::TestLinearPoroelasticity_Data::TestLinearPoroelasticity_Data(void) : auxDiscretizations(NULL) { auxDB.setDescription("material auxiliary field spatial database"); cs.setSpaceDim(spaceDim); + + const double lengthScale = 8.0e+3; + pylith::scales::ElasticityScales::setQuasistaticPoroelasticity(&scales, lengthScale); + dt = 0.05*scales.getTimeScale(); } // constructor diff --git a/tests/mmstests/poroelasticity/nofaults-2d/TestLinearPoroelasticity.hh b/tests/mmstests/poroelasticity/nofaults-2d/TestLinearPoroelasticity.hh index ed1d4f8869..22d927d3b4 100644 --- a/tests/mmstests/poroelasticity/nofaults-2d/TestLinearPoroelasticity.hh +++ b/tests/mmstests/poroelasticity/nofaults-2d/TestLinearPoroelasticity.hh @@ -18,7 +18,7 @@ #include "spatialdata/spatialdb/UserFunctionDB.hh" // USES UserFunctionDB #include "spatialdata/geocoords/CSCart.hh" // USES CSCart -#include "spatialdata/units/Nondimensional.hh" // USES Nondimensional +#include "pylith/scales/Scales.hh" // USES Scales #include "pylith/problems/Physics.hh" // USES FormulationEnum #include "pylith/topology/Field.hh" // HASA FieldBase::Discretization @@ -87,7 +87,7 @@ public: PylithReal t; ///< Time for MMS solution. PylithReal dt; ///< Time step in simulation. spatialdata::geocoords::CSCart cs; ///< Coordinate system. - spatialdata::units::Nondimensional normalizer; ///< Scales for nondimensionalization. + pylith::scales::Scales scales; ///< Scales for nondimensionalization. pylith::problems::Physics::FormulationEnum formulation; ///< Time stepping formulation pylith::materials::Poroelasticity material; ///< Materials. diff --git a/tests/pytests/scales/Makefile.am b/tests/pytests/scales/Makefile.am new file mode 100644 index 0000000000..ebdf66d091 --- /dev/null +++ b/tests/pytests/scales/Makefile.am @@ -0,0 +1,22 @@ +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +include $(top_srcdir)/tests/check.am + +TESTS = test_scales.py +dist_check_SCRIPTS = test_scales.py + +noinst_PYTHON = \ + TestScales.py \ + TestQuasistaticElasticity.py \ + TestDynamicElasticity.py + + +# End of file diff --git a/tests/pytests/scales/TestGeneral.py b/tests/pytests/scales/TestGeneral.py new file mode 100644 index 0000000000..4f38057e1f --- /dev/null +++ b/tests/pytests/scales/TestGeneral.py @@ -0,0 +1,118 @@ +#!/usr/bin/env nemesis +# +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +import unittest + +from spatialdata.testing.TestCases import make_suite +from pylith.scales.General import General + +from pythia.pyre.units.length import meter +from pythia.pyre.units.pressure import pascal +from pythia.pyre.units.time import second +from pythia.pyre.units.mass import kilogram +from pythia.pyre.units.temperature import kelvin + + +class TestGeneral(unittest.TestCase): + + def test_constructor(self): + dim = General() + dim._configure() + + self.assertEqual(1.0 * meter, dim.getDisplacementScale()) + self.assertEqual(1.0 * meter, dim.getLengthScale()) + self.assertEqual(1.0 * pascal, dim.getRigidityScale()) + self.assertEqual(1.0 * second, dim.getTimeScale()) + self.assertEqual(1.0 * kelvin, dim.getTemperatureScale()) + + def test_displacementScale(self): + dim = General() + dim._configure() + dim.setDisplacementScale(2.0 * meter) + + self.assertEqual(2.0 * meter, dim.getDisplacementScale()) + self.assertEqual(1.0 * pascal, dim.getLengthScale()) + self.assertEqual(1.0 * pascal, dim.getRigidityScale()) + self.assertEqual(1.0 * second, dim.getTimeScale()) + + def test_lengthScale(self): + dim = General() + dim._configure() + dim.setLengthScale(2.0 * meter) + + self.assertEqual(1.0 * meter, dim.getDisplacementScale()) + self.assertEqual(2.0 * meter, dim.getLengthScale()) + self.assertEqual(1.0 * pascal, dim.getRigidityScale()) + self.assertEqual(1.0 * second, dim.getTimeScale()) + + def test_rigidityScale(self): + dim = General() + dim._configure() + dim.setRigidityScale(2.0 * pascal) + + self.assertEqual(1.0 * meter, dim.getDisplacementScale()) + self.assertEqual(1.0 * meter, dim.getLengthScale()) + self.assertEqual(2.0 * pascal, dim.getRigidityScale()) + self.assertEqual(1.0 * second, dim.getTimeScale()) + + def test_timeScale(self): + dim = General() + dim._configure() + dim.setTimeScale(2.0 * second) + + self.assertEqual(1.0 * meter, dim.getDisplacementScale()) + self.assertEqual(1.0 * meter, dim.getLengthScale()) + self.assertEqual(1.0 * pascal, dim.getRigidityScale()) + self.assertEqual(2.0 * second, dim.getTimeScale()) + + def test_temperatureScale(self): + dim = General() + dim._configure() + dim.setTemperatureScale(2.0 * kelvin) + + self.assertEqual(1.0 * meter, dim.getDisplacementScale()) + self.assertEqual(1.0 * meter, dim.getLengthScale()) + self.assertEqual(1.0 * pascal, dim.getRigidityScale()) + self.assertEqual(1.0 * second, dim.getTimeScale()) + self.assertEqual(2.0 * kelvin, dim.getTemperatureScale()) + + def test_nondimensionalize(self): + dim = General() + dim._configure() + + scale = 8.0 * meter + value = 2.0 * meter + valueE = 0.25 + + self.assertEqual(valueE, dim.nondimensionalize(value, scale)) + + def test_dimensionalize(self): + dim = General() + dim._configure() + + scale = 8.0 * meter + value = 0.25 + valueE = 2.0 * meter + + self.assertEqual(valueE, dim.dimensionalize(value, scale)) + + +def load_tests(loader, tests, pattern): + TEST_CLASSES = [TestGeneral] + return make_suite(test_classes=TEST_CLASSES, loader=loader) + + +if __name__ == "__main__": + unittest.main(verbosity=2) + + +# End of file diff --git a/tests/pytests/scales/TestQuasistaticElasticity.py b/tests/pytests/scales/TestQuasistaticElasticity.py new file mode 100644 index 0000000000..431add2705 --- /dev/null +++ b/tests/pytests/scales/TestQuasistaticElasticity.py @@ -0,0 +1,51 @@ +#!/usr/bin/env nemesis +# +# ================================================================================================= +# This code is part of SpatialData, developed through the Computational Infrastructure +# for Geodynamics (https://github.com/geodynamics/spatialdata). +# +# Copyright (c) 2010-2025, University of California, Davis and the SpatialData Development Team. +# All rights reserved. +# +# See https://mit-license.org/ and LICENSE.md and for license information. +# ================================================================================================= + +import unittest + +from spatialdata.testing.TestCases import make_suite +from pylith.scales.QuasistaticElasticity import QuasistaticElasticity + +from pythia.pyre.units.length import meter, kilometer +from pythia.pyre.units.pressure import pascal +from pythia.pyre.units.time import year + + +class TestElasticityScales(unittest.TestCase): + + def test_constructor(self): + dim = QuasistaticElasticity() + dim._configure() + + # Default values + displacementScale = 1.0 * meter + lengthScale = 100.0 * kilometer + rigidityScale = 1.0e10 * pascal + timeScale = 1.0e2 * year + + # Check defaults + self.assertEqual(displacementScale, dim.getDisplacementScale()) + self.assertEqual(lengthScale, dim.getLengthScale()) + self.assertEqual(rigidityScale, dim.getRigidityScale()) + self.assertEqual(timeScale, dim.getTimeScale()) + + +def load_tests(loader, tests, pattern): + TEST_CLASSES = [TestElasticityScales] + return make_suite(test_classes=TEST_CLASSES, loader=loader) + + +if __name__ == "__main__": + unittest.main(verbosity=2) + + +# End of file diff --git a/tests/pytests/scales/__init__.py b/tests/pytests/scales/__init__.py new file mode 100644 index 0000000000..adbbd07392 --- /dev/null +++ b/tests/pytests/scales/__init__.py @@ -0,0 +1,12 @@ +from . import ( + TestGeneral, + TestQuasistaticElasticity, + #TestDynamicElasticity, +) + +def test_modules(): + return [ + TestGeneral, + TestQuasistaticElasticity, + #TestDynamicElasticity, + ] diff --git a/tests/pytests/test_pylith.py b/tests/pytests/test_pylith.py index 1d8d6df526..e828e5908f 100755 --- a/tests/pytests/test_pylith.py +++ b/tests/pytests/test_pylith.py @@ -32,6 +32,7 @@ class TestApp: "meshio", "mpi", "problems", + "scales", "topology", "utils", ] diff --git a/tests/pytests/utils/TestConstants.py b/tests/pytests/utils/TestConstants.py index 6137408ca9..68972e83bc 100644 --- a/tests/pytests/utils/TestConstants.py +++ b/tests/pytests/utils/TestConstants.py @@ -5,27 +5,31 @@ # Copyright (c) 2010-2025, University of California, Davis and the PyLith Development Team. # All rights reserved. # -# See https://mit-license.org/ and LICENSE.md and for license information. +# See https://mit-license.org/ and LICENSE.md and for license information. # ================================================================================================= import unittest from pylith.testing.TestCases import make_suite + class TestConstants(unittest.TestCase): - """Unit testing of constants. - """ - - def test_maxdouble(self): - from pylith.utils.utils import maxdouble - self.assertAlmostEqual(1.0, maxdouble()/1.0e+99, 7) - return + """Unit testing of constants.""" + + def test_g_acc(self): + from pylith.utils.utils import g_acc + + self.assertAlmostEqual(1.0, g_acc() / 9.80665, 7) + + def test_max_double(self): + from pylith.utils.utils import max_double + + assert max_double() > 1.0e99 + def test_max_float(self): + from pylith.utils.utils import max_float - def test_maxfloat(self): - from pylith.utils.utils import maxfloat - self.assertAlmostEqual(1.0, maxfloat()/1.0e+30, 7) - return + assert max_float() > 1.0e30 def load_tests(loader, tests, pattern): @@ -37,4 +41,4 @@ def load_tests(loader, tests, pattern): unittest.main(verbosity=2) -# End of file +# End of file diff --git a/tests/src/MMSTest.cc b/tests/src/MMSTest.cc index c7a4794731..d34cb36605 100644 --- a/tests/src/MMSTest.cc +++ b/tests/src/MMSTest.cc @@ -16,6 +16,7 @@ #include "pylith/utils/PetscOptions.hh" // USES PetscOptions #include "pylith/topology/Mesh.hh" // USES Mesh +#include "pylith/topology/MeshOps.hh" // USES MeshOps #include "pylith/topology/Field.hh" // USES Field #include "petscts.h" // USES PetscTS @@ -36,7 +37,7 @@ pylith::testing::MMSTest::MMSTest(void) : _solutionExactVec(NULL), _solutionDotExactVec(NULL), _jacobianConvergenceRate(0.0), - _tolerance(1.0e-9), + _tolerance(1.0e-8), _isJacobianLinear(false), _allowZeroResidual(false) { GenericComponent::setName("mmstest"); // Override in child class for finer control of journal output. @@ -67,21 +68,24 @@ pylith::testing::MMSTest::testDiscretization(void) { PYLITH_METHOD_BEGIN; assert(_problem); - _initialize(); - + PetscErrorCode err = PETSC_SUCCESS; pythia::journal::debug_t debug(GenericComponent::getName()); + if (debug.state()) { + err = PetscOptionsSetValue(NULL, "-dm_plex_print_l2", "2");PYLITH_CHECK_ERROR(err); + } // if + + _initialize(); const pylith::topology::Field* solution = _problem->getSolution();assert(solution); if (debug.state()) { solution->view("Solution field layout", pylith::topology::Field::VIEW_LAYOUT); } // if - PetscErrorCode err = 0; - const PylithReal tolerance = -1.0; + const PylithReal ignoreTolerance = -1.0; const pylith::string_vector subfieldNames = solution->getSubfieldNames(); const size_t numSubfields = subfieldNames.size(); pylith::real_array error(numSubfields); err = DMSNESCheckDiscretization(_problem->getPetscSNES(), _problem->getPetscDM(), _problem->getStartTime(), - _solutionExactVec, tolerance, &error[0]);PYLITH_CHECK_ERROR(err); + _solutionExactVec, ignoreTolerance, &error[0]);PYLITH_CHECK_ERROR(err); if (debug.state()) { solution->view("Solution field"); @@ -89,11 +93,11 @@ pylith::testing::MMSTest::testDiscretization(void) { bool fail = false; std::ostringstream msg; + msg << "Discretization test failed for subfield(s):\n"; for (size_t i_field = 0; i_field < numSubfields; ++i_field) { - msg << "Discretization test failed for subfield(s): "; if (error[i_field] > _tolerance) { fail = true; - msg << " " << subfieldNames[i_field] << " (" << error[i_field] << ")"; + msg << " " << subfieldNames[i_field] << " (error=" << error[i_field] << ", tolerance="<< _tolerance << ")\n"; } // if } // for if (fail) { @@ -111,7 +115,7 @@ pylith::testing::MMSTest::testResidual(void) { PYLITH_METHOD_BEGIN; assert(_problem); - PetscErrorCode err = 0; + PetscErrorCode err = PETSC_SUCCESS; pythia::journal::debug_t debug(GenericComponent::getName()); if (debug.state()) { err = PetscOptionsSetValue(NULL, "-dm_plex_print_fem", "2");PYLITH_CHECK_ERROR(err); @@ -153,12 +157,12 @@ pylith::testing::MMSTest::testJacobianTaylorSeries(void) { assert(_solutionExactVec); assert(_solutionDotExactVec); - PetscErrorCode err = 0; - const PylithReal tolerance = -1.0; + PetscErrorCode err = PETSC_SUCCESS; + PetscBool isLinear = PETSC_FALSE; PylithReal convergenceRate = 0.0; err = DMTSCheckJacobian(_problem->getPetscTS(), _problem->getPetscDM(), _problem->getStartTime(), _solutionExactVec, - _solutionDotExactVec, tolerance, &isLinear, &convergenceRate);PYLITH_CHECK_ERROR(err); + _solutionDotExactVec, _tolerance, &isLinear, &convergenceRate);PYLITH_CHECK_ERROR(err); if (_isJacobianLinear) { REQUIRE(isLinear == PETSC_TRUE); @@ -178,7 +182,7 @@ pylith::testing::MMSTest::testJacobianFiniteDiff(void) { PYLITH_METHOD_BEGIN; assert(_problem); - PetscErrorCode err = 0; + PetscErrorCode err = PETSC_SUCCESS; err = PetscOptionsSetValue(NULL, "-ts_max_snes_failures", "1");PYLITH_CHECK_ERROR(err); err = PetscOptionsSetValue(NULL, "-ts_error_if_step_fails", "false");PYLITH_CHECK_ERROR(err); _initialize(); @@ -198,7 +202,7 @@ pylith::testing::MMSTest::testJacobianFiniteDiff(void) { err = SNESTestJacobian(_problem->getPetscSNES(), &jacobianNorm, &diffNorm);PYLITH_CHECK_ERROR(err); INFO("jacobianNorm=" << jacobianNorm << ", ||Code Jacobian - Finite Diff Jacobain||="<