Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ci/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ jobs:
set -ex
echo $(PAT) | docker login -u $(GH_USERNAME) --password-stdin docker.pkg.github.com
docker pull $(DPF_IMAGE)
docker run --restart always --name dpf -v `pwd`:/dpf -p $(DPF_PORT):50054 $(DPF_IMAGE) > log.txt &
docker run --restart always --name dpf -v `pwd`:/dpf -v /tmp:/dpf/_cache -p $(DPF_PORT):50054 $(DPF_IMAGE) > log.txt &
grep -q 'server started on ip' <(timeout 60 tail -f log.txt)
python -c "from ansys.dpf import core; core.connect_to_server(port=$(DPF_PORT)); print('Python Connected')"
displayName: Pull, launch, and validate DPF service
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
- name: Pull, launch, and validate DPF service
run: |
echo $PAT | docker login -u $GH_USERNAME --password-stdin docker.pkg.github.com
docker run --restart always --name dpf -v `pwd`:/dpf -p $DPF_PORT:50054 $DPF_IMAGE > log.txt &
docker run --restart always --name dpf -v `pwd`:/dpf -v /tmp:/dpf/_cache -p $DPF_PORT:50054 $DPF_IMAGE > log.txt &
grep -q 'server started on ip' <(timeout 60 tail -f log.txt)
python -c "import os; from ansys.dpf import core; core.connect_to_server(port=os.environ['DPF_PORT']); print('Python Connected')"
env:
Expand Down
9 changes: 4 additions & 5 deletions ansys/dpf/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@
if os.environ.get('DPF_DOCKER', False): # pragma: no cover
# Running DPF within docker (likely for CI)
# path must be relative to DPF directory
_module_path = os.path.dirname(inspect.getfile(inspect.currentframe()))
EXAMPLES_PATH = os.path.join(_module_path, 'examples', '_cache')
if not os.path.isdir(EXAMPLES_PATH):
os.makedirs(EXAMPLES_PATH)

#
# assumes the following docker mount:
# -v /tmp:/dpf/_cache
EXAMPLES_PATH = '/tmp'
else:
try:
import appdirs
Expand Down
2 changes: 1 addition & 1 deletion ansys/dpf/core/_version.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Version for ansys-dpf-core"""
# major, minor, patch
version_info = 0, 1, 2
version_info = 0, 2, 0

# Nice string for the version
__version__ = '.'.join(map(str, version_info))
2 changes: 1 addition & 1 deletion ansys/dpf/core/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def __getitem__(self, index):
if not self_len:
raise IndexError('This collection contains no items')
if index >= self_len:
raise IndexError(f'This collection contains only {self_len} entries')
raise IndexError(f'This collection contains only {self_len} entrie(s)')

return self._get_entries(index)

Expand Down
81 changes: 76 additions & 5 deletions ansys/dpf/core/examples/downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def _retrieve_file(url, filename, directory):
local_path = os.path.join(EXAMPLES_PATH, directory, os.path.basename(filename))
local_path_no_zip = local_path.replace('.zip', '')
if os.path.isfile(local_path_no_zip) or os.path.isdir(local_path_no_zip):
return local_path_no_zip, None
return local_path_no_zip

# grab the correct url retriever
urlretrieve = urllib.request.urlretrieve
Expand All @@ -44,13 +44,84 @@ def _download_file(directory, filename):
if os.environ.get('DPF_DOCKER', False): # pragma: no cover
# override path if running on docker as path must be relative
# to docker mount
local_path = os.path.join('/dpf/ansys/dpf/core/examples/_cache/', directory,
filename)
#
# Assumes the following mapping in docker
# DWN_CSH=/tmp/dpf_cache
# -v $DWN_CSH:/dpf/_cache
local_path = os.path.join('/dpf/_cache', directory, filename)
return local_path

###############################################################################
# front-facing downloads

def download_transient_result():
"""Download an example transient result and return the download path"""
def download_transient_result() -> str:
"""Download an example transient result file and return the download path.

Examples files are downloaded to a persistent cache to avoid
re-downloading the same file twice.

Returns
-------
str
Path to the example file.

Examples
--------
Download an example result file and return the path of the file

>>> from ansys.dpf.core import examples
>>> path = examples.transient_result
>>> path
'C:/Users/user/AppData/local/temp/transient.rst'

"""
return _download_file('transient', 'transient.rst')


def download_all_kinds_of_complexity() -> str:
"""Download an example static result and return the download path.

Examples files are downloaded to a persistent cache to avoid
re-downloading the same file twice.

Returns
-------
str
Path to the example file.

Examples
--------
Download an example result file and return the path of the file

>>> from ansys.dpf.core import examples
>>> path = examples.download_all_kinds_of_complexity
>>> path
'C:/Users/user/AppData/local/temp/allKindOfComplexity.rst'

