weac 2.3.2__tar.gz → 2.4.1__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.
- {weac-2.3.2 → weac-2.4.1}/CITATION.cff +1 -1
- {weac-2.3.2 → weac-2.4.1}/PKG-INFO +6 -2
- {weac-2.3.2 → weac-2.4.1}/setup.cfg +1 -1
- {weac-2.3.2 → weac-2.4.1}/weac/__init__.py +1 -1
- {weac-2.3.2 → weac-2.4.1}/weac/eigensystem.py +29 -24
- {weac-2.3.2 → weac-2.4.1}/weac/layered.py +5 -4
- {weac-2.3.2 → weac-2.4.1}/weac/mixins.py +113 -75
- {weac-2.3.2 → weac-2.4.1}/weac/plot.py +1 -1
- {weac-2.3.2 → weac-2.4.1}/weac/tools.py +61 -5
- {weac-2.3.2 → weac-2.4.1}/LICENSE +0 -0
- {weac-2.3.2 → weac-2.4.1}/MANIFEST.in +0 -0
- {weac-2.3.2 → weac-2.4.1}/README.md +0 -0
- {weac-2.3.2 → weac-2.4.1}/build/weac.egg-info/SOURCES.txt +0 -0
- {weac-2.3.2 → weac-2.4.1}/img/bc.png +0 -0
- {weac-2.3.2 → weac-2.4.1}/img/layering.png +0 -0
- {weac-2.3.2 → weac-2.4.1}/img/logo.png +0 -0
- {weac-2.3.2 → weac-2.4.1}/img/model.png +0 -0
- {weac-2.3.2 → weac-2.4.1}/img/profiles.png +0 -0
- {weac-2.3.2 → weac-2.4.1}/img/systems.png +0 -0
- {weac-2.3.2 → weac-2.4.1}/pyproject.toml +0 -0
- {weac-2.3.2 → weac-2.4.1}/weac/inverse.py +0 -0
|
@@ -8,7 +8,7 @@ authors:
|
|
|
8
8
|
- family-names: "Weissgraeber"
|
|
9
9
|
given-names: "Philipp"
|
|
10
10
|
orcid: "https://orcid.org/0000-0001-8320-8672"
|
|
11
|
-
version: 2.
|
|
11
|
+
version: 2.4.1
|
|
12
12
|
date-released: 2021-12-30
|
|
13
13
|
identifiers:
|
|
14
14
|
- description: Collection of archived snapshots of all versions of WEAC
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: weac
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.1
|
|
4
4
|
Summary: Weak layer anticrack nucleation model
|
|
5
5
|
Home-page: https://github.com/2phi/weac
|
|
6
6
|
Author: 2phi GbR
|
|
@@ -15,8 +15,12 @@ Classifier: Operating System :: OS Independent
|
|
|
15
15
|
Classifier: Topic :: Scientific/Engineering
|
|
16
16
|
Requires-Python: >=3.10
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
|
-
Provides-Extra: interactive
|
|
19
18
|
License-File: LICENSE
|
|
19
|
+
Requires-Dist: matplotlib
|
|
20
|
+
Requires-Dist: numpy
|
|
21
|
+
Requires-Dist: scipy
|
|
22
|
+
Provides-Extra: interactive
|
|
23
|
+
Requires-Dist: jupyter; extra == "interactive"
|
|
20
24
|
|
|
21
25
|
<!-- LOGO AND TITLE-->
|
|
22
26
|
<!-- <p align="right"><img src="https://github.com/2phi/weac/raw/main/img/logo.png" alt="Logo" width="80" height="80"></p> -->
|
|
@@ -96,11 +96,12 @@ class Eigensystem:
|
|
|
96
96
|
|
|
97
97
|
Arguments
|
|
98
98
|
---------
|
|
99
|
-
system : {'pst-', '-pst', 'skier', 'skiers'}, optional
|
|
99
|
+
system : {'pst-', '-pst', 'vpst-', '-vpst', 'skier', 'skiers'}, optional
|
|
100
100
|
Type of system to analyse: PST cut from the right (pst-),
|
|
101
|
-
PST cut form the left (-pst),
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
PST cut form the left (-pst), PST with vertical faces cut
|
|
102
|
+
from the right (vpst-), PST with vertical faces cut from the
|
|
103
|
+
left (-vpst), one skier on infinite slab (skier) or multiple
|
|
104
|
+
skiers on infinite slab (skiers). Default is 'pst-'.
|
|
104
105
|
layers : list, optional
|
|
105
106
|
2D list of layer densities and thicknesses. Columns are
|
|
106
107
|
density (kg/m^3) and thickness (mm). One row corresponds
|
|
@@ -110,7 +111,7 @@ class Eigensystem:
|
|
|
110
111
|
self.g = 9810 # Gravitaiton (mm/s^2)
|
|
111
112
|
self.lski = 1000 # Effective out-of-plane length of skis (mm)
|
|
112
113
|
self.tol = 1e-3 # Relative Romberg integration tolerance
|
|
113
|
-
self.system = system # 'pst-', '-pst', 'skier', 'skiers'
|
|
114
|
+
self.system = system # 'pst-', '-pst', 'vpst-', '-vpst', 'skier', 'skiers'
|
|
114
115
|
|
|
115
116
|
# Initialize weak-layer attributes that will be filled later
|
|
116
117
|
self.weak = False # Weak-layer properties dictionary
|
|
@@ -141,9 +142,9 @@ class Eigensystem:
|
|
|
141
142
|
self.sR = False # Stability shift of real eigenvalues
|
|
142
143
|
|
|
143
144
|
# Initialize touchdown attributes
|
|
145
|
+
self.touchdown = False # Flag whether touchdown is possible
|
|
144
146
|
self.lC = False # Minimum length of substratum contact (mm)
|
|
145
|
-
self.lS = False # Maximum
|
|
146
|
-
# between bedded and touchdowned boundary (mm)
|
|
147
|
+
self.lS = False # Maximum span between bedded and touchdown (mm)
|
|
147
148
|
self.ratio = False # Stiffness ratio of collalpsed to uncollapsed weak-layer
|
|
148
149
|
self.beta = False # Ratio of slab to bedding stiffness
|
|
149
150
|
|
|
@@ -221,7 +222,7 @@ class Eigensystem:
|
|
|
221
222
|
|
|
222
223
|
# Compute total slab thickness and center of gravity
|
|
223
224
|
self.h, self.zs = calc_center_of_gravity(layers)
|
|
224
|
-
|
|
225
|
+
|
|
225
226
|
# Assemble layering into matrix (top to bottom)
|
|
226
227
|
# Columns are density (kg/m^3), layer thickness (mm)
|
|
227
228
|
# Young's modulus (MPa), shear modulus (MPa), and
|
|
@@ -509,15 +510,19 @@ class Eigensystem:
|
|
|
509
510
|
First coefficient for sixth order term,
|
|
510
511
|
second coefficient for fith order term and so on.
|
|
511
512
|
"""
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
513
|
+
kA55 = self.kA55
|
|
514
|
+
D11 = self.D11
|
|
515
|
+
tc = self.tc
|
|
516
|
+
|
|
517
|
+
a1 = kA55**2*kR1*kN1*q0
|
|
518
|
+
a2 = 6*kA55*(D11*kA55 + kR1*kR2)*kN1*q0
|
|
519
|
+
a3 = 30*D11*kA55*(kR1 + kR2)*kN1*q0
|
|
520
|
+
a4 = 24*D11*(2*kA55**2*kR1 + 3*D11*kA55*kN1 + 3*kR1*kR2*kN1)*q0
|
|
521
|
+
a5 = 72*D11*(D11*(kA55**2 + (kR1 + kR2)*kN1)*q0 \
|
|
522
|
+
+ kA55*kR1*(2*kR2*q0 - kA55*kN1*tc))
|
|
523
|
+
a6 = 144*D11*kA55*(D11*(kR1 + kR2)*q0 \
|
|
524
|
+
- (D11*kA55 + kR1*kR2)*kN1*tc)
|
|
525
|
+
a7 = - 144*D11**2*kA55*(kR1 + kR2)*kN1*tc
|
|
521
526
|
return [a1,a2,a3,a4,a5,a6,a7]
|
|
522
527
|
|
|
523
528
|
# Get spring stiffnesses for adjacent segment with intact weak-layer
|
|
@@ -692,7 +697,7 @@ class Eigensystem:
|
|
|
692
697
|
A11 = self.A11
|
|
693
698
|
B11 = self.B11
|
|
694
699
|
kA55 = self.kA55
|
|
695
|
-
|
|
700
|
+
K0 = self.K0
|
|
696
701
|
|
|
697
702
|
# Unpack geometric properties
|
|
698
703
|
h = self.h
|
|
@@ -711,13 +716,13 @@ class Eigensystem:
|
|
|
711
716
|
[0]])
|
|
712
717
|
else:
|
|
713
718
|
zp = np.array([
|
|
714
|
-
[(-3*(qt + pt)/A11 - B11*(qn + pn)*x/
|
|
715
|
-
[(-2*(qt + pt)/A11 - B11*(qn + pn)*x/
|
|
716
|
-
[-A11*(qn + pn)*x**4/(24*
|
|
717
|
-
[-A11*(qn + pn)*x**3/(6*
|
|
718
|
-
[A11*(qn + pn)*x**3/(6*
|
|
719
|
+
[(-3*(qt + pt)/A11 - B11*(qn + pn)*x/K0)/6*x**2],
|
|
720
|
+
[(-2*(qt + pt)/A11 - B11*(qn + pn)*x/K0)/2*x],
|
|
721
|
+
[-A11*(qn + pn)*x**4/(24*K0)],
|
|
722
|
+
[-A11*(qn + pn)*x**3/(6*K0)],
|
|
723
|
+
[A11*(qn + pn)*x**3/(6*K0)
|
|
719
724
|
+ ((zs - B11/A11)*qt - h*pt/2 - (qn + pn)*x)/kA55],
|
|
720
|
-
[(qn + pn)*(A11*x**2/(2*
|
|
725
|
+
[(qn + pn)*(A11*x**2/(2*K0) - 1/kA55)]])
|
|
721
726
|
|
|
722
727
|
return zp
|
|
723
728
|
|
|
@@ -26,11 +26,12 @@ class Layered(FieldQuantitiesMixin, SolutionMixin, AnalysisMixin,
|
|
|
26
26
|
|
|
27
27
|
Arguments
|
|
28
28
|
---------
|
|
29
|
-
system : {'pst-', '-pst', 'skier', 'skiers'}, optional
|
|
29
|
+
system : {'pst-', '-pst', 'vpst-', '-vpst', 'skier', 'skiers'}, optional
|
|
30
30
|
Type of system to analyse: PST cut from the right (pst-),
|
|
31
|
-
PST cut form the left (-pst),
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
PST cut form the left (-pst), PST with vertical faces cut
|
|
32
|
+
from the right (vpst-), PST with vertical faces cut from the
|
|
33
|
+
left (-vpst), one skier on infinite slab (skier) or multiple
|
|
34
|
+
skiers on infinite slab (skiers). Default is 'pst-'.
|
|
34
35
|
layers : list, optional
|
|
35
36
|
2D list of layer densities and thicknesses. Columns are
|
|
36
37
|
density(kg/m ^ 3) and thickness(mm). One row corresponds
|
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
# Standard library imports
|
|
5
5
|
from functools import partial
|
|
6
6
|
|
|
7
|
-
|
|
8
7
|
# Third party imports
|
|
9
8
|
import numpy as np
|
|
10
9
|
from scipy.integrate import romberg, cumulative_trapezoid
|
|
11
10
|
|
|
12
11
|
# Module imports
|
|
13
|
-
from weac.tools import tensile_strength_slab
|
|
12
|
+
from weac.tools import tensile_strength_slab, calc_vertical_bc_center_of_gravity
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
class FieldQuantitiesMixin:
|
|
@@ -510,15 +509,16 @@ class SolutionMixin:
|
|
|
510
509
|
A - free end, B - intermediate touchdown,
|
|
511
510
|
C - full touchdown (maximum clamped end).
|
|
512
511
|
"""
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
512
|
+
if self.touchdown:
|
|
513
|
+
# Classify boundary type by element length
|
|
514
|
+
if l <= self.lC:
|
|
515
|
+
return 'A'
|
|
516
|
+
elif self.lC < l <= self.lS:
|
|
517
|
+
return 'B'
|
|
518
|
+
elif self.lS < l:
|
|
519
|
+
return 'C'
|
|
520
|
+
else:
|
|
521
|
+
return 'A'
|
|
522
522
|
|
|
523
523
|
def reduce_stiffness(self, l=0, mode='A'):
|
|
524
524
|
"""
|
|
@@ -586,28 +586,39 @@ class SolutionMixin:
|
|
|
586
586
|
if not k:
|
|
587
587
|
if mode in ['A']:
|
|
588
588
|
# Free end
|
|
589
|
-
bc = np.array([
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
589
|
+
bc = np.array([
|
|
590
|
+
self.N(z),
|
|
591
|
+
self.M(z),
|
|
592
|
+
self.V(z)
|
|
593
|
+
])
|
|
593
594
|
elif mode in ['B', 'C'] and pos in ['r', 'right']:
|
|
594
595
|
# Touchdown right
|
|
595
|
-
bc = np.array([
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
596
|
+
bc = np.array([
|
|
597
|
+
self.N(z),
|
|
598
|
+
self.M(z) + kf*kR*self.psi(z),
|
|
599
|
+
self.w(z)
|
|
600
|
+
])
|
|
599
601
|
elif mode in ['B', 'C'] and pos in ['l', 'left']:
|
|
600
602
|
# Touchdown left
|
|
601
|
-
bc = np.array([
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
603
|
+
bc = np.array([
|
|
604
|
+
self.N(z),
|
|
605
|
+
self.M(z) - kf*kR*self.psi(z),
|
|
606
|
+
self.w(z)
|
|
607
|
+
])
|
|
605
608
|
else:
|
|
606
609
|
# Free end
|
|
607
|
-
bc = np.array([
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
610
|
+
bc = np.array([
|
|
611
|
+
self.N(z),
|
|
612
|
+
self.M(z),
|
|
613
|
+
self.V(z)
|
|
614
|
+
])
|
|
615
|
+
# Set boundary conditions for PST-systems with vertical faces
|
|
616
|
+
elif self.system in ['-vpst', 'vpst-']:
|
|
617
|
+
bc = np.array([
|
|
618
|
+
self.N(z),
|
|
619
|
+
self.M(z),
|
|
620
|
+
self.V(z)
|
|
621
|
+
])
|
|
611
622
|
# Set boundary conditions for SKIER-systems
|
|
612
623
|
elif self.system in ['skier', 'skiers']:
|
|
613
624
|
# Infinite end (vanishing complementary solution)
|
|
@@ -653,40 +664,40 @@ class SolutionMixin:
|
|
|
653
664
|
"""
|
|
654
665
|
if pos in ('l', 'left'):
|
|
655
666
|
eqs = np.array([
|
|
656
|
-
self.bc(zl, l, k, pos)[0],
|
|
657
|
-
self.bc(zl, l, k, pos)[1],
|
|
658
|
-
self.bc(zl, l, k, pos)[2],
|
|
659
|
-
self.u(zr, z0=0),
|
|
660
|
-
self.w(zr),
|
|
661
|
-
self.psi(zr),
|
|
662
|
-
self.N(zr),
|
|
663
|
-
self.M(zr),
|
|
664
|
-
self.V(zr)])
|
|
667
|
+
self.bc(zl, l, k, pos)[0], # Left boundary condition
|
|
668
|
+
self.bc(zl, l, k, pos)[1], # Left boundary condition
|
|
669
|
+
self.bc(zl, l, k, pos)[2], # Left boundary condition
|
|
670
|
+
self.u(zr, z0=0), # ui(xi = li)
|
|
671
|
+
self.w(zr), # wi(xi = li)
|
|
672
|
+
self.psi(zr), # psii(xi = li)
|
|
673
|
+
self.N(zr), # Ni(xi = li)
|
|
674
|
+
self.M(zr), # Mi(xi = li)
|
|
675
|
+
self.V(zr)]) # Vi(xi = li)
|
|
665
676
|
elif pos in ('m', 'mid'):
|
|
666
677
|
eqs = np.array([
|
|
667
|
-
-self.u(zl, z0=0),
|
|
668
|
-
-self.w(zl),
|
|
669
|
-
-self.psi(zl),
|
|
670
|
-
-self.N(zl),
|
|
671
|
-
-self.M(zl),
|
|
672
|
-
-self.V(zl),
|
|
673
|
-
self.u(zr, z0=0),
|
|
674
|
-
self.w(zr),
|
|
675
|
-
self.psi(zr),
|
|
676
|
-
self.N(zr),
|
|
677
|
-
self.M(zr),
|
|
678
|
-
self.V(zr)])
|
|
678
|
+
-self.u(zl, z0=0), # -ui(xi = 0)
|
|
679
|
+
-self.w(zl), # -wi(xi = 0)
|
|
680
|
+
-self.psi(zl), # -psii(xi = 0)
|
|
681
|
+
-self.N(zl), # -Ni(xi = 0)
|
|
682
|
+
-self.M(zl), # -Mi(xi = 0)
|
|
683
|
+
-self.V(zl), # -Vi(xi = 0)
|
|
684
|
+
self.u(zr, z0=0), # ui(xi = li)
|
|
685
|
+
self.w(zr), # wi(xi = li)
|
|
686
|
+
self.psi(zr), # psii(xi = li)
|
|
687
|
+
self.N(zr), # Ni(xi = li)
|
|
688
|
+
self.M(zr), # Mi(xi = li)
|
|
689
|
+
self.V(zr)]) # Vi(xi = li)
|
|
679
690
|
elif pos in ('r', 'right'):
|
|
680
691
|
eqs = np.array([
|
|
681
|
-
-self.u(zl, z0=0),
|
|
682
|
-
-self.w(zl),
|
|
683
|
-
-self.psi(zl),
|
|
684
|
-
-self.N(zl),
|
|
685
|
-
-self.M(zl),
|
|
686
|
-
-self.V(zl),
|
|
687
|
-
self.bc(zr, l, k, pos)[0],
|
|
688
|
-
self.bc(zr, l, k, pos)[1],
|
|
689
|
-
self.bc(zr, l, k, pos)[2]])
|
|
692
|
+
-self.u(zl, z0=0), # -ui(xi = 0)
|
|
693
|
+
-self.w(zl), # -wi(xi = 0)
|
|
694
|
+
-self.psi(zl), # -psii(xi = 0)
|
|
695
|
+
-self.N(zl), # -Ni(xi = 0)
|
|
696
|
+
-self.M(zl), # -Mi(xi = 0)
|
|
697
|
+
-self.V(zl), # -Vi(xi = 0)
|
|
698
|
+
self.bc(zr, l, k, pos)[0], # Right boundary condition
|
|
699
|
+
self.bc(zr, l, k, pos)[1], # Right boundary condition
|
|
700
|
+
self.bc(zr, l, k, pos)[2]]) # Right boundary condition
|
|
690
701
|
else:
|
|
691
702
|
raise ValueError(
|
|
692
703
|
(f'Invalid position argument {pos} given. '
|
|
@@ -719,10 +730,10 @@ class SolutionMixin:
|
|
|
719
730
|
Used for system 'skiers'.
|
|
720
731
|
L : float, optional
|
|
721
732
|
Total length of model (mm). Used for systems 'pst-', '-pst',
|
|
722
|
-
and 'skier'.
|
|
733
|
+
'vpst-', '-vpst', and 'skier'.
|
|
723
734
|
a : float, optional
|
|
724
|
-
Crack length (mm).
|
|
725
|
-
'skier'.
|
|
735
|
+
Crack length (mm). Used for systems 'pst-', '-pst', 'pst-',
|
|
736
|
+
'-pst', and 'skier'.
|
|
726
737
|
phi : float, optional
|
|
727
738
|
Inclination (degree).
|
|
728
739
|
m : float, optional
|
|
@@ -752,12 +763,22 @@ class SolutionMixin:
|
|
|
752
763
|
ki = np.array(ki) # Crack
|
|
753
764
|
k0 = np.array(k0) # No crack
|
|
754
765
|
elif self.system == 'pst-':
|
|
755
|
-
li = np.array([L - a, lU])
|
|
766
|
+
li = np.array([L - a, lU]) # Segment lengths
|
|
756
767
|
mi = np.array([0]) # Skier weights
|
|
757
768
|
ki = np.array([True, False]) # Crack
|
|
758
769
|
k0 = np.array([True, True]) # No crack
|
|
759
770
|
elif self.system == '-pst':
|
|
760
|
-
li = np.array([lU, L - a])
|
|
771
|
+
li = np.array([lU, L - a]) # Segment lengths
|
|
772
|
+
mi = np.array([0]) # Skier weights
|
|
773
|
+
ki = np.array([False, True]) # Crack
|
|
774
|
+
k0 = np.array([True, True]) # No crack
|
|
775
|
+
elif self.system == 'vpst-':
|
|
776
|
+
li = np.array([L - a, a]) # Segment lengths
|
|
777
|
+
mi = np.array([0]) # Skier weights
|
|
778
|
+
ki = np.array([True, False]) # Crack
|
|
779
|
+
k0 = np.array([True, True]) # No crack
|
|
780
|
+
elif self.system == '-vpst':
|
|
781
|
+
li = np.array([a, L - a]) # Segment lengths
|
|
761
782
|
mi = np.array([0]) # Skier weights
|
|
762
783
|
ki = np.array([False, True]) # Crack
|
|
763
784
|
k0 = np.array([True, True]) # No crack
|
|
@@ -820,7 +841,7 @@ class SolutionMixin:
|
|
|
820
841
|
raise ValueError('Make sure len(li)=N, len(ki)=N, and '
|
|
821
842
|
'len(mi)=N-1 for a system of N segments.')
|
|
822
843
|
|
|
823
|
-
if self.system not in ['pst-', '-pst']:
|
|
844
|
+
if self.system not in ['pst-', '-pst', 'vpst-', '-vpst']:
|
|
824
845
|
# Boundary segments must be on foundation for infinite BCs
|
|
825
846
|
if not all([ki[0], ki[-1]]):
|
|
826
847
|
raise ValueError('Provide supported boundary segments in '
|
|
@@ -885,17 +906,34 @@ class SolutionMixin:
|
|
|
885
906
|
if self.system not in ['pst-', '-pst']:
|
|
886
907
|
rhs[:3] = self.bc(self.zp(x=0, phi=phi, bed=ki[0]))
|
|
887
908
|
rhs[-3:] = self.bc(self.zp(x=li[-1], phi=phi, bed=ki[-1]))
|
|
888
|
-
|
|
889
|
-
#
|
|
890
|
-
|
|
891
|
-
#
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
909
|
+
|
|
910
|
+
# Set rhs for vertical faces
|
|
911
|
+
if self.system in ['vpst-', '-vpst']:
|
|
912
|
+
# Calculate center of gravity and mass of
|
|
913
|
+
# added or cut off slab segement
|
|
914
|
+
xs, zs, m = calc_vertical_bc_center_of_gravity(self.slab, phi)
|
|
915
|
+
# Convert slope angle to radians
|
|
916
|
+
phi = np.deg2rad(phi)
|
|
917
|
+
# Translate inbto section forces and moments
|
|
918
|
+
N = -self.g*m*np.sin(phi)
|
|
919
|
+
M = -self.g*m*(xs*np.cos(phi) + zs*np.sin(phi))
|
|
920
|
+
V = self.g*m*np.cos(phi)
|
|
921
|
+
# Add to right-hand side
|
|
922
|
+
rhs[:3] = np.vstack([N, M, V]) # left end
|
|
923
|
+
rhs[-3:] = np.vstack([N, M, V]) # right end
|
|
924
|
+
|
|
925
|
+
# Set touchdown boundary conditions
|
|
926
|
+
elif self.system in ['pst-', '-pst']:
|
|
927
|
+
# Loop through segments to set touchdown at rhs
|
|
928
|
+
for i in range(nS):
|
|
929
|
+
# Length, foundation and position of segment i
|
|
930
|
+
l, k, pos = li[i], ki[i], pi[i]
|
|
931
|
+
mode = self.mode_td(l=l)
|
|
932
|
+
if not k and bool(mode in ['B', 'C']):
|
|
933
|
+
if i==0:
|
|
934
|
+
rhs[:3] = np.vstack([0,0,self.tc])
|
|
935
|
+
if i == (nS - 1):
|
|
936
|
+
rhs[-3:] = np.vstack([0,0,self.tc])
|
|
899
937
|
|
|
900
938
|
# --- SOLVE -----------------------------------------------------------
|
|
901
939
|
|
|
@@ -1091,7 +1129,7 @@ class AnalysisMixin:
|
|
|
1091
1129
|
# Solution at crack tip
|
|
1092
1130
|
z = self.z(li[idx], C[:, [idx]], li[idx], phi, bed=ki[idx])
|
|
1093
1131
|
# Mode I and II differential energy release rates
|
|
1094
|
-
Gdif[1:, j] = self.Gi(z, unit=unit), self.Gii(z, unit=unit)
|
|
1132
|
+
Gdif[1:, j] = np.concatenate((self.Gi(z, unit=unit), self.Gii(z, unit=unit)))
|
|
1095
1133
|
|
|
1096
1134
|
# Sum mode I and II contributions
|
|
1097
1135
|
Gdif[0, :] = Gdif[1, :] + Gdif[2, :]
|
|
@@ -349,7 +349,7 @@ def deformed(instance, xsl, xwl, z, phi, dz=2, scale=100,
|
|
|
349
349
|
'k', linewidth=1)
|
|
350
350
|
|
|
351
351
|
# Plot deformed weak-layer outline
|
|
352
|
-
if instance.system in ['-pst', 'pst-']:
|
|
352
|
+
if instance.system in ['-pst', 'pst-', '-vpst', 'vpst-']:
|
|
353
353
|
nanmask = np.isfinite(xwl)
|
|
354
354
|
plt.plot(outline(Xwl[:, nanmask] + scale*Uwl[:, nanmask]),
|
|
355
355
|
outline(Zwl[:, nanmask] + scale*Wwl[:, nanmask]),
|
|
@@ -49,6 +49,7 @@ def load_dummy_profile(profile_id):
|
|
|
49
49
|
'e': [hard, soft, soft],
|
|
50
50
|
'f': [soft, soft, hard],
|
|
51
51
|
# Homogeneous
|
|
52
|
+
'h': [medium, medium, medium],
|
|
52
53
|
'soft': [soft, soft, soft],
|
|
53
54
|
'medium': [medium, medium, medium],
|
|
54
55
|
'hard': [hard, hard, hard],
|
|
@@ -75,7 +76,7 @@ def calc_center_of_gravity(layers):
|
|
|
75
76
|
|
|
76
77
|
Arguments
|
|
77
78
|
---------
|
|
78
|
-
layers :
|
|
79
|
+
layers : ndarray
|
|
79
80
|
2D list of layer densities and thicknesses. Columns are
|
|
80
81
|
density (kg/m^3) and thickness (mm). One row corresponds
|
|
81
82
|
to one layer.
|
|
@@ -88,10 +89,10 @@ def calc_center_of_gravity(layers):
|
|
|
88
89
|
Z-coordinate of center of gravity (mm).
|
|
89
90
|
"""
|
|
90
91
|
# Layering info for center of gravity calculation (bottom to top)
|
|
91
|
-
n = layers.shape[0]
|
|
92
|
-
rho = np.flipud(layers[:, 0])
|
|
93
|
-
h = np.flipud(layers[:, 1])
|
|
94
|
-
H = sum(h)
|
|
92
|
+
n = layers.shape[0] # Number of layers
|
|
93
|
+
rho = 1e-12*np.flipud(layers[:, 0]) # Layer densities (kg/m^3 -> t/mm^3)
|
|
94
|
+
h = np.flipud(layers[:, 1]) # Layer thicknesses
|
|
95
|
+
H = sum(h) # Total slab thickness
|
|
95
96
|
# Layer center coordinates (bottom to top)
|
|
96
97
|
zi = [H/2 - sum(h[0:j]) - h[j]/2 for j in range(n)]
|
|
97
98
|
# Z-coordinate of the center of gravity
|
|
@@ -100,6 +101,61 @@ def calc_center_of_gravity(layers):
|
|
|
100
101
|
return H, zs
|
|
101
102
|
|
|
102
103
|
|
|
104
|
+
def calc_vertical_bc_center_of_gravity(slab, phi):
|
|
105
|
+
"""
|
|
106
|
+
Calculate center of gravity of triangular slab segements for vertical PSTs.
|
|
107
|
+
|
|
108
|
+
Parameters
|
|
109
|
+
----------
|
|
110
|
+
slab : ndarray
|
|
111
|
+
List of layer densities, thicknesses, and elastic properties.
|
|
112
|
+
Columns are density (kg/m^3), thickness (mm), Young's modulus
|
|
113
|
+
(MPa), shear modulus (MPa), and Poisson's ratio. One row corresponds
|
|
114
|
+
to one layer.
|
|
115
|
+
phi : fload
|
|
116
|
+
Slope angle (deg).
|
|
117
|
+
|
|
118
|
+
Returns
|
|
119
|
+
-------
|
|
120
|
+
xs : float
|
|
121
|
+
Horizontal coordinate of center of gravity (mm).
|
|
122
|
+
zs : float
|
|
123
|
+
Vertical coordinate of center of gravity (mm).
|
|
124
|
+
w : ndarray
|
|
125
|
+
Weight of the slab segment that is cut off or added (t).
|
|
126
|
+
"""
|
|
127
|
+
# Convert slope angle to radians
|
|
128
|
+
phi = np.deg2rad(phi)
|
|
129
|
+
|
|
130
|
+
# Catch flat-field case
|
|
131
|
+
if phi == 0:
|
|
132
|
+
xs = 0
|
|
133
|
+
zs = 0
|
|
134
|
+
w = 0
|
|
135
|
+
else:
|
|
136
|
+
# Layering info for center of gravity calculation (top to bottom)
|
|
137
|
+
n = slab.shape[0] # Number of slab
|
|
138
|
+
rho = 1e-12*slab[:, 0] # Layer densities (kg/m^3 -> t/mm^3)
|
|
139
|
+
hi = slab[:, 1] # Layer thicknesses
|
|
140
|
+
H = sum(hi) # Total slab thickness
|
|
141
|
+
# Layer coordinates z_i (top to bottom)
|
|
142
|
+
z = np.array([-H/2 + sum(hi[0:j]) for j in range(n + 1)])
|
|
143
|
+
zi = z[:-1] # z_i
|
|
144
|
+
zii = z[1:] # z_{i+1}
|
|
145
|
+
# Center of gravity of all layers (top to bottom)
|
|
146
|
+
zsi = zi + hi/3*(3/2*H - zi - 2*zii)/(H - zi - zii)
|
|
147
|
+
# Surface area of all layers (top to bottom)
|
|
148
|
+
Ai = hi/2*(H - zi - zii)*np.tan(phi)
|
|
149
|
+
# Center of gravity in vertical direction
|
|
150
|
+
zs = sum(zsi*rho*Ai)/sum(rho*Ai)
|
|
151
|
+
# Center of gravity in horizontal direction
|
|
152
|
+
xs = (H/2 - zs)*np.tan(phi/2)
|
|
153
|
+
# Weight of added or cut off slab segments (t)
|
|
154
|
+
w = sum(Ai*rho)
|
|
155
|
+
|
|
156
|
+
# Return center of gravity and weight of slab segment
|
|
157
|
+
return xs, zs, w
|
|
158
|
+
|
|
103
159
|
def scapozza(rho):
|
|
104
160
|
"""
|
|
105
161
|
Compute Young's modulus (MPa) from density (kg/m^3).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|