From ef40e5d80c8a435042d18da178faa737edd4d71e Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Wed, 20 Mar 2019 12:01:29 +1300 Subject: [PATCH 01/10] Create texture coordinates --- .../utils/eftfactory_bicubichermitelinear.py | 19 ++++ scaffoldmaker/utils/tubemesh.py | 101 ++++++++++++++++++ scaffoldmaker/utils/zinc_utils.py | 28 +++++ 3 files changed, 148 insertions(+) diff --git a/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py b/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py index 624c69e2..d02633f5 100644 --- a/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py +++ b/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py @@ -206,3 +206,22 @@ def createEftSplitXi1RightOut(self): remapEftNodeValueLabel(eft, [ 5, 7 ], self._d_ds2, [ (self._d_ds1, [1]), (self._d_ds2, []) ]) assert eft.validate(), 'eftfactory_bicubichermitelinear.createEftSplitXi1RightOut: Failed to validate eft' return eft + + def createEftOpenTube(self): + ''' + Create a basic bicubic hermite linear element template for elements + along boundary where a tube is opened for a flat preparation. Retain node + numbering with two versions for boundary nodes. + :return: Element field template + ''' + eft = self.createEftBasic() + for n in [ 1, 3, 5, 7 ]: + ln = n + 1 + eft.setTermNodeParameter(n*4 + 1, 1, ln, Node.VALUE_LABEL_VALUE, 2) + eft.setTermNodeParameter(n*4 + 2, 1, ln, Node.VALUE_LABEL_D_DS1, 2) + eft.setTermNodeParameter(n*4 + 3, 1, ln, Node.VALUE_LABEL_D_DS2, 2) + if self._useCrossDerivatives: + eft.setTermNodeParameter(n*4 + 4, 1, ln, Node.VALUE_LABEL_D2_DS1DS2, 2) + + assert eft.validate(), 'eftfactory_bicubichermitelinear.createEftFlattenTube: Failed to validate eft' + return eft diff --git a/scaffoldmaker/utils/tubemesh.py b/scaffoldmaker/utils/tubemesh.py index 77b1a659..f116ed1c 100644 --- a/scaffoldmaker/utils/tubemesh.py +++ b/scaffoldmaker/utils/tubemesh.py @@ -243,6 +243,107 @@ def generatetubemesh(region, result = element.setNodesByIdentifier(eft, nodeIdentifiers) elementIdentifier = elementIdentifier + 1 + # Create texture coordinates + textureCoordinates = getOrCreateTextureCoordinateField(fm) + textureNodetemplate1 = nodes.createNodetemplate() + textureNodetemplate1.defineField(textureCoordinates) + textureNodetemplate1.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_VALUE, 1) + textureNodetemplate1.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_D_DS1, 1) + textureNodetemplate1.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_D_DS2, 1) + if useCrossDerivatives: + textureNodetemplate1.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_D2_DS1DS2, 1) + + textureNodetemplate2 = nodes.createNodetemplate() + textureNodetemplate2.defineField(textureCoordinates) + textureNodetemplate2.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_VALUE, 2) + textureNodetemplate2.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_D_DS1, 2) + textureNodetemplate2.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_D_DS2, 2) + if useCrossDerivatives: + textureNodetemplate2.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_D2_DS1DS2, 2) + + bicubichermitelinear = eftfactory_bicubichermitelinear(mesh, useCrossDerivatives) + eftTexture = bicubichermitelinear.createEftBasic() + + elementtemplate1 = mesh.createElementtemplate() + elementtemplate1.setElementShapeType(Element.SHAPE_TYPE_CUBE) + elementtemplate1.defineField(textureCoordinates, -1, eftTexture) + + eftTexture2 = bicubichermitelinear.createEftOpenTube() + elementtemplate2 = mesh.createElementtemplate() + elementtemplate2.setElementShapeType(Element.SHAPE_TYPE_CUBE) + elementtemplate2.defineField(textureCoordinates, -1, eftTexture2) + + # Calculate texture coordinates and derivatives + uTexture = [] + d1Texture = [] + d2Texture = [] + for n3 in range(elementsCountThroughWall + 1): + for n2 in range(elementsCountAlong + 1): + for n1 in range(elementsCountAround + 1): + u = [ 1.0 / elementsCountAround * n1, + 1.0 / elementsCountAlong * n2, + wallThickness / elementsCountThroughWall * n3] + d1 = [1.0 / elementsCountAround, 0.0, 0.0] + d2 = [0.0, 1.0 / elementsCountAlong, 0.0] + uTexture.append(u) + d1Texture.append(d1) + d2Texture.append(d2) + + nodeIdentifier = nextNodeIdentifier + for n in range(len(uTexture)): + if n%(elementsCountAround+1) == 0.0: + node = nodes.findNodeByIdentifier(nodeIdentifier) + node.merge(textureNodetemplate2) + cache.setNode(node) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, uTexture[n]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1Texture[n]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2Texture[n]) + endIdx = n + elementsCountAround + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 2, uTexture[endIdx]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 2, d1Texture[endIdx]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 2, d2Texture[endIdx]) + if useCrossDerivatives: + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 1, zero) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 2, zero) + nodeIdentifier = nodeIdentifier + 1 + elif (n+1)%(elementsCountAround+1) > 0: + node = nodes.findNodeByIdentifier(nodeIdentifier) + node.merge(textureNodetemplate1) + cache.setNode(node) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, uTexture[n]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1Texture[n]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2Texture[n]) + if useCrossDerivatives: + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 1, zero) + nodeIdentifier = nodeIdentifier + 1 + + # create texture coordinate elements + elementIdentifier = nextElementIdentifier + now = (elementsCountAlong + 1)*elementsCountAround + for e3 in range(elementsCountThroughWall): + for e2 in range(elementsCountAlong): + for e1 in range(elementsCountAround): + if e1 < elementsCountAround - 1: + element = mesh.findElementByIdentifier(elementIdentifier) + element.merge(elementtemplate1) + bni11 = e3*now + e2*elementsCountAround + e1 + 1 + bni12 = e3*now + e2*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + bni21 = e3*now + (e2 + 1)*elementsCountAround + e1 + 1 + bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + nodeIdentifiers = [ bni11, bni12, bni21, bni22, bni11 + now, bni12 + now, bni21 + now, bni22 + now ] + result = element.setNodesByIdentifier(eftTexture, nodeIdentifiers) + else: + element = mesh.findElementByIdentifier(elementIdentifier) + element.merge(elementtemplate2) + # element = mesh.createElement(elementIdentifier, elementtemplate2) + bni11 = e3*now + e2*elementsCountAround + e1 + 1 + bni12 = e3*now + e2*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + bni21 = e3*now + (e2 + 1)*elementsCountAround + e1 + 1 + bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + nodeIdentifiers = [ bni11, bni12, bni21, bni22, bni11 + now, bni12 + now, bni21 + now, bni22 + now] + result2 = element.setNodesByIdentifier(eftTexture2, nodeIdentifiers) + elementIdentifier = elementIdentifier + 1 + fm.endChange() return annotationGroups, nodeIdentifier, elementIdentifier diff --git a/scaffoldmaker/utils/zinc_utils.py b/scaffoldmaker/utils/zinc_utils.py index 6c6fe294..002547ed 100644 --- a/scaffoldmaker/utils/zinc_utils.py +++ b/scaffoldmaker/utils/zinc_utils.py @@ -38,6 +38,34 @@ def getOrCreateCoordinateField(fieldmodule, name='coordinates', componentsCount= fieldmodule.endChange() return coordinates +def getOrCreateTextureCoordinateField(fieldmodule, name='textureCoordinates', componentsCount=3): + ''' + Finds or creates a rectangular cartesian texture coordinate field. + New field has component names, 'u', 'v', 'w'. + Raises exception if existing field of name is not finite element type or has incorrect attributes. + :param fieldmodule: Zinc fieldmodule to find or create field in. + :param name: Name of field to find or create. + :param componentsCount: Number of components / dimension of field. + ''' + assert (componentsCount > 0) and (componentsCount <= 3), 'getOrCreateCoordinateField. Dimensions must be from 1 to 3' + coordinates = fieldmodule.findFieldByName(name) + if coordinates.isValid(): + coordinates = coordinates.castFiniteElement() + assert coordinates.isValid(), 'getOrCreateCoordinateField. Existing field \'' + name + '\' is not finite element type' + assert coordinates.getNumberOfComponents() == componentsCount, 'getOrCreateCoordinateField. Existing field \'' + name + '\' does not have ' + str(componentsCount) + ' components' + assert coordinates.getCoordinateSystemType() == Field.COORDINATE_SYSTEM_TYPE_RECTANGULAR_CARTESIAN, 'getOrCreateCoordinateField. Existing field \'' + name + '\' is not rectangular Cartesian' + return coordinates + fieldmodule.beginChange() + coordinates = fieldmodule.createFieldFiniteElement(componentsCount) + coordinates.setName(name) + coordinates.setManaged(True) + coordinates.setTypeCoordinate(True) + coordinates.setCoordinateSystemType(Field.COORDINATE_SYSTEM_TYPE_RECTANGULAR_CARTESIAN) + for c in range(componentsCount): + coordinates.setComponentName(c + 1, ['u', 'v', 'w'][c]) + fieldmodule.endChange() + return coordinates + def getOrCreateElementXiField(fieldmodule, name='element_xi', mesh=None): ''' Finds or creates a stored mesh location field for storing locations in the From f5e49210c5bdf7d3073c0f13e4caaaa3c87cbb1f Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 15:11:31 +1300 Subject: [PATCH 02/10] Change textureCoordinate w to be between 0 and 1 --- scaffoldmaker/utils/tubemesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scaffoldmaker/utils/tubemesh.py b/scaffoldmaker/utils/tubemesh.py index f116ed1c..6c7981cf 100644 --- a/scaffoldmaker/utils/tubemesh.py +++ b/scaffoldmaker/utils/tubemesh.py @@ -282,7 +282,7 @@ def generatetubemesh(region, for n1 in range(elementsCountAround + 1): u = [ 1.0 / elementsCountAround * n1, 1.0 / elementsCountAlong * n2, - wallThickness / elementsCountThroughWall * n3] + 1.0 / elementsCountThroughWall * n3] d1 = [1.0 / elementsCountAround, 0.0, 0.0] d2 = [0.0, 1.0 / elementsCountAlong, 0.0] uTexture.append(u) From 6f23521bb65e552f44536bc9c5caefab72b02e68 Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 16:39:21 +1300 Subject: [PATCH 03/10] Correct name difference in assert --- scaffoldmaker/utils/eftfactory_bicubichermitelinear.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py b/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py index d02633f5..0abed7fc 100644 --- a/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py +++ b/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py @@ -223,5 +223,5 @@ def createEftOpenTube(self): if self._useCrossDerivatives: eft.setTermNodeParameter(n*4 + 4, 1, ln, Node.VALUE_LABEL_D2_DS1DS2, 2) - assert eft.validate(), 'eftfactory_bicubichermitelinear.createEftFlattenTube: Failed to validate eft' + assert eft.validate(), 'eftfactory_bicubichermitelinear.createEftOpenTube: Failed to validate eft' return eft From 0276ce1cd75a763b8e66d871b0a2a2bea8594942 Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 16:46:35 +1300 Subject: [PATCH 04/10] Change 'next' to 'first' in nextNodeIdentifier and nextElementIdentifier --- scaffoldmaker/utils/tubemesh.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scaffoldmaker/utils/tubemesh.py b/scaffoldmaker/utils/tubemesh.py index 6c7981cf..7236aa5b 100644 --- a/scaffoldmaker/utils/tubemesh.py +++ b/scaffoldmaker/utils/tubemesh.py @@ -25,7 +25,7 @@ def generatetubemesh(region, segmentAxis, segmentLength, useCrossDerivatives, useCubicHermiteThroughWall, # or Zinc Elementbasis.FUNCTION_TYPE_LINEAR_LAGRANGE etc. - nextNodeIdentifier = 1, nextElementIdentifier = 1 + firstNodeIdentifier = 1, firstElementIdentifier = 1 ): ''' Generates a 3-D tubular mesh with variable numbers of elements @@ -45,7 +45,7 @@ def generatetubemesh(region, :param segmentAxis: axis of segment profile :param segmentLength: length of segment profile :param useCubicHermiteThroughWall: use linear when false - :return: annotationGroups, nextNodeIdentifier, nextElementIdentifier + :return: annotationGroups, nodeIdentifier, elementIdentifier ''' zero = [0.0, 0.0, 0.0] annotationGroups = [] @@ -122,7 +122,7 @@ def generatetubemesh(region, result = elementtemplate.defineField(coordinates, -1, eft) # create nodes - nodeIdentifier = nextNodeIdentifier + nodeIdentifier = firstNodeIdentifier x = [ 0.0, 0.0, 0.0 ] dx_ds1 = [ 0.0, 0.0, 0.0 ] dx_ds2 = [ 0.0, 0.0, 0.0 ] @@ -229,7 +229,7 @@ def generatetubemesh(region, # nodeIdentifier = nodeIdentifier + 1 # create elements - elementIdentifier = nextElementIdentifier + elementIdentifier = firstElementIdentifier now = (elementsCountAlong + 1)*elementsCountAround for e3 in range(elementsCountThroughWall): for e2 in range(elementsCountAlong): @@ -289,7 +289,7 @@ def generatetubemesh(region, d1Texture.append(d1) d2Texture.append(d2) - nodeIdentifier = nextNodeIdentifier + nodeIdentifier = firstNodeIdentifier for n in range(len(uTexture)): if n%(elementsCountAround+1) == 0.0: node = nodes.findNodeByIdentifier(nodeIdentifier) @@ -318,7 +318,7 @@ def generatetubemesh(region, nodeIdentifier = nodeIdentifier + 1 # create texture coordinate elements - elementIdentifier = nextElementIdentifier + elementIdentifier = firstElementIdentifier now = (elementsCountAlong + 1)*elementsCountAround for e3 in range(elementsCountThroughWall): for e2 in range(elementsCountAlong): From a18b72800f553f618b358cf0b7a32cdd35da5477 Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 16:50:46 +1300 Subject: [PATCH 05/10] Change comment to 'define texture coordinates field over elements' --- scaffoldmaker/utils/tubemesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scaffoldmaker/utils/tubemesh.py b/scaffoldmaker/utils/tubemesh.py index 7236aa5b..d58b3a79 100644 --- a/scaffoldmaker/utils/tubemesh.py +++ b/scaffoldmaker/utils/tubemesh.py @@ -317,7 +317,7 @@ def generatetubemesh(region, textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 1, zero) nodeIdentifier = nodeIdentifier + 1 - # create texture coordinate elements + # define texture coordinates field over elements elementIdentifier = firstElementIdentifier now = (elementsCountAlong + 1)*elementsCountAround for e3 in range(elementsCountThroughWall): From 155369ec2b4c82604c938f032afb6c19825265ae Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 17:21:22 +1300 Subject: [PATCH 06/10] Remove common code when defining texture coordinate field over elements --- scaffoldmaker/utils/tubemesh.py | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/scaffoldmaker/utils/tubemesh.py b/scaffoldmaker/utils/tubemesh.py index d58b3a79..12b2b42d 100644 --- a/scaffoldmaker/utils/tubemesh.py +++ b/scaffoldmaker/utils/tubemesh.py @@ -262,11 +262,11 @@ def generatetubemesh(region, textureNodetemplate2.setValueNumberOfVersions(textureCoordinates, -1, Node.VALUE_LABEL_D2_DS1DS2, 2) bicubichermitelinear = eftfactory_bicubichermitelinear(mesh, useCrossDerivatives) - eftTexture = bicubichermitelinear.createEftBasic() + eftTexture1 = bicubichermitelinear.createEftBasic() elementtemplate1 = mesh.createElementtemplate() elementtemplate1.setElementShapeType(Element.SHAPE_TYPE_CUBE) - elementtemplate1.defineField(textureCoordinates, -1, eftTexture) + elementtemplate1.defineField(textureCoordinates, -1, eftTexture1) eftTexture2 = bicubichermitelinear.createEftOpenTube() elementtemplate2 = mesh.createElementtemplate() @@ -320,28 +320,19 @@ def generatetubemesh(region, # define texture coordinates field over elements elementIdentifier = firstElementIdentifier now = (elementsCountAlong + 1)*elementsCountAround + for e3 in range(elementsCountThroughWall): for e2 in range(elementsCountAlong): for e1 in range(elementsCountAround): - if e1 < elementsCountAround - 1: - element = mesh.findElementByIdentifier(elementIdentifier) - element.merge(elementtemplate1) - bni11 = e3*now + e2*elementsCountAround + e1 + 1 - bni12 = e3*now + e2*elementsCountAround + (e1 + 1)%elementsCountAround + 1 - bni21 = e3*now + (e2 + 1)*elementsCountAround + e1 + 1 - bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1)%elementsCountAround + 1 - nodeIdentifiers = [ bni11, bni12, bni21, bni22, bni11 + now, bni12 + now, bni21 + now, bni22 + now ] - result = element.setNodesByIdentifier(eftTexture, nodeIdentifiers) - else: - element = mesh.findElementByIdentifier(elementIdentifier) - element.merge(elementtemplate2) - # element = mesh.createElement(elementIdentifier, elementtemplate2) - bni11 = e3*now + e2*elementsCountAround + e1 + 1 - bni12 = e3*now + e2*elementsCountAround + (e1 + 1)%elementsCountAround + 1 - bni21 = e3*now + (e2 + 1)*elementsCountAround + e1 + 1 - bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1)%elementsCountAround + 1 - nodeIdentifiers = [ bni11, bni12, bni21, bni22, bni11 + now, bni12 + now, bni21 + now, bni22 + now] - result2 = element.setNodesByIdentifier(eftTexture2, nodeIdentifiers) + onOpening = e1 > elementsCountAround - 2 + element = mesh.findElementByIdentifier(elementIdentifier) + element.merge(elementtemplate2 if onOpening else elementtemplate1) + bni11 = e3*now + e2*elementsCountAround + e1 + 1 + bni12 = e3*now + e2*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + bni21 = e3*now + (e2 + 1)*elementsCountAround + e1 + 1 + bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + nodeIdentifiers = [ bni11, bni12, bni21, bni22, bni11 + now, bni12 + now, bni21 + now, bni22 + now ] + element.setNodesByIdentifier(eftTexture2 if onOpening else eftTexture1, nodeIdentifiers) elementIdentifier = elementIdentifier + 1 fm.endChange() From d2cc1e2bf2f2670fb99a90fbcf7c29d7dd988e88 Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 17:24:46 +1300 Subject: [PATCH 07/10] Change comment to 'Define texture coordinates field' --- scaffoldmaker/utils/tubemesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scaffoldmaker/utils/tubemesh.py b/scaffoldmaker/utils/tubemesh.py index 12b2b42d..18f47b48 100644 --- a/scaffoldmaker/utils/tubemesh.py +++ b/scaffoldmaker/utils/tubemesh.py @@ -243,7 +243,7 @@ def generatetubemesh(region, result = element.setNodesByIdentifier(eft, nodeIdentifiers) elementIdentifier = elementIdentifier + 1 - # Create texture coordinates + # Define texture coordinates field textureCoordinates = getOrCreateTextureCoordinateField(fm) textureNodetemplate1 = nodes.createNodetemplate() textureNodetemplate1.defineField(textureCoordinates) From 5d7e753d6e482a5257e75ac885cd5f91f31d009b Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 17:30:29 +1300 Subject: [PATCH 08/10] Document tube is opened on xi1 = 1 and potential for 6 variants --- scaffoldmaker/utils/eftfactory_bicubichermitelinear.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py b/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py index 0abed7fc..0d915bbb 100644 --- a/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py +++ b/scaffoldmaker/utils/eftfactory_bicubichermitelinear.py @@ -210,8 +210,9 @@ def createEftSplitXi1RightOut(self): def createEftOpenTube(self): ''' Create a basic bicubic hermite linear element template for elements - along boundary where a tube is opened for a flat preparation. Retain node - numbering with two versions for boundary nodes. + along boundary where a tube is opened on xi1 = 1 for a flat preparation. + Could eventually have 6 variants. Retain node numbering with two versions + for boundary nodes. :return: Element field template ''' eft = self.createEftBasic() From 5e7d3449930e2d3d33f0cb44d25244a31854d0c0 Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 17:43:07 +1300 Subject: [PATCH 09/10] Remove storage of d1 and d2 in lists --- scaffoldmaker/utils/tubemesh.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/scaffoldmaker/utils/tubemesh.py b/scaffoldmaker/utils/tubemesh.py index 18f47b48..b7cd71fe 100644 --- a/scaffoldmaker/utils/tubemesh.py +++ b/scaffoldmaker/utils/tubemesh.py @@ -275,19 +275,17 @@ def generatetubemesh(region, # Calculate texture coordinates and derivatives uTexture = [] - d1Texture = [] - d2Texture = [] + for n3 in range(elementsCountThroughWall + 1): for n2 in range(elementsCountAlong + 1): for n1 in range(elementsCountAround + 1): u = [ 1.0 / elementsCountAround * n1, 1.0 / elementsCountAlong * n2, 1.0 / elementsCountThroughWall * n3] - d1 = [1.0 / elementsCountAround, 0.0, 0.0] - d2 = [0.0, 1.0 / elementsCountAlong, 0.0] uTexture.append(u) - d1Texture.append(d1) - d2Texture.append(d2) + + d1 = [1.0 / elementsCountAround, 0.0, 0.0] + d2 = [0.0, 1.0 / elementsCountAlong, 0.0] nodeIdentifier = firstNodeIdentifier for n in range(len(uTexture)): @@ -296,12 +294,12 @@ def generatetubemesh(region, node.merge(textureNodetemplate2) cache.setNode(node) textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, uTexture[n]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1Texture[n]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2Texture[n]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2) endIdx = n + elementsCountAround textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 2, uTexture[endIdx]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 2, d1Texture[endIdx]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 2, d2Texture[endIdx]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 2, d1) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 2, d2) if useCrossDerivatives: textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 1, zero) textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 2, zero) @@ -311,8 +309,8 @@ def generatetubemesh(region, node.merge(textureNodetemplate1) cache.setNode(node) textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, uTexture[n]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1Texture[n]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2Texture[n]) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2) if useCrossDerivatives: textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 1, zero) nodeIdentifier = nodeIdentifier + 1 From f5a52d1e1b51d6ed202a235ad8a3c4125a8dc90b Mon Sep 17 00:00:00 2001 From: Mabelle Lin Date: Fri, 22 Mar 2019 18:20:38 +1300 Subject: [PATCH 10/10] Combine code in if and else clauses and insert space around operators --- scaffoldmaker/utils/tubemesh.py | 82 ++++++++++++++------------------- 1 file changed, 34 insertions(+), 48 deletions(-) diff --git a/scaffoldmaker/utils/tubemesh.py b/scaffoldmaker/utils/tubemesh.py index b7cd71fe..b7d8f404 100644 --- a/scaffoldmaker/utils/tubemesh.py +++ b/scaffoldmaker/utils/tubemesh.py @@ -71,7 +71,7 @@ def generatetubemesh(region, # Step through central line and rotate central line axes to align tangent # to tangent from previous frame - for n in range(1, elementsCountAlong+1): + for n in range(1, elementsCountAlong + 1): unitTangent = normalise(sd1[n]) cp = crossproduct3(prevUnitTangent, unitTangent) if magnitude(cp)> 0.0: @@ -138,7 +138,7 @@ def generatetubemesh(region, # Map each face along segment profile to central line for nSegment in range(segmentCountAlong): - for nAlongSegment in range(elementsCountAlongSegment+1): + for nAlongSegment in range(elementsCountAlongSegment + 1): n2 = nSegment*elementsCountAlongSegment + nAlongSegment if nSegment == 0 or (nSegment > 0 and nAlongSegment > 0): # Rotate to align segment axis with tangent of central line @@ -236,9 +236,9 @@ def generatetubemesh(region, for e1 in range(elementsCountAround): element = mesh.createElement(elementIdentifier, elementtemplate) bni11 = e3*now + e2*elementsCountAround + e1 + 1 - bni12 = e3*now + e2*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + bni12 = e3*now + e2*elementsCountAround + (e1 + 1) % elementsCountAround + 1 bni21 = e3*now + (e2 + 1)*elementsCountAround + e1 + 1 - bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1) % elementsCountAround + 1 nodeIdentifiers = [ bni11, bni12, bni21, bni22, bni11 + now, bni12 + now, bni21 + now, bni22 + now ] result = element.setNodesByIdentifier(eft, nodeIdentifiers) elementIdentifier = elementIdentifier + 1 @@ -274,46 +274,32 @@ def generatetubemesh(region, elementtemplate2.defineField(textureCoordinates, -1, eftTexture2) # Calculate texture coordinates and derivatives - uTexture = [] + d1 = [1.0 / elementsCountAround, 0.0, 0.0] + d2 = [0.0, 1.0 / elementsCountAlong, 0.0] + nodeIdentifier = firstNodeIdentifier for n3 in range(elementsCountThroughWall + 1): for n2 in range(elementsCountAlong + 1): - for n1 in range(elementsCountAround + 1): + for n1 in range(elementsCountAround): u = [ 1.0 / elementsCountAround * n1, 1.0 / elementsCountAlong * n2, 1.0 / elementsCountThroughWall * n3] - uTexture.append(u) - - d1 = [1.0 / elementsCountAround, 0.0, 0.0] - d2 = [0.0, 1.0 / elementsCountAlong, 0.0] - - nodeIdentifier = firstNodeIdentifier - for n in range(len(uTexture)): - if n%(elementsCountAround+1) == 0.0: - node = nodes.findNodeByIdentifier(nodeIdentifier) - node.merge(textureNodetemplate2) - cache.setNode(node) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, uTexture[n]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2) - endIdx = n + elementsCountAround - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 2, uTexture[endIdx]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 2, d1) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 2, d2) - if useCrossDerivatives: - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 1, zero) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 2, zero) - nodeIdentifier = nodeIdentifier + 1 - elif (n+1)%(elementsCountAround+1) > 0: - node = nodes.findNodeByIdentifier(nodeIdentifier) - node.merge(textureNodetemplate1) - cache.setNode(node) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, uTexture[n]) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1) - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2) - if useCrossDerivatives: - textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 1, zero) - nodeIdentifier = nodeIdentifier + 1 + node = nodes.findNodeByIdentifier(nodeIdentifier) + node.merge(textureNodetemplate2 if n1 == 0 else textureNodetemplate1) + cache.setNode(node) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 1, u) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 1, d1) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 1, d2) + if useCrossDerivatives: + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 1, zero) + if n1 == 0: + u = [ 1.0, 1.0 / elementsCountAlong * n2, 1.0 / elementsCountThroughWall * n3] + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_VALUE, 2, u) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS1, 2, d1) + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D_DS2, 2, d2) + if useCrossDerivatives: + textureCoordinates.setNodeParameters(cache, -1, Node.VALUE_LABEL_D2_DS1DS2, 2, zero) + nodeIdentifier = nodeIdentifier + 1 # define texture coordinates field over elements elementIdentifier = firstElementIdentifier @@ -326,9 +312,9 @@ def generatetubemesh(region, element = mesh.findElementByIdentifier(elementIdentifier) element.merge(elementtemplate2 if onOpening else elementtemplate1) bni11 = e3*now + e2*elementsCountAround + e1 + 1 - bni12 = e3*now + e2*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + bni12 = e3*now + e2*elementsCountAround + (e1 + 1) % elementsCountAround + 1 bni21 = e3*now + (e2 + 1)*elementsCountAround + e1 + 1 - bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1)%elementsCountAround + 1 + bni22 = e3*now + (e2 + 1)*elementsCountAround + (e1 + 1) % elementsCountAround + 1 nodeIdentifiers = [ bni11, bni12, bni21, bni22, bni11 + now, bni12 + now, bni21 + now, bni22 + now ] element.setNodesByIdentifier(eftTexture2 if onOpening else eftTexture1, nodeIdentifiers) elementIdentifier = elementIdentifier + 1 @@ -357,8 +343,8 @@ def getOuterCoordinatesAndCurvatureFromInner(xInner, d1Inner, d3Inner, wallThick for n1 in range(elementsCountAround): n = n2*elementsCountAround + n1 x = [xInner[n][i] + d3Inner[n][i]*wallThickness for i in range(3)] - prevIdx = n-1 if (n1 != 0) else (n2+1)*elementsCountAround - 1 - nextIdx = n+1 if (n1 < elementsCountAround-1) else n2*elementsCountAround + prevIdx = n - 1 if (n1 != 0) else (n2 + 1)*elementsCountAround - 1 + nextIdx = n + 1 if (n1 < elementsCountAround - 1) else n2*elementsCountAround norm = d3Inner[n] curvatureAround = 0.5*( getCubicHermiteCurvature(xInner[prevIdx], d1Inner[prevIdx], xInner[n], d1Inner[n], norm, 1.0) + @@ -390,7 +376,7 @@ def interpolatefromInnerAndOuter( xInner, xOuter, thickness, xi3, curvatureInner dx_ds2List = [] dx_ds3List =[] - for n2 in range(elementsCountAlong+1): + for n2 in range(elementsCountAlong + 1): for n1 in range(elementsCountAround): n = n2*elementsCountAround + n1 norm = d3InnerUnit[n] @@ -406,16 +392,16 @@ def interpolatefromInnerAndOuter( xInner, xOuter, thickness, xi3, curvatureInner dx_ds1List.append(dx_ds1) # dx_ds2 if n2 > 0 and n2 < elementsCountAlong: - prevIdx = (n2-1)*elementsCountAround + n1 - nextIdx = (n2+1)*elementsCountAround + n1 + prevIdx = (n2 - 1)*elementsCountAround + n1 + nextIdx = (n2 + 1)*elementsCountAround + n1 curvatureAround = 0.5*( - getCubicHermiteCurvature(xInner[prevIdx], d2Inner[prevIdx], xInner[n], d2Inner[n], norm, 1.0)+ + getCubicHermiteCurvature(xInner[prevIdx], d2Inner[prevIdx], xInner[n], d2Inner[n], norm, 1.0) + getCubicHermiteCurvature(xInner[n], d2Inner[n], xInner[nextIdx], d2Inner[nextIdx], norm, 0.0)) elif n2 == 0: - nextIdx = (n2+1)*elementsCountAround + n1 + nextIdx = (n2 + 1)*elementsCountAround + n1 curvatureAround = getCubicHermiteCurvature(xInner[n], d2Inner[n], xInner[nextIdx], d2Inner[nextIdx], norm, 0.0) else: - prevIdx = (n2-1)*elementsCountAround + n1 + prevIdx = (n2 - 1)*elementsCountAround + n1 curvatureAround = getCubicHermiteCurvature(xInner[prevIdx], d2Inner[prevIdx], xInner[n], d2Inner[n], norm, 1.0) factor = 1.0 - curvatureAround*thickness*xi3