"""
return _download_file('testing', 'allKindOfComplexity.rst')


def download_all_kinds_of_complexity_modal() -> str:
"""Download an example result file from a static modal analsys and
return the download path.

Examples files are downloaded to a persistent cache to avoid
re-downloading the same file twice.

Returns
-------
str
Path to the example file.

Examples
--------
Download an example result file and return the path of the file

>>> from ansys.dpf.core import examples
>>> path = examples.download_all_kinds_of_complexity_modal
>>> path
'C:/Users/user/AppData/local/temp/modal_allKindOfComplexity.rst'

"""
return _download_file('testing', 'modal_allKindOfComplexity.rst')
6 changes: 6 additions & 0 deletions ansys/dpf/core/examples/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@
# this files can be imported with from `ansys.dpf.core import examples`:
simple_bar = os.path.join(_module_path, 'ASimpleBar.rst')
static_rst = os.path.join(_module_path, 'static.rst')
complex_rst = os.path.join(_module_path, 'complex.rst')
multishells_rst = os.path.join(_module_path, 'model_with_ns.rst')
electric_therm = os.path.join(_module_path, 'rth', 'rth_electric.rth')
steady_therm = os.path.join(_module_path, 'rth', 'rth_steady.rth')
transient_therm = os.path.join(_module_path, 'rth', 'rth_transient.rth')
msup_transient = os.path.join(_module_path, 'msup_transient_plate1.rst')
Binary file added ansys/dpf/core/examples/model_with_ns.rst
Binary file not shown.
Binary file added ansys/dpf/core/examples/rth/rth_electric.rth
Binary file not shown.
Binary file added ansys/dpf/core/examples/rth/rth_steady.rth
Binary file not shown.
Binary file added ansys/dpf/core/examples/rth/rth_transient.rth
Binary file not shown.
36 changes: 24 additions & 12 deletions ansys/dpf/core/plotter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Dpf plotter class is contained in this module.
Allows to plot a mesh and a fields container
using pyvista."""
import tempfile

