Merge branch 'FreeCAD:master' into master
This commit is contained in:
@@ -581,7 +581,7 @@ class _ViewProviderAxis:
|
||||
t.string = self.getNumber(vobj,num)
|
||||
num += 1
|
||||
if hasattr(vobj,"BubblePosition"):
|
||||
if vobj.BubblePosition == "Both":
|
||||
if vobj.BubblePosition in ["Both","Arrow left","Arrow right","Bar left","Bar right"]:
|
||||
if not alt:
|
||||
num -= 1
|
||||
alt = not alt
|
||||
@@ -593,7 +593,11 @@ class _ViewProviderAxis:
|
||||
if hasattr(vobj,"ShowLabel") and hasattr(vobj.Object,"Labels"):
|
||||
if vobj.ShowLabel:
|
||||
self.labels = coin.SoSeparator()
|
||||
for i in range(len(vobj.Object.Shape.Edges)):
|
||||
if hasattr(vobj.Object,"Limit") and vobj.Object.Limit.Value:
|
||||
n = len(vobj.Object.Shape.Edges)/2
|
||||
else:
|
||||
n = len(vobj.Object.Shape.Edges)
|
||||
for i in range(n):
|
||||
if len(vobj.Object.Labels) > i:
|
||||
if vobj.Object.Labels[i]:
|
||||
import Draft
|
||||
|
||||
@@ -1140,6 +1140,7 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent):
|
||||
|
||||
pairs = [["Mode"+str(i),"Mode"+str(i+1)] for i in range(1,len(WindowOpeningModes),2)]
|
||||
self.invertPairs(pairs)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def invertHinge(self):
|
||||
|
||||
@@ -1147,6 +1148,8 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent):
|
||||
|
||||
pairs = [["Edge6","Edge8"],["Edge5","Edge7"]]
|
||||
self.invertPairs(pairs)
|
||||
self.invertOpening()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def invertPairs(self,pairs):
|
||||
|
||||
@@ -1166,7 +1169,6 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent):
|
||||
nparts.append(part)
|
||||
if nparts != self.Object.WindowParts:
|
||||
self.Object.WindowParts = nparts
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(translate("Arch","This window has no defined opening")+"\n")
|
||||
|
||||
|
||||
@@ -292,11 +292,11 @@ class Shape2DView(DraftObject):
|
||||
if sh.Volume < 0:
|
||||
sh.reverse()
|
||||
c = sh.section(cutp)
|
||||
if hasattr(obj,"InPlace"):
|
||||
if not obj.InPlace:
|
||||
c = self.getProjected(obj, c, proj)
|
||||
faces = []
|
||||
if (obj.ProjectionMode == "Cutfaces") and (sh.ShapeType == "Solid"):
|
||||
if hasattr(obj,"InPlace"):
|
||||
if not obj.InPlace:
|
||||
c = self.getProjected(obj, c, proj)
|
||||
wires = DraftGeomUtils.findWires(c.Edges)
|
||||
for w in wires:
|
||||
if w.isClosed():
|
||||
|
||||
@@ -95,7 +95,7 @@ def display_external(internal_value,
|
||||
if dim == 'Length':
|
||||
q = App.Units.Quantity(internal_value, App.Units.Length)
|
||||
if not unit:
|
||||
if not decimals and showUnit:
|
||||
if decimals == None and showUnit:
|
||||
return q.UserString
|
||||
|
||||
conversion = q.getUserPreferred()[1]
|
||||
|
||||
@@ -465,6 +465,9 @@ class ViewProviderDraft(object):
|
||||
return ":/icons/Draft_N-Curve.svg"
|
||||
elif tp in ("ShapeString"):
|
||||
return ":/icons/Draft_ShapeString_tree.svg"
|
||||
if hasattr(self.Object,"AutoUpdate") and not self.Object.AutoUpdate:
|
||||
import TechDrawGui
|
||||
return ":/icons/TechDraw_TreePageUnsync.svg"
|
||||
return ":/icons/Draft_Draft.svg"
|
||||
|
||||
def claimChildren(self):
|
||||
|
||||
@@ -133,6 +133,7 @@ SET(FemMesh_SRCS
|
||||
femmesh/__init__.py
|
||||
femmesh/femmesh2mesh.py
|
||||
femmesh/gmshtools.py
|
||||
femmesh/meshsetsgetter.py
|
||||
femmesh/meshtools.py
|
||||
)
|
||||
|
||||
|
||||
1056
src/Mod/Fem/femmesh/meshsetsgetter.py
Normal file
1056
src/Mod/Fem/femmesh/meshsetsgetter.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,7 @@ from .. import run
|
||||
from .. import settings
|
||||
from feminout import importCcxDatResults
|
||||
from feminout import importCcxFrdResults
|
||||
from femmesh import meshsetsgetter
|
||||
from femtools import femutils
|
||||
from femtools import membertools
|
||||
|
||||
@@ -60,14 +61,30 @@ 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
|
||||
|
||||
# get mesh set data
|
||||
# TODO evaluate if it makes sense to add new task
|
||||
# between check and prepare to the solver frame work
|
||||
meshdatagetter = meshsetsgetter.MeshSetsGetter(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
mesh_obj,
|
||||
membertools.AnalysisMember(self.analysis),
|
||||
)
|
||||
meshdatagetter.get_mesh_sets()
|
||||
|
||||
# write input file
|
||||
w = writer.FemInputWriterCcx(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
membertools.get_mesh_to_solve(self.analysis)[0], # pre check has been done already
|
||||
membertools.AnalysisMember(self.analysis),
|
||||
self.directory
|
||||
mesh_obj,
|
||||
meshdatagetter.member,
|
||||
self.directory,
|
||||
meshdatagetter.mat_geo_sets
|
||||
)
|
||||
path = w.write_calculix_input_file()
|
||||
path = w.write_solver_input()
|
||||
# report to user if task succeeded
|
||||
if path != "":
|
||||
self.pushStatus("Write completed!")
|
||||
|
||||
@@ -78,7 +78,7 @@ def write_constraint(f, femobj, disp_obj, ccxwriter):
|
||||
elif not disp_obj.zFree:
|
||||
f.write("{},3,3,{:.13G}\n".format(disp_obj.Name, disp_obj.zDisplacement))
|
||||
|
||||
if ccxwriter.beamsection_objects or ccxwriter.shellthickness_objects:
|
||||
if ccxwriter.member.geos_beamsection or ccxwriter.member.geos_shellthickness:
|
||||
if disp_obj.rotxFix:
|
||||
f.write("{},4\n".format(disp_obj.Name))
|
||||
elif not disp_obj.rotxFree:
|
||||
|
||||
@@ -57,7 +57,10 @@ def get_after_write_constraint():
|
||||
def write_meshdata_constraint(f, femobj, fix_obj, ccxwriter):
|
||||
if (
|
||||
ccxwriter.femmesh.Volumes
|
||||
and (len(ccxwriter.shellthickness_objects) > 0 or len(ccxwriter.beamsection_objects) > 0)
|
||||
and (
|
||||
len(ccxwriter.member.geos_shellthickness) > 0
|
||||
or len(ccxwriter.member.geos_beamsection) > 0
|
||||
)
|
||||
):
|
||||
if len(femobj["NodesSolid"]) > 0:
|
||||
f.write("*NSET,NSET={}Solid\n".format(fix_obj.Name))
|
||||
@@ -79,7 +82,10 @@ def write_constraint(f, femobj, fix_obj, ccxwriter):
|
||||
|
||||
if (
|
||||
ccxwriter.femmesh.Volumes
|
||||
and (len(ccxwriter.shellthickness_objects) > 0 or len(ccxwriter.beamsection_objects) > 0)
|
||||
and (
|
||||
len(ccxwriter.member.geos_shellthickness) > 0
|
||||
or len(ccxwriter.member.geos_beamsection) > 0
|
||||
)
|
||||
):
|
||||
if len(femobj["NodesSolid"]) > 0:
|
||||
f.write("*BOUNDARY\n")
|
||||
@@ -101,7 +107,7 @@ def write_constraint(f, femobj, fix_obj, ccxwriter):
|
||||
f.write(fix_obj.Name + ",1\n")
|
||||
f.write(fix_obj.Name + ",2\n")
|
||||
f.write(fix_obj.Name + ",3\n")
|
||||
if ccxwriter.beamsection_objects or ccxwriter.shellthickness_objects:
|
||||
if ccxwriter.member.geos_beamsection or ccxwriter.member.geos_shellthickness:
|
||||
f.write(fix_obj.Name + ",4\n")
|
||||
f.write(fix_obj.Name + ",5\n")
|
||||
f.write(fix_obj.Name + ",6\n")
|
||||
|
||||
@@ -43,14 +43,14 @@ from femmesh import meshtools
|
||||
# as it is none standard constraint method compared to all other constraints
|
||||
def handle_fluidsection_liquid_inlet_outlet(inpfile, ccxwriter):
|
||||
|
||||
if not ccxwriter.fluidsection_objects:
|
||||
if not ccxwriter.member.geos_fluidsection:
|
||||
return inpfile
|
||||
|
||||
# Fluid sections:
|
||||
# fluidsection Liquid inlet outlet objs requires special element definition
|
||||
# to fill ccxwriter.FluidInletoutlet_ele list the ccx_elset are needed
|
||||
# thus this has to be after the creation of ccx_elsets
|
||||
# different pipe cross sections will generate ccx_elsets
|
||||
# thus this has to be after the creation of mat_geo_sets
|
||||
# different pipe cross sections will generate mat_geo_sets
|
||||
|
||||
ccxwriter.FluidInletoutlet_ele = []
|
||||
ccxwriter.fluid_inout_nodes_file = join(
|
||||
@@ -76,8 +76,8 @@ def handle_fluidsection_liquid_inlet_outlet(inpfile, ccxwriter):
|
||||
return fluidsec_obj
|
||||
return None
|
||||
|
||||
def is_fluidsection_inoutlet_setnames_possible(ccx_elsets):
|
||||
for ccx_elset in ccx_elsets:
|
||||
def is_fluidsection_inoutlet_setnames_possible(mat_geo_sets):
|
||||
for ccx_elset in mat_geo_sets:
|
||||
if (
|
||||
ccx_elset["ccx_elset"]
|
||||
and "fluidsection_obj" in ccx_elset # fluid mesh
|
||||
@@ -95,7 +95,7 @@ def handle_fluidsection_liquid_inlet_outlet(inpfile, ccxwriter):
|
||||
|
||||
# collect elementIDs for fluidsection Liquid inlet outlet objs
|
||||
# if they have element data (happens if not "eall")
|
||||
for ccx_elset in ccxwriter.ccx_elsets:
|
||||
for ccx_elset in ccxwriter.mat_geo_sets:
|
||||
fluidsec_obj = get_fluidsection_inoutlet_obj_if_setdata(ccx_elset)
|
||||
if fluidsec_obj is None:
|
||||
continue
|
||||
@@ -118,9 +118,9 @@ def handle_fluidsection_liquid_inlet_outlet(inpfile, ccxwriter):
|
||||
)
|
||||
|
||||
# create the correct element definition for fluidsection Liquid inlet outlet objs
|
||||
# at least one "fluidsection_obj" needs to be in ccx_elsets and has the attributes
|
||||
# at least one "fluidsection_obj" needs to be in mat_geo_sets and has the attributes
|
||||
# TODO: what if there are other objs in elsets?
|
||||
if is_fluidsection_inoutlet_setnames_possible(ccxwriter.ccx_elsets) is not None:
|
||||
if is_fluidsection_inoutlet_setnames_possible(ccxwriter.mat_geo_sets) is not None:
|
||||
# it is not distinguished if split input file
|
||||
# for split input file the main file is just closed and reopend even if not needed
|
||||
inpfile.close()
|
||||
@@ -139,7 +139,7 @@ def handle_fluidsection_liquid_inlet_outlet(inpfile, ccxwriter):
|
||||
# split method into separate methods and move some part into base writer
|
||||
# see also method handle_fluidsection_liquid_inlet_outlet
|
||||
def write_constraints_fluidsection(f, ccxwriter):
|
||||
if not ccxwriter.fluidsection_objects:
|
||||
if not ccxwriter.member.geos_fluidsection:
|
||||
return
|
||||
if ccxwriter.analysis_type not in ["thermomech"]:
|
||||
return
|
||||
@@ -158,7 +158,7 @@ def write_constraints_fluidsection(f, ccxwriter):
|
||||
)
|
||||
# get nodes
|
||||
ccxwriter.get_constraints_fluidsection_nodes()
|
||||
for femobj in ccxwriter.fluidsection_objects:
|
||||
for femobj in ccxwriter.member.geos_fluidsection:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
fluidsection_obj = femobj["Object"]
|
||||
f.write("** " + fluidsection_obj.Label + "\n")
|
||||
|
||||
@@ -32,7 +32,7 @@ def write_femelement_geometry(f, ccxwriter):
|
||||
|
||||
f.write("\n{}\n".format(59 * "*"))
|
||||
f.write("** Sections\n")
|
||||
for ccx_elset in ccxwriter.ccx_elsets:
|
||||
for ccx_elset in ccxwriter.mat_geo_sets:
|
||||
if ccx_elset["ccx_elset"]:
|
||||
elsetdef = "ELSET={}, ".format(ccx_elset["ccx_elset_name"])
|
||||
material = "MATERIAL={}".format(ccx_elset["mat_obj_name"])
|
||||
|
||||
@@ -42,16 +42,16 @@ def write_femelement_material(f, ccxwriter):
|
||||
and not ccxwriter.solver_obj.ThermoMechSteadyState
|
||||
):
|
||||
return True
|
||||
if ccxwriter.centrif_objects:
|
||||
if ccxwriter.member.cons_centrif:
|
||||
return True
|
||||
if ccxwriter.selfweight_objects:
|
||||
if ccxwriter.member.cons_selfweight:
|
||||
return True
|
||||
return False
|
||||
|
||||
f.write("\n{}\n".format(59 * "*"))
|
||||
f.write("** Materials\n")
|
||||
f.write("** see information about units at file end\n")
|
||||
for femobj in ccxwriter.material_objects:
|
||||
for femobj in ccxwriter.member.mats_linear:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
mat_obj = femobj["Object"]
|
||||
mat_info_name = mat_obj.Material["Name"]
|
||||
@@ -107,7 +107,7 @@ def write_femelement_material(f, ccxwriter):
|
||||
# nonlinear material properties
|
||||
if ccxwriter.solver_obj.MaterialNonlinearity == "nonlinear":
|
||||
|
||||
for nlfemobj in ccxwriter.material_nonlinear_objects:
|
||||
for nlfemobj in ccxwriter.member.mats_nonlinear:
|
||||
# femobj --> dict, FreeCAD document object is nlfemobj["Object"]
|
||||
nl_mat_obj = nlfemobj["Object"]
|
||||
if nl_mat_obj.LinearBaseMaterial == mat_obj:
|
||||
|
||||
@@ -31,14 +31,17 @@ import six
|
||||
|
||||
def write_femelement_matgeosets(f, ccxwriter):
|
||||
|
||||
# write ccx_elsets to file
|
||||
# write mat_geo_sets 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")
|
||||
|
||||
for ccx_elset in ccxwriter.mat_geo_sets:
|
||||
|
||||
f.write("*ELSET,ELSET={}\n".format(ccx_elset["ccx_elset_name"]))
|
||||
|
||||
# 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")
|
||||
f.write("{}\n".format(ccx_elset["ccx_elset"]))
|
||||
else:
|
||||
for elid in ccx_elset["ccx_elset"]:
|
||||
f.write(str(elid) + ",\n")
|
||||
|
||||
@@ -48,7 +48,7 @@ def write_mesh(ccxwriter):
|
||||
)
|
||||
|
||||
# Check to see if fluid sections are in analysis and use D network element type
|
||||
if ccxwriter.fluidsection_objects:
|
||||
if ccxwriter.member.geos_fluidsection:
|
||||
meshtools.write_D_network_element_to_inputfile(ccxwriter.femmesh_file)
|
||||
|
||||
inpfile = codecs.open(ccxwriter.file_name, "w", encoding="utf-8")
|
||||
@@ -65,7 +65,7 @@ def write_mesh(ccxwriter):
|
||||
)
|
||||
|
||||
# Check to see if fluid sections are in analysis and use D network element type
|
||||
if ccxwriter.fluidsection_objects:
|
||||
if ccxwriter.member.geos_fluidsection:
|
||||
# inpfile is closed
|
||||
meshtools.write_D_network_element_to_inputfile(ccxwriter.femmesh_file)
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ def write_step_output(f, ccxwriter):
|
||||
f.write("\n{}\n".format(59 * "*"))
|
||||
f.write("** Outputs --> frd file\n")
|
||||
if (
|
||||
ccxwriter.beamsection_objects
|
||||
or ccxwriter.shellthickness_objects
|
||||
or ccxwriter.fluidsection_objects
|
||||
ccxwriter.member.geos_beamsection
|
||||
or ccxwriter.member.geos_shellthickness
|
||||
or ccxwriter.member.geos_fluidsection
|
||||
):
|
||||
if ccxwriter.solver_obj.BeamShellResultOutput3D is False:
|
||||
f.write("*NODE FILE, OUTPUT=2d\n")
|
||||
@@ -43,13 +43,13 @@ def write_step_output(f, ccxwriter):
|
||||
f.write("*NODE FILE\n")
|
||||
# MPH write out nodal temperatures if thermomechanical
|
||||
if ccxwriter.analysis_type == "thermomech":
|
||||
if not ccxwriter.fluidsection_objects:
|
||||
if not ccxwriter.member.geos_fluidsection:
|
||||
f.write("U, NT\n")
|
||||
else:
|
||||
f.write("MF, PS\n")
|
||||
else:
|
||||
f.write("U\n")
|
||||
if not ccxwriter.fluidsection_objects:
|
||||
if not ccxwriter.member.geos_fluidsection:
|
||||
f.write("*EL FILE\n")
|
||||
if ccxwriter.solver_obj.MaterialNonlinearity == "nonlinear":
|
||||
f.write("S, E, PEEQ\n")
|
||||
@@ -58,11 +58,11 @@ def write_step_output(f, ccxwriter):
|
||||
|
||||
# dat file
|
||||
# reaction forces: freecadweb.org/tracker/view.php?id=2934
|
||||
if ccxwriter.fixed_objects:
|
||||
if ccxwriter.member.cons_fixed:
|
||||
f.write("** outputs --> dat file\n")
|
||||
# reaction forces for all Constraint fixed
|
||||
f.write("** reaction forces for Constraint fixed\n")
|
||||
for femobj in ccxwriter.fixed_objects:
|
||||
for femobj in ccxwriter.member.cons_fixed:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
fix_obj_name = femobj["Object"].Name
|
||||
f.write("*NODE PRINT, NSET={}, TOTALS=ONLY\n".format(fix_obj_name))
|
||||
|
||||
@@ -42,7 +42,7 @@ from . import write_constraint_fixed as con_fixed
|
||||
from . import write_constraint_fluidsection as con_fluidsection
|
||||
from . import write_constraint_force as con_force
|
||||
from . import write_constraint_heatflux as con_heatflux
|
||||
from . import write_constraint_initialtemperature as con_initialtemp
|
||||
from . import write_constraint_initialtemperature as con_itemp
|
||||
from . import write_constraint_planerotation as con_planerotation
|
||||
from . import write_constraint_pressure as con_pressure
|
||||
from . import write_constraint_sectionprint as con_sectionprint
|
||||
@@ -110,7 +110,8 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
solver_obj,
|
||||
mesh_obj,
|
||||
member,
|
||||
dir_name=None
|
||||
dir_name=None,
|
||||
mat_geo_sets=None
|
||||
):
|
||||
writerbase.FemInputWriter.__init__(
|
||||
self,
|
||||
@@ -118,7 +119,8 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
solver_obj,
|
||||
mesh_obj,
|
||||
member,
|
||||
dir_name
|
||||
dir_name,
|
||||
mat_geo_sets
|
||||
)
|
||||
self.mesh_name = self.mesh_object.Name
|
||||
self.file_name = join(self.dir_name, self.mesh_name + ".inp")
|
||||
@@ -128,17 +130,14 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
|
||||
# ********************************************************************************************
|
||||
# write calculix input
|
||||
def write_calculix_input_file(self):
|
||||
def write_solver_input(self):
|
||||
|
||||
FreeCAD.Console.PrintMessage("Get mesh sets.\n")
|
||||
time_start = time.process_time()
|
||||
self.get_mesh_sets()
|
||||
time_getsets = time.process_time()
|
||||
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Start writing CalculiX input file to: {}\n"
|
||||
.format(self.file_name)
|
||||
)
|
||||
|
||||
if self.solver_obj.SplitInputWriter is True:
|
||||
FreeCAD.Console.PrintMessage("Split input file.\n")
|
||||
self.split_inpfile = True
|
||||
@@ -152,48 +151,48 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
# element sets for materials and element geometry
|
||||
write_femelement_matgeosets.write_femelement_matgeosets(inpfile, self)
|
||||
|
||||
# some fluidsection objs need special treatment, ccx_elsets are needed for this
|
||||
# some fluidsection objs need special treatment, mat_geo_sets are needed for this
|
||||
inpfile = con_fluidsection.handle_fluidsection_liquid_inlet_outlet(inpfile, self)
|
||||
|
||||
# element sets constraints
|
||||
self.write_constraints_meshsets(inpfile, self.centrif_objects, con_centrif)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_centrif, con_centrif)
|
||||
|
||||
# node sets
|
||||
self.write_constraints_meshsets(inpfile, self.fixed_objects, con_fixed)
|
||||
self.write_constraints_meshsets(inpfile, self.displacement_objects, con_displacement)
|
||||
self.write_constraints_meshsets(inpfile, self.planerotation_objects, con_planerotation)
|
||||
self.write_constraints_meshsets(inpfile, self.transform_objects, con_transform)
|
||||
self.write_constraints_meshsets(inpfile, self.temperature_objects, con_temperature)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_fixed, con_fixed)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_displacement, con_displacement)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_planerotation, con_planerotation)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_transform, con_transform)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_temperature, con_temperature)
|
||||
|
||||
# surface sets
|
||||
self.write_constraints_meshsets(inpfile, self.contact_objects, con_contact)
|
||||
self.write_constraints_meshsets(inpfile, self.tie_objects, con_tie)
|
||||
self.write_constraints_meshsets(inpfile, self.sectionprint_objects, con_sectionprint)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_contact, con_contact)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_tie, con_tie)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_sectionprint, con_sectionprint)
|
||||
|
||||
# materials and fem element types
|
||||
write_femelement_material.write_femelement_material(inpfile, self)
|
||||
self.write_constraints_propdata(inpfile, self.initialtemperature_objects, con_initialtemp)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_initialtemperature, con_itemp)
|
||||
write_femelement_geometry.write_femelement_geometry(inpfile, self)
|
||||
|
||||
# constraints independent from steps
|
||||
self.write_constraints_propdata(inpfile, self.planerotation_objects, con_planerotation)
|
||||
self.write_constraints_propdata(inpfile, self.contact_objects, con_contact)
|
||||
self.write_constraints_propdata(inpfile, self.tie_objects, con_tie)
|
||||
self.write_constraints_propdata(inpfile, self.transform_objects, con_transform)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_planerotation, con_planerotation)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_contact, con_contact)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_tie, con_tie)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_transform, con_transform)
|
||||
|
||||
# step equation
|
||||
write_step_equation.write_step_equation(inpfile, self)
|
||||
|
||||
# constraints dependent from steps
|
||||
self.write_constraints_propdata(inpfile, self.fixed_objects, con_fixed)
|
||||
self.write_constraints_propdata(inpfile, self.displacement_objects, con_displacement)
|
||||
self.write_constraints_propdata(inpfile, self.sectionprint_objects, con_sectionprint)
|
||||
self.write_constraints_propdata(inpfile, self.selfweight_objects, con_selfweight)
|
||||
self.write_constraints_propdata(inpfile, self.centrif_objects, con_centrif)
|
||||
self.write_constraints_meshsets(inpfile, self.force_objects, con_force)
|
||||
self.write_constraints_meshsets(inpfile, self.pressure_objects, con_pressure)
|
||||
self.write_constraints_propdata(inpfile, self.temperature_objects, con_temperature)
|
||||
self.write_constraints_meshsets(inpfile, self.heatflux_objects, con_heatflux)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_fixed, con_fixed)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_displacement, con_displacement)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_sectionprint, con_sectionprint)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_selfweight, con_selfweight)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_centrif, con_centrif)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_force, con_force)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_pressure, con_pressure)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_temperature, con_temperature)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_heatflux, con_heatflux)
|
||||
con_fluidsection.write_constraints_fluidsection(inpfile, self)
|
||||
|
||||
# output and step end
|
||||
@@ -206,19 +205,10 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
# close file
|
||||
inpfile.close()
|
||||
|
||||
setstime = round((time_getsets - time_start), 3)
|
||||
writetime = round((time.process_time() - time_getsets), 3)
|
||||
all_time = round((setstime + writetime), 3)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Getting mesh sets or groups time: {} seconds \n".format(setstime)
|
||||
)
|
||||
writetime = round((time.process_time() - time_start), 3)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Writing time CalculiX input file: {} seconds \n".format(writetime)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Overall time CalculiX input file: {} seconds \n\n"
|
||||
.format(all_time)
|
||||
)
|
||||
|
||||
# return
|
||||
if self.femelement_count_test is True:
|
||||
|
||||
@@ -84,7 +84,7 @@ class Prepare(run.Prepare):
|
||||
FreeCAD.Console.PrintLog("Machine testmode: {}\n".format(self.testmode))
|
||||
w = writer.Writer(self.solver, self.directory)
|
||||
try:
|
||||
w.write()
|
||||
w.write_solver_input()
|
||||
self.checkHandled(w)
|
||||
except writer.WriteError as e:
|
||||
self.report.error(str(e))
|
||||
|
||||
@@ -79,7 +79,7 @@ class Writer(object):
|
||||
def getHandledConstraints(self):
|
||||
return self._handledObjects
|
||||
|
||||
def write(self):
|
||||
def write_solver_input(self):
|
||||
self._handleRedifinedConstants()
|
||||
self._handleSimulation()
|
||||
self._handleHeat()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,7 @@ class Prepare(run.Prepare):
|
||||
membertools.AnalysisMember(self.analysis),
|
||||
self.directory
|
||||
)
|
||||
path = w.write_z88_input()
|
||||
path = w.write_solver_input()
|
||||
# report to user if task succeeded
|
||||
if path is not None:
|
||||
self.pushStatus("Write completed!")
|
||||
|
||||
@@ -63,7 +63,7 @@ class FemInputWriterZ88(writerbase.FemInputWriter):
|
||||
"FemInputWriterZ88 --> self.file_name --> " + self.file_name + "\n"
|
||||
)
|
||||
|
||||
def write_z88_input(self):
|
||||
def write_solver_input(self):
|
||||
timestart = time.process_time()
|
||||
FreeCAD.Console.PrintMessage("Write z88 input files to: {}\n".format(self.dir_name))
|
||||
if not self.femnodes_mesh:
|
||||
|
||||
@@ -487,7 +487,10 @@ class _TaskPanel:
|
||||
"May try the following in Python console:\n"
|
||||
"from FreeCAD import Units\n"
|
||||
"Units.Quantity('{}')\n"
|
||||
.format(self.material["ThermalConductivity"], self.material["ThermalConductivity"])
|
||||
.format(
|
||||
self.material["ThermalConductivity"],
|
||||
self.material["ThermalConductivity"]
|
||||
)
|
||||
)
|
||||
self.material["ThermalConductivity"] = "0 W/m/K"
|
||||
if "ThermalConductivity" not in str(Units.Unit(self.material["ThermalConductivity"])):
|
||||
|
||||
@@ -366,6 +366,20 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject):
|
||||
self.set_inp_file_name()
|
||||
|
||||
def write_inp_file(self):
|
||||
|
||||
# get mesh set data
|
||||
# TODO use separate method for getting the mesh set data
|
||||
from femmesh import meshsetsgetter
|
||||
meshdatagetter = meshsetsgetter.MeshSetsGetter(
|
||||
self.analysis,
|
||||
self.solver,
|
||||
self.mesh,
|
||||
membertools.AnalysisMember(self.analysis),
|
||||
)
|
||||
# save the sets into the member objects of the instanz meshdatagetter
|
||||
meshdatagetter.get_mesh_sets()
|
||||
|
||||
# write input file
|
||||
import femsolver.calculix.writer as iw
|
||||
self.inp_file_name = ""
|
||||
try:
|
||||
@@ -373,10 +387,11 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject):
|
||||
self.analysis,
|
||||
self.solver,
|
||||
self.mesh,
|
||||
self.member,
|
||||
self.working_dir
|
||||
meshdatagetter.member,
|
||||
self.working_dir,
|
||||
meshdatagetter.mat_geo_sets
|
||||
)
|
||||
self.inp_file_name = inp_writer.write_calculix_input_file()
|
||||
self.inp_file_name = inp_writer.write_solver_input()
|
||||
except Exception:
|
||||
FreeCAD.Console.PrintError(
|
||||
"Unexpected error when writing CalculiX input file: {}\n"
|
||||
|
||||
@@ -37,9 +37,11 @@ if sys.version_info.major >= 3:
|
||||
unicode = str
|
||||
|
||||
|
||||
# ************************************************************************************************
|
||||
# ************************************************************************************************
|
||||
class MaterialEditor:
|
||||
|
||||
def __init__(self, obj=None, prop=None, material=None, card_path=''):
|
||||
def __init__(self, obj=None, prop=None, material=None, card_path=""):
|
||||
|
||||
"""Initializes, optionally with an object name and a material property
|
||||
name to edit, or directly with a material dictionary."""
|
||||
@@ -139,7 +141,7 @@ class MaterialEditor:
|
||||
|
||||
def implementModel(self):
|
||||
|
||||
'''implements the model with the material attribute structure.'''
|
||||
"""implements the model with the material attribute structure."""
|
||||
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material")
|
||||
widget = self.widget
|
||||
@@ -163,13 +165,13 @@ class MaterialEditor:
|
||||
for properName in group[gg]:
|
||||
pp = properName # property name
|
||||
item = QtGui.QStandardItem(pp)
|
||||
item.setToolTip(group[gg][properName]['Description'])
|
||||
item.setToolTip(group[gg][properName]["Description"])
|
||||
self.internalprops.append(pp)
|
||||
|
||||
it = QtGui.QStandardItem()
|
||||
it.setToolTip(group[gg][properName]['Description'])
|
||||
it.setToolTip(group[gg][properName]["Description"])
|
||||
|
||||
tt = group[gg][properName]['Type']
|
||||
tt = group[gg][properName]["Type"]
|
||||
itType = QtGui.QStandardItem(tt)
|
||||
|
||||
top.appendRow([item, it, itType])
|
||||
@@ -180,9 +182,9 @@ class MaterialEditor:
|
||||
|
||||
def updateMatParamsInTree(self, data):
|
||||
|
||||
'''updates the contents of the editor with the given dictionary
|
||||
"""updates the contents of the editor with the given dictionary
|
||||
the material property keys where added to the editor already
|
||||
not known material property keys will be added to the user defined group'''
|
||||
not known material property keys will be added to the user defined group"""
|
||||
|
||||
# print(data)
|
||||
model = self.widget.treeView.model()
|
||||
@@ -223,8 +225,8 @@ class MaterialEditor:
|
||||
return
|
||||
self.card_path = self.widget.ComboMaterial.itemData(index)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'choose_material in material editor:\n'
|
||||
' {}\n'.format(self.card_path)
|
||||
"choose_material in material editor:\n"
|
||||
" {}\n".format(self.card_path)
|
||||
)
|
||||
if os.path.isfile(self.card_path):
|
||||
from importFCMat import read
|
||||
@@ -234,11 +236,11 @@ class MaterialEditor:
|
||||
# the card could be updated the dict not
|
||||
self.widget.ComboMaterial.setCurrentIndex(index) # set after tree params
|
||||
else:
|
||||
FreeCAD.Console.PrintError('material card not found: {}\n'.format(self.card_path))
|
||||
FreeCAD.Console.PrintError("material card not found: {}\n".format(self.card_path))
|
||||
|
||||
def updateCardsInCombo(self):
|
||||
|
||||
'''updates the contents of the materials combo with existing material cards'''
|
||||
"""updates the contents of the materials combo with existing material cards"""
|
||||
|
||||
mat_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Cards")
|
||||
sort_by_resources = mat_prefs.GetBool("SortByResources", False)
|
||||
@@ -260,13 +262,13 @@ class MaterialEditor:
|
||||
a_path = card_names_tmp[a_name]
|
||||
card_name_list.append([a_name, a_path, self.icons[a_path]])
|
||||
|
||||
card_name_list.insert(0, [None, '', ''])
|
||||
card_name_list.insert(0, [None, "", ""])
|
||||
for mat in card_name_list:
|
||||
self.widget.ComboMaterial.addItem(QtGui.QIcon(mat[2]), mat[0], mat[1])
|
||||
|
||||
def openProductURL(self):
|
||||
|
||||
'''opens the contents of the ProductURL field in an external browser.'''
|
||||
"""opens the contents of the ProductURL field in an external browser."""
|
||||
|
||||
model = self.widget.treeView.model()
|
||||
item = model.findItems(translate("Material", "Product URL"),
|
||||
@@ -340,8 +342,8 @@ class MaterialEditor:
|
||||
|
||||
def deleteCustomProperty(self, key=None):
|
||||
|
||||
'''Deletes a custom property from the editor,
|
||||
or deletes the value of an internal property.'''
|
||||
"""Deletes a custom property from the editor,
|
||||
or deletes the value of an internal property."""
|
||||
|
||||
widget = self.widget
|
||||
treeView = widget.treeView
|
||||
@@ -377,8 +379,8 @@ class MaterialEditor:
|
||||
|
||||
def onClickTree(self, index):
|
||||
|
||||
'''Checks if the current item is a custom or an internal property,
|
||||
and enable the delete property or delete value button.'''
|
||||
"""Checks if the current item is a custom or an internal property,
|
||||
and enable the delete property or delete value button."""
|
||||
|
||||
widget = self.widget
|
||||
buttonDeleteProperty = widget.ButtonDeleteProperty
|
||||
@@ -428,18 +430,18 @@ class MaterialEditor:
|
||||
# since text(0) could be translated
|
||||
matkey = self.collapseKey(str(kk))
|
||||
matvalue = unicode(ii)
|
||||
if matvalue or (matkey == 'Name'):
|
||||
if matvalue or (matkey == "Name"):
|
||||
# use only keys which are not empty and the name even if empty
|
||||
d[matkey] = matvalue
|
||||
# self.outputDict(d)
|
||||
return d
|
||||
|
||||
def outputDict(self, d):
|
||||
print('MaterialEditor dictionary')
|
||||
print("MaterialEditor dictionary")
|
||||
for param in d:
|
||||
print(' {} : {}'.format(param, d[param]))
|
||||
print(" {} : {}".format(param, d[param]))
|
||||
|
||||
'''
|
||||
"""
|
||||
def setTexture(self, pattern):
|
||||
"displays a texture preview if needed"
|
||||
self.widget.PreviewVector.hide()
|
||||
@@ -453,7 +455,7 @@ class MaterialEditor:
|
||||
if pattern:
|
||||
self.widget.PreviewVector.setPixmap(QtGui.QPixmap(pattern))
|
||||
self.widget.PreviewVector.show()
|
||||
'''
|
||||
"""
|
||||
|
||||
def updatePreviews(self, mat=None):
|
||||
"updates the preview images from the content of the editor"
|
||||
@@ -505,9 +507,9 @@ class MaterialEditor:
|
||||
"Opens a FCMat file"
|
||||
filetuple = QtGui.QFileDialog.getOpenFileName(
|
||||
QtGui.QApplication.activeWindow(),
|
||||
'Open FreeCAD Material file',
|
||||
"Open FreeCAD Material file",
|
||||
self.directory,
|
||||
'*.FCMat'
|
||||
"*.FCMat"
|
||||
)
|
||||
self.card_path = filetuple[0]
|
||||
index = self.widget.ComboMaterial.findData(self.card_path)
|
||||
@@ -518,8 +520,8 @@ class MaterialEditor:
|
||||
if os.path.isfile(self.card_path):
|
||||
if index == -1:
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Card path: {} not found in known cards.'
|
||||
'The material parameter only are loaded.\n'
|
||||
"Card path: {} not found in known cards."
|
||||
"The material parameter only are loaded.\n"
|
||||
.format(self.card_path)
|
||||
)
|
||||
from importFCMat import read
|
||||
@@ -548,9 +550,9 @@ class MaterialEditor:
|
||||
name = "Material"
|
||||
filetuple = QtGui.QFileDialog.getSaveFileName(
|
||||
QtGui.QApplication.activeWindow(),
|
||||
'Save FreeCAD Material file',
|
||||
self.directory + '/' + name + '.FCMat',
|
||||
'*.FCMat'
|
||||
"Save FreeCAD Material file",
|
||||
self.directory + "/" + name + ".FCMat",
|
||||
"*.FCMat"
|
||||
)
|
||||
# a tuple of two empty strings returns True, so use the filename directly
|
||||
filename = filetuple[0]
|
||||
@@ -571,9 +573,11 @@ class MaterialEditor:
|
||||
return self.widget.exec_()
|
||||
|
||||
|
||||
# ************************************************************************************************
|
||||
# ************************************************************************************************
|
||||
class MaterialsDelegate(QtGui.QStyledItemDelegate):
|
||||
|
||||
'''provides display and editing facilities for data items from a model.'''
|
||||
"""provides display and editing facilities for data items from a model."""
|
||||
|
||||
def __init__(self):
|
||||
""
|
||||
@@ -582,7 +586,7 @@ class MaterialsDelegate(QtGui.QStyledItemDelegate):
|
||||
|
||||
def createEditor(self, parent, option, index):
|
||||
|
||||
'''returns the widget used to change data from the model.'''
|
||||
"""returns the widget used to change data from the model."""
|
||||
|
||||
model = index.model()
|
||||
column = index.column()
|
||||
@@ -628,16 +632,16 @@ class MaterialsDelegate(QtGui.QStyledItemDelegate):
|
||||
|
||||
def setEditorData(self, editor, index):
|
||||
|
||||
'''provides the widget with data to manipulate.'''
|
||||
"""provides the widget with data to manipulate."""
|
||||
|
||||
Type = editor.property('Type')
|
||||
Type = editor.property("Type")
|
||||
model = index.model()
|
||||
item = model.itemFromIndex(index)
|
||||
print("item1={}".format(item.text()))
|
||||
|
||||
if Type == "Color":
|
||||
|
||||
color = editor.property('color')
|
||||
color = editor.property("color")
|
||||
color = tuple([v/255.0 for v in color.getRgb()])
|
||||
item.setText(str(color))
|
||||
|
||||
@@ -649,16 +653,33 @@ class MaterialsDelegate(QtGui.QStyledItemDelegate):
|
||||
else:
|
||||
|
||||
super(MaterialsDelegate, self).setEditorData(editor, index)
|
||||
print("item2={}".format(item.text()))
|
||||
|
||||
|
||||
ui = FreeCADGui.UiLoader()
|
||||
|
||||
|
||||
# ************************************************************************************************
|
||||
# ************************************************************************************************
|
||||
def matProperWidget(parent=None, matproperty=None, Type="String", Value=None,
|
||||
minimum=None, maximum=None, stepsize=None, precision=None):
|
||||
minimum=None, maximum=None, stepsize=None, precision=12):
|
||||
|
||||
'''customs widgets for the material stuff.'''
|
||||
"""customs widgets for the material stuff."""
|
||||
|
||||
# FIXME
|
||||
# Workaround for problem from here:
|
||||
# https://forum.freecadweb.org/viewtopic.php?f=18&t=56912&start=20#p516811
|
||||
# set precision to 12
|
||||
# Better would be a similar system like used in FEM material task panel
|
||||
# if the value in the InputField has not changed the data is not changed
|
||||
# why does the value changes if the user clicks in
|
||||
# the value and unit should exact stay as it is displayed before the user
|
||||
# clicks in the field
|
||||
|
||||
# the user defined properties are of Type String and thus uses a "Gui::PrefLineEdit"
|
||||
|
||||
print(matproperty)
|
||||
print(Type)
|
||||
print(Value)
|
||||
|
||||
ui = FreeCADGui.UiLoader()
|
||||
|
||||
if Type == "String":
|
||||
|
||||
@@ -675,23 +696,31 @@ def matProperWidget(parent=None, matproperty=None, Type="String", Value=None,
|
||||
lineEdit = widget.children()[1]
|
||||
lineEdit.setText(Value)
|
||||
|
||||
elif Type == "Quantity":
|
||||
elif Type == "Quantity" or Type == "Float":
|
||||
|
||||
widget = ui.createWidget("Gui::InputField")
|
||||
# print(matproperty)
|
||||
if hasattr(FreeCAD.Units, matproperty):
|
||||
unit = getattr(FreeCAD.Units, matproperty)
|
||||
quantity = FreeCAD.Units.Quantity(1, unit)
|
||||
widget.setProperty('unit', quantity.getUserPreferred()[2])
|
||||
widget.setProperty("unit", quantity.getUserPreferred()[2])
|
||||
else:
|
||||
FreeCAD.Console.PrintError('Not known unit for property: {}\n'.format(matproperty))
|
||||
FreeCAD.Console.PrintWarning(
|
||||
"Not known unit for property: {}. Probably the Quantity does not have a unit.\n"
|
||||
.format(matproperty)
|
||||
)
|
||||
# the Gui::InputField is used for Floats too, because of the diggits
|
||||
|
||||
elif Type == "Integer":
|
||||
|
||||
widget = ui.createWidget("Gui::UIntSpinBox")
|
||||
|
||||
elif Type == "Float":
|
||||
# elif Type == "Float":
|
||||
|
||||
widget = ui.createWidget("Gui::PrefDoubleSpinBox")
|
||||
# widget = ui.createWidget("Gui::PrefDoubleSpinBox")
|
||||
# has only 2 diggits precision, but for example RelativePermittivity needs much more
|
||||
# see material card for Air, thus Workaround
|
||||
# a "Gui::InputField" without unit is used
|
||||
|
||||
elif Type == "Enumerator":
|
||||
|
||||
@@ -700,7 +729,7 @@ def matProperWidget(parent=None, matproperty=None, Type="String", Value=None,
|
||||
elif Type == "Boolean":
|
||||
|
||||
widget = ui.createWidget("Gui::PrefComboBox")
|
||||
widget.insertItems(0, ['', 'False', 'True'])
|
||||
widget.insertItems(0, ["", "False", "True"])
|
||||
|
||||
elif Type == "Vector":
|
||||
|
||||
@@ -713,22 +742,22 @@ def matProperWidget(parent=None, matproperty=None, Type="String", Value=None,
|
||||
value = string2tuple(Value)
|
||||
color = QtGui.QColor()
|
||||
color.setRgb(value[0], value[1], value[2], value[3])
|
||||
widget.setProperty('color', color)
|
||||
widget.setProperty("color", color)
|
||||
|
||||
else:
|
||||
|
||||
widget = QtGui.QLineEdit()
|
||||
|
||||
if minimum is not None:
|
||||
widget.setProperty('minimum', minimum)
|
||||
widget.setProperty("minimum", minimum)
|
||||
if maximum is not None:
|
||||
widget.setProperty('maximum', maximum)
|
||||
widget.setProperty("maximum", maximum)
|
||||
if stepsize is not None:
|
||||
widget.setProperty('stepsize', stepsize)
|
||||
widget.setProperty("stepsize", stepsize)
|
||||
if precision is not None:
|
||||
widget.setProperty('precision', precision)
|
||||
widget.setProperty("precision", precision)
|
||||
|
||||
widget.setProperty('Type', Type)
|
||||
widget.setProperty("Type", Type)
|
||||
|
||||
widget.setParent(parent)
|
||||
|
||||
@@ -738,7 +767,7 @@ def matProperWidget(parent=None, matproperty=None, Type="String", Value=None,
|
||||
def string2tuple(string):
|
||||
"provisionally"
|
||||
value = string[1:-1]
|
||||
value = value.split(',')
|
||||
value = value.split(",")
|
||||
value = [int(float(v)*255) for v in value]
|
||||
value = tuple(value)
|
||||
return value
|
||||
@@ -775,26 +804,28 @@ def editMaterial(material=None, card_path=None):
|
||||
return {}
|
||||
|
||||
|
||||
'''
|
||||
# ************************************************************************************************
|
||||
# ************************************************************************************************
|
||||
"""
|
||||
# some examples how to open the material editor in Python:
|
||||
import MaterialEditor
|
||||
MaterialEditor.openEditor()
|
||||
|
||||
doc = FreeCAD.open(
|
||||
FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd'
|
||||
FreeCAD.ConfigGet("AppHomePath") + "data/examples/FemCalculixCantilever3D.FCStd"
|
||||
)
|
||||
import MaterialEditor
|
||||
MaterialEditor.openEditor('SolidMaterial', 'Material')
|
||||
MaterialEditor.openEditor("SolidMaterial", "Material")
|
||||
|
||||
import MaterialEditor
|
||||
MaterialEditor.editMaterial({
|
||||
'Density': '1234.0 kg/m^3',
|
||||
'Name': 'My-Material-Data',
|
||||
'PoissonRatio': '0.66',
|
||||
'YoungsModulus': '123456 MPa'
|
||||
"Density": "1234.0 kg/m^3",
|
||||
"Name": "My-Material-Data",
|
||||
"PoissonRatio": "0.66",
|
||||
"YoungsModulus": "123456 MPa"
|
||||
})
|
||||
|
||||
import MaterialEditor
|
||||
MaterialEditor.editMaterial('ABS')
|
||||
MaterialEditor.editMaterial("ABS")
|
||||
|
||||
'''
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user