FEM: calculix writer, move material, element geometry and mat-geo-elementsets into separte methods
This commit is contained in:
@@ -202,6 +202,9 @@ SET(FemSolverCalculix_SRCS
|
|||||||
femsolver/calculix/write_constraint_temperature.py
|
femsolver/calculix/write_constraint_temperature.py
|
||||||
femsolver/calculix/write_constraint_tie.py
|
femsolver/calculix/write_constraint_tie.py
|
||||||
femsolver/calculix/write_constraint_transform.py
|
femsolver/calculix/write_constraint_transform.py
|
||||||
|
femsolver/calculix/write_femelement_geometry.py
|
||||||
|
femsolver/calculix/write_femelement_material.py
|
||||||
|
femsolver/calculix/write_femelement_matgeosets.py
|
||||||
femsolver/calculix/write_footer.py
|
femsolver/calculix/write_footer.py
|
||||||
femsolver/calculix/write_mesh.py
|
femsolver/calculix/write_mesh.py
|
||||||
femsolver/calculix/write_step_equation.py
|
femsolver/calculix/write_step_equation.py
|
||||||
|
|||||||
185
src/Mod/Fem/femsolver/calculix/write_femelement_geometry.py
Normal file
185
src/Mod/Fem/femsolver/calculix/write_femelement_geometry.py
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
# ***************************************************************************
|
||||||
|
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||||
|
# * *
|
||||||
|
# * This file is part of the FreeCAD CAx development system. *
|
||||||
|
# * *
|
||||||
|
# * This program is free software; you can redistribute it and/or modify *
|
||||||
|
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||||
|
# * as published by the Free Software Foundation; either version 2 of *
|
||||||
|
# * the License, or (at your option) any later version. *
|
||||||
|
# * for detail see the LICENCE text file. *
|
||||||
|
# * *
|
||||||
|
# * This program is distributed in the hope that it will be useful, *
|
||||||
|
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
# * GNU Library General Public License for more details. *
|
||||||
|
# * *
|
||||||
|
# * You should have received a copy of the GNU Library General Public *
|
||||||
|
# * License along with this program; if not, write to the Free Software *
|
||||||
|
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||||
|
# * USA *
|
||||||
|
# * *
|
||||||
|
# ***************************************************************************
|
||||||
|
|
||||||
|
__title__ = "FreeCAD FEM calculix write inpfile femelement geometry"
|
||||||
|
__author__ = "Bernd Hahnebach"
|
||||||
|
__url__ = "https://www.freecadweb.org"
|
||||||
|
|
||||||
|
|
||||||
|
def write_femelement_geometry(f, ccxwriter):
|
||||||
|
f.write("\n{}\n".format(59 * "*"))
|
||||||
|
f.write("** Sections\n")
|
||||||
|
for ccx_elset in ccxwriter.ccx_elsets:
|
||||||
|
if ccx_elset["ccx_elset"]:
|
||||||
|
if "beamsection_obj"in ccx_elset: # beam mesh
|
||||||
|
beamsec_obj = ccx_elset["beamsection_obj"]
|
||||||
|
elsetdef = "ELSET=" + ccx_elset["ccx_elset_name"] + ", "
|
||||||
|
material = "MATERIAL=" + ccx_elset["mat_obj_name"]
|
||||||
|
normal = ccx_elset["beam_normal"]
|
||||||
|
if beamsec_obj.SectionType == "Rectangular":
|
||||||
|
height = beamsec_obj.RectHeight.getValueAs("mm")
|
||||||
|
width = beamsec_obj.RectWidth.getValueAs("mm")
|
||||||
|
section_type = ", SECTION=RECT"
|
||||||
|
section_geo = str(height) + ", " + str(width) + "\n"
|
||||||
|
section_def = "*BEAM SECTION, {}{}{}\n".format(
|
||||||
|
elsetdef,
|
||||||
|
material,
|
||||||
|
section_type
|
||||||
|
)
|
||||||
|
elif beamsec_obj.SectionType == "Circular":
|
||||||
|
radius = 0.5 * beamsec_obj.CircDiameter.getValueAs("mm")
|
||||||
|
section_type = ", SECTION=CIRC"
|
||||||
|
section_geo = str(radius) + "\n"
|
||||||
|
section_def = "*BEAM SECTION, {}{}{}\n".format(
|
||||||
|
elsetdef,
|
||||||
|
material,
|
||||||
|
section_type
|
||||||
|
)
|
||||||
|
elif beamsec_obj.SectionType == "Pipe":
|
||||||
|
radius = 0.5 * beamsec_obj.PipeDiameter.getValueAs("mm")
|
||||||
|
thickness = beamsec_obj.PipeThickness.getValueAs("mm")
|
||||||
|
section_type = ", SECTION=PIPE"
|
||||||
|
section_geo = str(radius) + ", " + str(thickness) + "\n"
|
||||||
|
section_def = "*BEAM GENERAL SECTION, {}{}{}\n".format(
|
||||||
|
elsetdef,
|
||||||
|
material,
|
||||||
|
section_type
|
||||||
|
)
|
||||||
|
# see forum topic for output formatting of rotation
|
||||||
|
# https://forum.freecadweb.org/viewtopic.php?f=18&t=46133&p=405142#p405142
|
||||||
|
section_nor = "{:f}, {:f}, {:f}\n".format(
|
||||||
|
normal[0],
|
||||||
|
normal[1],
|
||||||
|
normal[2]
|
||||||
|
)
|
||||||
|
f.write(section_def)
|
||||||
|
f.write(section_geo)
|
||||||
|
f.write(section_nor)
|
||||||
|
elif "fluidsection_obj"in ccx_elset: # fluid mesh
|
||||||
|
fluidsec_obj = ccx_elset["fluidsection_obj"]
|
||||||
|
elsetdef = "ELSET=" + ccx_elset["ccx_elset_name"] + ", "
|
||||||
|
material = "MATERIAL=" + ccx_elset["mat_obj_name"]
|
||||||
|
if fluidsec_obj.SectionType == "Liquid":
|
||||||
|
section_type = fluidsec_obj.LiquidSectionType
|
||||||
|
if (section_type == "PIPE INLET") or (section_type == "PIPE OUTLET"):
|
||||||
|
section_type = "PIPE INOUT"
|
||||||
|
section_def = "*FLUID SECTION, {}TYPE={}, {}\n".format(
|
||||||
|
elsetdef,
|
||||||
|
section_type,
|
||||||
|
material
|
||||||
|
)
|
||||||
|
section_geo = liquid_section_def(fluidsec_obj, section_type)
|
||||||
|
"""
|
||||||
|
# deactivate as it would result in section_def and section_geo not defined
|
||||||
|
# deactivated in the App and Gui object and thus in the task panel as well
|
||||||
|
elif fluidsec_obj.SectionType == "Gas":
|
||||||
|
section_type = fluidsec_obj.GasSectionType
|
||||||
|
elif fluidsec_obj.SectionType == "Open Channel":
|
||||||
|
section_type = fluidsec_obj.ChannelSectionType
|
||||||
|
"""
|
||||||
|
f.write(section_def)
|
||||||
|
f.write(section_geo)
|
||||||
|
elif "shellthickness_obj"in ccx_elset: # shell mesh
|
||||||
|
shellth_obj = ccx_elset["shellthickness_obj"]
|
||||||
|
elsetdef = "ELSET=" + ccx_elset["ccx_elset_name"] + ", "
|
||||||
|
material = "MATERIAL=" + ccx_elset["mat_obj_name"]
|
||||||
|
section_def = "*SHELL SECTION, " + elsetdef + material + "\n"
|
||||||
|
section_geo = str(shellth_obj.Thickness.getValueAs("mm")) + "\n"
|
||||||
|
f.write(section_def)
|
||||||
|
f.write(section_geo)
|
||||||
|
else: # solid mesh
|
||||||
|
elsetdef = "ELSET=" + ccx_elset["ccx_elset_name"] + ", "
|
||||||
|
material = "MATERIAL=" + ccx_elset["mat_obj_name"]
|
||||||
|
section_def = "*SOLID SECTION, " + elsetdef + material + "\n"
|
||||||
|
f.write(section_def)
|
||||||
|
|
||||||
|
|
||||||
|
# ************************************************************************************************
|
||||||
|
# Helpers
|
||||||
|
def liquid_section_def(obj, section_type):
|
||||||
|
if section_type == "PIPE MANNING":
|
||||||
|
manning_area = str(obj.ManningArea.getValueAs("mm^2").Value)
|
||||||
|
manning_radius = str(obj.ManningRadius.getValueAs("mm"))
|
||||||
|
manning_coefficient = str(obj.ManningCoefficient)
|
||||||
|
section_geo = manning_area + "," + manning_radius + "," + manning_coefficient + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE ENLARGEMENT":
|
||||||
|
enlarge_area1 = str(obj.EnlargeArea1.getValueAs("mm^2").Value)
|
||||||
|
enlarge_area2 = str(obj.EnlargeArea2.getValueAs("mm^2").Value)
|
||||||
|
section_geo = enlarge_area1 + "," + enlarge_area2 + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE CONTRACTION":
|
||||||
|
contract_area1 = str(obj.ContractArea1.getValueAs("mm^2").Value)
|
||||||
|
contract_area2 = str(obj.ContractArea2.getValueAs("mm^2").Value)
|
||||||
|
section_geo = contract_area1 + "," + contract_area2 + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE ENTRANCE":
|
||||||
|
entrance_pipe_area = str(obj.EntrancePipeArea.getValueAs("mm^2").Value)
|
||||||
|
entrance_area = str(obj.EntranceArea.getValueAs("mm^2").Value)
|
||||||
|
section_geo = entrance_pipe_area + "," + entrance_area + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE DIAPHRAGM":
|
||||||
|
diaphragm_pipe_area = str(obj.DiaphragmPipeArea.getValueAs("mm^2").Value)
|
||||||
|
diaphragm_area = str(obj.DiaphragmArea.getValueAs("mm^2").Value)
|
||||||
|
section_geo = diaphragm_pipe_area + "," + diaphragm_area + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE BEND":
|
||||||
|
bend_pipe_area = str(obj.BendPipeArea.getValueAs("mm^2").Value)
|
||||||
|
bend_radius_diameter = str(obj.BendRadiusDiameter)
|
||||||
|
bend_angle = str(obj.BendAngle)
|
||||||
|
bend_loss_coefficient = str(obj.BendLossCoefficient)
|
||||||
|
section_geo = ("{},{},{},{}\n".format(
|
||||||
|
bend_pipe_area,
|
||||||
|
bend_radius_diameter,
|
||||||
|
bend_angle,
|
||||||
|
bend_loss_coefficient
|
||||||
|
))
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE GATE VALVE":
|
||||||
|
gatevalve_pipe_area = str(obj.GateValvePipeArea.getValueAs("mm^2").Value)
|
||||||
|
gatevalve_closing_coeff = str(obj.GateValveClosingCoeff)
|
||||||
|
section_geo = gatevalve_pipe_area + "," + gatevalve_closing_coeff + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE WHITE-COLEBROOK":
|
||||||
|
colebrooke_area = str(obj.ColebrookeArea.getValueAs("mm^2").Value)
|
||||||
|
colebrooke_diameter = str(2 * obj.ColebrookeRadius.getValueAs("mm"))
|
||||||
|
colebrooke_grain_diameter = str(obj.ColebrookeGrainDiameter.getValueAs("mm"))
|
||||||
|
colebrooke_form_factor = str(obj.ColebrookeFormFactor)
|
||||||
|
section_geo = ("{},{},{},{},{}\n".format(
|
||||||
|
colebrooke_area,
|
||||||
|
colebrooke_diameter,
|
||||||
|
"-1",
|
||||||
|
colebrooke_grain_diameter,
|
||||||
|
colebrooke_form_factor
|
||||||
|
))
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "LIQUID PUMP":
|
||||||
|
section_geo = ""
|
||||||
|
for i in range(len(obj.PumpFlowRate)):
|
||||||
|
flow_rate = str(obj.PumpFlowRate[i])
|
||||||
|
top = str(obj.PumpHeadLoss[i])
|
||||||
|
section_geo = section_geo + flow_rate + "," + top + ","
|
||||||
|
section_geo = section_geo + "\n"
|
||||||
|
return section_geo
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
194
src/Mod/Fem/femsolver/calculix/write_femelement_material.py
Normal file
194
src/Mod/Fem/femsolver/calculix/write_femelement_material.py
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
# ***************************************************************************
|
||||||
|
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||||
|
# * *
|
||||||
|
# * This file is part of the FreeCAD CAx development system. *
|
||||||
|
# * *
|
||||||
|
# * This program is free software; you can redistribute it and/or modify *
|
||||||
|
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||||
|
# * as published by the Free Software Foundation; either version 2 of *
|
||||||
|
# * the License, or (at your option) any later version. *
|
||||||
|
# * for detail see the LICENCE text file. *
|
||||||
|
# * *
|
||||||
|
# * This program is distributed in the hope that it will be useful, *
|
||||||
|
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
# * GNU Library General Public License for more details. *
|
||||||
|
# * *
|
||||||
|
# * You should have received a copy of the GNU Library General Public *
|
||||||
|
# * License along with this program; if not, write to the Free Software *
|
||||||
|
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||||
|
# * USA *
|
||||||
|
# * *
|
||||||
|
# ***************************************************************************
|
||||||
|
|
||||||
|
__title__ = "FreeCAD FEM calculix write inpfile materials"
|
||||||
|
__author__ = "Bernd Hahnebach"
|
||||||
|
__url__ = "https://www.freecadweb.org"
|
||||||
|
|
||||||
|
|
||||||
|
import FreeCAD
|
||||||
|
|
||||||
|
|
||||||
|
def write_femelement_material(f, ccxwriter):
|
||||||
|
|
||||||
|
# helper inside class method
|
||||||
|
def is_density_needed():
|
||||||
|
if ccxwriter.analysis_type == "frequency":
|
||||||
|
return True
|
||||||
|
if (
|
||||||
|
ccxwriter.analysis_type == "thermomech"
|
||||||
|
and not ccxwriter.solver_obj.ThermoMechSteadyState
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
if ccxwriter.centrif_objects:
|
||||||
|
return True
|
||||||
|
if ccxwriter.selfweight_objects:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
f.write("\n{}\n".format(59 * "*"))
|
||||||
|
f.write("** Materials\n")
|
||||||
|
f.write("** Young\'s modulus unit is MPa = N/mm2\n")
|
||||||
|
if is_density_needed() is True:
|
||||||
|
f.write("** Density\'s unit is t/mm^3\n")
|
||||||
|
if ccxwriter.analysis_type == "thermomech":
|
||||||
|
f.write("** Thermal conductivity unit is kW/mm/K = t*mm/K*s^3\n")
|
||||||
|
f.write("** Specific Heat unit is kJ/t/K = mm^2/s^2/K\n")
|
||||||
|
for femobj in ccxwriter.material_objects:
|
||||||
|
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||||
|
mat_obj = femobj["Object"]
|
||||||
|
mat_info_name = mat_obj.Material["Name"]
|
||||||
|
mat_name = mat_obj.Name
|
||||||
|
mat_label = mat_obj.Label
|
||||||
|
# get material properties of solid material, Currently in SI units: M/kg/s/Kelvin
|
||||||
|
if mat_obj.Category == "Solid":
|
||||||
|
YM = FreeCAD.Units.Quantity(mat_obj.Material["YoungsModulus"])
|
||||||
|
YM_in_MPa = float(YM.getValueAs("MPa"))
|
||||||
|
PR = float(mat_obj.Material["PoissonRatio"])
|
||||||
|
if is_density_needed() is True:
|
||||||
|
density = FreeCAD.Units.Quantity(mat_obj.Material["Density"])
|
||||||
|
density_in_tonne_per_mm3 = float(density.getValueAs("t/mm^3"))
|
||||||
|
if ccxwriter.analysis_type == "thermomech":
|
||||||
|
TC = FreeCAD.Units.Quantity(mat_obj.Material["ThermalConductivity"])
|
||||||
|
# SvdW: Add factor to force units to results base units
|
||||||
|
# of t/mm/s/K - W/m/K results in no factor needed
|
||||||
|
TC_in_WmK = float(TC.getValueAs("W/m/K"))
|
||||||
|
SH = FreeCAD.Units.Quantity(mat_obj.Material["SpecificHeat"])
|
||||||
|
# SvdW: Add factor to force units to results base units of t/mm/s/K
|
||||||
|
SH_in_JkgK = float(SH.getValueAs("J/kg/K")) * 1e+06
|
||||||
|
if mat_obj.Category == "Solid":
|
||||||
|
TEC = FreeCAD.Units.Quantity(mat_obj.Material["ThermalExpansionCoefficient"])
|
||||||
|
TEC_in_mmK = float(TEC.getValueAs("mm/mm/K"))
|
||||||
|
elif mat_obj.Category == "Fluid":
|
||||||
|
DV = FreeCAD.Units.Quantity(mat_obj.Material["DynamicViscosity"])
|
||||||
|
DV_in_tmms = float(DV.getValueAs("t/mm/s"))
|
||||||
|
# write material properties
|
||||||
|
f.write("** FreeCAD material name: " + mat_info_name + "\n")
|
||||||
|
f.write("** " + mat_label + "\n")
|
||||||
|
f.write("*MATERIAL, NAME=" + mat_name + "\n")
|
||||||
|
if mat_obj.Category == "Solid":
|
||||||
|
f.write("*ELASTIC\n")
|
||||||
|
f.write("{0:.0f}, {1:.3f}\n".format(YM_in_MPa, PR))
|
||||||
|
|
||||||
|
if is_density_needed() is True:
|
||||||
|
f.write("*DENSITY\n")
|
||||||
|
f.write("{0:.3e}\n".format(density_in_tonne_per_mm3))
|
||||||
|
if ccxwriter.analysis_type == "thermomech":
|
||||||
|
if mat_obj.Category == "Solid":
|
||||||
|
f.write("*CONDUCTIVITY\n")
|
||||||
|
f.write("{0:.3f}\n".format(TC_in_WmK))
|
||||||
|
f.write("*EXPANSION\n")
|
||||||
|
f.write("{0:.3e}\n".format(TEC_in_mmK))
|
||||||
|
f.write("*SPECIFIC HEAT\n")
|
||||||
|
f.write("{0:.3e}\n".format(SH_in_JkgK))
|
||||||
|
elif mat_obj.Category == "Fluid":
|
||||||
|
f.write("*FLUID CONSTANTS\n")
|
||||||
|
f.write("{0:.3e}, {1:.3e}\n".format(SH_in_JkgK, DV_in_tmms))
|
||||||
|
|
||||||
|
# nonlinear material properties
|
||||||
|
if ccxwriter.solver_obj.MaterialNonlinearity == "nonlinear":
|
||||||
|
|
||||||
|
for nlfemobj in ccxwriter.material_nonlinear_objects:
|
||||||
|
# femobj --> dict, FreeCAD document object is nlfemobj["Object"]
|
||||||
|
nl_mat_obj = nlfemobj["Object"]
|
||||||
|
if nl_mat_obj.LinearBaseMaterial == mat_obj:
|
||||||
|
if nl_mat_obj.MaterialModelNonlinearity == "simple hardening":
|
||||||
|
f.write("*PLASTIC\n")
|
||||||
|
if nl_mat_obj.YieldPoint1:
|
||||||
|
f.write(nl_mat_obj.YieldPoint1 + "\n")
|
||||||
|
if nl_mat_obj.YieldPoint2:
|
||||||
|
f.write(nl_mat_obj.YieldPoint2 + "\n")
|
||||||
|
if nl_mat_obj.YieldPoint3:
|
||||||
|
f.write(nl_mat_obj.YieldPoint3 + "\n")
|
||||||
|
f.write("\n")
|
||||||
|
|
||||||
|
|
||||||
|
# ************************************************************************************************
|
||||||
|
# Helpers
|
||||||
|
def liquid_section_def(obj, section_type):
|
||||||
|
if section_type == "PIPE MANNING":
|
||||||
|
manning_area = str(obj.ManningArea.getValueAs("mm^2").Value)
|
||||||
|
manning_radius = str(obj.ManningRadius.getValueAs("mm"))
|
||||||
|
manning_coefficient = str(obj.ManningCoefficient)
|
||||||
|
section_geo = manning_area + "," + manning_radius + "," + manning_coefficient + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE ENLARGEMENT":
|
||||||
|
enlarge_area1 = str(obj.EnlargeArea1.getValueAs("mm^2").Value)
|
||||||
|
enlarge_area2 = str(obj.EnlargeArea2.getValueAs("mm^2").Value)
|
||||||
|
section_geo = enlarge_area1 + "," + enlarge_area2 + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE CONTRACTION":
|
||||||
|
contract_area1 = str(obj.ContractArea1.getValueAs("mm^2").Value)
|
||||||
|
contract_area2 = str(obj.ContractArea2.getValueAs("mm^2").Value)
|
||||||
|
section_geo = contract_area1 + "," + contract_area2 + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE ENTRANCE":
|
||||||
|
entrance_pipe_area = str(obj.EntrancePipeArea.getValueAs("mm^2").Value)
|
||||||
|
entrance_area = str(obj.EntranceArea.getValueAs("mm^2").Value)
|
||||||
|
section_geo = entrance_pipe_area + "," + entrance_area + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE DIAPHRAGM":
|
||||||
|
diaphragm_pipe_area = str(obj.DiaphragmPipeArea.getValueAs("mm^2").Value)
|
||||||
|
diaphragm_area = str(obj.DiaphragmArea.getValueAs("mm^2").Value)
|
||||||
|
section_geo = diaphragm_pipe_area + "," + diaphragm_area + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE BEND":
|
||||||
|
bend_pipe_area = str(obj.BendPipeArea.getValueAs("mm^2").Value)
|
||||||
|
bend_radius_diameter = str(obj.BendRadiusDiameter)
|
||||||
|
bend_angle = str(obj.BendAngle)
|
||||||
|
bend_loss_coefficient = str(obj.BendLossCoefficient)
|
||||||
|
section_geo = ("{},{},{},{}\n".format(
|
||||||
|
bend_pipe_area,
|
||||||
|
bend_radius_diameter,
|
||||||
|
bend_angle,
|
||||||
|
bend_loss_coefficient
|
||||||
|
))
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE GATE VALVE":
|
||||||
|
gatevalve_pipe_area = str(obj.GateValvePipeArea.getValueAs("mm^2").Value)
|
||||||
|
gatevalve_closing_coeff = str(obj.GateValveClosingCoeff)
|
||||||
|
section_geo = gatevalve_pipe_area + "," + gatevalve_closing_coeff + "\n"
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "PIPE WHITE-COLEBROOK":
|
||||||
|
colebrooke_area = str(obj.ColebrookeArea.getValueAs("mm^2").Value)
|
||||||
|
colebrooke_diameter = str(2 * obj.ColebrookeRadius.getValueAs("mm"))
|
||||||
|
colebrooke_grain_diameter = str(obj.ColebrookeGrainDiameter.getValueAs("mm"))
|
||||||
|
colebrooke_form_factor = str(obj.ColebrookeFormFactor)
|
||||||
|
section_geo = ("{},{},{},{},{}\n".format(
|
||||||
|
colebrooke_area,
|
||||||
|
colebrooke_diameter,
|
||||||
|
"-1",
|
||||||
|
colebrooke_grain_diameter,
|
||||||
|
colebrooke_form_factor
|
||||||
|
))
|
||||||
|
return section_geo
|
||||||
|
elif section_type == "LIQUID PUMP":
|
||||||
|
section_geo = ""
|
||||||
|
for i in range(len(obj.PumpFlowRate)):
|
||||||
|
flow_rate = str(obj.PumpFlowRate[i])
|
||||||
|
top = str(obj.PumpHeadLoss[i])
|
||||||
|
section_geo = section_geo + flow_rate + "," + top + ","
|
||||||
|
section_geo = section_geo + "\n"
|
||||||
|
return section_geo
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# ***************************************************************************
|
||||||
|
# * Copyright (c) 2021 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||||
|
# * *
|
||||||
|
# * This file is part of the FreeCAD CAx development system. *
|
||||||
|
# * *
|
||||||
|
# * This program is free software; you can redistribute it and/or modify *
|
||||||
|
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||||
|
# * as published by the Free Software Foundation; either version 2 of *
|
||||||
|
# * the License, or (at your option) any later version. *
|
||||||
|
# * for detail see the LICENCE text file. *
|
||||||
|
# * *
|
||||||
|
# * This program is distributed in the hope that it will be useful, *
|
||||||
|
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
# * GNU Library General Public License for more details. *
|
||||||
|
# * *
|
||||||
|
# * You should have received a copy of the GNU Library General Public *
|
||||||
|
# * License along with this program; if not, write to the Free Software *
|
||||||
|
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||||
|
# * USA *
|
||||||
|
# * *
|
||||||
|
# ***************************************************************************
|
||||||
|
|
||||||
|
__title__ = "FreeCAD FEM calculix write inpfile material and geometry sets"
|
||||||
|
__author__ = "Bernd Hahnebach"
|
||||||
|
__url__ = "https://www.freecadweb.org"
|
||||||
|
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
|
def write_femelement_matgeosets(f, ccxwriter):
|
||||||
|
|
||||||
|
# write ccx_elsets to file
|
||||||
|
f.write("\n{}\n".format(59 * "*"))
|
||||||
|
f.write("** Element sets for materials and FEM element type (solid, shell, beam, fluid)\n")
|
||||||
|
for ccx_elset in ccxwriter.ccx_elsets:
|
||||||
|
f.write("*ELSET,ELSET=" + ccx_elset["ccx_elset_name"] + "\n")
|
||||||
|
# use six to be sure to be Python 2.7 and 3.x compatible
|
||||||
|
if isinstance(ccx_elset["ccx_elset"], six.string_types):
|
||||||
|
f.write(ccx_elset["ccx_elset"] + "\n")
|
||||||
|
else:
|
||||||
|
for elid in ccx_elset["ccx_elset"]:
|
||||||
|
f.write(str(elid) + ",\n")
|
||||||
@@ -29,7 +29,6 @@ __url__ = "https://www.freecadweb.org"
|
|||||||
## \addtogroup FEM
|
## \addtogroup FEM
|
||||||
# @{
|
# @{
|
||||||
|
|
||||||
import six
|
|
||||||
import time
|
import time
|
||||||
from os.path import join
|
from os.path import join
|
||||||
|
|
||||||
@@ -51,6 +50,9 @@ from . import write_constraint_selfweight as con_selfweight
|
|||||||
from . import write_constraint_temperature as con_temperature
|
from . import write_constraint_temperature as con_temperature
|
||||||
from . import write_constraint_tie as con_tie
|
from . import write_constraint_tie as con_tie
|
||||||
from . import write_constraint_transform as con_transform
|
from . import write_constraint_transform as con_transform
|
||||||
|
from . import write_femelement_geometry
|
||||||
|
from . import write_femelement_material
|
||||||
|
from . import write_femelement_matgeosets
|
||||||
from . import write_footer
|
from . import write_footer
|
||||||
from . import write_mesh
|
from . import write_mesh
|
||||||
from . import write_step_equation
|
from . import write_step_equation
|
||||||
@@ -161,8 +163,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
|||||||
inpfile = write_mesh.write_mesh(self)
|
inpfile = write_mesh.write_mesh(self)
|
||||||
|
|
||||||
# element sets for materials and element geometry
|
# element sets for materials and element geometry
|
||||||
# self.write_element_sets_material_and_femelement_geometry(inpfile)
|
write_femelement_matgeosets.write_femelement_matgeosets(inpfile, self)
|
||||||
self.write_element_sets_material_and_femelement_type(inpfile)
|
|
||||||
|
|
||||||
if self.fluidsection_objects:
|
if self.fluidsection_objects:
|
||||||
# some fluidsection objs need special treatment, ccx_elsets are needed for this
|
# some fluidsection objs need special treatment, ccx_elsets are needed for this
|
||||||
@@ -184,10 +185,9 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
|||||||
self.write_constraints_sets(inpfile, self.sectionprint_objects, con_sectionprint)
|
self.write_constraints_sets(inpfile, self.sectionprint_objects, con_sectionprint)
|
||||||
|
|
||||||
# materials and fem element types
|
# materials and fem element types
|
||||||
self.write_materials(inpfile)
|
write_femelement_material.write_femelement_material(inpfile, self)
|
||||||
self.write_constraints_data(inpfile, self.initialtemperature_objects, con_initialtemp)
|
self.write_constraints_data(inpfile, self.initialtemperature_objects, con_initialtemp)
|
||||||
# self.write_femelement_geometry(inpfile)
|
write_femelement_geometry.write_femelement_geometry(inpfile, self)
|
||||||
self.write_femelementsets(inpfile)
|
|
||||||
|
|
||||||
# constraints independent from steps
|
# constraints independent from steps
|
||||||
self.write_constraints_data(inpfile, self.planerotation_objects, con_planerotation)
|
self.write_constraints_data(inpfile, self.planerotation_objects, con_planerotation)
|
||||||
@@ -294,267 +294,4 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
|||||||
if write_after != "":
|
if write_after != "":
|
||||||
f.write(write_after)
|
f.write(write_after)
|
||||||
|
|
||||||
# ********************************************************************************************
|
|
||||||
# material and fem element geometry
|
|
||||||
# def write_element_sets_material_and_femelement_geometry(self, f):
|
|
||||||
def write_element_sets_material_and_femelement_type(self, f):
|
|
||||||
|
|
||||||
# write ccx_elsets to file
|
|
||||||
f.write("\n***********************************************************\n")
|
|
||||||
f.write("** Element sets for materials and FEM element type (solid, shell, beam, fluid)\n")
|
|
||||||
for ccx_elset in self.ccx_elsets:
|
|
||||||
f.write("*ELSET,ELSET=" + ccx_elset["ccx_elset_name"] + "\n")
|
|
||||||
# use six to be sure to be Python 2.7 and 3.x compatible
|
|
||||||
if isinstance(ccx_elset["ccx_elset"], six.string_types):
|
|
||||||
f.write(ccx_elset["ccx_elset"] + "\n")
|
|
||||||
else:
|
|
||||||
for elid in ccx_elset["ccx_elset"]:
|
|
||||||
f.write(str(elid) + ",\n")
|
|
||||||
|
|
||||||
def is_density_needed(self):
|
|
||||||
if self.analysis_type == "frequency":
|
|
||||||
return True
|
|
||||||
if self.analysis_type == "thermomech" and not self.solver_obj.ThermoMechSteadyState:
|
|
||||||
return True
|
|
||||||
if self.centrif_objects:
|
|
||||||
return True
|
|
||||||
if self.selfweight_objects:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def write_materials(self, f):
|
|
||||||
f.write("\n***********************************************************\n")
|
|
||||||
f.write("** Materials\n")
|
|
||||||
f.write("** Young\'s modulus unit is MPa = N/mm2\n")
|
|
||||||
if self.is_density_needed() is True:
|
|
||||||
f.write("** Density\'s unit is t/mm^3\n")
|
|
||||||
if self.analysis_type == "thermomech":
|
|
||||||
f.write("** Thermal conductivity unit is kW/mm/K = t*mm/K*s^3\n")
|
|
||||||
f.write("** Specific Heat unit is kJ/t/K = mm^2/s^2/K\n")
|
|
||||||
for femobj in self.material_objects:
|
|
||||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
|
||||||
mat_obj = femobj["Object"]
|
|
||||||
mat_info_name = mat_obj.Material["Name"]
|
|
||||||
mat_name = mat_obj.Name
|
|
||||||
mat_label = mat_obj.Label
|
|
||||||
# get material properties of solid material, Currently in SI units: M/kg/s/Kelvin
|
|
||||||
if mat_obj.Category == "Solid":
|
|
||||||
YM = FreeCAD.Units.Quantity(mat_obj.Material["YoungsModulus"])
|
|
||||||
YM_in_MPa = float(YM.getValueAs("MPa"))
|
|
||||||
PR = float(mat_obj.Material["PoissonRatio"])
|
|
||||||
if self.is_density_needed() is True:
|
|
||||||
density = FreeCAD.Units.Quantity(mat_obj.Material["Density"])
|
|
||||||
density_in_tonne_per_mm3 = float(density.getValueAs("t/mm^3"))
|
|
||||||
if self.analysis_type == "thermomech":
|
|
||||||
TC = FreeCAD.Units.Quantity(mat_obj.Material["ThermalConductivity"])
|
|
||||||
# SvdW: Add factor to force units to results base units
|
|
||||||
# of t/mm/s/K - W/m/K results in no factor needed
|
|
||||||
TC_in_WmK = float(TC.getValueAs("W/m/K"))
|
|
||||||
SH = FreeCAD.Units.Quantity(mat_obj.Material["SpecificHeat"])
|
|
||||||
# SvdW: Add factor to force units to results base units of t/mm/s/K
|
|
||||||
SH_in_JkgK = float(SH.getValueAs("J/kg/K")) * 1e+06
|
|
||||||
if mat_obj.Category == "Solid":
|
|
||||||
TEC = FreeCAD.Units.Quantity(mat_obj.Material["ThermalExpansionCoefficient"])
|
|
||||||
TEC_in_mmK = float(TEC.getValueAs("mm/mm/K"))
|
|
||||||
elif mat_obj.Category == "Fluid":
|
|
||||||
DV = FreeCAD.Units.Quantity(mat_obj.Material["DynamicViscosity"])
|
|
||||||
DV_in_tmms = float(DV.getValueAs("t/mm/s"))
|
|
||||||
# write material properties
|
|
||||||
f.write("** FreeCAD material name: " + mat_info_name + "\n")
|
|
||||||
f.write("** " + mat_label + "\n")
|
|
||||||
f.write("*MATERIAL, NAME=" + mat_name + "\n")
|
|
||||||
if mat_obj.Category == "Solid":
|
|
||||||
f.write("*ELASTIC\n")
|
|
||||||
f.write("{0:.0f}, {1:.3f}\n".format(YM_in_MPa, PR))
|
|
||||||
|
|
||||||
if self.is_density_needed() is True:
|
|
||||||
f.write("*DENSITY\n")
|
|
||||||
f.write("{0:.3e}\n".format(density_in_tonne_per_mm3))
|
|
||||||
if self.analysis_type == "thermomech":
|
|
||||||
if mat_obj.Category == "Solid":
|
|
||||||
f.write("*CONDUCTIVITY\n")
|
|
||||||
f.write("{0:.3f}\n".format(TC_in_WmK))
|
|
||||||
f.write("*EXPANSION\n")
|
|
||||||
f.write("{0:.3e}\n".format(TEC_in_mmK))
|
|
||||||
f.write("*SPECIFIC HEAT\n")
|
|
||||||
f.write("{0:.3e}\n".format(SH_in_JkgK))
|
|
||||||
elif mat_obj.Category == "Fluid":
|
|
||||||
f.write("*FLUID CONSTANTS\n")
|
|
||||||
f.write("{0:.3e}, {1:.3e}\n".format(SH_in_JkgK, DV_in_tmms))
|
|
||||||
|
|
||||||
# nonlinear material properties
|
|
||||||
if self.solver_obj.MaterialNonlinearity == "nonlinear":
|
|
||||||
|
|
||||||
for nlfemobj in self.material_nonlinear_objects:
|
|
||||||
# femobj --> dict, FreeCAD document object is nlfemobj["Object"]
|
|
||||||
nl_mat_obj = nlfemobj["Object"]
|
|
||||||
if nl_mat_obj.LinearBaseMaterial == mat_obj:
|
|
||||||
if nl_mat_obj.MaterialModelNonlinearity == "simple hardening":
|
|
||||||
f.write("*PLASTIC\n")
|
|
||||||
if nl_mat_obj.YieldPoint1:
|
|
||||||
f.write(nl_mat_obj.YieldPoint1 + "\n")
|
|
||||||
if nl_mat_obj.YieldPoint2:
|
|
||||||
f.write(nl_mat_obj.YieldPoint2 + "\n")
|
|
||||||
if nl_mat_obj.YieldPoint3:
|
|
||||||
f.write(nl_mat_obj.YieldPoint3 + "\n")
|
|
||||||
f.write("\n")
|
|
||||||
|
|
||||||
# def write_femelement_geometry(self, f):
|
|
||||||
def write_femelementsets(self, f):
|
|
||||||
f.write("\n***********************************************************\n")
|
|
||||||
f.write("** Sections\n")
|
|
||||||
for ccx_elset in self.ccx_elsets:
|
|
||||||
if ccx_elset["ccx_elset"]:
|
|
||||||
if "beamsection_obj"in ccx_elset: # beam mesh
|
|
||||||
beamsec_obj = ccx_elset["beamsection_obj"]
|
|
||||||
elsetdef = "ELSET=" + ccx_elset["ccx_elset_name"] + ", "
|
|
||||||
material = "MATERIAL=" + ccx_elset["mat_obj_name"]
|
|
||||||
normal = ccx_elset["beam_normal"]
|
|
||||||
if beamsec_obj.SectionType == "Rectangular":
|
|
||||||
height = beamsec_obj.RectHeight.getValueAs("mm")
|
|
||||||
width = beamsec_obj.RectWidth.getValueAs("mm")
|
|
||||||
section_type = ", SECTION=RECT"
|
|
||||||
section_geo = str(height) + ", " + str(width) + "\n"
|
|
||||||
section_def = "*BEAM SECTION, {}{}{}\n".format(
|
|
||||||
elsetdef,
|
|
||||||
material,
|
|
||||||
section_type
|
|
||||||
)
|
|
||||||
elif beamsec_obj.SectionType == "Circular":
|
|
||||||
radius = 0.5 * beamsec_obj.CircDiameter.getValueAs("mm")
|
|
||||||
section_type = ", SECTION=CIRC"
|
|
||||||
section_geo = str(radius) + "\n"
|
|
||||||
section_def = "*BEAM SECTION, {}{}{}\n".format(
|
|
||||||
elsetdef,
|
|
||||||
material,
|
|
||||||
section_type
|
|
||||||
)
|
|
||||||
elif beamsec_obj.SectionType == "Pipe":
|
|
||||||
radius = 0.5 * beamsec_obj.PipeDiameter.getValueAs("mm")
|
|
||||||
thickness = beamsec_obj.PipeThickness.getValueAs("mm")
|
|
||||||
section_type = ", SECTION=PIPE"
|
|
||||||
section_geo = str(radius) + ", " + str(thickness) + "\n"
|
|
||||||
section_def = "*BEAM GENERAL SECTION, {}{}{}\n".format(
|
|
||||||
elsetdef,
|
|
||||||
material,
|
|
||||||
section_type
|
|
||||||
)
|
|
||||||
# see forum topic for output formatting of rotation
|
|
||||||
# https://forum.freecadweb.org/viewtopic.php?f=18&t=46133&p=405142#p405142
|
|
||||||
section_nor = "{:f}, {:f}, {:f}\n".format(
|
|
||||||
normal[0],
|
|
||||||
normal[1],
|
|
||||||
normal[2]
|
|
||||||
)
|
|
||||||
f.write(section_def)
|
|
||||||
f.write(section_geo)
|
|
||||||
f.write(section_nor)
|
|
||||||
elif "fluidsection_obj"in ccx_elset: # fluid mesh
|
|
||||||
fluidsec_obj = ccx_elset["fluidsection_obj"]
|
|
||||||
elsetdef = "ELSET=" + ccx_elset["ccx_elset_name"] + ", "
|
|
||||||
material = "MATERIAL=" + ccx_elset["mat_obj_name"]
|
|
||||||
if fluidsec_obj.SectionType == "Liquid":
|
|
||||||
section_type = fluidsec_obj.LiquidSectionType
|
|
||||||
if (section_type == "PIPE INLET") or (section_type == "PIPE OUTLET"):
|
|
||||||
section_type = "PIPE INOUT"
|
|
||||||
section_def = "*FLUID SECTION, {}TYPE={}, {}\n".format(
|
|
||||||
elsetdef,
|
|
||||||
section_type,
|
|
||||||
material
|
|
||||||
)
|
|
||||||
section_geo = liquid_section_def(fluidsec_obj, section_type)
|
|
||||||
"""
|
|
||||||
# deactivate as it would result in section_def and section_geo not defined
|
|
||||||
# deactivated in the App and Gui object and thus in the task panel as well
|
|
||||||
elif fluidsec_obj.SectionType == "Gas":
|
|
||||||
section_type = fluidsec_obj.GasSectionType
|
|
||||||
elif fluidsec_obj.SectionType == "Open Channel":
|
|
||||||
section_type = fluidsec_obj.ChannelSectionType
|
|
||||||
"""
|
|
||||||
f.write(section_def)
|
|
||||||
f.write(section_geo)
|
|
||||||
elif "shellthickness_obj"in ccx_elset: # shell mesh
|
|
||||||
shellth_obj = ccx_elset["shellthickness_obj"]
|
|
||||||
elsetdef = "ELSET=" + ccx_elset["ccx_elset_name"] + ", "
|
|
||||||
material = "MATERIAL=" + ccx_elset["mat_obj_name"]
|
|
||||||
section_def = "*SHELL SECTION, " + elsetdef + material + "\n"
|
|
||||||
section_geo = str(shellth_obj.Thickness.getValueAs("mm")) + "\n"
|
|
||||||
f.write(section_def)
|
|
||||||
f.write(section_geo)
|
|
||||||
else: # solid mesh
|
|
||||||
elsetdef = "ELSET=" + ccx_elset["ccx_elset_name"] + ", "
|
|
||||||
material = "MATERIAL=" + ccx_elset["mat_obj_name"]
|
|
||||||
section_def = "*SOLID SECTION, " + elsetdef + material + "\n"
|
|
||||||
f.write(section_def)
|
|
||||||
|
|
||||||
|
|
||||||
# ************************************************************************************************
|
|
||||||
# Helpers
|
|
||||||
def liquid_section_def(obj, section_type):
|
|
||||||
if section_type == "PIPE MANNING":
|
|
||||||
manning_area = str(obj.ManningArea.getValueAs("mm^2").Value)
|
|
||||||
manning_radius = str(obj.ManningRadius.getValueAs("mm"))
|
|
||||||
manning_coefficient = str(obj.ManningCoefficient)
|
|
||||||
section_geo = manning_area + "," + manning_radius + "," + manning_coefficient + "\n"
|
|
||||||
return section_geo
|
|
||||||
elif section_type == "PIPE ENLARGEMENT":
|
|
||||||
enlarge_area1 = str(obj.EnlargeArea1.getValueAs("mm^2").Value)
|
|
||||||
enlarge_area2 = str(obj.EnlargeArea2.getValueAs("mm^2").Value)
|
|
||||||
section_geo = enlarge_area1 + "," + enlarge_area2 + "\n"
|
|
||||||
return section_geo
|
|
||||||
elif section_type == "PIPE CONTRACTION":
|
|
||||||
contract_area1 = str(obj.ContractArea1.getValueAs("mm^2").Value)
|
|
||||||
contract_area2 = str(obj.ContractArea2.getValueAs("mm^2").Value)
|
|
||||||
section_geo = contract_area1 + "," + contract_area2 + "\n"
|
|
||||||
return section_geo
|
|
||||||
elif section_type == "PIPE ENTRANCE":
|
|
||||||
entrance_pipe_area = str(obj.EntrancePipeArea.getValueAs("mm^2").Value)
|
|
||||||
entrance_area = str(obj.EntranceArea.getValueAs("mm^2").Value)
|
|
||||||
section_geo = entrance_pipe_area + "," + entrance_area + "\n"
|
|
||||||
return section_geo
|
|
||||||
elif section_type == "PIPE DIAPHRAGM":
|
|
||||||
diaphragm_pipe_area = str(obj.DiaphragmPipeArea.getValueAs("mm^2").Value)
|
|
||||||
diaphragm_area = str(obj.DiaphragmArea.getValueAs("mm^2").Value)
|
|
||||||
section_geo = diaphragm_pipe_area + "," + diaphragm_area + "\n"
|
|
||||||
return section_geo
|
|
||||||
elif section_type == "PIPE BEND":
|
|
||||||
bend_pipe_area = str(obj.BendPipeArea.getValueAs("mm^2").Value)
|
|
||||||
bend_radius_diameter = str(obj.BendRadiusDiameter)
|
|
||||||
bend_angle = str(obj.BendAngle)
|
|
||||||
bend_loss_coefficient = str(obj.BendLossCoefficient)
|
|
||||||
section_geo = ("{},{},{},{}\n".format(
|
|
||||||
bend_pipe_area,
|
|
||||||
bend_radius_diameter,
|
|
||||||
bend_angle,
|
|
||||||
bend_loss_coefficient
|
|
||||||
))
|
|
||||||
return section_geo
|
|
||||||
elif section_type == "PIPE GATE VALVE":
|
|
||||||
gatevalve_pipe_area = str(obj.GateValvePipeArea.getValueAs("mm^2").Value)
|
|
||||||
gatevalve_closing_coeff = str(obj.GateValveClosingCoeff)
|
|
||||||
section_geo = gatevalve_pipe_area + "," + gatevalve_closing_coeff + "\n"
|
|
||||||
return section_geo
|
|
||||||
elif section_type == "PIPE WHITE-COLEBROOK":
|
|
||||||
colebrooke_area = str(obj.ColebrookeArea.getValueAs("mm^2").Value)
|
|
||||||
colebrooke_diameter = str(2 * obj.ColebrookeRadius.getValueAs("mm"))
|
|
||||||
colebrooke_grain_diameter = str(obj.ColebrookeGrainDiameter.getValueAs("mm"))
|
|
||||||
colebrooke_form_factor = str(obj.ColebrookeFormFactor)
|
|
||||||
section_geo = ("{},{},{},{},{}\n".format(
|
|
||||||
colebrooke_area,
|
|
||||||
colebrooke_diameter,
|
|
||||||
"-1",
|
|
||||||
colebrooke_grain_diameter,
|
|
||||||
colebrooke_form_factor
|
|
||||||
))
|
|
||||||
return section_geo
|
|
||||||
elif section_type == "LIQUID PUMP":
|
|
||||||
section_geo = ""
|
|
||||||
for i in range(len(obj.PumpFlowRate)):
|
|
||||||
flow_rate = str(obj.PumpFlowRate[i])
|
|
||||||
top = str(obj.PumpHeadLoss[i])
|
|
||||||
section_geo = section_geo + flow_rate + "," + top + ","
|
|
||||||
section_geo = section_geo + "\n"
|
|
||||||
return section_geo
|
|
||||||
else:
|
|
||||||
return ""
|
|
||||||
## @}
|
## @}
|
||||||
|
|||||||
Reference in New Issue
Block a user