def setup_problem(self):
        """
        Setup the fitting problem.
        """
        # Create fitting problem
        self.problem.CreateStart(self.problem_user_num,
                                 self.problem_specification)
        self.problem.CreateFinish()

        self.problem.ControlLoopCreateStart()
        self.problem.ControlLoopCreateFinish()

        self.solver = iron.Solver()
        self.problem.SolversCreateStart()
        self.problem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1,
                               self.solver)
        # self.solver.OutputTypeSet(iron.SolverOutputTypes.NONE)
        self.solver.OutputTypeSet(iron.SolverOutputTypes.PROGRESS)
        # self.solver.LinearTypeSet(iron.LinearSolverTypes.DIRECT)
        # self.solver.LibraryTypeSet(iron.SolverLibraries.UMFPACK) # UMFPACK/SUPERLU
        self.solver.LinearTypeSet(iron.LinearSolverTypes.ITERATIVE)
        self.solver.LinearIterativeMaximumIterationsSet(5000)
        self.solver.LinearIterativeAbsoluteToleranceSet(1.0E-10)
        self.solver.LinearIterativeRelativeToleranceSet(1.0E-05)
        self.problem.SolversCreateFinish()

        self.solver = iron.Solver()
        self.solver_equations = iron.SolverEquations()
        self.problem.SolverEquationsCreateStart()
        self.problem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1,
                               self.solver)
        self.solver.SolverEquationsGet(self.solver_equations)
        self.solver_equations.SparsityTypeSet(
            iron.SolverEquationsSparsityTypes.SPARSE)
        _ = self.solver_equations.EquationsSetAdd(self.equations_set)
        self.problem.SolverEquationsCreateFinish()

        self.boundary_conditions = iron.BoundaryConditions()
        self.solver_equations.BoundaryConditionsCreateStart(
            self.boundary_conditions)
        # Mapping constraints
        if self.dependent_field_mappings:
            version = 1
            for mapped_node_idx in range(
                    self.num_mapped_dependent_field_nodes):
                for component in range(1, self.num_data_components + 1):
                    self.boundary_conditions.ConstrainNodeDofsEqual(
                        self.dependent_field, iron.FieldVariableTypes.U,
                        version,
                        iron.GlobalDerivativeConstants.NO_GLOBAL_DERIV,
                        component, self.mapped_dependent_field_node_nums[
                            mapped_node_idx, :], 1.0)
        self.solver_equations.BoundaryConditionsCreateFinish()
Beispiel #2
0
    def defineProblemSolver():
        # Define the problem
        problem = iron.Problem()
        problemSpecification = [
            iron.ProblemClasses.ELASTICITY,
            iron.ProblemTypes.FINITE_ELASTICITY,
            iron.ProblemSubtypes.FINITE_ELASTICITY_CELLML
        ]
        problem.CreateStart(problemUserNumber, problemSpecification)
        problem.CreateFinish()

        # Create control loops
        problem.ControlLoopCreateStart()
        problem.ControlLoopCreateFinish()

        # Create problem solver
        nonLinearSolver = iron.Solver()
        linearSolver = iron.Solver()
        problem.SolversCreateStart()
        problem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1,
                          nonLinearSolver)
        nonLinearSolver.outputType = iron.SolverOutputTypes.PROGRESS
        nonLinearSolver.NewtonJacobianCalculationTypeSet(
            iron.JacobianCalculationTypes.FD)
        nonLinearSolver.NewtonLinearSolverGet(linearSolver)
        linearSolver.linearType = iron.LinearSolverTypes.DIRECT
        #linearSolver.libraryType = iron.SolverLibraries.LAPACK
        problem.SolversCreateFinish()

        #Create the problem solver CellML equations
        CellMLSolver = iron.Solver()
        problem.CellMLEquationsCreateStart()
        nonLinearSolver.NewtonCellMLSolverGet(CellMLSolver)
        CellMLEquations = iron.CellMLEquations()
        CellMLSolver.CellMLEquationsGet(CellMLEquations)
        CellMLEquations.CellMLAdd(CellML)
        problem.CellMLEquationsCreateFinish()

        # 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()

        return [problem, solverEquations]
Beispiel #3
0
# Create problem solver
dynamicSolver = iron.Solver()
problem.SolversCreateStart()
problem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1, dynamicSolver)
dynamicSolver.outputType = iron.SolverOutputTypes.NONE
linearSolver = iron.Solver()
dynamicSolver.DynamicLinearSolverGet(linearSolver)
linearSolver.outputType = iron.SolverOutputTypes.NONE
linearSolver.linearType = iron.LinearSolverTypes.DIRECT
# linearSolver.LinearIterativeMaximumIterationsSet(1000)
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)

# Set maximum concentration (1) for nodes at the inlet
for inlet_node in inlet_node_array:
    boundaryConditions.SetNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               int(inlet_node), 1,
Beispiel #4
0
def reset_problem(simulation):
    """
    Resets the FE model's solvers so there is no data from the previous solve used in the next one.

    :param simulation: The simulation which needs its solver reset.
    """

    problemUserNumber = 12
    numberOfLoadIncrements = 1
    NumberOfGaussXi = 4

    simulation.problem.Destroy()

    simulation.problem = iron.Problem()
    simulation.problemSpecification = [iron.ProblemClasses.ELASTICITY,
            iron.ProblemTypes.FINITE_ELASTICITY,
            iron.ProblemSubtypes.NONE]
    simulation.problem.CreateStart(problemUserNumber, simulation.problemSpecification)
    simulation.problem.CreateFinish()

    # Create the problem control loop
    simulation.problem.ControlLoopCreateStart()
    simulation.controlLoop = iron.ControlLoop()
    simulation.problem.ControlLoopGet([iron.ControlLoopIdentifiers.NODE],simulation.controlLoop)
    simulation.controlLoop.MaximumIterationsSet(numberOfLoadIncrements)
    simulation.problem.ControlLoopCreateFinish()

    simulation.nonLinearSolver = iron.Solver()
    simulation.linearSolver = iron.Solver()
    simulation.problem.SolversCreateStart()
    simulation.problem.SolverGet([iron.ControlLoopIdentifiers.NODE],1,simulation.nonLinearSolver)

    if simulation.diagnostics == 4 or simulation.diagnostics == 'Matrix':
        simulation.nonLinearSolver.outputType = iron.SolverOutputTypes.MATRIX
    elif simulation.diagnostics == 3 or simulation.diagnostics == 'Solver':
        simulation.nonLinearSolver.outputType = iron.SolverOutputTypes.SOLVER
    elif simulation.diagnostics == 2 or simulation.diagnostics == 'Timing':
        simulation.nonLinearSolver.outputType = iron.SolverOutputTypes.TIMING
    elif simulation.diagnostics == 1 or simulation.diagnostics == 'Progress':
        simulation.nonLinearSolver.outputType = iron.SolverOutputTypes.PROGRESS
    else:
        simulation.nonLinearSolver.outputType = iron.SolverOutputTypes.NONE

    simulation.nonLinearSolver.NewtonJacobianCalculationTypeSet(iron.JacobianCalculationTypes.FD)
    simulation.nonLinearSolver.NewtonAbsoluteToleranceSet(1e-9)
    simulation.nonLinearSolver.NewtonSolutionToleranceSet(1e-9)
    simulation.nonLinearSolver.NewtonRelativeToleranceSet(1e-9)
    simulation.nonLinearSolver.NewtonMaximumIterationsSet(int(1e6))
    simulation.nonLinearSolver.NewtonMaximumFunctionEvaluationsSet(int(1e6))
    simulation.nonLinearSolver.NewtonLinearSolverGet(simulation.linearSolver)
    simulation.linearSolver.linearType = iron.LinearSolverTypes.DIRECT
    #linearSolver.libraryType = iron.SolverLibraries.LAPACK
    simulation.problem.SolversCreateFinish()

    simulation.solver = iron.Solver()
    simulation.solverEquations = iron.SolverEquations()
    simulation.problem.SolverEquationsCreateStart()
    simulation.problem.SolverGet([iron.ControlLoopIdentifiers.NODE],1,simulation.solver)
    simulation.solver.SolverEquationsGet(simulation.solverEquations)
    simulation.solverEquations.sparsityType = iron.SolverEquationsSparsityTypes.SPARSE
    equationsSetIndex = simulation.solverEquations.EquationsSetAdd(simulation.equationsSet)
    simulation.problem.SolverEquationsCreateFinish()

    simulation.boundaryConditions = iron.BoundaryConditions()
    simulation.solverEquations.BoundaryConditionsCreateStart(simulation.boundaryConditions)

    numberOfNodes = (NumberOfGaussXi + (NumberOfGaussXi-1)*(simulation.cantilever_elements[0]-1))\
                    * (NumberOfGaussXi + (NumberOfGaussXi-1)*(simulation.cantilever_elements[1]-1))\
                     * (NumberOfGaussXi + (NumberOfGaussXi-1)*(simulation.cantilever_elements[2]-1))

    for nodeNum in range(1, numberOfNodes+1, (NumberOfGaussXi + (NumberOfGaussXi-1)*(simulation.cantilever_elements[0]-1))):
        simulation.boundaryConditions.AddNode(simulation.dependentField, iron.FieldVariableTypes.U, 1, 1, nodeNum, 1, iron.BoundaryConditionsTypes.FIXED, 0.0)
        simulation.boundaryConditions.AddNode(simulation.dependentField, iron.FieldVariableTypes.U, 1, 1, nodeNum, 2, iron.BoundaryConditionsTypes.FIXED, 0.0)
        simulation.boundaryConditions.AddNode(simulation.dependentField, iron.FieldVariableTypes.U, 1, 1, nodeNum, 3, iron.BoundaryConditionsTypes.FIXED, 0.0)

    simulation.solverEquations.BoundaryConditionsCreateFinish()
