FEM: solver object is used to write the eigenmode params to input file

This commit is contained in:
Bernd Hahnebach 2016-08-08 06:25:30 +02:00
parent eeed00b409
commit c476bcfeb0
8 changed files with 25 additions and 64 deletions

View File

@ -49,8 +49,7 @@ class FemInputWriter():
selfweight_obj, force_obj, pressure_obj, selfweight_obj, force_obj, pressure_obj,
temperature_obj, heatflux_obj, initialtemperature_obj, temperature_obj, heatflux_obj, initialtemperature_obj,
beamsection_obj, shellthickness_obj, beamsection_obj, shellthickness_obj,
analysis_type, eigenmode_parameters, analysis_type, dir_name
dir_name
): ):
self.analysis = analysis_obj self.analysis = analysis_obj
self.solver_obj = solver_obj self.solver_obj = solver_obj
@ -69,10 +68,6 @@ class FemInputWriter():
self.beamsection_objects = beamsection_obj self.beamsection_objects = beamsection_obj
self.shellthickness_objects = shellthickness_obj self.shellthickness_objects = shellthickness_obj
self.analysis_type = analysis_type self.analysis_type = analysis_type
if eigenmode_parameters:
self.no_of_eigenfrequencies = eigenmode_parameters[0]
self.eigenfrequeny_range_low = eigenmode_parameters[1]
self.eigenfrequeny_range_high = eigenmode_parameters[2]
self.dir_name = dir_name self.dir_name = dir_name
if not dir_name: if not dir_name:
print('Error: FemInputWriter has no working_dir --> we gone make a temporary one!') print('Error: FemInputWriter has no working_dir --> we gone make a temporary one!')

View File

@ -44,8 +44,7 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
selfweight_obj, force_obj, pressure_obj, selfweight_obj, force_obj, pressure_obj,
temperature_obj, heatflux_obj, initialtemperature_obj, temperature_obj, heatflux_obj, initialtemperature_obj,
beamsection_obj, shellthickness_obj, beamsection_obj, shellthickness_obj,
analysis_type=None, eigenmode_parameters=None, analysis_type=None, dir_name=None
dir_name=None
): ):
FemInputWriter.FemInputWriter.__init__( FemInputWriter.FemInputWriter.__init__(
@ -57,8 +56,7 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
selfweight_obj, force_obj, pressure_obj, selfweight_obj, force_obj, pressure_obj,
temperature_obj, heatflux_obj, initialtemperature_obj, temperature_obj, heatflux_obj, initialtemperature_obj,
beamsection_obj, shellthickness_obj, beamsection_obj, shellthickness_obj,
analysis_type, eigenmode_parameters, analysis_type, dir_name)
dir_name)
self.file_name = self.dir_name + '/' + self.mesh_object.Name + '.inp' self.file_name = self.dir_name + '/' + self.mesh_object.Name + '.inp'
print('FemInputWriterCcx --> self.dir_name --> ' + self.dir_name) print('FemInputWriterCcx --> self.dir_name --> ' + self.dir_name)
print('FemInputWriterCcx --> self.file_name --> ' + self.file_name) print('FemInputWriterCcx --> self.file_name --> ' + self.file_name)
@ -567,7 +565,7 @@ class FemInputWriterCcx(FemInputWriter.FemInputWriter):
f.write('** Frequency analysis\n') f.write('** Frequency analysis\n')
f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name)) f.write('** written by {} function\n'.format(sys._getframe().f_code.co_name))
f.write('*FREQUENCY\n') f.write('*FREQUENCY\n')
f.write('{},{},{}\n'.format(self.no_of_eigenfrequencies, self.eigenfrequeny_range_low, self.eigenfrequeny_range_high)) f.write('{},{},{}\n'.format(self.solver_obj.EigenmodesCount, self.solver_obj.EigenmodeLowLimit, self.solver_obj.EigenmodeHighLimit))
def write_analysis_thermomech(self, f): def write_analysis_thermomech(self, f):
f.write('\n***********************************************************\n') f.write('\n***********************************************************\n')

View File

