Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerWorkflows/FreeCADBatchFEMTools/tests/variable_topology/variable_topology_generation.py
3206 views
1
"""
2
Geometry generation for with variable topology and solving test for
3
FreeCADBatchFEMTools - A library for using FreeCAD for FEM preprocessing in batch mode
4
5
Copyright 1st May 2018 - , Trafotek Oy, Finland
6
7
This library is free software; you can redistribute it and/or
8
modify it under the terms of the GNU Lesser General Public
9
License as published by the Free Software Foundation; either
10
version 2.1 of the License, or (at your option) any later version.
11
12
This library is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
Lesser General Public License for more details.
16
17
You should have received a copy of the GNU Lesser General Public
18
License along with this library (in file ../LGPL-2.1); if not, write
19
to the Free Software Foundation, Inc., 51 Franklin Street,
20
Fifth Floor, Boston, MA 02110-1301 USA
21
22
Authors: Eelis Takala, Janne Keranen
23
Emails: [email protected], [email protected]
24
Address: Trafotek Oy
25
Kaarinantie 700
26
20540 Turku
27
Finland
28
29
Original Date: May 2018
30
"""
31
doc = App.newDocument("Variable_geometry")
32
import os
33
import sys
34
import Part
35
import ObjectsFem
36
37
PWD = os.path.dirname(os.path.realpath(__file__))
38
module_path = PWD + "/../.."
39
sys.path.insert(0, module_path)
40
41
from FreeCADBatchFEMTools import fit_view
42
from FreeCADBatchFEMTools import pick_faces_from_geometry
43
from FreeCADBatchFEMTools import add_entity_in_list
44
from FreeCADBatchFEMTools import create_entities_dict
45
from FreeCADBatchFEMTools import merge_entities_dicts
46
from FreeCADBatchFEMTools import get_solids_from_entities_dict
47
from FreeCADBatchFEMTools import create_mesh_object_and_compound_filter
48
from FreeCADBatchFEMTools import find_boundaries_with_entities_dict
49
from FreeCADBatchFEMTools import find_bodies_with_entities_dict
50
from FreeCADBatchFEMTools import define_mesh_sizes
51
from FreeCADBatchFEMTools import create_mesh
52
from FreeCADBatchFEMTools import run_elmergrid
53
from FreeCADBatchFEMTools import remove_compare_faces_from_list
54
from FreeCADBatchFEMTools import faces_with_vertices_in_symmetry_plane
55
from FreeCADBatchFEMTools import create_xor_object
56
from FreeCADBatchFEMTools import reduce_half_symmetry
57
58
def create_bar(box_size, bar_length, center, name, symmetry_planes=None, mesh_size=None):
59
bar_obj = doc.addObject('Part::Box', name+'_obj')
60
bar_obj.Height = box_size
61
bar_obj.Width = bar_length
62
bar_obj.Length = box_size
63
bar_obj.Placement.Base = FreeCAD.Vector(center)- FreeCAD.Vector(box_size/2,0,box_size/2)
64
doc.recompute()
65
66
bar_obj = reduce_half_symmetry(bar_obj, name, App, doc, planes=symmetry_planes)
67
68
doc.recompute()
69
face_picks=[]
70
face_picks=[('alpha0',0),
71
('alpha1',5),
72
('beta0',3),
73
('beta1',1),
74
('gamma0',4),
75
('gamma1',2)]
76
77
faces = pick_faces_from_geometry(bar_obj, face_picks)
78
79
solids = []
80
add_entity_in_list(solids, name, bar_obj, {'mesh size':mesh_size})
81
entities_dict = create_entities_dict(name, faces, solids, main_object=bar_obj)
82
83
return entities_dict
84
85
def create_air(bars, x, y, z, name, symmetry_planes=None, mesh_size=None):
86
87
air_with_bars = doc.addObject('Part::Box', name+ '_whole')
88
air_with_bars.Height = z
89
air_with_bars.Width = y
90
air_with_bars.Length = x
91
air_with_bars.Placement.Base = FreeCAD.Vector(-x/2,-y/2,-z/2)
92
air_with_bars = reduce_half_symmetry(air_with_bars, name, App, doc, planes=symmetry_planes)
93
94
bar_objs = [bar['main object'] for bar in bars]
95
solid_objects = [air_with_bars]+bar_objs
96
97
air = create_xor_object(solid_objects, doc)
98
99
doc.recompute()
100
101
faces_in_symmetry_plane = faces_with_vertices_in_symmetry_plane(air.Shape.Faces, plane='zx')
102
103
# remove faces that belong to bar
104
bar_face_objects = []
105
for bar in bars:
106
bar_face_objects += [face_entity['geometric object'] for face_entity in bar['faces']]
107
108
remove_compare_faces_from_list(bar_face_objects, faces_in_symmetry_plane)
109
110
faces = []
111
add_entity_in_list(faces, 'gamma1', faces_in_symmetry_plane[0])
112
113
solids = []
114
add_entity_in_list(solids, name, air, {'mesh size':mesh_size})
115
entities_dict = create_entities_dict(name, faces, solids, main_object=air)
116
doc.recompute()
117
return entities_dict
118
119
120
def create_solids(model_parameters):
121
x = model_parameters['x']
122
y = model_parameters['y']
123
z = model_parameters['z']
124
n1 = model_parameters['n1']
125
n2 = model_parameters['n2']
126
box_size = model_parameters['box_size']
127
airgap = model_parameters['airgap']
128
default_mesh_size = model_parameters['default_mesh_size']
129
bar_mesh_sizes = model_parameters['bar_mesh_sizes']
130
air_mesh_sizes = model_parameters['air_mesh_sizes']
131
bar_centers = []
132
for j in range (0, n2):
133
for i in range (0, n1):
134
bar_centers.append(((airgap+box_size/2)+i*(airgap+box_size)-x/2,-y/2,(airgap+box_size/2)+j*(airgap+box_size)-z/2))
135
bars = []
136
for i,center in enumerate(bar_centers):
137
name = "bar_" + str(i)
138
bar = create_bar(box_size, y, center, name = name, symmetry_planes=['zx'], mesh_size=bar_mesh_sizes)
139
bars.append(bar)
140
141
air_entities = create_air(bars, x, y, z, name = 'air', symmetry_planes=['zx'], mesh_size=air_mesh_sizes)
142
143
entities_dicts = [air_entities] + bars
144
145
entities_dict = merge_entities_dicts(entities_dicts,
146
'variable_topology', default_mesh_size=default_mesh_size)
147
148
doc.recompute()
149
150
return entities_dict
151
152
def create_sif(model_parameters):
153
154
T_BC=model_parameters['T_BC']
155
n1=model_parameters['n1']
156
n2=model_parameters['n2']
157
158
filepart1='''
159
Header
160
CHECK KEYWORDS Warn
161
Mesh DB "." "variable_topology"
162
Include variable_topology/mesh.names
163
Results Directory ""
164
End
165
166
Simulation
167
Max Output Level = 5
168
Coordinate System = Cartesian !3D
169
Coordinate Mapping(3) = 1 2 3
170
171
Steady State Max Iterations = 1
172
Output Intervals = 1
173
Simulation Type = Steady state !Transient
174
Timestepping Method = BDF
175
BDF Order = 1
176
Post File = variable_topology.vtu
177
178
Timestep Sizes(1) = 0.1
179
Timestep Intervals(1) = 20
180
Output Intervals(1) = 1
181
182
End
183
184
185
Constants
186
Gravity(4) = 0 -1 0 9.82
187
Stefan Boltzmann = 5.67e-08
188
End
189
190
Body 1
191
Target Bodies(1) = $ air
192
Name = "Air"
193
Equation = 1
194
Material = 1
195
Initial Condition = 1
196
End
197
198
Body 2
199
Target Bodies('''
200
201
filepart1+=str(n1*n2)+ ') = $ '
202
203
for i in range (0, n1*n2-1):
204
filepart1=filepart1+'bar_'+str(i)+' \\ \n '
205
filepart1=filepart1+'bar_'+str(i+1)
206
207
filepart2='''
208
Name = "Bars"
209
Equation = 1
210
Material = 2
211
212
Initial Condition = 1
213
End
214
215
Solver 1
216
Equation = Heat Equation
217
Procedure = "HeatSolve" "HeatSolver"
218
Variable = Temperature
219
Exec Solver = Always
220
Stabilize = True
221
Bubbles = False
222
Lumped Mass Matrix = False
223
Optimize Bandwidth = True
224
Steady State Convergence Tolerance = 1.0e-5
225
Nonlinear System Convergence Tolerance = 1.0e-7
226
Nonlinear System Max Iterations = 1
227
Nonlinear System Newton After Iterations = 3
228
Nonlinear System Newton After Tolerance = 1.0e-3
229
Nonlinear System Relaxation Factor = 1
230
Linear System Solver = Iterative
231
Linear System Iterative Method = BiCGStab
232
Linear System Max Iterations = 500
233
Linear System Convergence Tolerance = 1.0e-10
234
BiCGstabl polynomial degree = 2
235
Linear System Preconditioning = ILU1
236
Linear System ILUT Tolerance = 1.0e-3
237
Linear System Abort Not Converged = False
238
Linear System Residual Output = 20
239
Linear System Precondition Recompute = 1
240
End
241
242
Solver 2
243
Exec Solver = Always
244
Equation = "save scalars"
245
Procedure = "SaveData" "SaveScalars"
246
! Variable 1 = Temperature
247
! Operator 1 = int mean
248
Variable 1 = Temperature
249
Operator 1 = max abs
250
Variable 2 = Temperature
251
Operator 2 = min abs
252
Variable 3 = Time
253
Filename = scalars.dat
254
End
255
256
Equation 1
257
Name = "HeatEquation"
258
Active Solvers(1) = 1
259
Convection = "constant"
260
End
261
262
Initial Condition 1
263
Name = "InitialState"
264
Temperature = 0.0
265
End
266
267
268
Material 1
269
Name = "Air"
270
Heat Conductivity = Real 1.0 !0.026
271
Density = Real 1.0 !1.1644
272
273
Heat Capacity = Real 1.0 !0.00121
274
End
275
276
Material 2
277
Name = "Copper"
278
Heat Conductivity = Real 1.0 !401
279
Density = Real 1.0 !8940
280
281
Heat Capacity = Real 1.0 !3.45
282
End
283
284
285
Boundary Condition 1
286
Target Boundaries(1) = $ air_gamma1
287
Name = "Symmetry_air"
288
289
Heat Flux = Real 0.0
290
End
291
292
'''
293
294
BCstring1='''
295
Boundary Condition '''
296
297
BCstring2='''
298
Target Boundaries(1) = $ bar_'''
299
300
BCstring3='''_gamma1
301
Name = "Bar '''
302
BCstring4=''' BC"
303
Temperature = Real '''
304
305
BCstring5='''
306
End
307
308
'''
309
310
filepart3=""
311
num=0
312
for j in range (0, n2):
313
for i in range (0, n1):
314
filepart3=filepart3+BCstring1+str(num+2)+BCstring2+str(num)+BCstring3+str(num)+BCstring4+str(T_BC[j][i])+BCstring5
315
num=num+1
316
317
export_path=PWD+u"/variable_topology.sif"
318
file = open(export_path, "w+")
319
file.write(filepart1+filepart2+filepart3)
320
file.close()
321
322
def get_test_params(test_number=1):
323
if test_number == 1:
324
n1=5
325
n2=2
326
T_BC=[[1.,2.,3.,4., 5.],[2.,3.,4.,5.,6.]]
327
elif test_number == 2:
328
n1=5
329
n2=3
330
T_BC=[[1.,2.,3.,4., 5.],[2.,3.,4.,5.,6.], [3.,4.,5.,6.,7.]]
331
elif test_number == 3:
332
n1=4
333
n2=2
334
T_BC=[[1.,2.,3.,4.],[2.,3.,4.,5.]]
335
elif test_number == 4:
336
n1=3
337
n2=3
338
T_BC=[[1.,2.,3.],[2.,3.,4.], [3.,4.,5]]
339
elif test_number == 5:
340
n1=10
341
n2=1
342
T_BC=[[1.,2.,3.,4., 5.,2.,3.,4.,5.,6.]]
343
elif test_number == 6:
344
n1=2
345
n2=1
346
T_BC=[[1.,6.]]
347
return n1, n2, T_BC
348
349
##### Tests #####
350
def test_all():
351
n1, n2, T_BC = get_test_params(6)
352
box_size=10.
353
airgap=5.
354
depth=25.
355
model_parameters = {}
356
model_parameters['n1']=n1
357
model_parameters['n2']=n2
358
model_parameters['box_size']=box_size
359
model_parameters['airgap']=airgap
360
model_parameters['T_BC']=T_BC
361
model_parameters['x'] =n1*box_size+(n1+1)*airgap
362
model_parameters['y'] =depth
363
model_parameters['z'] =n2*box_size+(n2+1)*airgap
364
model_parameters['default_mesh_size'] = 10 #If default mesh size is smaller than given mesh sizes, fallback value is used.
365
model_parameters['bar_mesh_sizes'] = 2
366
model_parameters['air_mesh_sizes'] = 2
367
368
default_mesh_size = model_parameters['default_mesh_size']
369
370
entities_dict = create_solids(model_parameters)
371
solid_objects = get_solids_from_entities_dict(entities_dict)
372
373
fit_view()
374
375
mesh_object, compound_filter = create_mesh_object_and_compound_filter(solid_objects, default_mesh_size, doc)
376
377
find_boundaries_with_entities_dict(mesh_object, compound_filter, entities_dict, doc)
378
find_bodies_with_entities_dict(mesh_object, compound_filter, entities_dict, doc)
379
380
define_mesh_sizes(mesh_object, compound_filter, entities_dict, doc)
381
create_mesh(mesh_object)
382
export_path=PWD+u"/variable_topology.unv"
383
run_elmergrid(export_path, mesh_object)
384
create_sif(model_parameters)
385
#################
386
387
test_all() #This test is with all the definitions and examples
388
if not FreeCAD.GuiUp:
389
exit()
390
391
392