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
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,
                               iron.BoundaryConditionsTypes.FIXED, 1.0)

# Set minimum concentration (0) for nodes at the outlet
for outlet_node in outlet_node_array:
    boundaryConditions.SetNode(dependentField, iron.FieldVariableTypes.U, 1, 1,
                               int(outlet_node), 1,
                               iron.BoundaryConditionsTypes.FIXED, 0.0)

solverEquations.BoundaryConditionsCreateFinish()
Beispiel #3
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
Beispiel #6
0
    def defineBoundaryConditions(solverEquations, increment):
        # Prescribe boundary conditions (absolute nodal parameters)
        boundaryConditions = iron.BoundaryConditions()
        solverEquations.BoundaryConditionsCreateStart(boundaryConditions)

        #Set x=0 nodes to no x displacment in x. Set x=width nodes to 10% x displacement
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, 1,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, 1,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, 1,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 7, 1,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, 1,
                                   iron.BoundaryConditionsTypes.FIXED,
                                   increment)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, 1,
                                   iron.BoundaryConditionsTypes.FIXED,
                                   increment)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, 1,
                                   iron.BoundaryConditionsTypes.FIXED,
                                   increment)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 8, 1,
                                   iron.BoundaryConditionsTypes.FIXED,
                                   increment)

        # Set y=0 nodes to no y displacement
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, 2,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, 2,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 5, 2,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 6, 2,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        # Set z=0 nodes to no y displacement
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 1, 3,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 2, 3,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 3, 3,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)
        boundaryConditions.AddNode(dependentField, iron.FieldVariableTypes.U,
                                   1, 1, 4, 3,
                                   iron.BoundaryConditionsTypes.FIXED, 0.0)

        solverEquations.BoundaryConditionsCreateFinish()
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
        nodeIdx = widthNodeIdx + (heightNodeIdx - 1) * numberOfXNodes
        elasticityBoundaryConditions.AddNode(
            elasticityDependentField, iron.FieldVariableTypes.U, 1, 1, nodeIdx,
            1, iron.BoundaryConditionsTypes.FIXED, 0.0)
        elasticityBoundaryConditions.AddNode(
            elasticityDependentField, iron.FieldVariableTypes.U, 1, 1, nodeIdx,
            2, iron.BoundaryConditionsTypes.FIXED, 0.0)
        elasticityBoundaryConditions.AddNode(
            elasticityDependentField, iron.FieldVariableTypes.U, 1, 1, nodeIdx,
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