Laxis: Netstat - A Netstat - Ab
Laxis: Netstat - A Netstat - Ab
The Python wrapper for the PLAXIS HTTP REST API hides the technicalities of dealing
with the HTTP communications behind a comfortable object-oriented wrapper.
Prerequisites:
• An editor for writing Python scripts in. This documentation assumes that the SciTE
editor will be used that comes with the PLAXIS installation.
• At least a very rudimentary knowledge of the Python language is recommended, as
this document makes no attempt to teach it. Good resources for this purpose are:
• Dive Into Python 3 (http://www.diveintopython3.net/)
• After Hours Programming
(http://www.afterhoursprogramming.com/tutorial/Python/Overview/)
• Think Python: How to Think Like a Computer Scientist
(http://greenteapress.com/thinkpython/html/index.html)
• Your firewall must not block the PLAXIS application from accessing the internet, nor
must it block other applications (in particular the python.exe executable) from talking
to the remote scripting server embedded inside the PLAXIS application.
Hint: Note that when using Python and other modules, users must do so under the
licensing conditions of those modules.
» The user can check the Python version delivered by PLAXIS by launching
the interactive interpreter from Expert menu.
When using the remote scripting in an automated process, you can start the server
without manual interaction by launching your PLAXIS application with the AppServerPort
command line parameter. For example in order to start the server in PLAXIS 3D on port
21403:
c:\Program Files (x86)\Plaxis\PLAXIS 3D\Plaxis3DInput.exe
--AppServerPassword=mypassword --AppServerPort=21403
When the server is running, the main window of your PLAXIS application will reflect this
information:
• Start SciTE from the Windows Start menu. It will be called 'Python editor for PLAXIS
3D'. This will present you with an empty document. Let us write a script that will start
a new project.
• First we must import the scripting library:
from plxscripting.easy import *
• Connect to the PLAXIS application (21403 is the port number, substitute yours as
applicable):
s_i, g_i = new_server('localhost', 21403, password="yourpassword")
Save this script somewhere on your hard drive. Make sure it ends with .py so SciTE
correctly identifies it as a Python script. Now we are able to run this script by going
to Tools and then clicking on Go or by pressing F5.
• A new project should now be visible in the PLAXIS application. If instead an error is
returned, check the following for the PLAXIS application you are trying to control:
• Is the application running?
• Does its title bar indicate that the server is active?
• Is the server active on the port you have specified when calling new_server?
You can also try a different port.
• Is your firewall blocking communications to the application?
• Is the password given to new_server the same as the one in the 'configure
Connecting to a PLAXIS application running on a computer other than your own requires
you to know the name or IP address of that machine. The IP address can be found by
typing in a Windows command prompt the following:
ipconfig | find "IPv4"
The result will give a set of four numbers separated by dots. E.g.:
IPv4 Address. . . . . . . . . . . : 10.4.2.178
In order to connect to this machine from within the same network, you can simply replace
'localhost' in the boilerplate connection code with the IP address you found, such as
'10.4.2.178'. For example:
>>> s_i, g_i = new_server('10.4.2.178', 21403, password="yourpassword")
If you want to connect to the same machine over the internet, you will need to set up
appropriate port forwarding rules in your router. Note that opening up your computer to
access from the network or even the internet carries significant security risks - do so only
if you have considered these risks.
If there is a need to write codes that are usable under both programs PLAXIS 2D and
PLAXIS 3D, it is possible to check the type and version of PLAXIS software.
With sbeing a server-type object as returned by the new_server(...)method, the
following code must be valid:
>>> print(s.name, s.major_version, s.minor_version, s.is_2d, s.is_3d)
PLAXIS 2D 2018 0 True False
>>> if s.major_version + s.minor_version / 10 > 2020: # i.e. both are numbers
... print('We come from the future')
We come from the future
>>> from .const import PLAXIS_2D, PLAXIS_3D # later to be extended with MPM!
>>> if s.name == PLAXIS_2D:
... print('This is PLAXIS 2D')
... elif s.is_3d: # indicates whether the application is 2D or 3D *capable*
# (not whether it's the 2D or 3D *product*; 2D MPM will have is_2d=True!)
... print('This is 3D or 3D MPM')
... else:
... print('Unknown application!')
This is PLAXIS 2D
def get_number(msg):
nr = nan
while isnan(nr):
try:
nr = float(input(msg + ': '))
except:
pass
return nr
width = get_number('Width')
height = get_number('Height')
All commands that are available in the PLAXIS command line are also available via the
Python wrapper. For more information, see the commands reference provided with your
PLAXIS application. Note that private commands in the application (i.e. commands
starting with a double underscore, __) are spelled without the double underscore when
used from Python. Commands that conflict with Python keywords should be spelled with
an extra trailing underscore in Python (e.g. import becomes import_). Identifiers
containing characters that are not part of the ASCII character set will be stripped of those
characters (e.g. 0 C becomes C).
• Start the interactive interpreter from PLAXIS 3D as described above. Now execute
the code displayed below. For the sake of completeness, the replies returned by the
different statements are included, but some of them are session-specific and will be
different for you.
• It is helpful while executing the Python code to keep an eye on the command line in
the PLAXIS application, in order to gain an understanding of how Python code maps
to commands.
• Keep also in mind that Python, unlike the PLAXIS command line, is case sensitive.
>>> s_i.new()
'OK'
>>> g_i.SoilContour.initializerectangular(0, 0, 10, 10)
'OK'
>>> g_i.borehole(0, 0)
<Borehole {0F389B97-EF0B-48A7-ACC6-E9CC9D3ADE8E}>
>>> g_i.soillayer(10)
<BoreholeVolume {260BC1DD-76F8-4780-AED8-18A5C88D8AAF}>
>>> material = g_i.soilmat()
>>> material.setproperties("SoilModel", "Linear elastic", "gammaUnsat", 16,
"gammaSat", 20, "Gref", 10000)
'Edited SoilMat_1'
>>> g_i.Soils[0].Material = material
>>> g_i.gotostructures()
'OK'
>>> g_i.lineload((3, 5, 0), (7, 5, 0))
[<Point {C05BBBD3-2179-4D6D-844B-9C3E7CD44EC4}>,
<Point {F671BF99-1384-4BF5-81E8-DB1315414820}>,
<Line {A81EAC2D-8E8F-4A64-8ACB-8F3C72C47D8E}>,
<LineLoad {231DBD97-9E3A-4247-AD30-C6DB982FFDAC}>]
>>> g_i.gotomesh()
'OK'
>>> g_i.mesh(0.2)
'Generated 161 elements, 340 nodes'
>>> output_port = g_i.selectmeshpoints()
>>> s_o, g_o = new_server('localhost', output_port, password="yourpassword")
>>> g_o.addcurvepoint('node', g_o.Soil_1_1, (5, 5, 0))
'Added Node_A (5.0000, 5.0000, 0.0000)'
>>> g_o.update()
'OK'
>>> g_i.gotostages()
'OK'
>>> phase1 = g_i.phase(g_i.Phases[0])
>>> g_i.LineLoads[0].Active[phase1] = True
>>> g_i.calculate()
'OK'
>>> output_port = g_i.view(phase1)
>>> s_o, g_o = new_server('localhost', output_port, password="yourpassword")
>>> utot = g_o.getcurveresults(g_o.CurvePoints.Nodes.value[0],
g_o.Phases[1], g_o.Soil.Utot)
>>> print(utot)
9.68897384455302E-5
>>> g_i.save(r'c:\data\scripting_sample')
'Project saved as: c:\\data\\scripting_sample.P3D'
• The command line history on the application side looks as follows (excluding the
commands sent to Output):
0001> initializerectangular SoilContour 0 0 10 10
0002> borehole 0 0
0003> soillayer 10
0004> soilmat
0005> setproperties SoilMat_1 "SoilModel" "Linear elastic" "gammaUnsat" 16
"gammaSat" 20 "Gref" 10000
0006> set Soil_1.Material SoilMat_1
0007> gotostructures
0008> lineload (3 5 0) (7 5 0)
0009> gotomesh
0010> mesh 0.2
0011> selectmeshpoints
0012> gotostages
0013> phase InitialPhase
0014> set LineLoad_1_1.Active Phase_1 True
0015> calculate
0016> view Phase_1
0017> save "c:\data\scripting_sample"
In the examples above, we have looked at possibilities for using the API interactively from
a Python prompt. While this is very useful for testing and finding out how things work,
most scripts will be saved so they can be run again without having to retype it.
• In the SciTE editor make a new text file by going to File > New or by pressing
Ctrl+N. After that, you can type the code, save and run it using Tools > Go. A
Python script equivalent to the interactive session presented above looks as follows:
from plxscripting.easy import *
g_i.gotostructures()
g_i.lineload((3, 5, 0), (7, 5, 0))
g_i.gotomesh()
g_i.mesh(0.2)
output_port = g_i.selectmeshpoints()
s_o, g_o = new_server('localhost', output_port, password="yourpassword")
g_o.addcurvepoint('node', g_o.Soil_1_1, (5, 5, 0))
g_o.update()
g_i.gotostages()
phase1 = g_i.phase(g_i.Phases[0])
g_i.LineLoads[0].Active[phase1] = True
g_i.calculate()
output_port = g_i.view(phase1)
s_o, g_o = new_server('localhost', output_port, password="yourpassword")
#In newer versions of the scripting layer it is possible to just write: g_o.CurvePoints.Nodes[0]
utot = g_o.getcurveresults(g_o.CurvePoints.Nodes.value[0], g_o.Phases[1], g_o.Soil.Utot)
print(utot)
g_i.save(r'c:\data\scripting_sample')
For some projects the overhead of updating the user interface may slow down the
execution of the script quite significantly. If you want maximum execution speed, launch
your PLAXIS application with the command parameter --NO_CONTROLLERS. For example:
Plaxis3DInput.exe --AppServerPort=21403 --NO_CONTROLLERS
The downside of this approach is that you will be unable to monitor progress or diagnose
problems visually. Instead, you will have to:
1. Stop the running script
2. Save the current project
3. Restart the application and open the saved project
By default the server object (typically referred to as s_i in these examples) implements a
caching system to reduce the number of calls by the script to the PLAXIS application,
thereby improving the overall performance of the system. It can be switched off using:
s_i.allow_caching = False
When the user want to install a third party package that is not already available in the
Python installation then you can do so by opening the command prompt from Python -
Expert - Command prompt or by selecting 'Console for PLAXIS 3D' from the PLAXIS
folder in the start menu. From there you can install new packages by either using conda
or pip.
For example, if you want to install the dropbox package you would type:
pip install dropbox
And if you want to install the cffi (C foreign function interface) package you would type:
conda install cffi
Note that not all packages that are available to pip are available to conda and some
complex packages such as numpy might be easier to install using conda than with pip.
Lastly installing new packages requires administrator rights on your PC.
While using Python scripts to manipulate the state of your PLAXIS application, it is
technically possible to interact with the same application in other ways as well (e.g. by
changing a project manually, or firing commands separately in an interpreter while the
main script is paused). This is very useful for troubleshooting.
In particular situations it may however lead to problems, in that internal data structures
built on the Python side have become obsolete due to actions outside of the script. The
main culprit is (re)opening a project while the script already has some internal
state/variables. Errors can look like this:
plxscripting.plx_scripting_exceptions.PlxScriptingError: Unsuccessful command:
GUID does not refer to object in registry: {F00F9FB0-B903-42BE-AE1F-
C7B8E200885D}
If you encounter such an error, simply stop the execution of your script and restart it.
Opening a project, removing all lines containing beams and saving again
s_i.open(r'c:\data\lines_with_beams.p3d')
lines = [b.Parent for b in g_i.Beams]
g_i.delete(*lines)
# alternatively (look at the difference in the command line):
# g_i.delete(lines)
g_i.save()
Reporting all points that are not used by lines and that have no features
points_in_lines = set()
for line in g_i.Lines[:]:
for point in line:
points_in_lines.add(point)
points = set(g_i.Points)
points_no_lines = points - points_in_lines
points_to_report = []
for p in points_no_lines:
if len(p.UserFeatures.value) == 0:
points_to_report.append(p)
for p in points_to_report:
print(p.Name)
g_i.pointload(diagonal_points)
def get_bottom_point(line):
first, second = line.First, line.Second
delta = second.z - first.z
if abs(delta) < 1E-4: # horizontal line
return None
if delta > 0: # Second point is higher -> move First down
return first
else: # First point is higher -> move Second down
return second
def lengthen_embedded_piles(extra_depth):
# start by selecting the lines which have embedded beams
pile_lines = [pile.Parent for pile in g_i.EmbeddedBeams[:]]
lengthen_embedded_piles(2.5)
Making all plates have identical settings for each phase in staged
construction
refplate = g_i.Plates[0]
otherplates = g_i.Plates[1:]
for phase in g_i.Phases:
if refplate.Active[phase] is None: # phase not yet initialized
continue
for otherplate in otherplates:
otherplate.Material[phase] = refplate.Material[phase]
otherplate.Active[phase] = refplate.Active[phase]
target_report.append(report_func(phase))
target_report.append('')
def phase_to_string(phase):
return "{} [{}]".format(phase.Identification, phase.Name)
def phase_to_string_with_error_code(phase):
return "{} [{}]. LogInfo: {}".format(
phase.Identification, phase.Name, phase.LogInfo)
def report_phases(phases_list):
successful_phases = []
failed_phases = []
uncalculated_phases = []
for phase in phases_list:
if phase.ShouldCalculate:
uncalculated_phases.append(phase)
elif phase.LogInfo == '0':
successful_phases.append(phase)
else:
failed_phases.append(phase)
report_lines = []
report_phases_by_kind(report_lines, successful_phases,
'Successful', phase_to_string)
report_phases_by_kind(report_lines, failed_phases,
'Failed', phase_to_string_with_error_code)
report_phases_by_kind(report_lines, uncalculated_phases,
'Skipped', phase_to_string)
return '\n'.join(report_lines)
def calculate_with_report():
phases_to_calculate = []
res = g_i.calculate()
report = [
'Title: {}'.format(g_i.Project.Title),
'Location: {}'.format(g_i.Project.Filename),
'',
report_phases(phases_to_calculate),
'',
'Command feedback:',
res]
return '\n'.join(report)
message = calculate_with_report()
# Run one command at a time and have the wrapper handle the response
# for you - not much extra control.
for command in commands:
print(s_i.call_and_handle_command(command))
# Run one command at a time and handle the response yourself. The
# response now consists of Python primitives representing the
# JSON communication rather than comfortable objects.
for command in commands:
print(s_i.call_commands(command))
s_i.new()
g_i.gotostructures()
# input parameters
nr_piles = 4 # must be > 1
total_angle_deg = 180 # over which to distribute the piles, must be > 0 and <= 360
pile_length = 10
pile_inclination_deg = 15
array_center = (5, 5, 0)
array_radius = 10
# calculations
def rel_coords_to_absolute(rel_coords, radius, offset):
coords = [radius * coord for coord in rel_coords]
return [p[0] + p[1] for p in zip(coords, offset)]
pile_inclination_rad = radians(pile_inclination_deg)
array_bottom_radius = array_radius + \
pile_length * sin(pile_inclination_rad)
array_bottom_center = (array_center[0], array_center[1],
array_center[2] - pile_length * cos(pile_inclination_rad))
pile_coords = []
for i in range(nr_piles):
angle = radians(total_angle_deg * i / (nr_piles - 1))
rel_coords = [cos(angle), sin(angle), 0]
top_coords = rel_coords_to_absolute(
rel_coords, array_radius, array_center)
bottom_coords = rel_coords_to_absolute(
rel_coords, array_bottom_radius, array_bottom_center)
pile_coords.append((top_coords, bottom_coords))
# Calling the view command while Input has a running server will also start
# Output with a server and return the port that the new server uses.
# The commands preview, view and viewmesh will behave similarly.
output_port = g_i.selectmeshpoints()
# Connect to the Output server the same way we connect to the Input one.
s_o, g_o = new_server('localhost', output_port, password="yourpassword")
# Select a history point and close Output with the update command.
g_o.addcurvepoint('node', g_o.Soil_1_1, 0, 0)
g_o.update()
last_phase = g_i.Phases[-1]
ux = g_i.getresults(last_phase, g_i.ResultTypes.Soil.Ux, 'node')
uy = g_i.getresults(last_phase, g_i.ResultTypes.Soil.Uy, 'node')
print(displacement_angles)
newest_plot = g_o.Plots[-1]
newest_plot.ResultType = g_o.ResultTypes.Soil.Utot
newest_plot.PlotType = 'shadings'
newest_plot.Phase = g_o.Phases[-1]
try:
from PIL import ImageFilter
pil_image = image_wrapper.image
new_image = pil_image.filter(ImageFilter.BLUR)
new_image.save("test.png")
except ImportError:
#Just save if we don't have Pillow
image_wrapper.save("test.png")
INPUT_SERVER_PORT = 10000
PLAXIS_PATH = r"C:\Program Files\Plaxis\PLAXIS 3D"
class SimpleProject(object):
"""
Class that provides a way to quickly setup a project for example purposes.
"""
def __init__(self, g_i):
from plxscripting.easy import new_server
self._new_server = new_server
def gather_results(self):
raise NotImplementedError("Override gather_results in subclass.")
def output_results(self):
raise NotImplementedError("Override output_results in subclass.")
def close_input(self):
self._input_process.kill()
@property
def g_i(self):
return self._g_i
def add_soil_layers(self):
raise NotImplementedError("Override add_soil_layers in subclass.")
def apply_soil_material(self):
SAND_PARAMETERS = [
('MaterialName', 'Sand'),
('Colour', 10676870),
('SoilModel', 3), # Hardening soil
('DrainageType', 'Drained'),
('gammaUnsat', 17),
('gammaSat', 20),
('E50ref', 43000),
('EoedRef', 28000),
('EurRef', 129000),
('powerm', 0.5),
('cref', 1),
('phi', 34.0),
('psi', 4.0),
('nu', 0.2),
('Rinter', 0.7),
('K0NC', 0.5),
('OCR', 1.0),
('POP', 0.0)
]
sand = self._g_i.soilmat(*SAND_PARAMETERS)
def add_structures(self):
pass # Not adding any plates is fine too.
def apply_plate_material(self):
DIAPHRAGM_WALL_PARAMETERS = [
('MaterialName', 'Wall'),
('Colour', 16711680),
('IsIsotropic', True),
('IsEndBearing', True),
('E1', 30000000),
('E2', 30000000),
('nu12', 0.15),
('d', 0.5),
('w', 15),
('G12', 13040000),
('G13', 13040000),
('G23', 13040000),
('RayleighAlpha', 0),
('RayleighBeta', 0)
]
diaphragm_wall_material = self._g_i.platemat(*DIAPHRAGM_WALL_PARAMETERS)
def mesh(self):
self._g_i.gotomesh()
self._g_i.mesh(0.4)
def select_curve_points(self):
pass # Not selecting any curve-points is fine too.
def configure_phases(self):
raise NotImplementedError("Override configure_phases in subclass.")
def make_project(self):
self._s_i.new()
self.add_soil_layers()
self.apply_soil_material()
self.add_structures()
self.apply_plate_material()
self.mesh()
self.select_curve_points()
self.configure_phases()
self._g_i.calculate()
def run(project_class):
# Replace with the path to your PLAXIS installation.
project = project_class(r"c:\Program Files (x86)\Plaxis\PLAXIS 3D")
project.make_project()
project.gather_results()
project.output_results()
project.close_input()
borehole = self._g_i.borehole(0,0)
self._g_i.soillayer(0)
self._g_i.setsoillayerlevel(borehole, 0, 30)
self._g_i.setsoillayerlevel(borehole, 1, 27)
self._g_i.soillayer(0)
self._g_i.setsoillayerlevel(borehole, 2, 15)
self._g_i.soillayer(0)
self._g_i.setsoillayerlevel(borehole, 3, 0)
borehole.Head = 23
def add_structures(self):
self._g_i.gotostructures()
self._g_i.plate(40, 0, 30, 40, 30, 30, 40, 30, 14, 40, 0, 14)
self._g_i.plate(60, 0, 30, 60, 30, 30, 60, 30, 14, 60, 0, 14)
def select_curve_points(self):
output_port = self._g_i.selectmeshpoints()
s_o, g_o = self._new_server('localhost', output_port, password="yourpassword")
g_o.addcurvepoint('node', 40, 0, 30)
g_o.update()
def configure_phases(self):
self._g_i.gotostages()
self._g_i.activate(self._g_i.SurfaceLoads, self._g_i.InitialPhase)
self._g_i.activate(self._g_i.Plates, self._g_i.InitialPhase)
self._g_i.activate(self._g_i.Interfaces, self._g_i.InitialPhase)
self._g_i.SoilPolygons[1], self._g_i.InitialPhase
surface_load = self._g_i.SurfaceLoads[0]
current_phase = self._g_i.InitialPhase
surface_load.sigz[current_phase] = 0.0
def gather_results(self):
output_port = self._g_i.view(self._g_i.InitialPhase)
s_o, g_o = self._new_server('localhost', output_port, password="yourpassword")
self._results = []
g_o.update()
def output_results(self):
# Prevent excess newlines.
if sys.version_info.major == 2:
file_kwargs = { 'mode': 'wb' }
else:
file_kwargs = { 'mode': 'w', 'newline': '' }
# By default the csv writers will separate values with a comma and the
# period will be used as the decimal separator.
# However, this might be problematic when trying to import a csv file
# on a system that uses comma as the decimal separator.
# In these cases do the following:
# - import the locale modules and call: locale.setlocale(locale.LC_ALL, '')
# - get the correct separator with: locale.localeconv()['decimal_point']
# - replace the period in the output results with the correct separator
# - use a different csv dialect (see Python docs) so the comma isn't used
# as the column separator.
with open("results.csv", **file_kwargs) as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=['phaseID', 'displacement'])
for row in self._results:
writer.writerow(row)
if __name__ == '__main__':
run(ExportCSVProject)
self._g_i.lineload(6, 0, 0, 6, 8, 0)
self._g_i.LineLoads[0].qz_start = -10
def configure_phases(self):
self._g_i.gotostages()
self._g_i.activate(self._g_i.Plates, self._g_i.InitialPhase)
next_phase = self._g_i.phase(self._g_i.InitialPhase)
self._g_i.activate(self._g_i.LineLoads, next_phase)
def gather_results(self):
width, height = 800, 600
output_port = self._g_i.view(self._g_i.InitialPhase)
s_o, g_o = self._new_server('localhost', output_port, password="yourpassword")
g_o.Plots[0].Phase = g_o.InitialPhase
self._initial_phase_image = g_o.Plots[0].export(width, height)
g_o.Plots[0].Phase = g_o.Phase_1
self._phase_1_image = g_o.Plots[0].export(width, height)
g_o.close()
def output_results(self):
# Get Pillow.Image objects.
inner_initial_image = self._initial_phase_image.image
inner_phase_1_image = self._phase_1_image.image
cropping_left = (0, 0,
inner_initial_image.width // 2, inner_initial_image.height)
left_image = inner_initial_image.crop(cropping_left)
cropping_right = (inner_phase_1_image.width // 2, 0,
inner_phase_1_image.width, inner_phase_1_image.height)
right_image = inner_phase_1_image.crop(cropping_right)
result_image = Image.new(
inner_initial_image.mode, inner_initial_image.size)
result_image.paste(left_image, cropping_left)
result_image.paste(right_image, cropping_right)
default_font = ImageFont.load_default()
drawing_context = ImageDraw.Draw(result_image)
initial_phase_ID = self._g_i.Phases[0].Identification.value
drawing_context.text((200, 160), initial_phase_ID,
font=default_font, fill=(0, 0, 0, 255))
phase_1_ID = self._g_i.Phases[1].Identification.value
after_text_size = default_font.getsize(phase_1_ID)
drawing_context.text((600 - after_text_size[0], 160),
phase_1_ID, font=default_font, fill=(0, 0, 0, 255))
result_image.save("plot_initial_vs_phase_1.png")
if __name__ == '__main__':
run(ExportPlotProject)
SAMPLE_COUNT = 16
class CrossSectionProject(SimpleProject):
def add_soil_layers(self):
self._g_i.borehole(0, 0)
self._g_i.soillayer(4)
def add_structures(self):
self._g_i.gotostructures()
self._g_i.surfload(5, 0, 0, 5, 8, 0, 7, 8, 0, 7, 0, 0)
def configure_phases(self):
self._g_i.gotostages()
self._g_i.activate(self._g_i.Plates, self._g_i.InitialPhase)
next_phase = self._g_i.phase(self._g_i.InitialPhase)
self._g_i.activate(self._g_i.SurfaceLoads, next_phase)
def gather_results(self):
start = (0.0, 4.0, 0.0)
end = (12.0, 4.0, 0.0)
output_port = self._g_i.view(self._g_i.Phases[-1])
s_o, g_o = self._new_server('localhost', output_port, password="yourpassword")
# Assumes that start and end contain floats, will not work correctly
# with integers in Python 2.
step = [(e - s) / (SAMPLE_COUNT - 1) for e, s in zip(end, start)]
self._results = []
for i in range(SAMPLE_COUNT):
position = (start[0] + i * step[0], start[1], start[2])
result_string = g_o.getsingleresult(g_o.Phases[-1],
g_o.ResultTypes.Soil.Utot, position)
# Check if position lies outside the mesh, it might make more sense
# to use 0 as the result for other result types.
if result_string == "not found":
raise Exception("Used getsingleresult for point outside mesh.")
self._results.append(float(result_string))
g_o.update()
def output_results(self):
pyplot.plot(range(len(self._results)), self._results, 'r')
pyplot.grid(True)
pyplot.show()
if __name__ == '__main__':
run(CrossSectionProject)