OPTUMCompute

From OPTUM CE
Jump to navigation Jump to search

1 Getting started

When OPTUM Compute has been installed, open the application and login using your e-mail and password. You will then be greeted by a minimalistic console, geometry window, and visualization window.

OPTUM C start.png

Direct interaction with the application is very limited, and all commands for modelling, analyzing, and viewing results are issued using Python. OPTUM Compute comes with a Python API (OptumCompute.py) and several examples. If the default directory was chosen for the installation, the Python scripts can be found here: C:\Program Files\OPTUM CE\OPTUM C 2020\Python In the current directory, the files are read-only. In order to edit them, copy the code to a new Python script (.py) in a new folder. To run the appended examples:

  1. Open them up in a Python environment (Spyder, PyCharm, Visual Studio Code or similar)
  2. Run OPTUM Compute
  3. Press Run in the Python environment
OPTUM C run.png

1.1 OptumCompute.py

The OPTUM Compute Python API should be imported to the Python script:

import OptumCompute as oc

With this, all the different functions and methods for building a model, running calculations, and viewing results are available within the script. The file contains all the methods available for OPTUM Compute. The input to most of the methods is shown in the file as well, with the exception of the materials, where the material parameters are defined by calling the appropriate names. For example, the method for creating an N-prism as seen in OptumCompute.py:

OPTUM C api.png

The method has a total of 4 inputs, and the 4th input is a location, which can be specified using oc.axis as follows:

OPTUM C nprism.png

which creates vertical 16-sided n-prism with a height of 59.5 metres and a radius of 3.9 metres with the base center located at (0, 0, 20.5 m).

2 Working with OPTUM Compute

Before building a model, specifying materials, etc. a Python script has to be created and the OPTUM Compute Python API imported as shown above. The workflow in OPTUM Compute then follows a few general steps as outlined below:

  1. Creating a material A material is created by specifying the material type and parameters as shown in Section 5. OPTUM Compute comes with two basic categories of materials, Solids and Shells. These are listed in Sections 6 and 7. A Shear Joint material can also be specified for interfaces.
  2. Create stages, analysis type and meshing The oc.setStageProperties method specifies the stage name, analysis type, number of elements and the element type to be used in the analysis. Mesh options can also be specified within the method as shown in Section 11.1. Similarly, the oc.newStage command is used to create a new stage. It also allow for specifying from which previous stage the analysis should be carried out from. Section 11 outlines the methods for creating stages.
  3. Creating a geometry For 3D volumes, the geometry of a material can be specified via the oc.makeBox or oc.makeNprism methods. More complex shapes can be created with the oc.makeFace, oc.makeWire and oc.extrude commands. For 2D faces, the oc.makeRect methods can be used to specify a planar geometry. Geometries can be edited or deleted with the oc.removeInterior, oc.partition and oc.DeleteShape commands.
  4. Assigning a geometry to a material A geometry is assigned a material via the oc.assignSolid method for Solids, oc.assignShell for Shells and oc.assignShearJoint for Shear Joints.
  5. Specify boundary conditions A face or a boundary on a geometry is assigned supports with the oc.assignSupport method. Other methods are also available to directly specify full, normal or tangential supports.
  6. Assign loads The oc.assignLoad method is used to assign a loading vector to a selected face of a geometry. The loading can be non-fixed for limit analysis and multiplier elastoplastic (MEP) problems or fixed for a standard single-step elastoplastic (EP) analysis.
  7. Running the analysis and viewing results After completing the above steps, the analysis is run and the results stored in a list by e.g. writing results = oc.runAnalysis. The analysis progress can be monitored in the Console window of OPTUM Compute. When the analysis is completed the results can be accessed in the results list as shown in Section 13. Section 12 specifies which plotting options are available via the os.plot function for visualization.

2.1 Functions Overview

An overview of the available methods and functions in OPTUM Compute is given below.

Function Description
oc.assignFullSupport Assign full supports to the given shapes
oc.assignLoad Assign the given load to the given shapes
oc.assignNormalSupport Assign normal supports to the given shapes
oc.assignShearJoint Assign the given shear joint material to the given shapes
oc.assignShell Assign the given shell material to the given (surface) shapes
oc.assignSolid Assign a solid material to a geometry in the current stage
oc.assignSupport Assign the given support to the given shapes
oc.assignTangentialSupport Assign tangential supports to the given shapes
oc.axis Axis with given point, normal vector (local Z) and primary vector (local X)
oc.boundBox Bounding box to test against
oc.camera Camera settings
oc.clear Clear everything the current project
oc.currentStage Access current stage information
oc.deleteShape Delete a signel selected object in the current stage
oc.deleteShapes Delete multipile selected objects in the current stage
oc.extractEdges List all edge shapes in current stage
oc.extractFaces List all surface shapes in current stage
oc.extractVertices List all vertex shapes in current stage
oc.extrude Extrude the given 2D shape to a 3D geometry
oc.linear Specify a linearly varying field
oc.loads List of all defined load attributes in current stage
oc.makeBox Bounding box to test against
oc.makeFace Create a 2D face in the current stage
oc.makeMaterial Create a new material in the current stage
oc.makeNprism Create a N-prism in the current stage
oc.makeRect Create a 2D rectangle in the current stage
oc.makeVertex Create a vertex point in the current stage
oc.makeWire Create a wire object in the current stage
oc.material Write out the material with the given id
oc.materials Write out all materials
oc.newStage Create a new stage
oc.partition Parition the selected geometries
oc.plane Plane containing global point (x, y, z) with normal vector (nx, ny, nz)
oc.plot Plot a specific result of the analysis
oc.profile Specify a piecewise linearly varying field
oc.project Access current project information
oc.removeInterior Remove the interior of the selected object
oc.runAnalysis Run the analysis using the stage parameters
oc.select Select objects within the specified domain
oc.selectAll Select all objects in the current stage
oc.setCamera Set the projection of the camera in the current stage
oc.setStageProperties Set the current stage properties
oc.shapes List all shapes in current stage
oc.shearJoints List of all defined solid attributes in current stage
oc.shells List of all defined shell attributes in current stage
oc.solids List of all defined solid attributes in current stage
oc.stages Access all stages information
oc.supports List of all defined support attributes in current stage
oc.vector Vector in global coordinates
The workflow and associated functions in OPTUM Compute.
The workflow and associated functions in OPTUM Compute.

3 Coordinate system

OPTUM Compute uses a standard Cartesian coordinate system. The directions of the global coordinate system are shown upon startup in the lower left corner of the Geometry window. This along with the naming conventions used for the global and local coordinate systems is shown below.

  • Global coordinate system in the Geometry window of OPTUM Compute
    Global coordinate system in the Geometry window of OPTUM Compute
  • Definition of the local and global coordinate system


3.1 Local axis

The oc.axis method specifies the location and orientation of a local coordinate system relative to the global origo:

oc.axis(P, normal, primary)
P Point of local csys origo, , relative to the global csys, default is or global origo
normal Normal vector, N, of the local csys, default is N = , i.e. local normal is in the direction of global coordinate
primary Primary vector, V, specifying the direction of the local csys, default is V, i.e. local -direction is in the global -direction

A local coordinate system with origo at , a normal in the direction of global and V pointing along global is defined as:

at = oc.axis(P=[1, 1, 15], normal=[0, 1, 0], primary=[0, 0, 1])

The above method is for example used to specify a reference point for geometries.

3.2 Defining a plane

The oc.plane method defines a local plane containing the global point with a normal vector :

oc.plane(P=[0,0,0], normal = [0,0,1])
P Point of local csys origo, , relative to the global csys, default is or global origo
normal Normal vector, N, of the local csys, default is N = , i.e. local normal is in the direction of global -coordinate

Similar as to the oc.axis method, a local plane with origo at and a normal in the direction of global can be specified as:

oc.plane(P=[1, 1, 15], normal = [0, -1, 0])

3.3 Defining a vector

The oc.vector method defines a vector in the global coordinate system:

oc.vector(x, y, z)
x magnitude of vector in global direction, default is 0
y magnitude of vector in global direction, default is 0
z magnitude of vector in global direction, default is 0

Defining a vector is required as an input to methods that e.g. specify the magnitude and direction of loading or extrusion of a 2D surface into a 3D volume.

4 Analysis Types

OPTUM Compute comes with four types of analyses: Limit Analysis, Initial Stress, Elastoplastic and Multiplier Elastoplastic analysis. Additionally, a Mesh analysis type is also available. In this section an overview of the different analysis types is given. A complete list of the available options for the different analysis types is found in a section on Stage Options.

4.1 Mesh

This analysis type is atypical in that it involves no physics but only generates a mesh for the current stage. Mesh analysis can be specified through the oc.setStageProperties method by specifying "analysisType": oc.AnalysisType.Mesh as given in a section on Stage Options:

oc.setStageProperties({
    "name": "Mesh", 
    "analysisType": oc.AnalysisType.Mesh, 
    "meshTargetCount": 1000,
    "elementFamily": 'mixed'
    })

The desired number of elements is here set to 1000 and a mixed element is used in the discretization.

Note: all analyses involve the automatic generation of a mesh. As such the Mesh analysis type is meant only to gauge the eventual mesh that would be used in an analysis with the same mesh settings.

4.2 Limit Analysis

The most basic analysis type in OPTUM Compute is Limit Analysis. This allows for the robust assessment of the stability or bearing capacity of geostructures without having to perform an exhaustive step-by-step elastoplastic analysis.

Both Fixed and Multiplier loads are applicable. In Limit Analysis, the former are kept constant while the latter are amplified until a state of incipient collapse is attained. The factor by which the multiplier loads need to be amplified in order to cause collapse is also referred to as the collapse multiplier.

The solution to a given Limit Analysis problem can be bracketed by using lower bound, upper bound and mixed elements. Using the lower bound element in Limit Analysis gives a solution which fulfills equilibrium and the yield conditions. To identify the upper bound a material specific flow rule and stress-strain relation is used. The mixed element type then implements a combination of the two.

A Limit Analysis stage can e.g. be specified as:

oc.setStageProperties({
    "name": "LA", 
    "analysisType": oc.AnalysisType.LimitAnalysis, 
    "meshTargetCount": 5000,
    "adaptIterations": 3,
    "meshStartCount": 1000,
    "elementFamily": 'mixed'
    })

where a mixed upper and lower bound solution is specified via the "elementFamily": 'mixed' and three mesh adaptation iterations are used.

Before running a Limit Analysis stage with the oc.runAnalysis() method, a multiplier loading must be specified:

oc.assignLoad(shape, oc.vector(0,0,-1), isFixed=False)

where the isFixed=False input denotes a multiplier loading. The Limit Analysis will then give as an output a collapse multiplier on the -1 kN loading in the -direction corresponding to a mixed upper and lower bound solution. Furthermore, a failure mechanism can be identified from the analysis. It should be noted that fixed loads and gravity are also included in the Limit Analysis but are not assigned a multiplier, i.e. they are held constant.


4.3 Initial Stress

The initial stresses in the ground are in many cases an important aspect of strength and deformation analysis. In problems involving complex geometries and/or constitutive models, a complete description of the initial stress state may be unavailable by simple methods.

The Initial Stress analysis ( analysis) in OPTUM Compute determines a stress field which satisfies the equilibrium and boundary conditions specified while also complying with the yield conditions of the materials and the earth pressure condition.

It is recommended to perform a Initial Stress analysis in an initial stage before proceeding to do an elastoplastic analysis. Initial stress analysis can be specified as:

oc.setStageProperties({
    "name": "InitialStress", 
    "analysisType": oc.AnalysisType.InitialStress, 
    "meshTargetCount": 1000,
    "elementFamily": "mixed"
    })

Note: Usually, the number of elements is not particularly critical and the computed stress fields will rarely improve significantly by increasing the number of elements above 1000. The mixed element type is recommended for this type of analysis.

4.4 Elastoplastic

A single-step Elastoplastic analysis entails that the failure criteria for all solid and structural elements are included in the analysis. Only fixed loads are processed while multiplier loads are ignored. Gravity is automatically included.

Elastoplastic is the appropriate analysis for both the situation where the deformations in response to a load of a given magnitude are to be computed and in the case where the analysis involves several linked stages in a staged construction scenario (e.g. excavation, embankment construction, etc). For example, after performing a analysis a new stage can be conducted as an elastoplastic analysis:

    oc.newStage({
    "name": "EP", 
    "analysisType": oc.AnalysisType.ElastoPlastic,
    "meshTargetCount": 1000,
    "fromStage": "K0",
    "elementFamily": 'mixed'
    })

where "fromStage": "K0" specifies that the analysis should continue from an initial stress analysis stage named "K0".

In Elastoplastic analysis the mixed element is usually an appropriate choice. However, the elements Lower and Upper may also be used to compute a response that underestimates (Lower) or overestimates (Upper) the true strength as well as stiffness.

4.5 Multiplier Elastoplastic

Multiplier Elastoplastic (MEP) analysis may be seen as combining the Limit Analysis and Elastoplastic analysis types. As in Limit Analysis, the Multiplier loads are amplified until collapse while Fixed loads and gravity are kept constant. This is done in a step-by-step elastoplastic manner with deformations computed at each load step.

Multiplier Elastoplastic analysis is for example useful in determining a Load-Displacement curve as shown in an example in [sec:MonopileTrescaMEP]. Before running a Multiplier Elastoplastic analysis stage with, a multiplier loading must be specified similarly as for Limit Analysis. An example of specifying a MEP stage starting from an Initial Stress analysis is given below:

oc.newStage({
    "name": "MEP", 
    "analysisType": oc.AnalysisType.MultiplierEP,
    "meshStartCount": 1500,
    "steps": 6,
    "w": 20,
    "adaptSteps" : [[0, 1, 1500], [1, 1, 1750], [2, 1, 2000], [3, 1, 2500],
            [4, 1, 3000], [5, 1, 5000]],
    "fromStage": "K0"
    })

In the above "analysisType": oc.AnalysisType.MultiplierEP specifies that the analysis should be conducted as MEP type. The "meshStartCount": 1500 input sets the starting number of elements in the mesh to 1500. Unique to the MEP analysis is the number of load steps to be run, "steps": 6, and the prescribed work for each step, "w": 20, here set at 6 and 20 kJ respectively. Using "fromStage": "K0" ensures that the analysis is to continue from an Initial Stress stage which has been run beforehand. For the MEP analysis, it is possible to select precisely which steps should be used for mesh adaptivity using the option adaptSteps, which is an array of lists containing step number, number of adaptations, and the target number of elements.

5 Creating a material

A new material is added using the following command:

oc.makeMaterial({...})

All materials are created with the same command, and the type of material is specified in the input.

5.1 Linearly varying material parameters

Linearly varying fields can be defined using the linear method, e.g.:

oc.linear(48, z=-6.4, zref=40.0)

which defines a field which takes the value of 48 at and decrease with the -coordinate, e.g. at the field will evaluate to 304. This field can be assigned to a material parameter, e.g. as the shear strength of a Tresca material for limit analysis:

soil = oc.makeMaterial({
    'type': 'Tresca',
    'specificWeight': 20.5,
    'su': oc.linear(48, z=-6.4, zref=40),
    'color': '#ff0000'
})

where 'color': '#ff0000' defined the color of the Tresca material in HEX format, i.e. the chosen color corresponds to bright red in this case.

The linear method can vary in all three directions. The full list of input can be seen below:

constant Value at reference point
x Gradient in the -direction
y Gradient in the -direction
z Gradient in the -direction
xref Reference coordinate
yref Reference coordinate
zref Reference coordinate

5.2 Material parameter profile

Piece-wise linearly varying fields can be defined using the profile method which takes two lists as input, e.g.:

oc.profile([5, 15, 40, 50], [1.5, 1.0, 1.0, 0.5])

which defines a field that takes the value of 1.5 at , decrease linearly to 1.0 at , stays constant between and , and decrease to 0.5 at . For -coordinates lower than 5 or higher than 50, the nearest value will be used, i.e. 1.5 for and 0.5 for . Defining a profile with a single point is equivalent to a constant field.

The profile can be assigned to material parameters, e.g. the cohesion of a Mohr-Coulomb material or as for an AUS material:

soil = oc.makeMaterial({
    'type': 'AUS',
    'specificWeight': 18,
    'suc': 30,
    'sue': 18,
    'K0': oc.profile([5, 15, 40, 50], [1.5, 1.0, 1.0, 0.5]),
    'color': '#100010'    
})

The full list of input can be seen below:

z -coordinates
values Values at each -coordinate

Both z and values are lists, i.e. defined using square brackets as seen above. The number of coordinates and values must be identical otherwise an error message will be shown.

5.2.1 Solids

5.2.1.1 Rigid solid

In order to define a rigid material, the type must be defined as “RigidSolid”:

oc.makeMaterial({'type': 'RigidSolid', ...})

The only parameter that can be defined for a rigid material is the unit weight:

specificWeight Unit weight [kN/m³, default = 0 kN/m³]

5.2.1.2 Mohr-Coulomb

Currently, only Mohr-Coulomb materials with associated flow rule are available. In order to define a Mohr-Coulomb material, the type must be defined as “MohrCoulomb”:

oc.makeMaterial({'type': 'MohrCoulomb', ...})

Strength related parameters (for Limit Analysis):

specificWeight Unit weight [kN/m³, default = 18 kN/m³]
c Cohesion [kPa, default = 5 kPa]
phi Friction angle [°, default = 25°]

Stiffness related parameters (for Elastoplastic Analysis):

E Young’s modulus [MPa, default = 30 MPa]
nu Poisson’s ratio [-, default = 0.25]
K0 K0 for initial stress analysis [-, default = 0.5]

Plastic flow related parameters (for Elastoplastic Analysis):

psi Dilatancy Angle [°, if none model respons is associated (psi=phi)]
epsilonvcr Volumetric cap [-, default = none]

Optional parameters:

ft Tension cut-off [kPa] (included only if “ft” is defined) Default is no tension cut-off.
fc Compression cut-off [kPa] (included only if “fc” is defined) Default is no compression cut-off.
5.2.1.3 Drucker-Prager

In order to define a Drucker-Prager material, the type must be defined as “DruckerPrager”:

oc.makeMaterial({'type': 'DruckerPrager', ...})

Strength related parameters (for Limit Analysis):

specificWeight Unit weight [kN/m³, default = 18 kN/m³]
k Cohesion [kPa, default = 5 kPa]
M Friction coefficient [-, default = 0.7]

Stiffness related parameters (for Elastoplastic Analysis):

E Young’s modulus [MPa, default = 30 MPa]
nu Poisson’s ratio [-, default = 0.25]
K0 K0 for initial stress analysis [-, default = 0.5]
5.2.1.4 Tresca

In order to define a Tresca material, the type must be defined as “Tresca”:

oc.makeMaterial({'type': 'Tresca', ...})

Strength related parameters (for Limit Analysis):

specificWeight Unit weight [kN/m³, default = 18 kN/m³]
su Shear strength [kPa, default = 30 kPa]

Stiffness related parameters (for Elastoplastic Analysis):

E Young’s modulus [MPa, default = 30 MPa]
nu Poisson’s ratio [-, default = 0.25]
K0 K0 for initial stress analysis [-, default = 0.5]

Optional parameters:

ft Tension cut-off [kPa] (included only if “ft” is defined) Default is no tension cut-off.
5.2.1.5 AUS

In order to define a AUS material, the type must be defined as “AUS”:

oc.makeMaterial({'type': 'AUS', ...})

Strength related parameters (for Limit Analysis):

specificWeight Unit weight [kN/m³, default = 18 kN/m³]
suc Undrained shear strength in triaxial compression [kPa, default = 30 kPa]
sue Undrained shear strength in triaxial extension [kPa, default = 18 kPa]

Stiffness and hardening related parameters (for Elastoplastic Analysis):

Eur Initial undrained Young’s modulus [MPa, default = 30 MPa]
epsilonC50 Axial plastic strains halfway to failure in triaxial compression [-, default = 0.005]
epsilonE50 Axial plastic strains halfway to failure in triaxial extension [-, default = 0.020]
alpha Fitting parameter for small strain stiffness, typically [-, default = 0.6]
K0 K0 for initial stress analysis [-, default = 0.5]

Optional parameters:

