pyStrata 0.5.0__tar.gz → 0.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyStrata-0.5.0 → pystrata-0.5.2}/HISTORY.rst +12 -0
- {pyStrata-0.5.0 → pystrata-0.5.2}/PKG-INFO +40 -29
- {pyStrata-0.5.0 → pystrata-0.5.2}/README.rst +23 -11
- {pyStrata-0.5.0 → pystrata-0.5.2}/pystrata/__init__.py +2 -4
- {pyStrata-0.5.0 → pystrata-0.5.2}/pystrata/motion.py +1 -1
- {pyStrata-0.5.0 → pystrata-0.5.2}/pystrata/output.py +7 -4
- {pyStrata-0.5.0 → pystrata-0.5.2}/pystrata/propagation.py +1 -1
- {pyStrata-0.5.0 → pystrata-0.5.2}/pystrata/site.py +117 -36
- {pyStrata-0.5.0 → pystrata-0.5.2}/pystrata/variation.py +53 -25
- {pyStrata-0.5.0/pyStrata.egg-info → pystrata-0.5.2/pystrata.egg-info}/PKG-INFO +40 -29
- pystrata-0.5.2/pystrata.egg-info/SOURCES.txt +26 -0
- {pyStrata-0.5.0 → pystrata-0.5.2}/requirements.txt +3 -1
- pystrata-0.5.2/setup.cfg +37 -0
- pystrata-0.5.2/setup.py +6 -0
- {pyStrata-0.5.0 → pystrata-0.5.2}/tests/__init__.py +0 -0
- pyStrata-0.5.0/tests/test_motion.py → pystrata-0.5.2/tests/motion_test.py +1 -1
- pyStrata-0.5.0/tests/test_notebooks.py → pystrata-0.5.2/tests/notebooks_test.py +1 -1
- pyStrata-0.5.0/tests/test_output.py → pystrata-0.5.2/tests/output_test.py +0 -3
- pyStrata-0.5.0/tests/test_propagation.py → pystrata-0.5.2/tests/propagation_test.py +12 -4
- pyStrata-0.5.0/tests/test_site.py → pystrata-0.5.2/tests/site_test.py +20 -0
- pyStrata-0.5.0/tests/test_variation.py → pystrata-0.5.2/tests/variation_test.py +43 -5
- pyStrata-0.5.0/pyStrata.egg-info/SOURCES.txt +0 -27
- pyStrata-0.5.0/pyStrata.egg-info/requires.txt +0 -10
- pyStrata-0.5.0/setup.cfg +0 -26
- pyStrata-0.5.0/setup.py +0 -48
- {pyStrata-0.5.0 → pystrata-0.5.2}/AUTHORS.rst +0 -0
- {pyStrata-0.5.0 → pystrata-0.5.2}/LICENSE +0 -0
- {pyStrata-0.5.0 → pystrata-0.5.2}/MANIFEST.in +0 -0
- {pyStrata-0.5.0 → pystrata-0.5.2}/pystrata/tools.py +0 -0
- {pyStrata-0.5.0/pyStrata.egg-info → pystrata-0.5.2/pystrata.egg-info}/dependency_links.txt +0 -0
- {pyStrata-0.5.0/pyStrata.egg-info → pystrata-0.5.2/pystrata.egg-info}/top_level.txt +0 -0
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
History
|
|
2
2
|
=======
|
|
3
3
|
|
|
4
|
+
v0.5.2 (2023-01-18)
|
|
5
|
+
-------------------
|
|
6
|
+
- Fixed: Providing unsmoothed transfer function output
|
|
7
|
+
- Fixed: MenqSoilType
|
|
8
|
+
|
|
9
|
+
v0.5.1 (2022-09-22)
|
|
10
|
+
-------------------
|
|
11
|
+
- Fixed: Correlation model from Toro. Previously used rho_0 instead of d_0, and the
|
|
12
|
+
wrong depth
|
|
13
|
+
- Renamed: BedrockDepthVariation to HalfSpaceDepthVariation
|
|
14
|
+
- Fixed: HalfSpaceDepthVariation was removing the last layer
|
|
15
|
+
|
|
4
16
|
v0.5.0 (2022-06-14)
|
|
5
17
|
-------------------
|
|
6
18
|
- Renamed to `pyStrata`.
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
|
-
Name:
|
|
3
|
-
Version: 0.5.
|
|
4
|
-
Summary: Site
|
|
5
|
-
Home-page:
|
|
6
|
-
Author: Albert Kottke
|
|
2
|
+
Name: pystrata
|
|
3
|
+
Version: 0.5.2
|
|
4
|
+
Summary: Site response analysis with Python
|
|
5
|
+
Home-page: https://github.com/arkottke/pystrata
|
|
6
|
+
Author: Albert R. Kottke
|
|
7
7
|
Author-email: albert.kottke@gmail.com
|
|
8
8
|
License: MIT
|
|
9
|
-
Keywords: site response
|
|
10
|
-
Classifier: Development Status :: 4 - Beta
|
|
11
|
-
Classifier: Environment :: Console
|
|
12
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
-
Classifier: Natural Language :: English
|
|
14
|
-
Classifier: Operating System :: OS Independent
|
|
15
|
-
Classifier: Programming Language :: Python
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
17
|
-
Classifier: Topic :: Scientific/Engineering
|
|
18
|
-
Classifier: Intended Audience :: Science/Research
|
|
19
|
-
Description-Content-Type: text/x-rst
|
|
20
|
-
Provides-Extra: dataframe
|
|
21
9
|
License-File: LICENSE
|
|
22
10
|
License-File: AUTHORS.rst
|
|
23
11
|
|
|
@@ -40,9 +28,20 @@ Strata_. These features include:
|
|
|
40
28
|
- equivalent-linear with frequency dependent properties
|
|
41
29
|
- quarter wavelength
|
|
42
30
|
- Nonlinear curve models:
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
- Predictive models:
|
|
32
|
+
- Darendeli (2001)
|
|
33
|
+
- Menq (2004)
|
|
34
|
+
- Kishida (2012)
|
|
35
|
+
- Curves:
|
|
36
|
+
- Vucetic & Dobry (1991)
|
|
37
|
+
- EPRI (1993)
|
|
38
|
+
- GEI (1983)
|
|
39
|
+
- GeoMatrix (1990)
|
|
40
|
+
- Idriss (1990)
|
|
41
|
+
- Imperial Valley Soils
|
|
42
|
+
- Iwasaki
|
|
43
|
+
- Peninsular Range
|
|
44
|
+
- Seed & Idriss
|
|
46
45
|
- Site and soil property uncertainty:
|
|
47
46
|
- Toro (1994) Vs correlation model
|
|
48
47
|
- G/Gmax and D uncertainty:
|
|
@@ -78,28 +77,40 @@ directory`_. An interactive Jupyter interface of these examples is available on
|
|
|
78
77
|
|
|
79
78
|
.. _Strata: https://github.com/arkottke/strata
|
|
80
79
|
.. _DOI: https://zenodo.org/badge/latestdoi/8959678
|
|
81
|
-
.. _`examples directory`: https://github.com/arkottke/pystrata/tree/
|
|
80
|
+
.. _`examples directory`: https://github.com/arkottke/pystrata/tree/main/examples
|
|
82
81
|
|
|
83
82
|
.. |PyPi Cheese Shop| image:: https://img.shields.io/pypi/v/pystrata.svg
|
|
84
83
|
:target: https://pypi.python.org/pypi/pystrata
|
|
85
|
-
.. |Build Status| image:: https://img.shields.io/
|
|
86
|
-
:
|
|
84
|
+
.. |Build Status| image:: https://img.shields.io/github/workflow/status/arkottke/pystrata/Python%20application
|
|
85
|
+
:alt: GitHub Workflow Status
|
|
86
|
+
:target: https://github.com/arkottke/pystrata/actions/workflows/python-app.yml
|
|
87
87
|
.. |Documentation Status| image:: https://readthedocs.org/projects/pystrata/badge/?version=latest&style=flat
|
|
88
88
|
:target: https://pystrata.readthedocs.org
|
|
89
|
-
.. |Code Quality| image:: https://
|
|
90
|
-
:target: https://www.codacy.com/
|
|
91
|
-
.. |Test Coverage| image:: https://
|
|
92
|
-
:target: https://www.codacy.com/
|
|
89
|
+
.. |Code Quality| image:: https://app.codacy.com/project/badge/Grade/6dbbb3a4279744d697b9bfe08af19ded
|
|
90
|
+
:target: https://www.codacy.com/gh/arkottke/pystrata/dashboard
|
|
91
|
+
.. |Test Coverage| image:: https://app.codacy.com/project/badge/Coverage/6dbbb3a4279744d697b9bfe08af19ded
|
|
92
|
+
:target: https://www.codacy.com/gh/arkottke/pystrata/dashboard
|
|
93
93
|
.. |License| image:: https://img.shields.io/badge/license-MIT-blue.svg
|
|
94
94
|
.. |Zenodo| image:: https://zenodo.org/badge/8959678.svg
|
|
95
95
|
:target: https://zenodo.org/badge/latestdoi/8959678
|
|
96
96
|
.. |MyBinder| image:: https://mybinder.org/badge_logo.svg
|
|
97
|
-
:target: https://mybinder.org/v2/gh/arkottke/pystrata/
|
|
98
|
-
|
|
97
|
+
:target: https://mybinder.org/v2/gh/arkottke/pystrata/main?filepath=examples
|
|
99
98
|
|
|
100
99
|
History
|
|
101
100
|
=======
|
|
102
101
|
|
|
102
|
+
v0.5.2 (2023-01-18)
|
|
103
|
+
-------------------
|
|
104
|
+
- Fixed: Providing unsmoothed transfer function output
|
|
105
|
+
- Fixed: MenqSoilType
|
|
106
|
+
|
|
107
|
+
v0.5.1 (2022-09-22)
|
|
108
|
+
-------------------
|
|
109
|
+
- Fixed: Correlation model from Toro. Previously used rho_0 instead of d_0, and the
|
|
110
|
+
wrong depth
|
|
111
|
+
- Renamed: BedrockDepthVariation to HalfSpaceDepthVariation
|
|
112
|
+
- Fixed: HalfSpaceDepthVariation was removing the last layer
|
|
113
|
+
|
|
103
114
|
v0.5.0 (2022-06-14)
|
|
104
115
|
-------------------
|
|
105
116
|
- Renamed to `pyStrata`.
|
|
@@ -17,9 +17,20 @@ Strata_. These features include:
|
|
|
17
17
|
- equivalent-linear with frequency dependent properties
|
|
18
18
|
- quarter wavelength
|
|
19
19
|
- Nonlinear curve models:
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
- Predictive models:
|
|
21
|
+
- Darendeli (2001)
|
|
22
|
+
- Menq (2004)
|
|
23
|
+
- Kishida (2012)
|
|
24
|
+
- Curves:
|
|
25
|
+
- Vucetic & Dobry (1991)
|
|
26
|
+
- EPRI (1993)
|
|
27
|
+
- GEI (1983)
|
|
28
|
+
- GeoMatrix (1990)
|
|
29
|
+
- Idriss (1990)
|
|
30
|
+
- Imperial Valley Soils
|
|
31
|
+
- Iwasaki
|
|
32
|
+
- Peninsular Range
|
|
33
|
+
- Seed & Idriss
|
|
23
34
|
- Site and soil property uncertainty:
|
|
24
35
|
- Toro (1994) Vs correlation model
|
|
25
36
|
- G/Gmax and D uncertainty:
|
|
@@ -55,20 +66,21 @@ directory`_. An interactive Jupyter interface of these examples is available on
|
|
|
55
66
|
|
|
56
67
|
.. _Strata: https://github.com/arkottke/strata
|
|
57
68
|
.. _DOI: https://zenodo.org/badge/latestdoi/8959678
|
|
58
|
-
.. _`examples directory`: https://github.com/arkottke/pystrata/tree/
|
|
69
|
+
.. _`examples directory`: https://github.com/arkottke/pystrata/tree/main/examples
|
|
59
70
|
|
|
60
71
|
.. |PyPi Cheese Shop| image:: https://img.shields.io/pypi/v/pystrata.svg
|
|
61
72
|
:target: https://pypi.python.org/pypi/pystrata
|
|
62
|
-
.. |Build Status| image:: https://img.shields.io/
|
|
63
|
-
:
|
|
73
|
+
.. |Build Status| image:: https://img.shields.io/github/workflow/status/arkottke/pystrata/Python%20application
|
|
74
|
+
:alt: GitHub Workflow Status
|
|
75
|
+
:target: https://github.com/arkottke/pystrata/actions/workflows/python-app.yml
|
|
64
76
|
.. |Documentation Status| image:: https://readthedocs.org/projects/pystrata/badge/?version=latest&style=flat
|
|
65
77
|
:target: https://pystrata.readthedocs.org
|
|
66
|
-
.. |Code Quality| image:: https://
|
|
67
|
-
:target: https://www.codacy.com/
|
|
68
|
-
.. |Test Coverage| image:: https://
|
|
69
|
-
:target: https://www.codacy.com/
|
|
78
|
+
.. |Code Quality| image:: https://app.codacy.com/project/badge/Grade/6dbbb3a4279744d697b9bfe08af19ded
|
|
79
|
+
:target: https://www.codacy.com/gh/arkottke/pystrata/dashboard
|
|
80
|
+
.. |Test Coverage| image:: https://app.codacy.com/project/badge/Coverage/6dbbb3a4279744d697b9bfe08af19ded
|
|
81
|
+
:target: https://www.codacy.com/gh/arkottke/pystrata/dashboard
|
|
70
82
|
.. |License| image:: https://img.shields.io/badge/license-MIT-blue.svg
|
|
71
83
|
.. |Zenodo| image:: https://zenodo.org/badge/8959678.svg
|
|
72
84
|
:target: https://zenodo.org/badge/latestdoi/8959678
|
|
73
85
|
.. |MyBinder| image:: https://mybinder.org/badge_logo.svg
|
|
74
|
-
:target: https://mybinder.org/v2/gh/arkottke/pystrata/
|
|
86
|
+
:target: https://mybinder.org/v2/gh/arkottke/pystrata/main?filepath=examples
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
# The MIT License (MIT)
|
|
2
3
|
#
|
|
3
4
|
# Copyright (c) 2016-2022 Albert Kottke
|
|
@@ -19,9 +20,6 @@
|
|
|
19
20
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
21
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
22
|
# SOFTWARE.
|
|
22
|
-
|
|
23
|
-
from pkg_resources import get_distribution
|
|
24
|
-
|
|
25
23
|
from . import motion
|
|
26
24
|
from . import output
|
|
27
25
|
from . import propagation
|
|
@@ -35,4 +33,4 @@ __author__ = "Albert Kottke"
|
|
|
35
33
|
__copyright__ = "Copyright 2016-2022 Albert Kottke"
|
|
36
34
|
__license__ = "MIT"
|
|
37
35
|
__title__ = "pyStrata"
|
|
38
|
-
__version__ =
|
|
36
|
+
__version__ = "0.5.2"
|
|
@@ -200,7 +200,7 @@ class TimeSeriesMotion(Motion):
|
|
|
200
200
|
tf : :class:`numpy.ndarray`
|
|
201
201
|
Complex-valued transfer function with length equal to `self.freq`.
|
|
202
202
|
"""
|
|
203
|
-
return -(osc_freq
|
|
203
|
+
return -(osc_freq**2.0) / (
|
|
204
204
|
np.square(self.freqs)
|
|
205
205
|
- np.square(osc_freq)
|
|
206
206
|
- 2.0j * damping * osc_freq * self.freqs
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
# The MIT License (MIT)
|
|
2
3
|
#
|
|
3
4
|
# Copyright (c) 2016-2021 Albert Kottke
|
|
@@ -406,7 +407,7 @@ class AriasIntensityTSOutput(AccelerationTSOutput):
|
|
|
406
407
|
|
|
407
408
|
def _modify_values(self, calc, location, values):
|
|
408
409
|
time_step = calc.motion.time_step
|
|
409
|
-
values = scipy.integrate.cumtrapz(values
|
|
410
|
+
values = scipy.integrate.cumtrapz(values**2, dx=time_step)
|
|
410
411
|
values *= GRAVITY * np.pi / 2
|
|
411
412
|
return values
|
|
412
413
|
|
|
@@ -486,15 +487,17 @@ class FourierAmplitudeSpectrumOutput(LocationBasedOutput):
|
|
|
486
487
|
loc = self._get_location(calc)
|
|
487
488
|
tf = calc.calc_accel_tf(calc.loc_input, loc)
|
|
488
489
|
|
|
489
|
-
if self.
|
|
490
|
-
|
|
490
|
+
if self._ko_bandwidth is None:
|
|
491
|
+
tf = np.interp(self.freqs, calc.motion.freqs, tf)
|
|
492
|
+
else:
|
|
493
|
+
tf = pykooh.smooth(
|
|
491
494
|
self.freqs,
|
|
492
495
|
calc.motion.freqs,
|
|
493
496
|
np.abs(tf * calc.motion.fourier_amps),
|
|
494
497
|
self.ko_bandwidth,
|
|
495
498
|
)
|
|
496
499
|
|
|
497
|
-
self._add_values(
|
|
500
|
+
self._add_values(tf)
|
|
498
501
|
|
|
499
502
|
|
|
500
503
|
class ResponseSpectrumOutput(LocationBasedOutput):
|
|
@@ -452,7 +452,7 @@ class LinearElasticCalculator(AbstractCalculator):
|
|
|
452
452
|
- self._waves_b[lout.index, :] * np.exp(-cterm)
|
|
453
453
|
)
|
|
454
454
|
)
|
|
455
|
-
denom = -(ang_freqs
|
|
455
|
+
denom = -(ang_freqs**2) * self.wave_at_location(lin)
|
|
456
456
|
|
|
457
457
|
# Only compute transfer function for non-zero frequencies
|
|
458
458
|
mask = ~np.isclose(ang_freqs, 0)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
# The MIT License (MIT)
|
|
2
3
|
#
|
|
3
4
|
# Copyright (c) 2016-2018 Albert Kottke
|
|
@@ -22,7 +23,10 @@
|
|
|
22
23
|
from __future__ import annotations
|
|
23
24
|
|
|
24
25
|
import collections
|
|
26
|
+
import warnings
|
|
25
27
|
from dataclasses import dataclass
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
from typing import List
|
|
26
30
|
from typing import Optional
|
|
27
31
|
from typing import Tuple
|
|
28
32
|
|
|
@@ -30,6 +34,7 @@ import matplotlib.pyplot as plt
|
|
|
30
34
|
import numpy as np
|
|
31
35
|
import numpy.typing as npt
|
|
32
36
|
import scipy.constants
|
|
37
|
+
import tomli
|
|
33
38
|
from scipy.interpolate import interp1d
|
|
34
39
|
|
|
35
40
|
from .motion import GRAVITY
|
|
@@ -39,6 +44,32 @@ COMP_MODULUS_MODEL = "dormieux"
|
|
|
39
44
|
|
|
40
45
|
KPA_TO_ATM = scipy.constants.kilo / scipy.constants.atm
|
|
41
46
|
|
|
47
|
+
PUBLISHED_CURVES = None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _load_published_curves():
|
|
51
|
+
"""Load published nonlinear curves."""
|
|
52
|
+
global PUBLISHED_CURVES
|
|
53
|
+
|
|
54
|
+
fpath = Path(__file__).parent / "data" / "published_curves.toml"
|
|
55
|
+
with fpath.open("rb") as fp:
|
|
56
|
+
models = tomli.load(fp)["models"]
|
|
57
|
+
|
|
58
|
+
# Count to make sure there aren't repeated names
|
|
59
|
+
counts = collections.Counter([m["name"] for m in models])
|
|
60
|
+
if max(counts.values()) > 1:
|
|
61
|
+
names = ", ".join([k for k, v in counts.items() if v > 1])
|
|
62
|
+
warnings.warn(f"Repeated names in {fpath}: " + names)
|
|
63
|
+
|
|
64
|
+
PUBLISHED_CURVES = {m["name"]: m for m in models}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def known_published_curves() -> List[dict]:
|
|
68
|
+
"""List of published curves in the database."""
|
|
69
|
+
if not PUBLISHED_CURVES:
|
|
70
|
+
_load_published_curves()
|
|
71
|
+
return list(PUBLISHED_CURVES.keys())
|
|
72
|
+
|
|
42
73
|
|
|
43
74
|
class NonlinearProperty(object):
|
|
44
75
|
"""Class for nonlinear property with a method for log-linear interpolation.
|
|
@@ -76,6 +107,18 @@ class NonlinearProperty(object):
|
|
|
76
107
|
|
|
77
108
|
self._update()
|
|
78
109
|
|
|
110
|
+
@classmethod
|
|
111
|
+
def from_published(cls, name, param):
|
|
112
|
+
assert param in cls.PARAMS
|
|
113
|
+
if not PUBLISHED_CURVES:
|
|
114
|
+
_load_published_curves()
|
|
115
|
+
|
|
116
|
+
selected = PUBLISHED_CURVES[name][param]
|
|
117
|
+
|
|
118
|
+
return cls(
|
|
119
|
+
name, strains=selected["strains"], values=selected["values"], param=param
|
|
120
|
+
)
|
|
121
|
+
|
|
79
122
|
def __call__(self, strains):
|
|
80
123
|
"""Return the nonlinear property at a specific strain.
|
|
81
124
|
|
|
@@ -192,6 +235,21 @@ class SoilType(object):
|
|
|
192
235
|
self.mod_reduc = mod_reduc
|
|
193
236
|
self.damping = damping
|
|
194
237
|
|
|
238
|
+
@classmethod
|
|
239
|
+
def from_published(cls, name, unit_wt, *args):
|
|
240
|
+
if not PUBLISHED_CURVES:
|
|
241
|
+
_load_published_curves()
|
|
242
|
+
|
|
243
|
+
model_mr = args[0]
|
|
244
|
+
model_d = args[1] if len(args) > 1 else args[0]
|
|
245
|
+
|
|
246
|
+
return cls(
|
|
247
|
+
name,
|
|
248
|
+
unit_wt=unit_wt,
|
|
249
|
+
mod_reduc=NonlinearProperty.from_published(model_mr, "mod_reduc"),
|
|
250
|
+
damping=NonlinearProperty.from_published(model_d, "damping"),
|
|
251
|
+
)
|
|
252
|
+
|
|
195
253
|
def copy(self):
|
|
196
254
|
return SoilType(self.name, self.unit_wt, self.mod_reduc, self.damping)
|
|
197
255
|
|
|
@@ -227,7 +285,7 @@ class SoilType(object):
|
|
|
227
285
|
# return all(
|
|
228
286
|
# getattr(self, attr) == getattr(other, attr)
|
|
229
287
|
# for attr in ['name', 'unit_wt', 'mod_reduc', 'damping'])
|
|
230
|
-
return self.__dict__ == other.__dict__
|
|
288
|
+
return (type(self) == type(other)) and (self.__dict__ == other.__dict__)
|
|
231
289
|
|
|
232
290
|
def __hash__(self):
|
|
233
291
|
return hash(self.__dict__.values())
|
|
@@ -269,22 +327,22 @@ class ModifiedHyperbolicSoilType(SoilType):
|
|
|
269
327
|
- strain_ref_percent
|
|
270
328
|
* np.log((strains_percent + strain_ref_percent) / strain_ref_percent)
|
|
271
329
|
)
|
|
272
|
-
/ (strains_percent
|
|
330
|
+
/ (strains_percent**2 / (strains_percent + strain_ref_percent))
|
|
273
331
|
- 2.0
|
|
274
332
|
)
|
|
275
333
|
# Correction between perfect hyperbolic strain model and modified
|
|
276
334
|
# model [%].
|
|
277
|
-
c1 = -1.1143 * self.curvature
|
|
278
|
-
c2 = 0.0805 * self.curvature
|
|
279
|
-
c3 = -0.0005 * self.curvature
|
|
335
|
+
c1 = -1.1143 * self.curvature**2 + 1.8618 * self.curvature + 0.2523
|
|
336
|
+
c2 = 0.0805 * self.curvature**2 - 0.0710 * self.curvature - 0.0095
|
|
337
|
+
c3 = -0.0005 * self.curvature**2 + 0.0002 * self.curvature + 0.0003
|
|
280
338
|
damping_masing = (
|
|
281
339
|
c1 * damping_masing_a1
|
|
282
|
-
+ c2 * damping_masing_a1
|
|
283
|
-
+ c3 * damping_masing_a1
|
|
340
|
+
+ c2 * damping_masing_a1**2
|
|
341
|
+
+ c3 * damping_masing_a1**3
|
|
284
342
|
)
|
|
285
343
|
|
|
286
344
|
# Compute the damping correction in percent
|
|
287
|
-
d_correction = self.masing_scaling * damping_masing * mod_reduc
|
|
345
|
+
d_correction = self.masing_scaling * damping_masing * mod_reduc**0.1
|
|
288
346
|
|
|
289
347
|
# Prevent the damping from reducing as it can at large strains
|
|
290
348
|
damping = np.maximum.accumulate(d_correction / 100.0)
|
|
@@ -371,14 +429,14 @@ class TwoParamModifiedHyperbolicSoilType(SoilType):
|
|
|
371
429
|
stress_mean_atm = stress_mean * KPA_TO_ATM
|
|
372
430
|
|
|
373
431
|
# Convert from percent to decimal strain
|
|
374
|
-
strain_mr = C.g1 * stress_mean_atm
|
|
432
|
+
strain_mr = C.g1 * stress_mean_atm**C.g2 / 100
|
|
375
433
|
b = C.b1 + C.b2 * stress_mean_atm
|
|
376
434
|
values_mr = 1 / ((1 + (strains / strain_mr) ** C.a)) ** b
|
|
377
435
|
mod_reduc = NonlinearProperty(name, strains, values_mr)
|
|
378
436
|
|
|
379
|
-
d_min = C.d0 * stress_mean_atm
|
|
437
|
+
d_min = C.d0 * stress_mean_atm**C.d1
|
|
380
438
|
# Convert from percent to decimal strain
|
|
381
|
-
strain_dr = (C.gd1 * stress_mean_atm
|
|
439
|
+
strain_dr = (C.gd1 * stress_mean_atm**C.gd2) / 100
|
|
382
440
|
term = (strains / strain_dr) ** C.c
|
|
383
441
|
# Convert to damping in decimal
|
|
384
442
|
values_d = (C.d * term + d_min) / (term + 1) / 100
|
|
@@ -437,7 +495,7 @@ class DarendeliSoilType(ModifiedHyperbolicSoilType):
|
|
|
437
495
|
def _calc_damping_min(self):
|
|
438
496
|
"""minimum damping [decimal]"""
|
|
439
497
|
return (
|
|
440
|
-
(0.8005 + 0.0129 * self._plas_index * self._ocr
|
|
498
|
+
(0.8005 + 0.0129 * self._plas_index * self._ocr**-0.1069)
|
|
441
499
|
* (self._stress_mean * KPA_TO_ATM) ** -0.2889
|
|
442
500
|
* (1 + 0.2919 * np.log(self._freq))
|
|
443
501
|
) / 100
|
|
@@ -451,7 +509,7 @@ class DarendeliSoilType(ModifiedHyperbolicSoilType):
|
|
|
451
509
|
def strain_ref(self):
|
|
452
510
|
"""reference strain [decimal]"""
|
|
453
511
|
return (
|
|
454
|
-
(0.0352 + 0.0010 * self._plas_index * self._ocr
|
|
512
|
+
(0.0352 + 0.0010 * self._plas_index * self._ocr**0.3246)
|
|
455
513
|
* (self._stress_mean * KPA_TO_ATM) ** 0.3483
|
|
456
514
|
) / 100
|
|
457
515
|
|
|
@@ -464,7 +522,7 @@ class DarendeliSoilType(ModifiedHyperbolicSoilType):
|
|
|
464
522
|
return fmt.format(self._plas_index, self._ocr, self._stress_mean)
|
|
465
523
|
|
|
466
524
|
|
|
467
|
-
class MenqSoilType(
|
|
525
|
+
class MenqSoilType(ModifiedHyperbolicSoilType):
|
|
468
526
|
"""
|
|
469
527
|
Menq SoilType for gravelly soils.
|
|
470
528
|
|
|
@@ -510,18 +568,23 @@ class MenqSoilType(DarendeliSoilType):
|
|
|
510
568
|
def _calc_damping_min(self):
|
|
511
569
|
return (
|
|
512
570
|
0.55
|
|
513
|
-
* self._uniformity_coeff
|
|
514
|
-
* self._diam_mean
|
|
571
|
+
* self._uniformity_coeff**0.1
|
|
572
|
+
* self._diam_mean**-0.3
|
|
515
573
|
* (self._stress_mean * KPA_TO_ATM) ** -0.08
|
|
516
574
|
) / 100
|
|
517
575
|
|
|
576
|
+
@property
|
|
577
|
+
def masing_scaling(self):
|
|
578
|
+
# Masing correction factor
|
|
579
|
+
return 0.6329 - 0.00566 * np.log(self._num_cycles)
|
|
580
|
+
|
|
518
581
|
@property
|
|
519
582
|
def strain_ref(self):
|
|
520
583
|
return (
|
|
521
584
|
0.12
|
|
522
|
-
* self._uniformity_coeff
|
|
585
|
+
* self._uniformity_coeff**-0.6
|
|
523
586
|
* (self._stress_mean * KPA_TO_ATM)
|
|
524
|
-
** (0.5 * self._uniformity_coeff
|
|
587
|
+
** (0.5 * self._uniformity_coeff**-0.15)
|
|
525
588
|
) / 100
|
|
526
589
|
|
|
527
590
|
@property
|
|
@@ -758,13 +821,7 @@ class Layer(object):
|
|
|
758
821
|
|
|
759
822
|
self._soil_type = soil_type
|
|
760
823
|
self._thickness = thickness
|
|
761
|
-
self.
|
|
762
|
-
|
|
763
|
-
self._damping = None
|
|
764
|
-
self._shear_mod = None
|
|
765
|
-
self._strain = None
|
|
766
|
-
self.strain_max = None
|
|
767
|
-
self.reset()
|
|
824
|
+
self.initial_shear_vel = shear_vel
|
|
768
825
|
|
|
769
826
|
self._depth = 0
|
|
770
827
|
self._stress_vert = 0
|
|
@@ -781,6 +838,20 @@ class Layer(object):
|
|
|
781
838
|
f"soil_type={st_name})>"
|
|
782
839
|
)
|
|
783
840
|
|
|
841
|
+
def __eq__(self, other):
|
|
842
|
+
attrs = ["_soil_type", "_thickness", "initial_shear_vel"]
|
|
843
|
+
return (type(self) == type(other)) and all(
|
|
844
|
+
[getattr(self, a) == getattr(other, a) for a in attrs]
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
def __hash__(self):
|
|
848
|
+
return hash(self.__dict__.values())
|
|
849
|
+
|
|
850
|
+
@classmethod
|
|
851
|
+
def copy_of(cls, other):
|
|
852
|
+
"""Return a copy of the Layer instance with previously defined SoilType."""
|
|
853
|
+
return cls(other.soil_type, other.thickness, other.shear_vel)
|
|
854
|
+
|
|
784
855
|
@property
|
|
785
856
|
def depth(self):
|
|
786
857
|
"""Depth to the top of the layer [m]."""
|
|
@@ -796,11 +867,6 @@ class Layer(object):
|
|
|
796
867
|
"""Depth to the base of the layer [m]."""
|
|
797
868
|
return self._depth + self._thickness
|
|
798
869
|
|
|
799
|
-
@classmethod
|
|
800
|
-
def duplicate(cls, other):
|
|
801
|
-
"""Create a copy of the layer."""
|
|
802
|
-
return cls(other.soil_type, other.thickness, other.shear_vel)
|
|
803
|
-
|
|
804
870
|
@property
|
|
805
871
|
def density(self):
|
|
806
872
|
"""Density of soil in [kg/m³]."""
|
|
@@ -818,13 +884,21 @@ class Layer(object):
|
|
|
818
884
|
@property
|
|
819
885
|
def initial_shear_mod(self):
|
|
820
886
|
"""Initial (small-strain) shear modulus [kN/m²]."""
|
|
821
|
-
return self.density * self.initial_shear_vel
|
|
887
|
+
return self.density * self.initial_shear_vel**2
|
|
822
888
|
|
|
823
889
|
@property
|
|
824
890
|
def initial_shear_vel(self):
|
|
825
891
|
"""Initial (small-strain) shear-wave velocity [m/s]."""
|
|
826
892
|
return self._initial_shear_vel
|
|
827
893
|
|
|
894
|
+
@initial_shear_vel.setter
|
|
895
|
+
def initial_shear_vel(self, value: float):
|
|
896
|
+
"""Set initial (small-strain) shear-wave velocity [m/s]."""
|
|
897
|
+
|
|
898
|
+
self._initial_shear_vel = value
|
|
899
|
+
# Reset the iterated values
|
|
900
|
+
self.reset()
|
|
901
|
+
|
|
828
902
|
@property
|
|
829
903
|
def comp_shear_mod(self):
|
|
830
904
|
"""Strain-compatible complex shear modulus [kN/m²]."""
|
|
@@ -838,12 +912,12 @@ class Layer(object):
|
|
|
838
912
|
# Simplifed shear modulus (Kramer, 1996)
|
|
839
913
|
# Correct dissipated energy
|
|
840
914
|
# Incorrect shear modulus: G * \sqrt{1 + 2 \beta^2 + \beta^4 }
|
|
841
|
-
comp_factor = 1 - damping
|
|
915
|
+
comp_factor = 1 - damping**2 + 2j * damping
|
|
842
916
|
elif COMP_MODULUS_MODEL == "dormieux":
|
|
843
917
|
# Dormieux and Canou (1990)
|
|
844
918
|
# Correct dissipated energy
|
|
845
919
|
# Correct shear modulus:
|
|
846
|
-
comp_factor = np.sqrt(1 - 4 * damping
|
|
920
|
+
comp_factor = np.sqrt(1 - 4 * damping**2) + 2j * damping
|
|
847
921
|
else:
|
|
848
922
|
raise NotImplementedError
|
|
849
923
|
comp_shear_mod = self.shear_mod * comp_factor
|
|
@@ -864,6 +938,8 @@ class Layer(object):
|
|
|
864
938
|
# Use a small initial value
|
|
865
939
|
self._strain = IterativeValue(1e-6)
|
|
866
940
|
|
|
941
|
+
self.strain_max = None
|
|
942
|
+
|
|
867
943
|
@property
|
|
868
944
|
def shear_mod(self):
|
|
869
945
|
"""Strain-compatible shear modulus [kN//m²]."""
|
|
@@ -933,7 +1009,7 @@ class Layer(object):
|
|
|
933
1009
|
@thickness.setter
|
|
934
1010
|
def thickness(self, thickness):
|
|
935
1011
|
self._thickness = thickness
|
|
936
|
-
self._profile.update_layers(self
|
|
1012
|
+
self._profile.update_layers(self._profile.index(self) + 1)
|
|
937
1013
|
|
|
938
1014
|
@property
|
|
939
1015
|
def travel_time(self):
|
|
@@ -1050,6 +1126,11 @@ class Profile(collections.abc.Container):
|
|
|
1050
1126
|
def __getitem__(self, key):
|
|
1051
1127
|
return self.layers[key]
|
|
1052
1128
|
|
|
1129
|
+
@classmethod
|
|
1130
|
+
def copy_of(cls, other):
|
|
1131
|
+
"""Return a copy of the profile with new Layer instances."""
|
|
1132
|
+
return cls([Layer.copy_of(layer) for layer in other], other.wt_depth)
|
|
1133
|
+
|
|
1053
1134
|
def index(self, layer):
|
|
1054
1135
|
return self.layers.index(layer)
|
|
1055
1136
|
|
|
@@ -1259,7 +1340,7 @@ class Profile(collections.abc.Container):
|
|
|
1259
1340
|
depths_mid = self.depth_mid
|
|
1260
1341
|
shear_vels = self.initial_shear_vel
|
|
1261
1342
|
|
|
1262
|
-
mode_incr = depths_mid * thicks / shear_vels
|
|
1343
|
+
mode_incr = depths_mid * thicks / shear_vels**2
|
|
1263
1344
|
# Mode shape is computed as the sumation from the base of
|
|
1264
1345
|
# the profile. Need to append a 0 for the roll performed in the next
|
|
1265
1346
|
# step
|
|
@@ -1269,7 +1350,7 @@ class Profile(collections.abc.Container):
|
|
|
1269
1350
|
# can be calculated for two adjacent layers
|
|
1270
1351
|
freq_fund = np.sqrt(
|
|
1271
1352
|
4
|
|
1272
|
-
* np.sum(thicks * depths_mid
|
|
1353
|
+
* np.sum(thicks * depths_mid**2 / shear_vels**2)
|
|
1273
1354
|
/ np.sum(
|
|
1274
1355
|
thicks * np.sum(np.c_[shape, np.roll(shape, -1)], axis=1)[:-1] ** 2
|
|
1275
1356
|
)
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
21
|
# SOFTWARE.
|
|
22
22
|
import copy
|
|
23
|
+
from abc import abstractmethod
|
|
23
24
|
from typing import Dict
|
|
24
25
|
from typing import List
|
|
25
26
|
from typing import Optional
|
|
@@ -241,24 +242,47 @@ class ToroThicknessVariation(object):
|
|
|
241
242
|
return varied
|
|
242
243
|
|
|
243
244
|
|
|
244
|
-
class
|
|
245
|
-
def __init__(
|
|
246
|
-
self,
|
|
247
|
-
dist: stats.rv_continuous,
|
|
248
|
-
discretize_kwds: Optional[Dict[str, float]] = None,
|
|
249
|
-
):
|
|
245
|
+
class HalfSpaceDepthVariation(object):
|
|
246
|
+
def __init__(self, dist: stats.rv_continuous):
|
|
250
247
|
self._dist = dist
|
|
251
|
-
self._discretize_kwds = discretize_kwds or dict(max_freq=50, wave_frac=2)
|
|
252
248
|
|
|
253
249
|
def __call__(self, profile: site.Profile) -> site.Profile:
|
|
250
|
+
# Update the distribution with the central value of the profile
|
|
254
251
|
varied_depth = self._dist.rvs()
|
|
255
252
|
|
|
253
|
+
# Find the layer
|
|
256
254
|
index, depth_within = profile.lookup_depth(varied_depth)
|
|
257
255
|
|
|
258
|
-
|
|
259
|
-
|
|
256
|
+
print(varied_depth, profile[-1].depth, index, depth_within)
|
|
257
|
+
|
|
258
|
+
half_space = profile[-1]
|
|
259
|
+
|
|
260
|
+
if index < (len(profile) - 1):
|
|
261
|
+
# Variation is within the layers
|
|
262
|
+
layers = [site.Layer.copy_of(layer) for layer in profile[: (index + 1)]]
|
|
263
|
+
# Reduce the thickness of the layer above the half-space
|
|
264
|
+
layers[-1]._thickness = depth_within
|
|
265
|
+
else:
|
|
266
|
+
# Variation extends past the depth of the model
|
|
267
|
+
orig_thick = profile[-2].thickness
|
|
268
|
+
total_thick = orig_thick + depth_within
|
|
269
|
+
count = np.ceil(total_thick // orig_thick).astype(int)
|
|
270
|
+
|
|
271
|
+
thick = total_thick / count
|
|
260
272
|
|
|
261
|
-
|
|
273
|
+
print(count, thick)
|
|
274
|
+
|
|
275
|
+
# Don't copy half-space
|
|
276
|
+
layers = [site.Layer.copy_of(layer) for layer in profile[:-1]]
|
|
277
|
+
# Don't call the setter function as it needs a profile defined
|
|
278
|
+
layers[-1]._thickness = thick
|
|
279
|
+
parent = layers[-1]
|
|
280
|
+
for _ in range(count - 1):
|
|
281
|
+
layers.append(site.Layer.copy_of(parent))
|
|
282
|
+
|
|
283
|
+
layers.append(half_space)
|
|
284
|
+
|
|
285
|
+
return site.Profile(layers, profile.wt_depth)
|
|
262
286
|
|
|
263
287
|
|
|
264
288
|
class LayerThicknessVariation(object):
|
|
@@ -302,17 +326,12 @@ class VelocityVariation(object):
|
|
|
302
326
|
ln_vel = np.clip(ln_vel_rand, mean - offset, mean + offset)
|
|
303
327
|
vel = np.exp(ln_vel)
|
|
304
328
|
|
|
305
|
-
|
|
329
|
+
varied = site.Profile.copy_of(profile)
|
|
330
|
+
# Update the velocities
|
|
306
331
|
end = None if self.vary_bedrock else -1
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
site.Layer(l.soil_type, l.thickness, vel[i])
|
|
310
|
-
for i, l in enumerate(profile[:end])
|
|
311
|
-
]
|
|
312
|
-
if not self.vary_bedrock:
|
|
313
|
-
layers.append(profile[-1])
|
|
332
|
+
for i, v in enumerate(vel[:end]):
|
|
333
|
+
varied[i].initial_shear_vel = v
|
|
314
334
|
|
|
315
|
-
varied = site.Profile(layers, profile.wt_depth)
|
|
316
335
|
return varied
|
|
317
336
|
|
|
318
337
|
def _calc_covar_matrix(self, profile):
|
|
@@ -341,6 +360,7 @@ class VelocityVariation(object):
|
|
|
341
360
|
|
|
342
361
|
return mat
|
|
343
362
|
|
|
363
|
+
@abstractmethod
|
|
344
364
|
def _calc_corr(self, profile):
|
|
345
365
|
"""Compute the adjacent-layer correlations.
|
|
346
366
|
|
|
@@ -356,6 +376,7 @@ class VelocityVariation(object):
|
|
|
356
376
|
"""
|
|
357
377
|
raise NotImplementedError
|
|
358
378
|
|
|
379
|
+
@abstractmethod
|
|
359
380
|
def _calc_ln_std(self, profile):
|
|
360
381
|
"""Compute the standard deviation for each layer.
|
|
361
382
|
|
|
@@ -497,13 +518,20 @@ class ToroVelocityVariation(VelocityVariation):
|
|
|
497
518
|
corr : :class:`numpy.array`
|
|
498
519
|
Adjacent-layer correlations
|
|
499
520
|
"""
|
|
500
|
-
|
|
521
|
+
|
|
522
|
+
# Toro defines the depth as the average midpoint depths of layers i and i-1.
|
|
523
|
+
depths_mid = np.array(profile.depth_mid)
|
|
524
|
+
depth = np.mean(np.c_[depths_mid[:-1], depths_mid[1:]], axis=1)
|
|
525
|
+
|
|
526
|
+
# t variable from Toro; defined as the difference of the midpoint depths
|
|
501
527
|
thick = np.diff(depth)
|
|
502
|
-
depth
|
|
528
|
+
# Remove the depth associated with the final layer. We will set that it is
|
|
529
|
+
# perfectly correlated later.
|
|
530
|
+
depth = depth[:-1]
|
|
503
531
|
|
|
504
532
|
# Depth dependent correlation
|
|
505
533
|
corr_depth = self.rho_200 * np.power(
|
|
506
|
-
(depth + self.
|
|
534
|
+
(depth + self.h_0) / (200 + self.h_0), self.b
|
|
507
535
|
)
|
|
508
536
|
corr_depth[depth > 200] = self.rho_200
|
|
509
537
|
|
|
@@ -627,7 +655,7 @@ class DepthDependToroVelVariation(ToroVelocityVariation):
|
|
|
627
655
|
rho_200: float,
|
|
628
656
|
h_0: float,
|
|
629
657
|
b: float,
|
|
630
|
-
ln_std_map=Optional[Dict[str,float]],
|
|
658
|
+
ln_std_map=Optional[Dict[str, float]],
|
|
631
659
|
vary_bedrock=False,
|
|
632
660
|
):
|
|
633
661
|
"""Initialize the model."""
|
|
@@ -875,9 +903,9 @@ def iter_varied_profiles(
|
|
|
875
903
|
var_velocity: VelocityVariation = None,
|
|
876
904
|
var_soiltypes: SoilTypeVariation = None,
|
|
877
905
|
):
|
|
878
|
-
for
|
|
906
|
+
for _ in range(count):
|
|
879
907
|
# Copy the profile to form the realization
|
|
880
|
-
p = profile
|
|
908
|
+
p = site.Profile.copy_of(profile)
|
|
881
909
|
|
|
882
910
|
if var_thickness:
|
|
883
911
|
p = var_thickness(p)
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
|
-
Name:
|
|
3
|
-
Version: 0.5.
|
|
4
|
-
Summary: Site
|
|
5
|
-
Home-page:
|
|
6
|
-
Author: Albert Kottke
|
|
2
|
+
Name: pystrata
|
|
3
|
+
Version: 0.5.2
|
|
4
|
+
Summary: Site response analysis with Python
|
|
5
|
+
Home-page: https://github.com/arkottke/pystrata
|
|
6
|
+
Author: Albert R. Kottke
|
|
7
7
|
Author-email: albert.kottke@gmail.com
|
|
8
8
|
License: MIT
|
|
9
|
-
Keywords: site response
|
|
10
|
-
Classifier: Development Status :: 4 - Beta
|
|
11
|
-
Classifier: Environment :: Console
|
|
12
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
-
Classifier: Natural Language :: English
|
|
14
|
-
Classifier: Operating System :: OS Independent
|
|
15
|
-
Classifier: Programming Language :: Python
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.6
|
|
17
|
-
Classifier: Topic :: Scientific/Engineering
|
|
18
|
-
Classifier: Intended Audience :: Science/Research
|
|
19
|
-
Description-Content-Type: text/x-rst
|
|
20
|
-
Provides-Extra: dataframe
|
|
21
9
|
License-File: LICENSE
|
|
22
10
|
License-File: AUTHORS.rst
|
|
23
11
|
|
|
@@ -40,9 +28,20 @@ Strata_. These features include:
|
|
|
40
28
|
- equivalent-linear with frequency dependent properties
|
|
41
29
|
- quarter wavelength
|
|
42
30
|
- Nonlinear curve models:
|
|
43
|
-
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
- Predictive models:
|
|
32
|
+
- Darendeli (2001)
|
|
33
|
+
- Menq (2004)
|
|
34
|
+
- Kishida (2012)
|
|
35
|
+
- Curves:
|
|
36
|
+
- Vucetic & Dobry (1991)
|
|
37
|
+
- EPRI (1993)
|
|
38
|
+
- GEI (1983)
|
|
39
|
+
- GeoMatrix (1990)
|
|
40
|
+
- Idriss (1990)
|
|
41
|
+
- Imperial Valley Soils
|
|
42
|
+
- Iwasaki
|
|
43
|
+
- Peninsular Range
|
|
44
|
+
- Seed & Idriss
|
|
46
45
|
- Site and soil property uncertainty:
|
|
47
46
|
- Toro (1994) Vs correlation model
|
|
48
47
|
- G/Gmax and D uncertainty:
|
|
@@ -78,28 +77,40 @@ directory`_. An interactive Jupyter interface of these examples is available on
|
|
|
78
77
|
|
|
79
78
|
.. _Strata: https://github.com/arkottke/strata
|
|
80
79
|
.. _DOI: https://zenodo.org/badge/latestdoi/8959678
|
|
81
|
-
.. _`examples directory`: https://github.com/arkottke/pystrata/tree/
|
|
80
|
+
.. _`examples directory`: https://github.com/arkottke/pystrata/tree/main/examples
|
|
82
81
|
|
|
83
82
|
.. |PyPi Cheese Shop| image:: https://img.shields.io/pypi/v/pystrata.svg
|
|
84
83
|
:target: https://pypi.python.org/pypi/pystrata
|
|
85
|
-
.. |Build Status| image:: https://img.shields.io/
|
|
86
|
-
:
|
|
84
|
+
.. |Build Status| image:: https://img.shields.io/github/workflow/status/arkottke/pystrata/Python%20application
|
|
85
|
+
:alt: GitHub Workflow Status
|
|
86
|
+
:target: https://github.com/arkottke/pystrata/actions/workflows/python-app.yml
|
|
87
87
|
.. |Documentation Status| image:: https://readthedocs.org/projects/pystrata/badge/?version=latest&style=flat
|
|
88
88
|
:target: https://pystrata.readthedocs.org
|
|
89
|
-
.. |Code Quality| image:: https://
|
|
90
|
-
:target: https://www.codacy.com/
|
|
91
|
-
.. |Test Coverage| image:: https://
|
|
92
|
-
:target: https://www.codacy.com/
|
|
89
|
+
.. |Code Quality| image:: https://app.codacy.com/project/badge/Grade/6dbbb3a4279744d697b9bfe08af19ded
|
|
90
|
+
:target: https://www.codacy.com/gh/arkottke/pystrata/dashboard
|
|
91
|
+
.. |Test Coverage| image:: https://app.codacy.com/project/badge/Coverage/6dbbb3a4279744d697b9bfe08af19ded
|
|
92
|
+
:target: https://www.codacy.com/gh/arkottke/pystrata/dashboard
|
|
93
93
|
.. |License| image:: https://img.shields.io/badge/license-MIT-blue.svg
|
|
94
94
|
.. |Zenodo| image:: https://zenodo.org/badge/8959678.svg
|
|
95
95
|
:target: https://zenodo.org/badge/latestdoi/8959678
|
|
96
96
|
.. |MyBinder| image:: https://mybinder.org/badge_logo.svg
|
|
97
|
-
:target: https://mybinder.org/v2/gh/arkottke/pystrata/
|
|
98
|
-
|
|
97
|
+
:target: https://mybinder.org/v2/gh/arkottke/pystrata/main?filepath=examples
|
|
99
98
|
|
|
100
99
|
History
|
|
101
100
|
=======
|
|
102
101
|
|
|
102
|
+
v0.5.2 (2023-01-18)
|
|
103
|
+
-------------------
|
|
104
|
+
- Fixed: Providing unsmoothed transfer function output
|
|
105
|
+
- Fixed: MenqSoilType
|
|
106
|
+
|
|
107
|
+
v0.5.1 (2022-09-22)
|
|
108
|
+
-------------------
|
|
109
|
+
- Fixed: Correlation model from Toro. Previously used rho_0 instead of d_0, and the
|
|
110
|
+
wrong depth
|
|
111
|
+
- Renamed: BedrockDepthVariation to HalfSpaceDepthVariation
|
|
112
|
+
- Fixed: HalfSpaceDepthVariation was removing the last layer
|
|
113
|
+
|
|
103
114
|
v0.5.0 (2022-06-14)
|
|
104
115
|
-------------------
|
|
105
116
|
- Renamed to `pyStrata`.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
AUTHORS.rst
|
|
2
|
+
HISTORY.rst
|
|
3
|
+
LICENSE
|
|
4
|
+
MANIFEST.in
|
|
5
|
+
README.rst
|
|
6
|
+
requirements.txt
|
|
7
|
+
setup.cfg
|
|
8
|
+
setup.py
|
|
9
|
+
pystrata/__init__.py
|
|
10
|
+
pystrata/motion.py
|
|
11
|
+
pystrata/output.py
|
|
12
|
+
pystrata/propagation.py
|
|
13
|
+
pystrata/site.py
|
|
14
|
+
pystrata/tools.py
|
|
15
|
+
pystrata/variation.py
|
|
16
|
+
pystrata.egg-info/PKG-INFO
|
|
17
|
+
pystrata.egg-info/SOURCES.txt
|
|
18
|
+
pystrata.egg-info/dependency_links.txt
|
|
19
|
+
pystrata.egg-info/top_level.txt
|
|
20
|
+
tests/__init__.py
|
|
21
|
+
tests/motion_test.py
|
|
22
|
+
tests/notebooks_test.py
|
|
23
|
+
tests/output_test.py
|
|
24
|
+
tests/propagation_test.py
|
|
25
|
+
tests/site_test.py
|
|
26
|
+
tests/variation_test.py
|
pystrata-0.5.2/setup.cfg
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
name = pystrata
|
|
3
|
+
version = attr: pystrata.__version__
|
|
4
|
+
description = Site response analysis with Python
|
|
5
|
+
description_file = README.rst
|
|
6
|
+
long_description = file: README.rst, HISTORY.rst
|
|
7
|
+
author = Albert R. Kottke
|
|
8
|
+
author_email = albert.kottke@gmail.com
|
|
9
|
+
license = MIT
|
|
10
|
+
url = https://github.com/arkottke/pystrata
|
|
11
|
+
|
|
12
|
+
[options]
|
|
13
|
+
packages = find:
|
|
14
|
+
|
|
15
|
+
[aliases]
|
|
16
|
+
test = pytest
|
|
17
|
+
|
|
18
|
+
[flake8]
|
|
19
|
+
exclude = docs/
|
|
20
|
+
|
|
21
|
+
[yapf]
|
|
22
|
+
based_on_style = pep8
|
|
23
|
+
spaces_around_power_operator = true
|
|
24
|
+
|
|
25
|
+
[tool:test]
|
|
26
|
+
addopts = --flake8
|
|
27
|
+
|
|
28
|
+
[wheel]
|
|
29
|
+
universal = 1
|
|
30
|
+
|
|
31
|
+
[pydocstyle]
|
|
32
|
+
ignore = D100,D101,D102,D103,D104,W503
|
|
33
|
+
|
|
34
|
+
[egg_info]
|
|
35
|
+
tag_build =
|
|
36
|
+
tag_date = 0
|
|
37
|
+
|
pystrata-0.5.2/setup.py
ADDED
|
File without changes
|
|
@@ -77,7 +77,7 @@ def test_ts_fft_with_tf(tsm):
|
|
|
77
77
|
def test_ts_fa_normalize(tsm):
|
|
78
78
|
"""Test the normalization of the Fourier amplitudes with Parsevla's theorem."""
|
|
79
79
|
assert_allclose(
|
|
80
|
-
trapz(tsm.accels
|
|
80
|
+
trapz(tsm.accels**2, dx=tsm.time_step),
|
|
81
81
|
2 * trapz(np.abs(tsm.fourier_amps) ** 2, tsm.freqs),
|
|
82
82
|
)
|
|
83
83
|
|
|
@@ -38,7 +38,7 @@ def test_notebook(fpath):
|
|
|
38
38
|
with fpath.open() as fp:
|
|
39
39
|
nb = nbformat.read(fp, as_version=4)
|
|
40
40
|
|
|
41
|
-
ep = ExecutePreprocessor(timeout=600)
|
|
41
|
+
ep = ExecutePreprocessor(timeout=600, kernel_name="python3")
|
|
42
42
|
|
|
43
43
|
try:
|
|
44
44
|
ep.preprocess(nb, {"metadata": {"path": fpath.parent}})
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
# encoding: utf-8
|
|
3
|
-
|
|
4
3
|
# This program is free software; you can redistribute it and/or modify
|
|
5
4
|
# it under the terms of the GNU General Public License as published by
|
|
6
5
|
# the Free Software Foundation; either version 2 of the License, or
|
|
@@ -16,10 +15,8 @@
|
|
|
16
15
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
17
16
|
#
|
|
18
17
|
# Copyright (C) Albert Kottke, 2013-2016
|
|
19
|
-
|
|
20
18
|
import numpy as np
|
|
21
19
|
import pytest
|
|
22
|
-
|
|
23
20
|
from numpy.testing import assert_allclose
|
|
24
21
|
|
|
25
22
|
import pystrata
|
|
@@ -294,7 +294,9 @@ class TestExample02LE(DeepSoilComparison):
|
|
|
294
294
|
pystrata.site.SoilType("Soil", 20.0, mod_reduc=None, damping=0), 20, 500
|
|
295
295
|
),
|
|
296
296
|
pystrata.site.Layer(
|
|
297
|
-
pystrata.site.SoilType("Rock", 25.0, mod_reduc=None, damping=0.02),
|
|
297
|
+
pystrata.site.SoilType("Rock", 25.0, mod_reduc=None, damping=0.02),
|
|
298
|
+
0,
|
|
299
|
+
760,
|
|
298
300
|
),
|
|
299
301
|
]
|
|
300
302
|
)
|
|
@@ -310,7 +312,9 @@ class TestExample02EL(DeepSoilComparison):
|
|
|
310
312
|
pystrata.site.SoilType("Soil", 20.0, mod_reduc=None, damping=0), 20, 500
|
|
311
313
|
),
|
|
312
314
|
pystrata.site.Layer(
|
|
313
|
-
pystrata.site.SoilType("Rock", 25.0, mod_reduc=None, damping=0.02),
|
|
315
|
+
pystrata.site.SoilType("Rock", 25.0, mod_reduc=None, damping=0.02),
|
|
316
|
+
0,
|
|
317
|
+
760,
|
|
314
318
|
),
|
|
315
319
|
]
|
|
316
320
|
)
|
|
@@ -322,10 +326,14 @@ class TestExample04EL(DeepSoilComparison):
|
|
|
322
326
|
profile = pystrata.site.Profile(
|
|
323
327
|
[
|
|
324
328
|
pystrata.site.Layer(
|
|
325
|
-
pystrata.site.SoilType("Soil", 20.0, mod_reduc=None, damping=0.05),
|
|
329
|
+
pystrata.site.SoilType("Soil", 20.0, mod_reduc=None, damping=0.05),
|
|
330
|
+
20,
|
|
331
|
+
500,
|
|
326
332
|
),
|
|
327
333
|
pystrata.site.Layer(
|
|
328
|
-
pystrata.site.SoilType("Rock", 25.0, mod_reduc=None, damping=0.02),
|
|
334
|
+
pystrata.site.SoilType("Rock", 25.0, mod_reduc=None, damping=0.02),
|
|
335
|
+
0,
|
|
336
|
+
760,
|
|
329
337
|
),
|
|
330
338
|
]
|
|
331
339
|
)
|
|
@@ -27,6 +27,26 @@ from . import FPATH_DATA
|
|
|
27
27
|
from pystrata import site
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
def test_published_nonlinear_property():
|
|
31
|
+
site.NonlinearProperty.from_published("Vucetic & Dobry (91), PI=0", "damping")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_published_soiltype_same():
|
|
35
|
+
model = "Vucetic & Dobry (91), PI=0"
|
|
36
|
+
|
|
37
|
+
st = site.SoilType.from_published("test", 14, model)
|
|
38
|
+
assert st.mod_reduc.name == model
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_published_soiltype_same():
|
|
42
|
+
model_mr = "Vucetic & Dobry (91), PI=0"
|
|
43
|
+
model_d = "Vucetic & Dobry (91), PI=15"
|
|
44
|
+
|
|
45
|
+
st = site.SoilType.from_published("test", 14, model_mr, model_d)
|
|
46
|
+
assert st.mod_reduc.name == model_mr
|
|
47
|
+
assert st.damping.name == model_d
|
|
48
|
+
|
|
49
|
+
|
|
30
50
|
@pytest.fixture
|
|
31
51
|
def nlp():
|
|
32
52
|
"""Create an example NonlinearProperty."""
|
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
#
|
|
17
17
|
# Copyright (C) Albert Kottke, 2013-2016
|
|
18
18
|
import numpy as np
|
|
19
|
+
import pytest
|
|
19
20
|
from numpy.testing import assert_allclose
|
|
21
|
+
from scipy.stats import lognorm
|
|
22
|
+
from scipy.stats import norm
|
|
20
23
|
from scipy.stats import pearsonr
|
|
21
24
|
|
|
22
25
|
from pystrata import motion
|
|
@@ -144,17 +147,26 @@ class TestSpidVariation:
|
|
|
144
147
|
)
|
|
145
148
|
|
|
146
149
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
profile = site.Profile(
|
|
150
|
+
@pytest.fixture
|
|
151
|
+
def profile():
|
|
152
|
+
"""Simple profile for tests."""
|
|
153
|
+
return site.Profile(
|
|
152
154
|
[
|
|
155
|
+
site.Layer(
|
|
156
|
+
site.DarendeliSoilType(18.0, plas_index=0, ocr=1, stress_mean=200),
|
|
157
|
+
10,
|
|
158
|
+
300,
|
|
159
|
+
),
|
|
153
160
|
site.Layer(
|
|
154
161
|
site.DarendeliSoilType(18.0, plas_index=0, ocr=1, stress_mean=200),
|
|
155
162
|
10,
|
|
156
163
|
400,
|
|
157
164
|
),
|
|
165
|
+
site.Layer(
|
|
166
|
+
site.DarendeliSoilType(18.0, plas_index=0, ocr=1, stress_mean=200),
|
|
167
|
+
10,
|
|
168
|
+
500,
|
|
169
|
+
),
|
|
158
170
|
site.Layer(
|
|
159
171
|
site.DarendeliSoilType(18.0, plas_index=0, ocr=1, stress_mean=200),
|
|
160
172
|
20,
|
|
@@ -164,6 +176,32 @@ def test_iter_variations():
|
|
|
164
176
|
]
|
|
165
177
|
)
|
|
166
178
|
|
|
179
|
+
|
|
180
|
+
@pytest.mark.parametrize("dist", [norm(scale=2, loc=50), lognorm(s=0.2, scale=50)])
|
|
181
|
+
def test_halfspace_depth_variation(dist, profile):
|
|
182
|
+
varier = variation.HalfSpaceDepthVariation(dist)
|
|
183
|
+
count = 500
|
|
184
|
+
|
|
185
|
+
varied = varier(profile)
|
|
186
|
+
# Check the surface and bedrock is the same
|
|
187
|
+
assert profile[0] == varied[0]
|
|
188
|
+
assert profile[-1] == varied[-1]
|
|
189
|
+
|
|
190
|
+
for _ in range(10):
|
|
191
|
+
v = varier(profile)
|
|
192
|
+
assert all(layer.thickness >= 0 for layer in v)
|
|
193
|
+
|
|
194
|
+
# Sample to the half-space from the varied profiles
|
|
195
|
+
depths = [varier(profile)[-1].depth for _ in range(count)]
|
|
196
|
+
|
|
197
|
+
assert_allclose(dist.mean(), np.mean(depths), rtol=0.2)
|
|
198
|
+
assert_allclose(dist.std(), np.std(depths), rtol=0.2)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def test_iter_variations(profile):
|
|
202
|
+
m = motion.SourceTheoryRvtMotion(6.0, 30, "wna")
|
|
203
|
+
m.calc_fourier_amps()
|
|
204
|
+
|
|
167
205
|
calc = propagation.EquivalentLinearCalculator()
|
|
168
206
|
var_thickness = variation.ToroThicknessVariation()
|
|
169
207
|
var_velocity = variation.ToroVelocityVariation.generic_model("USGS C")
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
AUTHORS.rst
|
|
2
|
-
HISTORY.rst
|
|
3
|
-
LICENSE
|
|
4
|
-
MANIFEST.in
|
|
5
|
-
README.rst
|
|
6
|
-
requirements.txt
|
|
7
|
-
setup.cfg
|
|
8
|
-
setup.py
|
|
9
|
-
pyStrata.egg-info/PKG-INFO
|
|
10
|
-
pyStrata.egg-info/SOURCES.txt
|
|
11
|
-
pyStrata.egg-info/dependency_links.txt
|
|
12
|
-
pyStrata.egg-info/requires.txt
|
|
13
|
-
pyStrata.egg-info/top_level.txt
|
|
14
|
-
pystrata/__init__.py
|
|
15
|
-
pystrata/motion.py
|
|
16
|
-
pystrata/output.py
|
|
17
|
-
pystrata/propagation.py
|
|
18
|
-
pystrata/site.py
|
|
19
|
-
pystrata/tools.py
|
|
20
|
-
pystrata/variation.py
|
|
21
|
-
tests/__init__.py
|
|
22
|
-
tests/test_motion.py
|
|
23
|
-
tests/test_notebooks.py
|
|
24
|
-
tests/test_output.py
|
|
25
|
-
tests/test_propagation.py
|
|
26
|
-
tests/test_site.py
|
|
27
|
-
tests/test_variation.py
|
pyStrata-0.5.0/setup.cfg
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
[aliases]
|
|
2
|
-
test = pytest
|
|
3
|
-
|
|
4
|
-
[flake8]
|
|
5
|
-
exclude = docs/
|
|
6
|
-
|
|
7
|
-
[metadata]
|
|
8
|
-
description-file = README.rst
|
|
9
|
-
|
|
10
|
-
[yapf]
|
|
11
|
-
based_on_style = pep8
|
|
12
|
-
spaces_around_power_operator = true
|
|
13
|
-
|
|
14
|
-
[tool:test]
|
|
15
|
-
addopts = --flake8
|
|
16
|
-
|
|
17
|
-
[wheel]
|
|
18
|
-
universal = 1
|
|
19
|
-
|
|
20
|
-
[pydocstyle]
|
|
21
|
-
ignore = D100,D101,D102,D103,D104,W503
|
|
22
|
-
|
|
23
|
-
[egg_info]
|
|
24
|
-
tag_build =
|
|
25
|
-
tag_date = 0
|
|
26
|
-
|
pyStrata-0.5.0/setup.py
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
from setuptools import find_packages
|
|
4
|
-
from setuptools import setup
|
|
5
|
-
|
|
6
|
-
with open("README.rst") as fp:
|
|
7
|
-
readme = fp.read()
|
|
8
|
-
|
|
9
|
-
with open("HISTORY.rst") as fp:
|
|
10
|
-
history = fp.read()
|
|
11
|
-
|
|
12
|
-
setup(
|
|
13
|
-
name="pyStrata",
|
|
14
|
-
version="0.5.0",
|
|
15
|
-
description="Site Response Analysis with Python",
|
|
16
|
-
long_description=readme + "\n\n" + history,
|
|
17
|
-
long_description_content_type='text/x-rst',
|
|
18
|
-
author="Albert Kottke",
|
|
19
|
-
author_email="albert.kottke@gmail.com",
|
|
20
|
-
url="http://github.com/arkottke/pystrata",
|
|
21
|
-
packages=find_packages(),
|
|
22
|
-
install_requires=[
|
|
23
|
-
"matplotlib",
|
|
24
|
-
"numpy",
|
|
25
|
-
"pyrvt",
|
|
26
|
-
"pykooh",
|
|
27
|
-
"scipy",
|
|
28
|
-
"setuptools",
|
|
29
|
-
"typing",
|
|
30
|
-
],
|
|
31
|
-
extras_require={
|
|
32
|
-
"dataframe": ["pandas"],
|
|
33
|
-
},
|
|
34
|
-
keywords="site response",
|
|
35
|
-
license="MIT",
|
|
36
|
-
classifiers=[
|
|
37
|
-
"Development Status :: 4 - Beta",
|
|
38
|
-
"Environment :: Console",
|
|
39
|
-
"License :: OSI Approved :: MIT License",
|
|
40
|
-
"Natural Language :: English",
|
|
41
|
-
"Operating System :: OS Independent",
|
|
42
|
-
"Programming Language :: Python",
|
|
43
|
-
"Programming Language :: Python :: 3.6",
|
|
44
|
-
"Topic :: Scientific/Engineering",
|
|
45
|
-
"Intended Audience :: Science/Research",
|
|
46
|
-
],
|
|
47
|
-
test_suite="tests",
|
|
48
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|