def solve_model(exportname, model=1, debug=False):
    # Setting debug=False will prevent output of solver progress/results to the screen.
    if debug:
        print("Solving model {0}".format(model))

    # Get the number of computational nodes and this computational node number
    numberOfComputationalNodes = iron.ComputationalNumberOfNodesGet()
    # computationalNodeNumber = iron.ComputationalNodeNumberGet()

    # Create a 3D rectangular cartesian coordinate system
    coordinateSystem = iron.CoordinateSystem()
    coordinateSystem.CreateStart(coordinateSystemUserNumber)
    coordinateSystem.DimensionSet(3)
    coordinateSystem.CreateFinish()

    # Create a region and assign the coordinate system to the region
    region = iron.Region()
    region.CreateStart(regionUserNumber, iron.WorldRegion)
    region.LabelSet("Region")
    region.coordinateSystem = coordinateSystem
    region.CreateFinish()

    # Define basis
    basis = iron.Basis()
    basis.CreateStart(basisUserNumber)
    if InterpolationType in (1, 2, 3, 4):
        basis.type = iron.BasisTypes.LAGRANGE_HERMITE_TP
    elif InterpolationType in (7, 8, 9):
        basis.type = iron.BasisTypes.SIMPLEX
    basis.numberOfXi = numberOfXi
    basis.interpolationXi = (
        [iron.BasisInterpolationSpecifications.LINEAR_LAGRANGE] * numberOfXi)
    if (NumberOfGaussXi > 0):
        basis.quadratureNumberOfGaussXi = [NumberOfGaussXi] * numberOfXi
    basis.CreateFinish()

    if (UsePressureBasis):
        # Define pressure basis
        pressureBasis = iron.Basis()
        pressureBasis.CreateStart(pressureBasisUserNumber)
        if InterpolationType in (1, 2, 3, 4):
            pressureBasis.type = iron.BasisTypes.LAGRANGE_HERMITE_TP
        elif InterpolationType in (7, 8, 9):
            pressureBasis.type = iron.BasisTypes.SIMPLEX
        pressureBasis.numberOfXi = numberOfXi
        pressureBasis.interpolationXi = (
            [iron.BasisInterpolationSpecifications.LINEAR_LAGRANGE] *
            numberOfXi)
        if (NumberOfGaussXi > 0):
            pressureBasis.quadratureNumberOfGaussXi = [NumberOfGaussXi
                                                       ] * numberOfXi
        pressureBasis.CreateFinish()

    # Start the creation of a generated mesh in the region
    generatedMesh = iron.GeneratedMesh()
    generatedMesh.CreateStart(generatedMeshUserNumber, region)
    generatedMesh.type = iron.GeneratedMeshTypes.REGULAR
    if (UsePressureBasis):
        generatedMesh.basis = [basis, pressureBasis]
    else:
        generatedMesh.basis = [basis]
        generatedMesh.extent = [width, length, height]
        generatedMesh.numberOfElements = ([
            numberGlobalXElements, numberGlobalYElements, numberGlobalZElements
        ])
    # Finish the creation of a generated mesh in the region
    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.MeshDecompositionSet(decomposition)
    geometricField.TypeSet(iron.FieldTypes.GEOMETRIC)
    geometricField.VariableLabelSet(iron.FieldVariableTypes.U, "Geometry")
    geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 1, 1)
    geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 2, 1)
    geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 3, 1)
    if InterpolationType == 4:
        geometricField.fieldScalingType = iron.FieldScalingTypes.ARITHMETIC_MEAN
    geometricField.CreateFinish()

    # Update the geometric field parameters from generated mesh
    generatedMesh.GeometricParametersCalculate(geometricField)

    # Create a fibre field and attach it to the geometric field
    fibreField = iron.Field()
    fibreField.CreateStart(fibreFieldUserNumber, region)
    fibreField.TypeSet(iron.FieldTypes.FIBRE)
    fibreField.MeshDecompositionSet(decomposition)
    fibreField.GeometricFieldSet(geometricField)
    fibreField.VariableLabelSet(iron.FieldVariableTypes.U, "Fibre")
    if InterpolationType == 4:
        fibreField.fieldScalingType = iron.FieldScalingTypes.ARITHMETIC_MEAN
    fibreField.CreateFinish()

    # Create a deformed geometry field, as Cmgui/Zinc doesn't like displaying
    # deformed fibres from the dependent field because it isn't a geometric field.
    deformedField = iron.Field()
    deformedField.CreateStart(deformedFieldUserNumber, region)
    deformedField.MeshDecompositionSet(decomposition)
    deformedField.TypeSet(iron.FieldTypes.GEOMETRIC)
    deformedField.VariableLabelSet(iron.FieldVariableTypes.U,
                                   "DeformedGeometry")
    for component in [1, 2, 3]:
        deformedField.ComponentMeshComponentSet(iron.FieldVariableTypes.U,
                                                component, 1)
    if InterpolationType == 4:
        deformedField.ScalingTypeSet(iron.FieldScalingTypes.ARITHMETIC_MEAN)
    deformedField.CreateFinish()

    pressureField = iron.Field()
    pressureField.CreateStart(pressureFieldUserNumber, region)
    pressureField.MeshDecompositionSet(decomposition)
    pressureField.VariableLabelSet(iron.FieldVariableTypes.U, "Pressure")
    pressureField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 1, 1)
    pressureField.ComponentInterpolationSet(
        iron.FieldVariableTypes.U, 1,
        iron.FieldInterpolationTypes.ELEMENT_BASED)
    pressureField.NumberOfComponentsSet(iron.FieldVariableTypes.U, 1)
    pressureField.CreateFinish()

    # Create the equations_set
    equationsSetField = iron.Field()
    equationsSet = iron.EquationsSet()

    problemSpecification = [
        iron.ProblemClasses.ELASTICITY, iron.ProblemTypes.FINITE_ELASTICITY,
        iron.EquationsSetSubtypes.MOONEY_RIVLIN
    ]
    equationsSet.CreateStart(equationsSetUserNumber, region, fibreField,
                             problemSpecification, equationsSetFieldUserNumber,
                             equationsSetField)
    equationsSet.CreateFinish()

    # Create the dependent field
    dependentField = iron.Field()
    equationsSet.DependentCreateStart(dependentFieldUserNumber, dependentField)
    dependentField.VariableLabelSet(iron.FieldVariableTypes.U, "Dependent")
    dependentField.ComponentInterpolationSet(
        iron.FieldVariableTypes.U, 4,
        iron.FieldInterpolationTypes.ELEMENT_BASED)
    dependentField.ComponentInterpolationSet(
        iron.FieldVariableTypes.DELUDELN, 4,
        iron.FieldInterpolationTypes.ELEMENT_BASED)
    if (UsePressureBasis):
        # Set the pressure to be nodally based and use the second mesh component
        if InterpolationType == 4:
            dependentField.ComponentInterpolationSet(
                iron.FieldVariableTypes.U, 4,
                iron.FieldInterpolationTypes.NODE_BASED)
            dependentField.ComponentInterpolationSet(
                iron.FieldVariableTypes.DELUDELN, 4,
                iron.FieldInterpolationTypes.NODE_BASED)
        dependentField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 4,
                                                 2)
        dependentField.ComponentMeshComponentSet(
            iron.FieldVariableTypes.DELUDELN, 4, 2)
    if InterpolationType == 4:
        dependentField.fieldScalingType = iron.FieldScalingTypes.ARITHMETIC_MEAN
    equationsSet.DependentCreateFinish()

    # Create the material field
    materialField = iron.Field()
    equationsSet.MaterialsCreateStart(materialFieldUserNumber, materialField)
    materialField.VariableLabelSet(iron.FieldVariableTypes.U, "Material")
    equationsSet.MaterialsCreateFinish()

    # Set Mooney-Rivlin constants c10 and c01 respectively.
    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 1, 1.0)
    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 2, 0.2)

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

    # Initialise dependent field from undeformed geometry and displacement bcs and set hydrostatic pressure
    iron.Field.ParametersToFieldParametersComponentCopy(
        geometricField, iron.FieldVariableTypes.U,
        iron.FieldParameterSetTypes.VALUES, 1, dependentField,
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 1)
    iron.Field.ParametersToFieldParametersComponentCopy(
        geometricField, iron.FieldVariableTypes.U,
        iron.FieldParameterSetTypes.VALUES, 2, dependentField,
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 2)
    iron.Field.ParametersToFieldParametersComponentCopy(
        geometricField, iron.FieldVariableTypes.U,
        iron.FieldParameterSetTypes.VALUES, 3, dependentField,
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 3)
    iron.Field.ComponentValuesInitialiseDP(dependentField,
                                           iron.FieldVariableTypes.U,
                                           iron.FieldParameterSetTypes.VALUES,
                                           4, 0.0)

    # Define the problem
    problem = iron.Problem()
    problemSpecification = [
        iron.ProblemClasses.ELASTICITY, iron.ProblemTypes.FINITE_ELASTICITY,
        iron.ProblemSubtypes.NONE
    ]
    problem.CreateStart(problemUserNumber, problemSpecification)
    problem.CreateFinish()

    # Create the problem control loop
    problem.ControlLoopCreateStart()
    controlLoop = iron.ControlLoop()
    problem.ControlLoopGet([iron.ControlLoopIdentifiers.NODE], controlLoop)
    controlLoop.MaximumIterationsSet(numberOfLoadIncrements)
    problem.ControlLoopCreateFinish()

    # Create problem solver
    nonLinearSolver = iron.Solver()
    linearSolver = iron.Solver()
    problem.SolversCreateStart()
    problem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1, nonLinearSolver)
    if debug:
        nonLinearSolver.outputType = iron.SolverOutputTypes.PROGRESS
    else:
        nonLinearSolver.outputType = iron.SolverOutputTypes.NONE
    nonLinearSolver.NewtonJacobianCalculationTypeSet(
        iron.JacobianCalculationTypes.EQUATIONS)
    nonLinearSolver.NewtonLinearSolverGet(linearSolver)
    linearSolver.linearType = iron.LinearSolverTypes.DIRECT
    #linearSolver.libraryType = iron.SolverLibraries.LAPACK
    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
    _ = solverEquations.EquationsSetAdd(equationsSet)
    problem.SolverEquationsCreateFinish()

    # Prescribe boundary conditions (absolute nodal parameters)
    boundaryConditions = iron.BoundaryConditions()
    solverEquations.BoundaryConditionsCreateStart(boundaryConditions)
    if model == 1:
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 7, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        p = -2. * -0.1056E+01

    elif model == 2:
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 7, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 7, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        p = -2. * -0.6656E+00

    elif model == 3:
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 7, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 7, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        p = -2. * -0.1450E+01

    elif model == 4:
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)

        p = -2. * -0.1056E+01

    elif model == 5:
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 7, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.5)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.25)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.75)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, X,
                                   iron.BoundaryConditionsTypes.FIXED, 0.75)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, Y,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 7, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, Z,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        p = -2. * -0.1000E+01

    solverEquations.BoundaryConditionsCreateFinish()

    # Solve the problem
    problem.Solve()

    # Copy deformed geometry into deformed field
    for component in [1, 2, 3]:
        dependentField.ParametersToFieldParametersComponentCopy(
            iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES,
            component, deformedField, iron.FieldVariableTypes.U,
            iron.FieldParameterSetTypes.VALUES, component)

    # Copy pressure into pressure field
    dependentField.ParametersToFieldParametersComponentCopy(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 4,
        pressureField, iron.FieldVariableTypes.U,
        iron.FieldParameterSetTypes.VALUES, 1)

    # Export results
    fields = iron.Fields()
    fields.CreateRegion(region)
    fields.NodesExport(exportname, "FORTRAN")
    fields.ElementsExport(exportname, "FORTRAN")
    fields.Finalise()

    results = {}
    elementNumber = 1
    xiPosition = [0.5, 0.5, 0.5]
    F = equationsSet.TensorInterpolateXi(
        iron.EquationsSetTensorEvaluateTypes.DEFORMATION_GRADIENT,
        elementNumber, xiPosition, (3, 3))
    results['Deformation Gradient Tensor'] = F
    if debug:
        print("Deformation Gradient Tensor")
        print(F)

    C = equationsSet.TensorInterpolateXi(
        iron.EquationsSetTensorEvaluateTypes.R_CAUCHY_GREEN_DEFORMATION,
        elementNumber, xiPosition, (3, 3))
    results['Right Cauchy-Green Deformation Tensor'] = C
    if debug:
        print("Right Cauchy-Green Deformation Tensor")
        print(C)

    E = equationsSet.TensorInterpolateXi(
        iron.EquationsSetTensorEvaluateTypes.GREEN_LAGRANGE_STRAIN,
        elementNumber, xiPosition, (3, 3))
    results['Green-Lagrange Strain Tensor'] = E
    if debug:
        print("Green-Lagrange Strain Tensor")
        print(E)

    I1 = numpy.trace(C)
    I2 = 0.5 * (numpy.trace(C)**2. - numpy.tensordot(C, C))
    I3 = numpy.linalg.det(C)
    results['Invariants'] = [I1, I2, I3]
    if debug:
        print("Invariants")
        print("I1={0}, I2={1}, I3={2}".format(I1, I2, I3))

    TC = equationsSet.TensorInterpolateXi(
        iron.EquationsSetTensorEvaluateTypes.CAUCHY_STRESS, elementNumber,
        xiPosition, (3, 3))
    results['Cauchy Stress Tensor'] = TC
    if debug:
        print("Cauchy Stress Tensor")
        print(TC)

    # Output of Second Piola-Kirchhoff Stress Tensor not implemented. It is
    # instead, calculated from TG=J*F^(-1)*TC*F^(-T), where T indicates the
    # transpose fo the matrix.
    #TG = equationsSet.TensorInterpolateXi(
    #    iron.EquationsSetTensorEvaluateTypes.SECOND_PK_STRESS,
    #    elementNumber, xiPosition,(3,3))
    #J=1. #Assumes J=1
    TG = numpy.dot(numpy.linalg.inv(F),
                   numpy.dot(TC, numpy.linalg.inv(numpy.matrix.transpose(F))))
    results['Second Piola-Kirchhoff Stress Tensor'] = TG
    if debug:
        print("Second Piola-Kirchhoff Stress Tensor")
        print(TG)

    # Note that the hydrostatic pressure value is different from the value quoted
    # in the original lab instructions. This is because the stress has been
    # evaluated using modified invariants (isochoric invariants)
    #p = dependentField.ParameterSetGetElement(
    #    iron.FieldVariableTypes.U,
    #    iron.FieldParameterSetTypes.VALUES,elementNumber,4)
    results['Hydrostatic pressure'] = p
    if debug:
        print("Hydrostatic pressure")
        print(p)

    problem.Destroy()
    coordinateSystem.Destroy()
    region.Destroy()
    basis.Destroy()

    return results
