| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| __title__ = "FreeCAD FEM solver Z88 tasks" |
| __author__ = "Bernd Hahnebach" |
| __url__ = "https://www.freecad.org" |
|
|
| |
| |
|
|
| import os |
| import os.path |
| import subprocess |
| from platform import system |
|
|
| import FreeCAD |
|
|
| from . import writer |
| from .. import run |
| from .. import settings |
| from feminout import importZ88O2Results |
| from femmesh import meshsetsgetter |
| from femtools import femutils |
| from femtools import membertools |
|
|
| SOLVER_TYPES = ["sorcg", "siccg", "choly"] |
|
|
|
|
| class Check(run.Check): |
|
|
| def run(self): |
| self.pushStatus("Checking analysis member...\n") |
| self.check_mesh_exists() |
| self.check_material_exists() |
| self.check_material_single() |
| self.check_geos_beamsection_single() |
| self.check_geos_shellthickness_single() |
| self.check_geos_beamsection_and_shellthickness() |
|
|
|
|
| class Prepare(run.Prepare): |
|
|
| def run(self): |
| self.pushStatus("Preparing solver input...\n") |
|
|
| |
| |
| mesh_obj = membertools.get_mesh_to_solve(self.analysis)[0] |
| meshdatagetter = meshsetsgetter.MeshSetsGetter( |
| self.analysis, |
| self.solver, |
| mesh_obj, |
| membertools.AnalysisMember(self.analysis), |
| ) |
| meshdatagetter.get_mesh_sets() |
|
|
| |
| w = writer.FemInputWriterZ88( |
| self.analysis, self.solver, mesh_obj, meshdatagetter.member, self.directory |
| ) |
| path = w.write_solver_input() |
| |
| if path is not None: |
| self.pushStatus("Writing solver input completed.") |
| else: |
| self.pushStatus("Writing solver input failed.") |
| self.fail() |
| |
| |
| |
| |
|
|
|
|
| class Solve(run.Solve): |
|
|
| def run(self): |
| self.pushStatus("Executing test solver...\n") |
|
|
| |
| self.pushStatus("Get solver binary...\n") |
| binary = settings.get_binary("Z88") |
| if binary is None: |
| self.pushStatus("Error: The z88r binary has not been found!") |
| self.fail() |
| return |
|
|
| prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Z88") |
| solver_index = prefs.GetInt("Solver", 0) |
| solver_name = SOLVER_TYPES[solver_index] |
| self.pushStatus(f"Used solver: {solver_name}\n") |
|
|
| |
| |
| |
| |
| |
| |
| self.pushStatus("Executing solver in test mode...\n") |
| Solve.runZ88(self, "-t", binary, solver_name, "hide") |
|
|
| |
| self.pushStatus("Executing solver in real mode...\n") |
| |
| Solve.runZ88(self, "-c", binary, solver_name, "normal") |
|
|
| def runZ88(self, command, binary, solver, state): |
| solver_name = solver |
| |
| self._process = subprocess.Popen( |
| [binary, command, "-" + solver_name], |
| cwd=self.directory, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE, |
| startupinfo=femutils.startProgramInfo(state), |
| ) |
| self.signalAbort.add(self._process.terminate) |
| self._process.communicate() |
| self.signalAbort.remove(self._process.terminate) |
|
|
| |
|
|
|
|
| class Results(run.Results): |
|
|
| def run(self): |
| prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/General") |
| if not prefs.GetBool("KeepResultsOnReRun", False): |
| self.purge_results() |
| self.load_results() |
|
|
| def purge_results(self): |
| self.pushStatus("Purge existing results...\n") |
| |
| 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() |
|
|
| def load_results(self): |
| self.pushStatus("Import new results...\n") |
| |
| disp_result_file = os.path.join(self.directory, "z88o2.txt") |
| if os.path.isfile(disp_result_file): |
| result_name_prefix = "Z88_" + self.solver.AnalysisType + "_" |
| importZ88O2Results.import_z88_disp(disp_result_file, self.analysis, result_name_prefix) |
| else: |
| |
| FreeCAD.Console.PrintError(f"FEM: No results found at {disp_result_file}!\n") |
| self.fail() |
|
|
|
|
| |
|
|