resetParameter Defines the degree of small strain stiffness reset: Value between 0 and 1 where
1: Full stiffness used. Independent of initial stress state
0: Stiffness reduced accordingly. Dependent on the intial stress state
A value of 1 is used per default if resetParameter is not given.
ft Tension cut-off [kPa] (included only if “ft” is defined) Default is no tension cut-off.
5.2.1.6 Hardening Mohr-Coulomb (HMC)

The Hardening Mohr-Coulomb material includes small strain stiffness and a non-associated flow rule. For elastoplastic analysis, several parameters must therefore be defined.
In order to define a Hardening Mohr-Coulomb material, the type must be defined as “HMC”:

oc.makeMaterial({'type': 'HMC', ...})

Strength related parameters (for Limit Analysis):

specificWeight Unit weight [kN/m³, default = 18 kN/m³]
c Cohesion [kPa, default = 0 kPa]
phi Friction angle [°>, default = 35°]

Stiffness and hardening related parameters (for Elastoplastic Analysis):

E0ref Initial stiffness at reference pressure [MPa, default = 200 MPa]
E50ref Stiffness halfway to failure at reference pressure [MPa, default = 34 MPa]
nu Poisson’s ratio [-, default = 0.25]
dilationRule Either “Taylor” or “Constant”. Use the provided class for setting the flow rule (Default is “Taylor”):
'dilationRule': oc.HMCdilationRule.Taylor
'dilationRule': oc.HMCdilationRule.Constant
psi Dilation angle [°, default = 5°]
epsilonvcr Volumetric dilation cap [-, default = 0.01]
pressureDependency Defines how and depend on the pressure. Use the provided class for setting the pressure dependency (Default is "MinorPrincipal"):
'pressureDepedency': oc.HMCpressureDependency.MinorPrincipal
'pressureDepedency': oc.HMCpressureDependency.MeanStress
'pressureDepedency': oc.HMCpressureDependency.Triaxial
referencePressure Reference pressure for elastic moduli [kPa, default = 100 kPa]
m Exponent for the pressure dependency, [-, default = 0.5]
alpha Fitting parameter for small strain stiffness, typically [-, default = 0.6]
K0 K0 for initial stress analysis [-, default = 0.5]

Optional parameters:

resetParameter Defines the degree of small strain stiffness reset: Value between 0 and 1 where
1: Full stiffness used. Independent of initial stress state
0: Stiffness reduced accordingly. Dependent on the initial stress state
A value of 1 is used per default if resetParameter is not given.
ft Tension cut-off [kPa] (included only if “ft” is defined) Default is no tension cut-off.

5.3 Shells

Shell materials are defined using the same basic makeMaterial-command as for Solids.

5.3.1 Rigid shell

In order to define a rigid shell material, the type must be defined as “RigidShell”:

oc.makeMaterial({'type': 'RigidShell', ...})

The only parameters that can be defined for a rigid shell material are the thickness and density:

thickness Thickness of shell [m, default = 0.1 m]
specificWeight Unit weight [kN/m³, default = 0 kN/m³]

5.3.2 Von Mises shell

In order to define a Von Mises shell material, the type must be defined as “VonMisesShell”:

oc.makeMaterial({'type': 'VonMisesShell', ...})

Strength related parameters (for Limit Analysis):

thickness Thickness of shell [m, default = 0.1 m]
specificWeight Unit weight [kN/m³, default = 0 kN/m³]
fy Yield strength [MPa, default = 300 MPa]
mp Yield moment [kNm/m, default = 100 kNm/m]

Stiffness related parameters (for Elastoplastic Analysis):

E Young’s modulus [MPa, default = 210,000 MPa]
nu Poisson’s ratio [-, default = 0.3]

6 Creating a geometry

Three basic types of shapes are available in OPTUM Compute: wires, 2D faces and 3D volumes. Furthermore, 2D geometries can be extruded to create more complex 3D volume shapes.

The following methods for creating a geometry all return a Python dictionary which can be stored as a variable or passed on to other functions to edit the shapes, assign materials, load specification etc.

Additionally, vertices can be added to faces for application of point loads. Partition is necessary for the added vertex to be a part of face and thereby be included in the meshing. In general, point loads should only be used on rigid shells or rigid solids. An example of this is given in a section on Load Specification.

6.1 3D Box

The oc.makeBox method creates a rectangular box in the current stage:

oc.makeBox(dx, dy, dz, at)
dx,dy,dz dimensions of rectangle [m, default is ]
at Axis location of first corner and orientation of box, default means origo and global axis

The at input attribute specifies the location and orientation of the object (see section on Coordinate System):

at = oc.axis(P, normal, primary)

By e.g. writing:

oc.makeBox(dx=30, dy=30, dz=10, at=oc.axis(P=[-15, -15, 0]))

a 3D box is created with depth and width of 30 m and a height of 10 m. Using at=oc.axis(P=[-15,-15,0]) in the input places the box with it’s center coinciding with the global origo. If no input for at is provided, the lower left corner of the box is by default placed at the global origo with its sides coinciding with the global coordinate system.

6.2 3D N-prism

The oc.makeNprism method creates and returns a N-prism volume shape in the current stage:

oc.makeNprism(n, radius, height, at)
n number of prism sides, [-, default is ]
radius outer radius of prism, [m, default is m]
height height of prism from base to top, [m, default is m]
at location and orientation of base point, default global origo and global axis. The reference point is set at the prism center.

For example, the above method can be called as:

oc.makeNprism(n=16, radius=3.9, height=59.5, at=oc.axis(P=[0, 0, 20.5]))

to create a vertical solid cylinder with a radius of 3.9 m and a height of 59.5 m, with its center located at m.

6.3 2D Rectangle

The oc.makeRect method creates and returns a rectangular surface shape in the current stage:

oc.makeRect(width, height, at) 
width width of rectangle in primary direction, [m, default is 10 m]
height height of rectangle in secondary direction, [m, default is 10 m]
at axis location and orientation of base point, default is origo and global axis

To create a 30 m wide and 20 m high 2D rectangular face, with a plane-normal coinciding with the global -direction, the above can be used as:

oc.makeRect(width=30, height=20, at=oc.plane(P=[10, 20, 30], normal=[0, -1, 0]))

where the location of the lower left corner of the rectangle is set at m.

6.4 2D Face

The oc.makeFace method generates a planar face shape:

oc.makeFace(pathData, at) 
pathData 2D points in the given planar coordinate system
at axis location and orientation of base point, default origo and global axis

For example, to create a 30-by-30 m rectangle with a 20 m indentation on one side, the coordinates of the corners are specified as:

oc.makeFace([[0,0], [10,0], [10,20], [20,20], [20,0], [30,0], [30,30], [0,30]])

Notice that the planar coordinates, , should be placed inside brackets to ensure that the pathData input is given as a Python list. As nothing is specified for at the coordinates are in the global coordinate system.

6.5 Wire

The oc.makeWire method creates a wire object:

oc.makeWire(pathData, at) 
pathData 2D points in the given planar coordinate system, default is the global -plane
at axis location and orientation of base point, default origo and global axis