def solve_model(exportname, model=1, debug=False):
    # Setting debug=False will prevent output of solver progress/results to the screen.
    if debug:
        print("Solving model {0}".format(model))

    # Get the number of computational nodes and this computational node number
    numberOfComputationalNodes = iron.ComputationalNumberOfNodesGet()
    # computationalNodeNumber = iron.ComputationalNodeNumberGet()

    # Create a 3D rectangular cartesian coordinate system
    coordinateSystem = iron.CoordinateSystem()
    coordinateSystem.CreateStart(coordinateSystemUserNumber)
    coordinateSystem.DimensionSet(3)
    coordinateSystem.CreateFinish()

    # Create a region and assign the coordinate system to the region
    region = iron.Region()
    region.CreateStart(regionUserNumber, iron.WorldRegion)
    region.LabelSet("Region")
    region.coordinateSystem = coordinateSystem
    region.CreateFinish()

    # Define basis
    basis = iron.Basis()
    basis.CreateStart(basisUserNumber)
    if InterpolationType in (1, 2, 3, 4):
        basis.type = iron.BasisTypes.LAGRANGE_HERMITE_TP
    elif InterpolationType in (7, 8, 9):
        basis.type = iron.BasisTypes.SIMPLEX
    basis.numberOfXi = numberOfXi
    basis.interpolationXi = (
        [iron.BasisInterpolationSpecifications.LINEAR_LAGRANGE] * numberOfXi)
    if (NumberOfGaussXi > 0):
        basis.quadratureNumberOfGaussXi = [NumberOfGaussXi] * numberOfXi
    basis.CreateFinish()

    if (UsePressureBasis):
        # Define pressure basis
        pressureBasis = iron.Basis()
        pressureBasis.CreateStart(pressureBasisUserNumber)
        if InterpolationType in (1, 2, 3, 4):
            pressureBasis.type = iron.BasisTypes.LAGRANGE_HERMITE_TP
        elif InterpolationType in (7, 8, 9):
            pressureBasis.type = iron.BasisTypes.SIMPLEX
        pressureBasis.numberOfXi = numberOfXi
        pressureBasis.interpolationXi = (
            [iron.BasisInterpolationSpecifications.LINEAR_LAGRANGE] *
            numberOfXi)
        if (NumberOfGaussXi > 0):
            pressureBasis.quadratureNumberOfGaussXi = [NumberOfGaussXi
                                                       ] * numberOfXi
        pressureBasis.CreateFinish()

    # Start the creation of a generated mesh in the region
    generatedMesh = iron.GeneratedMesh()
    generatedMesh.CreateStart(generatedMeshUserNumber, region)
    generatedMesh.type = iron.GeneratedMeshTypes.REGULAR
    if (UsePressureBasis):
        generatedMesh.basis = [basis, pressureBasis]
    else:
        generatedMesh.basis = [basis]
        generatedMesh.extent = [width, length, height]
        generatedMesh.numberOfElements = ([
            numberGlobalXElements, numberGlobalYElements, numberGlobalZElements
        ])
    # Finish the creation of a generated mesh in the region
    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.MeshDecompositionSet(decomposition)
    geometricField.TypeSet(iron.FieldTypes.GEOMETRIC)
    geometricField.VariableLabelSet(iron.FieldVariableTypes.U, "Geometry")
    geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 1, 1)
    geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 2, 1)
    geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 3, 1)
    if InterpolationType == 4:
        geometricField.fieldScalingType = iron.FieldScalingTypes.ARITHMETIC_MEAN
    geometricField.CreateFinish()

    # Update the geometric field parameters from generated mesh
    generatedMesh.GeometricParametersCalculate(geometricField)

    # Create a fibre field and attach it to the geometric field
    fibreField = iron.Field()
    fibreField.CreateStart(fibreFieldUserNumber, region)
    fibreField.TypeSet(iron.FieldTypes.FIBRE)
    fibreField.MeshDecompositionSet(decomposition)
    fibreField.GeometricFieldSet(geometricField)
    fibreField.VariableLabelSet(iron.FieldVariableTypes.U, "Fibre")
    if InterpolationType == 4:
        fibreField.fieldScalingType = iron.FieldScalingTypes.ARITHMETIC_MEAN
    fibreField.CreateFinish()

    # Create a deformed geometry field, as Cmgui/Zinc doesn't like displaying
    # deformed fibres from the dependent field because it isn't a geometric field.
    deformedField = iron.Field()
    deformedField.CreateStart(deformedFieldUserNumber, region)
    deformedField.MeshDecompositionSet(decomposition)
    deformedField.TypeSet(iron.FieldTypes.GEOMETRIC)
    deformedField.VariableLabelSet(iron.FieldVariableTypes.U,
                                   "DeformedGeometry")
    for component in [1, 2, 3]:
        deformedField.ComponentMeshComponentSet(iron.FieldVariableTypes.U,
                                                component, 1)
    if InterpolationType == 4:
        deformedField.ScalingTypeSet(iron.FieldScalingTypes.ARITHMETIC_MEAN)
    deformedField.CreateFinish()

    pressureField = iron.Field()
    pressureField.CreateStart(pressureFieldUserNumber, region)
    pressureField.MeshDecompositionSet(decomposition)
    pressureField.VariableLabelSet(iron.FieldVariableTypes.U, "Pressure")
    pressureField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 1, 1)
    pressureField.ComponentInterpolationSet(
        iron.FieldVariableTypes.U, 1,
        iron.FieldInterpolationTypes.ELEMENT_BASED)
    pressureField.NumberOfComponentsSet(iron.FieldVariableTypes.U, 1)
    pressureField.CreateFinish()

    # Create the equations_set
    equationsSetField = iron.Field()
    equationsSet = iron.EquationsSet()

    problemSpecification = [
        iron.ProblemClasses.ELASTICITY, iron.ProblemTypes.FINITE_ELASTICITY,
        iron.EquationsSetSubtypes.ORTHOTROPIC_MATERIAL_COSTA
    ]
    equationsSet.CreateStart(equationsSetUserNumber, region, fibreField,
                             problemSpecification, equationsSetFieldUserNumber,
                             equationsSetField)
    equationsSet.CreateFinish()

    # Create the dependent field
    dependentField = iron.Field()
    equationsSet.DependentCreateStart(dependentFieldUserNumber, dependentField)
    dependentField.VariableLabelSet(iron.FieldVariableTypes.U, "Dependent")
    dependentField.ComponentInterpolationSet(
        iron.FieldVariableTypes.U, 4,
        iron.FieldInterpolationTypes.ELEMENT_BASED)
    dependentField.ComponentInterpolationSet(
        iron.FieldVariableTypes.DELUDELN, 4,
        iron.FieldInterpolationTypes.ELEMENT_BASED)
    if (UsePressureBasis):
        # Set the pressure to be nodally based and use the second mesh component
        if InterpolationType == 4:
            dependentField.ComponentInterpolationSet(
                iron.FieldVariableTypes.U, 4,
                iron.FieldInterpolationTypes.NODE_BASED)
            dependentField.ComponentInterpolationSet(
                iron.FieldVariableTypes.DELUDELN, 4,
                iron.FieldInterpolationTypes.NODE_BASED)
        dependentField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 4,
                                                 2)
        dependentField.ComponentMeshComponentSet(
            iron.FieldVariableTypes.DELUDELN, 4, 2)
    if InterpolationType == 4:
        dependentField.fieldScalingType = iron.FieldScalingTypes.ARITHMETIC_MEAN
    equationsSet.DependentCreateFinish()

    # Create the material field
    materialField = iron.Field()
    equationsSet.MaterialsCreateStart(materialFieldUserNumber, materialField)
    materialField.VariableLabelSet(iron.FieldVariableTypes.U, "Material")
    equationsSet.MaterialsCreateFinish()

    # Set Costa constitutive relation parameters.
    # Q=[c_ff 2c_fs 2c_fn c_ss 2c_ns c_nn]' * [E_ff E_fs  E_fn  E_ss E_sn  E_nn].^2;
    if model in [1, 3, 4]:
        c_1 = 0.0475
        c_ff = 15.25
        c_fs = 6.05
        c_fn = c_fs
        c_ss = c_ff
        c_sn = c_fs
        c_nn = c_ff
    elif model in [2, 5, 6]:
        c_1 = 0.0475
        c_ff = 15.25
        c_fs = 6.95
        c_fn = 6.05
        c_ss = 6.8
        c_sn = 4.93
        c_nn = 8.9

    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 1, c_1)
    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 2, c_ff)
    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 3, c_fs)
    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 4, c_fn)
    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 5, c_ss)
    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 6, c_sn)
    materialField.ComponentValuesInitialiseDP(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 7, c_nn)

    if model in [1, 2]:
        angle = numpy.deg2rad(0.)
    elif model == 3:
        angle = numpy.deg2rad(30.)
    elif model in [4, 5]:
        angle = numpy.deg2rad(45.)
    elif model == 6:
        angle = numpy.deg2rad(90.)

    fibreField.ComponentValuesInitialiseDP(iron.FieldVariableTypes.U,
                                           iron.FieldParameterSetTypes.VALUES,
                                           1, angle)

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

    # Initialise dependent field from undeformed geometry and displacement bcs and set hydrostatic pressure
    iron.Field.ParametersToFieldParametersComponentCopy(
        geometricField, iron.FieldVariableTypes.U,
        iron.FieldParameterSetTypes.VALUES, 1, dependentField,
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 1)
    iron.Field.ParametersToFieldParametersComponentCopy(
        geometricField, iron.FieldVariableTypes.U,
        iron.FieldParameterSetTypes.VALUES, 2, dependentField,
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 2)
    iron.Field.ParametersToFieldParametersComponentCopy(
        geometricField, iron.FieldVariableTypes.U,
        iron.FieldParameterSetTypes.VALUES, 3, dependentField,
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 3)
    iron.Field.ComponentValuesInitialiseDP(dependentField,
                                           iron.FieldVariableTypes.U,
                                           iron.FieldParameterSetTypes.VALUES,
                                           4, 0.0)

    # Define the problem
    problem = iron.Problem()
    problemSpecification = [
        iron.ProblemClasses.ELASTICITY, iron.ProblemTypes.FINITE_ELASTICITY,
        iron.ProblemSubtypes.NONE
    ]
    problem.CreateStart(problemUserNumber, problemSpecification)
    problem.CreateFinish()

    # Create the problem control loop
    problem.ControlLoopCreateStart()
    controlLoop = iron.ControlLoop()
    problem.ControlLoopGet([iron.ControlLoopIdentifiers.NODE], controlLoop)
    controlLoop.MaximumIterationsSet(numberOfLoadIncrements)
    problem.ControlLoopCreateFinish()

    # Create problem solver
    nonLinearSolver = iron.Solver()
    linearSolver = iron.Solver()
    problem.SolversCreateStart()
    problem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1, nonLinearSolver)
    if debug:
        nonLinearSolver.outputType = iron.SolverOutputTypes.PROGRESS
    else:
        nonLinearSolver.outputType = iron.SolverOutputTypes.NONE
    nonLinearSolver.NewtonJacobianCalculationTypeSet(
        iron.JacobianCalculationTypes.EQUATIONS)
    nonLinearSolver.NewtonLinearSolverGet(linearSolver)
    linearSolver.linearType = iron.LinearSolverTypes.DIRECT
    #linearSolver.libraryType = iron.SolverLibraries.LAPACK
    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
    _ = solverEquations.EquationsSetAdd(equationsSet)
    problem.SolverEquationsCreateFinish()

    # Prescribe boundary conditions (absolute nodal parameters)
    boundaryConditions = iron.BoundaryConditions()
    solverEquations.BoundaryConditionsCreateStart(boundaryConditions)

    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               1, X, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               3, X, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               5, X, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               7, X, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               2, X, iron.BoundaryConditionsTypes.FIXED, 0.25)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               4, X, iron.BoundaryConditionsTypes.FIXED, 0.25)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               6, X, iron.BoundaryConditionsTypes.FIXED, 0.25)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               8, X, iron.BoundaryConditionsTypes.FIXED, 0.25)

    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               1, Y, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               2, Y, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               5, Y, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               6, Y, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               3, Y, iron.BoundaryConditionsTypes.FIXED, 0.25)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               4, Y, iron.BoundaryConditionsTypes.FIXED, 0.25)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               7, Y, iron.BoundaryConditionsTypes.FIXED, 0.25)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               8, Y, iron.BoundaryConditionsTypes.FIXED, 0.25)

    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               1, Z, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               2, Z, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               3, Z, iron.BoundaryConditionsTypes.FIXED, 0.0)
    boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               4, Z, iron.BoundaryConditionsTypes.FIXED, 0.0)

    solverEquations.BoundaryConditionsCreateFinish()

    # Solve the problem
    problem.Solve()

    # Copy deformed geometry into deformed field
    for component in [1, 2, 3]:
        dependentField.ParametersToFieldParametersComponentCopy(
            iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES,
            component, deformedField, iron.FieldVariableTypes.U,
            iron.FieldParameterSetTypes.VALUES, component)

    # Copy pressure into pressure field
    dependentField.ParametersToFieldParametersComponentCopy(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 4,
        pressureField, iron.FieldVariableTypes.U,
        iron.FieldParameterSetTypes.VALUES, 1)

    # Export results
    fields = iron.Fields()
    fields.CreateRegion(region)
    fields.NodesExport(exportname, "FORTRAN")
    fields.ElementsExport(exportname, "FORTRAN")
    fields.Finalise()

    Q = numpy.array([[numpy.cos(angle), -numpy.sin(angle), 0.],
                     [numpy.sin(angle), numpy.cos(angle), 0.], [0., 0., 1.]])

    results = {}
    elementNumber = 1
    xiPosition = [0.5, 0.5, 0.5]
    # Note that there seems to be a bug with F in OpenCMISS when fibre angles are specified in x1-x2 plane
    #F = equationsSet.TensorInterpolateXi(
    #    iron.EquationsSetTensorEvaluateTypes.DEFORMATION_GRADIENT,
    #    elementNumber, xiPosition,(3,3))
    Ffib = numpy.array([[0.1250E+01, 0., 0.], [0., 0.1250E+01, 0.],
                        [0., 0., 0.6400E+00]])
    Fref = Ffib
    results["Deformation gradient tensor (fibre coordinate system)"] = Ffib
    results["Deformation gradient tensor (reference coordinate system)"] = Fref
    if debug:
        print("Deformation gradient tensor (fibre coordinate system)")
        print(Ffib)
        print("Deformation gradient tensor (reference coordinate system)")
        print(Fref)

    Cfib = equationsSet.TensorInterpolateXi(
        iron.EquationsSetTensorEvaluateTypes.R_CAUCHY_GREEN_DEFORMATION,
        elementNumber, xiPosition, (3, 3))
    Cref = Cfib
    results[
        "Right Cauchy-Green deformation tensor (fibre coordinate system)"] = Cfib
    results[
        "Right Cauchy-Green deformation tensor (reference coordinate system)"] = Cref
    if debug:
        print(
            "Right Cauchy-Green deformation tensor (fibre coordinate system)")
        print(Cfib)
        print(
            "Right Cauchy-Green deformation tensor (reference coordinate system)"
        )
        print(Cref)

    Efib = equationsSet.TensorInterpolateXi(
        iron.EquationsSetTensorEvaluateTypes.GREEN_LAGRANGE_STRAIN,
        elementNumber, xiPosition, (3, 3))
    results["Green-Lagrange strain tensor (fibre coordinate system)"] = Efib
    if debug:
        print("Green-Lagrange strain tensor (fibre coordinate system)")
        print(Efib)

    Eref = numpy.dot(Q, numpy.dot(Efib, numpy.matrix.transpose(Q)))
    results[
        "Green-Lagrange strain tensor (reference coordinate system)"] = Eref
    if debug:
        print("Green-Lagrange strain tensor (reference coordinate system)")
        print(Eref)

    I1 = numpy.trace(Cfib)
    I2 = 0.5 * (numpy.trace(Cfib)**2. - numpy.tensordot(Cfib, Cfib))
    I3 = numpy.linalg.det(Cfib)
    results["Invariants of Cfib (fibre coordinate system)"] = [I1, I2, I3]
    if debug:
        print("Invariants of Cfib (fibre coordinate system)")
        print("I1={0}, I2={1}, I3={2}".format(I1, I2, I3))

    I1 = numpy.trace(Cref)
    I2 = 0.5 * (numpy.trace(Cref)**2. - numpy.tensordot(Cref, Cref))
    I3 = numpy.linalg.det(Cref)
    results["Invariants of Cref (reference coordinate system)"] = [I1, I2, I3]
    if debug:
        print("Invariants of Cref (reference coordinate system)")
        print("I1={0}, I2={1}, I3={2}".format(I1, I2, I3))

    TCref = equationsSet.TensorInterpolateXi(
        iron.EquationsSetTensorEvaluateTypes.CAUCHY_STRESS, elementNumber,
        xiPosition, (3, 3))
    results["Cauchy stress tensor (reference coordinate system)"] = TCref
    if debug:
        print("Cauchy stress tensor (reference coordinate system)")
        print(TCref)

    # Output of Second Piola-Kirchhoff Stress Tensor not implemented. It is
    # instead, calculated from TG=J*F^(-1)*TC*F^(-T), where T indicates the
    # transpose fo the matrix.
    #TG = equationsSet.TensorInterpolateXi(
    #    iron.EquationsSetTensorEvaluateTypes.SECOND_PK_STRESS,
    #    elementNumber, xiPosition,(3,3))
    #J=1. #Assumes J=1
    TGref = numpy.dot(
        numpy.linalg.inv(Fref),
        numpy.dot(TCref, numpy.linalg.inv(numpy.matrix.transpose(Fref))))
    results[
        "Second Piola-Kirchhoff stress tensor (reference coordinate system)"] = TGref
    if debug:
        print(
            "Second Piola-Kirchhoff stress tensor (reference coordinate system)"
        )
        print(TGref)

    TGfib = numpy.dot(numpy.matrix.transpose(Q), numpy.dot(TGref, Q))
    results[
        "Second Piola-Kirchhoff stress tensor (fibre coordinate system)"] = TGfib
    if debug:
        print("Second Piola-Kirchhoff stress tensor (fibre coordinate system)")
        print(TGfib)

    # Note that the hydrostatic pressure value is different from the value quoted
    # in the original lab instructions. This is because the stress has been
    # evaluated using modified invariants (isochoric invariants)
    p = -dependentField.ParameterSetGetElement(
        iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES,
        elementNumber, 4)
    results["Hydrostatic pressure"] = p
    if debug:
        print("Hydrostatic pressure")
        print(p)

    problem.Destroy()
    coordinateSystem.Destroy()
    region.Destroy()
    basis.Destroy()

    return results
