Search Results

Scripting Tunnel Tutorial (Part 1)

1.0 Introduction

The RS3 Scripting feature is an API tool based on the Python programming language, designed to model and interpret results with the interface. This tutorial walks you through how to automate the modeling process for a practical application using RS3 Scripting. You will also learn the basic steps required to run your first RS3 Python Script.

Topics covered in this tutorial include scripting exercise to conduct following operations:

  • Opening, closing and saving a model;
  • Defining Project Settings;
  • Defining properties of Materials and Liners;
  • Assigning material properties after Selecting external volume entities using different query methods;
  • Setting field stress; and
  • Meshing and computing the model

Prerequisites

Before you begin, ensure you have the RS3 program installed at minimum Version 4.042 and have gone through Getting Started with RS3 Python Scripting tutorial so you have initial setup with RS3 Scripting completed.

1.1 Tutorial Files

All tutorial files installed with RS3 can be accessed by selecting File > Recent > Tutorial Folder from the RS3 main menu. The starting files can be found in the Scripting > Scripting Tunnel Tutorial (Part 1) subfolder, including an initial model file, a python file (.py) and the python Jupyter notebook file (.ipynb) with the description markdowns, and a csv file of input data for material. The next part of this tutorial Scripting Tunnel Tutorial (Part 2) continues the result interpretation with the final product of this tutorial. The RS3 project file can be found in the Scripting >Scripting Tunnel Tutorial (Part 2).

2.0 Set Up RS3 and RocScript Editor

  1. Open RS3 Modeler
  2. Select Scripting from the top menu > Select RocScript Editor Rocscript. The RocScript Editor will be launched.
  3. In the RocScript Editor, select File > Open Folder, and select folder C:\Users\Public\Documents\Rocscience\RS3 Examples\Tutorials\Scripting Tunnel Tutorial (Part 1).
    If you provided a custom location for example files when installing RS3, search the provided location instead.
    Rocscript > Open Folder
  4. Navigate to Explorer tab and select New File
  5. Name the new file "Scripting_tutorial_modeler.py"

3.0 Set Up the Script and Open the Model

3.1 Import the Required Modules from RS3 Scripting

The RS3Modeler module is the primary module that contains scripting functions used to manipulate the models through scripts. Each submodule in RS3 scripting has a corresponding enum module. These enum modules provide predefined options for functions, similar to the dropdown selections available in the RS3 program. For example, enums related to material and support (e.g. bolt, beam, pile, etc) are located in the PropertyEnums module, while enums for project settings are stored in the ProjectSettingEnums module.

  1. Import the required modules from RS3 Python API library and os library.
from rs3.RS3Modeler import RS3Modeler
from rs3.projectSettings.ProjectSettingEnums import *
from rs3.properties.PropertyEnums import *
from rs3.mesh.MeshEnums import *
from rs3.CommonEnums import *
from rs3.ModelEnums import *
from rs3.loadings.LoadingEnums import *
from rs3.Geometry import Point, Polyline, Cube
import os

3.2 Open Starting Model File

  1. Start the RS3 program (server) with the port number 60064
  2. port=60064
    RS3Modeler.startApplication(port)
  3. The script (client ) connects with RS3 Modeler through the same port number 60064
  4. modeler = RS3Modeler(port)
    If you have RS3 application opened and wish to connect with that application, select Scripting > Manage Scripting Server > Choose an available port > Start Server and enter the port number that matches with the number assigned in scripting
  5. Open the starting file from the directory where the tutorial files are installed.
  6. # Find the current file folder path
    currentFileFolderPath = os.path.abspath("")
    # Open the model
    modelPath = rf"{currentFileFolderPath}\Scripting Tunnel Tutorial (Part 1) - Initial.rs3v3"
    model = modeler.openFile(modelPath)
    
    The starting file has preliminary geometry setup and support installation are complete.

First screen

4.0 Project Settings

In this section, the system of units, stages, and groundwater conditions is defined from project settings module

4.1 Define Units

The unit system is one of the most fundamental settings in a project. Changing the unit system at a later stage may reset all unit-dependent properties. Therefore, it is good to set the unit system at the beginning of the project.

