FEM: reformat codebase
This commit is contained in:
@@ -45,18 +45,16 @@ ANALYSIS_TYPES = ["static"]
|
||||
|
||||
|
||||
def create(doc, name="SolverZ88"):
|
||||
return femutils.createObject(
|
||||
doc, name, Proxy, ViewProxy)
|
||||
return femutils.createObject(doc, name, Proxy, ViewProxy)
|
||||
|
||||
|
||||
class Proxy(solverbase.Proxy):
|
||||
"""The Fem::FemSolver's Proxy python type, add solver specific properties
|
||||
"""
|
||||
"""The Fem::FemSolver's Proxy python type, add solver specific properties"""
|
||||
|
||||
Type = "Fem::SolverZ88"
|
||||
|
||||
def __init__(self, obj):
|
||||
super(Proxy, self).__init__(obj)
|
||||
super().__init__(obj)
|
||||
obj.Proxy = self
|
||||
|
||||
# z88_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Z88")
|
||||
@@ -67,39 +65,41 @@ class Proxy(solverbase.Proxy):
|
||||
|
||||
def createMachine(self, obj, directory, testmode=False):
|
||||
return run.Machine(
|
||||
solver=obj, directory=directory,
|
||||
solver=obj,
|
||||
directory=directory,
|
||||
check=tasks.Check(),
|
||||
prepare=tasks.Prepare(),
|
||||
solve=tasks.Solve(),
|
||||
results=tasks.Results(),
|
||||
testmode=testmode)
|
||||
testmode=testmode,
|
||||
)
|
||||
|
||||
def editSupported(self):
|
||||
return True
|
||||
|
||||
def edit(self, directory):
|
||||
pattern = os.path.join(directory, "z88i1.txt")
|
||||
FreeCAD.Console.PrintMessage("{}\n".format(pattern))
|
||||
FreeCAD.Console.PrintMessage(f"{pattern}\n")
|
||||
f = glob.glob(pattern)[0]
|
||||
FemGui.open(f)
|
||||
pattern = os.path.join(directory, "z88i2.txt")
|
||||
FreeCAD.Console.PrintMessage("{}\n".format(pattern))
|
||||
FreeCAD.Console.PrintMessage(f"{pattern}\n")
|
||||
f = glob.glob(pattern)[0]
|
||||
FemGui.open(f)
|
||||
pattern = os.path.join(directory, "z88i5.txt")
|
||||
FreeCAD.Console.PrintMessage("{}\n".format(pattern))
|
||||
FreeCAD.Console.PrintMessage(f"{pattern}\n")
|
||||
f = glob.glob(pattern)[0]
|
||||
FemGui.open(f)
|
||||
pattern = os.path.join(directory, "z88man.txt")
|
||||
FreeCAD.Console.PrintMessage("{}\n".format(pattern))
|
||||
FreeCAD.Console.PrintMessage(f"{pattern}\n")
|
||||
f = glob.glob(pattern)[0]
|
||||
FemGui.open(f)
|
||||
pattern = os.path.join(directory, "z88mat.txt")
|
||||
FreeCAD.Console.PrintMessage("{}\n".format(pattern))
|
||||
FreeCAD.Console.PrintMessage(f"{pattern}\n")
|
||||
f = glob.glob(pattern)[0]
|
||||
FemGui.open(f)
|
||||
pattern = os.path.join(directory, "z88elp.txt")
|
||||
FreeCAD.Console.PrintMessage("{}\n".format(pattern))
|
||||
FreeCAD.Console.PrintMessage(f"{pattern}\n")
|
||||
f = glob.glob(pattern)[0]
|
||||
FemGui.open(f)
|
||||
|
||||
@@ -112,4 +112,5 @@ class ViewProxy(solverbase.ViewProxy):
|
||||
def getIcon(self):
|
||||
return ":/icons/FEM_SolverZ88.svg"
|
||||
|
||||
|
||||
## @}
|
||||
|
||||
@@ -76,11 +76,7 @@ class Prepare(run.Prepare):
|
||||
|
||||
# write solver input
|
||||
w = writer.FemInputWriterZ88(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
mesh_obj,
|
||||
meshdatagetter.member,
|
||||
self.directory
|
||||
self.analysis, self.solver, mesh_obj, meshdatagetter.member, self.directory
|
||||
)
|
||||
path = w.write_solver_input()
|
||||
# report to user if task succeeded
|
||||
@@ -111,7 +107,7 @@ class Solve(run.Solve):
|
||||
prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/Z88")
|
||||
solver_index = prefs.GetInt("Solver", 0)
|
||||
solver_name = SOLVER_TYPES[solver_index]
|
||||
self.pushStatus("Used solver: {}\n".format(solver_name))
|
||||
self.pushStatus(f"Used solver: {solver_name}\n")
|
||||
|
||||
# run solver test mode
|
||||
# AFAIK: z88r needs to be run twice
|
||||
@@ -136,14 +132,14 @@ class Solve(run.Solve):
|
||||
cwd=self.directory,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
startupinfo=femutils.startProgramInfo(state)
|
||||
startupinfo=femutils.startProgramInfo(state),
|
||||
)
|
||||
else:
|
||||
self._process = subprocess.Popen(
|
||||
[binary, command, "-" + solver_name],
|
||||
cwd=self.directory,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
self.signalAbort.add(self._process.terminate)
|
||||
self._process.communicate()
|
||||
@@ -155,8 +151,7 @@ class Solve(run.Solve):
|
||||
class Results(run.Results):
|
||||
|
||||
def run(self):
|
||||
prefs = FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Fem/General")
|
||||
prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Fem/General")
|
||||
if not prefs.GetBool("KeepResultsOnReRun", False):
|
||||
self.purge_results()
|
||||
self.load_results()
|
||||
@@ -173,18 +168,14 @@ class Results(run.Results):
|
||||
def load_results(self):
|
||||
self.pushStatus("Import new results...\n")
|
||||
# displacements from z88o2 file
|
||||
disp_result_file = os.path.join(
|
||||
self.directory, "z88o2.txt")
|
||||
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)
|
||||
importZ88O2Results.import_z88_disp(disp_result_file, self.analysis, result_name_prefix)
|
||||
else:
|
||||
# TODO: use solver framework status message system
|
||||
FreeCAD.Console.PrintError(
|
||||
"FEM: No results found at {}!\n"
|
||||
.format(disp_result_file)
|
||||
)
|
||||
FreeCAD.Console.PrintError(f"FEM: No results found at {disp_result_file}!\n")
|
||||
self.fail()
|
||||
|
||||
|
||||
## @}
|
||||
|
||||
@@ -39,21 +39,9 @@ from femmesh import meshtools
|
||||
|
||||
|
||||
class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
def __init__(
|
||||
self,
|
||||
analysis_obj,
|
||||
solver_obj,
|
||||
mesh_obj,
|
||||
member,
|
||||
dir_name=None
|
||||
):
|
||||
def __init__(self, analysis_obj, solver_obj, mesh_obj, member, dir_name=None):
|
||||
writerbase.FemInputWriter.__init__(
|
||||
self,
|
||||
analysis_obj,
|
||||
solver_obj,
|
||||
mesh_obj,
|
||||
member,
|
||||
dir_name
|
||||
self, analysis_obj, solver_obj, mesh_obj, member, dir_name
|
||||
)
|
||||
self.file_name = join(self.dir_name, "z88")
|
||||
|
||||
@@ -63,18 +51,11 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
timestart = time.process_time()
|
||||
FreeCAD.Console.PrintMessage("\n") # because of time print in separate line
|
||||
FreeCAD.Console.PrintMessage("Z88 solver input writing...\n")
|
||||
FreeCAD.Console.PrintLog(
|
||||
"FemInputWriterZ88 --> self.dir_name --> {}\n"
|
||||
.format(self.dir_name)
|
||||
)
|
||||
FreeCAD.Console.PrintLog(f"FemInputWriterZ88 --> self.dir_name --> {self.dir_name}\n")
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"FemInputWriterZ88 --> self.file_name --> {}\n"
|
||||
.format(self.file_name)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Write z88 input files to: {}\n"
|
||||
.format(self.dir_name)
|
||||
f"FemInputWriterZ88 --> self.file_name --> {self.file_name}\n"
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(f"Write z88 input files to: {self.dir_name}\n")
|
||||
control = self.set_z88_elparam()
|
||||
if control is False:
|
||||
return None
|
||||
@@ -86,12 +67,10 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
self.write_z88_integration_properties()
|
||||
self.write_z88_memory_parameter()
|
||||
self.write_z88_solver_parameter()
|
||||
writing_time_string = (
|
||||
"Writing time input file: {} seconds"
|
||||
.format(round((time.process_time() - timestart), 2))
|
||||
writing_time_string = "Writing time input file: {} seconds".format(
|
||||
round((time.process_time() - timestart), 2)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"{}\n\n".format(writing_time_string))
|
||||
FreeCAD.Console.PrintMessage(f"{writing_time_string}\n\n")
|
||||
return self.dir_name
|
||||
|
||||
# ********************************************************************************************
|
||||
@@ -107,14 +86,14 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
param = {4: z8804, 24: z8824, 23: z8823, 17: z8817, 16: z8816, 1: z8801, 10: z8810}
|
||||
# TODO: test elements 17, 16, 10, INTORD etc
|
||||
self.z88_element_type = importZ88Mesh.get_z88_element_type(
|
||||
self.femmesh,
|
||||
self.femelement_table
|
||||
self.femmesh, self.femelement_table
|
||||
)
|
||||
if self.z88_element_type in param:
|
||||
self.z88_elparam = param[self.z88_element_type]
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
"Element type not supported by Z88. Can not write Z88 solver input.\n")
|
||||
"Element type not supported by Z88. Can not write Z88 solver input.\n"
|
||||
)
|
||||
return False
|
||||
FreeCAD.Console.PrintMessage(self.z88_elparam)
|
||||
FreeCAD.Console.PrintMessage("\n")
|
||||
@@ -130,10 +109,7 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
mesh_file_path = self.file_name + "i1.txt"
|
||||
f = open(mesh_file_path, "w")
|
||||
importZ88Mesh.write_z88_mesh_to_file(
|
||||
self.femnodes_mesh,
|
||||
self.femelement_table,
|
||||
self.z88_element_type,
|
||||
f
|
||||
self.femnodes_mesh, self.femelement_table, self.z88_element_type, f
|
||||
)
|
||||
f.close()
|
||||
|
||||
@@ -145,9 +121,9 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
# write nodes to constraints_data (different from writing to file in ccxInpWriter
|
||||
for femobj in self.member.cons_fixed:
|
||||
for n in femobj["Nodes"]:
|
||||
constraints_data.append((n, "{} 1 2 0\n".format(n)))
|
||||
constraints_data.append((n, "{} 2 2 0\n".format(n)))
|
||||
constraints_data.append((n, "{} 3 2 0\n".format(n)))
|
||||
constraints_data.append((n, f"{n} 1 2 0\n"))
|
||||
constraints_data.append((n, f"{n} 2 2 0\n"))
|
||||
constraints_data.append((n, f"{n} 3 2 0\n"))
|
||||
|
||||
# forces constraints
|
||||
# write node loads to constraints_data
|
||||
@@ -159,15 +135,15 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
for n in sorted(ref_shape[1]):
|
||||
# the loads in ref_shape[1][n] are without unit
|
||||
node_load = ref_shape[1][n]
|
||||
if (direction_vec.x != 0.0):
|
||||
if direction_vec.x != 0.0:
|
||||
v1 = direction_vec.x * node_load
|
||||
constraints_data.append((n, "{} 1 1 {}\n".format(n, v1)))
|
||||
if (direction_vec.y != 0.0):
|
||||
constraints_data.append((n, f"{n} 1 1 {v1}\n"))
|
||||
if direction_vec.y != 0.0:
|
||||
v2 = direction_vec.y * node_load
|
||||
constraints_data.append((n, "{} 2 1 {}\n".format(n, v2)))
|
||||
if (direction_vec.z != 0.0):
|
||||
constraints_data.append((n, f"{n} 2 1 {v2}\n"))
|
||||
if direction_vec.z != 0.0:
|
||||
v3 = direction_vec.z * node_load
|
||||
constraints_data.append((n, "{} 3 1 {}\n".format(n, v3)))
|
||||
constraints_data.append((n, f"{n} 3 1 {v3}\n"))
|
||||
|
||||
# write constraints_data to file
|
||||
constraints_file_path = self.file_name + "i2.txt"
|
||||
@@ -193,7 +169,7 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
materials_file_path = self.file_name + "mat.txt"
|
||||
fms = open(materials_file_path, "w")
|
||||
fms.write("1\n")
|
||||
fms.write("1 {} {}".format(self.element_count, material_data_file_name))
|
||||
fms.write(f"1 {self.element_count} {material_data_file_name}")
|
||||
fms.write("\n")
|
||||
fms.close()
|
||||
material_data_file_path = join(self.dir_name, material_data_file_name)
|
||||
@@ -201,7 +177,7 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
YM = FreeCAD.Units.Quantity(mat_obj.Material["YoungsModulus"])
|
||||
YM_in_MPa = YM.getValueAs("MPa")
|
||||
PR = float(mat_obj.Material["PoissonRatio"])
|
||||
fmd.write("{0} {1:.3f}".format(YM_in_MPa, PR))
|
||||
fmd.write(f"{YM_in_MPa} {PR:.3f}")
|
||||
fmd.write("\n")
|
||||
fmd.close()
|
||||
|
||||
@@ -219,35 +195,24 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
elif beam_obj.SectionType == "Circular":
|
||||
diameter = beam_obj.CircDiameter.getValueAs("mm").Value
|
||||
from math import pi
|
||||
|
||||
area = 0.25 * pi * diameter * diameter
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
"Cross section type {} not supported, "
|
||||
"cross section area will be 0 in solver input.\n"
|
||||
.format(beam_obj.SectionType)
|
||||
"cross section area will be 0 in solver input.\n".format(beam_obj.SectionType)
|
||||
)
|
||||
# TODO make the check in prechecks and delete it here
|
||||
# no extensive errorhandling in writer
|
||||
# this way the solver will fail and an exception is raised somehow
|
||||
elements_data.append(
|
||||
"1 {} {} 0 0 0 0 0 0 "
|
||||
.format(self.element_count, area)
|
||||
)
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Be aware, only trusses are supported for edge meshes!\n"
|
||||
)
|
||||
elements_data.append(f"1 {self.element_count} {area} 0 0 0 0 0 0 ")
|
||||
FreeCAD.Console.PrintWarning("Be aware, only trusses are supported for edge meshes!\n")
|
||||
elif meshtools.is_face_femmesh(self.femmesh):
|
||||
thick_obj = self.member.geos_shellthickness[0]["Object"]
|
||||
thickness = thick_obj.Thickness.getValueAs("mm").Value
|
||||
elements_data.append(
|
||||
"1 {} {} 0 0 0 0 0 0 "
|
||||
.format(self.element_count, thickness)
|
||||
)
|
||||
elements_data.append(f"1 {self.element_count} {thickness} 0 0 0 0 0 0 ")
|
||||
elif meshtools.is_solid_femmesh(self.femmesh):
|
||||
elements_data.append(
|
||||
"1 {} 0 0 0 0 0 0 0"
|
||||
.format(self.element_count)
|
||||
)
|
||||
elements_data.append(f"1 {self.element_count} 0 0 0 0 0 0 0")
|
||||
else:
|
||||
FreeCAD.Console.PrintError("Error!\n")
|
||||
f = open(element_properties_file_path, "w")
|
||||
@@ -260,14 +225,14 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
# ********************************************************************************************
|
||||
def write_z88_integration_properties(self):
|
||||
integration_data = []
|
||||
integration_data.append("1 {} {} {}".format(
|
||||
self.element_count,
|
||||
self.z88_elparam["INTORD"],
|
||||
self.z88_elparam["INTOS"]
|
||||
))
|
||||
integration_data.append(
|
||||
"1 {} {} {}".format(
|
||||
self.element_count, self.z88_elparam["INTORD"], self.z88_elparam["INTOS"]
|
||||
)
|
||||
)
|
||||
integration_properties_file_path = self.file_name + "int.txt"
|
||||
f = open(integration_properties_file_path, "w")
|
||||
f.write("{}\n".format(len(integration_data)))
|
||||
f.write(f"{len(integration_data)}\n")
|
||||
for i in integration_data:
|
||||
f.write(i)
|
||||
f.write("\n")
|
||||
@@ -297,9 +262,9 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
output = ""
|
||||
for line in template_array:
|
||||
if line.find("MAXGS") > -1:
|
||||
line = " MAXGS {}".format(MaxGS)
|
||||
line = f" MAXGS {MaxGS}"
|
||||
if line.find("MAXKOI") > -1:
|
||||
line = " MAXKOI {}".format(MaxKOI)
|
||||
line = f" MAXKOI {MaxKOI}"
|
||||
output += line + "\n"
|
||||
|
||||
solver_parameter_file_path = self.file_name + ".dyn"
|
||||
|
||||
Reference in New Issue
Block a user