elasticityProblem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1,
                            elasticityNonLinearSolver)
elasticityNonLinearSolver.outputType = iron.SolverOutputTypes.MONITOR
#elasticityNonLinearSolver.outputType = iron.SolverOutputTypes.PROGRESS
#elasticityNonLinearSolver.outputType = iron.SolverOutputTypes.MATRIX
elasticityNonLinearSolver.NewtonJacobianCalculationTypeSet(
    iron.JacobianCalculationTypes.FD)
elasticityNonLinearSolver.NewtonAbsoluteToleranceSet(1e-14)
elasticityNonLinearSolver.NewtonSolutionToleranceSet(1e-14)
elasticityNonLinearSolver.NewtonRelativeToleranceSet(1e-14)
elasticityNonLinearSolver.NewtonLinearSolverGet(elasticityLinearSolver)
#elasticityLinearSolver.linearType = iron.LinearSolverTypes.DIRECT
elasticityProblem.SolversCreateFinish()

# Create elasticity solver equations and add elasticity equations set to solver equations
elasticitySolverEquations = iron.SolverEquations()
elasticityProblem.SolverEquationsCreateStart()
elasticityNonLinearSolver.SolverEquationsGet(elasticitySolverEquations)
elasticitySolverEquations.sparsityType = iron.SolverEquationsSparsityTypes.SPARSE
elasticityEquationsSetIndex = elasticitySolverEquations.EquationsSetAdd(
    elasticityEquationsSet)
