def generateMesh(self, region):
        bases = self.setupBases(region)

        # Start the creation of a mesh in the region, setting
        # the number of mesh elements and number of mesh components
        # There are two mesh components, one quadratic and one linear
        mesh = iron.Mesh()
        mesh.CreateStart(1, region, 3)
        mesh.NumberOfComponentsSet(len(self.interpolations))
        mesh.NumberOfElementsSet(self.totalNumElements(self.interpolations[0]))

        # Create nodes in the region, setting the total number required
        # for the prolate spheroid geometry
        meshNodes = iron.Nodes()
        meshNodes.CreateStart(region, self.numNodes())
        meshNodes.CreateFinish()

        # Create mesh component elements for each of the
        # linear and quadratic mesh components
        for meshComponent, interpolation in enumerate(self.interpolations, 1):
            meshElements = iron.MeshElements()
            # Set the default basis that has no collapsed nodes
            basis = bases[(interpolation, False)]
            meshElements.CreateStart(mesh, meshComponent, basis)
            for elementNum, element in enumerate(self.elements(interpolation),
                                                 1):
                elementNodes, collapsed = element
                if collapsed:
                    basis = bases[(interpolation, collapsed)]
                    meshElements.BasisSet(elementNum, basis)
                meshElements.NodesSet(elementNum, elementNodes)
            meshElements.CreateFinish()

        mesh.CreateFinish()
        return mesh
if (UsePressureBasis):
    # Define pressure basis
    pressureBasis = iron.Basis()
    pressureBasis.CreateStart(pressureBasisUserNumber)
    pressureBasis.type = iron.BasisTypes.LAGRANGE_HERMITE_TP
    pressureBasis.numberOfXi = numberOfXi
    pressureBasis.interpolationXi = [
        iron.BasisInterpolationSpecifications.LINEAR_LAGRANGE
    ] * numberOfXi
    if (NumberOfGaussXi > 0):
        pressureBasis.quadratureNumberOfGaussXi = [NumberOfGaussXi
                                                   ] * numberOfXi
    pressureBasis.CreateFinish()

# Start the creation of input mesh in the region
mesh = iron.Mesh()
mesh.CreateStart(meshUserNumber, region, numberOfXi)
mesh.NumberOfComponentsSet(numberOfMeshComponents)
mesh.NumberOfElementsSet(exregion.num_elements)

# Define nodes for the mesh
nodes = iron.Nodes()
nodes.CreateStart(region, exregion.num_nodes)
nodes.CreateFinish()

#Specify the elementwise topology
quadraticelements = iron.MeshElements()
quadraticelements.CreateStart(mesh, QuadraticMeshComponentNumber, basis)
for elem in exregion.elements:
    quadraticelements.NodesSet(elem.number, elem.nodes)
quadraticelements.CreateFinish()
Ejemplo n.º 3
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()