PLAXIS
PLAXIS has a Python API that is distributed in a Python installer. The API can be used to build-up PLAXIS models and process results, integrating the PLAXIS workflow within your VIKTOR app. For more information on the PLAXIS API, see the website.
A 'Bentley Geotechnical SELECT Entitlement' (previously 'PLAXIS-vip') license is required
To integrate PLAXIS in your application, the following is needed:
- A Plaxis worker
- A machine on which PLAXIS is installed (with the correct licensing)
Install Plaxis worker
Follow these steps to install the worker:
- Development
- Published App
-
Navigate to the "My Integrations" tab in your personal settings
-
Click "Add integration"
-
Follow the steps provided in the modal
3.1. Select Plaxis
3.2. Download the worker .msi (Microsoft Installer) and run it on the machine of choice
3.3. Copy the generated connection key and paste it when the installer asks for it. In the browser, you can now click Finish. Continue the installation in the installer wizard.
Connection KeyThe generated connection key should be copied immediately as VIKTOR will not preserve this data for security reasons.
-
In the installer wizard, select the Python executable of your choice, this can be your system Python, or the python.exe in a dedicated virtual environment
tipYour default Python environment can usually be found in
C:\Users\Username\AppData\Local\Programs\Python\Python31X\python.exe
If you cannot find it, try running the following command in your terminal
where python
-
Make sure to launch the worker once the installation is finished. If you closed the integration, you can restart it through the desktop shortcut.
You need to be an environment administrator in order to install a worker for a published app.
-
Navigate to the "Integrations" tab in the Administrator panel
-
Click "Add integration"
-
Follow the steps provided in the modal
3.1. Select Plaxis
3.2. Select the workspace(s) the integration should be available to
3.3. Download the worker .msi (Microsoft Installer) and run it on the machine of choice
3.4. Copy the generated connection key and paste it when the installer asks for it. In the browser, you can now click Finish and continue in the installer.
Connection KeyThe generated connection key should be copied immediately as VIKTOR will not preserve this data for security reasons.
-
In the installer wizard, select the Python executable of your choice, this can be your system Python, or the python.exe in a dedicated virtual environment
tipYour default Python environment can usually be found in
C:\Users\<Username>\AppData\Local\Programs\Python\Python31X\python.exe
.If you cannot find it, try running
where python
in your terminal. -
Make sure to launch the integration once the installation is finished. If you closed the integration, you can restart it through the desktop shortcut.
Set up the app
From within the VIKTOR app, the Python script is sent, via the plaxis worker, to the server. After the analysis, the worker sends back the specified
files to the app, after which the developer can process the results (visualize,
download, etc.). In the following code snippet two files are sent to the worker: run_plaxis.py
and input.json
.
For additional ideas on how to pass parameters to PLAXIS have a look at the
PLAXIS sample application.
import viktor as vkt
script = vkt.File.from_path(Path(__file__).parent / "run_plaxis.py")
files = [('input.json', vkt.File.from_data(b'{parameter_a: 1, parameter_b: 2}')]
analysis = vkt.plaxis.PlaxisAnalysis(
script=script, files=files, output_filenames=["output.txt"]
)
analysis.execute(timeout=300)
output_file = analysis.get_output_file("output.txt")
The file run_plaxis.py
and the other file represented as bytes is then sent to the Python distribution PLAXIS is set
to work with. You can specify which Python distribution PLAXIS should use,
in the "Using a custom Python distribution" section.
run_plaxis.py
The Python script that is sent to the worker should consist of the following parts:
- Starting of the PLAXIS remote scripting service
- Code to build-up the PLAXIS model and read-out the desired results
- Creation of output files in the working directory of the worker, to be returned to the app
- Close the PLAXIS application
Starting of the PLAXIS remote scripting service can be done as follows:
import subprocess, time
PLAXIS_PATH = r'C:\Program Files\Bentley\Geotechnical\PLAXIS 2D CONNECT Edition V20\\Plaxis2DXInput.exe' # Specify PLAXIS path on server.
PORT_I = 10000 # Define an input port number.
PORT_O = 10001 # Define an output port number.
PASSWORD = 'secret' # Define a password.
subprocess.Popen([PLAXIS_PATH, f'--AppServerPassword={PASSWORD}', f'--AppServerPort={PORT}']) # Start the PLAXIS remote scripting service.
time.sleep(30) # Wait for PLAXIS to boot before sending commands to the scripting service.
# Start the scripting server.
global g_i, s_i
s_i, g_i = new_server('localhost', PORT_I, password=PASSWORD)
s_o, g_o = new_server('localhost', PORT_O, password=PASSWORD)
# Execute code.
...
# Extract required data and write files to working directory.
...
# Close the application
g_o.close() # Close the output window
g_i.kill() # Close the input window
The resulting files can be very large. Consider sending back files to the app with only the relevant information, by filtering out unnecessary results, to reduce in size. An example can be found in the sample application
Testing
PlaxisAnalysis.execute
needs to be mocked within
the context of (automated) testing.
The viktor.testing
module provides the mock_PlaxisAnalysis
decorator that facilitate mocking of workers:
import unittest
import viktor as vkt
from viktor.testing import mock_PlaxisAnalysis
from app.my_entity_type.controller import MyEntityTypeController
class TestMyEntityTypeController(unittest.TestCase):
@mock_PlaxisAnalysis(get_output_file={
'result.xml': vkt.File.from_path('test_file.xml'), # <name>: <File>
'result.json': vkt.File.from_path('test_file.json'),
...
})
def test_analysis(self):
MyEntityTypeController().analysis()
For the decorator's input parameters the following holds:
- If a Sequence type is provided, the next entry is returned for each corresponding method call. When a call is performed on a depleted iterable, an Exception is raised.
- If a single object is provided, the object is returned each time the corresponding method is called (endlessly).
- If None is provided (default), a default File/BytesIO object (with empty content) is returned each time the corresponding method is called (endlessly).