-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwriteinpfile.py
283 lines (239 loc) · 25.9 KB
/
writeinpfile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# -*- coding: utf-8 -*-
###################################################################################
#
# Copyright 2021 Jose Gabriel Egas Ortuno
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
#
###################################################################################
"""
This class reads the FreeCAD scripted objects and writes the adequate inpout file file to be executed by MBDyn.
The input file is stored as a text object within FreeCAD
"""
import FreeCAD
#import os
#from FreeCAD import Units
#__dir__ = os.path.dirname(__file__)
class Writeinpfile:
def __init__(self):
MBDyn = FreeCAD.ActiveDocument.getObject("MBDyn")#Get the simulation scripted object
ControlData = FreeCAD.ActiveDocument.getObject("ControlData")#Get the simulation scripted object
gravity = FreeCAD.ActiveDocument.getObjectsByLabel("gravity")#Get the gravity object. If len is zero, there is no gravity
#Retrieve all the structural nodes, rigid bodies, joints, etc:
StructuralNodes = []
NumberStructuralNodes = 0
RigidBodies = []
NumberRigidBodies = 0
Joints = []
NumberJoints = 0
Forces = []
NumberForces = 0
precission = int(FreeCAD.ActiveDocument.getObjectsByLabel('MBDyn')[0].precision) #Max number of decimal places used when writing the .mbd file with values obtained from the CAD file
#Count nodes, bodies and joints:
for obj in FreeCAD.ActiveDocument.Objects:
if obj.Label.startswith('structural'):#Get all the structural nodes
StructuralNodes.append(obj)
if obj.Label.startswith('body'):
if(obj.type=='rigid'):#Only rigid bodies go into the .imp file. Dummy bodies can exist in the CAD, these are used only for the animation for example of static and dymmy nodes.
RigidBodies.append(obj)
if obj.Label.startswith('joint'):#Get all the joints
Joints.append(obj)
if obj.Label.startswith('force'):#Get all the joints
Forces.append(obj)
NumberStructuralNodes = len(StructuralNodes)
NumberRigidBodies = len(RigidBodies)
NumberJoints = len(Joints)
NumberForces = len(Forces)
listlines = []
listlines.append('###################################################################################################################### \n')
listlines.append('# MBDyn is a free and open-source general purpose multi-body dynamics software. See https://www.mbdyn.org/ for details. \n')
listlines.append('# This input file was automatically generated by the FreeCAD dynamics workbench. \n')
listlines.append('# To learn more about MBDyn input files, you can visit the website: https://www.sky-engin.jp/en/MBDynTutorial/index.html \n')
listlines.append('# Details about the structure of input files can be studied in the input file manuals: https://www.mbdyn.org/?Software_Download \n')
listlines.append('# Although MBDyn has already reached a mature stage and is used by several industries, \n')
listlines.append('# the FreeCAD dynamics workbench is still under development, and it is likely to have bugs. \n')
listlines.append('# Please be aware of this fact before you decide to use this input file for any critical application. \n')
listlines.append('# If you think you have found a bug or have any suggestion, please send your comments to Jose Egas: \n')
listlines.append('# [email protected] \n')
listlines.append('###################################################################################################################### \n\n')
listlines.append('# [Data Block]\n\n')
listlines.append('begin: data;\n')
listlines.append(' problem: initial value;\n')
listlines.append('end: data;\n\n')
listlines.append('#-----------------------------------------------------------------------------\n')
listlines.append('# [Problem Block]\n\n')
listlines.append('begin: initial value;\n')
listlines.append(' initial time: '+MBDyn.initial_time[:-2]+';\n')
listlines.append(' final time: '+MBDyn.final_time[:-2]+';\n')
listlines.append(' time step: '+MBDyn.time_step[:-2]+';\n')
listlines.append(' max iterations: '+MBDyn.max_iterations+';\n')
listlines.append(' tolerance: '+MBDyn.tolerance+';\n')
listlines.append(' derivatives tolerance: '+MBDyn.derivatives_tolerance+';\n')
listlines.append(' derivatives max iterations: '+MBDyn.derivatives_max_iterations+';\n')
listlines.append('end: initial value;\n\n')
listlines.append('#-----------------------------------------------------------------------------\n')
listlines.append('# [Control Data Block]\n\n')
listlines.append('begin: control data;\n')
listlines.append(' default orientation: euler321;\n')
listlines.append(' initial stiffness: '+str(ControlData.initial_position_stiffness)+', '+str(ControlData.initial_velocity_stiffness)+';\n')
if(ControlData.output_frequency != 'none'):
listlines.append(' output frequency: '+str(ControlData.output_frequency)+';\n')
if(ControlData.skip_initial_joint_assembly == 'true'):
listlines.append(' skip initial joint assembly;\n')
listlines.append(' structural nodes: '+str(NumberStructuralNodes)+';\n')
listlines.append(' rigid bodies: '+str(NumberRigidBodies)+';\n')
if(len(Joints)>0):
listlines.append(' joints: '+str(NumberJoints)+';\n')
if(len(Forces)>0):
listlines.append(' forces: '+str(NumberForces)+';\n')
if(len(gravity)==1):
listlines.append(' gravity;\n')
listlines.append('end: control data;\n\n')
listlines.append('#-----------------------------------------------------------------------------\n')
listlines.append('# [Nodes Block]\n\n')
listlines.append('begin: nodes;\n')
for x in range(0, len(StructuralNodes)):
if(StructuralNodes[x].type=='dynamic'):#Write all structural dynamic nodes
listlines.append(' structural: '+StructuralNodes[x].label+', # node label\n')
listlines.append(' dynamic,\n')
listlines.append(' '+str(round(StructuralNodes[x].position_X.getValueAs('m').Value,precission))+', '+str(round(StructuralNodes[x].position_Y.getValueAs('m').Value,precission))+', '+str(round(StructuralNodes[x].position_Z.getValueAs('m').Value,precission))+', # absolute position in meters\n')
listlines.append(' euler, '+str(round(StructuralNodes[x].yaw.getValueAs('rad').Value,precission))+', '+str(round(StructuralNodes[x].pitch.getValueAs('rad').Value,precission))+', '+str(round(StructuralNodes[x].roll.getValueAs('rad').Value,precission))+', # absolute orientation in radians\n')
listlines.append(' '+str(round(StructuralNodes[x].velocity_X.getValueAs('m/s').Value,precission))+', '+str(round(StructuralNodes[x].velocity_Y.getValueAs('m/s').Value,precission))+', '+str(round(StructuralNodes[x].velocity_Z.getValueAs('m/s').Value,precission))+', # absolute velocity in meters per second\n')
listlines.append(' '+str(round(FreeCAD.Units.Quantity(StructuralNodes[x].angular_velocity_X).getValueAs('rad/s').Value,precission))+', '+str(round(FreeCAD.Units.Quantity(StructuralNodes[x].angular_velocity_Y).getValueAs('rad/s').Value,precission))+', '+str(round(FreeCAD.Units.Quantity(StructuralNodes[x].angular_velocity_Z).getValueAs('rad/s').Value,precission))+'; # absolute angular velocity in radians per second\n\n')
if(StructuralNodes[x].type=='static'):#Write all structural static nodes
listlines.append(' structural: '+StructuralNodes[x].label+', # node label\n')
listlines.append(' static,\n')
listlines.append(' '+str(round(StructuralNodes[x].position_X.getValueAs('m').Value,precission))+', '+str(round(StructuralNodes[x].position_Y.getValueAs('m').Value,precission))+', '+str(round(StructuralNodes[x].position_Z.getValueAs('m').Value,precission))+', # absolute position in meters\n')
listlines.append(' euler, '+str(round(StructuralNodes[x].yaw.getValueAs('rad').Value,precission))+', '+str(round(StructuralNodes[x].pitch.getValueAs('rad').Value,precission))+', '+str(round(StructuralNodes[x].roll.getValueAs('rad').Value,precission))+', # absolute orientation in radians\n')
listlines.append(' '+str(round(StructuralNodes[x].velocity_X.getValueAs('m/s').Value,precission))+', '+str(round(StructuralNodes[x].velocity_Y.getValueAs('m/s').Value,precission))+', '+str(round(StructuralNodes[x].velocity_Z.getValueAs('m/s').Value,precission))+', # absolute velocity in meters per second\n')
listlines.append(' '+str(round(FreeCAD.Units.Quantity(StructuralNodes[x].angular_velocity_X).getValueAs('rad/s').Value,precission))+', '+str(round(FreeCAD.Units.Quantity(StructuralNodes[x].angular_velocity_Y).getValueAs('rad/s').Value,precission))+', '+str(round(FreeCAD.Units.Quantity(StructuralNodes[x].angular_velocity_Z).getValueAs('rad/s').Value,precission))+'; # absolute angular velocity in radians per second\n\n')
if(StructuralNodes[x].type=='dummy'):#Write all dummy nodes
listlines.append(' structural: '+StructuralNodes[x].label+', # node label\n')
listlines.append(' dummy,\n')
listlines.append(' '+StructuralNodes[x].base_node+', # base node\n')
listlines.append(' offset,\n')
listlines.append(' '+str(round(StructuralNodes[x].relative_offset_X.getValueAs('m').Value,precission))+', '+str(round(StructuralNodes[x].relative_offset_Y.getValueAs('m').Value,precission))+', '+str(round(StructuralNodes[x].relative_offset_Z.getValueAs('m').Value,precission))+', # offset relative to the base node\n')
listlines.append(' eye; # orientation relative to the base node\n\n')
listlines.append('end: nodes;\n\n')
listlines.append('#-----------------------------------------------------------------------------\n')
listlines.append('# [Elements Block]\n\n')
listlines.append('begin: elements;\n')
for x in range(0, len(RigidBodies)):#Bodies.
listlines.append(' body: '+RigidBodies[x].label+', # body label\n')
listlines.append(' '+RigidBodies[x].node+', # base node label\n')
listlines.append(' '+str(round(FreeCAD.Units.Quantity(RigidBodies[x].mass).Value,precission))+', # body mass in kilograms\n')
listlines.append(' '+str(round(RigidBodies[x].relative_center_of_mass_X.getValueAs('m').Value,precission))+', '+str(round(RigidBodies[x].relative_center_of_mass_Y.getValueAs('m').Value,precission))+', '+str(round(RigidBodies[x].relative_center_of_mass_Z.getValueAs('m').Value,precission))+', # center of mass relative to the structural dynamic node, in meters\n')
listlines.append(' '+'diag, '+str(FreeCAD.Units.Quantity(RigidBodies[x].ixx).getValueAs('m^2*kg').Value)+', '+str(FreeCAD.Units.Quantity(RigidBodies[x].iyy).getValueAs('m^2*kg').Value)+', '+str(FreeCAD.Units.Quantity(RigidBodies[x].izz).getValueAs('m^2*kg').Value)+'; # inertia moments in kg*m^2\n\n')
#Joints:
if(len(Joints)>0):
for x in range(0, len(Joints)):
if(Joints[x].joint=='revolute pin'):#Revolute pins
listlines.append(' joint: '+Joints[x].label+', # joint label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node+', # asociated node\n')
listlines.append(' '+str(round(Joints[x].relative_offset_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_Z.getValueAs('m').Value,precission))+', # offset relative to the asociated node\n')
listlines.append(' hinge, euler, '+str(round(Joints[x].relative_orientation_roll.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].relative_orientation_pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].relative_orientation_yaw.getValueAs('rad').Value,precission))+', # relative axis orientation\n')
listlines.append(' '+str(round(Joints[x].position_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].position_Y.getValueAs('m').Value,precission))+' ,'+str(round(Joints[x].position_Z.getValueAs('m').Value,precission))+', # absolute pin position\n')
#listlines.append(' hinge,\n')
listlines.append(' hinge, euler, '+str(round(Joints[x].roll.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].yaw.getValueAs('rad').Value,precission))+'; # absolute pin orientation\n\n')
if(Joints[x].joint=='revolute hinge'):#Revolute hinges
listlines.append(' joint: '+Joints[x].label+', # hinge label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node_1+', # first asociated node\n')
listlines.append(' '+str(round(Joints[x].relative_offset_1_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_1_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_1_Z.getValueAs('m').Value,precission))+', # Relative offset 1\n')
listlines.append(' hinge, euler, '+str(round(Joints[x].relative_orientation_axis_1_roll.getValueAs('rad').Value,precission))+','+str(round(Joints[x].relative_orientation_axis_1_pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].relative_orientation_axis_1_yaw.getValueAs('rad').Value,precission))+', # relative axis orientation\n')
listlines.append(' '+Joints[x].node_2+', # second asociated node\n')
listlines.append(' '+str(round(Joints[x].relative_offset_2_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_2_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_2_Z.getValueAs('m').Value,precission))+', # Relative offset 2\n')
listlines.append(' hinge, euler, '+str(round(Joints[x].relative_orientation_axis_2_roll.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].relative_orientation_axis_2_pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].relative_orientation_axis_2_yaw.getValueAs('rad').Value,precission))+'; # relative axis orientation\n\n')
if(Joints[x].joint=='clamp'):#Revolute hinges
listlines.append(' joint: '+Joints[x].label+', # clamp label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node+', # asociated node\n')
listlines.append(' '+str(round(Joints[x].position_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].position_Y.getValueAs('m').Value,precission))+' ,'+str(round(Joints[x].position_Z.getValueAs('m').Value,precission))+', # absolute pin position\n')
listlines.append(' euler, '+str(round(Joints[x].yaw.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].roll.getValueAs('rad').Value,precission))+'; # absolute pin orientation\n\n')
if(Joints[x].joint=='axial rotation'):#Revolute hinges
listlines.append(' joint: '+Joints[x].label+', # joint label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].static_node+', # static node label\n')
listlines.append(' null, # offset relative to node 1\n')
listlines.append(' hinge, euler, '+str(round(Joints[x].yaw.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].roll.getValueAs('rad').Value,precission))+', # orientation relative to staic node\n')
listlines.append(' '+Joints[x].dynamic_node+', # dynamic node label\n')
listlines.append(' '+str(round(Joints[x].relative_offset_1_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_1_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_1_Z.getValueAs('m').Value,precission))+', # offset relative to the dynamic node\n')
listlines.append(' hinge, euler, '+str(round(Joints[x].yaw.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].roll.getValueAs('rad').Value,precission))+', # orientation relative to dynamic node\n')
listlines.append(' '+Joints[x].angular_velocity+'; # angular velocity function\n\n')
if(Joints[x].joint=='in line'):#in line joints
listlines.append(' joint: '+Joints[x].label+', # joint label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node_1+', # node 1\n')
listlines.append(' '+str(round(Joints[x].relative_line_position_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_line_position_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_line_position_Z.getValueAs('m').Value,precission))+', # relative line position\n')
listlines.append(' euler, pi*'+str(round(Joints[x].roll.Value/180.0,precission))+', pi*'+str(round(Joints[x].pitch.Value/180.0,precission))+', pi*'+str(round(Joints[x].yaw.Value/180.0,precission))+', # relative line orientation\n')
listlines.append(' '+Joints[x].node_2+', # node 2 (fixed to node 1)\n')
listlines.append(' offset, '+str(round(Joints[x].relative_offset_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_Z.getValueAs('m').Value,precission))+'; # relative offset\n\n')
if(Joints[x].joint=='in plane'):#in line joints
listlines.append(' joint: '+Joints[x].label+', # joint label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node_1+', # node 1\n')
listlines.append(' position,'+str(round(Joints[x].relative_plane_position_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_plane_position_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_plane_position_Z.getValueAs('m').Value,precission))+', # relative line position\n')
listlines.append(' '+Joints[x].relative_normal_direction+', # relative plane orientation\n')
listlines.append(' '+Joints[x].node_2+', # node 2 \n')
listlines.append(' offset, '+str(round(Joints[x].relative_offset_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_Z.getValueAs('m').Value,precission))+'; # relative offset\n\n')
if(Joints[x].joint=='prismatic'):#in line joints
listlines.append(' joint: '+Joints[x].label+', # joint label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node_1+', # node 1\n')
listlines.append(' '+Joints[x].node_2+'; # node 2 (aligned to node 1)\n\n')
if(Joints[x].joint=='deformable displacement joint'):#in line joints
listlines.append(' joint: '+Joints[x].label+', # joint label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node_1+', # node 1\n')
listlines.append(' null, # relative offset to 1 [m]\n')
listlines.append(' '+Joints[x].node_2+', # node 2\n')
listlines.append(' null, # relative offset to 2 [m]\n')
listlines.append(' linear viscoelastic isotropic,\n')
listlines.append(' '+Joints[x].stiffness[:-6]+', # spring stiffness in Newtons per meter\n')
listlines.append(' '+Joints[x].viscosity[:-4]+', # viscosity coefficient in Newtons-second per meter\n')
listlines.append(' prestrain, single, '+Joints[x].direction+', const, '+str(Joints[x].lenght.getValueAs('m')*-1)+'; #direction of oscillation and spring natural lenght in meters\n\n')
if(Joints[x].joint=='drive hinge'):#Drive hinges
sf = FreeCAD.ActiveDocument.getObjectsByLabel("scalar function: "+str(Joints[x].label))[0].Text
listlines.append(' joint: '+Joints[x].label+', # hinge label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node_1+', # first asociated node\n')
listlines.append(' hinge, euler, '+str(round(Joints[x].relative_orientation_axis_1_yaw.getValueAs('rad').Value,precission))+','+str(round(Joints[x].relative_orientation_axis_1_pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].relative_orientation_axis_1_roll.getValueAs('rad').Value,precission))+', # relative axis orientation\n')
listlines.append(' '+Joints[x].node_2+', # second asociated node\n')
listlines.append(' hinge, euler, '+str(round(Joints[x].relative_orientation_axis_2_yaw.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].relative_orientation_axis_2_pitch.getValueAs('rad').Value,precission))+', '+str(round(Joints[x].relative_orientation_axis_2_roll.getValueAs('rad').Value,precission))+', # relative axis orientation\n')
listlines.append(' single,'+ Joints[x].rotation_axis +', scalar function, ' + '"' + Joints[x].scalar_function + '"' + ', \n')
listlines.append(' multilinear,')
listlines.append(sf + '\n\n')
if(Joints[x].joint=='spherical hinge'):#Spherical hinges
listlines.append(' joint: '+Joints[x].label+', # hinge label\n')
listlines.append(' '+Joints[x].joint+',\n')
listlines.append(' '+Joints[x].node_1+', # first asociated node\n')
listlines.append(' '+str(round(Joints[x].relative_offset_X.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_Y.getValueAs('m').Value,precission))+', '+str(round(Joints[x].relative_offset_Z.getValueAs('m').Value,precission))+', '+ '# relatiive offset\n')
listlines.append(' '+Joints[x].node_2+', # second asociated node\n')
listlines.append(' null;\n\n')
#Forces:
for x in range(0, len(Forces)):
listlines.append(' force: '+Forces[x].label+', # force label\n')
listlines.append(' '+Forces[x].type+', # force type\n')
listlines.append(' '+Forces[x].node+', # node\n')
listlines.append(' position, '+Forces[x].position+', # relative arm\n')
listlines.append(' '+ Forces[x].force_type +', '+ Forces[x].direction +', ' + Forces[x].force_value+'; # force value\n\n')
if(len(gravity)==1):
listlines.append(' gravity: uniform, '+gravity[0].direction+', '+gravity[0].type+', '+gravity[0].g[:-6]+';\n\n')
listlines.append('end: elements;\n\n')
#Add all the lines to the FreeCAD text document
FreeCAD.ActiveDocument.getObject("input_file").Text = ' '.join(listlines)