def setGeometry(self, geometricField):
     decomposition = iron.Decomposition()
     geometricField.MeshDecompositionGet(decomposition)
     geometricInterpolation = self.interpolations[0]
     compNodeNumber = iron.ComputationalNodeNumberGet()
     geometricMeshComponent = 1
     # Set the geometric field parameters from the prolate spheroid geometry
     for nodeNum, values in enumerate(self.nodeValues(), 1):
         if decomposition.NodeDomainGet(
                 nodeNum, geometricMeshComponent) == compNodeNumber:
             versionNumber = 1
             for component in range(3):
                 componentValues = values[component]
                 if geometricInterpolation != 'cubic_hermite':
                     componentValues = componentValues[:1]
                 for derivativeNumber, value in componentValues:
                     # Note: Python uses 0-based indexing, OpenCMISS uses 1-based
                     geometricField.ParameterSetUpdateNode(
                         iron.FieldVariableTypes.U,
                         iron.FieldParameterSetTypes.VALUES, versionNumber,
                         derivativeNumber, nodeNum, component + 1, value)
     # After modifying the geometric field, ParameterSetUpdateStart/Finish
     # must be called so that the field data at ghost nodes is synchronised
     # across all processes. The UpdateFinish routine could be called later
     # on just before the geometric values are actually needed, to avoid
     # blocking.
     geometricField.ParameterSetUpdateStart(
         iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES)
     geometricField.ParameterSetUpdateFinish(
         iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES)
    def setFibres(self, fibreField):
        endocardiumFibreAngle = self.endocardiumFibreAngle
        epicardiumFibreAngle = self.epicardiumFibreAngle
        sheetAngle = self.sheetAngle
        geometricMeshComponent = 1
        compNodeNumber = iron.ComputationalNodeNumberGet()

        hasQuadratic = self.interpolations[0] == 'quadratic'
        if hasQuadratic:
            elFactor = 2
        else:
            elFactor = 1

        # fibre, imbrication, sheet
        epiAngles = np.array([epicardiumFibreAngle, 0.0, sheetAngle])
        endoAngles = np.array([endocardiumFibreAngle, 0.0, sheetAngle])
        lmbdaDerivs = (epiAngles - endoAngles) / self.numElements[2]

        decomposition = iron.Decomposition()
        fibreField.MeshDecompositionGet(decomposition)

        # Set fibre angles at nodes
        def setAngles(pos, angles):
            nodeNumber = self.nodeAtPosition(pos)
            if decomposition.NodeDomainGet(
                    nodeNumber, geometricMeshComponent) == compNodeNumber:
                version = 1
                for component, angle in enumerate(angles, 1):
                    derivative = 1
                    fibreField.ParameterSetUpdateNode(
                        iron.FieldVariableTypes.U,
                        iron.FieldParameterSetTypes.VALUES, version,
                        derivative, nodeNumber, component, angle)

        # Only loop over linear component nodes
        for k in range(0, self.numElements[2] * elFactor + 1, elFactor):
            transmuralPos = float(k) / float(self.numElements[2] * elFactor)
            fibreAngle = endocardiumFibreAngle + transmuralPos * (
                epicardiumFibreAngle - endocardiumFibreAngle)
            for j in range(0, self.numElements[1] * elFactor + 1, elFactor):
                for i in range(0, self.numElements[0] * elFactor, elFactor):
                    if j == 0:
                        setAngles((i, j, k), [0.0, 0.0, 0.0])
                    else:
                        setAngles((i, j, k), [fibreAngle, 0.0, sheetAngle])

        fibreField.ParameterSetUpdateStart(iron.FieldVariableTypes.U,
                                           iron.FieldParameterSetTypes.VALUES)
        fibreField.ParameterSetUpdateFinish(iron.FieldVariableTypes.U,
                                            iron.FieldParameterSetTypes.VALUES)
    quadraticelements.NodesSet(elem.number, elem.nodes)
quadraticelements.CreateFinish()

if (UsePressureBasis):
    #Specify the elementwise topology that suits the mesh element basis
    linearelements = iron.MeshElements()
    linearelements.CreateStart(mesh, LinearMeshComponentNumber, pressureBasis)
    for elem in exregion.elements:
        linearNodes = list(elem.nodes[i - 1]
                           for i in [1, 3, 7, 9, 19, 21, 25, 27])
        linearelements.NodesSet(elem.number, linearNodes)
    linearelements.CreateFinish()
mesh.CreateFinish()

# Create a decomposition for the mesh
decomposition = iron.Decomposition()
decomposition.CreateStart(decompositionUserNumber, mesh)
decomposition.type = iron.DecompositionTypes.CALCULATED
decomposition.numberOfDomains = numberOfComputationalNodes
decomposition.CreateFinish()

