Skip to content

Commit 0570316

Browse files
committed
WIP
1 parent 98967f1 commit 0570316

6 files changed

Lines changed: 363 additions & 114 deletions

File tree

Binary file not shown.

Examples/safarrancho6.py

Lines changed: 99 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
11
if __name__ == '__main__':
2-
from FEM import MGDCM, ContinumTotalLagrangian, TriMembraneLinear, BarLinear, Geometry3D
2+
from FEM import MGDCM, NewtonTotalLagrangian, ContinumTotalLagrangian, QuadMembraneLinear, Geometry3D
33
import matplotlib.pyplot as plt
44
import numpy as np
5-
from matplotlib.animation import FuncAnimation
6-
h1 = 1
7-
h2 = 0.5
8-
h = h1 + h2
9-
d1 = 2.5
10-
d2 = 4
11-
P = 5
12-
t = 0.1
13-
N = 200
14-
L0 = 1
5+
import matplotlib.animation as animation
156

7+
def analytical_force(u, E, A, L, h):
8+
L0 = np.sqrt(L**2 + h**2)
9+
y = h - u
10+
l = np.sqrt(L**2 + y**2)
11+
strain = (L0-l) / L0
12+
strain = strain + 1/2*strain**2
13+
N = E * A * strain
14+
vertical_component = (y / l)
15+
return -2 * N * vertical_component
16+
17+
a = 400
18+
b = 20
19+
L = (a**2 + b**2)**0.5
20+
h = 653
21+
t = 1
22+
A = h*t
23+
P = 1000
1624
nu = 0.5
1725
young = 20500 # Young's modulus in MPa
1826

@@ -25,6 +33,33 @@
2533
[c12, c22, 0.0],
2634
[0.0, 0.0, c66]])
2735

36+
coords = [
37+
[0, 0, 0],
38+
[a, 0, b],
39+
[2*a, 0, 0],
40+
[0, h, 0],
41+
[a, h, b],
42+
[2*a, h, 0],
43+
]
44+
45+
elements = [
46+
[0, 1, 4, 3],
47+
[1, 2, 5, 4]]
48+
49+
types = [QuadMembraneLinear]*(len(elements))
50+
51+
geo = Geometry3D(elements, coords, types, 3, fast=True)
52+
geo.cbe = [[0, 0],
53+
[1, 0],
54+
[2, 0],
55+
[6, 0],
56+
[7, 0],
57+
[8, 0],
58+
[9, 0],
59+
[11, 0],
60+
[15, 0],
61+
[17, 0]]
62+
2863
def cm(_E):
2964
E = np.zeros((3, 1))
3065
E[0, 0] = _E[0, 0]
@@ -37,91 +72,70 @@ def cm(_E):
3772
_S[0, 1] = S[2, 0]
3873
_S[1, 0] = S[2, 0]
3974
return C, _S, t
40-
41-
coords = [[0.0, 0.0, h]]
42-
gamma = 60 * np.pi / 180
43-
for i in range(0, 6):
44-
theta = i * gamma
45-
coords.append([d1*np.cos(theta), d1*np.sin(theta), h1])
46-
for i in range(0, 6):
47-
theta = i * gamma - np.pi/2
48-
coords.append([d2*np.cos(theta), d2*np.sin(theta), 0])
49-
coords = np.array(coords)
50-
51-
elements = [[0, 1, 2],
52-
[0, 2, 3],
53-
[0, 3, 4],
54-
[0, 4, 5],
55-
[0, 5, 6],
56-
57-
[5, 7, 6],
58-
[6, 8, 1],
59-
[1, 9, 2],
60-
[2, 10, 3],
61-
[3, 11, 4],
62-
[4, 12, 5],
63-
]
64-
types = [TriMembraneLinear]*(len(elements))
65-
66-
geo = Geometry3D(elements, coords, types, 3, fast=True)
67-
geo.cbe = []
68-
for node in [7, 8, 9, 10, 11, 12]:
69-
geo.cbe += [[node*3, 0], [node*3+1, 0], [node*3+2, 0]]
70-
for node in [0, 1, 2, 3, 4, 5, 6]:
71-
geo.cbe += [[node*3, 0], [node*3+1, 0]]
72-
geo.cbn = [[2, -P]]
73-
74-
O = ContinumTotalLagrangian(geo, cm, solver=MGDCM, verbose=True)
75-
O.solver.set_delta_lambda_bar(L0)
76-
O.solver.momentum = False
77-
O.solver.tol = 1e-3
78-
O.solver.set_increments(N)
75+
O = ContinumTotalLagrangian(
76+
geo, cm, solver=NewtonTotalLagrangian, override_nvn=True)
77+
O.solver.load_steps = 100
78+
O.solver.unloading = True
79+
O.cbn = [[5, -P/2], [14, -P/2]]
7980
O.solve()
8081

8182
displacements = []
8283
load_factors = []
8384
for i in range(len(O.solver.solutions)):
8485
O.solver.setSolution(i, elements=True)
85-
displacements.append(-O.U[2][0])
86+
displacements.append(-O.U[5][0])
8687
load_factors.append(O.solution_info['ld'])
88+
data = np.array([displacements, load_factors]).T
89+
us = np.linspace(0, np.max(displacements), len(displacements))
90+
force = -analytical_force(us, young, A, a, b)/P
8791