@ -41,8 +41,7 @@ class FemInputWriterZ88(FemInputWriter.FemInputWriter):
selfweight_obj, force_obj, pressure_obj, selfweight_obj, force_obj, pressure_obj,
temperature_obj, heatflux_obj, initialtemperature_obj, temperature_obj, heatflux_obj, initialtemperature_obj,
beamsection_obj, shellthickness_obj, beamsection_obj, shellthickness_obj,
analysis_type=None, eigenmode_parameters=None, analysis_type=None, dir_name=None
dir_name=None
): ):
FemInputWriter.FemInputWriter.__init__( FemInputWriter.FemInputWriter.__init__(
@ -54,8 +53,7 @@ class FemInputWriterZ88(FemInputWriter.FemInputWriter):
selfweight_obj, force_obj, pressure_obj, selfweight_obj, force_obj, pressure_obj,
temperature_obj, heatflux_obj, initialtemperature_obj, temperature_obj, heatflux_obj, initialtemperature_obj,
beamsection_obj, shellthickness_obj, beamsection_obj, shellthickness_obj,
analysis_type, eigenmode_parameters, analysis_type, dir_name)
dir_name)
self.file_name = self.dir_name + '/z88' self.file_name = self.dir_name + '/z88'
print('FemInputWriterZ88 --> self.dir_name --> ' + self.dir_name) print('FemInputWriterZ88 --> self.dir_name --> ' + self.dir_name)
print('FemInputWriterZ88 --> self.file_name --> ' + self.file_name) print('FemInputWriterZ88 --> self.file_name --> ' + self.file_name)

View File

@ -290,6 +290,7 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
def check_prerequisites(self): def check_prerequisites(self):
message = "" message = ""
# analysis
if not self.analysis: if not self.analysis:
message += "No active Analysis\n" message += "No active Analysis\n"
if self.analysis_type not in self.known_analysis_types: if self.analysis_type not in self.known_analysis_types:
@ -299,6 +300,18 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
import os import os
if not (os.path.isdir(self.working_dir)): if not (os.path.isdir(self.working_dir)):
message += "Working directory \'{}\' doesn't exist.".format(self.working_dir) message += "Working directory \'{}\' doesn't exist.".format(self.working_dir)
# solver
if not self.solver:
message += "No solver object defined in the analysis\n"
else:
if self.analysis_type == "frequency":
if not hasattr(self.solver, "EigenmodeHighLimit"):
message += "Frequency analysis: Solver has no EigenmodeHighLimit.\n"
elif not hasattr(self.solver, "EigenmodeLowLimit"):
message += "Frequency analysis: Solver has no EigenmodeLowLimit.\n"
elif not hasattr(self.solver, "EigenmodesCount"):
message += "Frequency analysis: Solver has no EigenmodesCount.\n"
# mesh
if not self.mesh: if not self.mesh:
message += "No mesh object defined in the analysis\n" message += "No mesh object defined in the analysis\n"
if self.mesh: if self.mesh:
@ -356,43 +369,6 @@ class FemTools(QtCore.QRunnable, QtCore.QObject):
message += "Shell thicknesses defined but FEM mesh has no shell elements.\n" message += "Shell thicknesses defined but FEM mesh has no shell elements.\n"
return message return message
## Sets eigenmode parameters for CalculiX frequency analysis
# @param self The python object self
# @param number number of eigenmodes that wll be calculated, default read for FEM prefs or 10 if not set in the FEM prefs
# @param limit_low lower value of requested eigenfrequency range, default read for FEM prefs or 0.0 if not set in the FEM prefs
# @param limit_high higher value of requested eigenfrequency range, default read for FEM prefs or 1000000.o if not set in the FEM prefs
def set_eigenmode_parameters(self, number=None, limit_low=None, limit_high=None):
self.fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem")
if number is not None:
_number = number
else:
try:
_number = self.solver.EigenmodesCount
except:
#Not yet in prefs, so it will always default to 10
_number = self.fem_prefs.GetInteger("EigenmodesCount", 10)
if _number < 1:
_number = 1
if limit_low is not None:
_limit_low = limit_low
else:
try:
_limit_low = self.solver.EigenmodeLowLimit
except:
#Not yet in prefs, so it will always default to 0.0
_limit_low = self.fem_prefs.GetFloat("EigenmodeLowLimit", 0.0)
if limit_high is not None:
_limit_high = limit_high
else:
try:
_limit_high = self.solver.EigenmodeHighLimit
except:
#Not yet in prefs, so it will always default to 1000000.0
_limit_high = self.fem_prefs.GetFloat("EigenmodeHighLimit", 1000000.0)
self.eigenmode_parameters = (_number, _limit_low, _limit_high)
## Sets base_name ## Sets base_name
# @param self The python object self # @param self The python object self
# @param base_name base name of .inp/.frd file (without extension). It is used to construct .inp file path that is passed to CalculiX ccx # @param base_name base name of .inp/.frd file (without extension). It is used to construct .inp file path that is passed to CalculiX ccx

View File