The pathData input is specified in the same way as for the oc.makeFace method. To create a 30-by-30 m hollow rectangle with a 10 m indentation on one side:

oc.makeWire([[0,0], [10,0], [10,20], [20,20], [20,0], [30,0], [30,30], [0,30], [0,0]])

6.6 Extrude a 2D face or wire

he oc.extrude method extrudes a 2D face or wire:

oc.extrude(shapes, vector) 
shapes instance or collection of shape dictionaries, each with attribute id identifying the shape (output from e.g. oc.makeFace or oc.makeWire)
vector vector in global coordinates specifying the direction and magnitude of the extrusion (use oc.vector)

The input attribute oc.vector specifies a vector in the global coordinate system. This controls the direction of extrusion for the object. The oc.extrude and vector methods are illustrated in the figure below.

OPTUM C extrude.png

The shapes input specifies the geometrical object to be extruded. For example, to create a 30-by-30 m box of height 20 m, the oc.makeFace method is fed into the shapes input:

oc.extrude(oc.makeFace( [[0,0],[10,0],[10,20],[20,20], [20,0],[30,0],[30,30],[0,30]]), oc.vector(z=20))

For more complex shapes, the oc.extrude method along with the oc.makeWire and oc.makeFace provide an easy way to first create the planar layout and then extruding the 2D face to make a 3D volume object.

6.7 Partition shapes

Partitioning shapes in the current stage into a new set of non-overlapping shapes is done via the oc.partition method:

oc.partition(shapes)   

where shapes is an instance or collection of shape dictionaries, each with an attribute id identifying the shape. The method is illustrated below.

OPTUM C partition.png

For example, a 30x30x20 m box can be partitioned into two parts by using a 2D plane:

s1 = oc.makeBox(dx=30, dy=30, dz=20)
s2 = oc.makeRect(30, 30, at=oc.axis(P=[0, 0, 10]))
oc.partition([s1, s2])
oc.deleteShapes(s2)

where after partitioning, the 2D plane used to cut the 3D volume is deleted via the oc.deleteShapes(s2) method.

After partitioning, OPTUM Compute generates new object id’s for the geometries in the current stage. Therefore, a dictionary with the pre-partitioned shape which is stored in a variable cannot be used as a reference after performing the partitioning.

6.8 Create a vertex

The oc.makeVertex method creates a vertex at given location:

oc.makeVertex(x, y, z)
x,y,z Vertex location in global coordinates

The vertex method is for example used to ensure that a node is placed at a specific point on a geometry. This must be the case for point loads as shown in an example in a section on Load Specification.

6.9 Selecting shapes

electing shapes in the current stage is done via the oc.select method:

oc.select(bound, level, partials)
bound Bounding box to test against
level The (combination) of parts to select, i.e. Edge, Face etc. as: Edge : oc.Level.Edge
Face : oc.Level.Face
Shell : oc.Level.Shell
Solid : oc.Level.Solid
Vertex : oc.Level.Vertex
Wire : oc.Level.Wire
partials Include shapes that overlaps the bounding box. If false, only include shapes fully contained in box. Default is partials=True .

The bound input attribute is specified via the oc.boundBox(x, y, z, dx, dy, dz) command where give the reference location of the bounding volume dimensions to be selected. Selecting a face within a bounding box is illustrated in the figure below.

OPTUM C boundbox.png


To specify which type of geometry to select, the level input is given as e.g. oc.Level.Solid to select all solids within the domain.

For selecting only 2D faces within a 30 m wide, 30 m deep and 10 m high box, with its center at global origo:

oc.select(oc.boundBox(x=-15, y=-15, z=0, dx=30, dy=30, dz=10), 
           oc.Level.Face, 
           partials=False)

If multiple 2D faces are present within the bounding box, the method returns a list of dictionaries containing the description of the shapes. This includes the dimensions and reference point of the object along with its id and object type.

All shapes in the stage can be selected using the following method:

shapes = oc.selectAll()  

where shapes will be a list of all shapes in the current stage.

6.10 Replace shapes

To replace a given (volume) shapes in the current stage with their corresponding surface shell shapes the following method can be used:

oc.removeInterior(shapes)     

where shapes is a dictionary containing the volume to be replaced.

For example, to create a circular hollow section the oc.makeNprism method along with oc.removeInterior, oc.select and oc.deleteShapes can be used to create a hollow shell object as:

oc.removeInterior(oc.makeNprism(n=16, radius=3.9, height=59.9))
oc.deleteShapes(oc.select(oc.boundBox(z=59.9), oc.Level.Face) +                
                oc.select(oc.boundBox(z=0.0), oc.Level.Face))

In the above the 16-side prism with a radius of 3.9 m and height of 59.9 m is first created and then hollowed out/replaced by a shell object. Then, the top and bottom faces are selected and subsequently deleted.

6.11 Delete a single shape

Deleting a shape from the current stage is done with the following method:

oc.deleteShape(shape) 

The input shape can be a single object such as the rectangular face stored as a dictionary in s2 in the partitioning example above:

s2 = oc.makeRect(30, 30, at=oc.axis(P=[0, 0, 15]))
oc.deleteShape(s2)

Another example for the use of the above command is when having selected multiple shapes but only a single shape in the list is to be deleted:

sel = oc.select(oc.boundBox(x=-15, y=-15, z=0, dx=30, dy=30, dz=10), 
                oc.Level.Face, 
                partials=False)
oc.deleteShapes(sel[0])

Note in the above the the index in sel[0] refers to the first element in the list, sel[1] to the second etc.

6.12 Delete multiple shapes

Deleting multiple shapes is done via the oc.deleteShapes(shapes) method as:

oc.deleteShapes(shapes) 

If for example, all faces within a certain volume are to be deleted, the above method can be used in combination with the oc.select method as:

sel = oc.select(oc.boundBox(x=-15, y=-15, z=0, dx=30, dy=30, dz=10), 
                oc.Level.Face, 
                partials=False)
oc.deleteShapes(sel)

To delete only certain shapes within the list of selected shapes:

oc.deleteShapes(sel[0]+sel[3]+sel[5])

can be used to remove the first, fourth and sixth shape in the list respectively.

7 Boundary conditions

7.1 Assign supports

A general way to specify boundary conditions is via the oc.assignSupport method as:

assignSupport(shapes, x, y, z, rotation, isLocal)
shapes Instance or list of shape dictionaries, each with attribute id identifying the shape.
x, y, z, rotation Degree of freedom for each global or local axis
isLocal Degrees of freedom parameters are consider in the canonical local coordinate system for the shapes, default is False.

It is considered good practice to always use symmetry in a model to reduce the computational cost. For example, a model including both solid and shell materials can be reduced to half by using one axis of symmetry. The shell boundary conditions can then be specified in the following way:

oc.assignSupport(shellEdge, 
                 x = oc.Support.Free, 
                 y = oc.Support.Fixed, 
                 z = oc.Support.Free, 
                 rotation = oc.Support.Fixed)