88-
# Plot the results
89-
fig = plt.figure(figsize=(12, 5))
92+
plots = []
93+
fig = plt.figure(figsize=(12, 6))
9094
ax = fig.add_subplot(1, 2, 1, projection='3d')
9195
ax2 = fig.add_subplot(1, 2, 2)
92-
cosa, = ax2.plot(
93-
displacements[:1], load_factors[:1], '-', label='Numerical')
94-
ax2.legend()
95-
ax2.set_ylabel('Load factor')
96-
ax2.set_xlabel('Displacement')
97-
ax2.grid()
98-
ax2.set_xlim(1.1*min(displacements), 4)
99-
ax2.set_ylim(-80, 70)
100-
ax.set(xlim3d=(-d1*1.2, d1*1.2), ylim3d=(-d1*1.2, d1*1.2),
101-
zlim3d=(0, h), xlabel='X', ylabel='Y', zlabel='Z')
102-
ax.set_aspect('equal')
103-
lines = []
10496
for e in O.elements:
105-
coords = e.coords + e.Ue.T
106-
lines.append(
107-
ax.plot(coords[:, 0], coords[:, 1], 'r-')[0])
108-
109-
def animate(i, lines, cosa):
110-
O.solver.setSolution(i, elements=True)
111-
for j, e in enumerate(O.elements):
112-
coords = e.coords + e.Ue.T
113-
lines[j].set_data_3d(coords.T)
114-
cosa.set_data(displacements[:i], load_factors[:i])
115-
return lines + [cosa]
97+
surf = ax.plot_trisurf(e.coords[:, 0], e.coords[:, 1],
98+
e.coords[:, 2], alpha=0.5, color='b')
99+
plots.append(surf)
100+
pl, = ax2.plot(us[:1], force[:1], '--', lw=3, c='gray', label="Analytical")
101+
plots.append(pl)
102+
pl, = ax2.plot(displacements[:1], load_factors[:1],
103+
'-', c='k', label="Continumm incremental")
104+
plots.append(pl)
105+
ax2.set_xlabel('Displacement')
106+
ax2.set_ylabel('Load factor')
116107

117-
anim = FuncAnimation(
118-
fig,
119-
animate,
120-
frames=len(O.solver.solutions)-1,
121-
interval=60,
122-
fargs=(lines, cosa),
123-
blit=True
124-
)
125-
# anim.save('./Examples/examples_results/RToff_non_lineal.mp4')
108+
def animate(i, plots):
109+
plots = []
110+
ax.clear()
111+
ax2.clear()
112+
O.solver.setSolution(i-1, elements=True)
113+
for e in O.elements:
114+
coords = e.coords + e.Ue[:3].T
115+
surf = ax.plot_trisurf(coords[:, 0], coords[:, 1],
116+
coords[:, 2], alpha=0.5, color='r')
117+
plots.append(surf)
118+
ax.set_xlim(0, 2*a)
119+
ax.set_ylim(0, h)
120+
ax.set_zlim(-b, b)
121+
ax.set_title(
122+
f'Deformed shape at load step {i}, load factor: {O.solution_info["ld"]:.2f}')
123+
pl, = ax2.plot(us[:i], force[:i], '--', c='gray', lw=3,
124+
label="Analytical")
125+
plots.append(pl)
126+
pl, = ax2.plot(displacements[:i],
127+
load_factors[:i], '-', c='k', label="Continumm incremental")
128+
plots.append(pl)
129+
ax2.legend()
130+
ax2.grid()
131+
ax2.set_xlabel('Displacement')
132+
ax2.set_ylabel('Load factor')
133+
ax2.set_xlim(0, 60)
134+
ax2.set_ylim(-1, 1)
135+
return plots
126136

137+
pam_ani = animation.FuncAnimation(fig, animate, fargs=(plots,),
138+
interval=5, blit=False, frames=len(O.solver.solutions))
139+
pam_ani.save(
140+
'./Examples/examples_results/Truss_non_lineal_continumm_incremental_membranes_newton.mp4')
127141
plt.show()