RS3 supports a variety of metric and imperial units. The unit system used in a model is determined by the selected stress unit. In this tutorial, the metric unit system with kPa as the stress unit is used.

model.ProjectSettings.Units.setUnitSystem(UnitSystemType.METRIC_KPA)

4.2 Define Stages

The model requires 10 stages, organized as follows:

  • Initial Stage
  • Grouting Stages, before excavation for every two tunnel slices
  • Excavate Stages, where every tunnel slice is excavated in three steps
  • Support Installation, where liners are installed at the same stage as the excavation

Since liners are installed sequentially in the initial model, a grouting stage is inserted before the liner installation for every two tunnel slices.

  1. To simplify the syntax, a variable is defined to reference the stages object:
  2. stages = model.ProjectSettings.Stages
  3. Stage names can be updated individually if needed.
  4. stages.setName(1, "Initial Stage")
  5. A grouting stage is added before any excavation using reference stages. When a reference stage is specified, the new stage is inserted after the reference stage.
  6. # Add a stage after stage 1
    stages.addStages(1, 1)
  7. If the stages follow a consistent naming pattern, for loops can be used to simplify the process. Each slice of tunnel is excavated in three steps. In total, there are three grouting stages and nine excavation stages. The name reflects both
  8. 
    groutingStageCount = 1
    excavationStages = 9
    
    for excavationStageIndex in range(excavationStages):
     stageNumber = 2 + excavationStageIndex
    
     if groutingStageCount <= 3 and excavationStageIndex % 2 == 0:
     stages.setName(stageNumber, f"Grouting Stage {groutingStageCount} Excavation Stage {excavationStageIndex+1}")
     groutingStageCount += 1
     else:
     stages.setName(stageNumber, f"Excavation Stage {excavationStageIndex+1}")
    

Stage list

4.3 Set Groundwater Method

Groundwater analysis is not included in this model. Therefore, the groundwater method type can be safely set to None.

model.ProjectSettings.Groundwater.setGroundwaterMethod(GroundwaterMethodType.GW_NONE)

5.0 Set Material Properties

In this section, material properties and support properties are defined through scripting

5.1 Set Material Properties in Scripting

  1. Create a new material for grouting.
    groutingName = "grouting"
    model.createNewMaterialProperty(groutingName)
    grouting = model.getMaterialPropertyByName(groutingName)
    
  2. Assign a color associated with the material. After entering a hex color code, you may optionally use the color picker to select the desired color.
    grouting.setMaterialColor("#727272")
    
  3. Assign the material properties of the grouting as summarized in the following table.
    PropertyValue
    Initial Element LoadingBody Force Only
    Unit Weight (kN/m3)22
    Elastic TypeLinear Isotropic
    Poisson's Ratio0.25
    Young's Modulus150e3
    Constitutive ModelElastic
    Peak Cohesion (kPa)50
    Peak Friction Angle (o)35
    Tensile Strength (kPa)30


    Properties can be assigned through individual function calls or collectively using the setProperties() function.

    grouting.InitialConditions.setInitialElementLoading(InitialElementLoadingType.BODY_FORCE_ONLY)
    grouting.InitialConditions.setUnitWeight(22)
    grouting.ConstitutiveModel.MohrCoulomb.setElasticType(MaterialElasticityTypes.LINEAR_ISOTROPIC)
    grouting.ConstitutiveModel.MohrCoulomb.LinearIsotropicStiffness.setPoissonsRatio(0.25)
    grouting.ConstitutiveModel.MohrCoulomb.LinearIsotropicStiffness.setYoungsModulus(150e3)
    grouting.ConstitutiveModel.setConstitutiveModel(constitutiveModelTypes=ConstitutiveModelTypes.MOHR_COULOMB)
    grouting.ConstitutiveModel.MohrCoulomb.setMaterialType(MaterialType.ELASTIC)
    grouting.ConstitutiveModel.MohrCoulomb.setProperties(Cohesion=50, FrictionAngle=35, TensileStrength=30)
    

Have completed this step, check the material dialog from RS3 (Materials > Define Materials), you shall find the the material property named Grouting created

Grouting material dialog

  • Not all properties are available through the `setProperties()` function, so some properties may still need to be set individually
  • All materials are set to behave perfectly elastic. Strength parameters are used only for the strength factor calculations and non-linear analysis shall not be computed to take into account the material yielding