@ -69,7 +69,6 @@ class FemToolsCcx(FemTools.FemTools):
self.results_present = False self.results_present = False
if self.solver: if self.solver:
self.set_analysis_type() self.set_analysis_type()
self.set_eigenmode_parameters()
self.setup_working_dir() self.setup_working_dir()
else: else:
raise Exception('FEM: No solver found!') raise Exception('FEM: No solver found!')
@ -95,8 +94,7 @@ class FemToolsCcx(FemTools.FemTools):
self.selfweight_constraints, self.force_constraints, self.pressure_constraints, self.selfweight_constraints, self.force_constraints, self.pressure_constraints,
self.temperature_constraints, self.heatflux_constraints, self.initialtemperature_constraints, self.temperature_constraints, self.heatflux_constraints, self.initialtemperature_constraints,
self.beam_sections, self.shell_thicknesses, self.beam_sections, self.shell_thicknesses,
self.analysis_type, self.eigenmode_parameters, self.analysis_type, self.working_dir)
self.working_dir)
self.inp_file_name = inp_writer.write_calculix_input_file() self.inp_file_name = inp_writer.write_calculix_input_file()
except: except:
print("Unexpected error when writing CalculiX input file:", sys.exc_info()[0]) print("Unexpected error when writing CalculiX input file:", sys.exc_info()[0])

View File

@ -88,8 +88,7 @@ class FemToolsZ88(FemTools.FemTools):
self.selfweight_constraints, self.force_constraints, self.pressure_constraints, self.selfweight_constraints, self.force_constraints, self.pressure_constraints,
self.temperature_constraints, self.heatflux_constraints, self.initialtemperature_constraints, self.temperature_constraints, self.heatflux_constraints, self.initialtemperature_constraints,
self.beam_sections, self.shell_thicknesses, self.beam_sections, self.shell_thicknesses,
self.analysis_type, None, self.analysis_type, self.working_dir)
self.working_dir)
self.inp_file_name = inp_writer.write_z88_input() self.inp_file_name = inp_writer.write_z88_input()
except: except:
print("Unexpected error when writing Z88 input files:", sys.exc_info()[0]) print("Unexpected error when writing Z88 input files:", sys.exc_info()[0])

View File

@ -85,6 +85,9 @@ class FemTest(unittest.TestCase):
self.solver_object.SteadyState = True self.solver_object.SteadyState = True
self.solver_object.MatrixSolverType = 'default' self.solver_object.MatrixSolverType = 'default'
self.solver_object.IterationsControlParameterTimeUse = False self.solver_object.IterationsControlParameterTimeUse = False
self.solver_object.EigenmodesCount = 10
self.solver_object.EigenmodeHighLimit = 1000000.0
self.solver_object.EigenmodeLowLimit = 0.0
self.active_doc.recompute() self.active_doc.recompute()
def create_new_mesh(self): def create_new_mesh(self):
@ -269,11 +272,6 @@ class FemTest(unittest.TestCase):
self.assertTrue(True if fea.working_dir == frequency_analysis_dir else False, self.assertTrue(True if fea.working_dir == frequency_analysis_dir else False,
"Setting working directory {} failed".format(frequency_analysis_dir)) "Setting working directory {} failed".format(frequency_analysis_dir))
fcc_print('Setting eigenmode calculation parameters')
fea.set_eigenmode_parameters(number=10, limit_low=0.0, limit_high=1000000.0)
self.assertTrue(True if fea.eigenmode_parameters == (10, 0.0, 1000000.0) else False,
"Setting eigenmode calculation parameters failed")
fcc_print('Checking FEM inp file prerequisites for frequency analysis...') fcc_print('Checking FEM inp file prerequisites for frequency analysis...')
error = fea.check_prerequisites() error = fea.check_prerequisites()
self.assertFalse(error, "FemToolsCcx check_prerequisites returned error message: {}".format(error)) self.assertFalse(error, "FemToolsCcx check_prerequisites returned error message: {}".format(error))
@ -569,7 +567,7 @@ def create_cube_test_results():
# frequency # frequency
fea.reset_all() fea.reset_all()
fea.set_analysis_type('frequency') fea.set_analysis_type('frequency')
fea.set_eigenmode_parameters(1) # we should only have one result object fea.solver.EigenmodesCount = 1 # we should only have one result object
fea.run() fea.run()
fea.load_results() fea.load_results()

View File

@ -65,7 +65,6 @@ class _FemSolverCalculix():
obj.EigenmodesCount = (noe, 1, 100, 1) obj.EigenmodesCount = (noe, 1, 100, 1)
obj.addProperty("App::PropertyFloatConstraint", "EigenmodeLowLimit", "Fem", "Low frequency limit for eigenmode calculations") obj.addProperty("App::PropertyFloatConstraint", "EigenmodeLowLimit", "Fem", "Low frequency limit for eigenmode calculations")
# Not yet in prefs, so it will always default to 0.0
ell = ccx_prefs.GetFloat("EigenmodeLowLimit", 0.0) ell = ccx_prefs.GetFloat("EigenmodeLowLimit", 0.0)
obj.EigenmodeLowLimit = (ell, 0.0, 1000000.0, 10000.0) obj.EigenmodeLowLimit = (ell, 0.0, 1000000.0, 10000.0)