Skip to content

Commit

Permalink
FEM: ccx writer, better handling of different analysis types
Browse files Browse the repository at this point in the history
  • Loading branch information
berndhahnebach committed Feb 6, 2017
1 parent 4610840 commit d444ca1
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 88 deletions.
130 changes: 57 additions & 73 deletions src/Mod/Fem/FemInputWriterCcx.py
Expand Up @@ -109,14 +109,7 @@ def write_calculix_one_input_file(self):
self.write_constraints_transform(inpfile)

# step begin
if self.analysis_type == "frequency":
self.write_step_begin_static_frequency(inpfile)
self.write_analysis_frequency(inpfile)
elif self.analysis_type == "static":
self.write_step_begin_static_frequency(inpfile)
elif self.analysis_type == "thermomech":
self.write_step_begin_thermomech(inpfile)
self.write_analysis_thermomech(inpfile)
self.write_step_begin(inpfile)

# constraints depend on step used in all analysis types
if self.fixed_objects:
Expand Down Expand Up @@ -254,14 +247,7 @@ def write_calculix_splitted_input_file(self):
self.write_constraints_transform(inpfileMain)

# step begin
if self.analysis_type == "frequency":
self.write_step_begin_static_frequency(inpfileMain)
self.write_analysis_frequency(inpfileMain)
elif self.analysis_type == "static":
self.write_step_begin_static_frequency(inpfileMain)
elif self.analysis_type == "thermomech":
self.write_step_begin_thermomech(inpfileMain)
self.write_analysis_thermomech(inpfileMain)
self.write_step_begin(inpfileMain)

# constraints depend on step used in all analysis types
if self.fixed_objects:
Expand Down Expand Up @@ -576,77 +562,75 @@ def write_femelementsets(self, f):
setion_def = '*SOLID SECTION, ' + elsetdef + material + '\n'
f.write(setion_def)

def write_step_begin_static_frequency(self, f):
def write_step_begin(self, f):
f.write('\n***********************************************************\n')
f.write('** One step is needed to run the mechanical analysis of FreeCAD\n')
f.write('** At least one step is needed to run an CalculiX analysis of FreeCAD\n')
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
static_frequency_step = '*STEP'
if self.solver_obj.GeometricalNonlinearity == "nonlinear" and self.analysis_type == 'static':
static_frequency_step += ', NLGEOM' # https://www.comsol.com/blogs/what-is-geometric-nonlinearity/
elif self.solver_obj.GeometricalNonlinearity == "nonlinear" and self.analysis_type == 'frequency':
print('Analysis type frequency and geometrical nonlinear analyis are not allowed together, linear is used instead!')
f.write(static_frequency_step + '\n')
if self.solver_obj.IterationsControlParameterTimeUse:
f.write('*CONTROLS, PARAMETERS=TIME INCREMENTATION\n')
f.write(self.solver_obj.IterationsControlParameterIter + '\n')
f.write(self.solver_obj.IterationsControlParameterCutb + '\n')
analysis_static = '*STATIC'
if self.solver_obj.MatrixSolverType == "default":
pass
elif self.solver_obj.MatrixSolverType == "spooles":
analysis_static += ', SOLVER=SPOOLES'
elif self.solver_obj.MatrixSolverType == "iterativescaling":
analysis_static += ', SOLVER=ITERATIVE SCALING'
elif self.solver_obj.MatrixSolverType == "iterativecholesky":
analysis_static += ', SOLVER=ITERATIVE CHOLESKY'
if self.solver_obj.IterationsUserDefinedIncrementations:
analysis_static += ', DIRECT'
f.write(analysis_static + '\n')
if self.solver_obj.IterationsUserDefinedIncrementations:
f.write(self.solver_obj.IterationsUserDefinedTimeStepLength + '\n')