Examples/safarrancho7.py

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
if __name__ == '__main__':
2+
from FEM import MGDCM, ContinumTotalLagrangian, QuadMembraneLinear, QuadShellLinear, Geometry3D
3+
import matplotlib.pyplot as plt
4+
import numpy as np
5+
import matplotlib.animation as animation
6+
7+
def analytical_force(u, E, A, L, h):
8+
L0 = np.sqrt(L**2 + h**2)
9+
y = h - u
10+
l = np.sqrt(L**2 + y**2)
11+
strain = (L0-l) / L0
12+
strain = strain + 1/2*strain**2
13+
N = E * A * strain
14+
vertical_component = (y / l)
15+
return -2 * N * vertical_component
16+
17+
a = 400
18+
b = 20
19+
L = (a**2 + b**2)**0.5
20+
h = 653
21+
t = 1
22+
A = h*t
23+
P = 1000
24+
nu = 0.5
25+
young = 20500 # Young's modulus in MPa
26+
27+
c11 = young / (1 - nu**2)
28+
c12 = nu * c11
29+
c22 = c11
30+
c66 = young / (2 * (1 + nu))
31+
C = np.array([
32+
[c11, c12, 0.0],
33+
[c12, c22, 0.0],
34+
[0.0, 0.0, c66]])
35+
36+
coords = [
37+
[0, 0, 0],
38+
[a, 0, b],
39+
[2*a, 0, 0],
40+
[0, h, 0],
41+
[a, h, b],
42+
[2*a, h, 0],
43+
]
44+
45+
elements = [
46+
[0, 1, 4, 3],
47+
[1, 2, 5, 4]]
48+
49+
types = [QuadShellLinear]*(len(elements))
50+
51+
geo = Geometry3D(elements, coords, types, 5, fast=True)
52+
geo.cbe = [[0, 0],
53+
[1, 0],
54+
[2, 0],
55+
[6, 0],
56+
[7, 0],
57+
[8, 0],
58+
[9, 0],
59+
[11, 0],
60+
[15, 0],
61+
[17, 0]]
62+
63+
def cm(_E):
64+
E = np.zeros((3, 1))
65+
E[0, 0] = _E[0, 0]
66+
E[1, 0] = _E[1, 1]
67+
E[2, 0] = 2*_E[0, 1]
68+
S = C @ E
69+
_S = np.zeros((2, 2))
70+
_S[0, 0] = S[0, 0]
71+
_S[1, 1] = S[1, 0]
72+
_S[0, 1] = S[2, 0]
73+
_S[1, 0] = S[2, 0]
74+
return C, _S, t
75+
O = ContinumTotalLagrangian(geo, cm, solver=MGDCM, override_nvn=True)
76+
O.solver.set_delta_lambda_bar(0.05)
77+
O.solver.momentum = False
78+
O.solver.set_increments(220)
79+
O.cbn = [[5, -P/2], [14, -P/2]]
80+
O.solve()
81+
82+
displacements = []
83+
load_factors = []
84+
for i in range(len(O.solver.solutions)):
85+
O.solver.setSolution(i, elements=True)
86+
displacements.append(-O.U[5][0])
87+
load_factors.append(O.solution_info['ld'])
88+
data = np.array([displacements, load_factors]).T
89+
np.savetxt('./Examples/examples_results/safarrancho3.csv', data,
90+
header='Displacement\tLoad factor', delimiter=',')
91+
us = np.linspace(0, np.max(displacements), len(displacements))
92+
force = -analytical_force(us, young, A, a, b)/P
93+
94+
plots = []
95+
fig = plt.figure(figsize=(12, 6))
96+
ax = fig.add_subplot(1, 2, 1, projection='3d')
97+
ax2 = fig.add_subplot(1, 2, 2)
98+
for e in O.elements:
99+
surf = ax.plot_trisurf(e.coords[:, 0], e.coords[:, 1],
100+
e.coords[:, 2], alpha=0.5, color='b')
101+
plots.append(surf)
102+
pl, = ax2.plot(us[:1], force[:1], '--', lw=3, c='gray', label="Analytical")
103+
plots.append(pl)
104+
pl, = ax2.plot(displacements[:1], load_factors[:1],
105+
'-', c='k', label="Continumm incremental")
106+
plots.append(pl)
107+
ax2.set_xlabel('Displacement')
108+
ax2.set_ylabel('Load factor')
109+
110+
def animate(i, plots):
111+
plots = []
112+
ax.clear()
113+
ax2.clear()
114+
O.solver.setSolution(i-1, elements=True)
115+
for e in O.elements:
116+
coords = e.coords + e.Ue[:3].T
117+
surf = ax.plot_trisurf(coords[:, 0], coords[:, 1],
118+
coords[:, 2], alpha=0.5, color='r')
119+
plots.append(surf)
120+
ax.set_xlim(0, 2*a)
121+
ax.set_ylim(0, h)
122+
ax.set_zlim(-b, b)
123+
ax.set_title(
124+
f'Deformed shape at load step {i}, load factor: {O.solution_info["ld"]:.2f}')
125+
pl, = ax2.plot(us[:i], force[:i], '--', c='gray', lw=3,
126+
label="Analytical")
127+
plots.append(pl)
128+
pl, = ax2.plot(displacements[:i],
129+
load_factors[:i], '-', c='k', label="Continumm incremental")
130+
plots.append(pl)
131+
ax2.legend()
132+
ax2.grid()
133+
ax2.set_xlabel('Displacement')
134+
ax2.set_ylabel('Load factor')
135+
ax2.set_xlim(0, 60)
136+
ax2.set_ylim(-1, 1)
137+
return plots
138+
139+
pam_ani = animation.FuncAnimation(fig, animate, fargs=(plots,),
140+
interval=5, blit=False, frames=len(O.solver.solutions))
141+
pam_ani.save(
142+
'./Examples/examples_results/Truss_non_lineal_continumm_incremental_membranes.mp4')
143+
plt.show()

0 commit comments

Comments
 (0)