Skip to content

Commit

Permalink
Fix tube network number of element settings
Browse files Browse the repository at this point in the history
  • Loading branch information
rchristie committed Sep 8, 2024
1 parent 78cc4e5 commit 6116333
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 149 deletions.
23 changes: 11 additions & 12 deletions src/scaffoldmaker/meshtypes/meshtype_2d_tubenetwork1.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def getParameterSetNames(cls):
def getDefaultOptions(cls, parameterSetName="Default"):
options = {
"Network layout": ScaffoldPackage(MeshType_1d_network_layout1, defaultParameterSetName=parameterSetName),
"Elements count around": 8,
"Annotation elements counts around": [0],
"Number of elements around": 8,
"Annotation numbers of elements around": [0],
"Target element density along longest segment": 4.0,
"Show trim surfaces": False
}
Expand All @@ -35,8 +35,8 @@ def getDefaultOptions(cls, parameterSetName="Default"):
def getOrderedOptionNames():
return [
"Network layout",
"Elements count around",
"Annotation elements counts around",
"Number of elements around",
"Annotation numbers of elements around",
"Target element density along longest segment",
"Show trim surfaces"
]
Expand Down Expand Up @@ -74,12 +74,12 @@ def getOptionScaffoldPackage(cls, optionName, scaffoldType, parameterSetName=Non
def checkOptions(cls, options):
if not options["Network layout"].getScaffoldType() in cls.getOptionValidScaffoldTypes("Network layout"):
options["Network layout"] = cls.getOptionScaffoldPackage("Network layout", MeshType_1d_network_layout1)
elementsCountAround = options["Elements count around"]
if options["Elements count around"] < 4:
options["Elements count around"] = 4
annotationElementsCountsAround = options["Annotation elements counts around"]
dependentChanges = False
if options["Number of elements around"] < 4:
options["Number of elements around"] = 4
annotationElementsCountsAround = options["Annotation numbers of elements around"]
if len(annotationElementsCountsAround) == 0:
options["Annotation elements count around"] = [0]
options["Annotation numbers of elements around"] = [0]
else:
for i in range(len(annotationElementsCountsAround)):
if annotationElementsCountsAround[i] <= 0:
Expand All @@ -88,7 +88,6 @@ def checkOptions(cls, options):
annotationElementsCountsAround[i] = 4
if options["Target element density along longest segment"] < 1.0:
options["Target element density along longest segment"] = 1.0
dependentChanges = False
return dependentChanges

@classmethod
Expand All @@ -107,10 +106,10 @@ def generateBaseMesh(cls, region, options):
tubeNetworkMeshBuilder = TubeNetworkMeshBuilder(
networkMesh,
targetElementDensityAlongLongestSegment=options["Target element density along longest segment"],
defaultElementsCountAround=options["Elements count around"],
defaultElementsCountAround=options["Number of elements around"],
elementsCountThroughWall=1,
layoutAnnotationGroups=networkLayout.getAnnotationGroups(),
annotationElementsCountsAround=options["Annotation elements counts around"])
annotationElementsCountsAround=options["Annotation numbers of elements around"])
tubeNetworkMeshBuilder.build()
generateData = TubeNetworkMeshGenerateData(
region, 2,
Expand Down
212 changes: 121 additions & 91 deletions src/scaffoldmaker/meshtypes/meshtype_3d_tubenetwork1.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,62 +8,19 @@
calculateElementsCountAcrossMinor, TubeNetworkMeshBuilder, TubeNetworkMeshGenerateData)


def checkCoreParameters(cls, options, dependentChangesIn=False):
dependentChanges = dependentChangesIn
# Check elements count around are ok
if options["Elements count around"] < 8:
options["Elements count around"] = 8 # core transition and major element counts may also reduce below
dependentChanges = True
elif options["Elements count around"] % 4:
options["Elements count around"] += 4 - options["Elements count around"] % 4