import pyvista as pv
import matplotlib.pyplot as pyplot
Expand Down Expand Up @@ -174,7 +175,11 @@ def plot_contour(self, field_or_fields_container, notebook=None,
break

# Merge field data into a single array
overall_data = np.full((len(mesh_location), component_count), np.nan)
if component_count > 1:
overall_data = np.full((len(mesh_location), component_count), np.nan)
else:
overall_data = np.full(len(mesh_location), np.nan)

for field in fields_container:
ind = mesh_location.map_scoping(field.scoping)
overall_data[ind] = field.data
Expand All @@ -194,31 +199,38 @@ def plot_contour(self, field_or_fields_container, notebook=None,
return plotter.show()

def _plot_contour_using_vtk_file(self, fields_container, notebook=None):
"""Plot the contour result on its mesh support. The obtained figure depends on the
support (can be a meshed_region or a time_freq_support).
If transient analysis, plot the last result.

This method is private, publishes a vtk file and print (using pyvista) from this file."""
"""Plot the contour result on its mesh support. The obtained
figure depends on the support (can be a meshed_region or a
time_freq_support). If transient analysis, plot the last
result.

This method is private. DPF publishes a vtk file and displays
this file using pyvista.
"""
plotter = pv.Plotter(notebook=notebook)
# mesh_provider = Operator("MeshProvider")
# mesh_provider.inputs.data_sources.connect(self._evaluator._model.metadata.data_sources)

# create a temporary file at the default temp directory
path = os.path.join(tempfile.gettempdir(), 'dpf_temp_hokflb2j9s.vtk')

vtk_export = dpf.core.Operator("vtk_export")
path = os.getcwd()
file_name = "dpf_temporary_hokflb2j9sjd0a3.vtk"
path += "/" + file_name
vtk_export.inputs.mesh.connect(self._mesh)
vtk_export.inputs.fields1.connect(fields_container)
vtk_export.inputs.file_path.connect(path)
vtk_export.run()
grid = pv.read(path)

if os.path.exists(path):
os.remove(path)

names = grid.array_names
field_name = fields_container[0].name
for n in names: #get new name (for example if time_steps)
for n in names: # get new name (for example if time_steps)
if field_name in n:
field_name = n #default: will plot the last time_step
field_name = n # default: will plot the last time_step
val = grid.get_array(field_name)
plotter.add_mesh(grid, scalars=val, stitle = field_name, show_edges=True)
plotter.add_mesh(grid, scalars=val, stitle=field_name, show_edges=True)
plotter.add_axes()
plotter.show()

2 changes: 1 addition & 1 deletion docker/run_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
# and 50054 for DPF_IP and DPF_PORT respectively.

source IMAGE_NAME
docker run -it --rm -v `pwd`/../:/dpf -p 50054:50054 --name dpf $IMAGE
docker run -it --rm -v `pwd`/../:/dpf -v /tmp:/dpf/_cache -p 50054:50054 --name dpf $IMAGE

1 change: 1 addition & 0 deletions ignore_words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pres
WAN
filname
ans
entrie
11 changes: 9 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
setup(
name='ansys-dpf-core',
packages=['ansys.dpf.core', 'ansys.dpf.core.examples'],
author='Camille Bellot, Ramdane Lagha',
version=__version__,

description='DPF Python gRPC client',
Expand All @@ -41,7 +40,15 @@
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
],
package_data={'ansys.dpf.core.examples': ['ASimpleBar.rst', 'static.rst']},
package_data={'ansys.dpf.core.examples': ['ASimpleBar.rst',
'static.rst',
'complex.rst',
'model_with_ns.rst',
'msup_transient_plate1.rst',
'rth/rth_electric.rth',
'rth/rth_steady.rth',
'rth/rth_transient.rth',
]},
python_requires='>=3.5.*',
install_requires=install_requires,
)
8 changes: 4 additions & 4 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def resolve_test_file(basename, additional_path=''):
@pytest.fixture()
def allkindofcomplexity():
"""Resolve the path of the "allKindOfComplexity.rst" result file."""
return resolve_test_file('allKindOfComplexity.rst')
return examples.download_all_kinds_of_complexity()


@pytest.fixture()
Expand Down Expand Up @@ -85,13 +85,13 @@ def simple_rst():
@pytest.fixture()
def multishells():
"""Resolve the path of the "rst_operators/multishells.rst" result file."""
return resolve_test_file('multishells.rst', 'rst_operators')
return examples.multishells_rst


@pytest.fixture()
def complex_model():
"""Resolve the path of the "complex/fileComplex.rst" result file."""
return resolve_test_file('fileComplex.rst', 'complex')
return examples.complex_rst


@pytest.fixture()
Expand All @@ -101,7 +101,7 @@ def plate_msup():
Originally:
UnitTestDataFiles/DataProcessing/expansion/msup/Transient/plate1/file.rst
"""
return resolve_test_file('plate1.rst', 'msup_transient')
return examples.msup_transient


@pytest.fixture(scope="session", autouse=True)
Expand Down
30 changes: 30 additions & 0 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Verify all examples can be accessed or downloaded"""
import pytest

from ansys.dpf.core import Model
from ansys.dpf.core import examples


def test_download_all_kinds_of_complexity_modal():
path = examples.download_all_kinds_of_complexity_modal()
assert isinstance(Model(path), Model)


def test_download_all_kinds_of_complexity():
path = examples.download_all_kinds_of_complexity()
assert isinstance(Model(path), Model)


@pytest.mark.parametrize("example", ['simple_bar',
'static_rst',
'complex_rst',
'multishells_rst',
'electric_therm',
'steady_therm',
'transient_therm',
'msup_transient'])
def test_examples(example):
# get example by string so we can parameterize it without breaking
# collection
path = getattr(globals()['examples'], example)
assert isinstance(Model(path), Model)
2 changes: 1 addition & 1 deletion tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ def test_kinetic(static_model):


def test_str_model(static_model):
assert 'Physics Type: Mecanic' in str(static_model)
assert '81 nodes' in str(static_model)
assert 'Unit: m' in str(static_model)
assert 'Physics Type: Mecanic' in str(static_model)


# @pytest.mark.skipif(NO_PLOTTING, reason="Requires system to support plotting")
Expand Down
14 changes: 13 additions & 1 deletion tests/test_plotter.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import unittest
import os

from pyvista.plotting.renderer import CameraPosition
import pytest
Expand All @@ -9,6 +9,9 @@
from ansys.dpf import core
from ansys.dpf.core import errors as dpf_errors

# currently running dpf on docker. Used for testing on CI
RUNNING_DOCKER = os.environ.get('DPF_DOCKER', False)


def test_chart_plotter(plate_msup):
model = Model(plate_msup)
Expand Down Expand Up @@ -209,3 +212,12 @@ def test_throw_complex_file(complex_model):
mesh = model.metadata.meshed_region
with pytest.raises(dpf_errors.ComplexPlottingError):
mesh.plot(fc)


@pytest.mark.skipif(RUNNING_DOCKER, reason='Path hidden within docker container')
def test_plot_contour_using_vtk_file(complex_model):
model = core.Model(complex_model)
stress = model.results.displacement()
fc = stress.outputs.fields_container()
pl = DpfPlotter(model.metadata.meshed_region)
pl._plot_contour_using_vtk_file(fc)
Binary file removed tests/testfiles/allKindOfComplexity.rst
Binary file not shown.