FEM: tasks module for z88, mystran and calculix, code improvements
This commit is contained in:
@@ -51,7 +51,7 @@ _inputFileName = None
|
||||
class Check(run.Check):
|
||||
|
||||
def run(self):
|
||||
self.pushStatus("Checking analysis...\n")
|
||||
self.pushStatus("Checking analysis member...\n")
|
||||
self.check_mesh_exists()
|
||||
|
||||
# workaround use Calculix ccxtools pre checks
|
||||
@@ -73,13 +73,12 @@ class Prepare(run.Prepare):
|
||||
|
||||
def run(self):
|
||||
global _inputFileName
|
||||
self.pushStatus("Preparing input files...\n")
|
||||
|
||||
mesh_obj = membertools.get_mesh_to_solve(self.analysis)[0] # pre check done already
|
||||
self.pushStatus("Preparing input...\n")
|
||||
|
||||
# get mesh set data
|
||||
# TODO evaluate if it makes sense to add new task
|
||||
# between check and prepare to the solver frame work
|
||||
mesh_obj = membertools.get_mesh_to_solve(self.analysis)[0] # pre check done already
|
||||
meshdatagetter = meshsetsgetter.MeshSetsGetter(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
@@ -88,7 +87,7 @@ class Prepare(run.Prepare):
|
||||
)
|
||||
meshdatagetter.get_mesh_sets()
|
||||
|
||||
# write input file
|
||||
# write solver input
|
||||
w = writer.FemInputWriterCcx(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
@@ -100,9 +99,9 @@ class Prepare(run.Prepare):
|
||||
path = w.write_solver_input()
|
||||
# report to user if task succeeded
|
||||
if path != "" and os.path.isfile(path):
|
||||
self.pushStatus("Write completed.")
|
||||
self.pushStatus("Writing solver input completed.")
|
||||
else:
|
||||
self.pushStatus("Writing CalculiX solver input file failed,")
|
||||
self.pushStatus("Writing solver input failed.")
|
||||
self.fail()
|
||||
_inputFileName = os.path.splitext(os.path.basename(path))[0]
|
||||
|
||||
@@ -112,7 +111,13 @@ class Solve(run.Solve):
|
||||
def run(self):
|
||||
self.pushStatus("Executing solver...\n")
|
||||
|
||||
# get solver binary
|
||||
self.pushStatus("Get solver binary...\n")
|
||||
binary = settings.get_binary("Calculix")
|
||||
if binary is None:
|
||||
self.fail() # a print has been made in settings module
|
||||
|
||||
# run solver
|
||||
self._process = subprocess.Popen(
|
||||
[binary, "-i", _inputFileName],
|
||||
cwd=self.directory,
|
||||
@@ -131,10 +136,6 @@ class Solve(run.Solve):
|
||||
class Results(run.Results):
|
||||
|
||||
def run(self):
|
||||
if not _inputFileName:
|
||||
# TODO do not run solver
|
||||
# do not try to read results in a smarter way than an Exception
|
||||
raise Exception("Error on writing CalculiX input file.\n")
|
||||
prefs = FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/General")
|
||||
if not prefs.GetBool("KeepResultsOnReRun", False):
|
||||
@@ -142,10 +143,12 @@ class Results(run.Results):
|
||||
self.load_results()
|
||||
|
||||
def purge_results(self):
|
||||
|
||||
# dat file will not be removed
|
||||
# results from other solvers will be removed too
|
||||
# the user should decide if purge should only delete the solver results or all results
|
||||
self.pushStatus("Purge existing results...\n")
|
||||
# TODO dat file will not be removed
|
||||
# TODO implement a generic purge method
|
||||
# TODO results from other solvers will be removed too
|
||||
# the user should decide if purge should only
|
||||
# delete this solver results or results from all solvers
|
||||
for m in membertools.get_member(self.analysis, "Fem::FemResultObject"):
|
||||
if m.Mesh and femutils.is_of_type(m.Mesh, "Fem::MeshResult"):
|
||||
self.analysis.Document.removeObject(m.Mesh.Name)
|
||||
@@ -153,10 +156,11 @@ class Results(run.Results):
|
||||
self.analysis.Document.recompute()
|
||||
|
||||
def load_results(self):
|
||||
self.load_results_ccxfrd()
|
||||
self.load_results_ccxdat()
|
||||
self.pushStatus("Import new results...\n")
|
||||
self.load_ccxfrd_results()
|
||||
self.load_ccxdat_results()
|
||||
|
||||
def load_results_ccxfrd(self):
|
||||
def load_ccxfrd_results(self):
|
||||
frd_result_file = os.path.join(
|
||||
self.directory, _inputFileName + ".frd")
|
||||
if os.path.isfile(frd_result_file):
|
||||
@@ -164,18 +168,26 @@ class Results(run.Results):
|
||||
importCcxFrdResults.importFrd(
|
||||
frd_result_file, self.analysis, result_name_prefix)
|
||||
else:
|
||||
raise Exception(
|
||||
"FEM: No results found at {}!".format(frd_result_file))
|
||||
# TODO: use solver framework status message system
|
||||
FreeCAD.Console.PrintError(
|
||||
"FEM: No results found at {}!\n"
|
||||
.format(frd_result_file)
|
||||
)
|
||||
self.fail()
|
||||
|
||||
def load_results_ccxdat(self):
|
||||
def load_ccxdat_results(self):
|
||||
dat_result_file = os.path.join(
|
||||
self.directory, _inputFileName + ".dat")
|
||||
if os.path.isfile(dat_result_file):
|
||||
mode_frequencies = importCcxDatResults.import_dat(
|
||||
dat_result_file, self.analysis)
|
||||
else:
|
||||
raise Exception(
|
||||
"FEM: No .dat results found at {}!".format(dat_result_file))
|
||||
# TODO: use solver framework status message system
|
||||
FreeCAD.Console.PrintError(
|
||||
"FEM: No results found at {}!\n"
|
||||
.format(dat_result_file)
|
||||
)
|
||||
self.fail()
|
||||
if mode_frequencies:
|
||||
for m in membertools.get_member(self.analysis, "Fem::FemResultObject"):
|
||||
if m.Eigenmode > 0:
|
||||
|
||||
@@ -57,7 +57,7 @@ _inputFileName = None
|
||||
class Check(run.Check):
|
||||
|
||||
def run(self):
|
||||
self.pushStatus("Checking analysis...\n")
|
||||
self.pushStatus("Checking analysis member...\n")
|
||||
self.check_mesh_exists()
|
||||
self.check_material_exists()
|
||||
self.check_material_single() # no multiple material
|
||||
@@ -70,13 +70,11 @@ class Prepare(run.Prepare):
|
||||
|
||||
def run(self):
|
||||
global _inputFileName
|
||||
self.pushStatus("Preparing input files...\n")
|
||||
|
||||
mesh_obj = membertools.get_mesh_to_solve(self.analysis)[0] # pre check done already
|
||||
self.pushStatus("Preparing solver input...\n")
|
||||
|
||||
# get mesh set data
|
||||
# TODO evaluate if it makes sense to add new task
|
||||
# between check and prepare to the solver frame work
|
||||
# TODO see calculix tasks get mesh set data
|
||||
mesh_obj = membertools.get_mesh_to_solve(self.analysis)[0] # pre check done already
|
||||
meshdatagetter = meshsetsgetter.MeshSetsGetter(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
@@ -85,44 +83,36 @@ class Prepare(run.Prepare):
|
||||
)
|
||||
meshdatagetter.get_mesh_sets()
|
||||
|
||||
# write input file
|
||||
# write solver input
|
||||
w = writer.FemInputWriterMystran(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
mesh_obj,
|
||||
meshdatagetter.member,
|
||||
self.directory,
|
||||
meshdatagetter.mat_geo_sets
|
||||
)
|
||||
path = w.write_solver_input()
|
||||
# report to user if task succeeded
|
||||
if path != "":
|
||||
self.pushStatus("Write completed!")
|
||||
self.pushStatus("Writing solver input completed.")
|
||||
else:
|
||||
self.pushStatus("Writing CalculiX input file failed!")
|
||||
self.pushStatus("Writing solver input failed.")
|
||||
self.fail()
|
||||
_inputFileName = os.path.splitext(os.path.basename(path))[0]
|
||||
|
||||
|
||||
class Solve(run.Solve):
|
||||
|
||||
def run(self):
|
||||
# print(_inputFileName)
|
||||
if not _inputFileName:
|
||||
# TODO do not run solver, do not try to read results in a smarter way than an Exception
|
||||
raise Exception("Error on writing Mystran input file.\n")
|
||||
self.pushStatus("Executing solver...\n")
|
||||
|
||||
infile = _inputFileName + ".bdf"
|
||||
|
||||
# TODO use solver framework status system
|
||||
FreeCAD.Console.PrintMessage("Mystran: solver input file: {} \n\n".format(infile))
|
||||
|
||||
# get binary
|
||||
self.pushStatus("Get solver...\n")
|
||||
# get solver binary
|
||||
self.pushStatus("Get solver binary...\n")
|
||||
binary = settings.get_binary("Mystran")
|
||||
# use preferences editor to add a group Mystran and the prefs:
|
||||
# "UseStandardMystranLocation" --> bool, set to False
|
||||
# "mystranBinaryPath, string" --> the binary path
|
||||
if binary is None:
|
||||
return # a print has been made in settings module
|
||||
self.fail() # a print has been made in settings module
|
||||
|
||||
# run solver
|
||||
self.pushStatus("Executing solver...\n")
|
||||
@@ -147,19 +137,19 @@ class Results(run.Results):
|
||||
if not prefs.GetBool("KeepResultsOnReRun", False):
|
||||
self.purge_results()
|
||||
if result_reading is True:
|
||||
self.load_results() # ToDo in all solvers generischer name
|
||||
self.load_results()
|
||||
|
||||
def purge_results(self):
|
||||
self.pushStatus("Purge existing results...\n")
|
||||
# TODO see calculix result tasks
|
||||
for m in membertools.get_member(self.analysis, "Fem::FemResultObject"):
|
||||
if femutils.is_of_type(m.Mesh, "Fem::MeshResult"):
|
||||
self.analysis.Document.removeObject(m.Mesh.Name)
|
||||
self.analysis.Document.removeObject(m.Name)
|
||||
self.analysis.Document.recompute()
|
||||
# deletes all results from any solver
|
||||
# TODO: delete only the mystran results, fix in all solver
|
||||
|
||||
def load_results(self):
|
||||
self.pushStatus("Import results...\n")
|
||||
self.pushStatus("Import new results...\n")
|
||||
neu_result_file = os.path.join(self.directory, _inputFileName + ".NEU")
|
||||
if os.path.isfile(neu_result_file):
|
||||
hfcMystranNeuIn.import_neu(neu_result_file)
|
||||
@@ -169,11 +159,11 @@ class Results(run.Results):
|
||||
self.analysis.addObject(o)
|
||||
break
|
||||
else:
|
||||
# TODO: use solver framework error and status message system
|
||||
# TODO: use solver framework status message system
|
||||
FreeCAD.Console.PrintError(
|
||||
"FEM: No results found at {}!\n".format(neu_result_file)
|
||||
"FEM: No results found at {}!\n"
|
||||
.format(neu_result_file)
|
||||
)
|
||||
return
|
||||
|
||||
self.fail()
|
||||
|
||||
## @}
|
||||
|
||||
@@ -45,7 +45,7 @@ from femtools import membertools
|
||||
class Check(run.Check):
|
||||
|
||||
def run(self):
|
||||
self.pushStatus("Checking analysis...\n")
|
||||
self.pushStatus("Checking analysis member...\n")
|
||||
self.check_mesh_exists()
|
||||
self.check_material_exists()
|
||||
self.check_material_single() # no multiple material
|
||||
@@ -57,7 +57,7 @@ class Check(run.Check):
|
||||
class Prepare(run.Prepare):
|
||||
|
||||
def run(self):
|
||||
self.pushStatus("Preparing input files...\n")
|
||||
self.pushStatus("Preparing solver input...\n")
|
||||
w = writer.FemInputWriterZ88(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
@@ -68,33 +68,45 @@ class Prepare(run.Prepare):
|
||||
path = w.write_solver_input()
|
||||
# report to user if task succeeded
|
||||
if path is not None:
|
||||
self.pushStatus("Write completed!")
|
||||
self.pushStatus("Writing solver input completed.")
|
||||
else:
|
||||
self.pushStatus("Writing Z88 solver input files failed!")
|
||||
self.pushStatus("Writing solver input failed.")
|
||||
self.fail()
|
||||
# print(path)
|
||||
# z88 does not pass a main input file to the solver
|
||||
# it passes the directory all input files are in
|
||||
# not _inputFileName is needed
|
||||
|
||||
|
||||
class Solve(run.Solve):
|
||||
|
||||
def run(self):
|
||||
# AFAIK: z88r needs to be run twice, once in test mode and once in real solve mode
|
||||
# the subprocess was just copied, it seems to work :-)
|
||||
# TODO: search out for "Vektor GS" and "Vektor KOI" and print values
|
||||
# may be compared with the used ones
|
||||
self.pushStatus("Executing test solver...\n")
|
||||
|
||||
# get solver binary
|
||||
self.pushStatus("Get solver binary...\n")
|
||||
binary = settings.get_binary("Z88")
|
||||
if binary is None:
|
||||
self.fail() # a print has been made in settings module
|
||||
|
||||
# run solver test mode
|
||||
# AFAIK: z88r needs to be run twice
|
||||
# once in test mode and once in real solve mode
|
||||
# the subprocess was just copied, it works :-)
|
||||
# TODO: search out for "Vektor GS" and "Vektor KOI" and print values
|
||||
# may be compare with the used ones
|
||||
self.pushStatus("Executing solver in test mode...\n")
|
||||
self._process = subprocess.Popen(
|
||||
[binary, "-t", "-choly"],
|
||||
cwd=self.directory,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
self.signalAbort.add(self._process.terminate)
|
||||
# output = self._observeSolver(self._process)
|
||||
self._process.communicate()
|
||||
self.signalAbort.remove(self._process.terminate)
|
||||
|
||||
self.pushStatus("Executing real solver...\n")
|
||||
# run solver real mode
|
||||
self.pushStatus("Executing solver in real mode...\n")
|
||||
binary = settings.get_binary("Z88")
|
||||
self._process = subprocess.Popen(
|
||||
[binary, "-c", "-choly"],
|
||||
@@ -102,12 +114,10 @@ class Solve(run.Solve):
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
self.signalAbort.add(self._process.terminate)
|
||||
# output = self._observeSolver(self._process)
|
||||
self._process.communicate()
|
||||
self.signalAbort.remove(self._process.terminate)
|
||||
# if not self.aborted:
|
||||
# self._updateOutput(output)
|
||||
# del output # get flake8 quiet
|
||||
|
||||
# for chatching the output see CalculiX or Elmer solver tasks module
|
||||
|
||||
|
||||
class Results(run.Results):
|
||||
@@ -120,6 +130,8 @@ class Results(run.Results):
|
||||
self.load_results()
|
||||
|
||||
def purge_results(self):
|
||||
self.pushStatus("Purge existing results...\n")
|
||||
# TODO see calculix result tasks
|
||||
for m in membertools.get_member(self.analysis, "Fem::FemResultObject"):
|
||||
if femutils.is_of_type(m.Mesh, "Fem::MeshResult"):
|
||||
self.analysis.Document.removeObject(m.Mesh.Name)
|
||||
@@ -127,6 +139,7 @@ class Results(run.Results):
|
||||
self.analysis.Document.recompute()
|
||||
|
||||
def load_results(self):
|
||||
self.pushStatus("Import new results...\n")
|
||||
# displacements from z88o2 file
|
||||
disp_result_file = os.path.join(
|
||||
self.directory, "z88o2.txt")
|
||||
@@ -135,7 +148,11 @@ class Results(run.Results):
|
||||
importZ88O2Results.import_z88_disp(
|
||||
disp_result_file, self.analysis, result_name_prefix)
|
||||
else:
|
||||
raise Exception(
|
||||
"FEM: No results found at {}!".format(disp_result_file))
|
||||
# TODO: use solver framework status message system
|
||||
FreeCAD.Console.PrintError(
|
||||
"FEM: No results found at {}!\n"
|
||||
.format(disp_result_file)
|
||||
)
|
||||
self.fail()
|
||||
|
||||
## @}
|
||||
|
||||
Reference in New Issue
Block a user