# Check elements count across transition
if options['Number of elements across core transition'] < 1:
options['Number of elements across core transition'] = 1
while True:
minElementsCountAcross = 2 + 2 * options['Number of elements across core transition']
maxElementsCountAcross = calculateElementsCountAcrossMinor(
options["Elements count around"], options['Number of elements across core transition'],
minElementsCountAcross)
if maxElementsCountAcross >= minElementsCountAcross:
break
options['Number of elements across core transition'] -= 1
dependentChanges = True

# Check elements count across major are ok
if options['Number of elements across core major'] < minElementsCountAcross:
options['Number of elements across core major'] = minElementsCountAcross
dependentChanges = True
elif options['Number of elements across core major'] > maxElementsCountAcross:
options['Number of elements across core major'] = maxElementsCountAcross
dependentChanges = True
elif (options['Number of elements across core major'] % 2):
options['Number of elements across core major'] += 1

annotationElementsCountsAround = options["Annotation elements counts around"]
if len(annotationElementsCountsAround) == 0:
options["Annotation elements count around"] = [0]
else:
for i in range(len(annotationElementsCountsAround)):
if annotationElementsCountsAround[i] <= 0:
annotationElementsCountsAround[i] = 0
elif annotationElementsCountsAround[i] < 4:
annotationElementsCountsAround[i] = 4

if options["Use linear through wall"]:
dependentChanges = True
options["Use linear through wall"] = False

return dependentChanges


class MeshType_3d_tubenetwork1(Scaffold_base):
"""
Generates a 3-D hermite tube network, with linear or cubic basis through wall.
Number of elements generated are primarily controlled by "elements count around" and "elements count across major".
The elements count around parameter determines the number of elements around a circular rim.
The elements count across major determines the number of elements across the major axis of an ellipse (y-axis in the scaffold).
The number of elements across minor axis (z-axis) is calculated internally based on the two elements count parameters.
Generates a 3-D hermite tube network from a network layout description, with linear or cubic basis through the
shell wall, optionally with a solid core. The number of elements generated are primarily controlled by the
"Number of elements around" and "Number of elements across core box minor" settings.
The Number of elements around parameter determines the number of elements around the elliptical shell.
The core is built out of a regular box with specified number of elements across core box minor.
The minor direction is in the direction of d3 in the network layout it is defined from.
The number of elements across the core box major axis is calculated internally from the above.
The reason for preferring the minor number is that this must currently match when using the core,
plus it is planned to eventually use an odd number to specify a half phase difference in starting node
even without a core, as that is required to work with odd minor numbers in the core, once supported.
There are any number of transition elements between the box and the shell forming further concentric rim elements.
"""

@classmethod
Expand All @@ -80,33 +37,33 @@ def getDefaultOptions(cls, parameterSetName="Default"):
"Network layout": ScaffoldPackage(MeshType_1d_network_layout1,
{"scaffoldSettings": {"Define inner coordinates": True}},
defaultParameterSetName=parameterSetName),
"Elements count around": 8,
"Elements count through wall": 1,
"Annotation elements counts around": [0],
"Number of elements around": 8,
"Number of elements through shell": 1,
"Annotation numbers of elements around": [0],
"Target element density along longest segment": 4.0,
"Use linear through wall": False,
"Use linear through shell": False,
"Show trim surfaces": False,
"Core": False,
'Number of elements across core major': 4,
'Number of elements across core transition': 1,
"Annotation elements counts across major": [0]
"Number of elements across core box minor": 2,
"Number of elements across core transition": 1,
"Annotation numbers of elements across core box minor": [0]
}
return options

@staticmethod
def getOrderedOptionNames():
return [
"Network layout",
"Elements count around",
"Elements count through wall",
"Annotation elements counts around",
"Number of elements around",
"Number of elements through shell",
"Annotation numbers of elements around",
"Target element density along longest segment",
"Use linear through wall",
"Use linear through shell",
"Show trim surfaces",
"Core",
'Number of elements across core major',
'Number of elements across core transition',
"Annotation elements counts across major"
"Number of elements across core box minor",
"Number of elements across core transition",
"Annotation numbers of elements across core box minor"
]