corresponding to symmetry about the global -direction, where displacement in the -direction and rotation is fixed.

7.2 Assign full supports

Boundary conditions can be directly assigned as fully fixed (global fixed) as follows:

 oc.assignFullSupport(shapes)    

where shapes is a list containing the dictionaries holding the object description.

7.3 Assign normal supports

To specify a boundary condition directly with local and free but local fixed:

 oc.assignNormalSupport(shapes)  

where shapes is a list containing the dictionaries holding the object description.

7.4 Assign tangential supports

To specify a boundary condition directly with local and fixed and local free:

 oc.assignTangentialSupport(shapes)  

where shapes is a list containing the dictionaries holding the object description.

7.5 Standard fixities

Specifying the boundary conditions of the computational domain is essential when carrying out an analysis with a soil volume which is practically infinite. For example, the figure below shows a soil domain with standard fixities where the displacement normal to the plane is restricted for the sides of the soil domain whereas both normal and in-plane displacements are restricted for the bottom face.

OPTUM C StandardFix.png

A general approach to add standard fixities to a model is shown in the Python code below:

tol = 1E-5
sel = oc.select(oc.boundBox(-15-1, -15-1, 0, 30+2, 30+2, 10+1), oc.Level.Face)
bottoms = []
sides = []
for i in sel:
    b = i['bound']
    x, y, z, dx, dy, dz = [b[c] for c in ['x', 'y', 'z', 'dx', 'dy', 'dz']]
    if abs(z) < tol and dz < tol:
        bottoms.append(i)
    elif abs(x) - foundation_w/2 < tol and dx < tol:
        sides.append(i)
    elif abs(y) - foundation_w/2 < tol and dy < tol:
        sides.append(i)
    elif abs(y) < tol and dy < tol:
        sides.append(i)
oc.assignFullSupport(bottoms)
oc.assignNormalSupport(sides)

This can be broken down in a few steps:

  • Firstly, all 2D faces within a e.g. 30x30x10 volume are selected and a list for storing the faces representing the bottom and sides of the domain is initialized
  • A loop is used to iterate through all the 2D faces in the selected volume and a nested conditional if-elif statement used to check whether a face corresponds to a side or a bottom
  • Finally, the bottom faces are assigned full supports (global fixed) and the sides assigned normal supports (local free, global fixed)

Note that in the above a tolerance variable is introduced as tol=1E-5. This is to allow for conditional statements on the dimensions of the faces, which are stored as floating point numbers with double precision.

8 Load specification

To assign a given load to specific shapes the oc.assignLoad method is used as:

 assignLoad(shapes, vector, isFixed)  
shapes Instance or collection of shape dictionaries, each with attribute id identifying the shape
vector Load vector in global coordinates specified via oc.vector()
isFixed Load is to be considered a fixed (non-multiplier) load, default is False

The units of the load vector depends on the shape to which it is applied: If the shape is a solid a volume load is applied (kN/m³), if the shape is a face a surface load is applied (kN/m²), if the shape is an edge an edge load is applied (kN/m), and, finally, if the shape is a vertex a point load is applied (kN).

Arrows are used to denote assigned loads in the Geometry window as shown in the figure below.

OPTUM C Load.png

To apply a vertical multiplier load to a rectangular face stored in rect (for e.g. Limit Analysis), the above method can be used as:

oc.assignLoad(rect, oc.vector(0,0,-1), isFixed=False)

As the given shape is a 2D face, the loading type is a surface load in units of kN/m.

For point loading, a node must be placed where the loading is assigned. This can be ensured by creating a vertex via the oc.makeVertex method on the geometry. For example, to assign a 25 kN vertical point loading on the middle upper face of a 10x10x10 m box:

s1 = oc.makeBox(10,10,10,at=oc.axis([-5,-5,-10]))
v = oc.makeVertex()
oc.partition([s1, v])
oc.assignLoad(v, oc.vector(0,0,-25))

Generally, the s1 shape in this example is assigned a rigid solid or shell material. Note that the box and vertex must be partitioned via the oc.partition([s1, v]) method.

9 Stage options

The stage options define the calculations to be run. The following options are available:

analysisType Use the provided analysisType class (Default analysis type is meshing):
oc.AnalysisType.Mesh: Meshing
oc.AnalysisType.LimitAnalysis: Limit analysis
oc.AnalysisType.ElastoPlastic: Single-step elastoplastic analysis
oc.AnalysisType.InitialStress: Initial stress analysis
oc.AnalysisType.MultiplierEP: Multiplier elastoplastic analysis
elementFamily Use the provided elementFamily class:
oc.AnalysisType.Upper: Upper bound elements
oc.AnalysisType.Mixed: Mixed elements
oc.AnalysisType.Lower: Lower bound elements (Currently not available)
name Unique name for the stage (standard string)
fromStage Defines previous stage: Results are carried over and analysis continues with e.g. additional loads. The previous stage is referenced using the name.

When using the AUS or HMC materials, so-called iterations are needed to ensure convergence for each step. Tolerances and maximum number of iterations can be provided:

tol Defines the acceptance criterion for the multiplier, i.e. , default is tol = 0.01
iterations Defines the maximum number of iterations, default is 15

For the multiplier elastoplastic (MEP) analysis additional parameters can be given:

steps Number of load steps to be run, default is 1
w Prescribed work (kJ) for each step. Input can be either a single double or a list of doubles. Default value is 1.0.
tol2 Defines the acceptance criterion for the dampening and step length

9.1 Mesh options

When defining a stage, several options for the mesh and mesh adaptivity can be defined. Generally, the following options are available:

meshTargetCount Desired number of elements [integer]
meshStartCount Initial number of elements when using mesh adaptivity [integer]
adaptIterations Number of mesh adaptations [integer]
refinementFactor Defines the degree of refinement, i.e. the minimum size of new elements compared to the old size [double, default = 0.25]
coarseningFactor Defines the degree of coarsening, i.e. the maximum size of new elements compared to the old size [double, default = 1.50]
targetLowerBound Defines the lowest number of elements accepted relative to the target number [double, default = 0.90]
targetUpperBound Defines the highest number of elements accepted relative to the target number [double, default = 1.10]

For multiplier elastoplastic analysis, mesh adaptivity can be chosen for any number of steps:

adaptSteps List of triplets [3 integers]: Each triplet specifies the step number (starting from 0), the number of adaptivity iterations, and the target number of elements.

An example of performing initial stress analysis, creating a new stage with MEP analysis and using mesh adaptivity is given in the Examples section.

10 Plotting options

The results can be visualised in OPTUM Compute using the oc.plot method. The following input parameters are available:

fieldSetName Field to be plotted, e.g. stresses, displacements and so on
layer Toggle between regular elements and (collapsed) interface elements. Default: Regular elements are shown.
include Toggle between solids and shells. Default: Both are shown.
displacementScale Factor for the displacements (or normalized velocities for Limit Analysis) for better visualization. Default: 0.
rangeMax Maximum for shown values. Default: No maximum is used.
rangeMin Minimum for shown values. Default: No minimum is used.
step Display the MEP results for specified step. Default: Last step is shown.
camera Specify initial view using oc.camera, e.g. camera=oc.camera(location=oc.vector(100,100,50)). Default: Top-down view is used.
clipPlane Allow cutting through the model for better visualization, e.g. clipPlane=oc.plane(0,0,0,1,0,0), where the first three inputs to plane specify a point and the next three specify the normal vector. Default: No clipping plane is used.
slicePlane Similar to clipPlane, but only the intersection of the plane and elements is shown. Default: No slice plane is used.
filename File name for export of view. Default: No file name is specified, thus, no image is exported.
renderAttributes Renders the boundary conditions on the result set. Default: False, i.e. not shown.

The result fields can be plotted by specifying the correct fieldSetName:

u| Euclidian norm of the displacements (or normalized velocities for Limit Analysis).
ux Displacement in the -direction. Not available for Limit Analysis.
uy Displacement in the -direction. Not available for Limit Analysis.
uz Displacement in the -direction. Not available for Limit Analysis.
sx
sy
sz
sxy
syz
szx
s1 , largest principal stress, i.e.
s2 , middle principal stress
s3 , smallest principal stress
mx , moment in the -direction (shells)
my , moment in the -direction (shells)
mxy , twisting moment (shells)
m1 , largest principal moment, (shells)
m2 , smallest principal moment (shells)
td Total dissipation (solids)
td Shear dissipation (solids)

Strains will be added to the result set in the nearest future.

The layer input takes a string as input:

layer= Default option, solids and shells are shown.
layer='volumes' Same as default option, solids and shells are shown.
layer='interfaces' Interface elements are shown.

The include input takes a string as input:

include= Default option, solids and shells are shown.
include='solids' Solids shown.
include='shells' Shells are shown.

11 Accessing the results

The result set is the output when an analysis is run:

results = oc.runAnalysis()

The results follow a tree structure using python default list and dictionaries, the aim is for the user to access data in the model using generator expressions. Information in the element edges for displacement, stress and material field are available. In addition to information in the edges the nodal forces and its location is also available for each element, other relevant information regarding the stage has also been included (name, element type, etc).

The result data structure follows:

results[#Stage]['name'] Name of stage
results[#Stage]['elementFamilty'] Element family
results[#Stage]['results'] Results for the selected stage

The result field contains a list with the element information. If the results of a stage contain more than one result (e.g. MEP) the list is accessed by its index.

results[#Stage]['results'][#result]
Result list for selected stage

The result field contains the information of the elements and a other global output such as load multipliers and other info from the solver. The available fields are:

results[#Stage]['results'][#result]['analysis']
Load multiplier info, analysis type and solver output
results[#Stage]['results'][#result]['InterfaceElements']
List of Interface elements
results[#Stage]['results'][#result]['ShellElements'] if the result field contains Shell elements
List of shells elements
results[#Stage]['results'][#result]['SolidElements'] if the result field contains Volume/Solid elements
List of solid elements

11.1 Element tree list

Each element in the element list (Interfaces, Shell or Soild Element) is accessed by its index.

results[#Stage]['results'][#result]['#Solid/Interface/ShellElements'][#EL] Location of the solid or shell element

For each element the information available is:

results[#Stage]['results'][#result]['#Solid/Inteface/ShellElements'][#EL]['Nodes']
Node info belonging to the element - Only Nodal Forces and Position
results[#Stage]['results'][#result]['#Solid/Inteface/ShellElements'][#EL]['Points'].
Information belonging to the edges of the element
results[#Stage]['results'][#result]['#Solid/Interface/ShellElements'][#EL]['fieldDefinitions']
Field definition corresponding to the 'values' points belonging to that particular element (mirrors results[#Stage]['results'][#result]['SolidElements'][#EL]['Points'][#POINT]['values']

11.2 Point and Node tree list

The lowest level containing information of the data tree corresponds to points and nodes. The "point" field corresponds to the edges of each element, while the "node" correspond to the nodal forces (generally an element consists of more nodes than points)

results[#Stage]['results'][#result]['#Solid/Interface/ShellElements'][#EL]['Points'][#Point] Point information "location" and "values", value corresponds to variable defined in 'fieldDefinitions'
results[#Stage]['results'][#result]['#Solid/Interface/ShellElements'][#EL]['Nodes'][#Node] Node information "NodalPosition" and "NodalForce"

An agile method to obtain the corresponding value is to use a lambda function to return the index associated with the string in FieldDefinitions as it is element type dependent.

def indexOfDefintion(FieldDefinitions, name):
        for ci,i in enumerate(FieldDefinitions):
            if i == name:
                return ci
IndexFun = lambda name : indexOfDefintion(results[#Stage]['results'][#result]['#Solid/Interface/ShellElements'][#EL]['fieldDefinitions'],name)

Therefore the x-displacement on the third point for the first solid element in the list can be accessed via:

results[0]['results'][0]['SolidElements'][0]['Points'][2]['values'][IndexFun('Ux')]

12 Examples

12.1 Monopile with Tresca material

In this section, we will go through an example script for modelling and analysing a monopile. The script is included as an example in the installed version of OPTUM Compute as well.

First and foremost, we import OptumCompute and set the camera to perspective. Moreover, several variables are defined to make the model parametric:

import OptumCompute as oc

oc.setCamera(oc.CameraOption.Perspective)
oc.clear()
foundation_w = 50.0
foundation_h = 40.0

d = 19.5
pile_z = foundation_h - d
pile_h = 40.0 + d
pile_r = 3.9

tol = 1E-5

Next, the materials are defined: The soil is modelled as a Tresca material with a shear strength, which increase with the depth and has the value of 48 kPa at ground level, while the monopile is modelled as a rigid shell.

solid1 = oc.makeMaterial({
    'type': 'Tresca',
    'specificWeight': 20.5,
    'su': oc.linear(48, z=-6.4, zref=foundation_h),
    'E': 50,
    'nu': 0.0,
    'K0': 0.5,
    'color': '#ff0000'
})

shellMaterial = oc.makeMaterial({
    'type': 'RigidShell',
    'thickness': 0.080,
    'color': '#60ff00'
})

The model is encapsulated in a small method, as it needs to be defined twice; once for the initial stress analysis and once for the multiplier elastoplastic analysis. The geometry of the soil is created using the makeBox method, while the monopile is created using the makeNprism method. Due to the symmetry of the model, half is removed using a box to partition, and finally, the interior of the pile is removed above ground level.

def create_geometry():
    shift = foundation_w/2
    s1 = oc.makeBox(foundation_w, foundation_w, foundation_h, 
            at=oc.axis(P=[-shift, -shift, 0]))
    s2 = oc.makeNprism(16, pile_r, pile_h, at=oc.axis(P=[0, 0, pile_z]))
    s3 = oc.makeBox(foundation_w+2, foundation_w/2+1, 
            foundation_h+pile_h+1, at=oc.axis(P=[-shift-1, 0, 0]))
    oc.partition([s1, s2, s3])

    # Remove half:
    sel = oc.select(oc.boundBox(-shift+2, 1, 1, foundation_w+2, 
            foundation_w/2+2, foundation_h+pile_h ), 
            oc.Level.Solid)
    oc.deleteShapes(sel)

    # Hollow out pile above ground and delete face:
    sel = oc.select(oc.boundBox(z=pile_h + pile_z/2), oc.Level.Solid)
    oc.removeInterior(sel[0])
    sel = oc.select(oc.boundBox(z=pile_h + pile_z/2), oc.Level.Face)
    oc.deleteShapes(sel[0])

With the geometry in place, materials can be assigned to the shapes. This is done by selecting a shape in the model using the select method and then assigning materials. For the shells, two selections are used to be able to define interfaces between the pile and the soil. These interfaces means that a displacement discontinuity can occur. Finally, a shear joint is assigned at pile bottom, which again enables a displacement discontinuity.

    # solid 
    sel = oc.select(oc.boundBox(-shift-1, -shift-1, 0, foundation_w+2, 
            foundation_w+2, foundation_h+1), oc.Level.Solid)
    oc.assignSolid(sel, solid1)

    # shell    
    sel = oc.select(oc.boundBox(x = -pile_r-1, y=-pile_r-1, z=pile_z+1, 
            dx=2*pile_r+2, dy=pile_r, dz=foundation_h-pile_z-2), oc.Level.Face)
    sel = list(filter(lambda s:s['bound']['dy'] > 1e-5, sel))
    oc.assignShell(sel, shellMaterial, plusMaterial=solid1, minusMaterial=solid1)

    sel = oc.select(oc.boundBox(-pile_r-1, -pile_r-1, foundation_h+1, 
                    2*pile_r+2, pile_r+2, pile_h), oc.Level.Face)
    oc.assignShell(sel, shellMaterial)
    
    # shear joint at pile bottom:
    sel = oc.select(oc.boundBox(0, -1, pile_z), oc.Level.Face)
    oc.assignShearJoint(sel, solid1)

For the soil, standard fixities are used. This is done by selecting the faces of the soil domain and assigning full support for the bottom and normal supports for the sides. When using either the assignNormalSupport or assignTangentialSupport methods, the local coordinate system of the face is used.

    # standard fixities
    sel = oc.select(oc.boundBox(-shift-1, -shift-1, 0, foundation_w+2, 
                    foundation_w+2, foundation_h+1), oc.Level.Face)
    bottoms = []
    sides = []
    for i in sel:
        b = i['bound']
        x, y, z, dx, dy, dz = [b[c] for c in ['x', 'y', 'z', 'dx', 'dy', 'dz']]
        if abs(z) < tol and dz < tol:
            bottoms.append(i)
        elif abs(x) - foundation_w/2 < tol and dx < tol:
            sides.append(i)
        elif abs(y) - foundation_w/2 < tol and dy < tol:
            sides.append(i)
        elif abs(y) < tol and dy < tol:
            sides.append(i)
    oc.assignFullSupport(bottoms)
    oc.assignNormalSupport(sides)

Symmetry conditions must be applied to the pile itself. Again, this is done by selecting the relevant edges and applying supports using the assignSupport method.

    # shell BCs
    edges = []
    edges.extend(oc.select(oc.boundBox(x = -pile_r, y = 0, 
            z = pile_z/2+foundation_h/2), oc.Level.Edge))
    edges.extend(oc.select(oc.boundBox(x = pile_r, y = 0, 
            z = pile_z/2+foundation_h/2), oc.Level.Edge))
    
    edges.extend(oc.select(oc.boundBox(x = -pile_r, y = 0, 
            z = pile_z/2+foundation_h), oc.Level.Edge))
    edges.extend(oc.select(oc.boundBox(x = pile_r, y = 0, 
            z = pile_z/2+foundation_h), oc.Level.Edge))   
    
    edges.extend(oc.select(oc.boundBox(x = 0, y = 0, z = pile_z+foundation_h), 
            oc.Level.Edge))
    
    oc.assignSupport(edges, x=oc.Support.Free, y=oc.Support.Fixed, 
            z=oc.Support.Free, rotation=oc.Support.Fixed)

    return

An initial stress stage is required when doing a multiplier elastoplastic analysis. A stage name is needed as reference for following stage. The analysis type is set to oc.AnalysisType.InitialStress, and we will be using approximately 1500 mixed elements. The stage is run using oc.runAnalysis().

# STAGE 1
oc.setStageProperties({
    "name": "K0", 
    "analysisType": oc.AnalysisType.InitialStress, 
    "meshTargetCount": 1500,
    "elementFamily": 'mixed'
})
create_geometry()
result = oc.runAnalysis()

With the initial stresses computed, we can create a new stage for the multiplier elastoplastic (MEP) analysis. With the new stage initiated, we recreate the geometry and define the load acting horizontally at the pile top. For the analysis, we want to run six steps starting at 1500 elements and adapt the mesh every step increasing the element count to 4000 for the final step.

For the MEP analysis, it is possible to select precisely which steps should be used for mesh adaptivity using the option adaptSteps, which is an array of lists containing step number, number of adaptations, and the target number of elements.

# STAGE 2
oc.newStage({
    "name": "MEP", 
    "analysisType": oc.AnalysisType.MultiplierEP,
    "meshStartCount": 1500,
    "steps": 6,
    "w": 20,
    "adaptSteps" : [[0, 1, 1500], [1, 1, 1750], [2, 1, 2000], [3, 1, 2500],
            [4, 1, 3000], [5, 1, 5000]],
    "fromStage": "K0"
})
create_geometry()
sel = oc.select(oc.boundBox(0,0,pile_z+pile_h), oc.Level.Face)
oc.assignLoad(sel, oc.vector(10,0,0), isFixed = False)

result = oc.runAnalysis()

oc.plot('|U|', displacementScale = 10)

The six steps of the MEP analysis yield the following load multipliers and maximum displacements:

MEP step 1 concluded: Multiplier = 11.2121, max displacement = 0.0862609 m
MEP step 2 concluded: Multiplier = 17.3423, max displacement = 0.172418 m
MEP step 3 concluded: Multiplier = 20.8508, max displacement = 0.258606 m
MEP step 4 concluded: Multiplier = 22.9506, max displacement = 0.344827 m
MEP step 5 concluded: Multiplier = 24.064, max displacement = 0.431041 m
MEP step 6 concluded: Multiplier = 24.672, max displacement = 0.517284 m

Multiplying with the applied load of 10 kN/m² and the area of the pile top (23.282 m²), we get the following load displacement curve for the top of the pile:

OPTUM C TrescaUP.png



Return to Main Page