elasticityProblem.SolverEquationsCreateFinish()

# Prescribe boundary conditions (absolute nodal parameters)
elasticityBoundaryConditions = iron.BoundaryConditions()
elasticitySolverEquations.BoundaryConditionsCreateStart(
    elasticityBoundaryConditions)

for widthNodeIdx in range(1, numberOfXNodes + 1):
    for heightNodeIdx in range(1, numberOfYNodes + 1):
        # Set left hand build in nodes ot no displacement
Beispiel #8
0
    def setupProblem(self, showProgress=False):
        # Number of Gauss points used
        numberOfGaussXi = 3
        numberOfCircumfrentialElements = self.circumferentialElements
        numberOfLengthElements = self.axialElements
        numberOfLengthNodes = self.axialElements + 1
        numberOfCircumfrentialNodes = numberOfCircumfrentialElements
        numberOfWallNodes = self.wallElements + 1
        numberOfWallElements = self.wallElements

        coordinateSystemUserNumber = 1
        regionUserNumber = 1
        tricubicHermiteBasisUserNumber = 1
        meshUserNumber = 1
        decompositionUserNumber = 1
        geometricFieldUserNumber = 1
        tau = 0.1
        kappa = 0.05
        lambdaFieldUserNumber = 12
        fittingEquationsSetUserNumber = 13
        fittingEquationsSetFieldUserNumber = 14
        fittingDependentFieldUserNumber = 15
        fittingIndependentFieldUserNumber = 16
        fittingMaterialsFieldUserNumber = 17
        fittingProblemUserNumber = 18

        # Get the number of computational nodes and this computational node number
        numberOfComputationalNodes = iron.ComputationalNumberOfNodesGet()

        # Create a 3D rectangular cartesian coordinate system
        coordinateSystem = iron.CoordinateSystem()
        coordinateSystem.CreateStart(coordinateSystemUserNumber)
        # Set the number of dimensions to 3
        coordinateSystem.DimensionSet(3)
        # Finish the creation of the coordinate system
        coordinateSystem.CreateFinish()

        # Create a region and assign the coordinate system to the region
        region = iron.Region()
        region.CreateStart(regionUserNumber, iron.WorldRegion)
        region.LabelSet("HeartTubeRegion")
        # Set the regions coordinate system to the 3D RC coordinate system that we have created
        region.coordinateSystem = coordinateSystem
        # Finish the creation of the region
        region.CreateFinish()
        self.region = region
        # Define basis
        # Start the creation of a tricubic Hermite basis function
        tricubicHermiteBasis = iron.Basis()
        tricubicHermiteBasis.CreateStart(tricubicHermiteBasisUserNumber)
        tricubicHermiteBasis.type = iron.BasisTypes.LAGRANGE_HERMITE_TP
        tricubicHermiteBasis.numberOfXi = 3
        tricubicHermiteBasis.interpolationXi = [
            iron.BasisInterpolationSpecifications.CUBIC_HERMITE
        ] * 3
        tricubicHermiteBasis.quadratureNumberOfGaussXi = [numberOfGaussXi] * 3
        tricubicHermiteBasis.CreateFinish()

        # Start the creation of a manually generated mesh in the region
        numberOfNodes = numberOfCircumfrentialElements * (
            numberOfLengthElements + 1) * (numberOfWallElements + 1)
        numberOfElements = numberOfCircumfrentialElements * numberOfLengthElements * numberOfWallElements

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

        # Create the mesh. The mesh will have two components - 1. tricubic Hermite elements; 2. trilinear Lagrange elements
        mesh.CreateStart(meshUserNumber, region, 3)
        mesh.NumberOfComponentsSet(1)
        mesh.NumberOfElementsSet(numberOfElements)

        tricubicHermiteElements = iron.MeshElements()
        tricubicHermiteElements.CreateStart(mesh, 1, tricubicHermiteBasis)

        elementNumber = 0
        for wallElementIdx in range(1, numberOfWallElements + 1):
            for lengthElementIdx in range(1, numberOfLengthElements + 1):
                for circumfrentialElementIdx in range(
                        1, numberOfCircumfrentialElements + 1):
                    elementNumber = elementNumber + 1
                    localNode1 = circumfrentialElementIdx + (lengthElementIdx-1)*numberOfCircumfrentialNodes + \
                        (wallElementIdx-1)*numberOfCircumfrentialNodes*numberOfLengthNodes
                    if circumfrentialElementIdx == numberOfCircumfrentialElements:
                        localNode2 = 1 + (lengthElementIdx-1)*numberOfCircumfrentialNodes + \
                            (wallElementIdx-1)*numberOfCircumfrentialNodes*numberOfLengthNodes
                    else:
                        localNode2 = localNode1 + 1
                    localNode3 = localNode1 + numberOfCircumfrentialNodes
                    localNode4 = localNode2 + numberOfCircumfrentialNodes
                    localNode5 = localNode1 + numberOfCircumfrentialNodes * numberOfLengthNodes
                    localNode6 = localNode2 + numberOfCircumfrentialNodes * numberOfLengthNodes
                    localNode7 = localNode3 + numberOfCircumfrentialNodes * numberOfLengthNodes
                    localNode8 = localNode4 + numberOfCircumfrentialNodes * numberOfLengthNodes
                    localNodes = [
                        localNode1, localNode2, localNode3, localNode4,
                        localNode5, localNode6, localNode7, localNode8
                    ]
                    tricubicHermiteElements.NodesSet(elementNumber, localNodes)

        tricubicHermiteElements.CreateFinish()

        # Finish the mesh creation
        mesh.CreateFinish()

        # Create a decomposition for the mesh
        decomposition = iron.Decomposition()
        decomposition.CreateStart(decompositionUserNumber, mesh)
        # Set the decomposition to be a general decomposition with the specified number of domains
        decomposition.type = iron.DecompositionTypes.CALCULATED
        decomposition.numberOfDomains = numberOfComputationalNodes
        # Finish the decomposition
        decomposition.CreateFinish()

        # Create a field for the geometry
        geometricField = iron.Field()
        geometricField.CreateStart(geometricFieldUserNumber, region)
        # Set the decomposition to use
        geometricField.MeshDecompositionSet(decomposition)
        geometricField.TypeSet(iron.FieldTypes.GEOMETRIC)
        # Set the field label
        geometricField.VariableLabelSet(iron.FieldVariableTypes.U, "Geometry")
        # Set the domain to be used by the field components to be tricubic Hermite
        geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 1,
                                                 1)
        geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 2,
                                                 1)
        geometricField.ComponentMeshComponentSet(iron.FieldVariableTypes.U, 3,
                                                 1)
        # Set the scaling type
        geometricField.ScalingTypeSet(iron.FieldScalingTypes.UNIT)
        # Finish creating the field
        geometricField.CreateFinish()

        self.setupGeometry(geometricField)
        # Update the geometric field
        geometricField.ParameterSetUpdateStart(
            iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES)
        geometricField.ParameterSetUpdateFinish(
            iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES)

        lambdaField = iron.Field()
        lambdaField.CreateStart(lambdaFieldUserNumber, region)
        lambdaField.TypeSet(iron.FieldTypes.GENERAL)
        # Set the decomposition
        lambdaField.MeshDecompositionSet(decomposition)
        # Set the geometric field
        lambdaField.GeometricFieldSet(geometricField)
        lambdaField.ScalingTypeSet(iron.FieldScalingTypes.NONE)
        # Set the field variables
        lambdaField.NumberOfVariablesSet(1)
        lambdaField.VariableTypesSet([iron.FieldVariableTypes.U])
        # Set the variable label
        lambdaField.VariableLabelSet(iron.FieldVariableTypes.U, "NodeLambda")
        # Set the components to be tricubic-hermite
        lambdaField.NumberOfComponentsSet(iron.FieldVariableTypes.U, 9)
        for comp in range(1, 10):
            lambdaField.ComponentMeshComponentSet(iron.FieldVariableTypes.U,
                                                  comp, 1)
            # Set the interpolation types
            lambdaField.ComponentInterpolationSet(
                iron.FieldVariableTypes.U, comp,
                iron.FieldInterpolationTypes.NODE_BASED)

        lambdaField.ScalingTypeSet(iron.FieldScalingTypes.UNIT)

        lambdaField.CreateFinish()
        # Initialise the lambda field
        for comp in range(1, 10):
            lambdaField.ComponentValuesInitialiseDP(
                iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES,
                comp, 0.0)

        # Create Gauss point fitting equations set
        fittingEquationsSetSpecification = [
            iron.EquationsSetClasses.FITTING,
            iron.EquationsSetTypes.GAUSS_FITTING_EQUATION,
            iron.EquationsSetSubtypes.GAUSS_POINT_FITTING,
            iron.EquationsSetFittingSmoothingTypes.SOBOLEV_VALUE
        ]
        fittingEquationsSetField = iron.Field()
        fittingEquationsSet = iron.EquationsSet()
        fittingEquationsSet.CreateStart(fittingEquationsSetUserNumber, region,
                                        geometricField,
                                        fittingEquationsSetSpecification,
                                        fittingEquationsSetFieldUserNumber,
                                        fittingEquationsSetField)
        fittingEquationsSet.CreateFinish()

        # Create the fitting dependent field
        fittingDependentField = iron.Field()
        fittingEquationsSet.DependentCreateStart(
            fittingDependentFieldUserNumber, fittingDependentField)
        fittingDependentField.VariableLabelSet(iron.FieldVariableTypes.U,
                                               "FittingU")
        fittingDependentField.VariableLabelSet(
            iron.FieldVariableTypes.DELUDELN, "FittingDelUdelN")
        # Set the number of components to 9
        fittingDependentField.NumberOfComponentsSet(iron.FieldVariableTypes.U,
                                                    9)
        fittingDependentField.NumberOfComponentsSet(
            iron.FieldVariableTypes.DELUDELN, 9)
        # Set the field variables to be tricubic hermite
        for comp in range(1, 10):
            fittingDependentField.ComponentMeshComponentSet(
                iron.FieldVariableTypes.U, comp, 1)
            fittingDependentField.ComponentMeshComponentSet(
                iron.FieldVariableTypes.DELUDELN, comp, 1)

        # Finish creating the fitting dependent field
        fittingEquationsSet.DependentCreateFinish()

        # Create the fitting independent field
        fittingIndependentField = iron.Field()
        fittingEquationsSet.IndependentCreateStart(
            fittingIndependentFieldUserNumber, fittingIndependentField)
        fittingIndependentField.VariableLabelSet(iron.FieldVariableTypes.U,
                                                 "GaussLambda")
        fittingIndependentField.VariableLabelSet(iron.FieldVariableTypes.V,
                                                 "LambdaWeight")
        # Set the number of components to 9
        fittingIndependentField.NumberOfComponentsSet(
            iron.FieldVariableTypes.U, 9)
        fittingIndependentField.NumberOfComponentsSet(
            iron.FieldVariableTypes.V, 9)
        # Finish creating the fitting independent field
        fittingEquationsSet.IndependentCreateFinish()
        # Initialise data point vector field to 0.0
        for comp in range(1, 10):
            fittingIndependentField.ComponentValuesInitialiseDP(
                iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES,
                comp, 0.0)
            # Initialise data point weight field to 1.0
            fittingIndependentField.ComponentValuesInitialiseDP(
                iron.FieldVariableTypes.V, iron.FieldParameterSetTypes.VALUES,
                comp, 1.0)

        # Create material field (Sobolev parameters)
        fittingMaterialField = iron.Field()
        fittingEquationsSet.MaterialsCreateStart(
            fittingMaterialsFieldUserNumber, fittingMaterialField)
        fittingMaterialField.VariableLabelSet(iron.FieldVariableTypes.U,
                                              "SmoothingParameters")
        fittingEquationsSet.MaterialsCreateFinish()
        # Set kappa and tau - Sobolev smoothing parameters
        fittingMaterialField.ComponentValuesInitialiseDP(
            iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 1,
            tau)
        fittingMaterialField.ComponentValuesInitialiseDP(
            iron.FieldVariableTypes.U, iron.FieldParameterSetTypes.VALUES, 2,
            kappa)

        # Create the fitting equations
        fittingEquations = iron.Equations()
        fittingEquationsSet.EquationsCreateStart(fittingEquations)
        # Set the fitting equations sparsity type
        fittingEquations.sparsityType = iron.EquationsSparsityTypes.SPARSE
        # Set the fitting equations output type to none
        fittingEquations.outputType = iron.EquationsOutputTypes.NONE
        # Finish creating the fitting equations
        fittingEquationsSet.EquationsCreateFinish()

        # Create fitting problem
        fittingProblemSpecification = [
            iron.ProblemClasses.FITTING, iron.ProblemTypes.DATA_FITTING,
            iron.ProblemSubtypes.STATIC_FITTING
        ]
        fittingProblem = iron.Problem()
        fittingProblem.CreateStart(fittingProblemUserNumber,
                                   fittingProblemSpecification)
        fittingProblem.CreateFinish()

        # Create control loops
        fittingProblem.ControlLoopCreateStart()
        fittingProblem.ControlLoopCreateFinish()

        # Create problem solver
        fittingSolver = iron.Solver()
        fittingProblem.SolversCreateStart()
        fittingProblem.SolverGet([iron.ControlLoopIdentifiers.NODE], 1,
                                 fittingSolver)
        fittingSolver.outputType = iron.SolverOutputTypes.NONE
        fittingProblem.SolversCreateFinish()

        # Create fitting solver equations and add fitting equations set to solver equations
        fittingSolverEquations = iron.SolverEquations()
        fittingProblem.SolverEquationsCreateStart()
        # Get the solver equations
        fittingSolver.SolverEquationsGet(fittingSolverEquations)
        fittingSolverEquations.sparsityType = iron.SolverEquationsSparsityTypes.SPARSE
        fittingEquationsSetIndex = fittingSolverEquations.EquationsSetAdd(
            fittingEquationsSet)
        fittingProblem.SolverEquationsCreateFinish()

        # Prescribe boundary conditions for the fitting problem

        fittingBoundaryConditions = iron.BoundaryConditions()
        fittingSolverEquations.BoundaryConditionsCreateStart(
            fittingBoundaryConditions)
        fittingBoundaryConditions.AddNode(
            fittingDependentField, iron.FieldVariableTypes.U, 1,
            iron.GlobalDerivativeConstants.NO_GLOBAL_DERIV, 1, 8,
            iron.BoundaryConditionsTypes.FIXED, 0.0)

        fittingSolverEquations.BoundaryConditionsCreateFinish()

        self.fittingIndependentField = fittingIndependentField
        self.fittingDependentField = fittingDependentField
        self.lambdaField = lambdaField
        self.fittingProblem = fittingProblem