@classmethod
Expand Down Expand Up @@ -146,27 +103,84 @@ def checkOptions(cls, options):
options["Network layout"] = cls.getOptionScaffoldPackage("Network layout", MeshType_1d_network_layout1)
dependentChanges = False

# Parameters specific to the core
if options["Core"] == True:
dependentChanges = checkCoreParameters(cls, options, dependentChanges)
if options["Number of elements around"] < 8:
options["Number of elements around"] = 8
elif options["Number of elements around"] % 4:
options["Number of elements around"] += 4 - options["Number of elements around"] % 4

annotationAroundCounts = options["Annotation numbers of elements around"]
minAroundCount = options["Number of elements around"]
if len(annotationAroundCounts) == 0:
annotationAroundCounts = options["Annotation numbers of elements around"] = [0]
else:
for i in range(len(annotationAroundCounts)):
if annotationAroundCounts[i] <= 0:
annotationAroundCounts[i] = 0
else:
if annotationAroundCounts[i] < 8:
annotationAroundCounts[i] = 8
elif annotationAroundCounts[i] % 4:
annotationAroundCounts[i] += 4 - annotationAroundCounts[i]
if annotationAroundCounts[i] < minAroundCount:
minAroundCount = annotationAroundCounts[i]

if options["Number of elements across core transition"] < 1:
options["Number of elements across core transition"] = 1

maxCoreBoxMinorCount = options["Number of elements around"] // 2 - 2
if options["Number of elements across core box minor"] < 2:
options["Number of elements across core box minor"] = 2
elif options["Number of elements across core box minor"] > maxCoreBoxMinorCount:
options["Number of elements across core box minor"] = maxCoreBoxMinorCount
dependentChanges = True
elif options["Number of elements across core box minor"] % 2:
options["Number of elements across core box minor"] += 1

annotationCoreBoxMinorCounts = options["Annotation numbers of elements across core box minor"]
if len(annotationCoreBoxMinorCounts) == 0:
annotationCoreBoxMinorCounts = options["Annotation numbers of elements across core box minor"] = [0]
if len(annotationCoreBoxMinorCounts) > len(annotationAroundCounts):
annotationCoreBoxMinorCounts = options["Annotation numbers of elements across core box minor"] = \
annotationCoreBoxMinorCounts[:len(annotationAroundCounts)]
dependentChanges = True
for i in range(len(annotationCoreBoxMinorCounts)):
aroundCount = annotationAroundCounts[i] if annotationAroundCounts[i] \
else options["Number of elements around"]
maxCoreBoxMinorCount = aroundCount // 2 - 2
if annotationCoreBoxMinorCounts[i] <= 0:
annotationCoreBoxMinorCounts[i] = 0
# this may reduce the default
if maxCoreBoxMinorCount < options["Number of elements across core box minor"]:
options["Number of elements across core box minor"] = maxCoreBoxMinorCount
dependentChanges = True
elif annotationCoreBoxMinorCounts[i] < 2:
annotationCoreBoxMinorCounts[i] = 2
elif annotationCoreBoxMinorCounts[i] > maxCoreBoxMinorCount:
annotationCoreBoxMinorCounts[i] = maxCoreBoxMinorCount
dependentChanges = True
elif annotationCoreBoxMinorCounts[i] % 2:
annotationCoreBoxMinorCounts[i] += 1

if options["Use linear through shell"]:
options["Use linear through shell"] = False
dependentChanges = True

# When core option is false
else:
if options["Elements count around"] < 4:
options["Elements count around"] = 4
annotationElementsCountsAround = options["Annotation elements counts around"]
if len(annotationElementsCountsAround) == 0:
options["Annotation elements count around"] = [0]
if options["Number of elements around"] < 4:
options["Number of elements around"] = 4
annotationAroundCounts = options["Annotation numbers of elements around"]
if len(annotationAroundCounts) == 0:
options["Annotation numbers of elements around"] = [0]
else:
for i in range(len(annotationElementsCountsAround)):
if annotationElementsCountsAround[i] <= 0:
annotationElementsCountsAround[i] = 0
elif annotationElementsCountsAround[i] < 4:
annotationElementsCountsAround[i] = 4
for i in range(len(annotationAroundCounts)):
if annotationAroundCounts[i] <= 0:
annotationAroundCounts[i] = 0
elif annotationAroundCounts[i] < 4:
annotationAroundCounts[i] = 4

