ebbef2p-python 0.0.2.dev1__py3-none-any.whl → 1.0.0__py3-none-any.whl
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.
- ebbef2p/__init__.py +24 -2
- ebbef2p/elements.py +117 -0
- ebbef2p/exceptions.py +23 -0
- ebbef2p/mesh.py +116 -0
- ebbef2p/model.py +189 -0
- ebbef2p/plotting.py +36 -0
- ebbef2p/results.py +215 -0
- ebbef2p/solver.py +130 -0
- ebbef2p/vlasov.py +177 -0
- ebbef2p_python-1.0.0.dist-info/METADATA +126 -0
- ebbef2p_python-1.0.0.dist-info/RECORD +14 -0
- {ebbef2p_python-0.0.2.dev1.dist-info → ebbef2p_python-1.0.0.dist-info}/WHEEL +1 -2
- {ebbef2p_python-0.0.2.dev1.dist-info → ebbef2p_python-1.0.0.dist-info/licenses}/LICENSE +1 -1
- ebbef2p/beam.py +0 -36
- ebbef2p/distributed_load.py +0 -16
- ebbef2p/elastic_foundation_support.py +0 -33
- ebbef2p/element.py +0 -76
- ebbef2p/helpers.py +0 -15
- ebbef2p/nodal_load.py +0 -5
- ebbef2p/nodal_support.py +0 -7
- ebbef2p/soil_conditions.py +0 -33
- ebbef2p/structure.py +0 -394
- ebbef2p/vlasov_foundation_parameters.py +0 -46
- ebbef2p_python-0.0.2.dev1.dist-info/METADATA +0 -40
- ebbef2p_python-0.0.2.dev1.dist-info/RECORD +0 -19
- ebbef2p_python-0.0.2.dev1.dist-info/top_level.txt +0 -2
- tests/test_beam.py +0 -13
- tests/test_structure.py +0 -25
- /tests/__init__.py → /ebbef2p/py.typed +0 -0
ebbef2p/beam.py
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#import json
|
|
2
|
-
class Beam():
|
|
3
|
-
"""A Beam defines a structure member.
|
|
4
|
-
|
|
5
|
-
A beam is a slender member that is subjected only to transverse loadings.
|
|
6
|
-
It is assumed to have homogeneous properties (e.g. E), with a constant
|
|
7
|
-
cross-section.
|
|
8
|
-
|
|
9
|
-
Parameters
|
|
10
|
-
----------
|
|
11
|
-
coord : :obj:`list` of :obj:`float`
|
|
12
|
-
List containing start and end coordinates of structural beam.
|
|
13
|
-
E : float
|
|
14
|
-
Young's modulus of the beam cross-section.
|
|
15
|
-
I : float
|
|
16
|
-
Area moment of inertia of the beam cross-section.
|
|
17
|
-
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def __init__(self, coord, E, I):
|
|
22
|
-
"""Constructor method"""
|
|
23
|
-
|
|
24
|
-
self.coord = coord
|
|
25
|
-
self.E = E
|
|
26
|
-
self.I = I
|
|
27
|
-
|
|
28
|
-
@property
|
|
29
|
-
def length(self):
|
|
30
|
-
""":float Returns the length between beam end nodes."""
|
|
31
|
-
return self.coord[1] - self.coord[0]
|
|
32
|
-
|
|
33
|
-
def __str__(self):
|
|
34
|
-
return f"Coords: {self.coord} \nYoung's modulus: {self.E} \nMoment of inertia: {self.I} \nLength: {self.length}"
|
|
35
|
-
# def __repr__(self):
|
|
36
|
-
# return json.dumps(self.__dict__)
|
ebbef2p/distributed_load.py
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
class DistributedLoad():
|
|
2
|
-
"""
|
|
3
|
-
*value* : list
|
|
4
|
-
[x_start, x_end]
|
|
5
|
-
|
|
6
|
-
*position* : list
|
|
7
|
-
[x_start, x_end]
|
|
8
|
-
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
def __init__(self, value, position):
|
|
12
|
-
self.value = value
|
|
13
|
-
self.position = position
|
|
14
|
-
|
|
15
|
-
def __str__(self):
|
|
16
|
-
return f"value: {self.value} \nposition: {self.position}"
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
class ElasticFoundationSupport():
|
|
2
|
-
|
|
3
|
-
""" Sc class
|
|
4
|
-
|
|
5
|
-
Attributes:
|
|
6
|
-
value (list): Float values
|
|
7
|
-
position (list):
|
|
8
|
-
type (str): 'k' and 't'
|
|
9
|
-
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
def __init__(self, value, position, type):
|
|
13
|
-
"""Inits the ElasticFoundationSupport class.
|
|
14
|
-
|
|
15
|
-
value (list):
|
|
16
|
-
position (list):
|
|
17
|
-
type (str):
|
|
18
|
-
|
|
19
|
-
"""
|
|
20
|
-
self.value = value
|
|
21
|
-
self.position = position
|
|
22
|
-
self.type = type
|
|
23
|
-
|
|
24
|
-
def __str__(self):
|
|
25
|
-
return f"Value: {self.value} \nPosition: {self.position} \nType: {self.type}"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# def __init__(self, k, t):
|
|
29
|
-
# self.k = k
|
|
30
|
-
# self.t = t
|
|
31
|
-
|
|
32
|
-
# def __str__(self):
|
|
33
|
-
# return f"k: {self.k} \nt: {self.t}"
|
ebbef2p/element.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
from .beam import Beam
|
|
2
|
-
import numpy as np
|
|
3
|
-
|
|
4
|
-
class BeamElement(Beam):
|
|
5
|
-
def __init__(self, coord, E, I, k, t):
|
|
6
|
-
Beam.__init__(self, coord, E, I)
|
|
7
|
-
# self.coord = coord
|
|
8
|
-
#self.E = E
|
|
9
|
-
#self.I = I
|
|
10
|
-
self.k = k
|
|
11
|
-
self.t = t
|
|
12
|
-
self.ke = self.flexural_stiffness()
|
|
13
|
-
self.k1 = self.first_parameter_foundation_stiffness()
|
|
14
|
-
self.k2 = self.second_parameter_foundation_stiffness()
|
|
15
|
-
self.stiffness = self.stiffness()
|
|
16
|
-
#self.forces = self.forces()
|
|
17
|
-
# def __init__(self):
|
|
18
|
-
#self.coord = coord
|
|
19
|
-
# @property
|
|
20
|
-
# def length(self):
|
|
21
|
-
# return self
|
|
22
|
-
|
|
23
|
-
def flexural_stiffness(self):
|
|
24
|
-
E = self.E
|
|
25
|
-
I = self.I
|
|
26
|
-
l = self.length
|
|
27
|
-
ke = (I*E/l**3)*np.array([
|
|
28
|
-
[12, 6*l, -12, 6*l],
|
|
29
|
-
[6*l, 4*l**2, -6*l, 2*l**2],
|
|
30
|
-
[-12, -6*l, 12, -6*l],
|
|
31
|
-
[6*l, 2*l**2, -6*l, 4*l**2]])
|
|
32
|
-
|
|
33
|
-
return ke
|
|
34
|
-
|
|
35
|
-
def first_parameter_foundation_stiffness(self):
|
|
36
|
-
k = self.k
|
|
37
|
-
l = self.length
|
|
38
|
-
k1 = np.array([
|
|
39
|
-
[1/35*l*(10*k[0]+3*k[1]), 1/420*l**2*(15*k[0]+7*k[1]),
|
|
40
|
-
9/140*l*(k[0]+k[1]), -1/420*l**2*(7*k[0]+6*k[1])],
|
|
41
|
-
[1/420*l**2*(15*k[0]+7*k[1]), 1/840*l**3*(5*k[0]+3*k[1]),
|
|
42
|
-
1/420*l**2*(6*k[0]+7*k[1]), -1/280*l**3*(k[0]+k[1])],
|
|
43
|
-
[9/140*l*(k[0]+k[1]), 1/420*l**2*(6*k[0]+7*k[1]),
|
|
44
|
-
1/35*l*(3*k[0]+10*k[1]), -1/420*l**2*(7*k[0]+15*k[1])],
|
|
45
|
-
[-1/420*l**2*(7*k[0]+6*k[1]), -1/280*l**3*(k[0]+k[1]), -1/420*l**2*(7*k[0]+15*k[1]), 1/840*l**3*(3*k[0]+5*k[1])]])
|
|
46
|
-
|
|
47
|
-
return k1
|
|
48
|
-
|
|
49
|
-
def second_parameter_foundation_stiffness(self):
|
|
50
|
-
t = self.t
|
|
51
|
-
l = self.length
|
|
52
|
-
k2 = np.array([
|
|
53
|
-
[3/5/l*(t[0]+t[1]), 1/10*t[1], -
|
|
54
|
-
3/5/l*(t[0]+t[1]), 1/10*t[0]],
|
|
55
|
-
[1/10*t[1], 1/30*l *
|
|
56
|
-
(3*t[0]+t[1]), -1/10*t[1], -1/60*l*(t[0]+t[1])],
|
|
57
|
-
[-3/5/l*(t[0]+t[1]), -1/10*t[1],
|
|
58
|
-
3/5/l*(t[0]+t[1]), -1/10*t[0]],
|
|
59
|
-
[1/10*t[0], -1/60*l*(t[0]+t[1]), -1/10*t[0], 1/30*l*(t[0]+3*t[1])]])
|
|
60
|
-
|
|
61
|
-
return k2
|
|
62
|
-
|
|
63
|
-
def stiffness(self):
|
|
64
|
-
return self.ke + self.k1 + self.k2
|
|
65
|
-
|
|
66
|
-
def is_within(self, rcoord):
|
|
67
|
-
if self.coord[0] >= rcoord[0] and self.coord[1] <= rcoord[1]:
|
|
68
|
-
return True
|
|
69
|
-
else:
|
|
70
|
-
return False
|
|
71
|
-
|
|
72
|
-
def forces(self, u):
|
|
73
|
-
return np.dot(self.ke, u)
|
|
74
|
-
|
|
75
|
-
def __str__(self):
|
|
76
|
-
return f"Coords: {self.coord} \nYoung's modulus: {self.E} \nLength: {self.length} \nk: {self.k} \nt: {self.t} \nforces: {self.forces}"
|
ebbef2p/helpers.py
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import itertools
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def pairwise(iterable):
|
|
5
|
-
#~ "s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
|
6
|
-
a, b = itertools.tee(iterable)
|
|
7
|
-
next(b, None)
|
|
8
|
-
return zip(a, b)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def is_within(xa, xb):
|
|
12
|
-
if xa[0] >= xb[0] and xa[1] <= xb[1]:
|
|
13
|
-
return True
|
|
14
|
-
else:
|
|
15
|
-
return False
|
ebbef2p/nodal_load.py
DELETED
ebbef2p/nodal_support.py
DELETED
ebbef2p/soil_conditions.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
class SoilCondition():
|
|
2
|
-
|
|
3
|
-
""" Sc class
|
|
4
|
-
|
|
5
|
-
Attributes:
|
|
6
|
-
value (list): Float values
|
|
7
|
-
position (list):
|
|
8
|
-
type (str): 'k' and 't'
|
|
9
|
-
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
def __init__(self, value, position, type):
|
|
13
|
-
"""Inits the SoilCondition class.
|
|
14
|
-
|
|
15
|
-
value (list):
|
|
16
|
-
position (list):
|
|
17
|
-
type (str):
|
|
18
|
-
|
|
19
|
-
"""
|
|
20
|
-
self.value = value
|
|
21
|
-
self.position = position
|
|
22
|
-
self.type = type
|
|
23
|
-
|
|
24
|
-
def __str__(self):
|
|
25
|
-
return f"Value: {self.value} \nPosition: {self.position} \nType: {self.type}"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# def __init__(self, k, t):
|
|
29
|
-
# self.k = k
|
|
30
|
-
# self.t = t
|
|
31
|
-
|
|
32
|
-
# def __str__(self):
|
|
33
|
-
# return f"k: {self.k} \nt: {self.t}"
|
ebbef2p/structure.py
DELETED
|
@@ -1,394 +0,0 @@
|
|
|
1
|
-
from .beam import Beam
|
|
2
|
-
from .element import BeamElement
|
|
3
|
-
from .soil_conditions import SoilCondition
|
|
4
|
-
from .distributed_load import DistributedLoad
|
|
5
|
-
from .nodal_load import NodalLoad
|
|
6
|
-
from .nodal_support import NodalSupport
|
|
7
|
-
from .helpers import *
|
|
8
|
-
import numpy as np
|
|
9
|
-
from functools import reduce
|
|
10
|
-
import math
|
|
11
|
-
import matplotlib.pyplot as plt
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
class Structure():
|
|
15
|
-
"""docstring for Structure"""
|
|
16
|
-
|
|
17
|
-
def __init__(self, name):
|
|
18
|
-
"""Constructor method
|
|
19
|
-
"""
|
|
20
|
-
self.name = name
|
|
21
|
-
self.beams = []
|
|
22
|
-
#self.forces = []
|
|
23
|
-
#self.moments = []
|
|
24
|
-
self.nodal_loads = []
|
|
25
|
-
self.distributed_loads = []
|
|
26
|
-
self.nodal_supports = []
|
|
27
|
-
self.constraints = []
|
|
28
|
-
self.soil_conditions = []
|
|
29
|
-
self.nodes = []
|
|
30
|
-
self.u = []
|
|
31
|
-
self.forces = []
|
|
32
|
-
#self.qn = []
|
|
33
|
-
|
|
34
|
-
# @property
|
|
35
|
-
def get_points_(self):
|
|
36
|
-
|
|
37
|
-
v = np.array([])
|
|
38
|
-
for b in self.beams:
|
|
39
|
-
# [2, 3, 5] -> [0, 2, 5, 10] np.cumsum()
|
|
40
|
-
v = np.union1d(v, b.coord)
|
|
41
|
-
# for f in self.forces:
|
|
42
|
-
# v = np.union1d(v, f[1])
|
|
43
|
-
for nl in self.nodal_loads:
|
|
44
|
-
v = np.union1d(v, nl.position)
|
|
45
|
-
|
|
46
|
-
for ns in self.nodal_supports:
|
|
47
|
-
v = np.union1d(v, ns.position)
|
|
48
|
-
# for m in self.moments:
|
|
49
|
-
# v = np.union1d(v, m[1])
|
|
50
|
-
for q in self.distributed_loads:
|
|
51
|
-
v = np.union1d(v, q.position)
|
|
52
|
-
for sc in self.soil_conditions:
|
|
53
|
-
#v = reduce(np.union1d, (v, sc.k[1], sc.t[1]))
|
|
54
|
-
#reduce(np.union1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))
|
|
55
|
-
v = np.union1d(v, sc.position)
|
|
56
|
-
|
|
57
|
-
return v
|
|
58
|
-
|
|
59
|
-
def get_points(self):
|
|
60
|
-
v = list(set().union([val for sublist in [b.coord for b in self.beams] for val in sublist],
|
|
61
|
-
[nls.position for nls in self.nodal_loads +
|
|
62
|
-
self.nodal_supports],
|
|
63
|
-
[val for sublist in [
|
|
64
|
-
q.position for q in self.distributed_loads] for val in sublist],
|
|
65
|
-
[val for sublist in [sc.position for sc in self.soil_conditions] for val in sublist])) \
|
|
66
|
-
# [val for sublist in [sc.t[1] for sc in self.soil_conditions] for val in sublist] ))
|
|
67
|
-
v.sort()
|
|
68
|
-
return v
|
|
69
|
-
|
|
70
|
-
def add_beam(self, coord, E, I):
|
|
71
|
-
self.beams.append(Beam(coord, E, I))
|
|
72
|
-
|
|
73
|
-
def add_nodal_load(self, value, position, type):
|
|
74
|
-
self.nodal_loads.append(NodalLoad(value, position, type))
|
|
75
|
-
|
|
76
|
-
def add_distributed_load(self, value, position):
|
|
77
|
-
self.distributed_loads.append(DistributedLoad(value, position))
|
|
78
|
-
|
|
79
|
-
def add_nodal_support(self, constraints, position):
|
|
80
|
-
self.nodal_supports.append(NodalSupport(constraints, position))
|
|
81
|
-
|
|
82
|
-
def add_soil_condition(self, value, position, type):
|
|
83
|
-
# self.soil_conditions[0].append(k)
|
|
84
|
-
# self.soil_conditions[1].append(t)
|
|
85
|
-
self.soil_conditions.append(SoilCondition(value, position, type))
|
|
86
|
-
|
|
87
|
-
def discretization(self, n):
|
|
88
|
-
points = self.get_points()
|
|
89
|
-
size = (max(points) - min(points))/n
|
|
90
|
-
nodes = np.array([])
|
|
91
|
-
#nodes = []
|
|
92
|
-
|
|
93
|
-
for i in range(1, len(points)):
|
|
94
|
-
nodes = np.union1d(nodes, np.linspace(
|
|
95
|
-
points[i-1], points[i], 1 + math.ceil((points[i]-points[i-1])/size)))
|
|
96
|
-
#nodes.append(np.linspace(points[i-1], points[i], 1 + math.ceil((points[i]-points[i-1])/size)))
|
|
97
|
-
# return nodes
|
|
98
|
-
self.nodes = nodes
|
|
99
|
-
self.elements = self.add_elements(nodes)
|
|
100
|
-
return nodes
|
|
101
|
-
|
|
102
|
-
def mesh(self, n):
|
|
103
|
-
points = self.get_points()
|
|
104
|
-
size = (max(points) - min(points))/n
|
|
105
|
-
nodes = np.array([])
|
|
106
|
-
#nodes = []
|
|
107
|
-
|
|
108
|
-
for i in range(1, len(points)):
|
|
109
|
-
nodes = np.union1d(nodes, np.linspace(
|
|
110
|
-
points[i-1], points[i], 1 + math.ceil((points[i]-points[i-1])/size)))
|
|
111
|
-
#nodes.append(np.linspace(points[i-1], points[i], 1 + math.ceil((points[i]-points[i-1])/size)))
|
|
112
|
-
# return nodes
|
|
113
|
-
self.nodes = nodes
|
|
114
|
-
#self.elements = self.add_elements(nodes)
|
|
115
|
-
return nodes
|
|
116
|
-
|
|
117
|
-
def add_elements(self, nodes):
|
|
118
|
-
elements = []
|
|
119
|
-
for x in pairwise(nodes):
|
|
120
|
-
ni, nj = x[0], x[1]
|
|
121
|
-
for b in self.beams:
|
|
122
|
-
# if b.coord[0] < nj <= b.coord[1]:
|
|
123
|
-
if is_within(x, b.coord):
|
|
124
|
-
E = b.E
|
|
125
|
-
# print(E)
|
|
126
|
-
I = b.I
|
|
127
|
-
for sc in self.soil_conditions:
|
|
128
|
-
# print(sc)
|
|
129
|
-
# if sc.k[1][0] < nj <= sc.k[1][1]:
|
|
130
|
-
if sc.type == 'k':
|
|
131
|
-
if is_within(x, sc.position):
|
|
132
|
-
ki = np.interp(ni, sc.position, sc.value)
|
|
133
|
-
kj = np.interp(nj, sc.position, sc.value)
|
|
134
|
-
else:
|
|
135
|
-
ki = 0
|
|
136
|
-
kj = 0
|
|
137
|
-
if sc.type == 't':
|
|
138
|
-
if is_within(x, sc.position):
|
|
139
|
-
ti = np.interp(ni, sc.position, sc.value)
|
|
140
|
-
tj = np.interp(nj, sc.position, sc.value)
|
|
141
|
-
else:
|
|
142
|
-
ti = 0
|
|
143
|
-
tj = 0
|
|
144
|
-
|
|
145
|
-
# if is_within(x, sc.position):
|
|
146
|
-
# if sc['type'] == 'k':
|
|
147
|
-
# ki = np.interp(ni, sc['position'], sc['value'])
|
|
148
|
-
# kj = np.interp(nj, sc['position'], sc['value'])
|
|
149
|
-
# if sc['type'] == 't':
|
|
150
|
-
# ti = np.interp(ni, sc['position'], sc['value'])
|
|
151
|
-
# tj = np.interp(nj, sc['position'], sc['value'])
|
|
152
|
-
# if is_within(x, sc.k[1]):
|
|
153
|
-
|
|
154
|
-
# ki = np.polyfit(sc.k[1], sc.k[0], 1)[
|
|
155
|
-
# 0]*ni + np.polyfit(sc.k[1], sc.k[0], 1)[1]
|
|
156
|
-
# kj = np.polyfit(sc.k[1], sc.k[0], 1)[
|
|
157
|
-
# 0]*nj + np.polyfit(sc.k[1], sc.k[0], 1)[1]
|
|
158
|
-
# else:
|
|
159
|
-
# ki = 0
|
|
160
|
-
# kj = 0
|
|
161
|
-
|
|
162
|
-
# ## if sc.t[1][0] < nj <= sc.t[1][1]:
|
|
163
|
-
# if is_within(x, sc.t[1]):
|
|
164
|
-
# ti = np.polyfit(sc.t[1], sc.t[0], 1)[
|
|
165
|
-
# 0]*ni + np.polyfit(sc.t[1], sc.t[0], 1)[1]
|
|
166
|
-
# tj = np.polyfit(sc.t[1], sc.t[0], 1)[
|
|
167
|
-
# 0]*nj + np.polyfit(sc.t[1], sc.t[0], 1)[1]
|
|
168
|
-
# else:
|
|
169
|
-
# ti = 0
|
|
170
|
-
# tj = 0
|
|
171
|
-
|
|
172
|
-
be = BeamElement((ni, nj), E, I, [ki, kj], [ti, tj])
|
|
173
|
-
elements.append(be)
|
|
174
|
-
|
|
175
|
-
return elements
|
|
176
|
-
|
|
177
|
-
def build_global_matrix(self):
|
|
178
|
-
elements = self.elements
|
|
179
|
-
K = np.zeros((2*(len(elements)+1), 2*(len(elements)+1)))
|
|
180
|
-
for e, element in enumerate(elements):
|
|
181
|
-
# ke = flexural_stiffness(element)
|
|
182
|
-
K[e*2:e*2+4, e*2:e*2+4] += element.stiffness
|
|
183
|
-
|
|
184
|
-
return K
|
|
185
|
-
|
|
186
|
-
def build_global_flexural_matrix(self, elements):
|
|
187
|
-
K = np.zeros((2*(len(elements)+1), 2*(len(elements)+1)))
|
|
188
|
-
for e, element in enumerate(elements):
|
|
189
|
-
# ke = flexural_stiffness(element)
|
|
190
|
-
K[e*2:e*2+4, e*2:e*2+4] += element.ke
|
|
191
|
-
|
|
192
|
-
return K
|
|
193
|
-
|
|
194
|
-
def get_forces(self):
|
|
195
|
-
f = np.zeros((len(self.elements), 4))
|
|
196
|
-
for e, element in enumerate(self.elements):
|
|
197
|
-
#f = np.append(f, np.dot(element.ke, self.u[2*e:2*e+4]))
|
|
198
|
-
# print(f)
|
|
199
|
-
f[e] = element.forces(self.u[2*e:2*e+4].flatten())
|
|
200
|
-
|
|
201
|
-
return f
|
|
202
|
-
|
|
203
|
-
#self.forces = f
|
|
204
|
-
|
|
205
|
-
def get_displacements(self):
|
|
206
|
-
|
|
207
|
-
#return dict(vertical_displacements=[w for w in self.u.flatten()[0::2]], rotations=[t for t in self.u.flatten()[1::2]])
|
|
208
|
-
return dict(vertical_displacements=[-w for w in self.u.flatten()[0::2]], rotations=[-t for t in self.u.flatten()[1::2]])
|
|
209
|
-
|
|
210
|
-
def get_shear_forces(self):
|
|
211
|
-
coords = list(itertools.chain(*[e.coord for e in self.elements]))
|
|
212
|
-
shear_forces = list(itertools.chain(
|
|
213
|
-
# *[(f[0], -f[2]) for f in self.get_forces()]))
|
|
214
|
-
*[(-f[0], f[2]) for f in self.get_forces()]))
|
|
215
|
-
# return [coords, shear_forces]
|
|
216
|
-
return dict(coords=coords, values=shear_forces)
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
def get_bending_moments(self):
|
|
220
|
-
coords = list(itertools.chain(*[e.coord for e in self.elements]))
|
|
221
|
-
bending_moments = list(itertools.chain(
|
|
222
|
-
#*[(-f[1], f[3]) for f in self.get_forces()]))
|
|
223
|
-
*[(f[1], -f[3]) for f in self.get_forces()]))
|
|
224
|
-
|
|
225
|
-
return dict(coords=coords, values=bending_moments)
|
|
226
|
-
|
|
227
|
-
def plot_shear_diagram(self):
|
|
228
|
-
#coords = list(itertools.chain(*[e.coord for e in self.elements]))
|
|
229
|
-
#shearing_forces = list(itertools.chain(*[(f[0], -f[2]) for f in self.get_forces()]))
|
|
230
|
-
# print(shearing_forces)
|
|
231
|
-
|
|
232
|
-
plt.plot(self.get_shear_forces()['coords'],
|
|
233
|
-
self.get_shear_forces()['values'])
|
|
234
|
-
plt.show()
|
|
235
|
-
|
|
236
|
-
def plot_moment_diagram(self):
|
|
237
|
-
#coords = list(itertools.chain(*[e.coord for e in self.elements]))
|
|
238
|
-
#bending_moments = list(itertools.chain(*[(-f[1], f[3]) for f in self.get_forces()]))
|
|
239
|
-
|
|
240
|
-
plt.plot(self.get_bending_moments()[
|
|
241
|
-
'coords'], self.get_bending_moments()['values'])
|
|
242
|
-
plt.show()
|
|
243
|
-
|
|
244
|
-
def get_bc(self):
|
|
245
|
-
#cs = np.zeros(len(self.nodes)*2)
|
|
246
|
-
bcdof = np.array([])
|
|
247
|
-
for c in self.constraints:
|
|
248
|
-
# ni = np.where(self.nodes == c[2])[0]
|
|
249
|
-
ni = np.where(self.nodes == c['x'])[0]
|
|
250
|
-
# print(ni)
|
|
251
|
-
if 'uz' in c:
|
|
252
|
-
# bcdof.append([int(ni[0]*2), c['ux']])
|
|
253
|
-
#{'uz': 0, 'x': 9}
|
|
254
|
-
bcdof = np.append(bcdof, [ni[0]*2, c['uz']])
|
|
255
|
-
if 'ur' in c:
|
|
256
|
-
bcdof = np.append(bcdof, [1+ni[0]*2, c['ur']])
|
|
257
|
-
# bcdof.append([int(1+ni[0]*2), c['ur']])
|
|
258
|
-
# bcdof.append([ni[0], c[0], c[1]])
|
|
259
|
-
# bcdof.append([ni[0]+1, c[0], c[1]])
|
|
260
|
-
# print(index)
|
|
261
|
-
#bcdof[2*index] = c[0]
|
|
262
|
-
#bcdof[2*index + 1] = c[1]
|
|
263
|
-
|
|
264
|
-
return np.reshape(bcdof, (len(self.constraints), 2))
|
|
265
|
-
|
|
266
|
-
def get_boudary_conditions(self):
|
|
267
|
-
bc = np.array([])
|
|
268
|
-
# constraints: {ur: 0, uz: 0}, position: 0 ##{'uz': 0, 'ur': "null"}, 9
|
|
269
|
-
for c in self.nodal_supports:
|
|
270
|
-
ni = np.where(self.nodes == c.position)[0]
|
|
271
|
-
#print(bool(c.constraints.get('uz') != 'NaN'))
|
|
272
|
-
|
|
273
|
-
if c.constraints['uz'] != 'NaN':
|
|
274
|
-
# if 'uz' in c.constraints:
|
|
275
|
-
bc = np.append(bc, [ni[0]*2, c.constraints['uz']])
|
|
276
|
-
if c.constraints['ur'] != 'NaN':
|
|
277
|
-
# if 'ur' in c.constraints:
|
|
278
|
-
bc = np.append(bc, [1+ni[0]*2, c.constraints['ur']])
|
|
279
|
-
return np.reshape(bc, (int(0.5*len(bc)), 2))
|
|
280
|
-
# print(bc)
|
|
281
|
-
|
|
282
|
-
def build_displacements_vector(self):
|
|
283
|
-
pass
|
|
284
|
-
|
|
285
|
-
def build_load_vector(self):
|
|
286
|
-
lv = np.zeros(len(self.nodes)*2)
|
|
287
|
-
# for f in self.forces:
|
|
288
|
-
# index = np.where(self.nodes == f[1])[0]
|
|
289
|
-
# # print(2*index)
|
|
290
|
-
# lv[2*index] = f[0]
|
|
291
|
-
# for m in self.moments:
|
|
292
|
-
# index = np.where(self.nodes == m[1])[0]
|
|
293
|
-
# lv[2*index + 1] = m[0]
|
|
294
|
-
|
|
295
|
-
# for i, n in enumerate(self.nodes):
|
|
296
|
-
# for q in self.distributed_loads:
|
|
297
|
-
# if q.position[0] <= n <= q.position[1]:
|
|
298
|
-
# qn = np.zeros(len(self.nodes))
|
|
299
|
-
# qn[i] = np.interp(n, q.position, q.value)
|
|
300
|
-
#lv[2*i] += (n[i+1] - n[i])/20*(7*qn[i] + 3*qn[i+1])
|
|
301
|
-
#self.qn = qn
|
|
302
|
-
|
|
303
|
-
for nl in self.nodal_loads:
|
|
304
|
-
index = np.where(self.nodes == nl.position)[0]
|
|
305
|
-
# print(index)
|
|
306
|
-
if nl.type == 'fz':
|
|
307
|
-
lv[2*index] = nl.value
|
|
308
|
-
if nl.type == 'my':
|
|
309
|
-
lv[2*index + 1] = nl.value
|
|
310
|
-
|
|
311
|
-
#t = np.zeros(len(self.nodes)*2)
|
|
312
|
-
# for ni, q in enumerate(pairwise(qn)):
|
|
313
|
-
|
|
314
|
-
# qi, qj = q[0], q[1]
|
|
315
|
-
# l = self.nodes[ni+1] - self.nodes[ni]
|
|
316
|
-
# F1q = l/20 * (7*qi + 3*qj)
|
|
317
|
-
# M1q = l**2/60 * (3*qi + 2*qj)
|
|
318
|
-
# F2q = l/20 * (3*qi + 7*qj)
|
|
319
|
-
# M2q = -l**2/60 * (2*qi + 3*qj)
|
|
320
|
-
|
|
321
|
-
#t += [F1q, M1q, F2q, M2q]
|
|
322
|
-
for e, n in enumerate(pairwise(self.nodes)):
|
|
323
|
-
for q in self.distributed_loads:
|
|
324
|
-
if is_within(n, q.position):
|
|
325
|
-
qi = np.interp(n[0], q.position, q.value)
|
|
326
|
-
qj = np.interp(n[1], q.position, q.value)
|
|
327
|
-
#print(f"qi: {qi} \nqj: {qj}")
|
|
328
|
-
#l = (nj - ni)
|
|
329
|
-
F1q = (n[1] - n[0])/20 * (7*qi + 3*qj)
|
|
330
|
-
M1q = (n[1] - n[0])**2/60 * (3*qi + 2*qj)
|
|
331
|
-
F2q = (n[1] - n[0])/20 * (3*qi + 7*qj)
|
|
332
|
-
M2q = -(n[1] - n[0])**2/60 * (2*qi + 3*qj)
|
|
333
|
-
|
|
334
|
-
lv[2*e:2*e+4] += [F1q, M1q, F2q, M2q]
|
|
335
|
-
|
|
336
|
-
return lv
|
|
337
|
-
|
|
338
|
-
def solve(self, K, f, constraints):
|
|
339
|
-
"""
|
|
340
|
-
Solve static FE-equations considering boundary conditions.
|
|
341
|
-
Adapted from CALFEM (for Python): https://github.com/CALFEM/calfem-python
|
|
342
|
-
|
|
343
|
-
Parameters:
|
|
344
|
-
|
|
345
|
-
K global stiffness matrix, dim(K)= nd x nd
|
|
346
|
-
f global load vector, dim(f)= nd x 1
|
|
347
|
-
|
|
348
|
-
constraints TO DO
|
|
349
|
-
Returns:
|
|
350
|
-
|
|
351
|
-
a solution including boundary values
|
|
352
|
-
Q reaction force vector
|
|
353
|
-
dim(a)=dim(Q)= nd x 1, nd : number of dof's
|
|
354
|
-
|
|
355
|
-
"""
|
|
356
|
-
|
|
357
|
-
nDofs = K.shape[0]
|
|
358
|
-
bcVal = constraints[:, 1]
|
|
359
|
-
bcPrescr = constraints[:, 0].astype(int)
|
|
360
|
-
nPdofs = bcPrescr.shape[0]
|
|
361
|
-
|
|
362
|
-
bc = np.ones(nDofs, 'bool')
|
|
363
|
-
bcDofs = np.arange(nDofs)
|
|
364
|
-
|
|
365
|
-
bc[np.ix_(bcPrescr)] = False
|
|
366
|
-
bcDofs = bcDofs[bc]
|
|
367
|
-
|
|
368
|
-
fsys = f[bcDofs]-K[np.ix_((bcDofs), (bcPrescr))].dot(bcVal)
|
|
369
|
-
asys = np.linalg.solve(K[np.ix_((bcDofs), (bcDofs))], fsys)
|
|
370
|
-
|
|
371
|
-
a = np.zeros([nDofs, 1])
|
|
372
|
-
a[np.ix_(bcPrescr)] = np.asmatrix(bcVal).reshape(nPdofs, 1)
|
|
373
|
-
a[np.ix_(bcDofs)] = np.asmatrix(asys).reshape(bcDofs.shape[0], 1)
|
|
374
|
-
#print(f"K.shape = {asys}")
|
|
375
|
-
#print(f"a shape = {a.shape}")
|
|
376
|
-
#print(f"f shape = {f.shape}")
|
|
377
|
-
# print(a.flatten())
|
|
378
|
-
|
|
379
|
-
Q = K*np.asmatrix(a)-f.reshape(nDofs, 1)
|
|
380
|
-
|
|
381
|
-
self.u = a
|
|
382
|
-
|
|
383
|
-
return (np.asmatrix(a), Q)
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
def elements_forces(self):
|
|
387
|
-
f = np.zeros(len(self.nodes)*2)
|
|
388
|
-
for i, el in enumerate(self.elements):
|
|
389
|
-
f[2*i:2*i+4] += el.forces(self.u[2*i:2*i+4].flatten())
|
|
390
|
-
|
|
391
|
-
self.forces = f
|
|
392
|
-
|
|
393
|
-
def __str__(self):
|
|
394
|
-
return f"Beams: {self.beams} \nNodal Loads: {self.nodal_loads} \nDistributed Loads: {self.distributed_loads} \nSoil Conditions: {self.soil_conditions}"
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
|
|
3
|
-
class VlasovFoundationParameters():
|
|
4
|
-
|
|
5
|
-
def __init__(self, Edef, nu, depth, gamma):
|
|
6
|
-
self.Edef = Edef
|
|
7
|
-
self.nu = nu
|
|
8
|
-
self.depth = depth
|
|
9
|
-
self.gamma = gamma
|
|
10
|
-
#self.k = None
|
|
11
|
-
#self.t = None
|
|
12
|
-
|
|
13
|
-
@property
|
|
14
|
-
def k(self):
|
|
15
|
-
return ((1-self.nu)/((1+self.nu)*(1-2*self.nu)*self.depth))*(self.Edef['E1']*(2*self.gamma*np.sinh(2*self.gamma)+4*(self.gamma**2))+(self.Edef['E2']-self.Edef['E1'])*(np.cosh(2*self.gamma)-1+2*self.gamma**2))/(8*((np.sinh(self.gamma))**2))
|
|
16
|
-
|
|
17
|
-
@property
|
|
18
|
-
def t(self):
|
|
19
|
-
return (self.depth/((1+self.nu)*self.gamma**2))*(self.Edef['E1']*(2*self.gamma*np.sinh(2*self.gamma)-4*(self.gamma**2))+(self.Edef['E2']-self.Edef['E1'])*(np.cosh(2*self.gamma)-1-2*self.gamma**2))/(16*((np.sinh(self.gamma))**2))
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def get_gamma(self, displacements, coords):
|
|
23
|
-
return self.depth*np.sqrt(((1-2*self.nu)/(2*(1-self.nu)))*(np.trapz([theta*theta for theta in displacements['rotations']], coords)/np.trapz([w*w for w in displacements['vertical_displacements']], coords)))
|
|
24
|
-
# function y=GAMMA(Translation,Rotation,Coords,nu,H)
|
|
25
|
-
|
|
26
|
-
# y=H*sqrt(((1-2*nu)/(2*(1-nu)))*(trapz(Rotation.^2,Coords)/trapz(Translation.^2,Coords))); [w*w for w in vertical_displacements]
|
|
27
|
-
|
|
28
|
-
def __str__(self):
|
|
29
|
-
return f"Edef: {self.Edef} \nnu: {self.nu} \ndepth: {self.depth} \ngamma: {self.gamma} \nk: {self.k} \nt: {self.t}"
|
|
30
|
-
|
|
31
|
-
# function y=VlasovParam(Foundation, Gamma)
|
|
32
|
-
|
|
33
|
-
# E=Foundation.Young;
|
|
34
|
-
# nu=Foundation.Poisson;
|
|
35
|
-
# H=Foundation.Depth;
|
|
36
|
-
# E1=E(1);
|
|
37
|
-
# E2=E(2);
|
|
38
|
-
# k=((1-nu)/((1+nu)*(1-2*nu)*H))*...
|
|
39
|
-
# (E1*(2*Gamma*np.sinh(2*Gamma)+4*(Gamma**2))+(E2-E1)*(np.cosh(2*Gamma)-1+2*Gamma**2))/(8*((sinh(Gamma))^2));
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
# t=(H/((1+nu)*Gamma^2))*...
|
|
43
|
-
# (E1*(2*Gamma*sinh(2*Gamma)-4*(Gamma^2))+(E2-E1)*(np.cosh(2*Gamma)-1-2*Gamma^2))/(16*((sinh(Gamma))^2));
|
|
44
|
-
|
|
45
|
-
# y=[k ; t];
|
|
46
|
-
|