FEM: ccx tools, move pre requisite checks in separate module

This commit is contained in:
Bernd Hahnebach
2020-03-01 12:14:46 +01:00
parent 871d660995
commit d388ca6260
3 changed files with 394 additions and 337 deletions

View File

@@ -1,4 +1,4 @@
if(BUILD_FEM_VTK)
add_definitions(-DFC_USE_VTK)
endif(BUILD_FEM_VTK)
@@ -221,6 +221,7 @@ SET(FemTools_SRCS
femtools/__init__.py
femtools/membertools.py
femtools/ccxtools.py
femtools/checksanalysis.py
femtools/constants.py
femtools/errors.py
femtools/femutils.py

View File

@@ -34,7 +34,6 @@ import subprocess
import FreeCAD
from femsolver.calculix.solver import ANALYSIS_TYPES
from femtools import femutils
from femtools import membertools
@@ -232,348 +231,27 @@ class FemToolsCcx(QtCore.QRunnable, QtCore.QObject):
def check_prerequisites(self):
FreeCAD.Console.PrintMessage("Check prerequisites.\n")
from FreeCAD import Units
message = ""
# analysis
if not self.analysis:
message += "No active Analysis\n"
if not self.working_dir:
message += "Working directory not set\n"
if not (os.path.isdir(self.working_dir)):
message += (
"Working directory \'{}\' doesn't exist."
.format(self.working_dir)
)
# solver
if not self.solver:
message += "No solver object defined in the analysis\n"
else:
if self.solver.AnalysisType not in ANALYSIS_TYPES:
message += (
"Unknown analysis type: {}\n"
.format(self.solver.AnalysisType)
)
if self.solver.AnalysisType == "frequency":
if not hasattr(self.solver, "EigenmodeHighLimit"):
message += "Frequency analysis: Solver has no EigenmodeHighLimit.\n"
elif not hasattr(self.solver, "EigenmodeLowLimit"):
message += "Frequency analysis: Solver has no EigenmodeLowLimit.\n"
elif not hasattr(self.solver, "EigenmodesCount"):
message += "Frequency analysis: Solver has no EigenmodesCount.\n"
if hasattr(self.solver, "MaterialNonlinearity") \
and self.solver.MaterialNonlinearity == "nonlinear":
if not self.member.mats_nonlinear:
message += (
"Solver is set to nonlinear materials, "
"but there is no nonlinear material in the analysis.\n"
)
if self.solver.Proxy.Type == "Fem::FemSolverCalculixCcxTools" \
and self.solver.GeometricalNonlinearity != "nonlinear":
# nonlinear geometry --> should be set
# https://forum.freecadweb.org/viewtopic.php?f=18&t=23101&p=180489#p180489
message += (
"Solver CalculiX triggers nonlinear geometry for nonlinear material, "
"thus it should to be set too.\n"
)
# mesh
if not self.mesh:
message += "No mesh object defined in the analysis\n"
if self.mesh:
if self.mesh.FemMesh.VolumeCount == 0 \
and self.mesh.FemMesh.FaceCount > 0 \
and not self.member.geos_shellthickness:
message += (
"FEM mesh has no volume elements, "
"either define a shell thicknesses or "
"provide a FEM mesh with volume elements.\n"
)
if self.mesh.FemMesh.VolumeCount == 0 \
and self.mesh.FemMesh.FaceCount == 0 \
and self.mesh.FemMesh.EdgeCount > 0 \
and not self.member.geos_beamsection \
and not self.member.geos_fluidsection:
message += (
"FEM mesh has no volume and no shell elements, "
"either define a beam/fluid section or provide "
"a FEM mesh with volume elements.\n"
)
if self.mesh.FemMesh.VolumeCount == 0 \
and self.mesh.FemMesh.FaceCount == 0 \
and self.mesh.FemMesh.EdgeCount == 0:
message += (
"FEM mesh has neither volume nor shell or edge elements. "
"Provide a FEM mesh with elements!\n"
)
# material linear and nonlinear
if not self.member.mats_linear:
message += "No material object defined in the analysis\n"
has_no_references = False
for m in self.member.mats_linear:
if len(m["Object"].References) == 0:
if has_no_references is True:
message += (
"More than one material has an empty references list "
"(Only one empty references list is allowed!).\n"
)
has_no_references = True
mat_ref_shty = ""
for m in self.member.mats_linear:
ref_shty = femutils.get_refshape_type(m["Object"])
if not mat_ref_shty:
mat_ref_shty = ref_shty
if mat_ref_shty and ref_shty and ref_shty != mat_ref_shty:
# mat_ref_shty could be empty in one material
# only the not empty ones should have the same shape type
message += (
"Some material objects do not have the same reference shape type "
"(all material objects must have the same reference shape type, "
"at the moment).\n"
)
for m in self.member.mats_linear:
mat_map = m["Object"].Material
mat_obj = m["Object"]
if mat_obj.Category == "Solid":
if "YoungsModulus" in mat_map:
# print(Units.Quantity(mat_map["YoungsModulus"]).Value)
if not Units.Quantity(mat_map["YoungsModulus"]).Value:
message += "Value of YoungsModulus is set to 0.0.\n"
else:
message += "No YoungsModulus defined for at least one material.\n"
if "PoissonRatio" not in mat_map:
# PoissonRatio is allowed to be 0.0 (in ccx), but it should be set anyway.
message += "No PoissonRatio defined for at least one material.\n"
if self.solver.AnalysisType == "frequency" or self.member.cons_selfweight:
if "Density" not in mat_map:
message += "No Density defined for at least one material.\n"
if self.solver.AnalysisType == "thermomech":
if "ThermalConductivity" in mat_map:
if not Units.Quantity(mat_map["ThermalConductivity"]).Value:
message += "Value of ThermalConductivity is set to 0.0.\n"
else:
message += (
"Thermomechanical analysis: No ThermalConductivity defined "
"for at least one material.\n"
)
if "ThermalExpansionCoefficient" not in mat_map and mat_obj.Category == "Solid":
message += (
"Thermomechanical analysis: No ThermalExpansionCoefficient defined "
"for at least one material.\n" # allowed to be 0.0 (in ccx)
)
if "SpecificHeat" not in mat_map:
message += (
"Thermomechanical analysis: No SpecificHeat "
"defined for at least one material.\n" # allowed to be 0.0 (in ccx)
)
if femutils.is_of_type(mat_obj, "Fem::MaterialReinforced"):
# additional tests for reinforced materials,
# they are needed for result calculation not for ccx analysis
mat_map_m = mat_obj.Material
if "AngleOfFriction" in mat_map_m:
# print(Units.Quantity(mat_map_m["AngleOfFriction"]).Value)
if not Units.Quantity(mat_map_m["AngleOfFriction"]).Value:
message += (
"Value of AngleOfFriction is set to 0.0 "
"for the matrix of a reinforced material.\n"
)
else:
message += (
"No AngleOfFriction defined for the matrix "
"of at least one reinforced material.\n"
)
if "CompressiveStrength" in mat_map_m:
# print(Units.Quantity(mat_map_m["CompressiveStrength"]).Value)
if not Units.Quantity(mat_map_m["CompressiveStrength"]).Value:
message += (
"Value of CompressiveStrength is set to 0.0 "
"for the matrix of a reinforced material.\n"
)
else:
message += (
"No CompressiveStrength defined for the matrinx "
"of at least one reinforced material.\n"
)
mat_map_r = mat_obj.Reinforcement
if "YieldStrength" in mat_map_r:
# print(Units.Quantity(mat_map_r["YieldStrength"]).Value)
if not Units.Quantity(mat_map_r["YieldStrength"]).Value:
message += (
"Value of YieldStrength is set to 0.0 "
"for the reinforcement of a reinforced material.\n"
)
else:
message += (
"No YieldStrength defined for the reinforcement "
"of at least one reinforced material.\n"
)
if len(self.member.mats_linear) == 1:
mobj = self.member.mats_linear[0]["Object"]
if hasattr(mobj, "References") and mobj.References:
FreeCAD.Console.PrintError(
"Only one material object, but this one has a reference shape. "
"The reference shape will be ignored.\n"
)
for m in self.member.mats_linear:
has_nonlinear_material = False
for nlm in self.member.mats_nonlinear:
if nlm["Object"].LinearBaseMaterial == m["Object"]:
if has_nonlinear_material is False:
has_nonlinear_material = True
else:
message += (
"At least two nonlinear materials use the same linear base material. "
"Only one nonlinear material for each linear material allowed.\n"
)
# which analysis needs which constraints
# no check in the regard of loads existence (constraint force, pressure, self weight)
# is done, because an analysis without loads at all is an valid analysis too
if self.solver.AnalysisType == "static":
if not (self.member.cons_fixed or self.member.cons_displacement):
message += (
"Static analysis: Neither constraint fixed nor "
"constraint displacement defined.\n"
)
if self.solver.AnalysisType == "thermomech":
if not self.member.cons_initialtemperature:
if not self.member.geos_fluidsection:
message += "Thermomechanical analysis: No initial temperature defined.\n"
if len(self.member.cons_initialtemperature) > 1:
message += "Thermomechanical analysis: Only one initial temperature is allowed.\n"
# constraints
# fixed
if self.member.cons_fixed:
for c in self.member.cons_fixed:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# displacement
if self.member.cons_displacement:
for di in self.member.cons_displacement:
if len(di["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# plane rotation
if self.member.cons_planerotation:
for c in self.member.cons_planerotation:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# contact
if self.member.cons_contact:
for c in self.member.cons_contact:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# tie
if self.member.cons_tie:
for c in self.member.cons_tie:
items = 0
for reference in c["Object"].References:
items += len(reference[1])
if items != 2:
message += (
"{} doesn't references exactly two needed faces.\n"
.format(c["Object"].Name)
)
# transform
if self.member.cons_transform:
for c in self.member.cons_transform:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# pressure
if self.member.cons_pressure:
for c in self.member.cons_pressure:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# force
if self.member.cons_force:
for c in self.member.cons_force:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# temperature
if self.member.cons_temperature:
for c in self.member.cons_temperature:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# heat flux
if self.member.cons_heatflux:
for c in self.member.cons_heatflux:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# beam section
if self.member.geos_beamsection:
if self.member.geos_shellthickness:
# this needs to be checked only once either here or in shell_thicknesses
message += (
"Beam sections and shell thicknesses in one analysis "
"is not supported at the moment.\n"
)
if self.member.geos_fluidsection:
# this needs to be checked only once either here or in shell_thicknesses
message += (
"Beam sections and fluid sections in one analysis "
"is not supported at the moment.\n"
)
has_no_references = False
for b in self.member.geos_beamsection:
if len(b["Object"].References) == 0:
if has_no_references is True:
message += (
"More than one beam section has an empty references "
"list (Only one empty references list is allowed!).\n"
)
has_no_references = True
if self.mesh:
if self.mesh.FemMesh.FaceCount > 0 or self.mesh.FemMesh.VolumeCount > 0:
message += (
"Beam sections defined but FEM mesh has volume or shell elements.\n"
)
if self.mesh.FemMesh.EdgeCount == 0:
message += (
"Beam sections defined but FEM mesh has no edge elements.\n"
)
if len(self.member.geos_beamrotation) > 1:
message += (
"Multiple beam rotations in one analysis are not supported at the moment.\n"
)
# beam rotations
if self.member.geos_beamrotation and not self.member.geos_beamsection:
message += "Beam rotations in the analysis but no beam sections defined.\n"
# shell thickness
if self.member.geos_shellthickness:
has_no_references = False
for s in self.member.geos_shellthickness:
if len(s["Object"].References) == 0:
if has_no_references is True:
message += (
"More than one shell thickness has an empty references "
"list (Only one empty references list is allowed!).\n"
)
has_no_references = True
if self.mesh:
if self.mesh.FemMesh.VolumeCount > 0:
message += "Shell thicknesses defined but FEM mesh has volume elements.\n"
if self.mesh.FemMesh.FaceCount == 0:
message += "Shell thicknesses defined but FEM mesh has no shell elements.\n"
# fluid section
if self.member.geos_fluidsection:
if not self.member.cons_selfweight:
message += (
"A fluid network analysis requires self weight constraint to be applied\n"
)
if self.solver.AnalysisType != "thermomech":
message += "A fluid network analysis can only be done in a thermomech analysis\n"
has_no_references = False
for f in self.member.geos_fluidsection:
if len(f["Object"].References) == 0:
if has_no_references is True:
message += (
"More than one fluid section has an empty references list "
"(Only one empty references list is allowed!).\n"
)
has_no_references = True
if self.mesh:
if self.mesh.FemMesh.FaceCount > 0 or self.mesh.FemMesh.VolumeCount > 0:
message += (
"Fluid sections defined but FEM mesh has volume or shell elements.\n"
)
if self.mesh.FemMesh.EdgeCount == 0:
message += "Fluid sections defined but FEM mesh has no edge elements.\n"
if not self.working_dir:
message += "Working directory not set\n"
if not (os.path.isdir(self.working_dir)):
message += (
"Working directory \'{}\' doesn't exist."
.format(self.working_dir)
)
from femtools.checksanalysis import check_analysismember
message += check_analysismember(
self.analysis,
self.solver,
self.mesh,
self.member
)
return message
def set_base_name(self, base_name=None):

View File

@@ -0,0 +1,378 @@
# ***************************************************************************
# * *
# * Copyright (c) 2020 Przemo Firszt <przemo@firszt.eu> *
# * Copyright (c) 2020 Bernd Hahnebach <bernd@bimstatik.org> *
# * *
# * 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__ = "Analysis Checks"
__author__ = "Przemo Firszt, Bernd Hahnebach"
__url__ = "http://www.freecadweb.org"
## \addtogroup FEM
# @{
import FreeCAD
from . import femutils
from femsolver.calculix.solver import ANALYSIS_TYPES
def check_analysismember(analysis, solver, mesh, member):
FreeCAD.Console.PrintMessage("Check prerequisites.\n")
from FreeCAD import Units
message = ""
# solver
if solver.AnalysisType not in ANALYSIS_TYPES:
message += (
"Unknown analysis type: {}\n"
.format(solver.AnalysisType)
)
if solver.AnalysisType == "frequency":
if not hasattr(solver, "EigenmodeHighLimit"):
message += "Frequency analysis: Solver has no EigenmodeHighLimit.\n"
elif not hasattr(solver, "EigenmodeLowLimit"):
message += "Frequency analysis: Solver has no EigenmodeLowLimit.\n"
elif not hasattr(solver, "EigenmodesCount"):
message += "Frequency analysis: Solver has no EigenmodesCount.\n"
if hasattr(solver, "MaterialNonlinearity") \
and solver.MaterialNonlinearity == "nonlinear":
if not member.mats_nonlinear:
message += (
"Solver is set to nonlinear materials, "
"but there is no nonlinear material in the analysis.\n"
)
if solver.Proxy.Type == "Fem::FemSolverCalculixCcxTools" \
and solver.GeometricalNonlinearity != "nonlinear":
# nonlinear geometry --> should be set
# https://forum.freecadweb.org/viewtopic.php?f=18&t=23101&p=180489#p180489
message += (
"Solver CalculiX triggers nonlinear geometry for nonlinear material, "
"thus it should to be set too.\n"
)
# mesh
if not mesh:
message += "No mesh object defined in the analysis\n"
if mesh:
if mesh.FemMesh.VolumeCount == 0 \
and mesh.FemMesh.FaceCount > 0 \
and not member.geos_shellthickness:
message += (
"FEM mesh has no volume elements, "
"either define a shell thicknesses or "
"provide a FEM mesh with volume elements.\n"
)
if mesh.FemMesh.VolumeCount == 0 \
and mesh.FemMesh.FaceCount == 0 \
and mesh.FemMesh.EdgeCount > 0 \
and not member.geos_beamsection \
and not member.geos_fluidsection:
message += (
"FEM mesh has no volume and no shell elements, "
"either define a beam/fluid section or provide "
"a FEM mesh with volume elements.\n"
)
if mesh.FemMesh.VolumeCount == 0 \
and mesh.FemMesh.FaceCount == 0 \
and mesh.FemMesh.EdgeCount == 0:
message += (
"FEM mesh has neither volume nor shell or edge elements. "
"Provide a FEM mesh with elements!\n"
)
# material linear and nonlinear
if not member.mats_linear:
message += "No material object defined in the analysis\n"
has_no_references = False
for m in member.mats_linear:
if len(m["Object"].References) == 0:
if has_no_references is True:
message += (
"More than one material has an empty references list "
"(Only one empty references list is allowed!).\n"
)
has_no_references = True
mat_ref_shty = ""
for m in member.mats_linear:
ref_shty = femutils.get_refshape_type(m["Object"])
if not mat_ref_shty:
mat_ref_shty = ref_shty
if mat_ref_shty and ref_shty and ref_shty != mat_ref_shty:
# mat_ref_shty could be empty in one material
# only the not empty ones should have the same shape type
message += (
"Some material objects do not have the same reference shape type "
"(all material objects must have the same reference shape type, "
"at the moment).\n"
)
for m in member.mats_linear:
mat_map = m["Object"].Material
mat_obj = m["Object"]
if mat_obj.Category == "Solid":
if "YoungsModulus" in mat_map:
# print(Units.Quantity(mat_map["YoungsModulus"]).Value)
if not Units.Quantity(mat_map["YoungsModulus"]).Value:
message += "Value of YoungsModulus is set to 0.0.\n"
else:
message += "No YoungsModulus defined for at least one material.\n"
if "PoissonRatio" not in mat_map:
# PoissonRatio is allowed to be 0.0 (in ccx), but it should be set anyway.
message += "No PoissonRatio defined for at least one material.\n"
if solver.AnalysisType == "frequency" or member.cons_selfweight:
if "Density" not in mat_map:
message += "No Density defined for at least one material.\n"
if solver.AnalysisType == "thermomech":
if "ThermalConductivity" in mat_map:
if not Units.Quantity(mat_map["ThermalConductivity"]).Value:
message += "Value of ThermalConductivity is set to 0.0.\n"
else:
message += (
"Thermomechanical analysis: No ThermalConductivity defined "
"for at least one material.\n"
)
if "ThermalExpansionCoefficient" not in mat_map and mat_obj.Category == "Solid":
message += (
"Thermomechanical analysis: No ThermalExpansionCoefficient defined "
"for at least one material.\n" # allowed to be 0.0 (in ccx)
)
if "SpecificHeat" not in mat_map:
message += (
"Thermomechanical analysis: No SpecificHeat "
"defined for at least one material.\n" # allowed to be 0.0 (in ccx)
)
if femutils.is_of_type(mat_obj, "Fem::MaterialReinforced"):
# additional tests for reinforced materials,
# they are needed for result calculation not for ccx analysis
mat_map_m = mat_obj.Material
if "AngleOfFriction" in mat_map_m:
# print(Units.Quantity(mat_map_m["AngleOfFriction"]).Value)
if not Units.Quantity(mat_map_m["AngleOfFriction"]).Value:
message += (
"Value of AngleOfFriction is set to 0.0 "
"for the matrix of a reinforced material.\n"
)
else:
message += (
"No AngleOfFriction defined for the matrix "
"of at least one reinforced material.\n"
)
if "CompressiveStrength" in mat_map_m:
# print(Units.Quantity(mat_map_m["CompressiveStrength"]).Value)
if not Units.Quantity(mat_map_m["CompressiveStrength"]).Value:
message += (
"Value of CompressiveStrength is set to 0.0 "
"for the matrix of a reinforced material.\n"
)
else:
message += (
"No CompressiveStrength defined for the matrinx "
"of at least one reinforced material.\n"
)
mat_map_r = mat_obj.Reinforcement
if "YieldStrength" in mat_map_r:
# print(Units.Quantity(mat_map_r["YieldStrength"]).Value)
if not Units.Quantity(mat_map_r["YieldStrength"]).Value:
message += (
"Value of YieldStrength is set to 0.0 "
"for the reinforcement of a reinforced material.\n"
)
else:
message += (
"No YieldStrength defined for the reinforcement "
"of at least one reinforced material.\n"
)
if len(member.mats_linear) == 1:
mobj = member.mats_linear[0]["Object"]
if hasattr(mobj, "References") and mobj.References:
FreeCAD.Console.PrintError(
"Only one material object, but this one has a reference shape. "
"The reference shape will be ignored.\n"
)
for m in member.mats_linear:
has_nonlinear_material = False
for nlm in member.mats_nonlinear:
if nlm["Object"].LinearBaseMaterial == m["Object"]:
if has_nonlinear_material is False:
has_nonlinear_material = True
else:
message += (
"At least two nonlinear materials use the same linear base material. "
"Only one nonlinear material for each linear material allowed.\n"
)
# which analysis needs which constraints
# no check in the regard of loads existence (constraint force, pressure, self weight)
# is done, because an analysis without loads at all is an valid analysis too
if solver.AnalysisType == "static":
if not (member.cons_fixed or member.cons_displacement):
message += (
"Static analysis: Neither constraint fixed nor "
"constraint displacement defined.\n"
)
if solver.AnalysisType == "thermomech":
if not member.cons_initialtemperature:
if not member.geos_fluidsection:
message += "Thermomechanical analysis: No initial temperature defined.\n"
if len(member.cons_initialtemperature) > 1:
message += "Thermomechanical analysis: Only one initial temperature is allowed.\n"
# constraints
# fixed
if member.cons_fixed:
for c in member.cons_fixed:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# displacement
if member.cons_displacement:
for di in member.cons_displacement:
if len(di["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# plane rotation
if member.cons_planerotation:
for c in member.cons_planerotation:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# contact
if member.cons_contact:
for c in member.cons_contact:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# tie
if member.cons_tie:
for c in member.cons_tie:
items = 0
for reference in c["Object"].References:
items += len(reference[1])
if items != 2:
message += (
"{} doesn't references exactly two needed faces.\n"
.format(c["Object"].Name)
)
# transform
if member.cons_transform:
for c in member.cons_transform:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# pressure
if member.cons_pressure:
for c in member.cons_pressure:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# force
if member.cons_force:
for c in member.cons_force:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# temperature
if member.cons_temperature:
for c in member.cons_temperature:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# heat flux
if member.cons_heatflux:
for c in member.cons_heatflux:
if len(c["Object"].References) == 0:
message += "{} has empty references.".format(c["Object"].Name)
# geometries
# beam section
if member.geos_beamsection:
if member.geos_shellthickness:
# this needs to be checked only once either here or in shell_thicknesses
message += (
"Beam sections and shell thicknesses in one analysis "
"is not supported at the moment.\n"
)
if member.geos_fluidsection:
# this needs to be checked only once either here or in shell_thicknesses
message += (
"Beam sections and fluid sections in one analysis "
"is not supported at the moment.\n"
)
has_no_references = False
for b in member.geos_beamsection:
if len(b["Object"].References) == 0:
if has_no_references is True:
message += (
"More than one beam section has an empty references "
"list (Only one empty references list is allowed!).\n"
)
has_no_references = True
if mesh:
if mesh.FemMesh.FaceCount > 0 or mesh.FemMesh.VolumeCount > 0:
message += (
"Beam sections defined but FEM mesh has volume or shell elements.\n"
)
if mesh.FemMesh.EdgeCount == 0:
message += (
"Beam sections defined but FEM mesh has no edge elements.\n"
)
if len(member.geos_beamrotation) > 1:
message += (
"Multiple beam rotations in one analysis are not supported at the moment.\n"
)
# beam rotations
if member.geos_beamrotation and not member.geos_beamsection:
message += "Beam rotations in the analysis but no beam sections defined.\n"
# shell thickness
if member.geos_shellthickness:
has_no_references = False
for s in member.geos_shellthickness:
if len(s["Object"].References) == 0:
if has_no_references is True:
message += (
"More than one shell thickness has an empty references "
"list (Only one empty references list is allowed!).\n"
)
has_no_references = True
if mesh:
if mesh.FemMesh.VolumeCount > 0:
message += "Shell thicknesses defined but FEM mesh has volume elements.\n"
if mesh.FemMesh.FaceCount == 0:
message += "Shell thicknesses defined but FEM mesh has no shell elements.\n"
# fluid section
if member.geos_fluidsection:
if not member.cons_selfweight:
message += (
"A fluid network analysis requires self weight constraint to be applied\n"
)
if solver.AnalysisType != "thermomech":
message += "A fluid network analysis can only be done in a thermomech analysis\n"
has_no_references = False
for f in member.geos_fluidsection:
if len(f["Object"].References) == 0:
if has_no_references is True:
message += (
"More than one fluid section has an empty references list "
"(Only one empty references list is allowed!).\n"
)
has_no_references = True
if mesh:
if mesh.FemMesh.FaceCount > 0 or mesh.FemMesh.VolumeCount > 0:
message += (
"Fluid sections defined but FEM mesh has volume or shell elements.\n"
)
if mesh.FemMesh.EdgeCount == 0:
message += "Fluid sections defined but FEM mesh has no edge elements.\n"
return message
## @}