# Common parameters
if options["Elements count through wall"] < 1:
options["Elements count through wall"] = 1
if options["Number of elements through shell"] < 1:
options["Number of elements through shell"] = 1

if options["Target element density along longest segment"] < 1.0:
options["Target element density along longest segment"] = 1.0
Expand All @@ -187,22 +201,38 @@ def generateBaseMesh(cls, region, options):
layoutAnnotationGroups = networkLayout.getAnnotationGroups()
networkMesh = networkLayout.getConstructionObject()

defaultAroundCount = options["Number of elements around"]
elementsCountTransition = options["Number of elements across core transition"]
defaultCoreBoxMinorCount = options["Number of elements across core box minor"]
defaultElementsCountAcrossMajor = calculateElementsCountAcrossMinor(
defaultAroundCount, elementsCountTransition, defaultCoreBoxMinorCount + 2 * elementsCountTransition)
annotationAroundCounts = options["Annotation numbers of elements around"]
annotationCoreBoxMinorCounts = options["Annotation numbers of elements across core box minor"]
annotationElementsCountsAcrossMajor = []
for i in range(len(annotationCoreBoxMinorCounts)):
aroundCount = annotationAroundCounts[i] if annotationAroundCounts[i] \
else defaultAroundCount
coreBoxMinorCount = annotationCoreBoxMinorCounts[i] if annotationCoreBoxMinorCounts[i] \
else defaultCoreBoxMinorCount
annotationElementsCountsAcrossMajor.append(calculateElementsCountAcrossMinor(
aroundCount, elementsCountTransition, coreBoxMinorCount + 2 * elementsCountTransition))

tubeNetworkMeshBuilder = TubeNetworkMeshBuilder(
networkMesh,
targetElementDensityAlongLongestSegment=options["Target element density along longest segment"],
defaultElementsCountAround=options["Elements count around"],
elementsCountThroughWall=options["Elements count through wall"],
defaultElementsCountAround=defaultAroundCount,
elementsCountThroughWall=options["Number of elements through shell"],
layoutAnnotationGroups=layoutAnnotationGroups,
annotationElementsCountsAround=options["Annotation elements counts around"],
defaultElementsCountAcrossMajor=options['Number of elements across core major'],
elementsCountTransition=options['Number of elements across core transition'],
annotationElementsCountsAcrossMajor=options["Annotation elements counts across major"],
annotationElementsCountsAround=annotationAroundCounts,
defaultElementsCountAcrossMajor=defaultElementsCountAcrossMajor,
elementsCountTransition=elementsCountTransition,
annotationElementsCountsAcrossMajor=annotationElementsCountsAcrossMajor,
isCore=options["Core"])

tubeNetworkMeshBuilder.build()
generateData = TubeNetworkMeshGenerateData(
region, 3,
isLinearThroughWall=options["Use linear through wall"],
isLinearThroughWall=options["Use linear through shell"],
isShowTrimSurfaces=options["Show trim surfaces"])
tubeNetworkMeshBuilder.generateMesh(generateData)
annotationGroups = generateData.getAnnotationGroups()
Expand Down
4 changes: 2 additions & 2 deletions src/scaffoldmaker/meshtypes/meshtype_3d_wholebody2.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ class MeshType_3d_wholebody2(Scaffold_base):
Generates a 3-D hermite bifurcating tube network, with linear basis through wall.
"""

@staticmethod
def getName():
@classmethod
def getName(cls):
return "3D Whole Body 2"

@classmethod
Expand Down
Loading

0 comments on commit 6116333

Please sign in to comment.