5.2 Import Material Properties through a CSV File

  1. Soil properties can also be imported from a CSV file. In this tutorial, the third-party library pandas is used to read the CSV file and create a DataFrame, which simplifies data manipulation.
    import pandas as pd
    
    soilPropertiesPath = rf"{currentFileFolderPath}\Soil Properties.csv"
    # Read the csv file
    soilPropertiesDf = pd.read_csv(soilPropertiesPath)
    
    # Set the soil layer as the index of the DataFrame
    soilPropertiesDf = soilPropertiesDf.set_index("Soil Layer")
    
    soilPropertiesDf
    
  2. As shown in the model, there are 10 soil layers, each with its own set of material properties. These properties can be assigned using various RS3 scripting functions. Using a pandas DataFrame provides a convenient way to organize and access the soil property data before assigning them to the model.
    numOfSoilLayers = 10
    
    for soilLayerIndex in range(numOfSoilLayers):
    
     # Get the material property by name
     material = model.getMaterialPropertyByName(f"Material {soilLayerIndex+1}")
    
     # Get each row of data from the DataFrame
     row = soilPropertiesDf.iloc[soilLayerIndex]
    
     # Set the material name based on the table
     material.setMaterialName(row["Material Name"])
    
     # Set the initial condition of the model
     material.InitialConditions.setUnitWeight(row["Unit Weight (kN/m^3)"])
    
     # Set constitutive model properties
     material.ConstitutiveModel.setConstitutiveModel(ConstitutiveModelTypes.MOHR_COULOMB)
    
     material.ConstitutiveModel.MohrCoulomb.setProperties(
     TensileStrength=row["Tensile Strength (kPa)"],
     FrictionAngle=row["Friction Angle (°)"],
     Cohesion=row["Cohesion (kPa)"],
     DilationAngle=row["Dilation Angle (°)"]
     )
    
     material.ConstitutiveModel.MohrCoulomb.setMaterialType(MaterialType.ELASTIC)
    
     material.ConstitutiveModel.MohrCoulomb.LinearIsotropicStiffness.setProperties(
     PoissonsRatio=row["Poissons Ratio"],
     YoungsModulus=row["Young's Modulus (kPa)"]
     )
    

5.3 Set Liner Properties

There are four liners pre-defined in the model, each with a thickness of 0.1 m. However, in the tunnel section used in this tutorial, the liner thickness needs to be increased to 0.17 m. Young's modulus is set to 21 GPa (21e6 kPa) A for loop can be used to retrieve all liners currently defined in the model and update their properties simultaneously.

liners = model.getAllLinerPropertiesInUse()
for liner in liners:
 liner.Standard.setThickness(0.17)
 liner.Standard.setYoungsModulus(21e6)

6.0 Automate Sequential Excavation

This section demonstrates methods to assign material properties to external volumes

Excavating (assigning "No Material") and applying material properties to the volumetric entities are conducted through a same set of action

6.1 Introduction to Selection Module

The function model.Selection.getExternalVolumes() provides a powerful way to select external volumes directly through scripting. It returns a set of references to volumetric entities in the same manner as selecting those volumes from the graphical user interface. The references are obtained based on volume entities intersecting with a specified coordinate point, a polyline, or a bounding region such as a cube, cylinder, or sphere. Once the external volume entities are selected, their names, assigned material properties, and roles can be modified programmatically.
This approach offers several advantages over the traditional workflow. Normally, volumetric entities must be selected manually in the view port or accessed through their predefined names in visibility panes. In complex models with a large list of geometric entities, locating and selecting the correct geometry can be time-consuming and error-prone. By selecting geometry based on spatial queries, scripts can automatically identify the relevant volumes without requiring prior knowledge of their names or manual interaction with the UI. This makes the process particularly useful for large or complex geometries, where manual selection would be difficult. As a result, scripting-based selection significantly improves modeling efficiency, reproducibility, and automation during model creation.

6.2 Select by Point - Grouting

In this section, grouting material is applied to the volumes selected as shown using scripting