def write_step_begin_thermomech(self, f):
f.write('\n***********************************************************\n')
f.write('** One step is needed to run the thermomechanical analysis of FreeCAD\n')
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
thermomech_step = '*STEP'
# STEP line
step = '*STEP'
if self.solver_obj.GeometricalNonlinearity == "nonlinear":
thermomech_step += ', NLGEOM'
if self.analysis_type == 'static' or self.analysis_type == 'thermomech':
step += ', NLGEOM' # https://www.comsol.com/blogs/what-is-geometric-nonlinearity/
elif self.analysis_type == 'frequency':
print('Analysis type frequency and geometrical nonlinear analyis are not allowed together, linear is used instead!')
if self.solver_obj.IterationsThermoMechMaximum:
thermomech_step += ', INC=' + str(self.solver_obj.IterationsThermoMechMaximum)
f.write(thermomech_step + '\n')
if self.analysis_type == 'thermomech':
step += ', INC=' + str(self.solver_obj.IterationsThermoMechMaximum)
elif self.analysis_type == 'static' or self.analysis_type == 'frequency':
pass # not supported for stati and frequency, ... really ?
# write step line
f.write(step + '\n')
# CONTROLS line
# all analyis types, ... really in frequency too?!?
if self.solver_obj.IterationsControlParameterTimeUse:
f.write('*CONTROLS, PARAMETERS=TIME INCREMENTATION\n')
f.write(self.solver_obj.IterationsControlParameterIter + '\n')
f.write(self.solver_obj.IterationsControlParameterCutb + '\n')

def write_analysis_frequency(self, f):
f.write('\n***********************************************************\n')
f.write('** Frequency analysis\n')
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
f.write('*FREQUENCY\n')
f.write('{},{},{}\n'.format(self.solver_obj.EigenmodesCount, self.solver_obj.EigenmodeLowLimit, self.solver_obj.EigenmodeHighLimit))

def write_analysis_thermomech(self, f):
f.write('\n***********************************************************\n')
f.write('** Coupled temperature displacement analysis\n')
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
thermomech_analysis = '*COUPLED TEMPERATURE-DISPLACEMENT'
# ANALYSIS type line
# analysis line --> analysis type
if self.analysis_type == 'static':
analysis_type = '*STATIC'
elif self.analysis_type == 'frequency':
analysis_type = '*FREQUENCY'
elif self.analysis_type == 'thermomech':
analysis_type = '*COUPLED TEMPERATURE-DISPLACEMENT'
# analysis line --> solver type
if self.solver_obj.MatrixSolverType == "default":
pass
elif self.solver_obj.MatrixSolverType == "spooles":
thermomech_analysis += ', SOLVER=SPOOLES'
analysis_type += ', SOLVER=SPOOLES'
elif self.solver_obj.MatrixSolverType == "iterativescaling":
thermomech_analysis += ', SOLVER=ITERATIVE SCALING'
analysis_type += ', SOLVER=ITERATIVE SCALING'
elif self.solver_obj.MatrixSolverType == "iterativecholesky":
thermomech_analysis += ', SOLVER=ITERATIVE CHOLESKY'
analysis_type += ', SOLVER=ITERATIVE CHOLESKY'
# analysis line --> user defined incrementations --> parameter DIRECT
if self.solver_obj.IterationsUserDefinedIncrementations:
if self.analysis_type == 'static': # it would be possible in thermomech too IMHO (bernd)
analysis_type += ', DIRECT'
elif self.analysis_type == 'thermomech':
print('IterationsUserDefinedIncrementations not implemented for thermomech at the moment')
elif self.analysis_type == 'frequency':
print('Analysis type frequency and IterationsUserDefinedIncrementations are not allowed together, it is ignored')
# analysis line --> steadystate --> thermomech only
if self.solver_obj.ThermoMechSteadyState:
thermomech_analysis += ', STEADY STATE'
self.solver_obj.TimeInitialStep = 1.0 # Set time to 1 and ignore user inputs for steady state
self.solver_obj.TimeEnd = 1.0
thermomech_time = '{},{}'.format(self.solver_obj.TimeInitialStep, self.solver_obj.TimeEnd) # OvG: 1.0 increment, total time 1 for steady state will cut back automatically
f.write(thermomech_analysis + '\n')
f.write(thermomech_time + '\n')
if self.analysis_type == 'thermomech':
analysis_type += ', STEADY STATE'
self.solver_obj.TimeInitialStep = 1.0 # Set time to 1 and ignore user inputs for steady state
self.solver_obj.TimeEnd = 1.0
elif self.analysis_type == 'static' or self.analysis_type == 'frequency':
pass # not supported for static and frequency!
# ANALYSIS paramter line
analysis_parameter = ''
if self.analysis_type == 'static':
if self.solver_obj.IterationsUserDefinedIncrementations:
analysis_parameter = self.solver_obj.IterationsUserDefinedTimeStepLength
elif self.analysis_type == 'frequency':
analysis_parameter = '{},{},{}\n'.format(self.solver_obj.EigenmodesCount, self.solver_obj.EigenmodeLowLimit, self.solver_obj.EigenmodeHighLimit)
elif self.analysis_type == 'thermomech':
analysis_parameter = '{},{}'.format(self.solver_obj.TimeInitialStep, self.solver_obj.TimeEnd) # OvG: 1.0 increment, total time 1 for steady state will cut back automatically
# write analysis type line, analysis parameter line
f.write(analysis_type + '\n')
f.write(analysis_parameter + '\n')

