for NodeNumber in right_boundary_nodes: NodeDomain = decomposition.NodeDomainGet(NodeNumber, 1) if NodeDomain == computationalNodeNumber: boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1, NodeNumber, 1, iron.BoundaryConditionsTypes.FIXED, 0.0) boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1, NodeNumber, 2, iron.BoundaryConditionsTypes.FIXED, 0.0) boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1, NodeNumber, 3, iron.BoundaryConditionsTypes.FIXED, 1.0) solverEquations.BoundaryConditionsCreateFinish() #The MUMPS solver may fail for large problems unable to allocate memory. #The solver can be instructed to allocate large heap space apriori #These settings are done here as the Solver is not assigned until problem Solver Equations are finalized #linearSolver.MumpsSetIcntl(23,640000) #linearSolver.MumpsSetIcntl(14,640000) # Solve the problem problem.Solve() # Export the results, here we export them as standard exnode, exelem files fields = iron.Fields() fields.CreateRegion(region) fields.NodesExport("AxialStretch", "FORTRAN") fields.ElementsExport("AxialStretch", "FORTRAN") fields.Finalise()
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()