diff --git a/src/scaffoldmaker/meshtypes/meshtype_3d_lung2.py b/src/scaffoldmaker/meshtypes/meshtype_3d_lung2.py index 8944424d..7d3f7bfb 100644 --- a/src/scaffoldmaker/meshtypes/meshtype_3d_lung2.py +++ b/src/scaffoldmaker/meshtypes/meshtype_3d_lung2.py @@ -480,11 +480,12 @@ def generateBaseMesh(cls, region, options): uElementsCount1 = 2 uElementsCount2 = 4 uElementsCount3 = 4 - # Fissure angle and element distribution - leftFissureAngle = math.atan(leftHeight/(leftDepth * 2.0)) * 180 / math.pi - leftObliqueProportion = 0.8 - rightFissureAngle = math.atan(rightHeight/(rightDepth * 2.0)) * 180 / math.pi - rightObliqueProportion = 0.8 + # Fissure locations + horizontalHeightProportion = 0.5 + leftObliqueLengthProportion = 0.8 + leftObliqueHeightProportion = 0.7 + rightObliqueLengthProportion = 0.8 + rightObliqueHeightProportion = 0.7 ############### # Create nodes @@ -496,8 +497,9 @@ def generateBaseMesh(cls, region, options): upperRightNodeIds = [] # Left lung nodes - nodeIdentifier = createLungNodes(spacingBetweenLeftRight, - leftDepth, leftWidth, leftHeight, leftFissureAngle, leftObliqueProportion, + nodeIdentifier = createLungNodes( + spacingBetweenLeftRight, leftDepth, leftWidth, leftHeight, + leftObliqueLengthProportion, leftObliqueHeightProportion, horizontalHeightProportion, leftLung, cache, coordinates, nodes, nodetemplate, mediastinumLeftNodesetGroup, leftMedialLungNodesetGroup, leftLungNodesetGroup, lungNodesetGroup, @@ -506,8 +508,9 @@ def generateBaseMesh(cls, region, options): lowerLeftNodeIds, upperLeftNodeIds, nodeIdentifier) # Right lung nodes - nodeIdentifier = createLungNodes(spacingBetweenLeftRight, - rightDepth, rightWidth, rightHeight, rightFissureAngle, rightObliqueProportion, + nodeIdentifier = createLungNodes( + spacingBetweenLeftRight, rightDepth, rightWidth, rightHeight, + rightObliqueLengthProportion, rightObliqueHeightProportion, horizontalHeightProportion, rightLung, cache, coordinates, nodes, nodetemplate, mediastinumRightNodesetGroup, rightMedialLungNodesetGroup, rightLungNodesetGroup, lungNodesetGroup, @@ -1037,20 +1040,22 @@ def defineFaceAnnotations(cls, region, options, annotationGroups): annotationGroups.remove(value) -def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureAngle, obliqueProportion, - lungSide, cache, coordinates, nodes, nodetemplate, - mediastinumNodesetGroup, medialLungNodesetGroup, - lungSideNodesetGroup, lungNodesetGroup, - lElementsCount1, lElementsCount2, lElementsCount3, - uElementsCount1, uElementsCount2, uElementsCount3, - lowerNodeIds, upperNodeIds, nodeIdentifier): +def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, + obliqueLengthProportion, obliqueHeightProportion, horizontalHeightProportion, + lungSide, cache, coordinates, nodes, nodetemplate, + mediastinumNodesetGroup, medialLungNodesetGroup, + lungSideNodesetGroup, lungNodesetGroup, + lElementsCount1, lElementsCount2, lElementsCount3, + uElementsCount1, uElementsCount2, uElementsCount3, + lowerNodeIds, upperNodeIds, nodeIdentifier): """ :param spaceFromCentre: :param lengthUnit: :param widthUnit: :param heightUnit: - :param fissureAngle: - :param obliqueProportion: + :param obliqueLengthProportion: Proportion of total base length from distal tip to start of oblique fissure. + :param obliqueHeightProportion: Proportion of height where oblique fissure intersects distal edge. + :param horizontalHeightProportion: Proportion of height where horizontal fissure intersects ventral edge. :param lungSide: :param cache: :param coordinates: @@ -1086,55 +1091,52 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA minorYAxis = [yAxis[i] * -lengthUnit for i in range(3)] minorZAxis = [zAxis[i] * heightUnit for i in range(3)] - fissureRadian = fissureAngle/180 * math.pi - tanFissureRadian = math.tan(fissureRadian) - - # Create 5 points at the centre of 2D Ellipse base - p1 = [yAxis[i] * -lengthUnit for i in range(3)] - p2 = [yAxis[i] * lengthUnit for i in range(3)] - p3 = [[p1[i] - (p1[i] - p2[i]) * obliqueProportion for i in range(3)]] # point of oblique fissure on diaphragm - - # Simplified simultaneous (linear and ellipsoid) equations - C = tanFissureRadian * p3[0][1] # (y-offset) - y = mx + c - - # Quadratic equation - ax^2 + bx + c = 0 - a = (heightUnit ** 2) + ((lengthUnit ** 2) * (tanFissureRadian ** 2)) - b = (lengthUnit ** 2) * 2 * tanFissureRadian * C - c = (lengthUnit ** 2) * (C ** 2) - ((lengthUnit ** 2) * (heightUnit ** 2)) - det = (b ** 2) - (4 * a * c) # determinant b^2 - 4ac - assert det > 0, "No real solution" - y = (-b + math.sqrt(det)) / (2 * a) - z = tanFissureRadian*y + C - p4 = [0.0, -y, z] # point at the oblique-ellispe intersection - - # points on 2D Ellipse base (two on the curve and one centre) - x = p3[0][1] - y = math.sqrt(1 - (x/lengthUnit) ** 2) * widthUnit - p3.append([y, p3[0][1], p3[0][2]]) - p3.insert(0, [-y, p3[0][1], p3[0][2]]) + # oblique fissure base point on x = 0 plane + obp = [0.0, (obliqueLengthProportion - 0.5) * 2.0 * lengthUnit, 0.0] + # oblique fissure distal point + obliqueTheta = math.acos(obliqueHeightProportion) + odp = [0.0, -lengthUnit * math.sin(obliqueTheta), obliqueHeightProportion * heightUnit] + # oblique fissure centre point + ocp = [0.5 * (obp[c] + odp[c]) for c in range(3)] + + # horizontal fissure ventral point + horizontalTheta = math.acos(horizontalHeightProportion) + hvp = [0.0, lengthUnit * math.sin(horizontalTheta), horizontalHeightProportion * heightUnit] # -------------------------------------------------- Lower lobe ------------------------------------------------ # lower lobe dorsal edge - dx = p4[1] vec1 = minorYAxis vec2 = [-minorZAxis[i] for i in range(3)] planeCentre = centre + dx = odp[1] totalRadiansAround = math.acos(-dx / magnitude(minorYAxis)) lower_edge, lower_edge_d3 = sampleEllipsePoints( planeCentre, vec1, vec2, 0.0, -totalRadiansAround, lElementsCount3) + # oblique fissure - in 2 parts as horizontal fissure starts half way up it + planeCentre, vec1, vec2 = getEllipsoidPlaneA(widthUnit, lengthUnit, heightUnit, obp, lower_edge[lElementsCount3]) + dx = dot(sub(obp, planeCentre), normalize(vec1)) + totalRadiansAround = math.acos(dx / magnitude(vec1)) + dx_mid = dot(sub(ocp, planeCentre), normalize(vec1)) + midRadiansAround = math.acos(dx_mid / magnitude(vec1)) + obl, obl_d2 = sampleEllipsePoints(planeCentre, vec1, vec2, 0.0, -midRadiansAround, lElementsCount2 - 2) + tx, td2 = sampleEllipsePoints(planeCentre, vec1, vec2, -midRadiansAround, -totalRadiansAround, 2) + obl += tx[1:] + obl_d2 += td2[1:] + # rows up dorsal edge - for n3 in range(lElementsCount3 + 1): + for n3 in range(lElementsCount3): if n3 == 0: - dx = p3[2][1] vec1 = minorYAxis vec2 = majorXAxis planeCentre = centre + dx = -obp[1] else: - planeCentre, vec1, vec2 = getEllipsoidPlaneA(widthUnit, lengthUnit, heightUnit, p3[1], lower_edge[n3]) - dx = magnitude(sub(p3[1], planeCentre)) - totalRadiansAround = math.acos(-dx / magnitude(vec1)) + pt = [0.0, lower_row1[-2][1], lower_row1[-2][2]] + planeCentre, vec1, vec2 = getEllipsoidPlaneA(widthUnit, lengthUnit, heightUnit, pt, lower_edge[n3]) + dx = dot(sub(pt, planeCentre), normalize(vec1)) + totalRadiansAround = math.acos(dx / magnitude(vec1)) px, pd2 = sampleEllipsePoints(planeCentre, vec1, vec2, 0.0, -totalRadiansAround, lElementsCount2) if n3 == 0: lower_row1, lower_row1_d2 = px, pd2 @@ -1148,18 +1150,26 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA # ---------------------------------------------------- Upper lobe -------------------------------------------- # upper lobe ventral-dorsal edge - # up from ventral tip of base to apex - dx = 0.0 + + # up from ventral tip of base to horizontal fissure point vec1 = [-minorYAxis[i] for i in range(3)] vec2 = minorZAxis planeCentre = centre - elementsCountAround = 5 + dx = hvp[1] + totalRadiansAround = math.acos(dx / lengthUnit) + elementsCountAround = 2 upper_edge, upper_edge_d2 = sampleEllipsePoints( - planeCentre, vec1, vec2, 0.0, math.pi / 2.0, elementsCountAround) + planeCentre, vec1, vec2, 0.0, totalRadiansAround, elementsCountAround) + # up from horizontal fissure point to apex + elementsCountAround = 3 + tx, td2 = sampleEllipsePoints( + planeCentre, vec1, vec2, totalRadiansAround, math.pi / 2.0, elementsCountAround) + upper_edge += tx[1:] + upper_edge_d2 += td2[1:] # down from apex to dorsal tip of oblique fissure - dx = obl[0][2] vec1 = minorZAxis vec2 = minorYAxis + dx = obl[0][2] planeCentre = centre elementsCountAround = 3 totalRadiansAround = math.acos(dx / magnitude(minorZAxis)) @@ -1176,12 +1186,12 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA planeCentre = centre vec1 = [-minorYAxis[i] for i in range(3)] vec2 = majorXAxis - dx = p3[1][1] + dx = obp[1] - planeCentre[1] else: obl_temp = [0.0, obl[-1 - n3][1], obl[-1 - n3][2]] planeCentre, vec1, vec2 = getEllipsoidPlaneA(widthUnit, lengthUnit, heightUnit, obl_temp, upper_edge[-1 - n3]) - dx = magnitude(sub(obl_temp, planeCentre)) + dx = dot(sub(obl_temp, planeCentre), normalize(vec1)) totalRadiansAround = math.acos(dx / magnitude(vec1)) px, pd2 = sampleEllipsePoints(planeCentre, vec1, vec2, -totalRadiansAround, 0.0, elementCount=2) if n3 == 0: @@ -1196,7 +1206,7 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA col_end = obl[n2 + 1] if n2 < 2 else upper_row3[1] midx = [0.0, col_end[1], col_end[2]] planeCentre, vec1, vec2 = getEllipsoidPlaneA(widthUnit, lengthUnit, heightUnit, midx, upper_edge[n2 + 2]) - dx = magnitude(sub(midx, planeCentre)) + dx = dot(sub(midx, planeCentre), normalize(vec1)) totalRadiansAround = math.acos(dx / magnitude(vec1)) px, pd3 = sampleEllipsePoints(planeCentre, vec1, vec2, -totalRadiansAround, 0.0, elementCount=2) if n2 == 0: @@ -1268,9 +1278,9 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA tx.append(x[n2]) td3 = [[0.0, 0.0, 0.0] for n3 in range(lElementsCount3 + 1)] fixEndDerivative = False - # if n2 == 1: - # td3[-1] = upper_col1_d3[0] - # fixEndDerivative = True + if n2 == 1: + td3[-1] = upper_col1_d3[0] + fixEndDerivative = True td3 = smoothCubicHermiteDerivativesLine(tx, td3, fixEndDerivative=fixEndDerivative) # make the derivatives tangential to the ellipsoid for n3 in range(lElementsCount3 + 1): @@ -1313,7 +1323,7 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA next_sxd2 = obl[n2 + 1] if n2 == 2: # 3-way point at intersection of lower, middle and upper lobes - sd2 = md3[n2][n3] + sd2 = upper_row3_d2[0] sd3 = [-d for d in md2[n3][n2]] else: continue @@ -1340,7 +1350,7 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA d1 = [-d for d in sd2] d2 = offset2 elif (n3 == 3) and (n2 == 2): # 3-way point - d3 = [0.0, -md2[n3][n2][1], -md2[n3][n2][2]] + pass else: d2 = offset2 else: # mirror in x @@ -1482,6 +1492,12 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA d1 = sd2 d2 = offset2 d3 = sd3 + elif n2 == 0: + # ventral edge + x = [0.0, sx[1], sx[2]] + d1 = [-d for d in sd2] + d2 = offset2 + d3 = [0.0, sd3[1], sd3[2]] elif n3 == 4: # apex row x = sx @@ -1492,7 +1508,6 @@ def createLungNodes(spaceFromCentre, lengthUnit, widthUnit, heightUnit, fissureA d3 = [0.0, sd3[1], sd3[2]] else: x = [0.0, sx[1], sx[2]] - d1 = [-d for d in sd2] d2 = offset2 d3 = [0.0, sd3[1], sd3[2]] else: # mirror in x @@ -1545,7 +1560,8 @@ def createLungElements(coordinates, eftfactory, eftRegular, elementtemplateRegul eftWedgeCollapseXi1_26 = eftfactory.createEftWedgeCollapseXi1Quadrant([2, 6]) eftWedgeCollapseXi1_57 = eftfactory.createEftWedgeCollapseXi1Quadrant([5, 7]) eftWedgeCollapseXi1_68 = eftfactory.createEftWedgeCollapseXi1Quadrant([6, 8]) - eftWedgeCollapseXi2_78 = eftfactory.createEftWedgeCollapseXi2Quadrant([7, 8]) + # eftWedgeCollapseXi2_78 = eftfactory.createEftWedgeCollapseXi2Quadrant([7, 8]) + eftWedgeCollapseXi3_78 = eftfactory.createEftWedgeCollapseXi3Quadrant([7, 8]) eftTetCollapseXi1Xi2_71 = eftfactory.createEftTetrahedronCollapseXi1Xi2Quadrant(7, 1) eftTetCollapseXi1Xi2_82 = eftfactory.createEftTetrahedronCollapseXi1Xi2Quadrant(8, 2) @@ -1580,7 +1596,8 @@ def createLungElements(coordinates, eftfactory, eftRegular, elementtemplateRegul # Middle wedge nodeIdentifiers.pop(7) nodeIdentifiers.pop(6) - eft = eftWedgeCollapseXi2_78 + # eft = eftWedgeCollapseXi2_78 + eft = eftWedgeCollapseXi3_78 elif (e3 == (lElementsCount3 - 1)) and (e2 == (lElementsCount2 - 3)): # Remapped cube element 1 eft = eftfactory.createEftBasic() diff --git a/src/scaffoldmaker/utils/eftfactory_tricubichermite.py b/src/scaffoldmaker/utils/eftfactory_tricubichermite.py index 1c4baeb7..fc304baa 100644 --- a/src/scaffoldmaker/utils/eftfactory_tricubichermite.py +++ b/src/scaffoldmaker/utils/eftfactory_tricubichermite.py @@ -887,8 +887,7 @@ def createEftWedgeCollapseXi1Quadrant(self, collapseNodes): else: valid = False - if not valid: - assert False, "createEftWedgeCollapseXi1Quadrant. Not implemented for collapse nodes " + str(collapseNodes) + assert valid, "createEftWedgeCollapseXi1Quadrant. Not implemented for collapse nodes " + str(collapseNodes) # zero cross derivative parameters remapEftNodeValueLabel(eft, nodes, Node.VALUE_LABEL_D2_DS1DS2, []) @@ -965,8 +964,7 @@ def createEftWedgeCollapseXi2Quadrant(self, collapseNodes): else: valid = False - if not valid: - assert False, "createEftWedgeCollapseXi2Quadrant. Not implemented for collapse nodes " + str(collapseNodes) + assert valid, "createEftWedgeCollapseXi2Quadrant. Not implemented for collapse nodes " + str(collapseNodes) # zero cross derivative parameters remapEftNodeValueLabel(eft, nodes, Node.VALUE_LABEL_D2_DS1DS2, []) @@ -978,6 +976,46 @@ def createEftWedgeCollapseXi2Quadrant(self, collapseNodes): print('eftfactory_tricubichermite.createEftWedgeCollapseXi2Quadrant: Failed to validate eft for collapseNodes', collapseNodes) return eft + def createEftWedgeCollapseXi3Quadrant(self, collapseNodes): + ''' + Create a tricubic hermite element field for a wedge element collapsed in xi3. + :param collapseNodes: As the element can be collapsed in xi3 at either ends of xi1 or xi2, collapseNodes + are the local indices of nodes whose d1 (for elements collapse at either ends of xi1) or + d2 (for elements collapse at either ends of xi2) are remapped with d3 before collapsing the nodes. + :return: Element field template + ''' + eft = self.createEftBasic() + + valid = True + if collapseNodes in [[3, 4], [7, 8]]: + nodes = [3, 4, 7, 8] + # remap parameters on xi2 = 1 before collapsing nodes + if collapseNodes == [3, 4]: + remapEftNodeValueLabel(eft, nodes, Node.VALUE_LABEL_D_DS3, []) + remapEftNodeValueLabel(eft, collapseNodes, Node.VALUE_LABEL_D_DS2, [(Node.VALUE_LABEL_D_DS3, [])]) + elif collapseNodes == [7, 8]: + setEftScaleFactorIds(eft, [1], []) + remapEftNodeValueLabel(eft, nodes, Node.VALUE_LABEL_D_DS3, []) + remapEftNodeValueLabel(eft, collapseNodes, Node.VALUE_LABEL_D_DS2, [(Node.VALUE_LABEL_D_DS3, [1])]) + else: + valid = False + ln_map = [1, 2, 3, 4, 5, 6, 3, 4] + else: + valid = False + + assert valid, "createEftWedgeCollapseXi3Quadrant. Not implemented for collapse nodes " + str(collapseNodes) + + # zero cross derivative parameters + remapEftNodeValueLabel(eft, nodes, Node.VALUE_LABEL_D2_DS1DS3, []) + remapEftNodeValueLabel(eft, nodes, Node.VALUE_LABEL_D2_DS2DS3, []) + remapEftNodeValueLabel(eft, nodes, Node.VALUE_LABEL_D3_DS1DS2DS3, []) + + remapEftLocalNodes(eft, 6, ln_map) + if not eft.validate(): + print('eftfactory_tricubichermite.createEftWedgeCollapseXi3Quadrant: ' + 'Failed to validate eft for collapseNodes', collapseNodes) + return eft + def createEftTetrahedronCollapseXi1Xi2Quadrant(self, peakNode, sideNode): ''' Create a tricubic hermite element field for a tetrahedron element, where xi1 and xi2 are collapsed on xi3 diff --git a/tests/test_lung.py b/tests/test_lung.py index a6b7de9b..7d3b6a75 100644 --- a/tests/test_lung.py +++ b/tests/test_lung.py @@ -1,4 +1,5 @@ import copy +import math import unittest from opencmiss.utils.zinc.finiteelement import evaluateFieldNodesetRange, findNodeWithName @@ -225,9 +226,11 @@ def test_lung2_human(self): # check coordinates range, outside surface area and volume coordinates = fieldmodule.findFieldByName("coordinates").castFiniteElement() self.assertTrue(coordinates.isValid()) + material_coordinates = fieldmodule.findFieldByName("lung coordinates").castFiniteElement() + self.assertTrue(material_coordinates.isValid()) minimums, maximums = evaluateFieldNodesetRange(coordinates, nodes) - assertAlmostEqualList(self, minimums, [-0.5604163214943202, -0.466842088914134, -0.2084853920913896], 1.0E-6) - assertAlmostEqualList(self, maximums, [0.5604163214943202, 0.34567264189961144, 0.9604476810137638], 1.0E-6) + assertAlmostEqualList(self, minimums, [-0.5604046150578359, -0.46588462707467704, -0.20848015499159522], 1.0E-6) + assertAlmostEqualList(self, maximums, [0.5604046150578359, 0.3440517958126045, 0.9604261163849366], 1.0E-6) with ChangeManager(fieldmodule): one = fieldmodule.createFieldConstant(1.0) upperRightFissureGroup = fieldmodule.findFieldByName('upper lobe of right lung').castGroup() @@ -238,13 +241,23 @@ def test_lung2_human(self): surfaceAreaField.setNumbersOfPoints(4) volumeField = fieldmodule.createFieldMeshIntegral(one, coordinates, mesh3d) volumeField.setNumbersOfPoints(3) + left_lung_group = getAnnotationGroupForTerm(annotationGroups, get_lung_term("left lung")) + left_lung_mesh_group = left_lung_group.getMeshGroup(mesh3d) + materialVolumeField = fieldmodule.createFieldMeshIntegral(one, material_coordinates, left_lung_mesh_group) + materialVolumeField.setNumbersOfPoints(3) fieldcache = fieldmodule.createFieldcache() result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1) self.assertEqual(result, RESULT_OK) - self.assertAlmostEqual(surfaceArea, 1.8798921303528096, delta=1.0E-2) + self.assertAlmostEqual(surfaceArea, 1.838244693520495, delta=1.0E-6) result, volume = volumeField.evaluateReal(fieldcache, 1) self.assertEqual(result, RESULT_OK) - self.assertAlmostEqual(volume, 0.3939966467507881, delta=1.0E-2) + self.assertAlmostEqual(volume, 0.3859394886952645, delta=1.0E-6) + result, material_volume = materialVolumeField.evaluateReal(fieldcache, 1) + self.assertEqual(result, RESULT_OK) + halfEllipsoidVolume = 0.5 * (4.0 / 3.0) * math.pi * 0.25 * 0.5 * 1.0 # 3 axis lengths + self.assertAlmostEqual(halfEllipsoidVolume, 0.2617993877991494, delta=1.0E-12) + # not quite the same as the above due to sharpening on the ventral edge + self.assertAlmostEqual(material_volume, 0.2597062752904966, delta=1.0E-6) # check some annotationGroups: expectedSizes3d = { @@ -434,8 +447,8 @@ def test_lung2_mouse(self): coordinates = fieldmodule.findFieldByName("coordinates").castFiniteElement() self.assertTrue(coordinates.isValid()) minimums, maximums = evaluateFieldNodesetRange(coordinates, nodes) - assertAlmostEqualList(self, minimums, [-0.5965044150610541, -0.9033753549633335, -0.6098596053921448], 1.0E-6) - assertAlmostEqualList(self, maximums, [0.6642334206803495, 0.013022322792385225, 0.6698850677137351], 1.0E-6) + assertAlmostEqualList(self, minimums, [-0.5965062723149795, -0.9035466860119679, -0.6098596059713717], 1.0E-6) + assertAlmostEqualList(self, maximums, [0.6642156880908214, 0.009214327892980281, 0.669464028759718], 1.0E-6) with ChangeManager(fieldmodule): one = fieldmodule.createFieldConstant(1.0) upperRightFissureGroup = fieldmodule.findFieldByName('upper lobe of right lung').castGroup() @@ -449,10 +462,10 @@ def test_lung2_mouse(self): fieldcache = fieldmodule.createFieldcache() result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1) self.assertEqual(result, RESULT_OK) - self.assertAlmostEqual(surfaceArea, 2.1246873977602028, delta=1.0E-2) + self.assertAlmostEqual(surfaceArea, 2.077889388115966, delta=1.0E-2) result, volume = volumeField.evaluateReal(fieldcache, 1) self.assertEqual(result, RESULT_OK) - self.assertAlmostEqual(volume, 0.38833210870887075, delta=1.0E-2) + self.assertAlmostEqual(volume, 0.3799935491917908, delta=1.0E-2) # check some annotationGroups: expectedSizes3d = { @@ -623,8 +636,8 @@ def test_lung2_human_openFissures(self): coordinates = fieldmodule.findFieldByName("coordinates").castFiniteElement() self.assertTrue(coordinates.isValid()) minimums, maximums = evaluateFieldNodesetRange(coordinates, nodes) - assertAlmostEqualList(self, minimums, [-0.5604163214943202, -0.466842088914134, -0.2084853920913896], 1.0E-6) - assertAlmostEqualList(self, maximums, [0.5604163214943202, 0.34567264189961144, 0.9604476810137638], 1.0E-6) + assertAlmostEqualList(self, minimums, [-0.5604046150578359, -0.46588462707467704, -0.20848015499159522], 1.0E-6) + assertAlmostEqualList(self, maximums, [0.5604046150578359, 0.3440517958126045, 0.9604261163849366], 1.0E-6) with ChangeManager(fieldmodule): one = fieldmodule.createFieldConstant(1.0) upperRightFissureGroup = fieldmodule.findFieldByName('upper lobe of right lung').castGroup() @@ -638,10 +651,10 @@ def test_lung2_human_openFissures(self): fieldcache = fieldmodule.createFieldcache() result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1) self.assertEqual(result, RESULT_OK) - self.assertAlmostEqual(surfaceArea, 1.8798921303528096, delta=1.0E-2) + self.assertAlmostEqual(surfaceArea, 1.8382446935204972, delta=1.0E-6) result, volume = volumeField.evaluateReal(fieldcache, 1) self.assertEqual(result, RESULT_OK) - self.assertAlmostEqual(volume, 0.3939966467507881, delta=1.0E-2) + self.assertAlmostEqual(volume, 0.3859394886952645, delta=1.0E-6) # check some annotationGroups: expectedSizes3d = { @@ -756,8 +769,8 @@ def test_lung2_mouse_openFissures(self): coordinates = fieldmodule.findFieldByName("coordinates").castFiniteElement() self.assertTrue(coordinates.isValid()) minimums, maximums = evaluateFieldNodesetRange(coordinates, nodes) - assertAlmostEqualList(self, minimums, [-0.5965044150610541, -0.9033753549633335, -0.6098596053921448], 1.0E-6) - assertAlmostEqualList(self, maximums, [0.6642334206803495, 0.013022322792385225, 0.6698850677137351], 1.0E-6) + assertAlmostEqualList(self, minimums, [-0.5965062723149795, -0.9035466860119679, -0.6098596059713717], 1.0E-6) + assertAlmostEqualList(self, maximums, [0.6642156880908214, 0.009214327892980281, 0.669464028759718], 1.0E-6) with ChangeManager(fieldmodule): one = fieldmodule.createFieldConstant(1.0) upperRightFissureGroup = fieldmodule.findFieldByName('upper lobe of right lung').castGroup() @@ -771,10 +784,10 @@ def test_lung2_mouse_openFissures(self): fieldcache = fieldmodule.createFieldcache() result, surfaceArea = surfaceAreaField.evaluateReal(fieldcache, 1) self.assertEqual(result, RESULT_OK) - self.assertAlmostEqual(surfaceArea, 2.1246873977602028, delta=1.0E-2) + self.assertAlmostEqual(surfaceArea, 2.077889388115967, delta=1.0E-2) result, volume = volumeField.evaluateReal(fieldcache, 1) self.assertEqual(result, RESULT_OK) - self.assertAlmostEqual(volume, 0.38833210870887075, delta=1.0E-2) + self.assertAlmostEqual(volume, 0.3799935491917908, delta=1.0E-2) # check some annotationGroups: expectedSizes3d = {