def write_constraints_fixed(self, f):
f.write('\n***********************************************************\n')
Expand Down
10 changes: 3 additions & 7 deletions src/Mod/Fem/test_files/ccx/cube_frequency.inp
Expand Up @@ -482,17 +482,13 @@ Eall
*SOLID SECTION, ELSET=MechanicalMaterialSolid, MATERIAL=MechanicalMaterial

***********************************************************
** One step is needed to run the mechanical analysis of FreeCAD
** written by write_step_begin_static_frequency function
** At least one step is needed to run an CalculiX analysis of FreeCAD
** written by write_step_begin function
*STEP
*STATIC

***********************************************************
** Frequency analysis
** written by write_analysis_frequency function
*FREQUENCY
10,0.0,1000000.0


***********************************************************
** Fixed Constraints
** written by write_constraints_fixed function
Expand Down
5 changes: 3 additions & 2 deletions src/Mod/Fem/test_files/ccx/cube_static.inp
Expand Up @@ -479,11 +479,12 @@ Eall
*SOLID SECTION, ELSET=MechanicalMaterialSolid, MATERIAL=MechanicalMaterial

***********************************************************
** One step is needed to run the mechanical analysis of FreeCAD
** written by write_step_begin_static_frequency function
** At least one step is needed to run an CalculiX analysis of FreeCAD
** written by write_step_begin function
*STEP
*STATIC


***********************************************************
** Fixed Constraints
** written by write_constraints_fixed function
Expand Down
8 changes: 2 additions & 6 deletions src/Mod/Fem/test_files/ccx/spine_thermomech.inp
Expand Up @@ -123,16 +123,12 @@ Nall,300.0
*SOLID SECTION, ELSET=MechanicalMaterialSolid, MATERIAL=MechanicalMaterial

***********************************************************
** One step is needed to run the thermomechanical analysis of FreeCAD
** written by write_step_begin_thermomech function
** At least one step is needed to run an CalculiX analysis of FreeCAD
** written by write_step_begin function
*STEP, INC=2000
*CONTROLS, PARAMETERS=TIME INCREMENTATION
4,8,9,200,10,400,,200,,
0.25,0.5,0.75,0.85,,,1.5,

***********************************************************
** Coupled temperature displacement analysis
** written by write_analysis_thermomech function
*COUPLED TEMPERATURE-DISPLACEMENT, STEADY STATE
1.0,1.0

Expand Down

0 comments on commit d444ca1

Please sign in to comment.