PolyFEM
Loading...
Searching...
No Matches
elasticity_rhs.py
Go to the documentation of this file.
1
import
os
2
import
argparse
3
4
from
sympy
import
*
5
from
sympy.matrices
import
*
6
import
re
7
8
# local
9
import
pretty_print
10
11
12
13
def
Det
(mat):
14
assert(mat.rows == mat.cols)
15
16
if(mat.rows == 1):
17
return
mat[0]
18
elif(mat.rows == 2):
19
return
mat[0, 0] * mat[1, 1] - mat[0, 1] * mat[1, 0]
20
elif(mat.rows == 3):
21
return
mat[0,0]*(mat[1,1]*mat[2,2]-mat[1,2]*mat[2,1])-mat[0,1]*(mat[1,0]*mat[2,2]-mat[1,2]*mat[2,0])+mat[0,2]*(mat[1,0]*mat[2,1]-mat[1,1]*mat[2,0])
22
23
assert(
False
)
24
return
0
25
26
27
def
sigma_fun
(j, ee, C, dim):
28
res = 0
29
30
for
k
in
range(dim):
31
res += C(j, k) * ee[k]
32
return
res
33
34
35
# sigma = 2 * mu * eps + lambda * strain.trace() * Id;
36
def
linear_elasticity
(disp_grad, def_grad):
37
l_dim = def_grad.rows
38
mu = Symbol(
'mu'
)
39
llambda = Symbol(
'lambda'
)
40
41
eps = 1 / 2 * (disp_grad + Transpose(disp_grad))
42
t_eps = eps[0, 0]
43
44
for
i
in
range(1,l_dim):
45
t_eps += eps[i, i]
46
47
sigma = 2*mu*eps + llambda * t_eps * eye(l_dim)
48
49
return
sigma
50
51
52
# sigma = (C:strain)
53
def
hooke
(disp_grad, def_grad):
54
l_dim = def_grad.rows
55
56
C = Function(
'C'
)
57
58
eps = 1 / 2 * (disp_grad + Transpose(disp_grad))
59
60
if
l_dim == 2:
61
ee = [eps[0, 0], eps[1, 1], 2 * eps[0, 1]]
62
63
sigma = Matrix([
64
[
sigma_fun
(0, ee, C, 3),
sigma_fun
(2, ee, C, 3)],
65
[
sigma_fun
(2, ee, C, 3),
sigma_fun
(1, ee, C, 3)]
66
])
67
else
:
68
ee = [eps[0, 0], eps[1, 1], eps[2, 2], 2 * eps[1, 2], 2 * eps[0, 2], 2 * eps[0, 1]]
69
70
sigma = Matrix([
71
[
sigma_fun
(0, ee, C, 6),
sigma_fun
(5, ee, C, 6),
sigma_fun
(4, ee, C, 6)],
72
[
sigma_fun
(5, ee, C, 6),
sigma_fun
(1, ee, C, 6),
sigma_fun
(3, ee, C, 6)],
73
[
sigma_fun
(4, ee, C, 6),
sigma_fun
(3, ee, C, 6),
sigma_fun
(2, ee, C, 6)]
74
])
75
76
return
sigma
77
78
79
# sigma = (C:strain)
80
def
saint_venant
(disp_grad, def_grad):
81
l_dim = def_grad.rows
82
83
C = Function(
'C'
)
84
85
eps = 1 / 2 * (Transpose(disp_grad) * disp_grad + disp_grad + Transpose(disp_grad))
86
87
if
l_dim == 2:
88
ee = [eps[0, 0], eps[1, 1], 2 * eps[0, 1]]
89
90
sigma = Matrix([
91
[
sigma_fun
(0, ee, C, 3),
sigma_fun
(2, ee, C, 3)],
92
[
sigma_fun
(2, ee, C, 3),
sigma_fun
(1, ee, C, 3)]
93
])
94
else
:
95
ee = [eps[0, 0], eps[1, 1], eps[2, 2], 2 * eps[1, 2], 2 * eps[0, 2], 2 * eps[0, 1]]
96
97
sigma = Matrix([
98
[
sigma_fun
(0, ee, C, 6),
sigma_fun
(5, ee, C, 6),
sigma_fun
(4, ee, C, 6)],
99
[
sigma_fun
(5, ee, C, 6),
sigma_fun
(1, ee, C, 6),
sigma_fun
(3, ee, C, 6)],
100
[
sigma_fun
(4, ee, C, 6),
sigma_fun
(3, ee, C, 6),
sigma_fun
(2, ee, C, 6)]
101
])
102
103
sigma = def_grad * sigma
104
105
return
sigma
106
107
108
# sigma = mu * (def_grad - def_grad^{-T}) + lambda ln (det def_grad) def_grad^{-T}
109
def
neo_hookean
(disp_grad, def_grad):
110
mu = Symbol(
'mu'
)
111
llambda = Symbol(
'lambda'
)
112
113
FmT = Inverse(Transpose(def_grad))
114
115
return
mu * (def_grad - FmT) + llambda * log(Determinant(def_grad)) * FmT
116
117
118
# sigma = (mu disp_grad + lambda ln(det def_grad) I)/det def_grad
119
# def neo_hookean(disp_grad, def_grad):
120
# l_dim = def_grad.rows
121
122
# mu = Symbol('mu')
123
# llambda = Symbol('lambda')
124
125
# J = Det(def_grad)
126
127
# return (mu * disp_grad + llambda * log(J) * eye(l_dim)) / J
128
129
130
def
divergence
(sigma):
131
if
dim == 2:
132
div = Matrix([
133
sigma[0, 0].diff(x) + sigma[0, 1].diff(y),
134
sigma[1, 0].diff(x) + sigma[1, 1].diff(y)
135
])
136
else
:
137
div = Matrix([
138
sigma[0, 0].diff(x) + sigma[0, 1].diff(y) + sigma[0, 2].diff(z),
139
sigma[1, 0].diff(x) + sigma[1, 1].diff(y) + sigma[1, 2].diff(z),
140
sigma[2, 0].diff(x) + sigma[2, 1].diff(y) + sigma[2, 2].diff(z)
141
])
142
143
return
div
144
145
146
def
parse_args
():
147
parser = argparse.ArgumentParser(
148
description=__doc__,
149
formatter_class=argparse.RawDescriptionHelpFormatter)
150
parser.add_argument(
"output"
, type=str, help=
"path to the output folder"
)
151
return
parser.parse_args()
152
153
154
if
__name__ ==
"__main__"
:
155
args =
parse_args
()
156
dims = [2, 3]
157
names = [
"linear_elasticity"
,
"hooke"
,
"saint_venant"
,
"neo_hookean"
]
158
cpp =
"#include <polyfem/autogen/auto_elasticity_rhs.hpp>\n\n\n"
159
hpp =
"#pragma once\n\n#include <polyfem/utils/ElasticityUtils.hpp>\n#include <polyfem/utils/AutodiffTypes.hpp>\n#include <Eigen/Dense>\n\n"
160
cpp = cpp +
"namespace polyfem {\nnamespace autogen "
+
"{\n"
161
hpp = hpp +
"namespace polyfem {\nnamespace autogen "
+
"{\n"
162
163
x = Symbol(
'x'
)
164
y = Symbol(
'y'
)
165
z = Symbol(
'z'
)
166
167
for
name
in
names:
168
for
dim
in
dims:
169
print(
"processing "
+ name +
" in "
+ str(dim) +
"D"
)
170
171
if
dim == 2:
172
X = Matrix([x, y])
173
f = Matrix([Function(
'f0'
)(x, y), Function(
'f1'
)(x, y)])
174
else
:
175
X = Matrix([x, y, z])
176
f = Matrix([Function(
'f0'
)(x, y, z), Function(
'f1'
)(x, y, z), Function(
'f2'
)(x, y, z)])
177
178
disp_grad = f.jacobian(X)
179
def_grad = (eye(dim) + disp_grad)
180
181
if
name ==
"hooke"
:
182
sigma =
hooke
(disp_grad, def_grad)
183
elif
name ==
"saint_venant"
:
184
sigma =
saint_venant
(disp_grad, def_grad)
185
elif
name ==
"neo_hookean"
:
186
sigma =
neo_hookean
(disp_grad, def_grad)
187
elif
name ==
"linear_elasticity"
:
188
sigma =
linear_elasticity
(disp_grad, def_grad)
189
190
div =
divergence
(sigma)
191
# div = simplify(div)
192
c99 =
pretty_print.C99_print
(div)
193
194
c99 = re.sub(
r"f0\(x, y(, z)?\)"
,
"pt(0)"
, c99)
195
c99 = re.sub(
r"f1\(x, y(, z)?\)"
,
"pt(1)"
, c99)
196
c99 = re.sub(
r"f2\(x, y(, z)?\)"
,
"pt(2)"
, c99)
197
198
c99 = re.sub(
r", x, x\)"
,
".getHessian()(0,0)"
, c99)
199
c99 = re.sub(
r", x, y\)"
,
".getHessian()(0,1)"
, c99)
200
c99 = re.sub(
r", x, z\)"
,
".getHessian()(0,2)"
, c99)
201
202
c99 = re.sub(
r", y, y\)"
,
".getHessian()(1,1)"
, c99)
203
c99 = re.sub(
r", y, z\)"
,
".getHessian()(1,2)"
, c99)
204
205
c99 = re.sub(
r", z, z\)"
,
".getHessian()(2,2)"
, c99)
206
207
c99 = re.sub(
r", x\)"
,
".getGradient()(0)"
, c99)
208
c99 = re.sub(
r", y\)"
,
".getGradient()(1)"
, c99)
209
c99 = re.sub(
r", z\)"
,
".getGradient()(2)"
, c99)
210
211
c99 = re.sub(
r"Derivative\(*"
,
""
, c99)
212
213
c99 = re.sub(
r", \(x, 2\)\)"
,
".getHessian()(0,0)"
, c99)
214
c99 = re.sub(
r", \(y, 2\)\)"
,
".getHessian()(1,1)"
, c99)
215
c99 = re.sub(
r", \(z, 2\)\)"
,
".getHessian()(2,2)"
, c99)
216
217
c99 = c99.replace(
"result_0[0]"
,
"res(0)"
)
218
c99 = c99.replace(
"result_0[1]"
,
"res(1)"
)
219
c99 = c99.replace(
"result_0[2]"
,
"res(2)"
)
220
221
# c99 = re.sub("// ", "", c99)
222
223
signature =
"void "
+ name +
"_"
+ str(dim) +
"d_function(const AutodiffHessianPt &pt"
224
if
name ==
"hooke"
or
name ==
"saint_venant"
:
225
signature = signature +
", const ElasticityTensor &C"
226
elif
name ==
"linear_elasticity"
or
name ==
"neo_hookean"
:
227
signature = signature +
", const double lambda, const double mu"
228
229
signature = signature +
", Eigen::Matrix<double, Eigen::Dynamic, 1, 0, 3, 1> &res)"
230
231
cpp = cpp + signature +
" {\nres.resize("
+ str(dim) +
");\n"
+ c99 +
"\n}\n\n"
232
hpp = hpp + signature +
";\n"
233
234
cpp = cpp +
"\n"
235
hpp = hpp +
"\n"
236
237
cpp = cpp +
"\n}}\n"
238
hpp = hpp +
"\n}}\n"
239
path = os.path.abspath(args.output)
240
241
print(
"saving..."
)
242
with
open(os.path.join(path,
"auto_elasticity_rhs.cpp"
),
"w"
)
as
file:
243
file.write(cpp)
244
245
with
open(os.path.join(path,
"auto_elasticity_rhs.hpp"
),
"w"
)
as
file:
246
file.write(hpp)
247
248
print(
"done!"
)
elasticity_rhs.hooke
hooke(disp_grad, def_grad)
Definition
elasticity_rhs.py:53
elasticity_rhs.sigma_fun
sigma_fun(j, ee, C, dim)
Definition
elasticity_rhs.py:27
elasticity_rhs.saint_venant
saint_venant(disp_grad, def_grad)
Definition
elasticity_rhs.py:80
elasticity_rhs.linear_elasticity
linear_elasticity(disp_grad, def_grad)
Definition
elasticity_rhs.py:36
elasticity_rhs.Det
Det(mat)
Definition
elasticity_rhs.py:13
elasticity_rhs.parse_args
parse_args()
Definition
elasticity_rhs.py:146
elasticity_rhs.neo_hookean
neo_hookean(disp_grad, def_grad)
Definition
elasticity_rhs.py:109
elasticity_rhs.divergence
divergence(sigma)
Definition
elasticity_rhs.py:130
pretty_print.C99_print
C99_print(expr)
Definition
pretty_print.py:8
matrices
src
polyfem
autogen
elasticity_rhs.py
Generated by
1.9.8