Grouting selected

  1. In this model, there are six slices of tunnel sections. A variable is created to store this number so that it can be reused later in the script.
    numOfSlices = 6
    
  2. To apply grouting for every two slices of tunnel before three-stage excavation, a for loop is used. Each slice is selected using a point located inside the slice. Three points are selected per slice to apply loop along the tunnel length
    Three points
  3. After the external volumes are selected, the entities are renamed, and the grouting material defined in Section 5.2.1 is assigned to them.
    currentStage = 2
    
    for sliceIndex in range(numOfSlices):
    
     # (Optional) To view the changes while modeling
     model.setActiveStage(currentStage)
    
     # each selection should get only one slice of external volume.
     y = 2.5 + sliceIndex * 5
     centralPoint = Point(0, y, 771.4)
     centralExternalVolume = model.Selection.getExternalVolumes(centralPoint)[0]
    
     # rename the slice
     centralExternalVolume.setName(f"Central Grouting {sliceIndex + 1}")
    
     # Change the current material to grouting
     centralExternalVolume.setAppliedMaterialProperty(currentStage, groutingName)
    
     leftPoint = Point(-11.25, y, 763.5)
     leftExternalVolume = model.Selection.getExternalVolumes(leftPoint)[0]
     leftExternalVolume.setName(f"Left Grouting {sliceIndex + 1}")
     leftExternalVolume.setAppliedMaterialProperty(currentStage, groutingName)
    
     rightPoint = Point(11.25, y, 763.5)
     rightExternalVolume = model.Selection.getExternalVolumes(rightPoint)[0]
     rightExternalVolume.setName(f"Right Grouting {sliceIndex + 1}")
     rightExternalVolume.setAppliedMaterialProperty(currentStage, groutingName)
    
     # After every two steps, set the currentStage to the next stage that sets grouting
     if sliceIndex % 2 == 1:
     currentStage += 2
    
    setAppliedMaterialProperty() requires both the stage number and the property name as inputs. Calling setActiveStage() is optional if only assigning properties. It can be used to switch stages and visualize the modeling process, but skipping rendering can reduce modeling time during automation.

6.3 Select by Cube - Upper Zone Excavation Sequence

There are two external volumes involved in the first excavation step. Defining a bounding region for selection can be useful when the region contains multiple small pieces of geometry. By default, any volume that intersects with the bounding region is selected. If you only want to select volumes completely inside the bounding region, the parameter includeIntersecting can be set to False. In this example, the default setting (includeIntersecting = True) is used

upper zone cube

To excavate material in RS3, the material assigned to the volume must be set to "No Material", which is the predefined name used in the RS3 Modeler.
noMaterial = "No Material"

currentStage = 3
for sliceIndex in range(numOfSlices):
 # (Optional) To view the changes while modeling
 model.setActiveStage(currentStage)
 
 # each selection should get only one slice of external volume.
 cube = Cube(Point(-4, 2 + sliceIndex * 5, 768), Point(4, 3 + sliceIndex * 5, 762))
 externalVolumes = model.Selection.getExternalVolumes(cube)
 
 for externalVolumeIndex in range(len(externalVolumes)): 
 # rename the slice
 externalVolumes[externalVolumeIndex].setName(f"Tunnel {sliceIndex + 1}-1-{externalVolumeIndex + 1}")
 
 # Change the current material to no material
 externalVolumes[externalVolumeIndex].setAppliedMaterialProperty(currentStage, noMaterial)

 # Moving one slice further
 currentStage += 1

6.4 Select by Polyline - Lower Zone Excavation Sequence

The second excavation step has an irregular tunnel shape, making it difficult to select all volumes using simple bounding regions such as cubes, cylinders, or spheres. In this case, selecting volumes by points or by polyline is more convenient. Here, a polyline selection method is used. This method is particularly useful when the region contains many small pieces, as any volume intersecting the polyline is selected.

Upper lower zone