# Create a field for the geometry
geometricField = iron.Field()
geometricField.CreateStart(geometricFieldUserNumber, region)
geometricField.MeshDecompositionSet(decomposition)
geometricField.TypeSet(iron.FieldTypes.GEOMETRIC)
geometricField.VariableLabelSet(iron.FieldVariableTypes.U, "coordinates")
geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 1, 1)
geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 2, 1)
geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 3, 1)
geometricField.CreateFinish()
예제 #4
0
def LidDriven(numberOfElements, cavityDimensions, lidVelocity, viscosity,
              density, outputFilename, transient, RBS, fdJacobian, analytic,
              basisList):
    """ Sets up the lid driven cavity problem and solves with the provided parameter values

          Square Lid-Driven Cavity

                  v=1
               >>>>>>>>>>
             1|          |
              |          |
         v=0  |          |  v=0
              |          |
              |          |
              ------------
             0    v=0    1
    """

    # Create a generated mesh
    generatedMesh = iron.GeneratedMesh()
    generatedMesh.CreateStart(generatedMeshUserNumber, region)
    generatedMesh.type = iron.GeneratedMeshTypes.REGULAR
    generatedMesh.basis = basisList
    generatedMesh.extent = cavityDimensions
    generatedMesh.numberOfElements = numberOfElements

    mesh = iron.Mesh()
    generatedMesh.CreateFinish(meshUserNumber, mesh)

    # Create a decomposition for the mesh
    decomposition = iron.Decomposition()
    decomposition.CreateStart(decompositionUserNumber, mesh)
    decomposition.type = iron.DecompositionTypes.CALCULATED
    decomposition.numberOfDomains = numberOfComputationalNodes
    decomposition.CreateFinish()

    # Create a field for the geometry
    geometricField = iron.Field()
    geometricField.CreateStart(geometricFieldUserNumber, region)
    geometricField.meshDecomposition = decomposition
    geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 1, 1)
    geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 2, 1)
    geometricField.CreateFinish()

    # Set geometry from the generated mesh
    generatedMesh.GeometricParametersCalculate(geometricField)

    # Create standard Navier-Stokes equations set
    equationsSetField = iron.Field()
    equationsSet = iron.EquationsSet()
    if RBS:
        equationsSetSpecification = [
            iron.EquationsSetClasses.FLUID_MECHANICS,
            iron.EquationsSetTypes.NAVIER_STOKES_EQUATION,
            iron.EquationsSetSubtypes.TRANSIENT_RBS_NAVIER_STOKES
        ]
    else:
        equationsSetSpecification = [
            iron.EquationsSetClasses.FLUID_MECHANICS,
            iron.EquationsSetTypes.NAVIER_STOKES_EQUATION,
            iron.EquationsSetSubtypes.TRANSIENT_NAVIER_STOKES
        ]
    equationsSet.CreateStart(equationsSetUserNumber, region, geometricField,
                             equationsSetSpecification,
                             equationsSetFieldUserNumber, equationsSetField)
    equationsSet.CreateFinish()

    if RBS:
        # Set max CFL number (default 1.0)
        equationsSetField.ComponentValuesInitialiseDP(
            iron.FieldVariableTypes.U1, iron.FieldParameterSetTypes.VALUES, 2,
            1.0E20)
        # Set time increment (default 0.0)
        equationsSetField.ComponentValuesInitialiseDP(
            iron.FieldVariableTypes.U1, iron.FieldParameterSetTypes.VALUES, 3,
            transient[2])
        # Set stabilisation type (default 1.0 = RBS)
        equationsSetField.ComponentValuesInitialiseDP(
            iron.FieldVariableTypes.U1, iron.FieldParameterSetTypes.VALUES, 4,
            1.0)

    # Create dependent field
    dependentField = iron.Field()
    equationsSet.DependentCreateStart(dependentFieldUserNumber, dependentField)
    dependentField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 1, 1)
    dependentField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 2, 1)
    dependentField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 3, 2)
    dependentField.ComponentMeshComponentSet(iron.FieldVariableTypes.DELUDELN,
                                             1, 1)
    dependentField.ComponentMeshComponentSet(iron.FieldVariableTypes.DELUDELN,
                                             2, 1)
    dependentField.ComponentMeshComponentSet(iron.FieldVariableTypes.DELUDELN,
                                             3, 2)
    dependentField.DOFOrderTypeSet(iron.FieldVariableTypes.U,
                                   iron.FieldDOFOrderTypes.SEPARATED)
    dependentField.DOFOrderTypeSet(iron.FieldVariableTypes.DELUDELN,
                                   iron.FieldDOFOrderTypes.SEPARATED)
    equationsSet.DependentCreateFinish()
    # Initialise dependent field
    dependentField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 1, 0.0)

    # Create materials field
    materialsField = iron.Field()
    equationsSet.MaterialsCreateStart(materialsFieldUserNumber, materialsField)
    equationsSet.MaterialsCreateFinish()
    # Initialise materials field parameters
    materialsField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 1,
        viscosity)
    materialsField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 2,
        density)

    # If specified, use a sinusoidal waveform to ramp up lid velocity from 0 to 1
    if analytic:
        # yOffset + amplitude*sin(frequency*time + phaseShift))))
        # Set the time it takes to ramp velocity up to full lid velocity
        rampPeriod = 10.0
        frequency = math.pi / (rampPeriod)
        amplitude = 0.5 * lidVelocity[0]
        yOffset = 0.5 * lidVelocity[0]
        phaseShift = -math.pi / 2.0
        startSine = 0.0
        stopSine = rampPeriod
        analyticField = iron.Field()
        equationsSet.AnalyticCreateStart(
            iron.NavierStokesAnalyticFunctionTypes.SINUSOID,
            analyticFieldUserNumber, analyticField)
        equationsSet.AnalyticCreateFinish()
        analyticParameters = [
            1.0, 0.0, 0.0, 0.0, amplitude, yOffset, frequency, phaseShift,
            startSine, stopSine
        ]

    # Create equations
    equations = iron.Equations()
    equationsSet.EquationsCreateStart(equations)
    equations.sparsityType = iron.EquationsSparsityTypes.SPARSE
    equations.outputType = iron.EquationsOutputTypes.NONE
    equationsSet.EquationsCreateFinish()

    # Create Navier-Stokes problem
    problem = iron.Problem()
    if RBS:
        problemSpecification = [
            iron.ProblemClasses.FLUID_MECHANICS,
            iron.ProblemTypes.NAVIER_STOKES_EQUATION,
            iron.ProblemSubtypes.TRANSIENT_RBS_NAVIER_STOKES
        ]
    else:
        problemSpecification = [
            iron.ProblemClasses.FLUID_MECHANICS,
            iron.ProblemTypes.NAVIER_STOKES_EQUATION,
            iron.ProblemSubtypes.TRANSIENT_NAVIER_STOKES
        ]
    problem.CreateStart(problemUserNumber, problemSpecification)
    problem.CreateFinish()

    # Create control loops
    problem.ControlLoopCreateStart()
    controlLoop = iron.ControlLoop()
    problem.ControlLoopGet([iron.ControlLoopIdentifiers.NODE], controlLoop)
    controlLoop.TimesSet(transient[0], transient[1], transient[2])
    controlLoop.TimeOutputSet(transient[3])
    problem.ControlLoopCreateFinish()

    # Create problem solver
    dynamicSolver = iron.Solver()
    problem.SolversCreateStart()
    problem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1, dynamicSolver)
    dynamicSolver.outputType = iron.SolverOutputTypes.NONE
    dynamicSolver.dynamicTheta = [0.5]
    nonlinearSolver = iron.Solver()
    dynamicSolver.DynamicNonlinearSolverGet(nonlinearSolver)
    if fdJacobian:
        nonlinearSolver.newtonJacobianCalculationType = iron.JacobianCalculationTypes.FD
    else:
        nonlinearSolver.newtonJacobianCalculationType = iron.JacobianCalculationTypes.EQUATIONS
    nonlinearSolver.outputType = iron.SolverOutputTypes.NONE
    nonlinearSolver.newtonAbsoluteTolerance = 1.0E-8
    nonlinearSolver.newtonRelativeTolerance = 1.0E-9
    nonlinearSolver.newtonSolutionTolerance = 1.0E-9
    nonlinearSolver.newtonMaximumFunctionEvaluations = 10000
    nonlinearSolver.newtonLineSearchType = iron.NewtonLineSearchTypes.QUADRATIC
    linearSolver = iron.Solver()
    nonlinearSolver.NewtonLinearSolverGet(linearSolver)
    linearSolver.outputType = iron.SolverOutputTypes.NONE
    linearSolver.linearType = iron.LinearSolverTypes.DIRECT
    linearSolver.libraryType = iron.SolverLibraries.MUMPS
    problem.SolversCreateFinish()

    # Create solver equations and add equations set to solver equations
    solver = iron.Solver()
    solverEquations = iron.SolverEquations()
    problem.SolverEquationsCreateStart()
    problem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1, solver)
    solver.SolverEquationsGet(solverEquations)
    solverEquations.sparsityType = iron.SolverEquationsSparsityTypes.SPARSE
    equationsSetIndex = solverEquations.EquationsSetAdd(equationsSet)
    problem.SolverEquationsCreateFinish()

    # Create boundary conditions
    boundaryConditions = iron.BoundaryConditions()
    solverEquations.BoundaryConditionsCreateStart(boundaryConditions)
    nodes = iron.Nodes()
    region.NodesGet(nodes)
    print("Total # of nodes: " + str(nodes.numberOfNodes))
    print("Analytic Parameters: " + str(analyticParameters))
    boundaryTolerance = 1.0e-6

    # Currently issues with getting generated mesh surfaces through python so easier to just loop over all nodes
    for node in range(nodes.numberOfNodes):
        nodeId = node + 1
        nodeNumber = nodes.UserNumberGet(nodeId)
        # print('node number: '+ str(nodeNumber))
        # Velocity nodes
        nodeDomain = decomposition.NodeDomainGet(nodeNumber, 1)
        if (nodeDomain == computationalNodeNumber):
            xLocation = geometricField.ParameterSetGetNodeDP(
                iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES,
                1, 1, nodeNumber, 1)
            yLocation = geometricField.ParameterSetGetNodeDP(
                iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES,
                1, 1, nodeNumber, 2)
            # rigid wall (left,right,bottom) conditions: v=0
            if (xLocation < boundaryTolerance
                    or cavityDimensions[0] - xLocation < boundaryTolerance
                    or yLocation < boundaryTolerance):
                boundaryConditions.SetNode(dependentField,
                                           iron.FieldVariableTypes.U, 1, 1,
                                           nodeNumber, 1,
                                           iron.BoundaryConditionsTypes.FIXED,
                                           0.0)
                boundaryConditions.SetNode(dependentField,
                                           iron.FieldVariableTypes.U, 1, 1,
                                           nodeNumber, 2,
                                           iron.BoundaryConditionsTypes.FIXED,
                                           0.0)
            # lid (top) conditions: v=v
            elif (cavityDimensions[1] - yLocation < boundaryTolerance):
                if not (xLocation < boundaryTolerance or
                        cavityDimensions[0] - xLocation < boundaryTolerance):
                    if analytic:
                        boundaryConditions.SetNode(
                            dependentField, iron.FieldVariableTypes.U, 1, 1,
                            nodeNumber, 1,
                            iron.BoundaryConditionsTypes.FIXED_INLET, 0.0)
                        boundaryConditions.SetNode(
                            dependentField, iron.FieldVariableTypes.U, 1, 1,
                            nodeNumber, 2,
                            iron.BoundaryConditionsTypes.FIXED_INLET, 0.0)
                        # Set analytic parameters
                        parameterNumber = 0
                        for parameter in analyticParameters:
                            parameterNumber += 1
                            analyticField.ParameterSetUpdateNodeDP(
                                iron.FieldVariableTypes.U,
                                iron.FieldParameterSetTypes.VALUES, 1, 1,
                                nodeNumber, parameterNumber, parameter)

                    else:
                        boundaryConditions.SetNode(
                            dependentField, iron.FieldVariableTypes.U, 1, 1,
                            nodeNumber, 1, iron.BoundaryConditionsTypes.FIXED,
                            lidVelocity[0])
                        boundaryConditions.SetNode(
                            dependentField, iron.FieldVariableTypes.U, 1, 1,
                            nodeNumber, 2, iron.BoundaryConditionsTypes.FIXED,
                            lidVelocity[1])

    # Pressure node
    nodeNumber = 1
    nodeDomain = decomposition.NodeDomainGet(nodeNumber, 2)
    if (nodeDomain == computationalNodeNumber):
        # bottom left node - reference pressure: p=0
        boundaryConditions.SetNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, nodeNumber, 3,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        print('pressure node: ' + str(nodeNumber))

    solverEquations.BoundaryConditionsCreateFinish()

    # Solve the problem
    print("solving...")
    problem.Solve()

    print("exporting CMGUI data")
    # Export results
    fields = iron.Fields()
    fields.CreateRegion(region)
    fields.NodesExport(outputFilename, "FORTRAN")
    fields.ElementsExport(outputFilename, "FORTRAN")
    fields.Finalise()

    # Clear fields so can run in batch mode on this region
    generatedMesh.Destroy()
    nodes.Destroy()
    mesh.Destroy()
    geometricField.Destroy()
    if RBS:
        equationsSetField.Destroy()
    if analytic:
        analyticField.Destroy()
    dependentField.Destroy()
    materialsField.Destroy()
    equationsSet.Destroy()
    problem.Destroy()