mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 06:39:13 +00:00
ifc2ca major update - todo: update readme file
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
# Use Miniconda base image
|
||||||
|
FROM continuumio/miniconda3:4.10.3
|
||||||
|
|
||||||
|
# Update Conda, install necessary libraries, and then install Mamba
|
||||||
|
RUN conda update -n base -c defaults conda && \
|
||||||
|
conda install libarchive -c conda-forge -y && \
|
||||||
|
conda install mamba -c conda-forge -y
|
||||||
|
|
||||||
|
# Install Code_Aster and Python dependencies with Conda
|
||||||
|
RUN mamba install -c conda-forge code-aster python=3.10 -y
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# Ifc2CA - IFC Code_Aster utility
|
||||||
|
# Copyright (C) 2020, 2021, 2023, 2024 Ioannis P. Christovasilis <ipc@aethereng.com>
|
||||||
|
#
|
||||||
|
# This file is part of Ifc2CA.
|
||||||
|
#
|
||||||
|
# Ifc2CA is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ifc2CA 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 Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with Ifc2CA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from .ifc2ca import Ifc2CA
|
||||||
@@ -0,0 +1,525 @@
|
|||||||
|
|
||||||
|
# Ifc2CA - IFC Code_Aster utility
|
||||||
|
# Copyright (C) 2020, 2021 Ioannis P. Christovasilis <ipc@aethereng.com>
|
||||||
|
#
|
||||||
|
# This file is part of Ifc2CA.
|
||||||
|
#
|
||||||
|
# Ifc2CA is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ifc2CA 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 Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with Ifc2CA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import json
|
||||||
|
import ifcopenshell
|
||||||
|
import os
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class CA2IFC:
|
||||||
|
def __init__(self, inputFilename, outputFilename):
|
||||||
|
self.inputFilename = inputFilename
|
||||||
|
self.outputFilename = outputFilename
|
||||||
|
self.data = None
|
||||||
|
self.f = None
|
||||||
|
self.reps = {}
|
||||||
|
self.origin = None
|
||||||
|
self.xAxis = None
|
||||||
|
self.yAxis = None
|
||||||
|
self.zAxis = None
|
||||||
|
|
||||||
|
def convert(self):
|
||||||
|
# load json file
|
||||||
|
with open(self.inputFilename) as dataFile:
|
||||||
|
self.data = json.load(dataFile)
|
||||||
|
|
||||||
|
# initiate ifc file
|
||||||
|
self.f = ifcopenshell.file()
|
||||||
|
|
||||||
|
# create header
|
||||||
|
self.create_header()
|
||||||
|
|
||||||
|
# create global axes
|
||||||
|
globalAxes = self.create_global_axes()
|
||||||
|
localPlacement = self.f.createIfcLocalPlacement(None, globalAxes)
|
||||||
|
|
||||||
|
# TODO: create units
|
||||||
|
lengthUnit = self.f.createIfcSIUnit(None, "LENGTHUNIT", None, "METRE")
|
||||||
|
unitAssignment = self.f.createIfcUnitAssignment((lengthUnit,))
|
||||||
|
|
||||||
|
# create owner history
|
||||||
|
ownerHistory = self.create_owner_history()
|
||||||
|
|
||||||
|
# create representations and subrepresentations
|
||||||
|
self.reps = self.create_reference_subrep(globalAxes)
|
||||||
|
|
||||||
|
# create project and model
|
||||||
|
project = self.f.createIfcProject(
|
||||||
|
self.guid(), ownerHistory, "A Project", None, None, None, None, (self.reps["model"],), unitAssignment
|
||||||
|
)
|
||||||
|
model = self.f.createIfcStructuralAnalysisModel(
|
||||||
|
self.guid(),
|
||||||
|
ownerHistory,
|
||||||
|
self.data["name"],
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
"NOTDEFINED",
|
||||||
|
globalAxes,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
localPlacement,
|
||||||
|
)
|
||||||
|
self.f.createIfcRelDeclares(self.guid(), ownerHistory, None, None, project, (model,))
|
||||||
|
|
||||||
|
# create materials
|
||||||
|
ifcMaterials = [None for _ in range(len(self.data["db"]["materials"]))]
|
||||||
|
for i, material in enumerate(self.data["db"]["materials"]):
|
||||||
|
ifcMaterials[i] = self.create_material(material)
|
||||||
|
|
||||||
|
# create profiles
|
||||||
|
ifcProfiles = [None for _ in range(len(self.data["db"]["profiles"]))]
|
||||||
|
for i, profile in enumerate(self.data["db"]["profiles"]):
|
||||||
|
ifcProfiles[i] = self.create_profile(profile)
|
||||||
|
|
||||||
|
# create material-profile sets
|
||||||
|
mpSets = list(
|
||||||
|
set([el["material"] + "-" + el["profile"] for el in self.data["elements"] if el["geometryType"] == "line"])
|
||||||
|
)
|
||||||
|
ifcMaterialProfileSets = [None for _ in range(len(mpSets))]
|
||||||
|
for i, mpSet in enumerate(mpSets):
|
||||||
|
materialIndex = [mat["referenceName"] for mat in self.data["db"]["materials"]].index(mpSet.split("-")[0])
|
||||||
|
profileIndex = [prof["referenceName"] for prof in self.data["db"]["profiles"]].index(mpSet.split("-")[1])
|
||||||
|
material = ifcMaterials[materialIndex]
|
||||||
|
profile = ifcProfiles[profileIndex]
|
||||||
|
matProf = self.f.createIfcMaterialProfile(
|
||||||
|
self.data["db"]["materials"][materialIndex]["name"]
|
||||||
|
+ " | "
|
||||||
|
+ self.data["db"]["profiles"][profileIndex]["profileName"],
|
||||||
|
None,
|
||||||
|
material,
|
||||||
|
profile,
|
||||||
|
)
|
||||||
|
ifcMaterialProfileSets[i] = self.f.createIfcMaterialProfileSet(None, None, (matProf,))
|
||||||
|
|
||||||
|
# create structural elements
|
||||||
|
ifcElements = [None for _ in range(len(self.data["elements"]))]
|
||||||
|
for i, el in enumerate(self.data["elements"]):
|
||||||
|
# geometry - product definition shape
|
||||||
|
prodDefShape = self.create_geometry(el)
|
||||||
|
|
||||||
|
if el["geometryType"] == "line":
|
||||||
|
# z axis TODO: group by elements
|
||||||
|
localZAxis = self.f.createIfcDirection(tuple(el["orientation"][2]))
|
||||||
|
# element
|
||||||
|
ifcElements[i] = self.f.createIfcStructuralCurveMember(
|
||||||
|
self.guid(),
|
||||||
|
ownerHistory,
|
||||||
|
el["name"],
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
localPlacement,
|
||||||
|
prodDefShape,
|
||||||
|
el["predefinedType"],
|
||||||
|
localZAxis,
|
||||||
|
)
|
||||||
|
|
||||||
|
if el["geometryType"] == "surface":
|
||||||
|
ifcElements[i] = self.f.createIfcStructuralSurfaceMember(
|
||||||
|
self.guid(),
|
||||||
|
ownerHistory,
|
||||||
|
el["name"],
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
localPlacement,
|
||||||
|
prodDefShape,
|
||||||
|
el["predefinedType"],
|
||||||
|
el["thickness"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# create structural point connections
|
||||||
|
ifcConnections = [None for _ in range(len(self.data["connections"]))]
|
||||||
|
for i, conn in enumerate(self.data["connections"]):
|
||||||
|
# geometry - product definition shape
|
||||||
|
prodDefShape = self.create_geometry(conn)
|
||||||
|
|
||||||
|
# boundary conditions
|
||||||
|
if conn["appliedCondition"]:
|
||||||
|
bc = self.create_applied_conditions(conn["appliedCondition"], conn["geometryType"])
|
||||||
|
if conn["geometryType"] == "point":
|
||||||
|
appliedCondition = self.f.createIfcBoundaryNodeCondition(
|
||||||
|
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
|
||||||
|
)
|
||||||
|
if conn["geometryType"] == "line":
|
||||||
|
appliedCondition = self.f.createIfcBoundaryEdgeCondition(
|
||||||
|
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
|
||||||
|
)
|
||||||
|
if conn["geometryType"] == "surface":
|
||||||
|
appliedCondition = self.f.createIfcBoundaryFaceCondition(None, bc["dx"], bc["dy"], bc["dz"])
|
||||||
|
else:
|
||||||
|
appliedCondition = None
|
||||||
|
|
||||||
|
if conn["geometryType"] == "point":
|
||||||
|
# local axes
|
||||||
|
localAxes = self.create_orientation(conn["orientation"])
|
||||||
|
# connection
|
||||||
|
ifcConnections[i] = self.f.createIfcStructuralPointConnection(
|
||||||
|
self.guid(),
|
||||||
|
ownerHistory,
|
||||||
|
conn["name"],
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
localPlacement,
|
||||||
|
prodDefShape,
|
||||||
|
appliedCondition,
|
||||||
|
localAxes,
|
||||||
|
)
|
||||||
|
|
||||||
|
if conn["geometryType"] == "line":
|
||||||
|
# z axis TODO: group by elements
|
||||||
|
localZAxis = self.f.createIfcDirection(tuple(conn["orientation"][2]))
|
||||||
|
# connection
|
||||||
|
ifcConnections[i] = self.f.createIfcStructuralCurveConnection(
|
||||||
|
self.guid(),
|
||||||
|
ownerHistory,
|
||||||
|
conn["name"],
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
localPlacement,
|
||||||
|
prodDefShape,
|
||||||
|
appliedCondition,
|
||||||
|
localZAxis,
|
||||||
|
)
|
||||||
|
|
||||||
|
if conn["geometryType"] == "surface":
|
||||||
|
ifcConnections[i] = self.f.createIfcStructuralSurfaceConnection(
|
||||||
|
self.guid(), ownerHistory, conn["name"], None, None, localPlacement, prodDefShape, appliedCondition
|
||||||
|
)
|
||||||
|
|
||||||
|
# assign material-profile-sets
|
||||||
|
for i, mpSet in enumerate(mpSets):
|
||||||
|
groupOfElements = []
|
||||||
|
for j, el in enumerate(self.data["elements"]):
|
||||||
|
if el["geometryType"] == "line" and el["material"] + "-" + el["profile"] == mpSet:
|
||||||
|
groupOfElements.append(ifcElements[j])
|
||||||
|
|
||||||
|
if groupOfElements:
|
||||||
|
self.f.createIfcRelAssociatesMaterial(
|
||||||
|
self.guid(), ownerHistory, None, None, tuple(groupOfElements), ifcMaterialProfileSets[i]
|
||||||
|
)
|
||||||
|
|
||||||
|
# assign materials
|
||||||
|
for i, mat in enumerate(self.data["db"]["materials"]):
|
||||||
|
groupOfElements = []
|
||||||
|
for j, el in enumerate(self.data["elements"]):
|
||||||
|
if el["geometryType"] == "surface" and el["material"] == mat["referenceName"]:
|
||||||
|
groupOfElements.append(ifcElements[j])
|
||||||
|
if groupOfElements:
|
||||||
|
self.f.createIfcRelAssociatesMaterial(
|
||||||
|
self.guid(), ownerHistory, None, None, tuple(groupOfElements), ifcMaterials[i]
|
||||||
|
)
|
||||||
|
|
||||||
|
# create connections with elements
|
||||||
|
for i, el in enumerate(self.data["elements"]):
|
||||||
|
for conn in el["connections"]:
|
||||||
|
j = [c["referenceName"] for c in self.data["connections"]].index(conn["relatedConnection"])
|
||||||
|
geometryType = self.data["connections"][j]["geometryType"]
|
||||||
|
|
||||||
|
if conn["appliedCondition"]:
|
||||||
|
bc = self.create_applied_conditions(conn["appliedCondition"], geometryType)
|
||||||
|
if geometryType == "point":
|
||||||
|
appliedCondition = self.f.createIfcBoundaryNodeCondition(
|
||||||
|
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
|
||||||
|
)
|
||||||
|
if geometryType == "line":
|
||||||
|
appliedCondition = self.f.createIfcBoundaryEdgeCondition(
|
||||||
|
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
|
||||||
|
)
|
||||||
|
if geometryType == "surface":
|
||||||
|
appliedCondition = self.f.createIfcBoundaryFaceCondition(None, bc["dx"], bc["dy"], bc["dz"])
|
||||||
|
else:
|
||||||
|
appliedCondition = None
|
||||||
|
|
||||||
|
# local axes
|
||||||
|
localAxes = self.create_orientation(conn["orientation"])
|
||||||
|
|
||||||
|
if geometryType == "point":
|
||||||
|
if not conn["eccentricity"]:
|
||||||
|
self.f.createIfcRelConnectsStructuralMember(
|
||||||
|
self.guid(),
|
||||||
|
ownerHistory,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
ifcElements[i],
|
||||||
|
ifcConnections[j],
|
||||||
|
appliedCondition,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
localAxes,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
pointOnElement = self.f.createIfcCartesianPoint(tuple(conn["eccentricity"]["pointOnElement"]))
|
||||||
|
vector = conn["eccentricity"]["vector"]
|
||||||
|
connPointEcc = self.f.createIfcConnectionPointEccentricity(
|
||||||
|
pointOnElement, None, vector[0], vector[1], vector[2]
|
||||||
|
)
|
||||||
|
self.f.createIfcRelConnectsWithEccentricity(
|
||||||
|
self.guid(),
|
||||||
|
ownerHistory,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
ifcElements[i],
|
||||||
|
ifcConnections[j],
|
||||||
|
appliedCondition,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
localAxes,
|
||||||
|
connPointEcc,
|
||||||
|
)
|
||||||
|
|
||||||
|
if geometryType in ["line", "surface"]:
|
||||||
|
self.f.createIfcRelConnectsStructuralMember(
|
||||||
|
self.guid(),
|
||||||
|
ownerHistory,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
ifcElements[i],
|
||||||
|
ifcConnections[j],
|
||||||
|
appliedCondition,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
localAxes,
|
||||||
|
)
|
||||||
|
|
||||||
|
# assign elements and connections to group
|
||||||
|
self.f.createIfcRelAssignsToGroup(
|
||||||
|
self.guid(), ownerHistory, None, None, tuple(ifcElements + ifcConnections), None, model
|
||||||
|
)
|
||||||
|
|
||||||
|
# finalize ifc file
|
||||||
|
self.f.write(self.outputFilename)
|
||||||
|
|
||||||
|
def guid(self):
|
||||||
|
return ifcopenshell.guid.new()
|
||||||
|
|
||||||
|
def create_header(self):
|
||||||
|
self.f.wrapped_data.header.file_name.name = os.path.basename(self.outputFilename)
|
||||||
|
|
||||||
|
def create_global_axes(self):
|
||||||
|
self.xAxis = self.f.createIfcDirection((1.0, 0.0, 0.0))
|
||||||
|
self.yAxis = self.f.createIfcDirection((0.0, 1.0, 0.0))
|
||||||
|
self.zAxis = self.f.createIfcDirection((0.0, 0.0, 1.0))
|
||||||
|
self.origin = self.f.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
||||||
|
axes = self.f.createIfcAxis2Placement3D(self.origin, self.zAxis, self.xAxis)
|
||||||
|
|
||||||
|
return axes
|
||||||
|
|
||||||
|
def create_orientation(self, orientation):
|
||||||
|
xAxis = self.f.createIfcDirection(tuple(orientation[0]))
|
||||||
|
zAxis = self.f.createIfcDirection(tuple(orientation[2]))
|
||||||
|
axes = self.f.createIfcAxis2Placement3D(self.origin, zAxis, xAxis)
|
||||||
|
|
||||||
|
return axes
|
||||||
|
|
||||||
|
def create_owner_history(self):
|
||||||
|
actor = self.f.createIfcActorRole("ENGINEER", None, None)
|
||||||
|
person = self.f.createIfcPerson("Christovasilis", None, "Ioannis", None, None, None, (actor,))
|
||||||
|
organization = self.f.createIfcOrganization(
|
||||||
|
None,
|
||||||
|
"IfcOpenShell",
|
||||||
|
"IfcOpenShell, an open source (LGPL) software library that helps users and software developers to work with the IFC file format.",
|
||||||
|
)
|
||||||
|
p_o = self.f.createIfcPersonAndOrganization(person, organization)
|
||||||
|
application = self.f.createIfcApplication(organization, "v0.0.x", "IFC2CA", "IFC2CA")
|
||||||
|
timestamp = int(datetime.now().timestamp())
|
||||||
|
ownerHistory = self.f.createIfcOwnerHistory(p_o, application, "READWRITE", None, None, None, None, timestamp)
|
||||||
|
|
||||||
|
return ownerHistory
|
||||||
|
|
||||||
|
def create_reference_subrep(self, globalAxes):
|
||||||
|
modelRep = self.f.createIfcGeometricRepresentationContext(None, "Model", 3, 1.0e-05, globalAxes, None)
|
||||||
|
bodySubRep = self.f.createIfcGeometricRepresentationSubContext(
|
||||||
|
"Body", "Model", None, None, None, None, modelRep, None, "MODEL_VIEW", None
|
||||||
|
)
|
||||||
|
refSubRep = self.f.createIfcGeometricRepresentationSubContext(
|
||||||
|
"Reference", "Model", None, None, None, None, modelRep, None, "GRAPH_VIEW", None
|
||||||
|
)
|
||||||
|
|
||||||
|
return {"model": modelRep, "body": bodySubRep, "reference": refSubRep}
|
||||||
|
|
||||||
|
def create_material(self, material):
|
||||||
|
ifcMaterial = self.f.createIfcMaterial(material["name"], None, material["category"])
|
||||||
|
|
||||||
|
mechProps = []
|
||||||
|
if "youngModulus" in material["mechProps"]:
|
||||||
|
youngModulus = self.f.createIfcPropertySingleValue(
|
||||||
|
"YoungModulus", None, self.f.createIfcModulusOfElasticityMeasure(material["mechProps"]["youngModulus"])
|
||||||
|
)
|
||||||
|
mechProps.append(youngModulus)
|
||||||
|
if "shearModulus" in material["mechProps"]:
|
||||||
|
shearModulus = self.f.createIfcPropertySingleValue(
|
||||||
|
"ShearModulus", None, self.f.createIfcModulusOfElasticityMeasure(material["mechProps"]["shearModulus"])
|
||||||
|
)
|
||||||
|
mechProps.append(shearModulus)
|
||||||
|
if "poissonRatio" in material["mechProps"]:
|
||||||
|
poissonRatio = self.f.createIfcPropertySingleValue(
|
||||||
|
"PoissonRatio", None, self.f.createIfcPositiveRatioMeasure(material["mechProps"]["poissonRatio"])
|
||||||
|
)
|
||||||
|
mechProps.append(poissonRatio)
|
||||||
|
if mechProps:
|
||||||
|
self.f.createIfcMaterialProperties(
|
||||||
|
"Pset_MaterialMechanical", material["name"], tuple(mechProps), ifcMaterial
|
||||||
|
)
|
||||||
|
|
||||||
|
commonProps = []
|
||||||
|
if "massDensity" in material["commonProps"]:
|
||||||
|
massDensity = self.f.createIfcPropertySingleValue(
|
||||||
|
"MassDensity", None, self.f.createIfcMassDensityMeasure(material["commonProps"]["massDensity"])
|
||||||
|
)
|
||||||
|
commonProps.append(massDensity)
|
||||||
|
if commonProps:
|
||||||
|
self.f.createIfcMaterialProperties("Pset_MaterialCommon", material["name"], tuple(commonProps), ifcMaterial)
|
||||||
|
|
||||||
|
return ifcMaterial
|
||||||
|
|
||||||
|
def create_profile(self, profile):
|
||||||
|
if profile["profileShape"] == "rectangular":
|
||||||
|
ifcProfile = self.f.createIfcRectangleProfileDef(
|
||||||
|
profile["profileType"], profile["profileName"], None, profile["xDim"], profile["yDim"]
|
||||||
|
)
|
||||||
|
|
||||||
|
if profile["profileShape"] == "iSymmetrical":
|
||||||
|
ifcProfile = self.f.createIfcIShapeProfileDef(
|
||||||
|
profile["profileType"],
|
||||||
|
profile["profileName"],
|
||||||
|
None,
|
||||||
|
profile["commonProps"]["overallWidth"],
|
||||||
|
profile["commonProps"]["overallDepth"],
|
||||||
|
profile["commonProps"]["webThickness"],
|
||||||
|
profile["commonProps"]["flangeThickness"],
|
||||||
|
profile["commonProps"]["filletRadius"],
|
||||||
|
)
|
||||||
|
|
||||||
|
mechProps = []
|
||||||
|
if "massPerLength" in profile["mechProps"]:
|
||||||
|
massPerLength = self.f.createIfcPropertySingleValue(
|
||||||
|
"MassPerLength", None, self.f.createIfcMassPerLengthMeasure(profile["mechProps"]["massPerLength"])
|
||||||
|
)
|
||||||
|
mechProps.append(massPerLength)
|
||||||
|
if "crossSectionArea" in profile["mechProps"]:
|
||||||
|
crossSectionArea = self.f.createIfcPropertySingleValue(
|
||||||
|
"CrossSectionArea", None, self.f.createIfcAreaMeasure(profile["mechProps"]["crossSectionArea"])
|
||||||
|
)
|
||||||
|
mechProps.append(crossSectionArea)
|
||||||
|
if "momentOfInertiaY" in profile["mechProps"]:
|
||||||
|
momentOfInertiaY = self.f.createIfcPropertySingleValue(
|
||||||
|
"MomentOfInertiaY",
|
||||||
|
None,
|
||||||
|
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["momentOfInertiaY"]),
|
||||||
|
)
|
||||||
|
mechProps.append(momentOfInertiaY)
|
||||||
|
if "momentOfInertiaZ" in profile["mechProps"]:
|
||||||
|
momentOfInertiaZ = self.f.createIfcPropertySingleValue(
|
||||||
|
"MomentOfInertiaZ",
|
||||||
|
None,
|
||||||
|
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["momentOfInertiaZ"]),
|
||||||
|
)
|
||||||
|
mechProps.append(momentOfInertiaZ)
|
||||||
|
if "torsionalConstantX" in profile["mechProps"]:
|
||||||
|
torsionalConstantX = self.f.createIfcPropertySingleValue(
|
||||||
|
"TorsionalConstantX",
|
||||||
|
None,
|
||||||
|
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["torsionalConstantX"]),
|
||||||
|
)
|
||||||
|
mechProps.append(torsionalConstantX)
|
||||||
|
if mechProps:
|
||||||
|
self.f.createIfcProfileProperties(
|
||||||
|
"Pset_ProfileMechanical", profile["profileName"], tuple(mechProps), ifcProfile
|
||||||
|
)
|
||||||
|
|
||||||
|
return ifcProfile
|
||||||
|
|
||||||
|
def create_geometry(self, object):
|
||||||
|
if object["geometryType"] == "point":
|
||||||
|
point = self.f.createIfcCartesianPoint(tuple(object["geometry"]))
|
||||||
|
vertex = self.f.createIfcVertexPoint(point)
|
||||||
|
vertexTopologyRep = self.f.createIfcTopologyRepresentation(
|
||||||
|
self.reps["reference"], "Reference", "Vertex", (vertex,)
|
||||||
|
)
|
||||||
|
vertexProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (vertexTopologyRep,))
|
||||||
|
|
||||||
|
return vertexProdDefShape
|
||||||
|
|
||||||
|
if object["geometryType"] == "line":
|
||||||
|
startPoint = self.f.createIfcCartesianPoint(tuple(object["geometry"][0]))
|
||||||
|
startVertex = self.f.createIfcVertexPoint(startPoint)
|
||||||
|
endPoint = self.f.createIfcCartesianPoint(tuple(object["geometry"][1]))
|
||||||
|
endVertex = self.f.createIfcVertexPoint(endPoint)
|
||||||
|
edge = self.f.createIfcEdge(startVertex, endVertex)
|
||||||
|
edgeTopologyRep = self.f.createIfcTopologyRepresentation(
|
||||||
|
self.reps["reference"], "Reference", "Edge", (edge,)
|
||||||
|
)
|
||||||
|
edgeProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (edgeTopologyRep,))
|
||||||
|
|
||||||
|
return edgeProdDefShape
|
||||||
|
|
||||||
|
if object["geometryType"] == "surface":
|
||||||
|
verts = [None for _ in range(len(object["geometry"]))]
|
||||||
|
for i, p in enumerate(object["geometry"]):
|
||||||
|
point = self.f.createIfcCartesianPoint(tuple(p))
|
||||||
|
verts[i] = self.f.createIfcVertexPoint(point)
|
||||||
|
|
||||||
|
orientedEdges = [None for _ in range(len(object["geometry"]))]
|
||||||
|
for i, v in enumerate(verts):
|
||||||
|
v2Index = (i + 1) if i < len(verts) - 1 else 0
|
||||||
|
edge = self.f.createIfcEdge(v, verts[v2Index])
|
||||||
|
orientedEdges[i] = self.f.createIfcOrientedEdge(None, None, edge, True)
|
||||||
|
|
||||||
|
edgeLoop = self.f.createIfcEdgeLoop(tuple(orientedEdges))
|
||||||
|
localAxes = self.create_orientation(object["orientation"])
|
||||||
|
plane = self.f.createIfcPlane(localAxes)
|
||||||
|
faceBound = self.f.createIfcFaceBound(edgeLoop, True)
|
||||||
|
face = self.f.createIfcFaceSurface((faceBound,), plane, True)
|
||||||
|
faceTopologyRep = self.f.createIfcTopologyRepresentation(
|
||||||
|
self.reps["reference"], "Reference", "Face", (face,)
|
||||||
|
)
|
||||||
|
faceProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (faceTopologyRep,))
|
||||||
|
|
||||||
|
return faceProdDefShape
|
||||||
|
|
||||||
|
def create_applied_conditions(self, bc, geometryType):
|
||||||
|
for dof in ["dx", "dy", "dz"]:
|
||||||
|
if isinstance(bc[dof], bool):
|
||||||
|
bc[dof] = self.f.createIfcBoolean(bc[dof])
|
||||||
|
else:
|
||||||
|
if geometryType == "point":
|
||||||
|
bc[dof] = self.f.createIfcLinearStiffnessMeasure(bc[dof])
|
||||||
|
if geometryType == "line":
|
||||||
|
bc[dof] = self.f.createIfcModulusOfLinearSubgradeReactionMeasure(bc[dof])
|
||||||
|
if geometryType == "surface":
|
||||||
|
bc[dof] = self.f.createIfcModulusOfSubgradeReactionMeasure(bc[dof])
|
||||||
|
|
||||||
|
for dof in ["drx", "dry", "drz"]:
|
||||||
|
if isinstance(bc[dof], bool):
|
||||||
|
bc[dof] = self.f.createIfcBoolean(bc[dof])
|
||||||
|
else:
|
||||||
|
if geometryType == "point":
|
||||||
|
bc[dof] = self.f.createIfcRotationalStiffnessMeasure(bc[dof])
|
||||||
|
if geometryType == "line":
|
||||||
|
bc[dof] = self.f.createIfcModulusOfRotationalSubgradeReactionMeasure(bc[dof])
|
||||||
|
|
||||||
|
return bc
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
inputFilename = "grid_of_beams.json"
|
||||||
|
outputFilename = "grid_of_beams.ifc"
|
||||||
|
|
||||||
|
ca2ifc = CA2IFC(inputFilename, outputFilename)
|
||||||
|
ca2ifc.convert()
|
||||||
+393
-467
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
# Ifc2CA - IFC Code_Aster utility
|
# Ifc2CA - IFC Code_Aster utility
|
||||||
# Copyright (C) 2020, 2021 Ioannis P. Christovasilis <ipc@aethereng.com>
|
# Copyright (C) 2020, 2021, 2023, 2024 Ioannis P. Christovasilis <ipc@aethereng.com>
|
||||||
#
|
#
|
||||||
# This file is part of Ifc2CA.
|
# This file is part of Ifc2CA.
|
||||||
#
|
#
|
||||||
@@ -17,509 +17,435 @@
|
|||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with Ifc2CA. If not, see <http://www.gnu.org/licenses/>.
|
# along with Ifc2CA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import json
|
import itertools
|
||||||
import ifcopenshell
|
|
||||||
import os
|
import ifcopenshell as ios
|
||||||
from datetime import datetime
|
import meshio
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
flatten = itertools.chain.from_iterable
|
||||||
|
|
||||||
|
|
||||||
class CA2IFC:
|
def get_element_data(model, name, element):
|
||||||
def __init__(self, inputFilename, outputFilename):
|
if element["geometry_type"] == "Edge":
|
||||||
self.inputFilename = inputFilename
|
for i, cell_block in enumerate(model.cells):
|
||||||
self.outputFilename = outputFilename
|
if cell_block.type == "line":
|
||||||
self.data = None
|
cell_tags = model.cell_data["cell_tags"][i]
|
||||||
self.f = None
|
break
|
||||||
self.reps = {}
|
rows = []
|
||||||
self.origin = None
|
for i_row, i in enumerate(cell_tags):
|
||||||
self.xAxis = None
|
if i == 0:
|
||||||
self.yAxis = None
|
continue
|
||||||
self.zAxis = None
|
tags = model.cell_tags[i]
|
||||||
|
for tag in tags:
|
||||||
|
if tag == name:
|
||||||
|
# print(i_row, i)
|
||||||
|
rows.append(i_row)
|
||||||
|
break
|
||||||
|
|
||||||
def convert(self):
|
points = list(set(flatten([cell_block.data[c] for c in rows])))
|
||||||
# load json file
|
points.sort(key=lambda p: np.linalg.norm(model.points[p] - np.array(element["origin"])))
|
||||||
with open(self.inputFilename) as dataFile:
|
coords = [np.round(model.points[p], 4).tolist() for p in points]
|
||||||
self.data = json.load(dataFile)
|
local_coords = [
|
||||||
|
[float(round(np.linalg.norm(model.points[p] - np.array(element["origin"])), 4))] for p in points
|
||||||
|
]
|
||||||
|
|
||||||
# initiate ifc file
|
return {
|
||||||
self.f = ifcopenshell.file()
|
"name": name,
|
||||||
|
"points": points,
|
||||||
|
"coords": coords,
|
||||||
|
"local_coords": local_coords,
|
||||||
|
}
|
||||||
|
|
||||||
# create header
|
elif element["geometry_type"] == "Face":
|
||||||
self.create_header()
|
triangle_cell_tags = None
|
||||||
|
quad_cell_tags = None
|
||||||
|
for i, cell_block in enumerate(model.cells):
|
||||||
|
if cell_block.type == "triangle":
|
||||||
|
triangle_cell_tags = model.cell_data["cell_tags"][i]
|
||||||
|
break
|
||||||
|
|
||||||
# create global axes
|
if triangle_cell_tags is not None:
|
||||||
globalAxes = self.create_global_axes()
|
rows = []
|
||||||
localPlacement = self.f.createIfcLocalPlacement(None, globalAxes)
|
for i_row, i in enumerate(triangle_cell_tags):
|
||||||
|
if i == 0:
|
||||||
# TODO: create units
|
continue
|
||||||
lengthUnit = self.f.createIfcSIUnit(None, "LENGTHUNIT", None, "METRE")
|
tags = model.cell_tags[i]
|
||||||
unitAssignment = self.f.createIfcUnitAssignment((lengthUnit,))
|
for tag in tags:
|
||||||
|
if tag == name:
|
||||||
# create owner history
|
# print(i_row, i)
|
||||||
ownerHistory = self.create_owner_history()
|
rows.append(i_row)
|
||||||
|
break
|
||||||
# create representations and subrepresentations
|
if not len(rows):
|
||||||
self.reps = self.create_reference_subrep(globalAxes)
|
points = []
|
||||||
|
|
||||||
# create project and model
|
|
||||||
project = self.f.createIfcProject(
|
|
||||||
self.guid(), ownerHistory, "A Project", None, None, None, None, (self.reps["model"],), unitAssignment
|
|
||||||
)
|
|
||||||
model = self.f.createIfcStructuralAnalysisModel(
|
|
||||||
self.guid(),
|
|
||||||
ownerHistory,
|
|
||||||
self.data["name"],
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
"NOTDEFINED",
|
|
||||||
globalAxes,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
localPlacement,
|
|
||||||
)
|
|
||||||
self.f.createIfcRelDeclares(self.guid(), ownerHistory, None, None, project, (model,))
|
|
||||||
|
|
||||||
# create materials
|
|
||||||
ifcMaterials = [None for _ in range(len(self.data["db"]["materials"]))]
|
|
||||||
for i, material in enumerate(self.data["db"]["materials"]):
|
|
||||||
ifcMaterials[i] = self.create_material(material)
|
|
||||||
|
|
||||||
# create profiles
|
|
||||||
ifcProfiles = [None for _ in range(len(self.data["db"]["profiles"]))]
|
|
||||||
for i, profile in enumerate(self.data["db"]["profiles"]):
|
|
||||||
ifcProfiles[i] = self.create_profile(profile)
|
|
||||||
|
|
||||||
# create material-profile sets
|
|
||||||
mpSets = list(
|
|
||||||
set([el["material"] + "-" + el["profile"] for el in self.data["elements"] if el["geometryType"] == "line"])
|
|
||||||
)
|
|
||||||
ifcMaterialProfileSets = [None for _ in range(len(mpSets))]
|
|
||||||
for i, mpSet in enumerate(mpSets):
|
|
||||||
materialIndex = [mat["referenceName"] for mat in self.data["db"]["materials"]].index(mpSet.split("-")[0])
|
|
||||||
profileIndex = [prof["referenceName"] for prof in self.data["db"]["profiles"]].index(mpSet.split("-")[1])
|
|
||||||
material = ifcMaterials[materialIndex]
|
|
||||||
profile = ifcProfiles[profileIndex]
|
|
||||||
matProf = self.f.createIfcMaterialProfile(
|
|
||||||
self.data["db"]["materials"][materialIndex]["name"]
|
|
||||||
+ " | "
|
|
||||||
+ self.data["db"]["profiles"][profileIndex]["profileName"],
|
|
||||||
None,
|
|
||||||
material,
|
|
||||||
profile,
|
|
||||||
)
|
|
||||||
ifcMaterialProfileSets[i] = self.f.createIfcMaterialProfileSet(None, None, (matProf,))
|
|
||||||
|
|
||||||
# create structural elements
|
|
||||||
ifcElements = [None for _ in range(len(self.data["elements"]))]
|
|
||||||
for i, el in enumerate(self.data["elements"]):
|
|
||||||
# geometry - product definition shape
|
|
||||||
prodDefShape = self.create_geometry(el)
|
|
||||||
|
|
||||||
if el["geometryType"] == "line":
|
|
||||||
# z axis TODO: group by elements
|
|
||||||
localZAxis = self.f.createIfcDirection(tuple(el["orientation"][2]))
|
|
||||||
# element
|
|
||||||
ifcElements[i] = self.f.createIfcStructuralCurveMember(
|
|
||||||
self.guid(),
|
|
||||||
ownerHistory,
|
|
||||||
el["name"],
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
localPlacement,
|
|
||||||
prodDefShape,
|
|
||||||
el["predefinedType"],
|
|
||||||
localZAxis,
|
|
||||||
)
|
|
||||||
|
|
||||||
if el["geometryType"] == "surface":
|
|
||||||
ifcElements[i] = self.f.createIfcStructuralSurfaceMember(
|
|
||||||
self.guid(),
|
|
||||||
ownerHistory,
|
|
||||||
el["name"],
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
localPlacement,
|
|
||||||
prodDefShape,
|
|
||||||
el["predefinedType"],
|
|
||||||
el["thickness"],
|
|
||||||
)
|
|
||||||
|
|
||||||
# create structural point connections
|
|
||||||
ifcConnections = [None for _ in range(len(self.data["connections"]))]
|
|
||||||
for i, conn in enumerate(self.data["connections"]):
|
|
||||||
# geometry - product definition shape
|
|
||||||
prodDefShape = self.create_geometry(conn)
|
|
||||||
|
|
||||||
# boundary conditions
|
|
||||||
if conn["appliedCondition"]:
|
|
||||||
bc = self.create_applied_conditions(conn["appliedCondition"], conn["geometryType"])
|
|
||||||
if conn["geometryType"] == "point":
|
|
||||||
appliedCondition = self.f.createIfcBoundaryNodeCondition(
|
|
||||||
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
|
|
||||||
)
|
|
||||||
if conn["geometryType"] == "line":
|
|
||||||
appliedCondition = self.f.createIfcBoundaryEdgeCondition(
|
|
||||||
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
|
|
||||||
)
|
|
||||||
if conn["geometryType"] == "surface":
|
|
||||||
appliedCondition = self.f.createIfcBoundaryFaceCondition(None, bc["dx"], bc["dy"], bc["dz"])
|
|
||||||
else:
|
else:
|
||||||
appliedCondition = None
|
points = list(flatten([cell_block.data[c] for c in rows]))
|
||||||
|
|
||||||
if conn["geometryType"] == "point":
|
for i, cell_block in enumerate(model.cells):
|
||||||
# local axes
|
if cell_block.type == "quad":
|
||||||
localAxes = self.create_orientation(conn["orientation"])
|
quad_cell_tags = model.cell_data["cell_tags"][i]
|
||||||
# connection
|
break
|
||||||
ifcConnections[i] = self.f.createIfcStructuralPointConnection(
|
|
||||||
self.guid(),
|
|
||||||
ownerHistory,
|
|
||||||
conn["name"],
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
localPlacement,
|
|
||||||
prodDefShape,
|
|
||||||
appliedCondition,
|
|
||||||
localAxes,
|
|
||||||
)
|
|
||||||
|
|
||||||
if conn["geometryType"] == "line":
|
if quad_cell_tags is not None:
|
||||||
# z axis TODO: group by elements
|
rows = []
|
||||||
localZAxis = self.f.createIfcDirection(tuple(conn["orientation"][2]))
|
for i_row, i in enumerate(quad_cell_tags):
|
||||||
# connection
|
if i == 0:
|
||||||
ifcConnections[i] = self.f.createIfcStructuralCurveConnection(
|
continue
|
||||||
self.guid(),
|
tags = model.cell_tags[i]
|
||||||
ownerHistory,
|
for tag in tags:
|
||||||
conn["name"],
|
if tag == name:
|
||||||
None,
|
# print(i_row, i)
|
||||||
None,
|
rows.append(i_row)
|
||||||
localPlacement,
|
break
|
||||||
prodDefShape,
|
if len(rows):
|
||||||
appliedCondition,
|
points.extend(list(flatten([cell_block.data[c] for c in rows])))
|
||||||
localZAxis,
|
|
||||||
)
|
|
||||||
|
|
||||||
if conn["geometryType"] == "surface":
|
points = list(set(points))
|
||||||
ifcConnections[i] = self.f.createIfcStructuralSurfaceConnection(
|
points.sort()
|
||||||
self.guid(), ownerHistory, conn["name"], None, None, localPlacement, prodDefShape, appliedCondition
|
coords = [model.points[p].tolist() for p in points]
|
||||||
)
|
local_coords = [
|
||||||
|
np.round(np.array(element["orientation"]).dot(model.points[p] - np.array(element["origin"])), 4).tolist()[
|
||||||
|
:2
|
||||||
|
]
|
||||||
|
for p in points
|
||||||
|
]
|
||||||
|
|
||||||
# assign material-profile-sets
|
return {
|
||||||
for i, mpSet in enumerate(mpSets):
|
"name": name,
|
||||||
groupOfElements = []
|
"points": points,
|
||||||
for j, el in enumerate(self.data["elements"]):
|
"coords": coords,
|
||||||
if el["geometryType"] == "line" and el["material"] + "-" + el["profile"] == mpSet:
|
"local_coords": local_coords,
|
||||||
groupOfElements.append(ifcElements[j])
|
}
|
||||||
|
|
||||||
if groupOfElements:
|
|
||||||
self.f.createIfcRelAssociatesMaterial(
|
|
||||||
self.guid(), ownerHistory, None, None, tuple(groupOfElements), ifcMaterialProfileSets[i]
|
|
||||||
)
|
|
||||||
|
|
||||||
# assign materials
|
def get_element_result_data(model, field_label, name, element, field_type):
|
||||||
for i, mat in enumerate(self.data["db"]["materials"]):
|
points = get_element_data(model, name, element)["points"]
|
||||||
groupOfElements = []
|
if field_type == "InternalForces":
|
||||||
for j, el in enumerate(self.data["elements"]):
|
if element["geometry_type"] == "Edge":
|
||||||
if el["geometryType"] == "surface" and el["material"] == mat["referenceName"]:
|
return {
|
||||||
groupOfElements.append(ifcElements[j])
|
"N": [round(model.point_data[field_label][p][0], 4) for p in points],
|
||||||
if groupOfElements:
|
"VY": [round(model.point_data[field_label][p][1], 4) for p in points],
|
||||||
self.f.createIfcRelAssociatesMaterial(
|
"VZ": [round(model.point_data[field_label][p][2], 4) for p in points],
|
||||||
self.guid(), ownerHistory, None, None, tuple(groupOfElements), ifcMaterials[i]
|
"MT": [round(model.point_data[field_label][p][3], 4) for p in points],
|
||||||
)
|
"MFY": [round(model.point_data[field_label][p][4], 4) for p in points],
|
||||||
|
"MFZ": [round(model.point_data[field_label][p][5], 4) for p in points],
|
||||||
|
}
|
||||||
|
|
||||||
# create connections with elements
|
elif element["geometry_type"] == "Face":
|
||||||
for i, el in enumerate(self.data["elements"]):
|
if len(model.point_data[field_label][points[0]]) == 8:
|
||||||
for conn in el["connections"]:
|
offset = 0
|
||||||
j = [c["referenceName"] for c in self.data["connections"]].index(conn["relatedConnection"])
|
elif len(model.point_data[field_label][points[0]]) == 14:
|
||||||
geometryType = self.data["connections"][j]["geometryType"]
|
offset = 6
|
||||||
|
else:
|
||||||
|
assert (
|
||||||
|
False
|
||||||
|
), f"Internal force field with {len(model.point_data[field_label][points[0]])} field values for {field_label} and {element['Name']} "
|
||||||
|
|
||||||
if conn["appliedCondition"]:
|
return {
|
||||||
bc = self.create_applied_conditions(conn["appliedCondition"], geometryType)
|
"NXX": [round(model.point_data[field_label][p][offset + 0], 4) for p in points],
|
||||||
if geometryType == "point":
|
"NYY": [round(model.point_data[field_label][p][offset + 1], 4) for p in points],
|
||||||
appliedCondition = self.f.createIfcBoundaryNodeCondition(
|
"NXY": [round(model.point_data[field_label][p][offset + 2], 4) for p in points],
|
||||||
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
|
"MXX": [round(model.point_data[field_label][p][offset + 3], 4) for p in points],
|
||||||
)
|
"MYY": [round(model.point_data[field_label][p][offset + 4], 4) for p in points],
|
||||||
if geometryType == "line":
|
"MXY": [round(model.point_data[field_label][p][offset + 5], 4) for p in points],
|
||||||
appliedCondition = self.f.createIfcBoundaryEdgeCondition(
|
"QX": [round(model.point_data[field_label][p][offset + 6], 4) for p in points],
|
||||||
None, bc["dx"], bc["dy"], bc["dz"], bc["drx"], bc["dry"], bc["drz"]
|
"QY": [round(model.point_data[field_label][p][offset + 7], 4) for p in points],
|
||||||
)
|
}
|
||||||
if geometryType == "surface":
|
|
||||||
appliedCondition = self.f.createIfcBoundaryFaceCondition(None, bc["dx"], bc["dy"], bc["dz"])
|
|
||||||
else:
|
|
||||||
appliedCondition = None
|
|
||||||
|
|
||||||
# local axes
|
if field_type == "Displacements":
|
||||||
localAxes = self.create_orientation(conn["orientation"])
|
return {
|
||||||
|
"DX": [round(model.point_data[field_label][p][0], 4) for p in points],
|
||||||
|
"DY": [round(model.point_data[field_label][p][1], 4) for p in points],
|
||||||
|
"DZ": [round(model.point_data[field_label][p][2], 4) for p in points],
|
||||||
|
"DRX": [round(model.point_data[field_label][p][3], 4) for p in points],
|
||||||
|
"DRY": [round(model.point_data[field_label][p][4], 4) for p in points],
|
||||||
|
"DRZ": [round(model.point_data[field_label][p][5], 4) for p in points],
|
||||||
|
}
|
||||||
|
|
||||||
if geometryType == "point":
|
|
||||||
if not conn["eccentricity"]:
|
|
||||||
self.f.createIfcRelConnectsStructuralMember(
|
|
||||||
self.guid(),
|
|
||||||
ownerHistory,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
ifcElements[i],
|
|
||||||
ifcConnections[j],
|
|
||||||
appliedCondition,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
localAxes,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
pointOnElement = self.f.createIfcCartesianPoint(tuple(conn["eccentricity"]["pointOnElement"]))
|
|
||||||
vector = conn["eccentricity"]["vector"]
|
|
||||||
connPointEcc = self.f.createIfcConnectionPointEccentricity(
|
|
||||||
pointOnElement, None, vector[0], vector[1], vector[2]
|
|
||||||
)
|
|
||||||
self.f.createIfcRelConnectsWithEccentricity(
|
|
||||||
self.guid(),
|
|
||||||
ownerHistory,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
ifcElements[i],
|
|
||||||
ifcConnections[j],
|
|
||||||
appliedCondition,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
localAxes,
|
|
||||||
connPointEcc,
|
|
||||||
)
|
|
||||||
|
|
||||||
if geometryType in ["line", "surface"]:
|
def results_to_ifc(ifc_file, ifc_model, rmed_path, global_case, field_types, data):
|
||||||
self.f.createIfcRelConnectsStructuralMember(
|
if not rmed_path.exists():
|
||||||
self.guid(),
|
print(f"Med file with results not found for case_instant: {global_case}")
|
||||||
ownerHistory,
|
return
|
||||||
None,
|
|
||||||
None,
|
result = meshio.read(rmed_path, "med")
|
||||||
ifcElements[i],
|
if global_case == "LC":
|
||||||
ifcConnections[j],
|
model_cases = data["load_cases"]
|
||||||
appliedCondition,
|
elif global_case == "COMB":
|
||||||
None,
|
model_cases = data["load_combinations"]
|
||||||
None,
|
for field in field_types:
|
||||||
localAxes,
|
if field == "InternalForces":
|
||||||
|
_parsed_data = internal_forces_to_ifc(ifc_file, ifc_model, result, model_cases, data["elements"])
|
||||||
|
elif field == "Displacements":
|
||||||
|
_parsed_data = displacements_to_ifc(ifc_file, ifc_model, result, model_cases, data["elements"])
|
||||||
|
|
||||||
|
|
||||||
|
def internal_forces_to_ifc(ifc_file, ifc_model, result, model_cases, elements):
|
||||||
|
result_cases = [dict() for _ in model_cases]
|
||||||
|
field_cases = [f"ELEMENT_FORCE[{i}] - {i + 1}" for i in range(len(result_cases))]
|
||||||
|
|
||||||
|
# Create Result Groups for load case_instance combinations
|
||||||
|
for iCase, case_instance in enumerate(model_cases):
|
||||||
|
result_cases[iCase]["case_instance"] = ifc_file.create_entity(
|
||||||
|
"IfcStructuralResultGroup",
|
||||||
|
**{
|
||||||
|
"GlobalId": ios.guid.new(),
|
||||||
|
"Name": "Internal Forces for " + case_instance["Name"],
|
||||||
|
"TheoryType": "FIRST_ORDER_THEORY",
|
||||||
|
"ResultForLoadGroup": ifc_file.by_id(case_instance["id"]),
|
||||||
|
"IsLinear": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
result_cases[iCase]["assignment"] = ifc_file.create_entity(
|
||||||
|
"IfcRelAssignsToGroup",
|
||||||
|
**{
|
||||||
|
"GlobalId": ios.guid.new(),
|
||||||
|
"RelatedObjects": [],
|
||||||
|
"RelatingGroup": result_cases[iCase]["case_instance"],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if ifc_model.HasResults:
|
||||||
|
ifc_model.HasResults += tuple([result["case_instance"] for result in result_cases])
|
||||||
|
else:
|
||||||
|
ifc_model.HasResults = tuple([result["case_instance"] for result in result_cases])
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for _, element in enumerate(elements):
|
||||||
|
group_name = getGroupName(element["ref_id"])
|
||||||
|
name = element["Name"]
|
||||||
|
info = get_element_data(result, group_name, element)
|
||||||
|
assert len(info["coords"]) >= 2
|
||||||
|
for iCase, field_case in enumerate(field_cases):
|
||||||
|
forces = get_element_result_data(result, field_case, group_name, element, field_type="InternalForces")
|
||||||
|
reaction = ifc_file.create_entity(
|
||||||
|
"IfcStructuralCurveReaction" if element["geometry_type"] == "Edge" else "IfcStructuralSurfaceReaction",
|
||||||
|
**{
|
||||||
|
"GlobalId": ios.guid.new(),
|
||||||
|
"Name": "Internal Forces for " + model_cases[iCase]["Name"] + f" on {name}",
|
||||||
|
# "AppliedLoad": load["ifcLoad"],
|
||||||
|
"GlobalOrLocal": "LOCAL_COORDS",
|
||||||
|
"PredefinedType": "DISCRETE",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
result_cases[iCase]["assignment"].RelatedObjects += (reaction,)
|
||||||
|
|
||||||
|
ifc_file.create_entity(
|
||||||
|
"IfcRelConnectsStructuralActivity",
|
||||||
|
**{
|
||||||
|
"GlobalId": ios.guid.new(),
|
||||||
|
"RelatingElement": ifc_file.by_id(element["id"]),
|
||||||
|
"RelatedStructuralActivity": reaction,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
reaction.AppliedLoad = ifc_file.create_entity(
|
||||||
|
"IfcStructuralLoadConfiguration",
|
||||||
|
**{
|
||||||
|
"Name": "Internal Forces for " + model_cases[iCase]["Name"] + f" on {name}",
|
||||||
|
"Values": [],
|
||||||
|
"Locations": tuple([tuple(node) for node in info["local_coords"]]),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if element["geometry_type"] == "Edge":
|
||||||
|
for iNode, node in enumerate(info["coords"]):
|
||||||
|
location = f"({node[0]}, {node[1]}, {node[2]})"
|
||||||
|
distance = info["local_coords"][iNode][0]
|
||||||
|
|
||||||
|
N = forces["N"][iNode]
|
||||||
|
VY = forces["VY"][iNode]
|
||||||
|
VZ = forces["VZ"][iNode]
|
||||||
|
MT = forces["MT"][iNode]
|
||||||
|
MFY = forces["MFY"][iNode]
|
||||||
|
MFZ = forces["MFZ"][iNode]
|
||||||
|
|
||||||
|
data.append([name, f"LCC-{iCase + 1} @ {distance}", location, N, VY, VZ, MT, MFY, MFZ])
|
||||||
|
|
||||||
|
pointValue = ifc_file.create_entity(
|
||||||
|
"IfcStructuralLoadSingleForce",
|
||||||
|
**{
|
||||||
|
"Name": "Internal Forces for " + model_cases[iCase]["Name"] + f" @ {distance} on {name}",
|
||||||
|
"ForceX": N,
|
||||||
|
"ForceY": VY,
|
||||||
|
"ForceZ": VZ,
|
||||||
|
"MomentX": MT,
|
||||||
|
"MomentY": MFY,
|
||||||
|
"MomentZ": MFZ,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
reaction.AppliedLoad.Values += (pointValue,)
|
||||||
|
|
||||||
# assign elements and connections to group
|
elif element["geometry_type"] == "Face":
|
||||||
self.f.createIfcRelAssignsToGroup(
|
for iNode, node in enumerate(info["coords"]):
|
||||||
self.guid(), ownerHistory, None, None, tuple(ifcElements + ifcConnections), None, model
|
location = f"({node[0]}, {node[1]}, {node[2]})"
|
||||||
|
distance = tuple(info["local_coords"][iNode])
|
||||||
|
|
||||||
|
NXX = forces["NXX"][iNode]
|
||||||
|
NYY = forces["NYY"][iNode]
|
||||||
|
NXY = forces["NXY"][iNode]
|
||||||
|
MXX = forces["MXX"][iNode]
|
||||||
|
MYY = forces["MYY"][iNode]
|
||||||
|
MXY = forces["MXY"][iNode]
|
||||||
|
|
||||||
|
data.append([name, f"LCC-{iCase + 1} @ {distance}", location, NXX, NYY, NXY, MXX, MYY, MXY])
|
||||||
|
|
||||||
|
pointValue = ifc_file.create_entity(
|
||||||
|
"IfcStructuralLoadSingleForce",
|
||||||
|
**{
|
||||||
|
"Name": "Internal Forces for " + model_cases[iCase]["Name"] + f" @ {distance} on {name}",
|
||||||
|
"ForceX": NXX,
|
||||||
|
"ForceY": NYY,
|
||||||
|
"ForceZ": NXY,
|
||||||
|
"MomentX": MXX,
|
||||||
|
"MomentY": MYY,
|
||||||
|
"MomentZ": MXY,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
reaction.AppliedLoad.Values += (pointValue,)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def displacements_to_ifc(ifc_file, ifc_model, result, model_cases, elements):
|
||||||
|
result_cases = [dict() for _ in model_cases]
|
||||||
|
field_cases = [f"MODEL_DISP[{i}] - {i + 1}" for i in range(len(result_cases))]
|
||||||
|
|
||||||
|
# Create Result Groups for load case_instance combinations
|
||||||
|
for iCase, case_instance in enumerate(model_cases):
|
||||||
|
result_cases[iCase]["case_instance"] = ifc_file.create_entity(
|
||||||
|
"IfcStructuralResultGroup",
|
||||||
|
**{
|
||||||
|
"GlobalId": ios.guid.new(),
|
||||||
|
"Name": "Global Displacements for " + case_instance["Name"],
|
||||||
|
"TheoryType": "FIRST_ORDER_THEORY",
|
||||||
|
"ResultForLoadGroup": ifc_file.by_id(case_instance["id"]),
|
||||||
|
"IsLinear": True,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
# finalize ifc file
|
result_cases[iCase]["assignment"] = ifc_file.create_entity(
|
||||||
self.f.write(self.outputFilename)
|
"IfcRelAssignsToGroup",
|
||||||
|
**{
|
||||||
def guid(self):
|
"GlobalId": ios.guid.new(),
|
||||||
return ifcopenshell.guid.new()
|
"RelatedObjects": [],
|
||||||
|
"RelatingGroup": result_cases[iCase]["case_instance"],
|
||||||
def create_header(self):
|
},
|
||||||
self.f.wrapped_data.header.file_name.name = os.path.basename(self.outputFilename)
|
|
||||||
|
|
||||||
def create_global_axes(self):
|
|
||||||
self.xAxis = self.f.createIfcDirection((1.0, 0.0, 0.0))
|
|
||||||
self.yAxis = self.f.createIfcDirection((0.0, 1.0, 0.0))
|
|
||||||
self.zAxis = self.f.createIfcDirection((0.0, 0.0, 1.0))
|
|
||||||
self.origin = self.f.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
|
||||||
axes = self.f.createIfcAxis2Placement3D(self.origin, self.zAxis, self.xAxis)
|
|
||||||
|
|
||||||
return axes
|
|
||||||
|
|
||||||
def create_orientation(self, orientation):
|
|
||||||
xAxis = self.f.createIfcDirection(tuple(orientation[0]))
|
|
||||||
zAxis = self.f.createIfcDirection(tuple(orientation[2]))
|
|
||||||
axes = self.f.createIfcAxis2Placement3D(self.origin, zAxis, xAxis)
|
|
||||||
|
|
||||||
return axes
|
|
||||||
|
|
||||||
def create_owner_history(self):
|
|
||||||
actor = self.f.createIfcActorRole("ENGINEER", None, None)
|
|
||||||
person = self.f.createIfcPerson("Christovasilis", None, "Ioannis", None, None, None, (actor,))
|
|
||||||
organization = self.f.createIfcOrganization(
|
|
||||||
None,
|
|
||||||
"IfcOpenShell",
|
|
||||||
"IfcOpenShell, an open source (LGPL) software library that helps users and software developers to work with the IFC file format.",
|
|
||||||
)
|
|
||||||
p_o = self.f.createIfcPersonAndOrganization(person, organization)
|
|
||||||
application = self.f.createIfcApplication(organization, "v0.0.x", "IFC2CA", "IFC2CA")
|
|
||||||
timestamp = int(datetime.now().timestamp())
|
|
||||||
ownerHistory = self.f.createIfcOwnerHistory(p_o, application, "READWRITE", None, None, None, None, timestamp)
|
|
||||||
|
|
||||||
return ownerHistory
|
|
||||||
|
|
||||||
def create_reference_subrep(self, globalAxes):
|
|
||||||
modelRep = self.f.createIfcGeometricRepresentationContext(None, "Model", 3, 1.0e-05, globalAxes, None)
|
|
||||||
bodySubRep = self.f.createIfcGeometricRepresentationSubContext(
|
|
||||||
"Body", "Model", None, None, None, None, modelRep, None, "MODEL_VIEW", None
|
|
||||||
)
|
|
||||||
refSubRep = self.f.createIfcGeometricRepresentationSubContext(
|
|
||||||
"Reference", "Model", None, None, None, None, modelRep, None, "GRAPH_VIEW", None
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return {"model": modelRep, "body": bodySubRep, "reference": refSubRep}
|
if ifc_model.HasResults:
|
||||||
|
ifc_model.HasResults += tuple([result["case_instance"] for result in result_cases])
|
||||||
|
else:
|
||||||
|
ifc_model.HasResults = tuple([result["case_instance"] for result in result_cases])
|
||||||
|
|
||||||
def create_material(self, material):
|
data = []
|
||||||
ifcMaterial = self.f.createIfcMaterial(material["name"], None, material["category"])
|
for _, element in enumerate(elements):
|
||||||
|
group_name = getGroupName(element["ref_id"])
|
||||||
|
name = element["Name"]
|
||||||
|
info = get_element_data(result, group_name, element)
|
||||||
|
assert len(info["coords"]) >= 2
|
||||||
|
for iCase, case_instance in enumerate(field_cases):
|
||||||
|
displacements = get_element_result_data(
|
||||||
|
result, case_instance, group_name, element, field_type="Displacements"
|
||||||
|
)
|
||||||
|
reaction = ifc_file.create_entity(
|
||||||
|
"IfcStructuralCurveReaction" if element["geometry_type"] == "Edge" else "IfcStructuralSurfaceReaction",
|
||||||
|
**{
|
||||||
|
"GlobalId": ios.guid.new(),
|
||||||
|
"Name": "Global Displacements for " + model_cases[iCase]["Name"] + f" on {name}",
|
||||||
|
# "AppliedLoad": load["ifcLoad"],
|
||||||
|
"GlobalOrLocal": "LOCAL_COORDS",
|
||||||
|
"PredefinedType": "DISCRETE",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
result_cases[iCase]["assignment"].RelatedObjects += (reaction,)
|
||||||
|
|
||||||
mechProps = []
|
ifc_file.create_entity(
|
||||||
if "youngModulus" in material["mechProps"]:
|
"IfcRelConnectsStructuralActivity",
|
||||||
youngModulus = self.f.createIfcPropertySingleValue(
|
**{
|
||||||
"YoungModulus", None, self.f.createIfcModulusOfElasticityMeasure(material["mechProps"]["youngModulus"])
|
"GlobalId": ios.guid.new(),
|
||||||
)
|
"RelatingElement": ifc_file.by_id(element["id"]),
|
||||||
mechProps.append(youngModulus)
|
"RelatedStructuralActivity": reaction,
|
||||||
if "shearModulus" in material["mechProps"]:
|
},
|
||||||
shearModulus = self.f.createIfcPropertySingleValue(
|
|
||||||
"ShearModulus", None, self.f.createIfcModulusOfElasticityMeasure(material["mechProps"]["shearModulus"])
|
|
||||||
)
|
|
||||||
mechProps.append(shearModulus)
|
|
||||||
if "poissonRatio" in material["mechProps"]:
|
|
||||||
poissonRatio = self.f.createIfcPropertySingleValue(
|
|
||||||
"PoissonRatio", None, self.f.createIfcPositiveRatioMeasure(material["mechProps"]["poissonRatio"])
|
|
||||||
)
|
|
||||||
mechProps.append(poissonRatio)
|
|
||||||
if mechProps:
|
|
||||||
self.f.createIfcMaterialProperties(
|
|
||||||
"Pset_MaterialMechanical", material["name"], tuple(mechProps), ifcMaterial
|
|
||||||
)
|
)
|
||||||
|
|
||||||
commonProps = []
|
reaction.AppliedLoad = ifc_file.create_entity(
|
||||||
if "massDensity" in material["commonProps"]:
|
"IfcStructuralLoadConfiguration",
|
||||||
massDensity = self.f.createIfcPropertySingleValue(
|
**{
|
||||||
"MassDensity", None, self.f.createIfcMassDensityMeasure(material["commonProps"]["massDensity"])
|
"Name": "Global Displacements for " + model_cases[iCase]["Name"] + f" on {name}",
|
||||||
)
|
"Values": [],
|
||||||
commonProps.append(massDensity)
|
"Locations": tuple([tuple(node) for node in info["local_coords"]]),
|
||||||
if commonProps:
|
},
|
||||||
self.f.createIfcMaterialProperties("Pset_MaterialCommon", material["name"], tuple(commonProps), ifcMaterial)
|
|
||||||
|
|
||||||
return ifcMaterial
|
|
||||||
|
|
||||||
def create_profile(self, profile):
|
|
||||||
if profile["profileShape"] == "rectangular":
|
|
||||||
ifcProfile = self.f.createIfcRectangleProfileDef(
|
|
||||||
profile["profileType"], profile["profileName"], None, profile["xDim"], profile["yDim"]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if profile["profileShape"] == "iSymmetrical":
|
if element["geometry_type"] == "Edge":
|
||||||
ifcProfile = self.f.createIfcIShapeProfileDef(
|
for iNode, node in enumerate(info["coords"]):
|
||||||
profile["profileType"],
|
location = f"({node[0]}, {node[1]}, {node[2]})"
|
||||||
profile["profileName"],
|
distance = info["local_coords"][iNode][0]
|
||||||
None,
|
|
||||||
profile["commonProps"]["overallWidth"],
|
|
||||||
profile["commonProps"]["overallDepth"],
|
|
||||||
profile["commonProps"]["webThickness"],
|
|
||||||
profile["commonProps"]["flangeThickness"],
|
|
||||||
profile["commonProps"]["filletRadius"],
|
|
||||||
)
|
|
||||||
|
|
||||||
mechProps = []
|
DX = displacements["DX"][iNode]
|
||||||
if "massPerLength" in profile["mechProps"]:
|
DY = displacements["DY"][iNode]
|
||||||
massPerLength = self.f.createIfcPropertySingleValue(
|
DZ = displacements["DZ"][iNode]
|
||||||
"MassPerLength", None, self.f.createIfcMassPerLengthMeasure(profile["mechProps"]["massPerLength"])
|
DRX = displacements["DRX"][iNode]
|
||||||
)
|
DRY = displacements["DRY"][iNode]
|
||||||
mechProps.append(massPerLength)
|
DRZ = displacements["DRZ"][iNode]
|
||||||
if "crossSectionArea" in profile["mechProps"]:
|
|
||||||
crossSectionArea = self.f.createIfcPropertySingleValue(
|
|
||||||
"CrossSectionArea", None, self.f.createIfcAreaMeasure(profile["mechProps"]["crossSectionArea"])
|
|
||||||
)
|
|
||||||
mechProps.append(crossSectionArea)
|
|
||||||
if "momentOfInertiaY" in profile["mechProps"]:
|
|
||||||
momentOfInertiaY = self.f.createIfcPropertySingleValue(
|
|
||||||
"MomentOfInertiaY",
|
|
||||||
None,
|
|
||||||
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["momentOfInertiaY"]),
|
|
||||||
)
|
|
||||||
mechProps.append(momentOfInertiaY)
|
|
||||||
if "momentOfInertiaZ" in profile["mechProps"]:
|
|
||||||
momentOfInertiaZ = self.f.createIfcPropertySingleValue(
|
|
||||||
"MomentOfInertiaZ",
|
|
||||||
None,
|
|
||||||
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["momentOfInertiaZ"]),
|
|
||||||
)
|
|
||||||
mechProps.append(momentOfInertiaZ)
|
|
||||||
if "torsionalConstantX" in profile["mechProps"]:
|
|
||||||
torsionalConstantX = self.f.createIfcPropertySingleValue(
|
|
||||||
"TorsionalConstantX",
|
|
||||||
None,
|
|
||||||
self.f.createIfcMomentOfInertiaMeasure(profile["mechProps"]["torsionalConstantX"]),
|
|
||||||
)
|
|
||||||
mechProps.append(torsionalConstantX)
|
|
||||||
if mechProps:
|
|
||||||
self.f.createIfcProfileProperties(
|
|
||||||
"Pset_ProfileMechanical", profile["profileName"], tuple(mechProps), ifcProfile
|
|
||||||
)
|
|
||||||
|
|
||||||
return ifcProfile
|
data.append([name, f"LCC-{iCase + 1} @ {distance}", location, DX, DY, DZ, DRX, DRY, DRZ])
|
||||||
|
|
||||||
def create_geometry(self, object):
|
pointValue = ifc_file.create_entity(
|
||||||
if object["geometryType"] == "point":
|
"IfcStructuralLoadSingleDisplacement",
|
||||||
point = self.f.createIfcCartesianPoint(tuple(object["geometry"]))
|
**{
|
||||||
vertex = self.f.createIfcVertexPoint(point)
|
"Name": "Global Displacements for "
|
||||||
vertexTopologyRep = self.f.createIfcTopologyRepresentation(
|
+ model_cases[iCase]["Name"]
|
||||||
self.reps["reference"], "Reference", "Vertex", (vertex,)
|
+ f" @ {distance} on {name}",
|
||||||
)
|
"DisplacementX": DX,
|
||||||
vertexProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (vertexTopologyRep,))
|
"DisplacementY": DY,
|
||||||
|
"DisplacementZ": DZ,
|
||||||
|
"RotationalDisplacementRX": DRX,
|
||||||
|
"RotationalDisplacementRY": DRY,
|
||||||
|
"RotationalDisplacementRZ": DRZ,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
reaction.AppliedLoad.Values += (pointValue,)
|
||||||
|
|
||||||
return vertexProdDefShape
|
elif element["geometry_type"] == "Face":
|
||||||
|
for iNode, node in enumerate(info["coords"]):
|
||||||
|
location = f"({node[0]}, {node[1]}, {node[2]})"
|
||||||
|
distance = tuple(info["local_coords"][iNode])
|
||||||
|
|
||||||
if object["geometryType"] == "line":
|
DX = displacements["DX"][iNode]
|
||||||
startPoint = self.f.createIfcCartesianPoint(tuple(object["geometry"][0]))
|
DY = displacements["DY"][iNode]
|
||||||
startVertex = self.f.createIfcVertexPoint(startPoint)
|
DZ = displacements["DZ"][iNode]
|
||||||
endPoint = self.f.createIfcCartesianPoint(tuple(object["geometry"][1]))
|
DRX = displacements["DRX"][iNode]
|
||||||
endVertex = self.f.createIfcVertexPoint(endPoint)
|
DRY = displacements["DRY"][iNode]
|
||||||
edge = self.f.createIfcEdge(startVertex, endVertex)
|
DRZ = displacements["DRZ"][iNode]
|
||||||
edgeTopologyRep = self.f.createIfcTopologyRepresentation(
|
|
||||||
self.reps["reference"], "Reference", "Edge", (edge,)
|
|
||||||
)
|
|
||||||
edgeProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (edgeTopologyRep,))
|
|
||||||
|
|
||||||
return edgeProdDefShape
|
data.append([name, f"LCC-{iCase + 1} @ {distance}", location, DX, DY, DZ, DRX, DRY, DRZ])
|
||||||
|
|
||||||
if object["geometryType"] == "surface":
|
pointValue = ifc_file.create_entity(
|
||||||
verts = [None for _ in range(len(object["geometry"]))]
|
"IfcStructuralLoadSingleDisplacement",
|
||||||
for i, p in enumerate(object["geometry"]):
|
**{
|
||||||
point = self.f.createIfcCartesianPoint(tuple(p))
|
"Name": "Global Displacements for "
|
||||||
verts[i] = self.f.createIfcVertexPoint(point)
|
+ model_cases[iCase]["Name"]
|
||||||
|
+ f" @ {distance} on {name}",
|
||||||
|
"DisplacementX": DX,
|
||||||
|
"DisplacementY": DY,
|
||||||
|
"DisplacementZ": DZ,
|
||||||
|
"RotationalDisplacementRX": DRX,
|
||||||
|
"RotationalDisplacementRY": DRY,
|
||||||
|
"RotationalDisplacementRZ": DRZ,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
reaction.AppliedLoad.Values += (pointValue,)
|
||||||
|
|
||||||
orientedEdges = [None for _ in range(len(object["geometry"]))]
|
return data
|
||||||
for i, v in enumerate(verts):
|
|
||||||
v2Index = (i + 1) if i < len(verts) - 1 else 0
|
|
||||||
edge = self.f.createIfcEdge(v, verts[v2Index])
|
|
||||||
orientedEdges[i] = self.f.createIfcOrientedEdge(None, None, edge, True)
|
|
||||||
|
|
||||||
edgeLoop = self.f.createIfcEdgeLoop(tuple(orientedEdges))
|
|
||||||
localAxes = self.create_orientation(object["orientation"])
|
|
||||||
plane = self.f.createIfcPlane(localAxes)
|
|
||||||
faceBound = self.f.createIfcFaceBound(edgeLoop, True)
|
|
||||||
face = self.f.createIfcFaceSurface((faceBound,), plane, True)
|
|
||||||
faceTopologyRep = self.f.createIfcTopologyRepresentation(
|
|
||||||
self.reps["reference"], "Reference", "Face", (face,)
|
|
||||||
)
|
|
||||||
faceProdDefShape = self.f.createIfcProductDefinitionShape(None, None, (faceTopologyRep,))
|
|
||||||
|
|
||||||
return faceProdDefShape
|
|
||||||
|
|
||||||
def create_applied_conditions(self, bc, geometryType):
|
|
||||||
for dof in ["dx", "dy", "dz"]:
|
|
||||||
if isinstance(bc[dof], bool):
|
|
||||||
bc[dof] = self.f.createIfcBoolean(bc[dof])
|
|
||||||
else:
|
|
||||||
if geometryType == "point":
|
|
||||||
bc[dof] = self.f.createIfcLinearStiffnessMeasure(bc[dof])
|
|
||||||
if geometryType == "line":
|
|
||||||
bc[dof] = self.f.createIfcModulusOfLinearSubgradeReactionMeasure(bc[dof])
|
|
||||||
if geometryType == "surface":
|
|
||||||
bc[dof] = self.f.createIfcModulusOfSubgradeReactionMeasure(bc[dof])
|
|
||||||
|
|
||||||
for dof in ["drx", "dry", "drz"]:
|
|
||||||
if isinstance(bc[dof], bool):
|
|
||||||
bc[dof] = self.f.createIfcBoolean(bc[dof])
|
|
||||||
else:
|
|
||||||
if geometryType == "point":
|
|
||||||
bc[dof] = self.f.createIfcRotationalStiffnessMeasure(bc[dof])
|
|
||||||
if geometryType == "line":
|
|
||||||
bc[dof] = self.f.createIfcModulusOfRotationalSubgradeReactionMeasure(bc[dof])
|
|
||||||
|
|
||||||
return bc
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
def getGroupName(name):
|
||||||
inputFilename = "grid_of_beams.json"
|
if "|" in name:
|
||||||
outputFilename = "grid_of_beams.ifc"
|
info = name.split("|")
|
||||||
|
sortName = "".join(c for c in info[0] if c.isupper())
|
||||||
ca2ifc = CA2IFC(inputFilename, outputFilename)
|
return f"{sortName[2:]}_{info[1]}"
|
||||||
ca2ifc.convert()
|
else:
|
||||||
|
return name
|
||||||
|
|||||||
+898
-572
File diff suppressed because it is too large
Load Diff
+297
-995
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,80 @@
|
|||||||
|
# STEP: DEFINE SUPPORTS AND CONSTRAINTS
|
||||||
|
connection = AFFE_CHAR_MECA(
|
||||||
|
MODELE = model,
|
||||||
|
{%- if vertexConnections %}
|
||||||
|
LIAISON_DDL = (
|
||||||
|
{%- for conn in vertexConnections %}
|
||||||
|
{%- if conn.appliedCondition %}
|
||||||
|
{%- for i in range(len(conn.liaisons.coeffs)) %}
|
||||||
|
_F(
|
||||||
|
GROUP_NO = {{ conn.liaisons.groupNames }},
|
||||||
|
DDL = {{ conn.liaisons.dofs[i] }},
|
||||||
|
COEF_MULT = {{ conn.liaisons.coeffs[i] }},
|
||||||
|
COEF_IMPO = 0.0
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- for rel in conn.related_elements %}
|
||||||
|
{%- for i in range(len(rel.liaisons.coeffs)) %}
|
||||||
|
_F(
|
||||||
|
GROUP_NO = {{ rel.liaisons.groupNames }},
|
||||||
|
DDL = {{ rel.liaisons.dofs[i] }},
|
||||||
|
COEF_MULT = {{ rel.liaisons.coeffs[i] }},
|
||||||
|
COEF_IMPO = 0.0
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
{%- if edgeConnections %}
|
||||||
|
LIAISON_GROUP = (
|
||||||
|
{%- for conn in edgeConnections %}
|
||||||
|
{%- if conn.appliedCondition %}
|
||||||
|
{%- for i in range(len(conn.liaisons.coeffs)) %}
|
||||||
|
_F(
|
||||||
|
GROUP_NO_1 = {{ tuple([conn.liaisons.groupNames[0]]) }},
|
||||||
|
GROUP_NO_2 = {{ tuple([conn.liaisons.groupNames[0]]) }},
|
||||||
|
DDL_1 = {{ conn.liaisons.dofs[i] }},
|
||||||
|
DDL_2 = {{ conn.liaisons.dofs[i] }},
|
||||||
|
COEF_MULT_1 = {{ conn.liaisons.coeffs[i] }},
|
||||||
|
COEF_MULT_2 = (0.0, 0.0, 0.0),
|
||||||
|
COEF_IMPO = 0.0
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- for rel in conn.related_elements %}
|
||||||
|
{%- for i in range(len(rel.liaisons.coeffs)) %}
|
||||||
|
_F(
|
||||||
|
GROUP_NO_1 = {{ tuple([rel.liaisons.groupNames[0]]) }},
|
||||||
|
GROUP_NO_2 = {{ tuple([rel.liaisons.groupNames[3]]) }},
|
||||||
|
DDL_1 = {{ tuple(rel.liaisons.dofs[i][:3]) }},
|
||||||
|
DDL_2 = {{ tuple(rel.liaisons.dofs[i][:3]) }},
|
||||||
|
COEF_MULT_1 = {{ tuple(rel.liaisons.coeffs[i][:3]) }},
|
||||||
|
COEF_MULT_2 = {{ tuple(rel.liaisons.coeffs[i][3:]) }},
|
||||||
|
COEF_IMPO = 0.0
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
{%- if unifiedConnections %}
|
||||||
|
LIAISON_UNIF = (
|
||||||
|
{%- for conn in unifiedConnections %}
|
||||||
|
_F(
|
||||||
|
GROUP_NO = {{ conn.unifiedGroupNames }},
|
||||||
|
DDL = ('DX', 'DY', 'DZ', 'DRX', 'DRY', 'DRZ')
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
{%- if rigidLinkGroupNames %}
|
||||||
|
LIAISON_SOLIDE = (
|
||||||
|
{%- for groupName in rigidLinkGroupNames %}
|
||||||
|
_F(GROUP_MA = {{ tuple([groupName]) }}),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
)
|
||||||
|
{{ "\n" }}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
# STEP: DEFINE ELEMENTS
|
||||||
|
element = AFFE_CARA_ELEM(
|
||||||
|
MODELE = model,
|
||||||
|
POUTRE = (
|
||||||
|
{%- for _, profile in profiles.items() %}
|
||||||
|
{%- if profile.properties %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ profile.groupNames }},
|
||||||
|
SECTION = 'GENERALE',
|
||||||
|
CARA = ('A', 'IY', 'IZ', 'JX'),
|
||||||
|
VALE = ({{ profile.properties.CrossSectionArea }}, {{ profile.properties.MomentOfInertiaY }}, {{ profile.properties.MomentOfInertiaZ }}, {{ profile.properties.TorsionalConstantX }})
|
||||||
|
),
|
||||||
|
{%- elif profile.type == "IfcRectangleProfileDef" and profile.ProfileType == "AREA" %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ profile.groupNames }},
|
||||||
|
SECTION = 'RECTANGLE',
|
||||||
|
CARA = ('HY', 'HZ'),
|
||||||
|
VALE = ({{ profile.XDim }}, {{ profile.YDim }})
|
||||||
|
),
|
||||||
|
{%- elif profile.type == "IfcRectangleHollowProfileDef" and profile.ProfileType == "AREA" %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ profile.groupNames }},
|
||||||
|
SECTION = 'RECTANGLE',
|
||||||
|
CARA = ('HY', 'HZ', 'EPY', 'EPZ'),
|
||||||
|
VALE = ({{ profile.XDim }}, {{ profile.YDim }}, {{ profile.WallThickness }}, {{ profile.WallThickness }})
|
||||||
|
),
|
||||||
|
{%- else %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ profile.groupNames }},
|
||||||
|
SECTION = 'GENERALE',
|
||||||
|
CARA = ('A', 'IY', 'IZ', 'JX'),
|
||||||
|
VALE = ({{ profile.properties.CrossSectionArea }}, {{ profile.properties.MomentOfInertiaY }}, {{ profile.properties.MomentOfInertiaZ }}, {{ profile.properties.TorsionalConstantX }})
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- if rigidLinkGroupNames %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ rigidLinkGroupNames }},
|
||||||
|
SECTION = 'RECTANGLE',
|
||||||
|
CARA = ('HY', 'HZ'),
|
||||||
|
VALE = (1.0, 1.0)
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
),
|
||||||
|
COQUE = (
|
||||||
|
{%- for el in shellElements %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([getGroupName(el.ref_id)]) }},
|
||||||
|
EPAIS = {{ el.Thickness }},
|
||||||
|
VECTEUR = {{ tuple(el.orientation[0]) }}
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
DISCRET = (
|
||||||
|
{%- for conn in vertexConnections %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([getGroupName(conn.ref_id) + "_0D"]) }},
|
||||||
|
CARA = 'K_TR_D_N',
|
||||||
|
VALE = {{ conn.stiffnesses }},
|
||||||
|
REPERE = 'LOCAL'
|
||||||
|
),
|
||||||
|
{%- if includeZeroLength1DSprings %}
|
||||||
|
{%- for rel in conn.related_elements %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([rel.springGroupName]) }},
|
||||||
|
CARA = 'K_TR_D_L',
|
||||||
|
VALE = {{ rel.stiffnesses }},
|
||||||
|
REPERE = 'LOCAL'
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- for conn in edgeConnections %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([getGroupName(conn.ref_id) + "_0D"]) }},
|
||||||
|
CARA = 'K_TR_D_N',
|
||||||
|
VALE = {{ conn.stiffnesses }},
|
||||||
|
REPERE = 'LOCAL'
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
ORIENTATION = (
|
||||||
|
{%- for el in beamElements %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([getGroupName(el.ref_id)]) }},
|
||||||
|
CARA = 'VECT_Y',
|
||||||
|
VALE = {{ tuple(el.orientation[1]) }}
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
{%- for conn in vertexConnections %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([getGroupName(conn.ref_id) + "_0D"]) }},
|
||||||
|
CARA = 'VECT_X_Y',
|
||||||
|
VALE = {{ tuple(conn.orientation[0] + conn.orientation[1]) }}
|
||||||
|
),
|
||||||
|
{%- if includeZeroLength1DSprings %}
|
||||||
|
{%- for rel in conn.related_elements %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([rel.springGroupName]) }},
|
||||||
|
CARA = 'VECT_X_Y',
|
||||||
|
VALE = {{ tuple(rel.orientation[0] + rel.orientation[1]) }},
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- for conn in edgeConnections %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([getGroupName(conn.ref_id) + "_0D"]) }},
|
||||||
|
CARA = 'VECT_X_Y',
|
||||||
|
VALE = {{ tuple(conn.orientation[0] + conn.orientation[1]) }}
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
{{ "\n" }}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
# STEP: DEFINE TIME
|
||||||
|
{{ analysis_time }} = DEFI_LIST_REEL(
|
||||||
|
DEBUT = {{ start }},
|
||||||
|
INTERVALLE = _F(
|
||||||
|
JUSQU_A = {{ end }},
|
||||||
|
NOMBRE = {{ steps }}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# STEP: DEFINE LOADS
|
||||||
|
{{ load }} = AFFE_CHAR_MECA_F(
|
||||||
|
MODELE = model,
|
||||||
|
FORCE_NODALE = (
|
||||||
|
{%- for el in vertexLoadElements %}
|
||||||
|
_F(
|
||||||
|
GROUP_NO = {{ tuple([getGroupName(el.ref_id)]) }},
|
||||||
|
{%- for key, load in el.loads[load_key].items() %}
|
||||||
|
{{ key }} = DEFI_FONCTION(NOM_PARA='INST', ABSCISSE={{ time }}, ORDONNEE={{ tuple(load) }}),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
FORCE_POUTRE = (
|
||||||
|
{%- for el in edgeLoadElements %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([getGroupName(el.ref_id)]) }},
|
||||||
|
{%- for key, load in el.loads[load_key].items() %}
|
||||||
|
{{ key }} = DEFI_FONCTION(NOM_PARA='INST', ABSCISSE={{ time }}, ORDONNEE={{ tuple(load) }}),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
FORCE_COQUE = (
|
||||||
|
{%- for el in faceLoadElements %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ tuple([getGroupName(el.ref_id)]) }},
|
||||||
|
{%- for key, load in el.loads[load_key].items() %}
|
||||||
|
{{ key }} = DEFI_FONCTION(NOM_PARA='INST', ABSCISSE={{ time }}, ORDONNEE={{ tuple(load) }}),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
{{ "\n" }}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# STEP: DEFINE MATERIALS
|
||||||
|
{%- for i, (_, material) in enumerate(materials.items()) %}
|
||||||
|
{{ "mat" + "_%s" % i }} = DEFI_MATERIAU(
|
||||||
|
ELAS = _F(
|
||||||
|
E = {{ material.properties.YoungModulus }},
|
||||||
|
NU = {{ material.properties.PoissonRatio }},
|
||||||
|
RHO = {{ material.properties.MassDensity }}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{% endfor %}
|
||||||
|
material = AFFE_MATERIAU(
|
||||||
|
MAILLAGE = mesh,
|
||||||
|
AFFE = (
|
||||||
|
{%- for i, (_, material) in enumerate(materials.items()) %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ material.groupNames }},
|
||||||
|
MATER = {{ "mat" + "_%s" % i }},
|
||||||
|
),
|
||||||
|
{%- endfor %}
|
||||||
|
{%- if rigidLinkGroupNames %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ rigidLinkGroupNames }},
|
||||||
|
MATER = {{ "mat_0" }},
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{{ "\n" }}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# STEP: DEFINE MODEL
|
||||||
|
model = AFFE_MODELE(
|
||||||
|
MAILLAGE = mesh,
|
||||||
|
AFFE = (
|
||||||
|
_F(
|
||||||
|
TOUT = 'OUI',
|
||||||
|
PHENOMENE = 'MECANIQUE',
|
||||||
|
MODELISATION = '3D'
|
||||||
|
),
|
||||||
|
{%- if faceGroupNames %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ faceGroupNames }},
|
||||||
|
PHENOMENE = 'MECANIQUE',
|
||||||
|
MODELISATION = 'DKT'
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
{%- if edgeGroupNames %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ edgeGroupNames }},
|
||||||
|
PHENOMENE = 'MECANIQUE',
|
||||||
|
MODELISATION = 'POU_D_E'
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
{%- if point0DGroupNames %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ point0DGroupNamesPlus }},
|
||||||
|
PHENOMENE = 'MECANIQUE',
|
||||||
|
MODELISATION = 'DIS_TR'
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
{%- if point1DGroupNames %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ point1DGroupNames }},
|
||||||
|
PHENOMENE = 'MECANIQUE',
|
||||||
|
MODELISATION = 'DIS_TR'
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
{%- if rigidLinkGroupNames %}
|
||||||
|
_F(
|
||||||
|
GROUP_MA = {{ rigidLinkGroupNames }},
|
||||||
|
PHENOMENE = 'MECANIQUE',
|
||||||
|
MODELISATION = 'POU_D_E'
|
||||||
|
),
|
||||||
|
{%- endif %}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{{ "\n" }}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
P actions make_etude
|
||||||
|
P memory_limit {{ allocated_memory }}
|
||||||
|
P time_limit {{ time_limit }}
|
||||||
|
P version stable
|
||||||
|
F comm {{ model_name }}_{{ run_label }}.comm D 1
|
||||||
|
F libr {{ model_name }}.med D 20
|
||||||
|
F mess {{ model_name }}_{{ run_label }}.mess R 6
|
||||||
|
{%- if "LC" in cases %}
|
||||||
|
F rmed {{ model_name + "_LC" }}.rmed R 80
|
||||||
|
{%- endif %}
|
||||||
|
{%- if "COMB" in cases %}
|
||||||
|
F rmed {{ model_name + "_COMB" }}.rmed R 81
|
||||||
|
{%- endif %}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# STEP: RESULT EXTRACTION
|
||||||
|
IMPR_RESU(
|
||||||
|
FORMAT="MED",
|
||||||
|
UNITE={{unit_number}},
|
||||||
|
RESU=_F(
|
||||||
|
RESULTAT={{res_Bld}},
|
||||||
|
NOM_CHAM=("DEPL", "EFGE_NOEU"),
|
||||||
|
NOM_CHAM_MED=("MODEL_DISP", "ELEMENT_FORCE"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
{{"\n"}}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
# STEP: CONCLUDE STUDY
|
||||||
|
# code_aster.close()
|
||||||
|
FIN()
|
||||||
|
{{"\n"}}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# STEP: READ MED FILE
|
||||||
|
mesh = LIRE_MAILLAGE(FORMAT="MED", UNITE=20)
|
||||||
|
{{"\n"}}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# STEP: RUN ANALYSIS
|
||||||
|
{{ res_Bld }} = MECA_STATIQUE(
|
||||||
|
MODELE = model,
|
||||||
|
CHAM_MATER = material,
|
||||||
|
CARA_ELEM = element,
|
||||||
|
LIST_INST = {{ analysis_time }},
|
||||||
|
EXCIT = (
|
||||||
|
_F(
|
||||||
|
CHARGE = connection
|
||||||
|
),
|
||||||
|
_F(
|
||||||
|
CHARGE = {{ load }}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
SOLVEUR=_F(
|
||||||
|
NPREC=12,
|
||||||
|
RESI_RELA=1e-1,
|
||||||
|
STOP_SINGULIER='NON',
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
{{ res_Bld }} = CALC_CHAMP(
|
||||||
|
reuse = {{ res_Bld }},
|
||||||
|
RESULTAT = {{ res_Bld }},
|
||||||
|
CONTRAINTE=('EFGE_NOEU', ),
|
||||||
|
)
|
||||||
|
{{ "\n" }}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Ifc2CA - IFC Code_Aster utility
|
||||||
|
# Copyright (C) 2020, 2021, 2023, 2024 Ioannis P. Christovasilis <ipc@aethereng.com>
|
||||||
|
#
|
||||||
|
# This file is part of Ifc2CA.
|
||||||
|
#
|
||||||
|
# Ifc2CA is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# Ifc2CA 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 Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with Ifc2CA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
# STEP: INITIALIZE STUDY
|
||||||
|
# import code_aster
|
||||||
|
# code_aster.init()
|
||||||
|
DEBUT()
|
||||||
|
{{"\n"}}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Ifc2CA - IFC Code_Aster utility
|
# Ifc2CA - IFC Code_Aster utility
|
||||||
# Copyright (C) 2020, 2021 Ioannis P. Christovasilis <ipc@aethereng.com>
|
# Copyright (C) 2020, 2021, 2023, 2024 Ioannis P. Christovasilis <ipc@aethereng.com>
|
||||||
#
|
#
|
||||||
# This file is part of Ifc2CA.
|
# This file is part of Ifc2CA.
|
||||||
#
|
#
|
||||||
@@ -16,26 +16,31 @@
|
|||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with Ifc2CA. If not, see <http://www.gnu.org/licenses/>.
|
# along with Ifc2CA. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from __future__ import division
|
import itertools
|
||||||
from __future__ import print_function
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import json
|
from pathlib import Path
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
import salome
|
import salome
|
||||||
import salome_notebook
|
import salome_notebook
|
||||||
import salome_version
|
import salome_version
|
||||||
import numpy as np
|
|
||||||
import itertools
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
flatten = itertools.chain.from_iterable
|
flatten = itertools.chain.from_iterable
|
||||||
|
|
||||||
|
mesh_size = {{ mesh_size }}
|
||||||
|
med_path = r"{{ med_path }}"
|
||||||
|
json_path = r"{{ json_path }}"
|
||||||
|
|
||||||
|
with open(json_path, "r") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
|
||||||
|
|
||||||
class MODEL:
|
class MODEL:
|
||||||
def __init__(self, dataFilename, medFilename, meshSize):
|
def __init__(self):
|
||||||
self.dataFilename = dataFilename
|
self.medFilename = med_path
|
||||||
self.medFilename = medFilename
|
self.mesh_size = mesh_size
|
||||||
self.meshSize = meshSize
|
|
||||||
self.tolLoc = 0
|
self.tolLoc = 0
|
||||||
self.mesh = None
|
self.mesh = None
|
||||||
self.meshNodes = None
|
self.meshNodes = None
|
||||||
@@ -82,29 +87,22 @@ class MODEL:
|
|||||||
|
|
||||||
return self.geompy.MakeFaceWires(LineList, 1)
|
return self.geompy.MakeFaceWires(LineList, 1)
|
||||||
|
|
||||||
def makeObject(self, geometry, geometryType):
|
def makeObject(self, geometry, geometry_type):
|
||||||
if geometryType == "point":
|
if geometry_type == "Vertex":
|
||||||
return self.makePoint(geometry)
|
return self.makePoint(geometry)
|
||||||
if geometryType == "line":
|
if geometry_type == "Edge":
|
||||||
return self.makeLine(geometry)
|
return self.makeLine(geometry)
|
||||||
if geometryType == "surface":
|
if geometry_type == "Face":
|
||||||
return self.makeFace(geometry)
|
return self.makeFace(geometry)
|
||||||
|
|
||||||
def makePartition(self, objects, geometryType):
|
def makePartition(self, objects, geometry_type):
|
||||||
if geometryType == "point":
|
if geometry_type == "Vertex":
|
||||||
shapeType = "VERTEX"
|
shapeType = "VERTEX"
|
||||||
if geometryType == "line":
|
if geometry_type == "Edge":
|
||||||
shapeType = "EDGE"
|
shapeType = "EDGE"
|
||||||
if geometryType == "surface":
|
if geometry_type == "Face":
|
||||||
shapeType = "FACE"
|
shapeType = "FACE"
|
||||||
return self.geompy.MakePartition(
|
return self.geompy.MakePartition(objects, [], [], [], self.geompy.ShapeType[shapeType], 0, [], 1)
|
||||||
objects, [], [], [], self.geompy.ShapeType[shapeType], 0, [], 1
|
|
||||||
)
|
|
||||||
|
|
||||||
def getLinkGeometry(self, ecc, orientation, finalPoint):
|
|
||||||
vector = np.array(orientation).transpose().dot(ecc["vector"])
|
|
||||||
initialPoint = (np.array(finalPoint) - vector).tolist()
|
|
||||||
return [initialPoint, finalPoint]
|
|
||||||
|
|
||||||
def length(self, geometry):
|
def length(self, geometry):
|
||||||
return (
|
return (
|
||||||
@@ -115,18 +113,17 @@ class MODEL:
|
|||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
# Read data from input file
|
# Read data from input file
|
||||||
with open(self.dataFilename) as dataFile:
|
# data = data
|
||||||
data = json.load(dataFile)
|
|
||||||
|
|
||||||
elements = data["elements"]
|
self.elements = elements = data["elements"]
|
||||||
connections = data["connections"]
|
self.connections = connections = data["connections"]
|
||||||
# --> Delete this reference data and repopulate it with the objects
|
# --> Delete this reference data and repopulate it with the objects
|
||||||
# while going through elements
|
# while going through elements
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
conn["relatedElements"] = []
|
conn["related_elements"] = []
|
||||||
# End <--
|
# End <--
|
||||||
|
|
||||||
meshSize = self.meshSize
|
mesh_size = self.mesh_size
|
||||||
|
|
||||||
dec = 7 # 4 decimals for length in mm
|
dec = 7 # 4 decimals for length in mm
|
||||||
tol = 10 ** (-dec - 3 + 1)
|
tol = 10 ** (-dec - 3 + 1)
|
||||||
@@ -134,7 +131,7 @@ class MODEL:
|
|||||||
self.tolLoc = tol * 10 * 2
|
self.tolLoc = tol * 10 * 2
|
||||||
tolLoc = self.tolLoc
|
tolLoc = self.tolLoc
|
||||||
|
|
||||||
NEW_SALOME = int(salome_version.getVersion()[0]) >= 9
|
self.NEW_SALOME = NEW_SALOME = int(salome_version.getVersion()[0]) >= 9
|
||||||
salome.salome_init()
|
salome.salome_init()
|
||||||
theStudy = salome.myStudy
|
theStudy = salome.myStudy
|
||||||
notebook = salome_notebook.NoteBook(theStudy)
|
notebook = salome_notebook.NoteBook(theStudy)
|
||||||
@@ -142,10 +139,11 @@ class MODEL:
|
|||||||
###
|
###
|
||||||
### GEOM component
|
### GEOM component
|
||||||
###
|
###
|
||||||
import GEOM
|
|
||||||
from salome.geom import geomBuilder
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
import GEOM
|
||||||
import SALOMEDS
|
import SALOMEDS
|
||||||
|
from salome.geom import geomBuilder
|
||||||
|
|
||||||
gg = salome.ImportComponentGUI("GEOM")
|
gg = salome.ImportComponentGUI("GEOM")
|
||||||
if NEW_SALOME:
|
if NEW_SALOME:
|
||||||
@@ -163,9 +161,9 @@ class MODEL:
|
|||||||
geompy.addToStudy(OY, "OY")
|
geompy.addToStudy(OY, "OY")
|
||||||
geompy.addToStudy(OZ, "OZ")
|
geompy.addToStudy(OZ, "OZ")
|
||||||
|
|
||||||
if len([e for e in elements if e["geometryType"] == "line"]) > 0:
|
if len([e for e in elements if e["geometry_type"] == "Edge"]) > 0:
|
||||||
buildingShapeType = "EDGE"
|
buildingShapeType = "EDGE"
|
||||||
if len([e for e in elements if e["geometryType"] == "surface"]) > 0:
|
if len([e for e in elements if e["geometry_type"] == "Face"]) > 0:
|
||||||
buildingShapeType = "FACE"
|
buildingShapeType = "FACE"
|
||||||
|
|
||||||
### Define entities ###
|
### Define entities ###
|
||||||
@@ -175,31 +173,23 @@ class MODEL:
|
|||||||
|
|
||||||
# Loop 1
|
# Loop 1
|
||||||
for el in elements:
|
for el in elements:
|
||||||
el["elemObj"] = self.makeObject(el["geometry"], el["geometryType"])
|
el["elemObj"] = self.makeObject(el["geometry"], el["geometry_type"])
|
||||||
|
|
||||||
el["connObjs"] = [None for _ in el["connections"]]
|
el["connObjs"] = [None for _ in el["connections"]]
|
||||||
el["linkObjs"] = [None for _ in el["connections"]]
|
el["linkObjs"] = [None for _ in el["connections"]]
|
||||||
el["linkPointObjs"] = [[None, None] for _ in el["connections"]]
|
el["linkPointObjs"] = [[None, None] for _ in el["connections"]]
|
||||||
for j, rel in enumerate(el["connections"]):
|
for j, rel in enumerate(el["connections"]):
|
||||||
conn = [
|
conn = [c for c in connections if c["ref_id"] == rel["related_connection"]][0]
|
||||||
c for c in connections if c["referenceName"] == rel["relatedConnection"]
|
|
||||||
][0]
|
|
||||||
if rel["eccentricity"]:
|
if rel["eccentricity"]:
|
||||||
rel["index"] = len(conn["relatedElements"]) + 1
|
rel["index"] = len(conn["related_elements"]) + 1
|
||||||
conn["relatedElements"].append(rel)
|
conn["related_elements"].append(rel)
|
||||||
|
|
||||||
if not rel["eccentricity"]:
|
if not rel["eccentricity"]:
|
||||||
el["connObjs"][j] = self.makeObject(
|
el["connObjs"][j] = self.makeObject(conn["geometry"], conn["geometry_type"])
|
||||||
conn["geometry"], conn["geometryType"]
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
if conn["geometryType"] == "point":
|
if conn["geometry_type"] == "Vertex":
|
||||||
geometry = self.getLinkGeometry(
|
geometry = rel["eccentricity"]["point_on_element"], conn["geometry"]
|
||||||
rel["eccentricity"], el["orientation"], conn["geometry"]
|
el["connObjs"][j] = self.makeObject(geometry[0], conn["geometry_type"])
|
||||||
)
|
|
||||||
el["connObjs"][j] = self.makeObject(
|
|
||||||
geometry[0], conn["geometryType"]
|
|
||||||
)
|
|
||||||
|
|
||||||
el["linkPointObjs"][j][0] = self.geompy.MakeVertex(
|
el["linkPointObjs"][j][0] = self.geompy.MakeVertex(
|
||||||
geometry[0][0], geometry[0][1], geometry[0][2]
|
geometry[0][0], geometry[0][1], geometry[0][2]
|
||||||
@@ -211,27 +201,18 @@ class MODEL:
|
|||||||
el["linkPointObjs"][j][0], el["linkPointObjs"][j][1]
|
el["linkPointObjs"][j][0], el["linkPointObjs"][j][1]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print(
|
print("Eccentricity defined for a %s geometry_type" % conn["geometry_type"])
|
||||||
"Eccentricity defined for a %s geometryType"
|
el["partObj"] = self.makePartition([el["elemObj"]] + el["connObjs"], el["geometry_type"])
|
||||||
% conn["geometryType"]
|
|
||||||
)
|
|
||||||
el["partObj"] = self.makePartition(
|
|
||||||
[el["elemObj"]] + el["connObjs"], el["geometryType"]
|
|
||||||
)
|
|
||||||
el["elemObj"] = geompy.GetInPlace(el["partObj"], el["elemObj"], True)
|
el["elemObj"] = geompy.GetInPlace(el["partObj"], el["elemObj"], True)
|
||||||
for j, rel in enumerate(el["connections"]):
|
for j, rel in enumerate(el["connections"]):
|
||||||
el["connObjs"][j] = geompy.GetInPlace(
|
el["connObjs"][j] = geompy.GetInPlace(el["partObj"], el["connObjs"][j], True)
|
||||||
el["partObj"], el["connObjs"][j], True
|
|
||||||
)
|
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
conn["connObj"] = self.makeObject(conn["geometry"], conn["geometryType"])
|
conn["connObj"] = self.makeObject(conn["geometry"], conn["geometry_type"])
|
||||||
|
|
||||||
# Make assemble of Building Object
|
# Make assemble of Building Object
|
||||||
bldObjs = []
|
bldObjs = []
|
||||||
bldObjs.extend([el["partObj"] for el in elements])
|
bldObjs.extend([el["partObj"] for el in elements])
|
||||||
bldObjs.extend(
|
bldObjs.extend(flatten([[link for link in el["linkObjs"] if link] for el in elements]))
|
||||||
flatten([[link for link in el["linkObjs"] if link] for el in elements])
|
|
||||||
)
|
|
||||||
bldObjs.extend([conn["connObj"] for conn in connections])
|
bldObjs.extend([conn["connObj"] for conn in connections])
|
||||||
|
|
||||||
bldComp = geompy.MakeCompound(bldObjs)
|
bldComp = geompy.MakeCompound(bldObjs)
|
||||||
@@ -240,59 +221,55 @@ class MODEL:
|
|||||||
|
|
||||||
# Loop 2
|
# Loop 2
|
||||||
for el in elements:
|
for el in elements:
|
||||||
# geompy.addToStudy(el['partObj'], self.getGroupName(el['referenceName']))
|
# geompy.addToStudy(el['partObj'], self.getGroupName(el['ref_id']))
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(el["partObj"], el["elemObj"], self.getGroupName(el["ref_id"]))
|
||||||
el["partObj"], el["elemObj"], self.getGroupName(el["referenceName"])
|
|
||||||
)
|
|
||||||
for j, rel in enumerate(el["connections"]):
|
for j, rel in enumerate(el["connections"]):
|
||||||
conn = [
|
conn = [c for c in connections if c["ref_id"] == rel["related_connection"]][0]
|
||||||
c for c in connections if c["referenceName"] == rel["relatedConnection"]
|
|
||||||
][0]
|
|
||||||
rel["conn_string"] = None
|
rel["conn_string"] = None
|
||||||
if conn["geometryType"] == "point":
|
if conn["geometry_type"] == "Vertex":
|
||||||
rel["conn_string"] = "_0DC_"
|
rel["conn_string"] = "_0DC_"
|
||||||
if conn["geometryType"] == "line":
|
if conn["geometry_type"] == "Edge":
|
||||||
rel["conn_string"] = "_1DC_"
|
rel["conn_string"] = "_1DC_"
|
||||||
if conn["geometryType"] == "surface":
|
if conn["geometry_type"] == "Face":
|
||||||
rel["conn_string"] = "_2DC_"
|
rel["conn_string"] = "_2DC_"
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(
|
||||||
el["partObj"],
|
el["partObj"],
|
||||||
el["connObjs"][j],
|
el["connObjs"][j],
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + rel["conn_string"] + self.getGroupName(rel["related_connection"]),
|
||||||
+ rel["conn_string"]
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
)
|
)
|
||||||
if rel["eccentricity"]:
|
if rel["eccentricity"]:
|
||||||
pass
|
pass
|
||||||
# geompy.addToStudy(el['linkObjs'][j], self.getGroupName(el['referenceName']) + '_1DR_' + self.getGroupName(rel['relatedConnection']))
|
# geompy.addToStudy(el['linkObjs'][j], self.getGroupName(el['ref_id']) + '_1DR_' + self.getGroupName(rel['related_connection']))
|
||||||
# geompy.addToStudyInFather(el['linkObjs'][j], el['linkPointObjs'][j][0], self.getGroupName(rel['relatedConnection']) + '_0DC_' + self.getGroupName(el['referenceName']))
|
# geompy.addToStudyInFather(el['linkObjs'][j], el['linkPointObjs'][j][0], self.getGroupName(rel['related_connection']) + '_0DC_' + self.getGroupName(el['ref_id']))
|
||||||
# geompy.addToStudyInFather(el['linkObjs'][j], el['linkPointObjs'][j][0], self.getGroupName(rel['relatedConnection']) + '_0DC_%g' % rel['index'])
|
# geompy.addToStudyInFather(el['linkObjs'][j], el['linkPointObjs'][j][0], self.getGroupName(rel['related_connection']) + '_0DC_%g' % rel['index'])
|
||||||
|
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
# geompy.addToStudy(conn['connObj'], self.getGroupName(conn['referenceName']))
|
# geompy.addToStudy(conn['connObj'], self.getGroupName(conn['ref_id']))
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(conn["connObj"], conn["connObj"], self.getGroupName(conn["ref_id"]))
|
||||||
conn["connObj"], conn["connObj"], self.getGroupName(conn["referenceName"])
|
|
||||||
)
|
|
||||||
|
|
||||||
elapsed_time = time.time() - init_time
|
elapsed_time = time.time() - init_time
|
||||||
init_time += elapsed_time
|
init_time += elapsed_time
|
||||||
print("Building Geometry Defined in %g sec" % (elapsed_time))
|
print("Building Geometry Defined in %g sec" % (elapsed_time))
|
||||||
|
|
||||||
# Define and add groups for all curve and surface members
|
# Define and add groups for all curve and surface members
|
||||||
if len([e for e in elements if e["geometryType"] == "line"]) > 0:
|
if len([e for e in elements if e["geometry_type"] == "Edge"]) > 0:
|
||||||
# Make compound of requested group
|
# Make compound of requested group
|
||||||
compoundTemp = geompy.MakeCompound(
|
compoundTemp = geompy.MakeCompound([e["elemObj"] for e in elements if e["geometry_type"] == "Edge"])
|
||||||
[e["elemObj"] for e in elements if e["geometryType"] == "line"]
|
|
||||||
)
|
|
||||||
# Define group object and add to study
|
# Define group object and add to study
|
||||||
curveCompound = geompy.GetInPlace(bldComp, compoundTemp, True)
|
curveCompound = geompy.GetInPlace(bldComp, compoundTemp, True)
|
||||||
geompy.addToStudyInFather(bldComp, curveCompound, "CurveMembers")
|
geompy.addToStudyInFather(bldComp, curveCompound, "CurveMembers")
|
||||||
|
|
||||||
if len([e for e in elements if e["geometryType"] == "surface"]) > 0:
|
rigid_links = list(flatten([[link for link in el["linkObjs"] if link] for el in elements]))
|
||||||
|
if len(rigid_links) > 0:
|
||||||
# Make compound of requested group
|
# Make compound of requested group
|
||||||
compoundTemp = geompy.MakeCompound(
|
compoundTemp = geompy.MakeCompound(rigid_links)
|
||||||
[e["elemObj"] for e in elements if e["geometryType"] == "surface"]
|
# Define group object and add to study
|
||||||
)
|
rigidLinkCompound = geompy.GetInPlace(bldComp, compoundTemp, True)
|
||||||
|
geompy.addToStudyInFather(bldComp, rigidLinkCompound, "RigidLinks")
|
||||||
|
|
||||||
|
if len([e for e in elements if e["geometry_type"] == "Face"]) > 0:
|
||||||
|
# Make compound of requested group
|
||||||
|
compoundTemp = geompy.MakeCompound([e["elemObj"] for e in elements if e["geometry_type"] == "Face"])
|
||||||
# Define group object and add to study
|
# Define group object and add to study
|
||||||
surfaceCompound = geompy.GetInPlace(bldComp, compoundTemp, True)
|
surfaceCompound = geompy.GetInPlace(bldComp, compoundTemp, True)
|
||||||
geompy.addToStudyInFather(bldComp, surfaceCompound, "SurfaceMembers")
|
geompy.addToStudyInFather(bldComp, surfaceCompound, "SurfaceMembers")
|
||||||
@@ -300,45 +277,34 @@ class MODEL:
|
|||||||
# Loop 3
|
# Loop 3
|
||||||
for el in elements:
|
for el in elements:
|
||||||
# el['partObj'] = geompy.RestoreGivenSubShapes(bldComp, [el['partObj']], GEOM.FSM_GetInPlace, False, False)[0]
|
# el['partObj'] = geompy.RestoreGivenSubShapes(bldComp, [el['partObj']], GEOM.FSM_GetInPlace, False, False)[0]
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(bldComp, el["elemObj"], self.getGroupName(el["ref_id"]))
|
||||||
bldComp, el["elemObj"], self.getGroupName(el["referenceName"])
|
|
||||||
)
|
|
||||||
|
|
||||||
for j, rel in enumerate(el["connections"]):
|
for j, rel in enumerate(el["connections"]):
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(
|
||||||
bldComp,
|
bldComp,
|
||||||
el["connObjs"][j],
|
el["connObjs"][j],
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + rel["conn_string"] + self.getGroupName(rel["related_connection"]),
|
||||||
+ rel["conn_string"]
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
)
|
)
|
||||||
if rel["eccentricity"]: # point geometry
|
if rel["eccentricity"]: # point geometry
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(
|
||||||
bldComp,
|
bldComp,
|
||||||
el["linkObjs"][j],
|
el["linkObjs"][j],
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + "_1DR_" + self.getGroupName(rel["related_connection"]),
|
||||||
+ "_1DR_"
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
)
|
)
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(
|
||||||
bldComp,
|
bldComp,
|
||||||
el["linkPointObjs"][j][0],
|
el["linkPointObjs"][j][0],
|
||||||
self.getGroupName(rel["relatedConnection"])
|
self.getGroupName(rel["related_connection"]) + "_0DC_" + self.getGroupName(el["ref_id"]),
|
||||||
+ "_0DC_"
|
|
||||||
+ self.getGroupName(el["referenceName"]),
|
|
||||||
)
|
)
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(
|
||||||
bldComp,
|
bldComp,
|
||||||
el["linkPointObjs"][j][1],
|
el["linkPointObjs"][j][1],
|
||||||
self.getGroupName(rel["relatedConnection"])
|
self.getGroupName(rel["related_connection"]) + "_0DC_%g" % rel["index"],
|
||||||
+ "_0DC_%g" % rel["index"],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
# conn['connObj'] = geompy.RestoreGivenSubShapes(bldComp, [conn['connObj']], GEOM.FSM_GetInPlace, False, False)[0]
|
# conn['connObj'] = geompy.RestoreGivenSubShapes(bldComp, [conn['connObj']], GEOM.FSM_GetInPlace, False, False)[0]
|
||||||
geompy.addToStudyInFather(
|
geompy.addToStudyInFather(bldComp, conn["connObj"], self.getGroupName(conn["ref_id"]))
|
||||||
bldComp, conn["connObj"], self.getGroupName(conn["referenceName"])
|
|
||||||
)
|
|
||||||
|
|
||||||
elapsed_time = time.time() - init_time
|
elapsed_time = time.time() - init_time
|
||||||
init_time += elapsed_time
|
init_time += elapsed_time
|
||||||
@@ -359,15 +325,15 @@ class MODEL:
|
|||||||
smesh = smeshBuilder.New(theStudy)
|
smesh = smeshBuilder.New(theStudy)
|
||||||
bldMesh = smesh.Mesh(bldComp)
|
bldMesh = smesh.Mesh(bldComp)
|
||||||
Regular_1D = bldMesh.Segment()
|
Regular_1D = bldMesh.Segment()
|
||||||
Local_Length_1 = Regular_1D.LocalLength(meshSize, None, tolLoc)
|
Local_Length_1 = Regular_1D.LocalLength(mesh_size, None, tolLoc)
|
||||||
|
|
||||||
if buildingShapeType == "FACE":
|
if buildingShapeType == "FACE":
|
||||||
NETGEN2D_ONLY = bldMesh.Triangle(algo=smeshBuilder.NETGEN_2D)
|
NETGEN2D_ONLY = bldMesh.Triangle(algo=smeshBuilder.NETGEN_2D)
|
||||||
NETGEN2D_Pars = NETGEN2D_ONLY.Parameters()
|
NETGEN2D_Pars = NETGEN2D_ONLY.Parameters()
|
||||||
NETGEN2D_Pars.SetMaxSize(meshSize)
|
NETGEN2D_Pars.SetMaxSize(mesh_size)
|
||||||
NETGEN2D_Pars.SetOptimize(1)
|
NETGEN2D_Pars.SetOptimize(1)
|
||||||
NETGEN2D_Pars.SetFineness(2)
|
NETGEN2D_Pars.SetFineness(2)
|
||||||
NETGEN2D_Pars.SetMinSize(meshSize / 5.0)
|
NETGEN2D_Pars.SetMinSize(mesh_size / 5.0)
|
||||||
NETGEN2D_Pars.SetUseSurfaceCurvature(1)
|
NETGEN2D_Pars.SetUseSurfaceCurvature(1)
|
||||||
NETGEN2D_Pars.SetQuadAllowed(1)
|
NETGEN2D_Pars.SetQuadAllowed(1)
|
||||||
NETGEN2D_Pars.SetSecondOrder(0)
|
NETGEN2D_Pars.SetSecondOrder(0)
|
||||||
@@ -383,142 +349,111 @@ class MODEL:
|
|||||||
smesh.SetName(NETGEN2D_ONLY.GetAlgorithm(), "NETGEN2D_ONLY")
|
smesh.SetName(NETGEN2D_ONLY.GetAlgorithm(), "NETGEN2D_ONLY")
|
||||||
smesh.SetName(NETGEN2D_Pars, "NETGEN2D_Pars")
|
smesh.SetName(NETGEN2D_Pars, "NETGEN2D_Pars")
|
||||||
|
|
||||||
smesh.SetName(bldMesh.GetMesh(), "bldMesh")
|
smesh.SetName(bldMesh.GetMesh(), "{{ mesh_name }}")
|
||||||
|
|
||||||
elapsed_time = time.time() - init_time
|
elapsed_time = time.time() - init_time
|
||||||
init_time += elapsed_time
|
init_time += elapsed_time
|
||||||
print("Meshing Operations Completed in %g sec" % (elapsed_time))
|
print("Meshing Operations Completed in %g sec" % (elapsed_time))
|
||||||
|
|
||||||
# Define and add groups for all curve and surface members
|
# Define and add groups for all curve and surface members
|
||||||
if len([e for e in elements if e["geometryType"] == "line"]) > 0:
|
if len([e for e in elements if e["geometry_type"] == "Edge"]) > 0:
|
||||||
tempgroup = bldMesh.GroupOnGeom(curveCompound, "CurveMembers", SMESH.EDGE)
|
tempgroup = bldMesh.GroupOnGeom(curveCompound, "CurveMembers", SMESH.EDGE)
|
||||||
smesh.SetName(tempgroup, "CurveMembers")
|
smesh.SetName(tempgroup, "CurveMembers")
|
||||||
|
|
||||||
if len([e for e in elements if e["geometryType"] == "surface"]) > 0:
|
if len(rigid_links) > 0:
|
||||||
|
tempgroup = bldMesh.GroupOnGeom(rigidLinkCompound, "RigidLinks", SMESH.EDGE)
|
||||||
|
smesh.SetName(tempgroup, "RigidLinks")
|
||||||
|
|
||||||
|
if len([e for e in elements if e["geometry_type"] == "Face"]) > 0:
|
||||||
tempgroup = bldMesh.GroupOnGeom(surfaceCompound, "SurfaceMembers", SMESH.FACE)
|
tempgroup = bldMesh.GroupOnGeom(surfaceCompound, "SurfaceMembers", SMESH.FACE)
|
||||||
smesh.SetName(tempgroup, "SurfaceMembers")
|
smesh.SetName(tempgroup, "SurfaceMembers")
|
||||||
|
|
||||||
# Define groups in Mesh
|
# Define groups in Mesh
|
||||||
for el in elements:
|
for el in elements:
|
||||||
if el["geometryType"] == "line":
|
if el["geometry_type"] == "Edge":
|
||||||
shapeType = SMESH.EDGE
|
shapeType = SMESH.EDGE
|
||||||
if el["geometryType"] == "surface":
|
if el["geometry_type"] == "Face":
|
||||||
shapeType = SMESH.FACE
|
shapeType = SMESH.FACE
|
||||||
tempgroup = bldMesh.GroupOnGeom(
|
tempgroup = bldMesh.GroupOnGeom(el["elemObj"], self.getGroupName(el["ref_id"]), shapeType)
|
||||||
el["elemObj"], self.getGroupName(el["referenceName"]), shapeType
|
smesh.SetName(tempgroup, self.getGroupName(el["ref_id"]))
|
||||||
)
|
# tempgroup = bldMesh.GroupOnGeom(el["elemObj"], self.getGroupName(el["ref_id"]), SMESH.NODE)
|
||||||
smesh.SetName(tempgroup, self.getGroupName(el["referenceName"]))
|
# smesh.SetName(tempgroup, self.getGroupName(el["ref_id"]))
|
||||||
|
|
||||||
for j, rel in enumerate(el["connections"]):
|
for j, rel in enumerate(el["connections"]):
|
||||||
tempgroup = bldMesh.GroupOnGeom(
|
tempgroup = bldMesh.GroupOnGeom(
|
||||||
el["connObjs"][j],
|
el["connObjs"][j],
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + rel["conn_string"] + self.getGroupName(rel["related_connection"]),
|
||||||
+ rel["conn_string"]
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
SMESH.NODE,
|
SMESH.NODE,
|
||||||
)
|
)
|
||||||
smesh.SetName(
|
smesh.SetName(
|
||||||
tempgroup,
|
tempgroup,
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + rel["conn_string"] + self.getGroupName(rel["related_connection"]),
|
||||||
+ rel["conn_string"]
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
)
|
)
|
||||||
rel["node"] = (
|
rel["node"] = (bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)).GetIDs()[0]
|
||||||
bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)
|
|
||||||
).GetIDs()[0]
|
|
||||||
if rel["eccentricity"]:
|
if rel["eccentricity"]:
|
||||||
tempgroup = bldMesh.GroupOnGeom(
|
tempgroup = bldMesh.GroupOnGeom(
|
||||||
el["linkObjs"][j],
|
el["linkObjs"][j],
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + "_1DR_" + self.getGroupName(rel["related_connection"]),
|
||||||
+ "_1DR_"
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
SMESH.EDGE,
|
SMESH.EDGE,
|
||||||
)
|
)
|
||||||
smesh.SetName(
|
smesh.SetName(
|
||||||
tempgroup,
|
tempgroup,
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + "_1DR_" + self.getGroupName(rel["related_connection"]),
|
||||||
+ "_1DR_"
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
tempgroup = bldMesh.GroupOnGeom(
|
tempgroup = bldMesh.GroupOnGeom(
|
||||||
el["linkPointObjs"][j][0],
|
el["linkPointObjs"][j][0],
|
||||||
self.getGroupName(rel["relatedConnection"])
|
self.getGroupName(rel["related_connection"]) + "_0DC_" + self.getGroupName(el["ref_id"]),
|
||||||
+ "_0DC_"
|
|
||||||
+ self.getGroupName(el["referenceName"]),
|
|
||||||
SMESH.NODE,
|
SMESH.NODE,
|
||||||
)
|
)
|
||||||
smesh.SetName(
|
smesh.SetName(
|
||||||
tempgroup,
|
tempgroup,
|
||||||
self.getGroupName(rel["relatedConnection"])
|
self.getGroupName(rel["related_connection"]) + "_0DC_" + self.getGroupName(el["ref_id"]),
|
||||||
+ "_0DC_"
|
|
||||||
+ self.getGroupName(el["referenceName"]),
|
|
||||||
)
|
)
|
||||||
rel["eccNode"] = (
|
rel["eccNode"] = (bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)).GetIDs()[0]
|
||||||
bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)
|
|
||||||
).GetIDs()[0]
|
|
||||||
|
|
||||||
tempgroup = bldMesh.GroupOnGeom(
|
tempgroup = bldMesh.GroupOnGeom(
|
||||||
el["linkPointObjs"][j][1],
|
el["linkPointObjs"][j][1],
|
||||||
self.getGroupName(rel["relatedConnection"])
|
self.getGroupName(rel["related_connection"])
|
||||||
+ "_0DC_"
|
+ "_0DC_"
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
+ self.getGroupName(rel["related_connection"]),
|
||||||
SMESH.NODE,
|
SMESH.NODE,
|
||||||
)
|
)
|
||||||
smesh.SetName(
|
smesh.SetName(
|
||||||
tempgroup,
|
tempgroup,
|
||||||
self.getGroupName(rel["relatedConnection"])
|
self.getGroupName(rel["related_connection"]) + "_0DC_%g" % rel["index"],
|
||||||
+ "_0DC_%g" % rel["index"],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for conn in connections:
|
for conn in connections:
|
||||||
tempgroup = bldMesh.GroupOnGeom(
|
tempgroup = bldMesh.GroupOnGeom(conn["connObj"], self.getGroupName(conn["ref_id"]), SMESH.NODE)
|
||||||
conn["connObj"], self.getGroupName(conn["referenceName"]), SMESH.NODE
|
smesh.SetName(tempgroup, self.getGroupName(conn["ref_id"]))
|
||||||
)
|
|
||||||
smesh.SetName(tempgroup, self.getGroupName(conn["referenceName"]))
|
|
||||||
nodesId = bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)
|
nodesId = bldMesh.GetIDSource(tempgroup.GetNodeIDs(), SMESH.NODE)
|
||||||
tempgroup = bldMesh.Add0DElementsToAllNodes(
|
tempgroup = bldMesh.Add0DElementsToAllNodes(nodesId, self.getGroupName(conn["ref_id"]))
|
||||||
nodesId, self.getGroupName(conn["referenceName"])
|
smesh.SetName(tempgroup, self.getGroupName(conn["ref_id"] + "_0D"))
|
||||||
)
|
if conn["geometry_type"] == "Vertex":
|
||||||
smesh.SetName(tempgroup, self.getGroupName(conn["referenceName"] + "_0D"))
|
|
||||||
if conn["geometryType"] == "point":
|
|
||||||
conn["node"] = nodesId.GetIDs()[0]
|
conn["node"] = nodesId.GetIDs()[0]
|
||||||
if conn["geometryType"] == "line":
|
if conn["geometry_type"] == "Edge":
|
||||||
tempgroup = bldMesh.GroupOnGeom(
|
tempgroup = bldMesh.GroupOnGeom(conn["connObj"], self.getGroupName(conn["ref_id"]), SMESH.EDGE)
|
||||||
conn["connObj"], self.getGroupName(conn["referenceName"]), SMESH.EDGE
|
smesh.SetName(tempgroup, self.getGroupName(conn["ref_id"]))
|
||||||
)
|
if conn["geometry_type"] == "Face":
|
||||||
smesh.SetName(tempgroup, self.getGroupName(conn["referenceName"]))
|
tempgroup = bldMesh.GroupOnGeom(conn["connObj"], self.getGroupName(conn["ref_id"]), SMESH.FACE)
|
||||||
if conn["geometryType"] == "surface":
|
smesh.SetName(tempgroup, self.getGroupName(conn["ref_id"]))
|
||||||
tempgroup = bldMesh.GroupOnGeom(
|
|
||||||
conn["connObj"], self.getGroupName(conn["referenceName"]), SMESH.FACE
|
|
||||||
)
|
|
||||||
smesh.SetName(tempgroup, self.getGroupName(conn["referenceName"]))
|
|
||||||
|
|
||||||
# create 1D SEG2 spring elements
|
# create 1D SEG2 spring elements
|
||||||
for el in elements:
|
for el in elements:
|
||||||
for j, rel in enumerate(el["connections"]):
|
for j, rel in enumerate(el["connections"]):
|
||||||
conn = [
|
conn = [c for c in connections if c["ref_id"] == rel["related_connection"]][0]
|
||||||
c for c in connections if c["referenceName"] == rel["relatedConnection"]
|
if conn["geometry_type"] == "Vertex":
|
||||||
][0]
|
|
||||||
if conn["geometryType"] == "point":
|
|
||||||
grpName = bldMesh.CreateEmptyGroup(
|
grpName = bldMesh.CreateEmptyGroup(
|
||||||
SMESH.EDGE,
|
SMESH.EDGE,
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + "_1DS_" + self.getGroupName(rel["related_connection"]),
|
||||||
+ "_1DS_"
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
)
|
)
|
||||||
smesh.SetName(
|
smesh.SetName(
|
||||||
grpName,
|
grpName,
|
||||||
self.getGroupName(el["referenceName"])
|
self.getGroupName(el["ref_id"]) + "_1DS_" + self.getGroupName(rel["related_connection"]),
|
||||||
+ "_1DS_"
|
|
||||||
+ self.getGroupName(rel["relatedConnection"]),
|
|
||||||
)
|
)
|
||||||
if not rel["eccentricity"]:
|
if not rel["eccentricity"]:
|
||||||
conn = [
|
conn = [conn for conn in connections if conn["ref_id"] == rel["related_connection"]][0]
|
||||||
conn
|
|
||||||
for conn in connections
|
|
||||||
if conn["referenceName"] == rel["relatedConnection"]
|
|
||||||
][0]
|
|
||||||
grpName.Add([bldMesh.AddEdge([conn["node"], rel["node"]])])
|
grpName.Add([bldMesh.AddEdge([conn["node"], rel["node"]])])
|
||||||
else:
|
else:
|
||||||
grpName.Add([bldMesh.AddEdge([rel["eccNode"], rel["node"]])])
|
grpName.Add([bldMesh.AddEdge([rel["eccNode"], rel["node"]])])
|
||||||
@@ -545,26 +480,30 @@ class MODEL:
|
|||||||
except:
|
except:
|
||||||
print("ExportMED() failed. Invalid file name?")
|
print("ExportMED() failed. Invalid file name?")
|
||||||
|
|
||||||
if salome.sg.hasDesktop():
|
# if salome.sg.hasDesktop():
|
||||||
if NEW_SALOME:
|
# if NEW_SALOME:
|
||||||
salome.sg.updateObjBrowser()
|
# salome.sg.updateObjBrowser()
|
||||||
else:
|
# else:
|
||||||
salome.sg.updateObjBrowser(1)
|
# salome.sg.updateObjBrowser(1)
|
||||||
|
|
||||||
elapsed_time = init_time - start_time
|
elapsed_time = init_time - start_time
|
||||||
print("ALL Operations Completed in %g sec" % (elapsed_time))
|
print("ALL Operations Completed in %g sec" % (elapsed_time))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
model = MODEL()
|
||||||
fileNames = ["structure_01"]
|
|
||||||
files = fileNames
|
|
||||||
|
|
||||||
meshSize = 0.1
|
for el in model.elements:
|
||||||
|
for j, conn in enumerate(el["connections"]):
|
||||||
|
d = model.geompy.MinDistance(el["elemObj"], el["connObjs"][j])
|
||||||
|
if d > 0:
|
||||||
|
print(f'NOTE: Element {el["ref_id"]} and connection {conn["ref_id"]} have a distance of {d}')
|
||||||
|
# elif d == 0:
|
||||||
|
# print(
|
||||||
|
# f'SUCCESS: Element {el["ref_id"]} and connection {conn["ref_id"]} have a distance of {d}'
|
||||||
|
# )
|
||||||
|
|
||||||
for fileName in files:
|
if salome.sg.hasDesktop():
|
||||||
BASE_PATH = Path(
|
if model.NEW_SALOME:
|
||||||
"/home/jesusbill/Dev-Projects/github.com/IfcOpenShell/analysis-models/models/"
|
salome.sg.updateObjBrowser()
|
||||||
)
|
else:
|
||||||
DATAFILENAME = BASE_PATH / fileName / f"{fileName}.json"
|
salome.sg.updateObjBrowser(1)
|
||||||
MEDFILENAME = BASE_PATH / fileName / f"{fileName}.med"
|
|
||||||
model = MODEL(DATAFILENAME, str(MEDFILENAME), meshSize)
|
|
||||||
Reference in New Issue
Block a user