currentStage = 4
for sliceIndex in range(numOfSlices):
 # (Optional) To view the changes while modeling
 model.setActiveStage(currentStage)
 
 # three slices will be selected by the polyline
 y = 2.5 + sliceIndex * 5
 polyline = Polyline([Point(-10.4, y, 764.25), Point(-10.15, y, 761.15), Point(0, y, 757), Point(10.15, y, 761.15), Point(10.4, y, 764.25)])
 externalVolumes = model.Selection.getExternalVolumes(polyline)
 
 for externalVolumeIndex in range(len(externalVolumes)): 
 # rename the slice
 externalVolumes[externalVolumeIndex].setName(f"Tunnel {sliceIndex + 1}-2-{externalVolumeIndex + 1}")
 
 # Change the current material to no material
 externalVolumes[externalVolumeIndex].setAppliedMaterialProperty(currentStage, noMaterial)

 # Moving one slice further
 currentStage += 1

Similarly, the third excavation step can also be performed using the polyline selection method.

lower lower zone

currentStage = 5
for sliceIndex in range(numOfSlices):
 # (Optional) To view the changes while modeling
 model.setActiveStage(currentStage)
 
 # three slices will be selected by the polyline
 y = 2.5 + sliceIndex * 5
 polyline = Polyline([Point(-10.35, y, 759.5), Point(-8.5, y, 757.5), Point(0, y, 755), Point(8.5, y, 757.5), Point(10.35, y, 759.5)])
 externalVolumes = model.Selection.getExternalVolumes(polyline)
 
 for externalVolumeIndex in range(len(externalVolumes)): 
 # rename the slice
 externalVolumes[externalVolumeIndex].setName(f"Tunnel {sliceIndex + 1}-3-{externalVolumeIndex + 1}")
 
 # Change the current material to no material
 externalVolumes[externalVolumeIndex].setAppliedMaterialProperty(currentStage, noMaterial)

 # Moving one slice further
 currentStage += 1

Excavation Sequence


7.0 Set Field Stress

This model uses the gravity field stress method with K0 condition.

fieldStress = model.Loadings.FieldStress
fieldStress.setType(FieldStressType.GRAVITY)
fieldStress.Gravity.setK0Condition(True)

8.0 Mesh the Model

  1. Set the model with 4-Noded Tetrahedra Graded mesh.
    mesh = model.Mesh
    mesh.setElementType(MeshElementType.MESH_4_NODED_TETRAHEDRA)
    mesh.setMeshGradation(MeshGradation.GRADED)
    
  2. Mesh the model.
    mesh.mesh()
    

Meshed


9.0 Compute the Model

Before compute, save the model as a new model.

saveAsPath = rf"{currentFileFolderPath}\Scripting Tunnel Tutorial (Part 1) - Final.rs3v3"
model.saveAs(saveAsPath)
# open the new model
saveAsModel = modeler.openFile(saveAsPath)

Compute the model. After computation is complete, the convergence status will be printed. This status indicates whether the model has converged at each stage. Based on the convergence status, you can determine whether it is appropriate to query the results for the corresponding stages.

computeResults = saveAsModel.Compute.compute()

10.0 Save and Close the project

Once the modeling process is complete, the project can be closed. You must specify whether the changes should be saved before closing the project.

# Not saving changes to the initial model
model.close(False)
# Save changes to the current model
saveAsModel.close(True)

This concludes the Scripting Tunnel Tutorial (Part 1).

    Rocscience logo, click here to return to the homepage Portal Account Portal Account Portal Help Log In Log Out Home Shopping Cart icon Click here to search our site Click here to close Learning Tech Support RSInsight+ Logo Documentation Info Chevron Delete Back to Top View More" Previous Next Edit PDF File Calendar Location Language External Link Apply to ACC External Link Fees Video Click here to visit Rocscience's LinkedIn page Click here to visit Rocscience's YouTube page Click here to visit Rocscience's X page Click here to visit Rocscience's Facebook page Click here to visit Rocscience's Instagram page Click here to visit Rocscience's Reddit page Bookmark Network Scroll down for more Checkmark Download Print Back to top Single User Multiple Users RSLog RocFall3 CPillar Dips EX3 RocFall RocPlane RocSlope3 RocSupport RocTopple RS2 RS3 RSData RSPile RSWall RSSeismic Settle3 Slide2 Slide3 SWedge UnWedge RocTunnel3 RocSlope2 BlastMetrix ShapeMetriX FragMetriX TestLicense Commercial License Education License Trial License Shop safe & secure Money-back guarantee