diff --git a/.ci/run_vms.py b/.ci/run_vms.py new file mode 100644 index 0000000000..087513ff83 --- /dev/null +++ b/.ci/run_vms.py @@ -0,0 +1,14 @@ +"""Run some vm manuals""" +from ansys.mapdl.core import launch_mapdl +from ansys.mapdl.core.examples import vmfiles + +mapdl = launch_mapdl() + +vms = list(vmfiles.keys()) + +for i, vm in enumerate(vms[:2]): + mapdl.clear() + print(f"Running the vm {i}: {vm}") + output = mapdl.input(vmfiles[vm]) + print(f"Running the vm {i}: Successfully completed") +mapdl.exit() diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 24a9352d3c..2baf83e58e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,7 +54,8 @@ defaults: permissions: contents: write packages: read - + pull-requests: write + jobs: doc-style: @@ -263,7 +264,7 @@ jobs: run: cat log.txt build-test: - name: "Remote: Build and unit testing" + name: "Remote: Build & test" runs-on: ubuntu-latest if: github.ref != 'refs/heads/main' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' timeout-minutes: 35 @@ -458,7 +459,7 @@ jobs: if compgen -G './logs-${{ matrix.mapdl-version }}/*.out' > /dev/null ;then for f in ./logs-${{ matrix.mapdl-version }}/*.out; do echo "::group:: Output file $f" && cat $f && echo "::endgroup::" ; done; fi || echo "Failed to display the 'log' files." build-test-ubuntu: - name: "Local: Build and unit testing on Ubuntu" + name: "Local: Build & test on Ubuntu" runs-on: ubuntu-latest if: github.ref != 'refs/heads/main' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' timeout-minutes: 55 @@ -482,8 +483,6 @@ jobs: with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.ref }} - persist-credentials: false - fetch-depth: 0 - name: "Setup Python" @@ -581,10 +580,89 @@ jobs: with: name: ubuntu-v22.2.0-local.xml path: ./ubuntu-v22.2.0-local.xml + + - name: 'Upload minimal requirements file' + uses: actions/upload-artifact@v3 + with: + name: minimum_requirements.txt + path: ./minimum_requirements.txt + + build-test-ubuntu-minimal: + name: "Local: Build & test minimal package on Ubuntu" + runs-on: ubuntu-latest + if: github.ref != 'refs/heads/main' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + timeout-minutes: 55 + container: + image: ghcr.io/ansys/mapdl:v22.2-ubuntu + options: "-u=0:0 --entrypoint /bin/bash" + credentials: + username: ${{ secrets.GH_USERNAME }} + password: ${{ secrets.GITHUB_TOKEN }} + env: + ON_LOCAL: true + ON_UBUNTU: true + # Because there is no 'ansys-tools-path' we need to input the executable path. + PYMAPDL_MAPDL_EXEC: /ansys_inc/v222/ansys/bin/ansys222 + + steps: + - name: "Install Git and checkout project" + uses: actions/checkout@v4 + with: + repository: ${{ github.event.pull_request.head.repo.full_name }} + ref: ${{ github.event.pull_request.head.ref }} + + - name: "Setup Python" + uses: actions/setup-python@v4 + with: + python-version: ${{ env.MAIN_PYTHON_VERSION }} + + - name: "Checking Python" + run: | + python --version + python -m pip install --upgrade pip + + - name: "Install ansys-mapdl-core" + run: | + python -m pip install . --no-deps + python -m pip install -r minimum_requirements.txt + python -c "from ansys.mapdl import core as pymapdl; print('Import successfull')" + + - name: "Running some verification manual examples" + run: | + unset PYMAPDL_START_INSTANCE + export ANSYSLMD_LICENSE_FILE=1055@${{ secrets.LICENSE_SERVER }} + python .ci/run_vms.py + + - name: "Unit testing requirements installation" + run: | + python -m pip install pytest pytest-rerunfailures pytest-cov + + - name: "Unit testing" + run: | + unset PYMAPDL_START_INSTANCE + export ANSYSLMD_LICENSE_FILE=1055@${{ secrets.LICENSE_SERVER }} + pytest -k "not test_dpf" \ + ${{ env.PYTEST_ARGUMENTS }} \ + --skip-regression-check \ + --cov-report=xml:ubuntu-v22.2.0-local-minimal.xml + + - uses: codecov/codecov-action@v3 + name: "Upload coverage to Codecov" + with: + token: ${{ secrets.CODECOV_TOKEN }} + root_dir: ${{ github.workspace }} + name: ubuntu-v22.2.0-local-minimal.xml + flags: ubuntu,local,v22.2.0,minimal + + - name: 'Upload coverage artifacts' + uses: actions/upload-artifact@v3 + with: + name: ubuntu-v22.2.0-local-minimal.xml + path: ./ubuntu-v22.2.0-local-minimal.xml test-windows: if: github.repository == '' - name: "Local: Build and unit testing on Windows" + name: "Local: Build & test on Windows" runs-on: [self-hosted, Windows, pymapdl] timeout-minutes: 30 env: @@ -676,6 +754,7 @@ jobs: ./**/*.tar.gz ./**/*pymapdl-Documentation-*.pdf ./**/ansys-mapdl-core*.zip + ./minimum_requirements.txt - name: Upload to Public PyPi env: diff --git a/doc/source/getting_started/contribution.rst b/doc/source/getting_started/contribution.rst index 12f8e16438..922d822911 100644 --- a/doc/source/getting_started/contribution.rst +++ b/doc/source/getting_started/contribution.rst @@ -38,7 +38,7 @@ use these issue templates: * **🎓 Adding an example**: Proposing a new example for the library * **💡 New feature**: Enhancements to the code -If your issue does not fit into one of these categories, click on `Open a black issue `_. +If your issue does not fit into one of these categories, click on `Open a blank issue `_. Viewing PyMAPDL documentation diff --git a/minimum_requirements.txt b/minimum_requirements.txt new file mode 100644 index 0000000000..be7a8b7caa --- /dev/null +++ b/minimum_requirements.txt @@ -0,0 +1,6 @@ +ansys-api-mapdl==0.5.1 +importlib-metadata==6.8.0 +numpy==1.26.1 +platformdirs==3.11.0 +psutil==5.9.6 +pyansys-tools-versioning==0.5.0 diff --git a/src/ansys/mapdl/core/__init__.py b/src/ansys/mapdl/core/__init__.py index bea5894f70..67c2982687 100644 --- a/src/ansys/mapdl/core/__init__.py +++ b/src/ansys/mapdl/core/__init__.py @@ -73,14 +73,18 @@ __version__ = importlib_metadata.version(__name__.replace(".", "-")) - -from ansys.tools.path.path import ( - change_default_ansys_path, - find_ansys, - get_ansys_path, - get_available_ansys_installations, - save_ansys_path, -) +try: + from ansys.tools.path.path import ( + change_default_ansys_path, + find_ansys, + get_ansys_path, + get_available_ansys_installations, + save_ansys_path, + ) +except: + # We don't really use these imports in the library. They are here for + # convenience. + pass from ansys.mapdl.core._version import SUPPORTED_ANSYS_VERSIONS from ansys.mapdl.core.convert import convert_apdl_block, convert_script diff --git a/src/ansys/mapdl/core/convert.py b/src/ansys/mapdl/core/convert.py index 1385256e41..3a1f3d1f41 100644 --- a/src/ansys/mapdl/core/convert.py +++ b/src/ansys/mapdl/core/convert.py @@ -1203,176 +1203,83 @@ def find_match(self, cmd): return each -import click - - -@click.command() -@click.argument("filename_in") -@click.option("-o", default=None, help="Name of the output Python script.") -@click.option("--filename_out", default=None, help="Name of the output Python script.") -@click.option( - "--loglevel", - default=LOGLEVEL_DEFAULT, - help="Logging level of the ansys object within the script.", -) -@click.option( - "--auto_exit", - default=AUTO_EXIT_DEFAULT, - help="Adds a line to the end of the script to exit MAPDL. Default ``True``", -) -@click.option( - "--line_ending", - default=LINE_ENDING_DEFAULT, - help="When None, automatically is ``\n.``", -) -@click.option( - "--exec_file", - default=EXEC_FILE_DEFAULT, - help="Specify the location of the ANSYS executable and include it in the converter output ``launch_mapdl`` call.", -) -@click.option( - "--macros_as_functions", - default=MACROS_AS_FUNCTIONS_DEFAULT, - help="Attempt to convert MAPDL macros to python functions.", -) -@click.option( - "--use_function_names", - default=USE_FUNCTION_NAMES_DEFAULT, - help="Convert MAPDL functions to ansys.mapdl.core.Mapdl class methods. When ``True``, the MAPDL command ``K`` will be converted to ``mapdl.k``. When ``False``, it will be converted to ``mapdl.run('k')``.", -) -@click.option( - "--show_log", - default=SHOW_LOG_DEFAULT, - help="Print the converted commands using a logger (from ``logging`` Python module).", -) -@click.option( - "--add_imports", - default=ADD_IMPORTS_DEFAULT, - help='If ``True``, add the lines ``from ansys.mapdl.core import launch_mapdl`` and ``mapdl = launch_mapdl(loglevel="WARNING")`` to the beginning of the output file. This option is useful if you are planning to use the output script from another mapdl session. See examples section. This option overrides ``auto_exit``.', -) -@click.option( - "--comment_solve", - default=COMMENT_SOLVE_DEFAULT, - help='If ``True``, it will pythonically comment the lines that contain ``"SOLVE"`` or ``"/EOF"``.', -) -@click.option( - "--cleanup_output", - default=CLEANUP_OUTPUT_DEFAULT, - help="If ``True`` the output is formatted using ``autopep8`` before writing the file or returning the string. This requires ``autopep8`` to be installed.", -) -@click.option( - "--header", - default=HEADER_DEFAULT, - help="If ``True``, the default header is written in the first line of the output. If a string is provided, this string will be used as header.", -) -@click.option( - "--print_com", - default=PRINT_COM_DEFAULT, - help="Print command ``/COM`` arguments to python console. Defaults to ``True``.", -) -@click.option( - "--only_commands", - default=ONLY_COMMANDS_DEFAULT, - help="""converts only the commands, meaning that header - (``header=False``), imports (``add_imports=False``), - and exit commands are NOT included (``auto_exit=False``). - Overrides ``header``, ``add_imports`` and ``auto_exit``.""", -) -@click.option( - "--use_vtk", - default=USE_VTK_DEFAULT, - help="""It sets the `mapdl.use_vtk` argument equals True or False depending on - this value.""", -) -@click.option( - "--clear_at_start", - default=CLEAR_AT_START_DEFAULT, - help="""Add a `mapdl.clear()` after the Mapdl object initialization. Defaults to - `False`.""", -) -@click.option( - "--check_parameter_names", - default=CHECK_PARAMETER_NAMES_DEFAULT, - help="""Set MAPDL object to avoid parameter name checks (do not raise leading underscored parameter exceptions). Defaults to `True`.""", -) -def cli( - filename_in, - o, - filename_out, - loglevel, - auto_exit, - line_ending, - exec_file, - macros_as_functions, - use_function_names, - show_log, - add_imports, - comment_solve, - cleanup_output, - header, - print_com, - only_commands, - use_vtk, - clear_at_start, - check_parameter_names, -): - """PyMAPDL CLI tool for converting MAPDL scripts to PyMAPDL scripts. - - USAGE: - - This example demonstrates the main use of this tool: - - $ pymapdl_convert_script mapdl.dat -o python.py - - File mapdl.dat successfully converted to python.py. - - The output argument is optional, in which case the "py" extension is used: - - $ pymapdl_convert_script mapdl.dat - - File mapdl.dat successfully converted to mapdl.py. - - You can use any option from ``ansys.mapdl.core.convert.convert_script`` function: +try: + import click - $ pymapdl_convert_script mapdl.dat --auto-exit False + _HAS_CLICK = True +except ModuleNotFoundError: + _HAS_CLICK = False - File mapdl.dat successfully converted to mapdl.py. +if _HAS_CLICK: + # Loading CLI - $ pymapdl_convert_script.exe mapdl.dat --filename_out mapdl.out --add_imports False - - File mapdl.dat successfully converted to mapdl.out. - - - """ - if o: - filename_out = o - - # Parsing commands: - loglevel = _parse_cli_command(loglevel, LOGLEVEL_DEFAULT) - auto_exit = _parse_cli_command(auto_exit, AUTO_EXIT_DEFAULT) - line_ending = _parse_cli_command(line_ending, LINE_ENDING_DEFAULT) - exec_file = _parse_cli_command(exec_file, EXEC_FILE_DEFAULT) - macros_as_functions = _parse_cli_command( - macros_as_functions, MACROS_AS_FUNCTIONS_DEFAULT + @click.command() + @click.argument("filename_in") + @click.option("-o", default=None, help="Name of the output Python script.") + @click.option( + "--filename_out", default=None, help="Name of the output Python script." ) - use_function_names = _parse_cli_command( - use_function_names, USE_FUNCTION_NAMES_DEFAULT + @click.option( + "--loglevel", + default="WARNING", + help="Logging level of the ansys object within the script.", ) - show_log = _parse_cli_command(show_log, SHOW_LOG_DEFAULT) - add_imports = _parse_cli_command(add_imports, ADD_IMPORTS_DEFAULT) - comment_solve = _parse_cli_command(comment_solve, COMMENT_SOLVE_DEFAULT) - cleanup_output = _parse_cli_command(cleanup_output, CLEANUP_OUTPUT_DEFAULT) - header = _parse_cli_command(header, HEADER_DEFAULT) - print_com = _parse_cli_command(print_com, PRINT_COM_DEFAULT) - only_commands = _parse_cli_command(only_commands, ONLY_COMMANDS_DEFAULT) - use_vtk = _parse_cli_command(use_vtk, USE_VTK_DEFAULT) - clear_at_start = _parse_cli_command(clear_at_start, CLEAR_AT_START_DEFAULT) - check_parameter_names = _parse_cli_command( - check_parameter_names, CHECK_PARAMETER_NAMES_DEFAULT + @click.option( + "--auto_exit", + default=True, + help="Adds a line to the end of the script to exit MAPDL. Default ``True``", ) - - convert_script( + @click.option( + "--line_ending", default=None, help="When None, automatically is ``\n.``" + ) + @click.option( + "--exec_file", + default=None, + help="Specify the location of the ANSYS executable and include it in the converter output ``launch_mapdl`` call.", + ) + @click.option( + "--macros_as_functions", + default=True, + help="Attempt to convert MAPDL macros to python functions.", + ) + @click.option( + "--use_function_names", + default=True, + help="Convert MAPDL functions to ansys.mapdl.core.Mapdl class methods. When ``True``, the MAPDL command ``K`` will be converted to ``mapdl.k``. When ``False``, it will be converted to ``mapdl.run('k')``.", + ) + @click.option( + "--show_log", + default=False, + help="Print the converted commands using a logger (from ``logging`` Python module).", + ) + @click.option( + "--add_imports", + default=True, + help='If ``True``, add the lines ``from ansys.mapdl.core import launch_mapdl`` and ``mapdl = launch_mapdl(loglevel="WARNING")`` to the beginning of the output file. This option is useful if you are planning to use the output script from another mapdl session. See examples section. This option overrides ``auto_exit``.', + ) + @click.option( + "--comment_solve", + default=False, + help='If ``True``, it will pythonically comment the lines that contain ``"SOLVE"`` or ``"/EOF"``.', + ) + @click.option( + "--cleanup_output", + default=True, + help="If ``True`` the output is formatted using ``autopep8`` before writing the file or returning the string. This requires ``autopep8`` to be installed.", + ) + @click.option( + "--header", + default=True, + help="If ``True``, the default header is written in the first line of the output. If a string is provided, this string will be used as header.", + ) + @click.option( + "--print_com", + default=True, + help="Print command ``/COM`` arguments to python console. Defaults to ``True``.", + ) + def cli( filename_in, + o, filename_out, loglevel, auto_exit, @@ -1386,29 +1293,63 @@ def cli( cleanup_output, header, print_com, - only_commands, - use_vtk, - clear_at_start, - check_parameter_names, - ) + ): + """PyMAPDL CLI tool for converting MAPDL scripts to PyMAPDL scripts. + + USAGE: + + This example demonstrates the main use of this tool: + + $ pymapdl_convert_script mapdl.dat -o python.py + + File mapdl.dat successfully converted to python.py. + + The output argument is optional, in which case the "py" extension is used: + + $ pymapdl_convert_script mapdl.dat + + File mapdl.dat successfully converted to mapdl.py. - if filename_out: - print(f"File {filename_in} successfully converted to {filename_out}.") - else: - print( - f"File {filename_in} successfully converted to {os.path.splitext(filename_in)[0] + '.py'}." + You can use any option from ``ansys.mapdl.core.convert.convert_script`` function: + + $ pymapdl_convert_script mapdl.dat --auto-exit False + + File mapdl.dat successfully converted to mapdl.py. + + $ pymapdl_convert_script.exe mapdl.dat --filename_out mapdl.out --add_imports False + + File mapdl.dat successfully converted to mapdl.out. + + + """ + if o: + filename_out = o + + convert_script( + filename_in, + filename_out, + loglevel, + auto_exit, + line_ending, + exec_file, + macros_as_functions, + use_function_names, + show_log, + add_imports, + comment_solve, + cleanup_output, + header, + print_com, ) + if filename_out: + print(f"File {filename_in} successfully converted to {filename_out}.") + else: + print( + f"File {filename_in} successfully converted to {os.path.splitext(filename_in)[0] + '.py'}." + ) -def _parse_cli_command(command, default=None): - if isinstance(command, bool): - return command - if command is None: - return +else: - if command.upper() == "TRUE": - return True - elif command.upper() == "FALSE": - return False - else: - return default + def cli(): + print("PyMAPDL CLI requires click to be installed.") diff --git a/src/ansys/mapdl/core/examples/downloads.py b/src/ansys/mapdl/core/examples/downloads.py index bdae6c01e8..8cf32be77f 100644 --- a/src/ansys/mapdl/core/examples/downloads.py +++ b/src/ansys/mapdl/core/examples/downloads.py @@ -6,7 +6,12 @@ import urllib.request import zipfile -import requests +try: + import requests + + _HAS_REQUESTS = True +except ModuleNotFoundError: + _HAS_REQUESTS = False from ansys.mapdl import core as pymapdl @@ -56,6 +61,9 @@ def _get_file_url(filename, directory=None): def _check_url_exist(url): + if not _HAS_REQUESTS: + raise ModuleNotFoundError("Examples module requires request module") + response = requests.get(url) if response.status_code == 200: return [True] diff --git a/src/ansys/mapdl/core/launcher.py b/src/ansys/mapdl/core/launcher.py index d68872e387..9a23856417 100644 --- a/src/ansys/mapdl/core/launcher.py +++ b/src/ansys/mapdl/core/launcher.py @@ -20,7 +20,12 @@ except ModuleNotFoundError: # pragma: no cover _HAS_PIM = False -from ansys.tools.path import find_ansys, get_ansys_path, version_from_path +try: + from ansys.tools.path import find_ansys, get_ansys_path, version_from_path + + _HAS_ATP = True +except ModuleNotFoundError: + _HAS_ATP = False from ansys.mapdl import core as pymapdl from ansys.mapdl.core import LOG @@ -413,8 +418,9 @@ def launch_grpc( raise IOError('Unable to write to ``run_location`` "%s"' % run_location) # verify version - if version_from_path("mapdl", exec_file) < 202: - raise VersionError("The MAPDL gRPC interface requires MAPDL 20.2 or later") + if _HAS_ATP: + if version_from_path("mapdl", exec_file) < 202: + raise VersionError("The MAPDL gRPC interface requires MAPDL 20.2 or later") # verify lock file does not exist check_lock_file(run_location, jobname, override) @@ -872,11 +878,23 @@ def _validate_MPI(add_sw, exec_path, force_intel=False): LOG.debug("Ubuntu system detected. Adding 'I_MPI_SHM_LMT' env var.") os.environ["I_MPI_SHM_LMT"] = "shm" - if ( - os.name == "nt" - and not force_intel - and (222 > version_from_path("mapdl", exec_path) >= 210) - ): + if _HAS_ATP: + condition = ( + os.name == "nt" + and not force_intel + and (222 > version_from_path("mapdl", exec_path) >= 210) + ) + else: + if os.name == "nt": + warnings.warn( + "Because 'ansys-tools-path' is not installed, PyMAPDL cannot check\n" + "if this Ansys version requires the MPI fix, so if you are on Windows,\n" + "the fix is applied by default.\n" + "Use 'force_intel=True' to not apply the fix." + ) + condition = os.name == "nt" and not force_intel + + if condition: # Workaround to fix a problem when launching ansys in 'dmp' mode in the # recent windows version and using VPN. # This is due to the intel compiler, and only affects versions between @@ -1516,6 +1534,11 @@ def launch_mapdl( exec_file = os.getenv("PYMAPDL_MAPDL_EXEC", None) if exec_file is None: + if not _HAS_ATP: + raise ModuleNotFoundError( + "If you don't have 'ansys-tools-path' library installed, you need to input the executable path ('exec_path')." + ) + LOG.debug("Using default executable.") # Load cached path exec_file = get_ansys_path(version=version) @@ -1559,8 +1582,11 @@ def launch_mapdl( # verify no lock file and the mode is valid check_lock_file(run_location, jobname, override) - mode = check_mode(mode, version_from_path("mapdl", exec_file)) - LOG.debug("Using mode %s", mode) + if _HAS_ATP: + mode = check_mode(mode, version_from_path("mapdl", exec_file)) + LOG.debug("Using mode %s", mode) + else: + mode = "grpc" # Setting SMP by default if student version is used. additional_switches = _force_smp_student_version(additional_switches, exec_file) @@ -1649,6 +1675,9 @@ def launch_mapdl( if run_location is None: mapdl._path = actual_run_location + # Setting launched property + mapdl._launched = True + except Exception as exception: # Failed to launch for some reason. Check if failure was due # to the license check @@ -1663,9 +1692,6 @@ def launch_mapdl( LOG.debug("Stopping license server check.") lic_check.is_connected = True - # Setting launched property - mapdl._launched = True - return mapdl diff --git a/src/ansys/mapdl/core/licensing.py b/src/ansys/mapdl/core/licensing.py index 1fb4916123..3a540d3347 100644 --- a/src/ansys/mapdl/core/licensing.py +++ b/src/ansys/mapdl/core/licensing.py @@ -9,6 +9,15 @@ from ansys.mapdl.core.errors import LicenseServerConnectionError from ansys.mapdl.core.misc import threaded_daemon +try: + from ansys.tools.path import get_ansys_path, version_from_path + + _HAS_ATP = True + +except ModuleNotFoundError: + _HAS_ATP = False + + LOCALHOST = "127.0.0.1" LIC_PATH_ENVAR = "ANSYSLIC_DIR" LIC_FILE_ENVAR = "ANSYSLMD_LICENSE_FILE" @@ -121,7 +130,7 @@ def start(self, license_file=True, checkout_license=False): disabled. """ - if license_file: + if license_file and _HAS_ATP: self._lic_file_thread = self.check_license_file() if checkout_license: self._checkout_thread = self.checkout_license() @@ -464,8 +473,6 @@ def get_ansys_license_debug_file_name(): # pragma: no cover # - For version 22.1 and above: `licdebug.$hostname.$appname.$version.out` # - For version 21.2 and below: `licdebug.$appname.$version.out` - from ansys.mapdl.core.launcher import get_ansys_path, version_from_path - name = "licdebug" hostname = socket.gethostname() appname = APP_NAME diff --git a/src/ansys/mapdl/core/mapdl.py b/src/ansys/mapdl/core/mapdl.py index a7362c2721..1a526b2aaa 100644 --- a/src/ansys/mapdl/core/mapdl.py +++ b/src/ansys/mapdl/core/mapdl.py @@ -16,7 +16,6 @@ from warnings import warn import weakref -from matplotlib.colors import to_rgba import numpy as np from numpy.typing import DTypeLike, NDArray @@ -463,6 +462,10 @@ def wrap_xsel_function(func): def wrap_xsel_function_output(method): # Injecting doc string modification name = method.__func__.__name__.upper() + if not self.geometry: + # Cases where the geometry module is not loaded + return None + if name == "NSEL": return self.mesh.nnum elif name == "ESEL": @@ -995,7 +998,6 @@ def info(self): return self._info @property - @requires_package("pyvista", softerror=True) def geometry(self) -> "Geometry": """Geometry information. @@ -1041,15 +1043,17 @@ def geometry(self) -> "Geometry": def _create_geometry(self) -> Union["Geometry", "LegacyGeometry"]: """Return geometry cache""" - from ansys.mapdl.core.mapdl_geometry import Geometry, LegacyGeometry if self.legacy_geometry: + from ansys.mapdl.core.mapdl_geometry import LegacyGeometry + return LegacyGeometry else: + from ansys.mapdl.core.mapdl_geometry import Geometry + return Geometry(self) @property - @requires_package("pyvista", softerror=True) def mesh(self): """Mesh information. @@ -1096,7 +1100,6 @@ def mesh(self): return self._mesh @property - @requires_package("ansys.mapdl.reader", softerror=True) @supress_logging def _mesh(self) -> "Archive": """Write entire archive to ASCII and read it in as an @@ -1927,6 +1930,8 @@ def aplot( ) if vtk: + from matplotlib.colors import to_rgba + kwargs.setdefault("show_scalar_bar", False) kwargs.setdefault("title", "MAPDL Area Plot") kwargs.setdefault("scalar_bar_args", {"title": "Scalar Bar Title"}) @@ -2071,7 +2076,7 @@ def __enter__(self) -> None: self._parent()._log.debug("Entering in 'WithInterativePlotting' mode") if not self._parent()._has_matplotlib: # pragma: no cover - raise ImportError( + raise ModuleNotFoundError( "Install matplotlib to display plots from MAPDL ," "from Python. Otherwise, plot with vtk with:\n" "``vtk=True``" @@ -2109,7 +2114,7 @@ def _has_matplotlib(self): import matplotlib # noqa: F401 return True - except ImportError: + except ModuleNotFoundError: return False @property @@ -3390,10 +3395,15 @@ def run( if short_cmd in PLOT_COMMANDS: self._log.debug("It is a plot command.") plot_path = self._get_plot_name(text) + if save_fig: return self._download_plot(plot_path, save_fig) - else: + elif self._has_matplotlib: return self._display_plot(plot_path) + else: + self._log.debug( + "Since matplolib is not installed, images are not shown." + ) return self._response @@ -4129,7 +4139,7 @@ def mpwrite( lib="", mat="", download_file=False, - progress_bar=True, + progress_bar=False, **kwargs, ): fname_ = fname + "." + ext diff --git a/src/ansys/mapdl/core/mapdl_console.py b/src/ansys/mapdl/core/mapdl_console.py index 084d7df0a5..9d73dece14 100644 --- a/src/ansys/mapdl/core/mapdl_console.py +++ b/src/ansys/mapdl/core/mapdl_console.py @@ -7,9 +7,8 @@ import time from ansys.mapdl.core.errors import MapdlExitedError, MapdlRuntimeError - -# from ansys.mapdl.core.misc import kill_process from ansys.mapdl.core.mapdl import _MapdlCore +from ansys.mapdl.core.misc import requires_package ready_items = [ rb"BEGIN:", @@ -200,6 +199,54 @@ def _run(self, command, **kwargs): # return last response and all preceding responses return full_response + @property + @requires_package("ansys.mapdl.reader", softerror=True) + @requires_package("pyvista", softerror=True) + def mesh(self): + """Mesh information. + + Returns + ------- + :class:`Mapdl.Mesh ` + + Examples + -------- + Return an array of the active nodes + + >>> mapdl.mesh.nodes + array([[ 1., 0., 0.], + [ 2., 0., 0.], + [ 3., 0., 0.], + [ 4., 0., 0.], + [ 5., 0., 0.], + [ 6., 0., 0.], + [ 7., 0., 0.], + [ 8., 0., 0.], + [ 9., 0., 0.], + [10., 0., 0.]]) + + Return an array of the node numbers of the active nodes + + >>> mapdl.mesh.nnum + array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=int32) + + Simply query and print the geometry + + >>> print(mapdl.mesh) + ANSYS Mapdl Mesh + Number of Nodes: 321 + Number of Elements: 40 + Number of Element Types: 1 + Number of Node Components: 2 + Number of Element Components: 2 + + Access the geometry as a VTK object + + >>> mapdl.mesh.grid + + """ + return self._mesh + def exit(self, close_log=True, timeout=3): """Exit MAPDL process. diff --git a/src/ansys/mapdl/core/mapdl_corba.py b/src/ansys/mapdl/core/mapdl_corba.py index e596421797..0f611419fe 100644 --- a/src/ansys/mapdl/core/mapdl_corba.py +++ b/src/ansys/mapdl/core/mapdl_corba.py @@ -10,7 +10,7 @@ from ansys.mapdl.core.errors import MapdlExitedError, MapdlRuntimeError from ansys.mapdl.core.mapdl import _MapdlCore -from ansys.mapdl.core.misc import random_string, threaded +from ansys.mapdl.core.misc import random_string, requires_package, threaded if sys.version_info[1] > 8: raise ImportError( @@ -220,6 +220,54 @@ def __init__( INSTANCES.append(weakref.ref(self)) self._corba_key = None + @property + @requires_package("ansys.mapdl.reader", softerror=True) + @requires_package("pyvista", softerror=True) + def mesh(self): + """Mesh information. + + Returns + ------- + :class:`Mapdl.Mesh ` + + Examples + -------- + Return an array of the active nodes + + >>> mapdl.mesh.nodes + array([[ 1., 0., 0.], + [ 2., 0., 0.], + [ 3., 0., 0.], + [ 4., 0., 0.], + [ 5., 0., 0.], + [ 6., 0., 0.], + [ 7., 0., 0.], + [ 8., 0., 0.], + [ 9., 0., 0.], + [10., 0., 0.]]) + + Return an array of the node numbers of the active nodes + + >>> mapdl.mesh.nnum + array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=int32) + + Simply query and print the geometry + + >>> print(mapdl.mesh) + ANSYS Mapdl Mesh + Number of Nodes: 321 + Number of Elements: 40 + Number of Element Types: 1 + Number of Node Components: 2 + Number of Element Components: 2 + + Access the geometry as a VTK object + + >>> mapdl.mesh.grid + + """ + return self._mesh + def _launch(self, start_parm, verbose): """Launch CORBA.""" corba_key, process = launch_corba(verbose=verbose, **start_parm) diff --git a/src/ansys/mapdl/core/mapdl_geometry.py b/src/ansys/mapdl/core/mapdl_geometry.py index 193a907344..2dbd4e44d9 100644 --- a/src/ansys/mapdl/core/mapdl_geometry.py +++ b/src/ansys/mapdl/core/mapdl_geometry.py @@ -5,7 +5,6 @@ import numpy as np from numpy.typing import NDArray -import pyvista as pv from ansys.mapdl.core import _HAS_PYVISTA, Mapdl from ansys.mapdl.core.errors import VersionError @@ -16,7 +15,7 @@ if TYPE_CHECKING: # pragma: no cover from pyiges import Iges -from ansys.mapdl.core.misc import run_as_prep7, supress_logging +from ansys.mapdl.core.misc import requires_package, run_as_prep7, supress_logging from ansys.mapdl.core.theme import MapdlTheme VALID_SELECTION_TYPE = ["S", "R", "A", "U"] @@ -56,28 +55,30 @@ """ -class Multiblock(pv.MultiBlock): - def __call__(self, *args, **kwargs): - raise VersionError(VERSION_ERROR) +if _HAS_PYVISTA: - @wraps(pv.MultiBlock.plot) - def plot(self, *args, **kwargs): - color = kwargs.pop("color", "white") - return super().plot(*args, color=color, theme=MapdlTheme(), **kwargs) + class Multiblock(pv.MultiBlock): + def __call__(self, *args, **kwargs): + raise VersionError(VERSION_ERROR) + @wraps(pv.MultiBlock.plot) + def plot(self, *args, **kwargs): + color = kwargs.pop("color", "white") + return super().plot(*args, color=color, theme=MapdlTheme(), **kwargs) -def merge_polydata(items: Iterable["pv.PolyData"]) -> "pv.PolyData": - """Merge list of polydata or unstructured grids""" + @requires_package("pyvista") + def merge_polydata(items: Iterable["pv.PolyData"]) -> "pv.PolyData": + """Merge list of polydata or unstructured grids""" - # lazy import here for faster module loading - from vtkmodules.vtkFiltersCore import vtkAppendPolyData + # lazy import here for faster module loading + from vtkmodules.vtkFiltersCore import vtkAppendPolyData - afilter = vtkAppendPolyData() - for item in items: - afilter.AddInputData(item) - afilter.Update() + afilter = vtkAppendPolyData() + for item in items: + afilter.AddInputData(item) + afilter.Update() - return pv.wrap(afilter.GetOutput()) + return pv.wrap(afilter.GetOutput()) def get_elements_per_area(resp: str) -> List[List[int]]: @@ -154,6 +155,7 @@ def __init__(self, mapdl: Mapdl): def _set_log_level(self, level: DEBUG_LEVELS) -> None: return self._mapdl.set_log_level(level) + @requires_package("pyiges") def _load_iges(self) -> "Iges": """Loads the iges file from MAPDL as a pyiges class""" # Lazy import here for speed and stability @@ -173,6 +175,7 @@ def _reset_cache(self) -> None: def __setitem__(self, key: Any, value: Any): raise NotImplementedError("This method has not been implemented yet") + @requires_package("pyvista") def __getitem__(self, name: str): name = name.lower() if "kp" in name: @@ -189,6 +192,7 @@ def __getitem__(self, name: str): ) @property + @requires_package("pyiges") def _keypoints(self) -> Tuple[NDArray, NDArray]: """Returns keypoints cache""" if self._keypoints_cache is None: @@ -196,7 +200,8 @@ def _keypoints(self) -> Tuple[NDArray, NDArray]: return self._keypoints_cache @property - def keypoints(self) -> pv.MultiBlock: + @requires_package("pyvista") + def keypoints(self) -> "pv.MultiBlock": """Obtain the keypoints geometry. Obtain the selected keypoints as a :class:`pyvista.MultiBlock` object. @@ -255,12 +260,13 @@ def keypoints(self) -> pv.MultiBlock: mb.set_block_name(index=ind, name=f"kp {mapdl_index}") return mb + @requires_package("pyvista") def get_keypoints( self, return_as_list: bool = False, return_as_array: bool = False, return_ids_in_array: bool = False, - ) -> Union[NDArray[Any], pv.PolyData, List[pv.PolyData]]: + ) -> Union[NDArray[Any], "pv.PolyData", List["pv.PolyData"]]: """Obtain the keypoints geometry. Obtain the selected keypoints as a :class:`pyvista.PolyData` object or @@ -356,14 +362,15 @@ def get_keypoints( return keypoints_pd @property - def _lines(self) -> List[pv.PolyData]: + def _lines(self) -> List["pv.PolyData"]: """Cache of the lines.""" if self._lines_cache is None: self._lines_cache = self._load_lines() return self._lines_cache @property - def lines(self) -> pv.MultiBlock: + @requires_package("pyvista") + def lines(self) -> "pv.MultiBlock": """Geometry of the lines. Obtain the selected lines as a :class:`pyvista.MultiBlock` object. @@ -435,9 +442,10 @@ def lines(self) -> pv.MultiBlock: mb.set_block_name(index=ind, name=f"line {mapdl_index}") return mb + @requires_package("pyvista") def get_lines( self, return_as_list: bool = False - ) -> Union[pv.PolyData, List[pv.PolyData]]: + ) -> Union["pv.PolyData", List["pv.PolyData"]]: """Obtain line geometry Obtain the active lines as a :class:`pyvista.PolyData` object or @@ -481,7 +489,8 @@ def get_lines( return merge_polydata(self._lines) @property - def areas(self) -> pv.MultiBlock: + @requires_package("pyvista") + def areas(self) -> "pv.MultiBlock": """Geometry of the areas. Obtain the selected areas as a :class:`pyvista.MultiBlock` object. @@ -550,9 +559,10 @@ def areas(self) -> pv.MultiBlock: mb.set_block_name(index=ind, name=f"area {mapdl_index}") return mb + @requires_package("pyvista") def get_areas( self, quality: int = 1, return_as_list: Optional[bool] = False - ) -> Union[List[pv.UnstructuredGrid], pv.PolyData]: + ) -> Union[List["pv.UnstructuredGrid"], "pv.PolyData"]: """Get active areas from MAPDL represented as :class:`pyvista.PolyData` or a list of :class:`pyvista.UnstructuredGrid`. Parameters @@ -627,13 +637,14 @@ def get_areas( @supress_logging @run_as_prep7 + @requires_package("pyvista") def generate_surface( self, density: int = 4, amin: Optional[int] = None, amax: Optional[int] = None, ninc: Optional[int] = None, - ) -> pv.PolyData: + ) -> "pv.PolyData": """ Generate an all-triangular surface of the active surfaces. @@ -854,7 +865,9 @@ def vnum(self) -> NDArray[np.int32]: return self._mapdl.get_array("VOLU", item1="VLIST").astype(np.int32) @supress_logging - def _load_lines(self) -> List[pv.PolyData]: + @requires_package("pyvista") + @requires_package("pyiges") + def _load_lines(self) -> List["pv.PolyData"]: """Load lines from MAPDL using IGES""" # ignore volumes with self._mapdl.save_selection: @@ -894,6 +907,7 @@ def _load_lines(self) -> List[pv.PolyData]: return lines_ + @requires_package("pyiges") def _load_keypoints(self) -> Tuple[NDArray, NDArray]: """Load keypoints from MAPDL using IGES.""" # write only keypoints @@ -1167,7 +1181,8 @@ def area_select( return self.anum @property - def volumes(self) -> pv.MultiBlock: + @requires_package("pyvista") + def volumes(self) -> "pv.MultiBlock": """Obtain the volumes geometry Obtain the selected volumes as a :class:`pyvista.MultiBlock` object. @@ -1238,9 +1253,10 @@ def volumes(self) -> pv.MultiBlock: mb.set_block_name(index=ind, name=f"volume {mapdl_index}") return mb + @requires_package("pyvista") def get_volumes( self, return_as_list: bool = False, quality: int = 4 - ) -> Union[List[pv.PolyData], pv.PolyData]: + ) -> Union[List["pv.PolyData"], "pv.PolyData"]: """Get active volumes from MAPDL represented as a :class:`pyvista.PolyData` object or a list of :class:`pyvista.UnstructuredGrid` objects. @@ -1490,13 +1506,15 @@ def keypoints(self) -> np.array: # type: ignore """Keypoint coordinates""" return super().get_keypoints(return_as_array=True) - def lines(self) -> pv.PolyData: + @requires_package("pyvista") + def lines(self) -> "pv.PolyData": """Active lines as a ``pyvista.PolyData`` object.""" return super().get_lines() # type: ignore + @requires_package("pyvista") def areas( self, quality=1, merge=False - ) -> Union[pv.PolyData, List[pv.UnstructuredGrid]]: + ) -> Union["pv.PolyData", List["pv.UnstructuredGrid"]]: """List of areas from MAPDL represented as a ``pyvista.PolyData`` object. Parameters diff --git a/src/ansys/mapdl/core/mapdl_grpc.py b/src/ansys/mapdl/core/mapdl_grpc.py index c9c119d2de..3cdf013779 100644 --- a/src/ansys/mapdl/core/mapdl_grpc.py +++ b/src/ansys/mapdl/core/mapdl_grpc.py @@ -49,7 +49,6 @@ parse_chunks, ) from ansys.mapdl.core.errors import ( - DifferentSessionConnectionError, MapdlConnectionError, MapdlExitedError, MapdlRuntimeError, @@ -61,7 +60,6 @@ check_valid_ip, last_created, random_string, - requires_package, run_as_prep7, supress_logging, ) @@ -419,12 +417,9 @@ def __init__( # initialize mesh, post processing, and file explorer interfaces self._mesh_rep: Optional["MeshGrpc"] = None - try: - from ansys.mapdl.core.mesh_grpc import MeshGrpc + from ansys.mapdl.core.mesh_grpc import MeshGrpc - self._mesh_rep = MeshGrpc(self) - except ModuleNotFoundError: # pragma: no cover - self._mesh_rep = None + self._mesh_rep = MeshGrpc(self) # Run at connect self._run_at_connect() @@ -884,7 +879,6 @@ def _reset_cache(self): self._geometry._reset_cache() @property - @requires_package("pyvista") def _mesh(self): return self._mesh_rep @@ -2438,7 +2432,7 @@ def _download( ) @protect_grpc - def upload(self, file_name: str, progress_bar: bool = True) -> str: + def upload(self, file_name: str, progress_bar: bool = _HAS_TQDM) -> str: """Upload a file to the grpc instance file_name : str @@ -3347,9 +3341,6 @@ def _check_session_id(self): elif pymapdl.RUNNING_TESTS or self._strict_session_id_check: if pymapdl_session_id != self._mapdl_session_id: self._log.error("The session ids do not match") - raise DifferentSessionConnectionError( - f"Local MAPDL session ID '{pymapdl_session_id}' is different from MAPDL session ID '{self._mapdl_session_id}." - ) else: self._log.debug("The session ids match") diff --git a/src/ansys/mapdl/core/mesh_grpc.py b/src/ansys/mapdl/core/mesh_grpc.py index 7f1705005f..95dc61565c 100644 --- a/src/ansys/mapdl/core/mesh_grpc.py +++ b/src/ansys/mapdl/core/mesh_grpc.py @@ -9,7 +9,7 @@ from ansys.mapdl.core.common_grpc import DEFAULT_CHUNKSIZE, parse_chunks from ansys.mapdl.core.mapdl_grpc import MapdlGrpc -from ansys.mapdl.core.misc import supress_logging, threaded +from ansys.mapdl.core.misc import requires_package, supress_logging, threaded TMP_NODE_CM = "__NODE__" @@ -711,6 +711,7 @@ def grid(self): return self._grid @property + @requires_package("pyvista") def _grid(self): if self._grid_cache is None: self._update_cache() diff --git a/src/ansys/mapdl/core/misc.py b/src/ansys/mapdl/core/misc.py index 29aa153e7f..c2fa1b0f2c 100644 --- a/src/ansys/mapdl/core/misc.py +++ b/src/ansys/mapdl/core/misc.py @@ -13,10 +13,17 @@ import sys import tempfile from threading import Thread +from typing import Union from warnings import warn import weakref -from ansys.tools.path import get_available_ansys_installations +try: + from ansys.tools.path import get_available_ansys_installations + + _HAS_ATP = True +except ModuleNotFoundError: + _HAS_ATP = False + import numpy as np from ansys.mapdl import core as pymapdl @@ -197,14 +204,22 @@ def mapdl_info(self): # List installed Ansys lines = ["", "Ansys Environment Report", "-" * 79] lines = ["\n", "Ansys Installation", "******************"] - mapdl_install = get_available_ansys_installations() - if not mapdl_install: - lines.append("Unable to locate any Ansys installations") + if _HAS_ATP: + mapdl_install = get_available_ansys_installations() + + if not mapdl_install: + lines.append("Unable to locate any Ansys installations") + else: + lines.append("Version Location") + lines.append("------------------") + for key in sorted(mapdl_install.keys()): + lines.append(f"{abs(key)} {mapdl_install[key]}") else: - lines.append("Version Location") - lines.append("------------------") - for key in sorted(mapdl_install.keys()): - lines.append(f"{abs(key)} {mapdl_install[key]}") + mapdl_install = None + lines.append( + "Unable to locate any Ansys installations because 'ansys-tools-path is not installed." + ) + install_info = "\n".join(lines) env_info_lines = [ @@ -1066,7 +1081,7 @@ def _get_load_step_options(self): return self._get_between(init_, end_string) -def write_array(filename, array): +def write_array(filename: Union[str, bytes], array: np.ndarray): """ Write an array to a file. @@ -1080,6 +1095,8 @@ def write_array(filename, array): array : numpy.ndarray Array. """ + if isinstance(filename, bytes): + filename = filename.decode() np.savetxt(filename, array, fmt="%20.12f") diff --git a/src/ansys/mapdl/core/pool.py b/src/ansys/mapdl/core/pool.py index a155838892..4a3b51f87c 100755 --- a/src/ansys/mapdl/core/pool.py +++ b/src/ansys/mapdl/core/pool.py @@ -6,15 +6,26 @@ from typing import Any, Dict, List, Optional import warnings -from ansys.mapdl.core import LOG, get_ansys_path, launch_mapdl +from ansys.mapdl.core import LOG, launch_mapdl from ansys.mapdl.core.errors import MapdlRuntimeError, VersionError -from ansys.mapdl.core.launcher import MAPDL_DEFAULT_PORT, port_in_use, version_from_path +from ansys.mapdl.core.launcher import MAPDL_DEFAULT_PORT, port_in_use from ansys.mapdl.core.mapdl_grpc import _HAS_TQDM from ansys.mapdl.core.misc import create_temp_dir, threaded, threaded_daemon +try: + from ansys.tools.path import get_ansys_path, version_from_path + + _HAS_ATP = True +except ModuleNotFoundError: + _HAS_ATP = False + if _HAS_TQDM: from tqdm import tqdm + DEFAULT_PROGRESS_BAR = True +else: + DEFAULT_PROGRESS_BAR = False + def available_ports(n_ports: int, starting_port: int = MAPDL_DEFAULT_PORT) -> List[int]: """Return a list the first ``n_ports`` ports starting from ``starting_port``.""" @@ -122,7 +133,7 @@ def __init__( wait: bool = True, run_location: Optional[str] = None, port: int = MAPDL_DEFAULT_PORT, - progress_bar: bool = True, + progress_bar: bool = DEFAULT_PROGRESS_BAR, restart_failed: bool = True, remove_temp_files: bool = True, names: Optional[str] = None, @@ -159,7 +170,14 @@ def __init__( if "exec_file" in kwargs: exec_file = kwargs["exec_file"] else: # get default executable - exec_file = get_ansys_path() + if _HAS_ATP: + exec_file = get_ansys_path() + else: + raise ValueError( + "Please use 'exec_file' argument to specify the location of the ansys installation.\n" + "Alternatively, PyMAPDL can detect your ansys installation if you install 'ansys-tools-path' library." + ) + if exec_file is None: raise FileNotFoundError( "Invalid exec_file path or cannot load cached " @@ -167,8 +185,9 @@ def __init__( "exec_file=" ) - if version_from_path("mapdl", exec_file) < 211: - raise VersionError("LocalMapdlPool requires MAPDL 2021R1 or later.") + if _HAS_ATP: + if version_from_path("mapdl", exec_file) < 211: + raise VersionError("LocalMapdlPool requires MAPDL 2021R1 or later.") # grab available ports ports = available_ports(n_instances, port) @@ -245,7 +264,7 @@ def map( self, func, iterable=None, - progress_bar=True, + progress_bar=DEFAULT_PROGRESS_BAR, close_when_finished=False, timeout=None, wait=True, @@ -439,7 +458,7 @@ def run_batch( self, files, clear_at_start=True, - progress_bar=True, + progress_bar=DEFAULT_PROGRESS_BAR, close_when_finished=False, timeout=None, wait=True, diff --git a/src/ansys/mapdl/core/theme.py b/src/ansys/mapdl/core/theme.py index f1c0f252df..e9c019b1ff 100644 --- a/src/ansys/mapdl/core/theme.py +++ b/src/ansys/mapdl/core/theme.py @@ -1,7 +1,15 @@ """Store parameters for a PyMAPDL-specific theme for pyvista""" -from matplotlib.colors import ListedColormap + import numpy as np +try: + from matplotlib.colors import ListedColormap + + _HAS_MATPLOTLIB = True +except ModuleNotFoundError: + _HAS_MATPLOTLIB = False + + from ansys.mapdl.core import _HAS_PYVISTA if _HAS_PYVISTA: @@ -46,10 +54,15 @@ class myEmptyClass: / 255 ) -PyMAPDL_cmap: ListedColormap = ListedColormap(MAPDL_colorbar, name="PyMAPDL", N=255) +if _HAS_MATPLOTLIB: + PyMAPDL_cmap: ListedColormap = ListedColormap(MAPDL_colorbar, name="PyMAPDL", N=255) def get_ansys_colors(N=9): + if not _HAS_MATPLOTLIB: + raise ModuleNotFoundError( + "'matplotlib' package is needed for 'get_ansys_colors'." + ) return np.array([PyMAPDL_cmap(i) for i in range(N)]) @@ -93,21 +106,23 @@ def __init__(self): self.background = "paraview" self.interactive = True - self.cmap = PyMAPDL_cmap + if _HAS_MATPLOTLIB: + self.cmap = PyMAPDL_cmap + + self.font.size = 18 + self.font.title_size = 18 + self.font.label_size = 18 + self.font.color = "black" + + self.axes.x_color = "tomato" + self.axes.y_color = "seagreen" + self.axes.z_color = "blue" - self.font.size = 18 - self.font.title_size = 18 - self.font.label_size = 18 - self.font.color = "black" self.show_edges = False self.color = "lightblue" self.outline_color = "black" self.edge_color = "black" - self.axes.x_color = "tomato" - self.axes.y_color = "seagreen" - self.axes.z_color = "blue" - self.color_cycler = get_cycler(MAPDL_colorbar.tolist()) self.render_points_as_spheres = True diff --git a/src/ansys/mapdl/core/xpl.py b/src/ansys/mapdl/core/xpl.py index 5c305a0e15..273b9b4018 100644 --- a/src/ansys/mapdl/core/xpl.py +++ b/src/ansys/mapdl/core/xpl.py @@ -6,7 +6,6 @@ import weakref from ansys.api.mapdl.v0 import mapdl_pb2 -from ansys.math.core.math import AnsMath import numpy as np from .common_grpc import ANSYS_VALUE_TYPE @@ -420,6 +419,8 @@ def extract(self, recordname, sets="ALL", asarray=False): 1.20642736e-02, 2.58299321e-11, 9.14504940e-04]]) """ + from ansys.math.core.math import AnsMath + if recordname.upper() != "NSL": raise ValueError("Currently, the only supported recordname is 'NSL'") @@ -472,6 +473,8 @@ def read(self, recordname, asarray=False): array([ 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52, 55, 58, 1], dtype=int32) """ + from ansys.math.core.math import AnsMath + rand_name = id_generator() response = self._mapdl.run(f"*XPL,READ,{recordname},{rand_name}") self._check_ignored(response) diff --git a/tests/.image_cache/bc_plot_options[False-False-False].png b/tests/.image_cache/bc_plot_options[False-False-False].png index 996436574d..6cd9a7ba4d 100644 Binary files a/tests/.image_cache/bc_plot_options[False-False-False].png and b/tests/.image_cache/bc_plot_options[False-False-False].png differ diff --git a/tests/.image_cache/bc_plot_options[False-False-True].png b/tests/.image_cache/bc_plot_options[False-False-True].png index 996436574d..6cd9a7ba4d 100644 Binary files a/tests/.image_cache/bc_plot_options[False-False-True].png and b/tests/.image_cache/bc_plot_options[False-False-True].png differ diff --git a/tests/.image_cache/bc_plot_options[False-True-False].png b/tests/.image_cache/bc_plot_options[False-True-False].png index ae4246015d..e688ff10f2 100644 Binary files a/tests/.image_cache/bc_plot_options[False-True-False].png and b/tests/.image_cache/bc_plot_options[False-True-False].png differ diff --git a/tests/.image_cache/bc_plot_options[False-True-True].png b/tests/.image_cache/bc_plot_options[False-True-True].png index ae4246015d..e688ff10f2 100644 Binary files a/tests/.image_cache/bc_plot_options[False-True-True].png and b/tests/.image_cache/bc_plot_options[False-True-True].png differ diff --git a/tests/.image_cache/bc_plot_options[True-False-False].png b/tests/.image_cache/bc_plot_options[True-False-False].png index 491c8d3f1f..b3c5ad397e 100644 Binary files a/tests/.image_cache/bc_plot_options[True-False-False].png and b/tests/.image_cache/bc_plot_options[True-False-False].png differ diff --git a/tests/.image_cache/bc_plot_options[True-False-True].png b/tests/.image_cache/bc_plot_options[True-False-True].png index 491c8d3f1f..b3c5ad397e 100644 Binary files a/tests/.image_cache/bc_plot_options[True-False-True].png and b/tests/.image_cache/bc_plot_options[True-False-True].png differ diff --git a/tests/.image_cache/bc_plot_options[True-True-False].png b/tests/.image_cache/bc_plot_options[True-True-False].png index 55ef2b4e34..bf02eb639b 100644 Binary files a/tests/.image_cache/bc_plot_options[True-True-False].png and b/tests/.image_cache/bc_plot_options[True-True-False].png differ diff --git a/tests/.image_cache/bc_plot_options[True-True-True].png b/tests/.image_cache/bc_plot_options[True-True-True].png index 55ef2b4e34..bf02eb639b 100644 Binary files a/tests/.image_cache/bc_plot_options[True-True-True].png and b/tests/.image_cache/bc_plot_options[True-True-True].png differ diff --git a/tests/common.py b/tests/common.py index 91f102eded..a8d4102db3 100644 --- a/tests/common.py +++ b/tests/common.py @@ -3,8 +3,6 @@ import os from typing import Dict -from ansys.tools.path import find_mapdl - from ansys.mapdl.core.launcher import _is_ubuntu Node = namedtuple("Node", ["number", "x", "y", "z", "thx", "thy", "thz"]) @@ -35,6 +33,8 @@ def is_on_local(): os.environ.get("PYMAPDL_START_INSTANCE", "").lower() != "false" ) # default is false + from ansys.tools.path import find_mapdl + _, rver = find_mapdl() if rver: @@ -59,6 +59,19 @@ def is_on_ubuntu(): def has_grpc(): + envvar = os.environ.get("HAS_GRPC", None) + + if envvar is not None: + return envvar.lower().strip() == "true" + + if testing_minimal(): + return True + + try: + from ansys.tools.path import find_mapdl + except ModuleNotFoundError: + return True + _, rver = find_mapdl() if rver: @@ -76,6 +89,28 @@ def is_smp(): return os.environ.get("DISTRIBUTED_MODE", "smp").lower().strip() == "smp" +def support_plotting(): + envvar = os.environ.get("SUPPORT_PLOTTING", None) + + if envvar is not None: + return envvar.lower().strip() == "true" + + if testing_minimal(): + return False + + try: + import pyvista + + return pyvista.system_supports_plotting() + + except ModuleNotFoundError: + return False + + +def testing_minimal(): + return os.environ.get("TESTING_MINIMAL", "NO").upper().strip() in ["YES", "TRUE"] + + def is_float(s: str) -> bool: try: float(s) diff --git a/tests/conftest.py b/tests/conftest.py index 1316fb292c..364728c27f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,21 +1,12 @@ from collections import namedtuple +from importlib import import_module import os from pathlib import Path from sys import platform from _pytest.terminal import TerminalReporter # for terminal customization -from ansys.tools.path import get_available_ansys_installations import pytest -import pyvista -import ansys.mapdl.core as pymapdl - -pymapdl.RUNNING_TESTS = True - -from ansys.mapdl.core.errors import MapdlExitedError, MapdlRuntimeError -from ansys.mapdl.core.examples import vmfiles -from ansys.mapdl.core.launcher import get_start_instance, launch_mapdl -from ansys.mapdl.core.theme import _apply_default_theme from common import ( Element, Node, @@ -27,17 +18,17 @@ is_on_local, is_on_ubuntu, is_smp, + support_plotting, + testing_minimal, ) -_apply_default_theme() - ################################################################ # # Setting testing environment # --------------------------- # -# Necessary for CI plotting -pyvista.OFF_SCREEN = True + +TESTING_MINIMAL = testing_minimal() ON_LOCAL = is_on_local() ON_CI = is_on_ci() @@ -50,14 +41,11 @@ HAS_GRPC = has_grpc() HAS_DPF = has_dpf() -SUPPORT_PLOTTING = pyvista.system_supports_plotting() +SUPPORT_PLOTTING = support_plotting() IS_SMP = is_smp() QUICK_LAUNCH_SWITCHES = "-smp -m 100 -db 100" -# check if the user wants to permit pytest to start MAPDL -START_INSTANCE = get_start_instance() - ## Skip ifs skip_on_windows = pytest.mark.skipif(ON_WINDOWS, reason="Skip on Windows") skip_on_linux = pytest.mark.skipif(ON_LINUX, reason="Skip on Linux") @@ -86,6 +74,106 @@ reason="""Requires DPF.""", ) +requires_linux = pytest.mark.skipif(not ON_LINUX, reason="This test requires Linux") +requires_windows = pytest.mark.skipif( + not ON_WINDOWS, reason="This test requires Windows" +) +requires_on_cicd = pytest.mark.skipif( + not ON_CI, reason="This test requires to be on CICD" +) + + +def has_dependency(requirement): + try: + import_module(requirement) + return True + except ModuleNotFoundError: + return False + + +def requires(requirement: str): + """Check requirements""" + requirement = requirement.lower() + + if "grpc" == requirement: + return skip_if_no_has_grpc + + elif "dpf" == requirement: + return skip_if_no_has_dpf + + elif "local" == requirement: + return skip_if_not_local + + elif "cicd" == requirement: + return skip_if_on_cicd + + elif "nocicd" == requirement: + return skip_if_on_cicd + + elif "xserver" == requirement: + return skip_no_xserver + + elif "linux" == requirement: + return requires_linux + + elif "nolinux" == requirement: + return skip_on_linux + + elif "windows" == requirement: + return requires_windows + + elif "nowindows" == requirement: + return skip_on_windows + + elif "console" == requirement: + return pytest.mark.console + + elif "corba" == requirement: + return pytest.mark.corba + + else: + return requires_dependency(requirement) + + +def requires_dependency(dependency: str): + try: + import_module(dependency) + return pytest.mark.skipif( + False, reason="Never skip" + ) # faking a null skipif decorator + + except ModuleNotFoundError: + # package does not exist + return pytest.mark.skip(reason=f"Requires '{dependency}' package") + + +################ + +if has_dependency("ansys-tools-package"): + from ansys.tools.path import get_available_ansys_installations + + +if has_dependency("pyvista"): + import pyvista + + from ansys.mapdl.core.theme import _apply_default_theme + + _apply_default_theme() + + # Necessary for CI plotting + pyvista.OFF_SCREEN = True + +import ansys.mapdl.core as pymapdl + +pymapdl.RUNNING_TESTS = True + +from ansys.mapdl.core.errors import MapdlExitedError, MapdlRuntimeError +from ansys.mapdl.core.examples import vmfiles +from ansys.mapdl.core.launcher import get_start_instance, launch_mapdl + +# check if the user wants to permit pytest to start MAPDL +START_INSTANCE = get_start_instance() + ################ if os.name == "nt": os_msg = """SET PYMAPDL_START_INSTANCE=False @@ -107,6 +195,7 @@ alexander.kaszynski@ansys.com """ +MAPDL_VERSION = None # this is cached by mapdl fixture and used in the minimal testing if START_INSTANCE and not ON_LOCAL: raise MapdlRuntimeError(ERRMSG) @@ -209,24 +298,25 @@ def pytest_collection_modifyitems(config, items): # --------------------------- # +if has_dependency("pytest-pyvista"): -@pytest.fixture(autouse=True) -def wrapped_verify_image_cache(verify_image_cache, pytestconfig): - # Checking if we want to avoid the check using pytest cli. - skip_regression_check = pytestconfig.option.skip_regression_check - if skip_regression_check: - verify_image_cache.skip = True + @pytest.fixture(autouse=True) + def wrapped_verify_image_cache(verify_image_cache, pytestconfig): + # Checking if we want to avoid the check using pytest cli. + skip_regression_check = pytestconfig.option.skip_regression_check + if skip_regression_check: + verify_image_cache.skip = True - # Configuration - # default check - verify_image_cache.error_value = 500.0 - verify_image_cache.warning_value = 200.0 + # Configuration + # default check + verify_image_cache.error_value = 500.0 + verify_image_cache.warning_value = 200.0 - # High variance test - verify_image_cache.var_error_value = 1000.0 - verify_image_cache.var_warning_value = 1000.0 + # High variance test + verify_image_cache.var_error_value = 1000.0 + verify_image_cache.var_warning_value = 1000.0 - return verify_image_cache + return verify_image_cache class Running_test: @@ -276,6 +366,7 @@ def is_exited(mapdl): # Restoring the local configuration mapdl._local = local_ + mapdl.gopr() yield # this is where the testing happens # Teardown : fill with any logic you want @@ -374,6 +465,7 @@ def mapdl(request, tmpdir_factory): start_timeout=50, ) mapdl._show_matplotlib_figures = False # CI: don't show matplotlib figures + MAPDL_VERSION = mapdl.version # Caching version if ON_CI: mapdl._local = ON_LOCAL # CI: override for testing diff --git a/tests/test_commands.py b/tests/test_commands.py index 799261fd06..1e9ad4cfd8 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -14,15 +14,11 @@ StringWithLiteralRepr, ) from ansys.mapdl.core.examples import verif_files +from conftest import has_dependency, requires -try: +if has_dependency("pandas"): import pandas as pd - HAS_PANDAS = True - -except ModuleNotFoundError: - HAS_PANDAS = False - LIST_OF_INQUIRE_FUNCTIONS = [ "ndinqr", "elmiqr", @@ -570,7 +566,7 @@ def test_cmd_class_prnsol_short(): assert out_list assert isinstance(out_array, np.ndarray) and out_array.size != 0 - if HAS_PANDAS: + if has_dependency("pandas"): out_df = out.to_dataframe() assert isinstance(out_df, pd.DataFrame) and not out_df.empty @@ -631,7 +627,7 @@ def test_output_listing(mapdl, plastic_solve, func, args): assert isinstance(out_list, list) and out_list assert isinstance(out_array, np.ndarray) and out_array.size != 0 - if HAS_PANDAS: + if has_dependency("pandas"): out_df = out.to_dataframe() assert isinstance(out_df, pd.DataFrame) and not out_df.empty @@ -648,7 +644,7 @@ def test_bclist(mapdl, beam_solve, func): with pytest.raises(ValueError): out.to_array() - if HAS_PANDAS: + if has_dependency("pandas"): out_df = out.to_dataframe() assert isinstance(out_df, pd.DataFrame) and not out_df.empty @@ -679,6 +675,7 @@ def test_string_with_literal(): assert len(output.split()) == 2 +@requires("pandas") @pytest.mark.parametrize("output,last_element", [(set_list_0, 9), (set_list_1, 15)]) def test_magicwords(output, last_element): magicwords = ["SET"] diff --git a/tests/test_component.py b/tests/test_component.py index 83ae0d40c1..b76f3d7140 100644 --- a/tests/test_component.py +++ b/tests/test_component.py @@ -119,12 +119,7 @@ def test_contains_entities(mapdl, cube_geom_and_mesh, func, entity, selector, im func_ = getattr(mapdl, func) func_("S", vmin=1, vmax=imax) - if entity in ["nodes", "elem"]: - count = getattr(mapdl.mesh, selector) - else: - count = getattr(mapdl.geometry, selector) - - assert len(count) == imax + assert mapdl.get_value(entity[:4], 0, "count") == imax mapdl.cm("mycomp", entity) diff --git a/tests/test_console.py b/tests/test_console.py index 02ae2f8426..ee09169d52 100644 --- a/tests/test_console.py +++ b/tests/test_console.py @@ -6,17 +6,24 @@ import os import time -from ansys.mapdl.reader import examples +import pytest + +from conftest import has_dependency, requires + +# skip entire module unless --console is enabled +pytestmark = requires("console") + import numpy as np import pytest -import pyvista + +if has_dependency("pyvista"): + import pyvista + +if has_dependency("ansys-mapdl-reader"): + from ansys.mapdl.reader import examples from ansys.mapdl import core as pymapdl from ansys.mapdl.core.errors import MapdlRuntimeError -from conftest import skip_no_xserver - -# skip entire module unless --console is enabled -pytestmark = pytest.mark.console @pytest.fixture(scope="function") @@ -198,7 +205,7 @@ def test_invalid_area(mapdl_console): # mapdl_console.input('thisisnotafile') -@skip_no_xserver +@requires("xserver") def test_kplot(cleared, mapdl_console, tmpdir): with pytest.raises(MapdlRuntimeError): mapdl_console.kplot(vtk=True) @@ -216,7 +223,7 @@ def test_kplot(cleared, mapdl_console, tmpdir): mapdl_console.kplot(knum=True, vtk=False) # make sure legacy still works -@skip_no_xserver +@requires("xserver") def test_aplot(cleared, mapdl_console): k0 = mapdl_console.k("", 0, 0, 0) k1 = mapdl_console.k("", 1, 0, 0) @@ -237,7 +244,7 @@ def test_aplot(cleared, mapdl_console): mapdl_console.aplot(vtk=False) -@skip_no_xserver +@requires("xserver") @pytest.mark.parametrize("vtk", [True, False]) def test_vplot(cleared, mapdl_console, vtk): mapdl_console.block(0, 1, 0, 1, 0, 1) @@ -278,7 +285,7 @@ def test_lines(cleared, mapdl_console): assert mapdl_console.geometry.n_line == 4 -@skip_no_xserver +@requires("xserver") def test_lplot(cleared, mapdl_console, tmpdir): with pytest.raises(MapdlRuntimeError): mapdl_console.lplot(vtk=True) @@ -353,7 +360,7 @@ def test_enum(mapdl_console, make_block): @pytest.mark.parametrize("knum", [True, False]) -@skip_no_xserver +@requires("xserver") def test_nplot_vtk(cleared, mapdl_console, knum): with pytest.raises(MapdlRuntimeError): mapdl_console.nplot() @@ -364,7 +371,7 @@ def test_nplot_vtk(cleared, mapdl_console, knum): mapdl_console.nplot(vtk=True, knum=knum, background="w", color="k") -@skip_no_xserver +@requires("xserver") def test_nplot(cleared, mapdl_console): mapdl_console.n(1, 0, 0, 0) mapdl_console.n(11, 10, 0, 0) @@ -483,7 +490,7 @@ def test_eplot_fail(mapdl_console): mapdl_console.eplot() -@skip_no_xserver +@requires("xserver") def test_eplot(mapdl_console, make_block): init_elem = mapdl_console.mesh.n_elem mapdl_console.aplot() # check aplot and verify it doesn't mess up the element plotting @@ -492,7 +499,7 @@ def test_eplot(mapdl_console, make_block): assert mapdl_console.mesh.n_elem == init_elem -@skip_no_xserver +@requires("xserver") def test_eplot_screenshot(mapdl_console, make_block, tmpdir): filename = str(tmpdir.mkdir("tmpdir").join("tmp.png")) mapdl_console.eplot( diff --git a/tests/test_convert.py b/tests/test_convert.py index 6f088cdeda..c9947bec14 100644 --- a/tests/test_convert.py +++ b/tests/test_convert.py @@ -9,6 +9,7 @@ FileTranslator, convert_apdl_block, ) +from conftest import requires nblock = """nblock,3,,326253 (1i9,3e20.9e3) @@ -594,6 +595,7 @@ def do_run(*args): return do_run +@requires("click") def test_converter_cli(tmpdir, run_cli): input_file = tmpdir.join("mapdl.dat") output_file = tmpdir.join("mapdl.py") diff --git a/tests/test_corba.py b/tests/test_corba.py index bac1525b38..64324107bc 100644 --- a/tests/test_corba.py +++ b/tests/test_corba.py @@ -6,17 +6,22 @@ import os import time -from ansys.mapdl.reader import examples import numpy as np import pytest -import pyvista -from ansys.mapdl import core as pymapdl -from ansys.mapdl.core.errors import MapdlRuntimeError -from conftest import skip_no_xserver +from conftest import has_dependency, requires # skip entire module unless --corba is enabled -pytestmark = pytest.mark.corba +pytestmark = requires("corba") + +if has_dependency("pyvista"): + import pyvista + +if has_dependency("ansys-mapdl-reader"): + from ansys.mapdl.reader import examples + +from ansys.mapdl import core as pymapdl +from ansys.mapdl.core.errors import MapdlRuntimeError @pytest.fixture(scope="function") @@ -186,7 +191,7 @@ def test_invalid_area(mapdl_corba): # mapdl_corba.input('thisisnotafile') -@skip_no_xserver +@requires("xserver") def test_kplot(cleared, mapdl_corba, tmpdir): mapdl_corba.k("", 0, 0, 0) mapdl_corba.k("", 1, 0, 0) @@ -201,7 +206,7 @@ def test_kplot(cleared, mapdl_corba, tmpdir): mapdl_corba.kplot(knum=True, vtk=False) # make sure legacy still works -@skip_no_xserver +@requires("xserver") def test_aplot(cleared, mapdl_corba): k0 = mapdl_corba.k("", 0, 0, 0) k1 = mapdl_corba.k("", 1, 0, 0) @@ -222,7 +227,7 @@ def test_aplot(cleared, mapdl_corba): mapdl_corba.aplot(vtk=False) -@skip_no_xserver +@requires("xserver") @pytest.mark.parametrize("vtk", [True, False]) def test_vplot(cleared, mapdl_corba, vtk): mapdl_corba.block(0, 1, 0, 1, 0, 1) @@ -263,7 +268,7 @@ def test_lines(cleared, mapdl_corba): assert mapdl_corba.geometry.n_line == 4 -@skip_no_xserver +@requires("xserver") def test_lplot(cleared, mapdl_corba, tmpdir): mapdl_corba.lplot(vtk=True) @@ -340,7 +345,7 @@ def test_enum(mapdl_corba, make_block): @pytest.mark.parametrize("nnum", [True, False]) -@skip_no_xserver +@requires("xserver") def test_nplot_vtk(cleared, mapdl_corba, nnum): mapdl_corba.nplot() @@ -350,7 +355,7 @@ def test_nplot_vtk(cleared, mapdl_corba, nnum): mapdl_corba.nplot(vtk=True, nnum=nnum, background="w", color="k") -@skip_no_xserver +@requires("xserver") def test_nplot(cleared, mapdl_corba): mapdl_corba.n(1, 0, 0, 0) mapdl_corba.n(11, 10, 0, 0) @@ -462,7 +467,7 @@ def test_builtin_parameters(mapdl_corba, cleared): assert mapdl_corba.parameters.real == 1 -@skip_no_xserver +@requires("xserver") def test_eplot(mapdl_corba, make_block): init_elem = mapdl_corba.mesh.n_elem mapdl_corba.aplot() # check aplot and verify it doesn't mess up the element plotting @@ -471,7 +476,7 @@ def test_eplot(mapdl_corba, make_block): assert mapdl_corba.mesh.n_elem == init_elem -@skip_no_xserver +@requires("xserver") def test_eplot_screenshot(mapdl_corba, make_block, tmpdir): filename = str(tmpdir.mkdir("tmpdir").join("tmp.png")) mapdl_corba.eplot( diff --git a/tests/test_database.py b/tests/test_database.py index fcd8dca351..9b17b3748e 100644 --- a/tests/test_database.py +++ b/tests/test_database.py @@ -46,6 +46,7 @@ def db(mapdl): ) mapdl.clear() + mapdl.db.start() return mapdl.db @@ -127,7 +128,8 @@ def test_clear(db): db._mapdl.prep7() db._mapdl.k(1, 1, 1, 1) db.clear() - assert db._mapdl.geometry.n_keypoint == 0 + with pytest.raises(ValueError, match="There are no KEYPOINTS defined."): + db._mapdl.get_value("KP", 0, "count") def test_nodes_repr(nodes): diff --git a/tests/test_dpf.py b/tests/test_dpf.py index c5b48b580c..46f9684272 100644 --- a/tests/test_dpf.py +++ b/tests/test_dpf.py @@ -3,23 +3,19 @@ import pytest -from conftest import skip_if_no_has_dpf +from conftest import HAS_DPF, has_dependency, requires -try: - from ansys.dpf import core as dpf - from ansys.dpf.core.server_types import DPF_DEFAULT_PORT -except ImportError: - skip_if_no_has_dpf = pytest.mark.skipif( - True, - reason="""DPF couldn't be imported.""", - ) - DPF_DEFAULT_PORT = None +if not has_dependency("ansys-dpf-core") or not HAS_DPF: + pytest.skip(allow_module_level=True) +from ansys.dpf import core as dpf +from ansys.dpf.core.server_types import DPF_DEFAULT_PORT DPF_PORT = os.environ.get("DPF_PORT", DPF_DEFAULT_PORT) # Set in ci.yaml -@skip_if_no_has_dpf +@requires("dpf") +@requires("ansys-dpf-core") def test_dpf_connection(): # uses 127.0.0.1 and port 50054 by default try: @@ -30,7 +26,8 @@ def test_dpf_connection(): assert False -@skip_if_no_has_dpf +@requires("dpf") +@requires("ansys-dpf-core") def test_upload(mapdl, solved_box, tmpdir): # Download RST file rst_path = mapdl.download_result(str(tmpdir.mkdir("tmpdir"))) diff --git a/tests/test_element.py b/tests/test_element.py index 6e088ee459..345e573a28 100644 --- a/tests/test_element.py +++ b/tests/test_element.py @@ -4,6 +4,7 @@ from ansys.mapdl.core import examples from ansys.mapdl.core._commands.parse import parse_e, parse_et +from conftest import requires @pytest.fixture @@ -33,7 +34,7 @@ def test_et(mapdl, cleared): assert n_plane183 == 17 -@pytest.mark.skip_grpc +@requires("grpc") def test_ewrite(mapdl, cleared): mapdl.et("", 183) n0 = mapdl.n("", 0, 0, 0) diff --git a/tests/test_examples.py b/tests/test_examples.py index cebebe8b87..588ee88baf 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -18,6 +18,7 @@ download_vtk_rotor, get_ext, ) +from conftest import requires def test_check_directory_exist(tmpdir): @@ -66,6 +67,7 @@ def test_load_verif(): assert os.path.isfile(filename) +@requires("requests") def test_bracket(mapdl, cleared, running_test): # note that this method just returns a file path with running_test(False): # To force downloading the file @@ -80,6 +82,7 @@ def test_bracket(mapdl, cleared, running_test): assert int(n_ent[0]) > 0 +@requires("requests") def test_download_example_data_true_download(): path = download_example_data("LatheCutter.anf", "geometry") assert os.path.exists(path) @@ -92,36 +95,43 @@ def test_failed_download(running_test): _download_file(filename, directory=None) +@requires("requests") def test_download_cfx_mapping_example_data(running_test): with running_test(): assert all(download_cfx_mapping_example_data().values()) +@requires("requests") def test_download_manifold_example_data(running_test): with running_test(): assert all(download_manifold_example_data().values()) +@requires("requests") def test_download_bracket(running_test): with running_test(): assert download_bracket() is True +@requires("requests") def test_download_vtk_rotor(running_test): with running_test(): assert download_vtk_rotor() is True +@requires("requests") def test__download_rotor_tech_demo_vtk(running_test): with running_test(): assert _download_rotor_tech_demo_vtk() is True +@requires("requests") def test_download_example_data(running_test): with running_test(): assert download_example_data("LatheCutter.anf", "geometry") is True +@requires("requests") def test_download_tech_demo_data(running_test): with running_test(): assert ( @@ -130,6 +140,7 @@ def test_download_tech_demo_data(running_test): ) +@requires("requests") def test_detach_examples_submodule(): cmd = """ import sys diff --git a/tests/test_files/sector.cdb b/tests/test_files/sector.cdb new file mode 100644 index 0000000000..82d041e41b --- /dev/null +++ b/tests/test_files/sector.cdb @@ -0,0 +1,835 @@ +/PREP7 +/NOPR +*IF,_CDRDOFF,EQ,1,THEN !if solid model was read in +_CDRDOFF= !reset flag, numoffs already performed +*ELSE !offset database for the following FE model +NUMOFF,NODE, 678 +NUMOFF,ELEM, 328 +NUMOFF,TYPE, 2 +*ENDIF +*SET,_BUTTON , 1.000000000000 +*SET,_GUI_CLR_BG,' #D4D0C8 ' +*SET,_GUI_CLR_FG,' #000000 ' +*SET,_GUI_CLR_INFOBG,' #FFFFDC ' +*SET,_GUI_CLR_SEL,' #FFFF80 ' +*SET,_GUI_CLR_SELBG,' #0A246A ' +*SET,_GUI_CLR_SELFG,' #FFFFFF ' +*SET,_GUI_CLR_WIN,' #FFFFFF ' +*SET,_GUI_FNT_FMLY,'helvetica ' +*SET,_GUI_FNT_PXLS, 10.00000000000 +*SET,_GUI_FNT_SLNT,'r ' +*SET,_GUI_FNT_WEGT,'medium ' +*SET,_NREAL , 0.000000000000 +*SET,_QUALKEY, 0.000000000000 +*SET,_RETURN , 0.000000000000 +*SET,_SAV1 , 20.00000000000 +*SET,_SAV2 , 10000.00000000 +*SET,_SAV3 , 0.000000000000 +*SET,_SAV4 , 5.000000000000 +*SET,_STATUS , 1.000000000000 +*SET,_UIQR , 1.000000000000 +*SET,_Z1 , 0.000000000000 +*SET,_ZRD , 2.000000000000 +DOF,DELETE +ET, 1,200 +KEYOP, 1, 1, 7 +ET, 2,185 +NBLOCK,6,SOLID, 678, 655 +(3i9,6e21.13e3) + 1 0 0-2.8749388208227E-001-7.7396874943990E-001-4.0554552665065E-002 + 2 0 0-3.0911290325736E-001-8.3123884941167E-001-3.3999817382376E-002 + 3 0 0-2.9830339266982E-001-8.0260379942578E-001-3.7277185023723E-002 + 4 0 0-2.9343895270591E-001-7.7173437034977E-001-1.0850000000000E-001 + 5 0 0-2.9046641739409E-001-7.7285155989483E-001-7.4527276332533E-002 + 6 0 0-3.1230136738781E-001-8.3004618405191E-001-1.0850000000000E-001 + 7 0 0-3.0287016004686E-001-8.0089027720084E-001-1.0850000000000E-001 + 8 0 0-3.1070713532258E-001-8.3064251673179E-001-7.1249908691188E-002 + 9 0 0-6.4106437325314E-001-5.2030455186348E-001-7.2000000000000E-001 + 10 0 0-6.8031539468484E-001-4.6781547761817E-001-7.7047094398237E-001 + 11 0 0-6.6068988396899E-001-4.9406001474082E-001-7.4523547199118E-001 + 12 0 0-7.1480401135042E-001-4.4620210783410E-001-7.8747094398236E-001 + 13 0 0-6.9755970301763E-001-4.5700879272613E-001-7.7897094398236E-001 + 14 0 0-7.6119802099886E-001-4.3525776058905E-001-7.8747094398236E-001 + 15 0 0-7.3800101617464E-001-4.4072993421158E-001-7.8747094398236E-001 + 16 0 0-7.6802731499679E-001-4.4344430896140E-001-7.7747094398236E-001 + 17 0 0-7.6461266799775E-001-4.3935103477525E-001-7.8247094398236E-001 + 18 0 0-7.2010697899418E-001-5.1764345889358E-001-7.2000000000000E-001 + 19 0 0-7.4406714699549E-001-4.8054388392749E-001-7.4873547199118E-001 + 20 0 0-6.8058567612366E-001-5.1897400537853E-001-7.2000000000000E-001 + 21 0 0-7.2684490224811E-001-4.5764450044740E-001-7.7380843657056E-001 + 22 0 0-3.7433509037666E-001-7.3590325278327E-001-3.2222856038608E-001 + 23 0 0-3.1000378801192E-001-7.6502193311952E-001-1.6363370400513E-001 + 24 0 0-3.2656862331793E-001-7.5830949588928E-001-2.1876740801025E-001 + 25 0 0-3.5045185684730E-001-7.4710637433627E-001-2.7049798419817E-001 + 26 0 0-3.7487641523837E-001-7.1875159113523E-001-3.3722856038608E-001 + 27 0 0-3.7460575280752E-001-7.2732742195925E-001-3.2972856038608E-001 + 28 0 0-2.8709654584008E-001-5.5466746970894E-001-3.3722856038608E-001 + 29 0 0-3.3098648053923E-001-6.3670953042208E-001-3.3722856038608E-001 + 30 0 0-2.8489860857260E-001-5.3888893632385E-001-3.5222856038608E-001 + 31 0 0-2.8599757720634E-001-5.4677820301639E-001-3.4472856038608E-001 + 32 0 0-3.0806562608361E-001-5.2598866231561E-001-4.2113844758148E-001 + 33 0 0-2.9648211732811E-001-5.3243879931973E-001-3.8668350398378E-001 + 34 0 0-3.2156329427311E-001-5.3542270811280E-001-4.3613844758148E-001 + 35 0 0-3.1481446017836E-001-5.3070568521421E-001-4.2863844758148E-001 + 36 0 0-3.7600763300706E-001-6.1603241889712E-001-4.3613844758148E-001 + 37 0 0-3.4878546364008E-001-5.7572756350496E-001-4.3613844758148E-001 + 38 0 0-3.8959461681388E-001-6.6216208765148E-001-4.1001170752194E-001 + 39 0 0-3.8280112491071E-001-6.3909725327465E-001-4.2307507755171E-001 + 40 0 0-4.1314538089745E-001-6.9745757627579E-001-4.1001170752194E-001 + 41 0 0-4.0136999885567E-001-6.7980983196363E-001-4.1001170752194E-001 + 42 0 0-4.3016310360769E-001-7.0472694118991E-001-4.2501170752194E-001 + 43 0 0-4.2165424225257E-001-7.0109225873285E-001-4.1751170752194E-001 + 44 0 0-4.6404461462219E-001-6.8166243024612E-001-4.7959361818188E-001 + 45 0 0-4.9792612563668E-001-6.5859791930233E-001-5.3417552884182E-001 + 46 0 0-5.3394540688984E-001-6.2797095323466E-001-5.8337418797363E-001 + 47 0 0-5.6996468814300E-001-5.9734398716698E-001-6.3257284710545E-001 + 48 0 0-6.0551453069807E-001-5.5882426951523E-001-6.7628642355272E-001 + 49 0 0-6.7566426154020E-001-5.7029580554594E-001-6.7504301677288E-001 + 50 0 0-6.3122154408623E-001-6.2294815219830E-001-6.3008603354576E-001 + 51 0 0-5.8417364096845E-001-6.6432206710988E-001-5.7686470238967E-001 + 52 0 0-5.3712573785067E-001-7.0569598202147E-001-5.2364337123358E-001 + 53 0 0-4.9298355164893E-001-7.3529113395669E-001-4.6085701573334E-001 + 54 0 0-4.4884136544719E-001-7.6488628589191E-001-3.9807066023310E-001 + 55 0 0-4.0875500832874E-001-7.8573793827451E-001-3.2929912553000E-001 + 56 0 0-3.6866865121030E-001-8.0658959065712E-001-2.6052759082690E-001 + 57 0 0-3.4048500929905E-001-8.1831788735451E-001-1.8451379541345E-001 + 58 0 0-3.0843998003228E-001-5.6428459821589E-001-3.7085265075605E-001 + 59 0 0-3.5289552361577E-001-5.9496707280998E-001-4.2030759435375E-001 + 60 0 0-3.2478946717900E-001-5.6205525768343E-001-4.0916751911838E-001 + 61 0 0-5.9899324838254E-001-6.0930550852781E-001-6.3233553646219E-001 + 62 0 0-5.6139122864364E-001-6.5960672810409E-001-5.7410199799256E-001 + 63 0 0-5.7781070378981E-001-6.0543073067684E-001-6.2856673592850E-001 + 64 0 0-4.0587882031398E-001-7.2061842393953E-001-3.8084550922150E-001 + 65 0 0-4.3384694973234E-001-7.1831170081573E-001-4.1801707985061E-001 + 66 0 0-4.8732826685383E-001-7.1879622123150E-001-4.6733291170643E-001 + 67 0 0-2.9883237111159E-001-5.4951707677169E-001-3.6984969557240E-001 + 68 0 0-3.9401089806791E-001-7.0810458370551E-001-3.7362013395401E-001 + 69 0 0-3.4761863726411E-001-7.8244954327320E-001-2.3964749941857E-001 + 70 0 0-5.1752593174368E-001-6.8214695066190E-001-5.2890945003770E-001 + 71 0 0-3.0931691123336E-001-5.3517767307503E-001-4.1180463917010E-001 + 72 0 0-3.1518185825831E-001-5.4728773623923E-001-4.0816456393473E-001 + 73 0 0-3.2067940720331E-001-5.4281574837841E-001-4.2499837234611E-001 + 74 0 0-3.8647367505359E-001-7.3984126219327E-001-3.3695393565357E-001 + 75 0 0-3.8364045547040E-001-7.7518443113019E-001-3.0610345087398E-001 + 76 0 0-3.3834558132698E-001-6.0841477868021E-001-3.7362013395401E-001 + 77 0 0-6.2177566070734E-001-6.1402084753361E-001-6.3509824085930E-001 + 78 0 0-6.2669707529080E-001-5.6269904736620E-001-6.8005522408642E-001 + 79 0 0-4.4318608065209E-001-7.4839137316672E-001-4.0454655620619E-001 + 80 0 0-4.1807152779375E-001-7.3783786602240E-001-3.8135088155017E-001 + 81 0 0-3.2978341422448E-001-5.7390172672285E-001-4.0447674112602E-001 + 82 0 0-5.8565671943661E-001-6.1351747418671E-001-6.2456062475155E-001 + 83 0 0-3.1056819638310E-001-5.4436668383445E-001-4.0247083075871E-001 + 84 0 0-3.1979552013352E-001-5.5020878864401E-001-4.1385829711074E-001 + 85 0 0-3.9861225973051E-001-7.4377927160327E-001-3.5167931092106E-001 + 86 0 0-6.1232977732846E-001-6.0509354286891E-001-6.4011044817283E-001 + 87 0 0-4.3753079585700E-001-7.3189646044154E-001-4.1102245217928E-001 + 88 0 0 5.2308702906449E-002-8.8530933087350E-001-1.0850000000000E-001 + 89 0 0 5.5706610534415E-002-8.8510201969841E-001-3.3999817382376E-002 + 90 0 0 5.4007656720432E-002-8.8520567528595E-001-7.1249908691188E-002 + 91 0 0 4.5822824802394E-002-8.2436680311098E-001-1.0850000000000E-001 + 92 0 0 4.9065763854421E-002-8.5483806699224E-001-1.0850000000000E-001 + 93 0 0 5.2162720916463E-002-8.2398993191112E-001-4.0554552665065E-002 + 94 0 0 4.8992772859427E-002-8.2417836751105E-001-7.4527276332533E-002 + 95 0 0 5.3934665725439E-002-8.5454597580476E-001-3.7277185023723E-002 + 96 0 0-4.4730589689635E-001-7.6578472584218E-001-7.2000000000000E-001 + 97 0 0-3.7401451943990E-001-7.3606623111812E-001-7.2000000000000E-001 + 98 0 0-4.1066020816812E-001-7.5092547848015E-001-7.2000000000000E-001 + 99 0 0-5.2126281534273E-001-7.1749138606146E-001-7.7747094398236E-001 + 100 0 0-4.8428435611954E-001-7.4163805595182E-001-7.4873547199118E-001 + 101 0 0-5.1835371403536E-001-7.0723487786684E-001-7.8747094398236E-001 + 102 0 0-5.1980826468897E-001-7.1236313196414E-001-7.8247094398236E-001 + 103 0 0-4.7151921020010E-001-6.9836289283619E-001-7.8747094398236E-001 + 104 0 0-4.9493646211773E-001-7.0279888535151E-001-7.8747094398236E-001 + 105 0 0-4.3122134163335E-001-7.0407990445988E-001-7.7047094398237E-001 + 106 0 0-4.5137027591672E-001-7.0122139864803E-001-7.7897094398236E-001 + 107 0 0-4.0261793053662E-001-7.2007306778900E-001-7.4523547199118E-001 + 108 0 0-4.7786507102537E-001-7.1371351017599E-001-7.7380843657056E-001 + 109 0 0-3.8528981551353E-001-7.9580855625427E-001-6.7504301677288E-001 + 110 0 0-3.2327373413071E-001-8.2583238666636E-001-6.3008603354576E-001 + 111 0 0-2.6346504868381E-001-8.4449323252085E-001-5.7686470238967E-001 + 112 0 0-2.0365636323692E-001-8.6315407837534E-001-5.2364337123358E-001 + 113 0 0-1.5129303679245E-001-8.7223635036028E-001-4.6085701573334E-001 + 114 0 0-9.8929710347990E-002-8.8131862234522E-001-3.9807066023310E-001 + 115 0 0-5.3827869796311E-002-8.8406296433620E-001-3.2929912553000E-001 + 116 0 0-8.7260292446313E-003-8.8680730632717E-001-2.6052759082690E-001 + 117 0 0 2.1791336830909E-002-8.8605831860033E-001-1.8451379541345E-001 + 118 0 0-1.0633527900159E-001-8.1876319273887E-001-4.2501170752194E-001 + 119 0 0-1.4666876124241E-001-8.1147356558579E-001-4.7959361818188E-001 + 120 0 0-1.8700224348323E-001-8.0418393843272E-001-5.3417552884182E-001 + 121 0 0-2.3236460362557E-001-7.9085517424313E-001-5.8337418797363E-001 + 122 0 0-2.7772696376791E-001-7.7752641005354E-001-6.3257284710545E-001 + 123 0 0-3.2587074160390E-001-7.5679632058583E-001-6.7628642355272E-001 + 124 0 0-9.3745532802687E-002-8.0520056603366E-001-4.1001170752194E-001 + 125 0 0-1.0004040590214E-001-8.1198187938627E-001-4.1751170752194E-001 + 126 0 0-8.6586807808907E-002-7.6337757400043E-001-4.1001170752194E-001 + 127 0 0-9.0166170305797E-002-7.8428907001705E-001-4.1001170752194E-001 + 128 0 0-9.2937107084464E-002-7.1570970046421E-001-4.3613844758148E-001 + 129 0 0-8.9761957446765E-002-7.3954363723274E-001-4.2307507755171E-001 + 130 0 0-7.5986651903432E-002-6.1992455776419E-001-4.3613844758148E-001 + 131 0 0-8.4461879493948E-002-6.6781712911420E-001-4.3613844758148E-001 + 132 0 0-6.7493090558325E-002-6.0581613183023E-001-4.2113844758148E-001 + 133 0 0-7.1739871230879E-002-6.1287034479721E-001-4.2863844758148E-001 + 134 0 0-4.1081952799151E-002-6.0817824362029E-001-3.5222856038608E-001 + 135 0 0-5.4287521678738E-002-6.0699718772526E-001-3.8668350398378E-001 + 136 0 0-3.6672160704326E-002-6.2348663274837E-001-3.3722856038608E-001 + 137 0 0-3.8877056751738E-002-6.1583243818433E-001-3.4472856038608E-001 + 138 0 0-5.0124036934622E-002-8.0908822595732E-001-3.3722856038608E-001 + 139 0 0-4.3398098819474E-002-7.1628742935285E-001-3.3722856038608E-001 + 140 0 0-4.2653302784203E-002-8.2453687188985E-001-3.2222856038608E-001 + 141 0 0-4.6388669859413E-002-8.1681254892359E-001-3.2972856038608E-001 + 142 0 0 2.7959900566102E-002-8.2497221207505E-001-1.6363370400513E-001 + 143 0 0 1.0096976329812E-002-8.2557762103912E-001-2.1876740801025E-001 + 144 0 0-1.6278163227196E-002-8.2505724646448E-001-2.7049798419817E-001 + 145 0 0-5.2258719496157E-002-6.4095347358651E-001-3.7085265075605E-001 + 146 0 0-8.0391192686226E-002-6.8706500744443E-001-4.2030759435375E-001 + 147 0 0-6.8101473698277E-002-6.4556680518760E-001-4.0916751911838E-001 + 148 0 0-2.9938068407226E-001-8.0026078270438E-001-6.3233553646219E-001 + 149 0 0-2.4457018054853E-001-8.3091911408070E-001-5.7410199799256E-001 + 150 0 0-2.8160548081402E-001-7.8810527991980E-001-6.2856673592850E-001 + 151 0 0-7.7686833959436E-002-8.2340347675360E-001-3.8084550922150E-001 + 152 0 0-1.0417522036822E-001-8.3267184339455E-001-4.1801707985061E-001 + 153 0 0-1.5283576248589E-001-8.5486728621278E-001-4.6733291170643E-001 + 154 0 0-4.9488224106617E-002-6.2355490485013E-001-3.6984969557240E-001 + 155 0 0-7.1934784868654E-002-8.0714439599549E-001-3.7362013395401E-001 + 156 0 0 6.8547354259039E-004-8.5619246368315E-001-2.3964749941857E-001 + 157 0 0-1.9532930336007E-001-8.3366900840403E-001-5.2890945003770E-001 + 158 0 0-6.4898689033617E-002-6.1471965439106E-001-4.1180463917010E-001 + 159 0 0-6.5330978308737E-002-6.2816823645123E-001-4.0816456393473E-001 + 160 0 0-7.2172160505998E-002-6.2631892685738E-001-4.2499837234611E-001 + 161 0 0-5.2140718950194E-002-8.3307162968169E-001-3.3695393565357E-001 + 162 0 0-3.5177082180408E-002-8.6420684690036E-001-3.0610345087398E-001 + 163 0 0-6.1629484256616E-002-6.9343210337440E-001-3.7362013395401E-001 + 164 0 0-3.1827555220754E-001-8.1383490114453E-001-6.3509824085930E-001 + 165 0 0-3.4364594486214E-001-7.6895182337041E-001-6.8005522408642E-001 + 166 0 0-1.0047243604143E-001-8.6394955819772E-001-4.0454655620619E-001 + 167 0 0-8.1821648425523E-002-8.4409344076188E-001-3.8135088155017E-001 + 168 0 0-6.7845278287989E-002-6.5842031442464E-001-4.0447674112602E-001 + 169 0 0-2.8548399786014E-001-7.9868414978606E-001-6.2456062475155E-001 + 170 0 0-6.2304287508909E-002-6.2362317695190E-001-4.0247083075871E-001 + 171 0 0-6.8357669108565E-002-6.3271329595056E-001-4.1385829711074E-001 + 172 0 0-6.1628135116184E-002-8.4160638747354E-001-3.5167931092106E-001 + 173 0 0-3.1327737028437E-001-8.0183741562269E-001-6.4011044817283E-001 + 174 0 0-1.0201516173486E-001-8.4658049405022E-001-4.1102245217928E-001 + 175 0 0-1.0102444899411E-001-8.8108051416251E-001-3.3999817382376E-002 + 176 0 0-9.0574200423374E-002-8.2065624445438E-001-4.0554552665054E-002 + 177 0 0-9.5799324708741E-002-8.5086837930844E-001-3.7277185023721E-002 + 178 0 0-1.1385009702910E-001-8.7951518869085E-001-1.1288303905988E-001 + 179 0 0-1.0743727301160E-001-8.8029785142668E-001-7.3441428221127E-002 + 180 0 0-8.1843769455740E-002-8.2157285419223E-001-1.1127946367209E-001 + 181 0 0-9.7846933242418E-002-8.5054402144154E-001-1.1208125136598E-001 + 182 0 0-8.6208984939557E-002-8.2111454932330E-001-7.5917008168569E-002 + 183 0 0-1.5334767836913E-001-8.7349487764398E-001-1.0849999999971E-001 + 184 0 0-1.3344121123607E-001-8.1478451168892E-001-1.0849999999971E-001 + 185 0 0-1.4339444480262E-001-8.4413969466644E-001-1.0849999999971E-001 + 186 0 0-2.1344008197099E-001-7.9325944101934E-001-1.0849999999985E-001 + 187 0 0-2.3282452287847E-001-8.5177053084793E-001-1.0849999999985E-001 + 188 0 0-1.3334232408605E-001-8.1480070075548E-001-4.0554552665054E-002 + 189 0 0-1.4368695909587E-001-8.7513591488249E-001-3.3999817382376E-002 + 190 0 0-1.3851464159096E-001-8.4496830781899E-001-3.7277185023721E-002 + 191 0 0-2.1041810308416E-001-7.9438472509769E-001-4.0554552665065E-002 + 192 0 0-2.2639993117662E-001-8.5318738214708E-001-3.3999817382376E-002 + 193 0 0-1.3339176766108E-001-8.1479260622220E-001-7.4527276332377E-002 + 194 0 0-1.4851731873249E-001-8.7431539626322E-001-7.1249908691043E-002 + 195 0 0-1.2235570404499E-001-8.7810821452250E-001-3.3999817382376E-002 + 196 0 0-1.1195826225471E-001-8.1772847260493E-001-4.0554552665065E-002 + 197 0 0-6.1886205191590E-002-8.8382102081460E-001-3.3999817382376E-002 + 198 0 0-2.2747961389069E-002-8.8656152746669E-001-3.3999817382376E-002 + 199 0 0 1.6479324572673E-002-8.8583177358255E-001-3.3999817382376E-002 + 200 0 0-5.4926068095909E-002-8.2303525765642E-001-4.0554552665065E-002 + 201 0 0-1.9277935768444E-002-8.2541427085846E-001-4.0554552665065E-002 + 202 0 0 1.6442392574009E-002-8.2470210138479E-001-4.0554552665065E-002 + 203 0 0-2.0390380339672E-002-8.3062682811040E-001-2.6103574364344E-002 + 204 0 0-1.3364790875408E-001-8.7649629514224E-001-1.1106509176900E-001 + 205 0 0-1.0764249034592E-001-8.1817868294057E-001-1.0988973183590E-001 + 206 0 0 1.3879323016609E-002-8.2490412547663E-001-1.0920374700457E-001 + 207 0 0-1.8064178769208E-002-8.2544144784227E-001-1.0990749400913E-001 + 208 0 0-4.9953974112474E-002-8.2350715101725E-001-1.1059347884061E-001 + 209 0 0-1.8671065331359E-002-8.2542822138796E-001-7.5231023323738E-002 + 210 0 0-7.2377902983277E-002-8.8291396919768E-001-1.1180642529748E-001 + 211 0 0-3.0905708937457E-002-8.8631274970452E-001-1.1072981153507E-001 + 212 0 0 1.0701496984496E-002-8.8581104028901E-001-1.0961490576754E-001 + 213 0 0-2.6827137727837E-002-8.8644746962962E-001-7.2364814408314E-002 + 214 0 0-7.1535024277687E-001-5.2419733106007E-001-7.7747094398238E-001 + 215 0 0-6.4396966055712E-001-6.0976379690285E-001-7.0744783914337E-001 + 216 0 0-6.7965995166699E-001-5.6698056398146E-001-7.4245939156287E-001 + 217 0 0-6.8208685627001E-001-5.6363609418497E-001-7.1377587244275E-001 + 218 0 0-7.4168877888683E-001-4.8382082001074E-001-7.7747094398236E-001 + 219 0 0-7.0956049321178E-001-5.1516565471549E-001-7.8747094398237E-001 + 220 0 0-7.1245536799432E-001-5.1968149288779E-001-7.8247094398237E-001 + 221 0 0-7.3537925710510E-001-4.7521170765255E-001-7.8747094398236E-001 + 222 0 0-6.6134504055286E-001-5.2217222543280E-001-7.8747094398236E-001 + 223 0 0-6.8545276688232E-001-5.1866894007415E-001-7.8747094398236E-001 + 224 0 0-6.8807452595186E-001-4.8418716663362E-001-7.8747094398236E-001 + 225 0 0-6.2200397372911E-001-5.4294697163673E-001-7.7047094398237E-001 + 226 0 0-6.4167450714137E-001-5.3255959853472E-001-7.7897094398237E-001 + 227 0 0-6.5115968420697E-001-5.0538122462745E-001-7.7047094398237E-001 + 228 0 0-5.5773840462986E-001-6.0877600917352E-001-7.0750446029015E-001 + 229 0 0-5.8987118917948E-001-5.7586149040512E-001-7.3898770213626E-001 + 230 0 0-5.9941071010573E-001-5.6452879554287E-001-7.1376372286983E-001 + 231 0 0-6.0085403259349E-001-6.0926990303818E-001-7.0747614971676E-001 + 232 0 0-2.4948162492130E-001-7.7129442840463E-001-4.1001170752194E-001 + 233 0 0-3.3131350290938E-001-7.3437600234021E-001-4.1001170752194E-001 + 234 0 0-2.1881607653197E-001-7.3645238843015E-001-4.1001170752194E-001 + 235 0 0-2.3414885072664E-001-7.5387340841739E-001-4.1001170752194E-001 + 236 0 0-3.0420534667293E-001-6.9930723804082E-001-4.1001170752194E-001 + 237 0 0-2.0677895139659E-001-6.9146232469482E-001-4.3613844758148E-001 + 238 0 0-2.1279751396428E-001-7.1395735656249E-001-4.2307507755171E-001 + 239 0 0-2.9139329220207E-001-6.5374737179632E-001-4.3613844758148E-001 + 240 0 0-1.6458233312307E-001-6.0248907393446E-001-4.3613844758148E-001 + 241 0 0-1.8568064225983E-001-6.4697569931464E-001-4.3613844758148E-001 + 242 0 0-2.4307281369808E-001-5.6895589102363E-001-4.3613844758148E-001 + 243 0 0-1.5410802713209E-001-5.8976200185525E-001-4.2113844758148E-001 + 244 0 0-1.5934518012758E-001-5.9612553789485E-001-4.2863844758148E-001 + 245 0 0-2.3108682660785E-001-5.5787533208543E-001-4.2113844758148E-001 + 246 0 0-1.3387717159131E-001-5.9468092771298E-001-3.5222856038608E-001 + 247 0 0-1.4399259936170E-001-5.9222146478411E-001-3.8668350398378E-001 + 248 0 0-2.0938789008196E-001-5.6678493201841E-001-3.5222856038608E-001 + 249 0 0-1.3383595359792E-001-6.1005603522231E-001-3.3722856038608E-001 + 250 0 0-1.3385656259462E-001-6.0236848146764E-001-3.4472856038608E-001 + 251 0 0-2.1046624971900E-001-5.8236175246562E-001-3.3722856038608E-001 + 252 0 0-2.0279985530099E-001-7.8486202300232E-001-3.3722856038608E-001 + 253 0 0-1.6831790444946E-001-6.9745902911231E-001-3.3722856038608E-001 + 254 0 0-2.8883813526968E-001-7.5180680706877E-001-3.3722856038608E-001 + 255 0 0-2.0422387290491E-001-7.9998310424659E-001-3.2222856038608E-001 + 256 0 0-2.0351186410295E-001-7.9242256362446E-001-3.2972856038608E-001 + 257 0 0-2.8927948164079E-001-7.6794317851493E-001-3.2222856038608E-001 + 258 0 0-1.4484396574081E-001-8.1275237937940E-001-1.6404863661761E-001 + 259 0 0-1.5624672024554E-001-8.1072024706989E-001-2.1959727323625E-001 + 260 0 0-1.8023529657522E-001-8.0535167565824E-001-2.7091291681117E-001 + 261 0 0-2.4282719163343E-001-7.8912312876237E-001-2.1918150292803E-001 + 262 0 0-2.4485360439811E-002-8.5587724042161E-001-1.1030169845691E-001 + 263 0 0-2.7346601789211E-001-7.7903574654988E-001-4.2501170752194E-001 + 264 0 0-3.5181456074990E-001-7.4188134386990E-001-4.2501170752194E-001 + 265 0 0-2.6147382140670E-001-7.7516508747725E-001-4.1751170752194E-001 + 266 0 0-5.9039383879783E-001-6.5784645827715E-001-6.6328771868877E-001 + 267 0 0-5.3681801703853E-001-7.0592911965145E-001-6.1912759823417E-001 + 268 0 0-4.8037006595866E-001-7.4245045560664E-001-5.6801249895676E-001 + 269 0 0-4.2392211487880E-001-7.7897179156183E-001-5.1689739967935E-001 + 270 0 0-3.6808968781243E-001-8.0451688454693E-001-4.5894764712686E-001 + 271 0 0-3.1225726074607E-001-8.3006197753203E-001-4.0099789457437E-001 + 272 0 0-2.6572645795333E-001-8.4470009898593E-001-3.3221530289165E-001 + 273 0 0-2.1919565516059E-001-8.5933822043983E-001-2.6343271120893E-001 + 274 0 0-1.8627166676485E-001-8.6641654904190E-001-1.8596635560432E-001 + 275 0 0-5.8554484615898E-001-6.6606759782179E-001-6.2464528947985E-001 + 276 0 0-4.8196578086693E-001-7.4445805644426E-001-5.2029767226718E-001 + 277 0 0-3.8198262372746E-001-8.0037371702331E-001-3.9954618573467E-001 + 278 0 0-2.9515462946486E-001-8.3629693078290E-001-2.6197148184264E-001 + 279 0 0-3.1971206578655E-001-7.5957051317524E-001-4.7815198592831E-001 + 280 0 0-3.6595811368099E-001-7.4010527980060E-001-5.3129226433468E-001 + 281 0 0-4.1472430448952E-001-7.1168698619648E-001-5.7771941797452E-001 + 282 0 0-4.6349049529806E-001-6.8326869259236E-001-6.2414657161435E-001 + 283 0 0-5.1061444996396E-001-6.4602235088294E-001-6.6582551595225E-001 + 284 0 0-5.1852030345229E-001-6.4250840636683E-001-6.2836638839575E-001 + 285 0 0-4.3386707557739E-001-7.0245264472007E-001-5.3273632046801E-001 + 286 0 0-1.1473280769097E-001-8.1762873003805E-001-3.2222856038608E-001 + 287 0 0-1.5947834029794E-001-8.0880591714232E-001-3.2222856038608E-001 + 288 0 0-9.8402391581270E-002-8.1958940958894E-001-2.7079114950967E-001 + 289 0 0-8.2071975471568E-002-8.2155008913983E-001-2.1935373863327E-001 + 290 0 0-8.1957872463655E-002-8.2156147166603E-001-1.6531660115267E-001 + 291 0 0-1.1930273350324E-001-8.1697442745961E-001-2.1947315861701E-001 + 292 0 0-1.1522640304801E-001-8.0240828292136E-001-3.3722856038608E-001 + 293 0 0-1.5901312917456E-001-7.9363515296221E-001-3.3722856038608E-001 + 294 0 0-1.1497960536965E-001-8.1001850648006E-001-3.2972856038608E-001 + 295 0 0-8.3032638609398E-002-6.1902020121494E-001-3.3722856038608E-001 + 296 0 0-1.0843429610366E-001-6.1453811821862E-001-3.3722856038608E-001 + 297 0 0-9.9129520828706E-002-7.1071424206815E-001-3.3722856038608E-001 + 298 0 0-8.4605956409759E-002-6.0366409119546E-001-3.5222856038608E-001 + 299 0 0-8.3819297509579E-002-6.1134214620520E-001-3.4472856038608E-001 + 300 0 0-1.0924156400053E-001-5.9917250945422E-001-3.5222856038608E-001 + 301 0 0-1.0305023066935E-001-6.0079044001869E-001-4.2113844758148E-001 + 302 0 0-1.2857912890072E-001-5.9527622093697E-001-4.2113844758148E-001 + 303 0 0-9.3828093539556E-002-6.0222726560707E-001-3.8668350398378E-001 + 304 0 0-1.1094907549245E-001-6.1463056483874E-001-4.3613844758148E-001 + 305 0 0-1.0699965308090E-001-6.0771050242871E-001-4.2863844758148E-001 + 306 0 0-1.3776570430776E-001-6.0855981938660E-001-4.3613844758148E-001 + 307 0 0-1.3473984388474E-001-7.0902951679246E-001-4.3613844758148E-001 + 308 0 0-1.2284445968859E-001-6.6183004081560E-001-4.3613844758148E-001 + 309 0 0-1.7075939764066E-001-7.0024592074364E-001-4.3613844758148E-001 + 310 0 0-1.3690768461904E-001-7.5597545043842E-001-4.1001170752194E-001 + 311 0 0-1.3582376425189E-001-7.3250248361544E-001-4.2307507755171E-001 + 312 0 0-1.7786188057551E-001-7.4621391943429E-001-4.1001170752194E-001 + 313 0 0-1.5848974338210E-001-7.9499508030180E-001-4.1001170752194E-001 + 314 0 0-2.0398568415170E-001-7.8314475435321E-001-4.1001170752194E-001 + 315 0 0-1.4769871400057E-001-7.7548526537011E-001-4.1001170752194E-001 + 316 0 0-1.7997121608768E-001-8.0578577719156E-001-4.2501170752194E-001 + 317 0 0-2.2671861698989E-001-7.9241076187072E-001-4.2501170752194E-001 + 318 0 0-1.6923047973489E-001-8.0039042874668E-001-4.1751170752194E-001 + 319 0 0-5.3394076122318E-001-6.2975203123825E-001-7.2466231097144E-001 + 320 0 0-5.4583958292652E-001-6.1926402020588E-001-7.1608338563079E-001 + 321 0 0-4.7496911772068E-001-6.7146416406828E-001-6.8249130833101E-001 + 322 0 0-4.1599747421817E-001-7.1317629689832E-001-6.4032030569059E-001 + 323 0 0-3.5463212562529E-001-7.4248804543915E-001-5.9169802661262E-001 + 324 0 0-2.9326677703241E-001-7.7179979397998E-001-5.4307574753466E-001 + 325 0 0-2.3661899656005E-001-7.8879278558578E-001-4.8404372752830E-001 + 326 0 0-3.2999612685614E-001-7.5682422900185E-001-5.3718316701278E-001 + 327 0 0-4.4000099399363E-001-6.9862685507280E-001-6.3223289784751E-001 + 328 0 0-6.2945669154883E-001-6.2473441172696E-001-7.2773259288742E-001 + 329 0 0-6.3651788280190E-001-6.1744960861403E-001-7.1743694693316E-001 + 330 0 0-1.2786506679017E-001-8.7747297840605E-001-2.0065491185641E-001 + 331 0 0-1.4188003655125E-001-8.7543076812126E-001-2.8842678465294E-001 + 332 0 0-1.9264795183973E-001-8.6411230181226E-001-3.6189807922094E-001 + 333 0 0-2.4341586712822E-001-8.5279383550325E-001-4.3536937378895E-001 + 334 0 0-3.0748594068339E-001-8.2903047405633E-001-4.9436665170324E-001 + 335 0 0-3.7155601423856E-001-8.0526711260942E-001-5.5336392961752E-001 + 336 0 0-4.3863579345030E-001-7.6689989932117E-001-6.0005230787698E-001 + 337 0 0-5.0571557266203E-001-7.2853268603292E-001-6.4674068613643E-001 + 338 0 0-5.6758613210543E-001-6.7663354887994E-001-6.8723663951192E-001 + 339 0 0-1.8078929023183E-001-8.6823040966607E-001-2.7617322967537E-001 + 340 0 0-2.7803724825233E-001-8.4214256531522E-001-4.1830821568519E-001 + 341 0 0-3.9781534745220E-001-7.9262334123019E-001-5.3517664462543E-001 + 342 0 0-5.2120137045098E-001-7.1753602221175E-001-6.3288353834915E-001 + 343 0 0-1.2435810175080E-001-7.5803425226511E-001-4.1001170752194E-001 + 344 0 0-1.1180851888257E-001-7.6009305409180E-001-4.1001170752194E-001 + 345 0 0-9.9197663345737E-002-7.6173531404612E-001-4.1001170752194E-001 + 346 0 0-1.4235528411000E-001-7.9787376317077E-001-4.1001170752194E-001 + 347 0 0-1.2622082483790E-001-8.0075244603974E-001-4.1001170752194E-001 + 348 0 0-1.0998317882029E-001-8.0297650603670E-001-4.1001170752194E-001 + 349 0 0-1.1901467186023E-001-7.8042275006577E-001-4.1001170752194E-001 + 350 0 0-1.2431365450827E-001-7.1085284452333E-001-4.3613844758148E-001 + 351 0 0-1.1388746513179E-001-7.1267617225420E-001-4.3613844758148E-001 + 352 0 0-1.0341228610818E-001-7.1419293635963E-001-4.3613844758148E-001 + 353 0 0-1.1284851128631E-001-7.3638800765971E-001-4.2308119353284E-001 + 354 0 0-1.0222720647896E-001-6.1607780461568E-001-4.3613844758148E-001 + 355 0 0-9.3505337465465E-002-6.1752504439261E-001-4.3613844758148E-001 + 356 0 0-8.4745994684449E-002-6.1872480107840E-001-4.3613844758148E-001 + 357 0 0-1.0369640129863E-001-6.6510060832340E-001-4.3613844758148E-001 + 358 0 0-5.8169872638601E-001-6.2724322148261E-001-7.2619745192943E-001 + 359 0 0-9.4179454206554E-002-6.0217781243329E-001-4.2113844758148E-001 + 360 0 0-8.5308677743755E-002-6.0356518484789E-001-4.2113844758148E-001 + 361 0 0-7.6400884151040E-002-6.0469065833906E-001-4.2113844758148E-001 + 362 0 0-8.8957202724308E-002-6.0747347426946E-001-4.3173974048170E-001 + 363 0 0-5.8836620685452E-001-5.7922842124323E-001-7.7047094398237E-001 + 364 0 0-6.0518509029181E-001-5.6108769643998E-001-7.7047094398237E-001 + 365 0 0-6.3086208771108E-001-5.5861804658197E-001-7.8747094398236E-001 + 366 0 0-6.0961414728280E-001-5.6892323391260E-001-7.7897094398236E-001 + 367 0 0-6.4610356413219E-001-5.4039513600756E-001-7.8747094398236E-001 + 368 0 0-6.8041238432377E-001-5.5309197479644E-001-7.8747094398236E-001 + 369 0 0-6.9498643876777E-001-5.3412881475597E-001-7.8747094398236E-001 + 370 0 0-6.5563723601743E-001-5.5585501068921E-001-7.8747094398236E-001 + 371 0 0-6.8567394244500E-001-5.6245893750865E-001-7.7747094398236E-001 + 372 0 0-6.8304316338439E-001-5.5777545615255E-001-7.8247094398236E-001 + 373 0 0-7.0051209261094E-001-5.4332813428436E-001-7.7747094398236E-001 + 374 0 0-7.3745215018422E-002-6.0498796498390E-001-3.5222856038608E-001 + 375 0 0-6.2884473627084E-002-6.0631183877234E-001-3.5222856038608E-001 + 376 0 0-5.1983213213118E-002-6.0724504119632E-001-3.5222856038608E-001 + 377 0 0-7.4109301391613E-002-6.0504240703119E-001-3.8668350398378E-001 + 378 0 0-7.1463343352781E-002-6.2035295945631E-001-3.3722856038608E-001 + 379 0 0-5.9894048096163E-002-6.2168571769768E-001-3.3722856038608E-001 + 380 0 0-4.8283104400244E-002-6.2258617522302E-001-3.3722856038608E-001 + 381 0 0-6.1080315015427E-002-6.1090878546684E-001-3.4162486871582E-001 + 382 0 0-6.5756531699692E-001-5.9359667461781E-001-7.5260176843489E-001 + 383 0 0-5.6115348403885E-001-6.0449022624074E-001-7.4756662747690E-001 + 384 0 0-1.2161120215260E+000-1.2303568262168E+000-7.2313585266101E-001 + 385 0 0-5.1055638863057E-001-1.6528879401662E+000-1.2351988013257E-001 + 386 0 0-1.1442683010779E+000-1.2938925615014E+000-6.8115254980496E-001 + 387 0 0-1.0724245806299E+000-1.3574282967860E+000-6.3916924694890E-001 + 388 0 0-9.9584969772137E-001-1.4114556026955E+000-5.9250231116497E-001 + 389 0 0-9.1927481481284E-001-1.4654829086049E+000-5.4583537538104E-001 + 390 0 0-8.4162689517780E-001-1.5087955800241E+000-4.9063505947769E-001 + 391 0 0-7.6397897554276E-001-1.5521082514434E+000-4.3543474357434E-001 + 392 0 0-6.9216155523057E-001-1.5835005121936E+000-3.6628417300183E-001 + 393 0 0-6.2034413491838E-001-1.6148927729438E+000-2.9713360242931E-001 + 394 0 0-5.6545026177448E-001-1.6338903565550E+000-2.1032674128094E-001 + 395 0 0-1.2012331424876E+000-1.2448876680679E+000-7.3985043715255E-001 + 396 0 0-1.2086725820068E+000-1.2376222471424E+000-7.3149314490678E-001 + 397 0 0-4.7551052766374E-001-1.6633087827578E+000-1.1587599339095E-001 + 398 0 0-5.0784521323467E-001-1.6533769191587E+000-2.1837515973677E-001 + 399 0 0-5.4017989880560E-001-1.6434450555595E+000-3.2087432608258E-001 + 400 0 0-6.1845415203486E-001-1.6134415352292E+000-3.9420279155853E-001 + 401 0 0-6.9672840526411E-001-1.5834380148989E+000-4.6753125703448E-001 + 402 0 0-7.8332083757754E-001-1.5393748442960E+000-5.2253739153807E-001 + 403 0 0-8.6991326989097E-001-1.4953116736932E+000-5.7754352604166E-001 + 404 0 0-9.5544093187297E-001-1.4385050568264E+000-6.2152269818174E-001 + 405 0 0-1.0409685938550E+000-1.3816984399596E+000-6.6550187032181E-001 + 406 0 0-1.1211008681713E+000-1.3132930540138E+000-7.0267615373718E-001 + 407 0 0-4.9303345814716E-001-1.6580983614620E+000-1.1969793676176E-001 + 408 0 0-5.8073579141095E-001-1.6295558625873E+000-3.0882944018442E-001 + 409 0 0-7.3068349489776E-001-1.5680586720535E+000-4.5133866854059E-001 + 410 0 0-8.9479253959923E-001-1.4805582324907E+000-5.6161276930758E-001 + 411 0 0-1.0567955467820E+000-1.3696311697023E+000-6.5230258546895E-001 + 412 0 0-9.8984530395514E-002-8.0440689103347E-001-3.3722856038608E-001 + 413 0 0-8.2742657742908E-002-8.0640549914484E-001-3.3722856038608E-001 + 414 0 0-6.6433347338765E-002-8.0774686255108E-001-3.3722856038608E-001 + 415 0 0-7.1318352919535E-002-7.1404560842126E-001-3.3722856038608E-001 + 416 0 0-4.3934392557184E-001-1.5849294957135E+000-1.1561163403002E-001 + 417 0 0-4.0317732347993E-001-1.5065502086693E+000-1.1534727466909E-001 + 418 0 0-3.6701072138803E-001-1.4281709216250E+000-1.1508291530816E-001 + 419 0 0-3.3084411929612E-001-1.3497916345807E+000-1.1481855594723E-001 + 420 0 0-2.9467751720422E-001-1.2714123475365E+000-1.1455419658630E-001 + 421 0 0-2.5851091511232E-001-1.1930330604922E+000-1.1428983722537E-001 + 422 0 0-2.2234431302041E-001-1.1146537734479E+000-1.1402547786444E-001 + 423 0 0-1.8617771092851E-001-1.0362744864037E+000-1.1376111850351E-001 + 424 0 0-1.5001110883660E-001-9.5789519935938E-001-1.1349675914258E-001 + 425 0 0-4.7484588084386E-001-1.5749468139465E+000-1.2205767049497E-001 + 426 0 0-4.3913537305714E-001-1.4970056877268E+000-1.2059546085736E-001 + 427 0 0-4.0342486527042E-001-1.4190645615071E+000-1.1913325121976E-001 + 428 0 0-3.6771435748370E-001-1.3411234352875E+000-1.1767104158215E-001 + 429 0 0-3.3200384969699E-001-1.2631823090678E+000-1.1620883194455E-001 + 430 0 0-2.9629334191027E-001-1.1852411828481E+000-1.1474662230694E-001 + 431 0 0-2.6058283412355E-001-1.1073000566284E+000-1.1328441266934E-001 + 432 0 0-2.2487232633684E-001-1.0293589304087E+000-1.1182220303173E-001 + 433 0 0-1.8916181855012E-001-9.5141780418906E-001-1.1035999339413E-001 + 434 0 0-4.2974572877798E-001-1.4979715504739E+000-1.0763884058617E-001 + 435 0 0-3.5604273380313E-001-1.3425164256957E+000-1.0405824231406E-001 + 436 0 0-2.8201492539630E-001-1.1872062899597E+000-1.0088103522092E-001 + 437 0 0-2.0739216662550E-001-1.0321627263107E+000-9.8114263774300E-002 + 438 0 0-1.1440320976020E+000-1.1828959102736E+000-7.3862165545361E-001 + 439 0 0-1.0868310527164E+000-1.1209041524793E+000-7.3739287375466E-001 + 440 0 0-1.0296300078307E+000-1.0589123946850E+000-7.3616409205572E-001 + 441 0 0-9.7242896294511E-001-9.9692063689073E-001-7.3493531035678E-001 + 442 0 0-9.1522791805948E-001-9.3492887909643E-001-7.3370652865783E-001 + 443 0 0-8.5802687317384E-001-8.7293712130213E-001-7.3247774695889E-001 + 444 0 0-8.0082582828821E-001-8.1094536350784E-001-7.3124896525995E-001 + 445 0 0-7.4362478340258E-001-7.4895360571354E-001-7.3002018356100E-001 + 446 0 0-6.8642373851694E-001-6.8696184791925E-001-7.2879140186206E-001 + 447 0 0-9.8742875060201E-001-1.3163861922324E+000-6.6362243020995E-001 + 448 0 0-8.2007312305776E-001-1.4262925220749E+000-5.7514556310021E-001 + 449 0 0-6.5140543326384E-001-1.5103506329990E+000-4.6436399445142E-001 + 450 0 0-5.0037207625118E-001-1.5666424117258E+000-3.1771788214799E-001 + 451 0 0-1.0103599800327E+000-1.1859890484923E+000-6.9956793192638E-001 + 452 0 0-9.3388890734904E-001-1.2510739445053E+000-6.6174299009810E-001 + 453 0 0-8.5206094178679E-001-1.3041736574810E+000-6.1724529512842E-001 + 454 0 0-7.7023297622455E-001-1.3572733704567E+000-5.7274760015875E-001 + 455 0 0-6.8815771874406E-001-1.3972683107779E+000-5.1697216601355E-001 + 456 0 0-6.0608246126357E-001-1.4372632510992E+000-4.6119673186836E-001 + 457 0 0-5.3332335748017E-001-1.4635515094956E+000-3.8787908504087E-001 + 458 0 0-4.6056425369676E-001-1.4898397678921E+000-3.1456143821339E-001 + 459 0 0-4.3187078858835E-001-1.4981949882807E+000-2.1495435644124E-001 + 460 0 0-8.8034748052063E-001-1.1857685744770E+000-6.5985951242591E-001 + 461 0 0-7.2038856003552E-001-1.2882683516454E+000-5.7033654348432E-001 + 462 0 0-5.6074980951251E-001-1.3641928020654E+000-4.5800515982789E-001 + 463 0 0-4.2073791431228E-001-1.4130430462629E+000-3.1136239681510E-001 + 464 0 0-8.9961750831867E-001-1.0586919206697E+000-6.9645567255525E-001 + 465 0 0-8.2680605369223E-001-1.1204632044487E+000-6.5797603475373E-001 + 466 0 0-7.4867509876936E-001-1.1698632686414E+000-6.1295076078181E-001 + 467 0 0-6.7054414384649E-001-1.2192633328341E+000-5.6792548680989E-001 + 468 0 0-5.9298065080397E-001-1.2551928429329E+000-5.1136953729865E-001 + 469 0 0-5.1541715776145E-001-1.2911223530316E+000-4.5481358778742E-001 + 470 0 0-4.4816436634463E-001-1.3136843388326E+000-3.8148847160211E-001 + 471 0 0-3.8091157492780E-001-1.3362463246337E+000-3.0816335541681E-001 + 472 0 0-3.5587784711196E-001-1.3430189796072E+000-2.1149095568202E-001 + 473 0 0-7.7326359728473E-001-1.0551642711358E+000-6.5608807654060E-001 + 474 0 0-6.2069807448006E-001-1.1502705976594E+000-5.6550023513674E-001 + 475 0 0-4.7008106563011E-001-1.2180650020741E+000-4.5159731818682E-001 + 476 0 0-3.4107794750117E-001-1.2594495084875E+000-3.0492714775151E-001 + 477 0 0-7.8887400702554E-001-9.3140122956251E-001-6.9333893264318E-001 + 478 0 0-7.1972114087723E-001-9.8986533782289E-001-6.5420011832748E-001 + 479 0 0-6.4528657299543E-001-1.0355716001538E+000-6.0863755089554E-001 + 480 0 0-5.7085200511363E-001-1.0812778624846E+000-5.6307498346359E-001 + 481 0 0-4.9779848930620E-001-1.1131427568006E+000-5.0572801602490E-001 + 482 0 0-4.2474497349877E-001-1.1450076511166E+000-4.4838104858621E-001 + 483 0 0-3.6299464678666E-001-1.1638301717290E+000-3.7503599433622E-001 + 484 0 0-3.0124432007454E-001-1.1826526923413E+000-3.0169094008622E-001 + 485 0 0-2.7987761759343E-001-1.1878428764168E+000-2.0799038865579E-001 + 486 0 0-6.6617834350521E-001-9.2457229100897E-001-6.5230723462256E-001 + 487 0 0-5.2100754473583E-001-1.0122950930176E+000-5.6063473817637E-001 + 488 0 0-3.7941289288978E-001-1.0719587631179E+000-4.4514113957369E-001 + 489 0 0-2.6141533865999E-001-1.1058492656500E+000-2.9842695466354E-001 + 490 0 0-6.7813016476788E-001-8.0411642495429E-001-6.9021726723932E-001 + 491 0 0-6.1263554613319E-001-8.5927924419504E-001-6.5041435091765E-001 + 492 0 0-5.4189931524561E-001-9.0129578387282E-001-6.0430442190340E-001 + 493 0 0-4.7116308435804E-001-9.4331232355059E-001-5.5819449288916E-001 + 494 0 0-4.0262194831941E-001-9.7111109933489E-001-5.0004786172517E-001 + 495 0 0-3.3408081228079E-001-9.9890987511920E-001-4.4190123056117E-001 + 496 0 0-2.7783358476312E-001-1.0139778570389E+000-3.6853209990102E-001 + 497 0 0-2.2158635724545E-001-1.0290458389586E+000-2.9516296924086E-001 + 498 0 0-2.0388203408698E-001-1.0326601626811E+000-2.0446204387219E-001 + 499 0 0-5.5917555939761E-001-7.9390596511398E-001-6.4857751852704E-001 + 500 0 0-4.2135954929830E-001-8.7428971808001E-001-5.5577921125334E-001 + 501 0 0-2.8874833970450E-001-9.2585185531122E-001-4.3863530217506E-001 + 502 0 0-1.8173319689835E-001-9.5223830353993E-001-2.9179487694690E-001 + 503 0 0-1.1588821265706E+000-1.1683140563054E+000-7.2155339476523E-001 + 504 0 0-1.1016522316153E+000-1.1062712863941E+000-7.1997093686945E-001 + 505 0 0-1.0444223366599E+000-1.0442285164827E+000-7.1838847897368E-001 + 506 0 0-9.8719244170458E-001-9.8218574657134E-001-7.1680602107790E-001 + 507 0 0-9.2996254674923E-001-9.2014297665997E-001-7.1522356318212E-001 + 508 0 0-8.7273265179388E-001-8.5810020674860E-001-7.1364110528634E-001 + 509 0 0-8.1550275683853E-001-7.9605743683723E-001-7.1205864739056E-001 + 510 0 0-7.5827286188318E-001-7.3401466692586E-001-7.1047618949478E-001 + 511 0 0-7.0104296692783E-001-6.7197189701450E-001-7.0889373159900E-001 + 512 0 0-1.0936439999928E+000-1.1139324017158E+000-7.3934887568216E-001 + 513 0 0-9.7966612903371E-001-9.8947420195442E-001-7.3691938067342E-001 + 514 0 0-8.6607461231774E-001-8.6465981618169E-001-7.3438228671653E-001 + 515 0 0-7.5419578692751E-001-7.3827694015112E-001-7.3089663013103E-001 + 516 0 0-2.6219058045181E-001-1.0198993753900E+000-1.9110586948926E-001 + 517 0 0-3.3799903549336E-001-1.1733991757405E+000-1.9592054719560E-001 + 518 0 0-4.1381314384853E-001-1.3268969003982E+000-2.0072945997865E-001 + 519 0 0-4.8963083147879E-001-1.4803936091918E+000-2.0553168131115E-001 + 520 0 0-2.5935224486369E-001-9.3488902040557E-001-2.6691112357786E-001 + 521 0 0-2.9950883456678E-001-1.0104398203713E+000-2.7038953594678E-001 + 522 0 0-3.3960678182162E-001-1.0859984945021E+000-2.7374200401552E-001 + 523 0 0-3.7970472907645E-001-1.1615571686329E+000-2.7709447208426E-001 + 524 0 0-4.1980832964491E-001-1.2371137670709E+000-2.8044117522970E-001 + 525 0 0-4.5991193021336E-001-1.3126703655089E+000-2.8378787837514E-001 + 526 0 0-5.0001911005691E-001-1.3882259480829E+000-2.8712789007005E-001 + 527 0 0-5.4012628990045E-001-1.4637815306568E+000-2.9046790176495E-001 + 528 0 0-5.8023521240942E-001-1.5393371518003E+000-2.9380075209713E-001 + 529 0 0-3.5106871734565E-001-9.9246718822212E-001-3.3920172159548E-001 + 530 0 0-4.3632133754617E-001-1.1402335658022E+000-3.4600353507290E-001 + 531 0 0-5.2159122826906E-001-1.2879925358645E+000-3.5278505726994E-001 + 532 0 0-6.0687288409593E-001-1.4357472178102E+000-3.5954528592405E-001 + 533 0 0-3.5744293043529E-001-9.0227826680248E-001-4.0450590090928E-001 + 534 0 0-4.0262860012451E-001-9.7449455607292E-001-4.0801390724418E-001 + 535 0 0-4.4778327307020E-001-1.0467022595223E+000-4.1146325265286E-001 + 536 0 0-4.9293794601589E-001-1.1189099629716E+000-4.1491259806154E-001 + 537 0 0-5.3810423617033E-001-1.1911123345959E+000-4.1834741711314E-001 + 538 0 0-5.8327052632476E-001-1.2633147062201E+000-4.2178223616475E-001 + 539 0 0-6.2844500230808E-001-1.3355138055918E+000-4.2520245312395E-001 + 540 0 0-6.7361947829140E-001-1.4077129049635E+000-4.2862267008315E-001 + 541 0 0-7.1879922691708E-001-1.4799105782034E+000-4.3202870682875E-001 + 542 0 0-4.6280289815938E-001-9.4540988282830E-001-4.6536413929742E-001 + 543 0 0-5.5748719148123E-001-1.0862653723531E+000-4.7171873369786E-001 + 544 0 0-6.5218938939736E-001-1.2271126079362E+000-4.7804839632799E-001 + 545 0 0-7.4690411837908E-001-1.3679550269508E+000-4.8435348054500E-001 + 546 0 0-4.7344965553652E-001-8.4764850057275E-001-5.1980588551500E-001 + 547 0 0-5.2297719619425E-001-9.1632520958367E-001-5.2271437135065E-001 + 548 0 0-5.7250681657041E-001-9.8497299565915E-001-5.2561962034242E-001 + 549 0 0-6.2203643694656E-001-1.0536207817346E+000-5.2852486933418E-001 + 550 0 0-6.7157234470826E-001-1.1222656456935E+000-5.3141971291271E-001 + 551 0 0-7.2110825246996E-001-1.1909105096524E+000-5.3431455649123E-001 + 552 0 0-7.7064850546836E-001-1.2595538292952E+000-5.3719942374903E-001 + 553 0 0-8.2018875846675E-001-1.3281971489381E+000-5.4008429100684E-001 + 554 0 0-8.6973178663980E-001-1.3968400287715E+000-5.4295983319394E-001 + 555 0 0-5.8341708430916E-001-8.7632673183561E-001-5.7291477476974E-001 + 556 0 0-6.8651271563773E-001-1.0101147014476E+000-5.7783930053745E-001 + 557 0 0-7.8961871503207E-001-1.1438973593392E+000-5.8274464787289E-001 + 558 0 0-8.9273188634190E-001-1.2776770343174E+000-5.8763186986168E-001 + 559 0 0-5.9033749473130E-001-7.7112868686950E-001-6.2112138821150E-001 + 560 0 0-6.4385697242407E-001-8.3632825408755E-001-6.2311517818884E-001 + 561 0 0-6.9742298337648E-001-9.0146843762402E-001-6.2513445496478E-001 + 562 0 0-7.5098899432890E-001-9.6660862116050E-001-6.2715373174073E-001 + 563 0 0-8.0455908596154E-001-1.0317464150933E+000-6.2916423549764E-001 + 564 0 0-8.5812917759417E-001-1.0968842090260E+000-6.3117473925454E-001 + 565 0 0-9.1170209590561E-001-1.1620205643613E+000-6.3317709398553E-001 + 566 0 0-9.6527501421705E-001-1.2271569196966E+000-6.3517944871653E-001 + 567 0 0-1.0188497974235E+000-1.2922926082413E+000-6.3717434783271E-001 + 568 0 0-7.0106491715363E-001-7.8517146050671E-001-6.6679568384181E-001 + 569 0 0-8.1186082306139E-001-9.1235441395455E-001-6.7039741851353E-001 + 570 0 0-9.2266080964937E-001-1.0395349777987E+000-6.7399038016622E-001 + 571 0 0-1.0334636229162E+000-1.1667141030453E+000-6.7757519279299E-001 + 572 0 0-9.6750815573310E-002-8.1975104803592E-001-3.2222856038608E-001 + 573 0 0-7.8768823455648E-002-8.2187336603379E-001-3.2222856038608E-001 + 574 0 0-6.0711063119926E-002-8.2320511896182E-001-3.2222856038608E-001 + 575 0 0-8.1062517151065E-002-8.1723220204343E-001-3.3283840645043E-001 + 576 0 0-2.7059014454680E-002-8.2514661945704E-001-1.6448773502902E-001 + 577 0 0-5.9062912805860E-002-8.2320094010582E-001-2.1921085734109E-001 + 578 0 0-3.6053850140151E-002-8.2485179107181E-001-2.1906797604891E-001 + 579 0 0-1.2978436905170E-002-8.2521470605546E-001-2.1891769202958E-001 + 580 0 0-5.7411336797900E-002-8.2336257855280E-001-2.7064826821750E-001 + 581 0 0-1.6163572250842E-001-8.0944712905244E-001-4.2501170752194E-001 + 582 0 0-1.4330022892915E-001-8.1310848091331E-001-4.2501170752194E-001 + 583 0 0-1.2481775396537E-001-8.1593583682609E-001-4.2501170752194E-001 + 584 0 0-1.3527385859121E-001-8.1000423442698E-001-4.1438137919602E-001 + 585 0 0-4.1555115330167E-001-7.1181760916279E-001-7.2092661208856E-001 + 586 0 0-4.5708778716345E-001-6.8756898720745E-001-7.2185322417713E-001 + 587 0 0-4.9551427419332E-001-6.5866050922285E-001-7.2325776757428E-001 + 588 0 0-2.1406978705669E-001-7.9691254400979E-001-5.3632002364552E-001 + 589 0 0-3.1326664930169E-001-7.6293378715574E-001-6.3434967683563E-001 + 590 0 0-1.9221877977965E-001-8.0137481525009E-001-4.8173811298558E-001 + 591 0 0-2.4113733063015E-001-7.8964114958686E-001-5.3846451844923E-001 + 592 0 0-2.9497183273281E-001-7.6899115692240E-001-5.8729551250752E-001 + 593 0 0-3.4880633483548E-001-7.4834116425795E-001-6.3612650656581E-001 + 594 0 0-4.0294706099946E-001-7.1795507573270E-001-6.7898986537147E-001 + 595 0 0-2.6720205383128E-001-7.8072047178342E-001-5.4077013299195E-001 + 596 0 0-3.8240190452682E-001-7.3075873057813E-001-6.3822340612820E-001 + 597 0 0-5.8621860435149E-001-6.6296703815166E-001-7.2580414382332E-001 + 598 0 0-5.4298051715414E-001-7.0119966457635E-001-7.2387569475922E-001 + 599 0 0-4.9514320702525E-001-7.3349219520926E-001-7.2193784737961E-001 + 600 0 0-5.3579569609242E-002-8.8494088852997E-001-1.9261377932869E-001 + 601 0 0-1.0906673341614E-001-8.7949989773834E-001-2.8146226588762E-001 + 602 0 0-7.6253430281026E-002-8.8356902735542E-001-2.7449774712231E-001 + 603 0 0-4.2489729762829E-002-8.8518816684130E-001-2.6751266897460E-001 + 604 0 0-1.2453223545589E-001-8.7671127646874E-001-3.4559981431835E-001 + 605 0 0-2.0811345387949E-001-8.6132368054266E-001-4.2603562765167E-001 + 606 0 0-1.7281104063075E-001-8.6985352558207E-001-4.1670188151440E-001 + 607 0 0-1.3587037548937E-001-8.7558607396364E-001-4.0738627087375E-001 + 608 0 0-2.3143588668661E-001-8.5396541943632E-001-4.7758704848439E-001 + 609 0 0-3.3080837349051E-001-8.2167221294999E-001-5.4591807253596E-001 + 610 0 0-2.9006073274247E-001-8.3807731329057E-001-5.3847221545439E-001 + 611 0 0-2.4685854798969E-001-8.5061569583295E-001-5.3105779334398E-001 + 612 0 0-3.5400588643523E-001-8.1013510887522E-001-5.8844027090310E-001 + 613 0 0-4.6183330639501E-001-7.5536279524639E-001-6.4257450624411E-001 + 614 0 0-4.1795104012799E-001-7.8219290445987E-001-6.3840832635180E-001 + 615 0 0-3.7061238712935E-001-8.0401264556311E-001-6.3424717994878E-001 + 616 0 0-4.8046577864107E-001-7.4169628451811E-001-6.8114201055551E-001 + 617 0 0-5.0003452467254E-001-6.9438407622149E-001-7.2284805481624E-001 + 618 0 0-6.4705023907536E-001-6.0384609975022E-001-7.7747094398236E-001 + 619 0 0-6.0842653570572E-001-6.4523326199179E-001-7.7747094398236E-001 + 620 0 0-5.6484467552422E-001-6.8136232402663E-001-7.7747094398236E-001 + 621 0 0-5.7638321525745E-001-6.7401127653839E-001-7.5067332036799E-001 + 622 0 0-5.5098393358228E-001-6.1283769827028E-001-7.7047094398237E-001 + 623 0 0-5.1360166031004E-001-6.4644697529733E-001-7.7047094398237E-001 + 624 0 0-4.7241150097169E-001-6.7526343987860E-001-7.7047094398237E-001 + 625 0 0-4.8578003729660E-001-6.6760625574391E-001-7.4616209329860E-001 + 626 0 0-6.4236511073185E-001-5.9422180369523E-001-7.8747094398236E-001 + 627 0 0-6.0431783713994E-001-6.3535163259402E-001-7.8747094398236E-001 + 628 0 0-5.6133577558762E-001-6.7129325523039E-001-7.8747094398236E-001 + 629 0 0-6.0779669428922E-001-6.4179664166133E-001-7.8454346697477E-001 + 630 0 0-5.9323191093920E-001-5.9606910942421E-001-7.8747094398236E-001 + 631 0 0-5.5560173416733E-001-6.3352017226645E-001-7.8747094398236E-001 + 632 0 0-5.1356047218371E-001-6.6594153255132E-001-7.8747094398236E-001 + 633 0 0-5.7995978565363E-001-6.3443590243024E-001-7.8747094398236E-001 + 634 0 0-5.3239313372469E-001-6.3733965331192E-001-7.8231900596618E-001 + 635 0 0-2.3693683525043E-001-8.0938185214099E-001-3.5341965270211E-001 + 636 0 0-2.8886190343290E-001-8.0220442444904E-001-4.1276010121468E-001 + 637 0 0-4.8103647784957E-001-6.9755983780197E-001-6.1519914511161E-001 + 638 0 0-5.1451516410053E-001-6.8941585848386E-001-6.2953028362370E-001 + 639 0 0-1.6622939248708E-001-6.4125852297212E-001-4.0526467843521E-001 + 640 0 0-1.6066650220735E-001-6.1599775139992E-001-4.1443809897408E-001 + 641 0 0-1.5348837820558E-001-6.0775930499092E-001-4.0305796233020E-001 + 642 0 0-1.0020831775449E-001-6.1887998085332E-001-4.0319573602594E-001 + 643 0 0-1.0550085540798E-001-6.2786921913603E-001-4.1446217003100E-001 + 644 0 0-1.0685923801371E-001-6.5388578516303E-001-4.0518924509059E-001 + 645 0 0-4.7797524087764E-001-7.1450501631542E-001-6.5280938390974E-001 + 646 0 0-4.3741494500198E-001-7.2518150000707E-001-6.3654812320263E-001 + 647 0 0-2.0494802080713E-001-8.2751045118032E-001-4.2862187220561E-001 + 648 0 0-1.4995186760851E-001-8.3009074150904E-001-3.6534203756880E-001 + 672 0 0-8.1304854507376E-002-6.2160489127241E-001-4.0276658242962E-001 + 673 0 0-8.6972813975529E-002-6.3063631159317E-001-4.1408447256282E-001 + 674 0 0-8.7389112642237E-002-6.5658844625118E-001-4.0467348802975E-001 + 675 0 0-3.9870421693107E-001-7.6270722901753E-001-6.4637054342821E-001 + 676 0 0-3.6409997419993E-001-7.6575391511015E-001-6.3037967227040E-001 + 677 0 0-1.5436091939736E-001-8.3914455015380E-001-4.1978446753563E-001 + 678 0 0-1.0661412144830E-001-8.3920115235609E-001-3.5847099282556E-001 +N,R5.3,LOC, -1, +EBLOCK,19,SOLID, 328, 105 +(19i9) + 1 2 1 1 0 0 0 0 8 0 224 96 97 105 99 598 586 623 619 + 1 2 1 1 0 0 0 0 8 0 225 598 586 623 619 328 319 363 371 + 1 2 1 1 0 0 0 0 8 0 226 99 105 103 101 619 623 631 627 + 1 2 1 1 0 0 0 0 8 0 227 619 623 631 627 371 363 365 368 + 1 2 1 1 0 0 0 0 8 0 228 168 136 170 171 674 379 672 673 + 1 2 1 1 0 0 0 0 8 0 229 674 379 672 673 644 295 642 643 + 1 2 1 1 0 0 0 0 8 0 230 136 168 128 126 379 674 351 344 + 1 2 1 1 0 0 0 0 8 0 231 379 674 351 344 295 644 307 310 + 1 2 1 1 0 0 0 0 8 0 232 130 128 168 171 355 351 674 673 + 1 2 1 1 0 0 0 0 8 0 233 355 351 674 673 304 307 644 643 + 1 2 1 1 0 0 0 0 8 0 234 169 173 110 112 676 675 614 610 + 1 2 1 1 0 0 0 0 8 0 235 676 675 614 610 646 645 337 335 + 1 2 1 1 0 0 0 0 8 0 236 173 169 122 97 675 676 593 586 + 1 2 1 1 0 0 0 0 8 0 237 675 676 593 586 645 646 322 319 + 1 2 1 1 0 0 0 0 8 0 238 169 112 120 122 676 610 591 593 + 1 2 1 1 0 0 0 0 8 0 239 676 610 591 593 646 335 324 322 + 1 2 1 1 0 0 0 0 8 0 240 124 118 174 172 347 582 677 678 + 1 2 1 1 0 0 0 0 8 0 241 347 582 677 678 313 316 647 648 + 1 2 1 1 0 0 0 0 8 0 242 138 124 172 140 413 347 678 573 + 1 2 1 1 0 0 0 0 8 0 243 413 347 678 573 292 313 648 286 + 1 2 1 1 0 0 0 0 8 0 244 118 120 112 174 582 591 610 677 + 1 2 1 1 0 0 0 0 8 0 245 582 591 610 677 316 324 335 647 + 1 2 1 1 0 0 0 0 8 0 246 112 114 174 174 610 606 677 677 + 1 2 1 1 0 0 0 0 8 0 247 610 606 677 677 335 333 647 647 + 1 2 1 1 0 0 0 0 8 0 248 174 114 116 172 677 606 602 678 + 1 2 1 1 0 0 0 0 8 0 249 677 606 602 678 647 333 331 648 + 1 2 1 1 0 0 0 0 8 0 250 172 116 143 140 678 602 578 573 + 1 2 1 1 0 0 0 0 8 0 251 678 602 578 573 648 331 289 286 + 1 2 1 1 0 0 0 0 8 0 252 110 173 97 96 614 675 586 598 + 1 2 1 1 0 0 0 0 8 0 253 614 675 586 598 337 645 319 328 + 1 2 1 1 0 0 0 0 8 0 254 143 116 88 91 578 602 211 207 + 1 2 1 1 0 0 0 0 8 0 255 578 602 211 207 289 331 178 180 + 1 2 1 1 0 0 0 0 8 0 256 138 136 126 124 413 379 344 347 + 1 2 1 1 0 0 0 0 8 0 257 413 379 344 347 292 295 310 313 + 1 2 1 1 0 0 0 0 8 0 258 171 170 132 130 673 672 360 355 + 1 2 1 1 0 0 0 0 8 0 259 673 672 360 355 643 642 301 304 + 1 2 1 1 0 0 0 0 8 0 260 132 170 136 134 360 672 379 375 + 1 2 1 1 0 0 0 0 8 0 261 360 672 379 375 301 642 295 298 + 1 2 1 1 0 0 0 0 8 0 262 198 211 178 175 201 207 180 176 + 1 2 1 1 0 0 0 0 8 0 263 89 88 211 198 93 91 207 201 + 1 2 1 1 0 0 0 0 8 0 264 432 521 273 183 423 497 331 178 + 1 2 1 1 0 0 0 0 8 0 265 521 534 271 273 497 495 333 331 + 1 2 1 1 0 0 0 0 8 0 266 534 547 269 271 495 493 335 333 + 1 2 1 1 0 0 0 0 8 0 267 547 560 267 269 493 491 337 335 + 1 2 1 1 0 0 0 0 8 0 268 560 510 215 267 491 445 328 337 + 1 2 1 1 0 0 0 0 8 0 269 430 523 521 432 421 484 497 423 + 1 2 1 1 0 0 0 0 8 0 270 523 536 534 521 484 482 495 497 + 1 2 1 1 0 0 0 0 8 0 271 536 549 547 534 482 480 493 495 + 1 2 1 1 0 0 0 0 8 0 272 549 562 560 547 480 478 491 493 + 1 2 1 1 0 0 0 0 8 0 273 562 508 510 560 478 443 445 491 + 1 2 1 1 0 0 0 0 8 0 274 428 525 523 430 419 471 484 421 + 1 2 1 1 0 0 0 0 8 0 275 525 538 536 523 471 469 482 484 + 1 2 1 1 0 0 0 0 8 0 276 538 551 549 536 469 467 480 482 + 1 2 1 1 0 0 0 0 8 0 277 551 564 562 549 467 465 478 480 + 1 2 1 1 0 0 0 0 8 0 278 564 506 508 562 465 441 443 478 + 1 2 1 1 0 0 0 0 8 0 279 426 527 525 428 417 458 471 419 + 1 2 1 1 0 0 0 0 8 0 280 527 540 538 525 458 456 469 471 + 1 2 1 1 0 0 0 0 8 0 281 540 553 551 538 456 454 467 469 + 1 2 1 1 0 0 0 0 8 0 282 553 566 564 551 454 452 465 467 + 1 2 1 1 0 0 0 0 8 0 283 566 504 506 564 452 439 441 465 + 1 2 1 1 0 0 0 0 8 0 284 385 393 527 426 397 399 458 417 + 1 2 1 1 0 0 0 0 8 0 285 393 391 540 527 399 401 456 458 + 1 2 1 1 0 0 0 0 8 0 286 391 389 553 540 401 403 454 456 + 1 2 1 1 0 0 0 0 8 0 287 389 387 566 553 403 405 452 454 + 1 2 1 1 0 0 0 0 8 0 288 387 384 504 566 405 395 439 452 + 1 2 1 1 0 0 0 0 8 0 289 365 368 371 363 222 219 214 225 + 1 2 1 1 0 0 0 0 8 0 290 363 371 328 319 225 214 215 228 + 1 2 1 1 0 0 0 0 8 0 291 295 298 301 642 249 246 243 641 + 1 2 1 1 0 0 0 0 8 0 292 301 304 643 642 243 240 640 641 + 1 2 1 1 0 0 0 0 8 0 293 310 313 292 295 234 232 252 249 + 1 2 1 1 0 0 0 0 8 0 294 178 180 289 331 183 184 259 273 + 1 2 1 1 0 0 0 0 8 0 295 319 328 337 645 228 215 267 638 + 1 2 1 1 0 0 0 0 8 0 296 289 286 648 331 259 255 635 273 + 1 2 1 1 0 0 0 0 8 0 297 331 648 647 333 273 635 636 271 + 1 2 1 1 0 0 0 0 8 0 298 335 333 647 647 269 271 636 636 + 1 2 1 1 0 0 0 0 8 0 299 335 647 316 324 269 636 263 280 + 1 2 1 1 0 0 0 0 8 0 300 648 286 292 313 635 255 252 232 + 1 2 1 1 0 0 0 0 8 0 301 647 648 313 316 636 635 232 263 + 1 2 1 1 0 0 0 0 8 0 302 324 322 646 335 280 282 637 269 + 1 2 1 1 0 0 0 0 8 0 303 322 319 645 646 282 228 638 637 + 1 2 1 1 0 0 0 0 8 0 304 337 335 646 645 267 269 637 638 + 1 2 1 1 0 0 0 0 8 0 305 644 643 304 307 639 640 240 237 + 1 2 1 1 0 0 0 0 8 0 306 307 310 295 644 237 234 249 639 + 1 2 1 1 0 0 0 0 8 0 307 642 643 644 295 641 640 639 249 + 1 2 1 1 0 0 0 0 8 0 308 81 84 83 28 639 640 641 249 + 1 2 1 1 0 0 0 0 8 0 309 28 38 36 81 249 234 237 639 + 1 2 1 1 0 0 0 0 8 0 310 34 84 81 36 240 640 639 237 + 1 2 1 1 0 0 0 0 8 0 311 82 52 50 86 637 269 267 638 + 1 2 1 1 0 0 0 0 8 0 312 86 9 47 82 638 228 282 637 + 1 2 1 1 0 0 0 0 8 0 313 82 47 45 52 637 282 280 269 + 1 2 1 1 0 0 0 0 8 0 314 40 85 87 42 232 635 636 263 + 1 2 1 1 0 0 0 0 8 0 315 26 22 85 40 252 255 635 232 + 1 2 1 1 0 0 0 0 8 0 316 42 87 52 45 263 636 269 280 + 1 2 1 1 0 0 0 0 8 0 317 52 87 54 54 269 636 271 271 + 1 2 1 1 0 0 0 0 8 0 318 87 85 56 54 636 635 273 271 + 1 2 1 1 0 0 0 0 8 0 319 85 22 24 56 635 255 259 273 + 1 2 1 1 0 0 0 0 8 0 320 50 18 9 86 267 215 228 638 + 1 2 1 1 0 0 0 0 8 0 321 24 4 6 56 259 184 183 273 + 1 2 1 1 0 0 0 0 8 0 322 26 40 38 28 252 232 234 249 + 1 2 1 1 0 0 0 0 8 0 323 84 34 32 83 640 240 243 641 + 1 2 1 1 0 0 0 0 8 0 324 32 30 28 83 243 246 249 641 + 1 2 1 1 0 0 0 0 8 0 325 18 16 10 9 215 214 225 228 + 1 2 1 1 0 0 0 0 8 0 326 16 14 12 10 214 219 222 225 + 1 2 1 1 0 0 0 0 8 0 327 178 180 184 183 175 176 188 189 + 1 2 1 1 0 0 0 0 8 0 328 189 183 6 2 188 184 4 1 + -1 +CMBLOCK,REFINE ,NODE, 7 ! users node component definition +(8i10) + 384 395 -396 438 -446 503 -515 +EXTOPT,ATTR, 0, 0, 0 +EXTOPT,ESIZE, 0, 0.0000 +EXTOPT,ACLEAR, 0 +TREF, 0.00000000 +IRLF, 0 +BFUNIF,TEMP,_TINY +ACEL, 0.00000000 , 0.00000000 , 0.00000000 +OMEGA, 0.00000000 , 0.00000000 , 0.00000000 +DOMEGA, 0.00000000 , 0.00000000 , 0.00000000 +CGLOC, 0.00000000 , 0.00000000 , 0.00000000 +CGOMEGA, 0.00000000 , 0.00000000 , 0.00000000 +DCGOMG, 0.00000000 , 0.00000000 , 0.00000000 + +KUSE, 0 +TIME, 0.00000000 +ALPHAD, 0.00000000 +BETAD, 0.00000000 +DMPRAT, 0.00000000 +DMPSTR, 0.00000000 + +CRPLIM, 0.100000000 , 0 +CRPLIM, 0.00000000 , 1 +NCNV, 1, 0.00000000 , 0, 0.00000000 , 0.00000000 + +NEQIT, 0 + +ERESX,DEFA + +/GO +FINISH diff --git a/tests/test_geometry.py b/tests/test_geometry.py index f597deab25..aca6243697 100644 --- a/tests/test_geometry.py +++ b/tests/test_geometry.py @@ -1,7 +1,11 @@ """Test geometry commands""" import numpy as np import pytest -import pyvista as pv + +from conftest import has_dependency, requires + +if has_dependency("pyvista"): + import pyvista as pv from ansys.mapdl.core.mapdl_geometry import Geometry, LegacyGeometry @@ -497,6 +501,7 @@ def test_empty_model(mapdl): assert mapdl.geometry.vnum.size == 0 +@requires("pyvista") @pytest.mark.parametrize( "entity,number", (["keypoints", 8], ["lines", 12], ["areas", 6], ["volumes", 1]) ) @@ -506,6 +511,7 @@ def test_entities_simple_cube(mapdl, cube_solve, entity, number): assert isinstance(entity, pv.MultiBlock) +@requires("pyvista") @pytest.mark.parametrize( "entity,number", (["keypoints", 26], ["lines", 45], ["areas", 28], ["volumes", 6]) ) @@ -519,10 +525,12 @@ def test_create_geometry(mapdl): assert isinstance(mapdl._create_geometry(), Geometry) +@requires("pyvista") def test_get_lines(mapdl, contact_geom_and_mesh): assert isinstance(mapdl.geometry.get_lines(), pv.PolyData) +@requires("pyvista") @pytest.mark.parametrize( "entity,number", (["keypoints", 26], ["lines", 45], ["areas", 28], ["volumes", 6]) ) @@ -548,6 +556,7 @@ def test_geometry_get_apis(mapdl, contact_geom_and_mesh, entity, number): assert len(as_an_array) == number +@requires("pyvista") @pytest.mark.parametrize( "entity,entity_name,number", ( @@ -573,6 +582,7 @@ def test_geometry_names(mapdl, contact_geom_and_mesh, entity, entity_name, numbe assert mb_names == names +@requires("pyvista") def test_geometry_get_item(mapdl, contact_geom_and_mesh): assert isinstance(mapdl.geometry["kp 2"], pv.PolyData) assert mapdl.geometry["kp 2"].n_points > 0 @@ -587,6 +597,7 @@ def test_geometry_get_item(mapdl, contact_geom_and_mesh): assert mapdl.geometry["volume 1"].n_cells > 0 +@requires("pyvista") def test_geometry_get_item_error(mapdl, contact_geom_and_mesh): with pytest.raises(ValueError): mapdl.geometry["l 0"] @@ -595,11 +606,13 @@ def test_geometry_get_item_error(mapdl, contact_geom_and_mesh): mapdl.geometry["kip 0"] +@requires("pyvista") def test_geometry_get_block_error(mapdl, contact_geom_and_mesh): with pytest.raises(KeyError): mapdl.geometry["kp 0"] +@requires("pyvista") def test_build_legacy_geometry(mapdl, contact_geom_and_mesh): leg_geo = LegacyGeometry(mapdl) diff --git a/tests/test_grpc.py b/tests/test_grpc.py index 31630cf4cf..656f3cd1b0 100644 --- a/tests/test_grpc.py +++ b/tests/test_grpc.py @@ -16,10 +16,10 @@ PATH = os.path.dirname(os.path.abspath(__file__)) -# skip entire module unless HAS_GRPC installed or connecting to server -pytestmark = pytest.mark.skip_grpc +from conftest import has_dependency, requires -from conftest import skip_if_not_local +# skip entire module unless HAS_GRPC installed or connecting to server +pytestmark = requires("grpc") def write_tmp_in_mapdl_instance(mapdl, filename, ext="txt"): @@ -258,7 +258,10 @@ def test__download(mapdl, tmpdir): assert out_file.exists() out_file = tmpdir.join("out1_" + file_name) - mapdl._download(file_name, out_file_name=out_file, progress_bar=True) + if has_dependency("tqdm"): + mapdl._download(file_name, out_file_name=out_file, progress_bar=True) + else: + mapdl._download(file_name, out_file_name=out_file) assert out_file.exists() out_file = tmpdir.join("out2_" + file_name) @@ -355,7 +358,7 @@ def test_download_with_extension( os.remove(file) -@skip_if_not_local +@requires("local") def test_download_recursive(mapdl): if mapdl._local: temp_dir = os.path.join(mapdl.directory, "new_folder") diff --git a/tests/test_inline_functions/test_query.py b/tests/test_inline_functions/test_query.py index d7d240a8ff..c132a5a314 100644 --- a/tests/test_inline_functions/test_query.py +++ b/tests/test_inline_functions/test_query.py @@ -1,6 +1,7 @@ import pytest from ansys.mapdl.core.errors import MapdlCommandIgnoredError, MapdlRuntimeError +from conftest import requires class TestParseParameter: @@ -76,7 +77,7 @@ def test_interactive_mode_error(self, mapdl, line_geometry): with mapdl.non_interactive: q.kx(1) - @pytest.mark.skip_grpc # only works in gRPC mode + @requires("grpc") # only works in gRPC mode def test_nopr_mode(self, mapdl, line_geometry): try: # enter no printout mode diff --git a/tests/test_krylov.py b/tests/test_krylov.py index 29efa45a31..18de44fb48 100644 --- a/tests/test_krylov.py +++ b/tests/test_krylov.py @@ -5,6 +5,12 @@ import numpy as np import pytest +from conftest import has_dependency + +if not has_dependency("ansys-math-core"): + # Needs ansys-math-core + pytest.skip(allow_module_level=True) + PATH = os.path.dirname(os.path.abspath(__file__)) # Krylov Apdl Macro Files diff --git a/tests/test_launcher.py b/tests/test_launcher.py index 3cfc64763c..13c414f683 100644 --- a/tests/test_launcher.py +++ b/tests/test_launcher.py @@ -15,19 +15,11 @@ _parse_ip_route, _validate_MPI, _verify_version, - find_ansys, - get_default_ansys, launch_mapdl, update_env_vars, - version_from_path, ) from ansys.mapdl.core.licensing import LICENSES -from conftest import ( - QUICK_LAUNCH_SWITCHES, - skip_if_not_local, - skip_on_linux, - skip_on_windows, -) +from conftest import QUICK_LAUNCH_SWITCHES, requires try: import ansys_corba # noqa: F401 @@ -36,18 +28,28 @@ except: HAS_CORBA = False -# CORBA and console available versions -from ansys.tools.path import get_available_ansys_installations +try: + from ansys.tools.path import ( + find_ansys, + get_available_ansys_installations, + version_from_path, + ) -from ansys.mapdl.core._version import SUPPORTED_ANSYS_VERSIONS as versions + from ansys.mapdl.core.launcher import get_default_ansys -valid_versions = list(get_available_ansys_installations().keys()) + installed_mapdl_versions = list(get_available_ansys_installations().keys()) + try: + V150_EXEC = find_ansys("150")[0] + except ValueError: + V150_EXEC = "" +except: + from conftest import MAPDL_VERSION -try: - V150_EXEC = find_ansys("150")[0] -except ValueError: + installed_mapdl_versions = [MAPDL_VERSION] V150_EXEC = "" +from ansys.mapdl.core._version import SUPPORTED_ANSYS_VERSIONS as versions + paths = [ ("/usr/dir_v2019.1/slv/ansys_inc/v211/ansys/bin/ansys211", 211), ("C:/Program Files/ANSYS Inc/v202/ansys/bin/win64/ANSYS202.exe", 202), @@ -69,8 +71,8 @@ def fake_local_mapdl(mapdl): mapdl._local = False -@skip_if_not_local -@skip_on_linux +@requires("local") +@requires("windows") def test_validate_sw(): # ensure that windows adds msmpi # fake windows path @@ -85,21 +87,24 @@ def test_validate_sw(): assert "msmpi" in add_sw and "INTELMPI" not in add_sw -@skip_if_not_local +@requires("ansys-tools-path") +@requires("local") @pytest.mark.parametrize("path_data", paths) def test_version_from_path(path_data): exec_file, version = path_data assert version_from_path("mapdl", exec_file) == version -@skip_if_not_local +@requires("ansys-tools-path") +@requires("local") def test_catch_version_from_path(): with pytest.raises(RuntimeError): version_from_path("mapdl", "abc") -@skip_if_not_local -@skip_on_windows +@requires("ansys-tools-path") +@requires("local") +@requires("linux") def test_find_ansys_linux(): # assuming ansys is installed, should be able to find it on linux # without env var @@ -108,14 +113,16 @@ def test_find_ansys_linux(): assert isinstance(ver, float) -@skip_if_not_local +@requires("ansys-tools-path") +@requires("local") def test_invalid_mode(): with pytest.raises(ValueError): - exec_file = find_ansys(valid_versions[0])[0] + exec_file = find_ansys(installed_mapdl_versions[0])[0] pymapdl.launch_mapdl(exec_file, mode="notamode", start_timeout=start_timeout) -@skip_if_not_local +@requires("ansys-tools-path") +@requires("local") @pytest.mark.skipif(not os.path.isfile(V150_EXEC), reason="Requires v150") def test_old_version(): exec_file = find_ansys("150")[0] @@ -123,28 +130,31 @@ def test_old_version(): pymapdl.launch_mapdl(exec_file, mode="corba", start_timeout=start_timeout) -@skip_if_not_local -@skip_on_windows -@pytest.mark.console +@requires("ansys-tools-path") +@requires("local") +@requires("linux") +@requires("console") def test_failed_console(): - exec_file = find_ansys(valid_versions[0])[0] + exec_file = find_ansys(installed_mapdl_versions[0])[0] with pytest.raises(ValueError): pymapdl.launch_mapdl(exec_file, mode="console", start_timeout=start_timeout) -@skip_if_not_local -@pytest.mark.parametrize("version", valid_versions) -@pytest.mark.console -@skip_on_windows +@requires("ansys-tools-path") +@requires("local") +@requires("console") +@requires("linux") +@pytest.mark.parametrize("version", installed_mapdl_versions) def test_launch_console(version): exec_file = find_ansys(version)[0] mapdl = pymapdl.launch_mapdl(exec_file, mode="console", start_timeout=start_timeout) assert mapdl.version == int(version) / 10 -@skip_if_not_local -@pytest.mark.corba -@pytest.mark.parametrize("version", valid_versions) +@requires("ansys-tools-path") +@requires("local") +@requires("corba") +@pytest.mark.parametrize("version", installed_mapdl_versions) def test_launch_corba(version): mapdl = pymapdl.launch_mapdl( find_ansys(version)[0], mode="corba", start_timeout=start_timeout @@ -158,7 +168,7 @@ def test_launch_corba(version): assert mapdl_ref() is None -@skip_if_not_local +@requires("local") def test_license_type_keyword(): checks = [] for license_name, license_description in LICENSES.items(): @@ -176,7 +186,7 @@ def test_license_type_keyword(): assert any(checks) -@skip_if_not_local +@requires("local") def test_license_type_keyword_names(): # This test might became a way to check available licenses, which is not the purpose. @@ -198,7 +208,7 @@ def test_license_type_keyword_names(): assert successful_check # if at least one license is ok, this should be true. -@skip_if_not_local +@requires("local") def test_license_type_additional_switch(): # This test might became a way to check available licenses, which is not the purpose. successful_check = False @@ -217,7 +227,8 @@ def test_license_type_additional_switch(): assert successful_check # if at least one license is ok, this should be true. -@skip_if_not_local +@requires("ansys-tools-path") +@requires("local") def test_license_type_dummy(): dummy_license_type = "dummy" with pytest.raises(LicenseServerConnectionError): @@ -227,7 +238,7 @@ def test_license_type_dummy(): ) -@skip_if_not_local +@requires("local") def test_remove_temp_files(): """Ensure the working directory is removed when run_location is not set.""" mapdl = launch_mapdl( @@ -248,7 +259,7 @@ def test_remove_temp_files(): assert os.path.isdir(path) -@skip_if_not_local +@requires("local") def test_remove_temp_files_fail(tmpdir): """Ensure the working directory is not removed when the cwd is changed.""" mapdl = launch_mapdl( @@ -374,22 +385,23 @@ def test_license_product_argument_p_arg_warning(): assert "qwer -p asdf" in _check_license_argument(None, "qwer -p asdf") -valid_versions = [] -valid_versions.extend(list(versions.keys())) -valid_versions.extend([each / 10 for each in versions.keys()]) -valid_versions.extend([str(each) for each in list(versions.keys())]) -valid_versions.extend([str(each / 10) for each in versions.keys()]) -valid_versions.extend(list(versions.values())) +installed_mapdl_versions = [] +installed_mapdl_versions.extend(list(versions.keys())) +installed_mapdl_versions.extend([each / 10 for each in versions.keys()]) +installed_mapdl_versions.extend([str(each) for each in list(versions.keys())]) +installed_mapdl_versions.extend([str(each / 10) for each in versions.keys()]) +installed_mapdl_versions.extend(list(versions.values())) -@pytest.mark.parametrize("version", valid_versions) +@pytest.mark.parametrize("version", installed_mapdl_versions) def test__verify_version_pass(version): ver = _verify_version(version) assert isinstance(ver, int) assert min(versions.keys()) <= ver <= max(versions.keys()) -@skip_if_not_local +@requires("ansys-tools-path") +@requires("local") def test_find_ansys(mapdl): assert find_ansys() is not None @@ -405,7 +417,7 @@ def test_find_ansys(mapdl): assert find_ansys(version="11") -@skip_if_not_local +@requires("local") def test_version(mapdl): version = int(10 * mapdl.version) mapdl_ = launch_mapdl( @@ -416,7 +428,7 @@ def test_version(mapdl): mapdl_.exit() -@skip_if_not_local +@requires("local") def test_raise_exec_path_and_version_launcher(): with pytest.raises(ValueError): launch_mapdl( @@ -427,13 +439,14 @@ def test_raise_exec_path_and_version_launcher(): ) -@skip_on_windows -@skip_if_not_local +@requires("linux") +@requires("local") def test_is_ubuntu(): assert _is_ubuntu() -@skip_if_not_local +@requires("ansys-tools-path") +@requires("local") def test_get_default_ansys(): assert get_default_ansys() is not None diff --git a/tests/test_launcher_remote.py b/tests/test_launcher_remote.py index cdf4a23f87..86c1067652 100644 --- a/tests/test_launcher_remote.py +++ b/tests/test_launcher_remote.py @@ -1,4 +1,11 @@ """Test the PyPIM integration.""" +import pytest + +from conftest import has_dependency + +if not has_dependency("ansys-platform-instancemanagement"): + pytest.skip(allow_module_level=True) + from unittest.mock import create_autospec import ansys.platform.instancemanagement as pypim diff --git a/tests/test_licensing.py b/tests/test_licensing.py index b9950f82ed..ec62eed25e 100644 --- a/tests/test_licensing.py +++ b/tests/test_licensing.py @@ -9,7 +9,7 @@ from ansys.mapdl.core import errors, launch_mapdl, licensing from ansys.mapdl.core.misc import threaded from conftest import ON_LOCAL as IS_LOCAL -from conftest import QUICK_LAUNCH_SWITCHES, skip_if_not_local +from conftest import QUICK_LAUNCH_SWITCHES, requires try: LIC_INSTALLED = os.path.isfile(licensing.get_ansys_license_utility_path()) @@ -141,7 +141,7 @@ def test_get_ansys_license_debug_file_tail(tmpdir, license_checker): assert "CHECKOUT" in line -@skip_if_not_local +@requires("local") @skip_no_lic_bin def test_check_license_file_fail(license_checker): with pytest.raises(TimeoutError): @@ -158,7 +158,7 @@ def test_license_checker(tmpdir, license_checker): assert license_checker.check() -@skip_if_not_local +@requires("local") @skip_no_lic_bin def test_check_license_file(tmpdir): timeout = 15 @@ -238,6 +238,7 @@ def test_check_license_file_exception(license_checker): license_checker._check_license_file(0.01) +@requires("ansys-tools-path") def test_license_wait(): license_checker = licensing.LicenseChecker() assert not license_checker._lic_file_thread @@ -272,6 +273,7 @@ def test_license_check(): license_checker.check() +@requires("ansys-tools-path") def test_stop_license_checker(): license_checker = licensing.LicenseChecker() @@ -284,6 +286,7 @@ def test_stop_license_checker(): assert not license_checker._lic_file_thread.is_alive() +@requires("ansys-tools-path") def test_is_connected_license_checker(): license_checker = licensing.LicenseChecker() diff --git a/tests/test_logging.py b/tests/test_logging.py index 8ad8b81701..b788d5f097 100644 --- a/tests/test_logging.py +++ b/tests/test_logging.py @@ -7,7 +7,7 @@ from ansys.mapdl.core import LOG # Global logger from ansys.mapdl.core import logging -from conftest import skip_if_no_has_grpc +from conftest import requires ## Notes # Use the next fixtures for: @@ -172,7 +172,7 @@ def test_global_logger_debug_levels(caplog): ) -@skip_if_no_has_grpc +@requires("grpc") def test_global_logger_format(): # Since we cannot read the format of our logger, because pytest just dont show the console output or # if it does, it formats the logger with its own formatter, we are going to check the logger handlers @@ -195,7 +195,7 @@ def test_global_logger_format(): assert "This is a message" in log -@skip_if_no_has_grpc +@requires("grpc") def test_instance_logger_format(mapdl): # Since we cannot read the format of our logger, because pytest just dont show the console output or # if it does, it formats the logger with its own formatter, we are going to check the logger handlers diff --git a/tests/test_mapdl.py b/tests/test_mapdl.py index b99490ad48..bab5602e29 100644 --- a/tests/test_mapdl.py +++ b/tests/test_mapdl.py @@ -6,18 +6,22 @@ import shutil import time -from ansys.mapdl.reader import examples -from ansys.mapdl.reader.rst import Result import grpc import numpy as np import psutil import pytest -from pyvista import MultiBlock + +from conftest import has_dependency + +if has_dependency("pyvista"): + from pyvista import MultiBlock + +if has_dependency("ansys-mapdl-reader"): + from ansys.mapdl.reader.rst import Result from ansys.mapdl import core as pymapdl from ansys.mapdl.core.commands import CommandListingOutput from ansys.mapdl.core.errors import ( - DifferentSessionConnectionError, IncorrectWorkingDirectory, MapdlCommandIgnoredError, MapdlConnectionError, @@ -26,14 +30,11 @@ from ansys.mapdl.core.launcher import launch_mapdl from ansys.mapdl.core.mapdl_grpc import SESSION_ID_NAME from ansys.mapdl.core.misc import random_string -from conftest import ( - IS_SMP, - ON_LOCAL, - QUICK_LAUNCH_SWITCHES, - skip_if_not_local, - skip_if_on_cicd, - skip_on_windows, -) +from conftest import IS_SMP, ON_CI, ON_LOCAL, QUICK_LAUNCH_SWITCHES, requires + +# Path to files needed for examples +PATH = os.path.dirname(os.path.abspath(__file__)) +test_files = os.path.join(PATH, "test_files") CMD_BLOCK = """/prep7 ! Mat @@ -156,7 +157,7 @@ def warns_in_cdread_error_log(mapdl, tmpdir): return any(warns) -@pytest.mark.skip_grpc +@requires("grpc") def test_internal_name_grpc(mapdl): assert str(mapdl._ip) in mapdl.name assert str(mapdl._port) in mapdl.name @@ -181,7 +182,7 @@ def test_jobname(mapdl, cleared): assert mapdl.jobname == other_jobname -@pytest.mark.skip_grpc +@requires("grpc") def test_server_version(mapdl): if mapdl.version == 20.2: assert mapdl._server_version == (0, 0, 0) @@ -196,7 +197,7 @@ def test_server_version(mapdl): assert mapdl._server_version[0] >= 0 -@pytest.mark.skip_grpc +@requires("grpc") def test_global_mute(mapdl): mapdl.mute = True assert mapdl.mute is True @@ -218,7 +219,7 @@ def test_parsav_parres(mapdl, cleared, tmpdir): assert np.allclose(mapdl.parameters["MYARR"], arr) -@pytest.mark.skip_grpc +@requires("grpc") def test_no_results(mapdl, cleared, tmpdir): pth = str(tmpdir.mkdir("tmpdir")) mapdl.jobname = random_string() @@ -306,7 +307,8 @@ def test_allow_ignore(mapdl): mapdl.allow_ignore = True assert mapdl.allow_ignore is True mapdl.k() - assert mapdl.geometry.n_keypoint == 0 + with pytest.raises(ValueError, match="There are no KEYPOINTS defined"): + mapdl.get_value("KP", 0, "count") mapdl.allow_ignore = False @@ -347,7 +349,7 @@ def test_ignore_error(mapdl): assert mapdl.ignore_error is False -@pytest.mark.skip_grpc +@requires("grpc") def test_list(mapdl, tmpdir): """Added for backwards compatibility""" fname = "tmp.txt" @@ -361,7 +363,7 @@ def test_list(mapdl, tmpdir): assert output == txt -@pytest.mark.skip_grpc +@requires("grpc") def test_invalid_input(mapdl): with pytest.raises(FileNotFoundError): mapdl.input("thisisnotafile") @@ -378,11 +380,14 @@ def test_keypoints(cleared, mapdl): knum.append(i + 1) assert mapdl.geometry.n_keypoint == 4 - assert isinstance(mapdl.geometry.keypoints, MultiBlock) - assert np.allclose(kps, mapdl.geometry.get_keypoints(return_as_array=True)) assert np.allclose(knum, mapdl.geometry.knum) + if has_dependency("pyvista"): + assert isinstance(mapdl.geometry.keypoints, MultiBlock) + assert np.allclose(kps, mapdl.geometry.get_keypoints(return_as_array=True)) + +@requires("pyvista") def test_lines(cleared, mapdl): assert mapdl.geometry.n_line == 0 @@ -396,12 +401,14 @@ def test_lines(cleared, mapdl): l3 = mapdl.l(k3, k0) lines = mapdl.geometry.lines - assert isinstance(lines, MultiBlock) assert np.allclose(mapdl.geometry.lnum, [l0, l1, l2, l3]) assert mapdl.geometry.n_line == 4 + if has_dependency("pyvista"): + assert isinstance(lines, MultiBlock) -@skip_if_not_local + +@requires("local") def test_apdl_logging_start(tmpdir): filename = str(tmpdir.mkdir("tmpdir").join("tmp.inp")) @@ -429,7 +436,7 @@ def test_apdl_logging_start(tmpdir): assert "K,4,0,1,0" in text -@pytest.mark.corba +@requires("corba") def test_corba_apdl_logging_start(tmpdir): filename = str(tmpdir.mkdir("tmpdir").join("tmp.inp")) @@ -692,6 +699,7 @@ def test_partial_mesh_nnum(mapdl, make_block): assert np.allclose(allsel_nnum_old, mapdl.mesh.nnum) +@requires("pyvista") def test_partial_mesh_nnum2(mapdl, make_block): mapdl.nsel("S", "NODE", vmin=1, vmax=10) mapdl.esel("S", "ELEM", vmin=10, vmax=20) @@ -702,7 +710,7 @@ def test_cyclic_solve(mapdl, cleared): # build the cyclic model mapdl.prep7() mapdl.shpp("off") - mapdl.cdread("db", examples.sector_archive_file) + mapdl.cdread("db", os.path.join(test_files, "sector.cdb")) mapdl.prep7() time.sleep(1.0) mapdl.cyclic() @@ -785,7 +793,7 @@ def test_load_array_failure_types(mapdl, array): assert mapdl.parameters["myarr"].ndim == array.ndim + 1 -@pytest.mark.skip_grpc +@requires("grpc") def test_lssolve(mapdl, cleared): mapdl.mute = True @@ -881,7 +889,7 @@ def test_cdread(mapdl, cleared): mapdl.cdread("test", "model2", "cdb") -@skip_if_not_local +@requires("local") def test_cdread_different_location(mapdl, cleared, tmpdir): random_letters = mapdl.directory.split("/")[0][-3:0] dirname = "tt" + random_letters @@ -1027,7 +1035,7 @@ def test_inval_commands_silent(mapdl, tmpdir, cleared): mapdl._run("/gopr") # getting settings back -@skip_if_not_local +@requires("local") def test_path_without_spaces(mapdl, path_tests): old_path = mapdl.directory try: @@ -1037,7 +1045,7 @@ def test_path_without_spaces(mapdl, path_tests): mapdl.directory = old_path -@skip_if_not_local +@requires("local") def test_path_with_spaces(mapdl, path_tests): old_path = mapdl.directory try: @@ -1047,7 +1055,7 @@ def test_path_with_spaces(mapdl, path_tests): mapdl.directory = old_path -@skip_if_not_local +@requires("local") def test_path_with_single_quote(mapdl, path_tests): with pytest.raises(MapdlRuntimeError): mapdl.cwd(path_tests.path_with_single_quote) @@ -1077,7 +1085,8 @@ def test_cwd(mapdl, tmpdir): mapdl.cwd(old_path) -@skip_if_on_cicd +@requires("nocicd") +@requires("local") def test_inquire(mapdl): # Testing basic functions (First block: Functions) assert "apdl" in mapdl.inquire("", "apdl").lower() @@ -1110,6 +1119,7 @@ def test_ksel(mapdl, cleared): mapdl.prep7() assert "SELECTED" in mapdl.ksel("S", "KP", vmin=1, return_mapdl_output=True) assert "SELECTED" in mapdl.ksel("S", "KP", "", 1, return_mapdl_output=True) + assert 1 in mapdl.ksel("S", "KP", vmin=1) @@ -1304,7 +1314,10 @@ def test_mpfunctions(mapdl, cube_solve, capsys): captured = capsys.readouterr() # To flush it output = mapdl.mpread(fname, ext) captured = capsys.readouterr() - assert f"Uploading {fname}.{ext}:" in captured.err + if has_dependency("tqdm"): + # Printing uploading requires tqdm + assert f"Uploading {fname}.{ext}:" in captured.err + assert "PROPERTY TEMPERATURE TABLE NUM. TEMPS= 1" in output assert "TEMPERATURE TABLE ERASED." in output assert "0.4000000" in output @@ -1359,7 +1372,7 @@ def test_result_file(mapdl, solved_box): assert isinstance(mapdl.result_file, str) -@skip_if_not_local +@requires("local") def test_file_command_local(mapdl, cube_solve, tmpdir): rst_file = mapdl.result_file @@ -1422,7 +1435,7 @@ def test_file_command_remote(mapdl, cube_solve, tmpdir): assert "DATA FILE CHANGED TO FILE" in output -@skip_on_windows +@requires("linux") def test_lgwrite(mapdl, cleared, tmpdir): filename = str(tmpdir.join("file.txt")) @@ -1493,7 +1506,7 @@ def test_non_interactive(mapdl, cleared): mapdl.k(1, 1, 1, 1) mapdl.k(2, 2, 2, 2) - assert len(mapdl.geometry.keypoints) == 2 + assert mapdl.get_value("KP", 0, "count") == 2 def test_ignored_command(mapdl, cleared): @@ -1720,7 +1733,7 @@ def test_get_file_name(mapdl): ) -@skip_if_not_local +@requires("local") def test_cache_pids(mapdl): assert mapdl._pids mapdl._cache_pids() # Recache pids @@ -1729,7 +1742,7 @@ def test_cache_pids(mapdl): assert "ansys" in "".join(psutil.Process(each).cmdline()) -@skip_if_not_local +@requires("local") def test_process_is_alive(mapdl): assert mapdl.process_is_alive @@ -1785,18 +1798,6 @@ def test_session_id(mapdl, running_test): mapdl._session_id_ = id_ -def test_session_id_different(mapdl, running_test): - # Assert it works - with running_test(): - assert mapdl.prep7() - - mapdl._run(f"{SESSION_ID_NAME}='1234'") - - with running_test(): - with pytest.raises(DifferentSessionConnectionError): - mapdl.prep7() - - def test_check_empty_session_id(mapdl): # it should run normal mapdl._session_id_ = None @@ -1805,6 +1806,7 @@ def test_check_empty_session_id(mapdl): assert mapdl.prep7() +@requires("requests") # Requires 'requests' package def test_igesin_whitespace(mapdl, cleared, tmpdir): bracket_file = pymapdl.examples.download_bracket() assert os.path.isfile(bracket_file) @@ -1822,7 +1824,7 @@ def test_igesin_whitespace(mapdl, cleared, tmpdir): assert int(n_ent[0]) > 0 -@skip_if_not_local +@requires("local") def test_save_on_exit(mapdl, cleared): mapdl2 = launch_mapdl( license_server_check=False, additional_switches=QUICK_LAUNCH_SWITCHES @@ -1920,6 +1922,7 @@ def num_(): assert [1, 2, 4] == mapdl.mesh.rlblock_num +@requires("ansys-mapdl-reader") def test_download_results_non_local(mapdl, cube_solve): assert mapdl.result is not None assert isinstance(mapdl.result, Result) @@ -1971,7 +1974,7 @@ def test_port(mapdl): def test_distributed(mapdl): - if IS_SMP and not ON_LOCAL: + if ON_CI and IS_SMP and not ON_LOCAL: assert not mapdl._distributed else: assert mapdl._distributed @@ -2006,6 +2009,7 @@ def test_check_parameter_names(mapdl): mapdl.check_parameter_names = True # returning to default +@requires("pyvista") def test_components_selection_keep_between_plots(mapdl, cube_solve): mapdl.cm("mycm", "volu") assert "MYCM" in mapdl.cmlist() diff --git a/tests/test_mesh_grpc.py b/tests/test_mesh_grpc.py index 7667c6ac97..40de300285 100644 --- a/tests/test_mesh_grpc.py +++ b/tests/test_mesh_grpc.py @@ -3,7 +3,11 @@ import numpy as np import pytest -import pyvista as pv + +from conftest import has_dependency, requires + +if has_dependency("pyvista"): + import pyvista as pv from ansys.mapdl.core import examples @@ -94,9 +98,10 @@ def test_empty_mesh(mapdl, cleared): assert not mapdl.mesh._has_nodes # Others - assert mapdl.mesh.grid is None - with pytest.raises(ValueError): - mapdl.mesh.save("file.vtk") + if has_dependency("pyvista"): + assert mapdl.mesh.grid is None + with pytest.raises(ValueError): + mapdl.mesh.save("file.vtk") def test_non_empty_mesh(mapdl, contact_geom_and_mesh): @@ -137,9 +142,11 @@ def test_non_empty_mesh(mapdl, contact_geom_and_mesh): assert mapdl.mesh._has_nodes # Others - assert isinstance(mapdl.mesh.grid, pv.UnstructuredGrid) - assert mapdl.mesh.grid.n_cells > 0 - assert mapdl.mesh.grid.n_points > 0 + if has_dependency("pyvista"): + assert isinstance(mapdl.mesh.grid, pv.UnstructuredGrid) + + assert mapdl.mesh.grid.n_cells > 0 + assert mapdl.mesh.grid.n_points > 0 def test_tshape_key(mapdl, contact_geom_and_mesh): @@ -152,6 +159,7 @@ def test_tshape_key(mapdl, contact_geom_and_mesh): assert tshape.size > 0 +@requires("pyvista") def test_save(mapdl, cube_geom_and_mesh): # This test seems to fail when parallelized. fname = "mesh.vtk" diff --git a/tests/test_misc.py b/tests/test_misc.py index 3d7d9e32df..fc1bdd713d 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -4,7 +4,11 @@ import numpy as np import pytest -from pyvista.plotting import system_supports_plotting + +from conftest import has_dependency, requires + +if has_dependency("pyvista"): + from pyvista.plotting import system_supports_plotting from ansys.mapdl import core as pymapdl from ansys.mapdl.core.misc import ( @@ -20,6 +24,7 @@ ) +@requires("pyvista") def test_report(): report = pymapdl.Report( additional=["matplotlib", "pyvista", "pyiges", "tqdm"], @@ -291,7 +296,21 @@ def test_plain_report(): # There should be only one package not found ("ger") assert "Package not found" in rep_str - _rep_str = rep_str.replace("Package not found", "", 1) + not_found_packages = 1 + + # Plus the not additional packages + if not has_dependency("pyvista"): + not_found_packages += 1 + if not has_dependency("tqdm"): + not_found_packages += 1 + if not has_dependency("ansys.mapdl.reader"): + not_found_packages += 1 + if not has_dependency("scipy"): + not_found_packages += 1 + if not has_dependency("pexpect"): + not_found_packages += 1 + + _rep_str = rep_str.replace("Package not found", "", not_found_packages) assert "Package not found" not in _rep_str assert "\n" in rep_str diff --git a/tests/test_plotting.py b/tests/test_plotting.py index ab6199a04c..d0710e4679 100644 --- a/tests/test_plotting.py +++ b/tests/test_plotting.py @@ -3,6 +3,12 @@ import numpy as np import pytest + +from conftest import has_dependency + +if not has_dependency("pyvista"): + pytest.skip(allow_module_level=True) + from pyvista.plotting import Plotter from ansys.mapdl.core.errors import ComponentDoesNotExits diff --git a/tests/test_pool.py b/tests/test_pool.py index 302e3c66ed..2e18ee4303 100644 --- a/tests/test_pool.py +++ b/tests/test_pool.py @@ -2,16 +2,28 @@ from pathlib import Path import time -from ansys.tools.path import find_ansys import numpy as np import pytest +from conftest import has_dependency + +if has_dependency("ansys-tools-path"): + from ansys.tools.path import find_ansys + + EXEC_FILE = find_ansys()[0] + +else: + EXEC_FILE = os.environ.get("PYMAPDL_MAPDL_EXEC") + +if not EXEC_FILE: + pytest.skip(allow_module_level=True) + from ansys.mapdl.core import LocalMapdlPool, examples from ansys.mapdl.core.errors import VersionError -from conftest import QUICK_LAUNCH_SWITCHES, skip_if_not_local +from conftest import QUICK_LAUNCH_SWITCHES, requires # skip entire module unless HAS_GRPC -pytestmark = pytest.mark.skip_grpc +pytestmark = requires("grpc") skip_if_ignore_pool = pytest.mark.skipif( @@ -31,7 +43,6 @@ @pytest.fixture(scope="module") def pool(tmpdir_factory): - EXEC_FILE = find_ansys()[0] run_path = str(tmpdir_factory.mktemp("ansys_pool")) mapdl_pool = LocalMapdlPool( @@ -78,7 +89,7 @@ def test_invalid_exec(): @pytest.mark.xfail(strict=False, reason="Flaky test. See #2435") -@skip_if_not_local +@requires("local") def test_heal(pool): pool_sz = len(pool) pool[0].exit() @@ -96,7 +107,7 @@ def test_heal(pool): pool._verify_unique_ports() -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_simple_map(pool): pool_sz = len(pool) @@ -104,7 +115,7 @@ def test_simple_map(pool): assert len(pool) == pool_sz -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_map_timeout(pool): pool_sz = len(pool) @@ -131,7 +142,7 @@ def func(mapdl, tsleep): assert len(pool) == pool_sz -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_simple(pool): pool_sz = len(pool) @@ -145,7 +156,7 @@ def func(mapdl): # fails intermittently -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_batch(pool): input_files = [examples.vmfiles["vm%d" % i] for i in range(1, 11)] @@ -154,7 +165,7 @@ def test_batch(pool): # fails intermittently -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_map(pool): completed_indices = [] @@ -168,12 +179,12 @@ def func(mapdl, input_file, index): return mapdl.parameters.routine inputs = [(examples.vmfiles["vm%d" % i], i) for i in range(1, 11)] - outputs = pool.map(func, inputs, progress_bar=True, wait=True) + outputs = pool.map(func, inputs, wait=True) assert len(outputs) == len(inputs) -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_abort(pool, tmpdir): pool_sz = len(pool) # initial pool size @@ -208,7 +219,7 @@ def test_abort(pool, tmpdir): assert path_deleted -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_directory_names_default(pool): dirs_path_pool = os.listdir(pool._root_dir) @@ -218,11 +229,12 @@ def test_directory_names_default(pool): assert "Instance_3" in dirs_path_pool -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_directory_names_custom_string(tmpdir): pool = LocalMapdlPool( 2, + exec_file=EXEC_FILE, run_location=tmpdir, nproc=NPROC, names="my_instance", @@ -237,7 +249,7 @@ def test_directory_names_custom_string(tmpdir): pool.exit(block=True) -@skip_if_not_local +@requires("local") @skip_if_ignore_pool def test_directory_names_function(tmpdir): def myfun(i): @@ -250,6 +262,7 @@ def myfun(i): pool = LocalMapdlPool( 3, + exec_file=EXEC_FILE, nproc=NPROC, names=myfun, run_location=tmpdir, diff --git a/tests/test_post.py b/tests/test_post.py index 4067707b5b..fdbf24d702 100644 --- a/tests/test_post.py +++ b/tests/test_post.py @@ -4,8 +4,12 @@ import numpy as np import pytest -from pyvista import Plotter -from pyvista.plotting.renderer import CameraPosition + +from conftest import has_dependency, requires + +if has_dependency("pyvista"): + from pyvista import Plotter + from pyvista.plotting.renderer import CameraPosition from ansys.mapdl.core import examples from ansys.mapdl.core.post import ( @@ -151,12 +155,14 @@ def test_disp_norm_all(mapdl, static_solve): @pytest.mark.parametrize("comp", ["X", "Y", "z", "norm"]) # lowercase intentional +@requires("pyvista") def test_disp_plot(mapdl, static_solve, comp): assert ( mapdl.post_processing.plot_nodal_displacement(comp, smooth_shading=True) is None ) +@requires("pyvista") def test_disp_plot_subselection(mapdl, static_solve, verify_image_cache): verify_image_cache.skip = True # skipping image verification @@ -171,9 +177,7 @@ def test_disp_plot_subselection(mapdl, static_solve, verify_image_cache): mapdl.allsel() -def test_nodal_eqv_stress(mapdl, static_solve, verify_image_cache): - verify_image_cache.skip = True # skipping image verification - +def test_nodal_eqv_stress(mapdl, static_solve): mapdl.post1(mute=True) mapdl.set(1, 1, mute=True) @@ -187,6 +191,7 @@ def test_nodal_eqv_stress(mapdl, static_solve, verify_image_cache): assert np.allclose(seqv_ans, seqv_aligned) +@requires("pyvista") def test_plot_nodal_eqv_stress(mapdl, static_solve, verify_image_cache): verify_image_cache.skip = True # skipping image verification @@ -226,6 +231,7 @@ def test_rot(mapdl, static_solve, comp): @pytest.mark.parametrize("comp", ["X", "Y", "z"]) # lowercase intentional +@requires("pyvista") def test_plot_rot(mapdl, static_solve, comp): assert mapdl.post_processing.plot_nodal_rotation(comp) is None @@ -244,11 +250,13 @@ def test_element_temperature(mapdl, static_solve): assert np.allclose(values, 0) +@requires("pyvista") def test_plot_element_temperature(mapdl, static_solve): mapdl.set(1, 1, mute=True) assert mapdl.post_processing.plot_element_temperature() is None +@requires("pyvista") def test_plot_temperature(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_temperature() is None @@ -259,6 +267,7 @@ def test_pressure(mapdl, static_solve): assert np.allclose(from_grpc, 0) +@requires("pyvista") def test_plot_pressure(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_pressure() is None @@ -269,6 +278,7 @@ def test_voltage(mapdl, static_solve): assert np.allclose(from_grpc, 0) +@requires("pyvista") def test_plot_voltage(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_voltage() is None @@ -290,6 +300,7 @@ def test_nodal_component_stress(mapdl, static_solve, comp): assert np.allclose(from_grpc, from_prns) +@requires("pyvista") def test_plot_nodal_component_stress(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_component_stress("X") is None @@ -311,6 +322,7 @@ def test_nodal_principal_stress(mapdl, static_solve, comp): assert np.allclose(from_grpc, from_prns) +@requires("pyvista") def test_plot_nodal_principal_stress(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_principal_stress(1) is None @@ -329,6 +341,7 @@ def test_nodal_stress_intensity(mapdl, static_solve): assert np.allclose(sint_ans, sint_aligned) +@requires("pyvista") def test_plot_nodal_stress_intensity(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_stress_intensity() is None @@ -350,6 +363,7 @@ def test_nodal_total_component_strain(mapdl, static_solve, comp): assert np.allclose(data_ans, data) +@requires("pyvista") def test_plot_nodal_total_component_strain(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_total_component_strain("x") is None @@ -371,6 +385,7 @@ def test_nodal_principal_total_strain(mapdl, static_solve, comp): assert np.allclose(from_grpc, from_prns) +@requires("pyvista") def test_plot_nodal_principal_total_strain(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_total_principal_strain(1) is None @@ -389,6 +404,7 @@ def test_nodal_total_strain_intensity(mapdl, static_solve): assert np.allclose(sint_ans, sint_aligned) +@requires("pyvista") def test_plot_nodal_total_strain_intensity(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_total_strain_intensity() is None @@ -407,6 +423,7 @@ def test_nodal_total_eqv_strain(mapdl, static_solve): assert np.allclose(seqv_ans, seqv_aligned) +@requires("pyvista") def test_plot_nodal_total_eqv_strain(mapdl, static_solve): assert ( mapdl.post_processing.plot_nodal_total_eqv_strain(smooth_shading=True) is None @@ -431,6 +448,7 @@ def test_nodal_component_stress(mapdl, static_solve, comp): assert np.allclose(from_grpc, from_prns) +@requires("pyvista") def test_plot_nodal_component_stress(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_component_stress("X") is None @@ -451,6 +469,7 @@ def test_nodal_principal_stress(mapdl, static_solve, comp): assert np.allclose(from_grpc, from_prns, atol=1e-5) +@requires("pyvista") def test_plot_nodal_principal_stress(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_principal_stress(1) is None @@ -469,6 +488,7 @@ def test_nodal_stress_intensity(mapdl, static_solve): assert np.allclose(sint_ans, sint_aligned) +@requires("pyvista") def test_plot_nodal_stress_intensity(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_stress_intensity() is None @@ -490,6 +510,7 @@ def test_nodal_elastic_component_strain(mapdl, static_solve, comp): assert np.allclose(data_ans, data) +@requires("pyvista") def test_plot_nodal_elastic_component_strain(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_elastic_component_strain("x") is None @@ -511,6 +532,7 @@ def test_nodal_elastic_principal_strain(mapdl, static_solve, comp): assert np.allclose(from_grpc, from_prns) +@requires("pyvista") def test_plot_nodal_elastic_principal_strain(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_elastic_principal_strain(1) is None @@ -529,6 +551,7 @@ def test_nodal_elastic_strain_intensity(mapdl, static_solve): assert np.allclose(sint_ans, sint_aligned) +@requires("pyvista") def test_plot_nodal_elastic_strain_intensity(mapdl, static_solve): assert mapdl.post_processing.plot_nodal_elastic_strain_intensity() is None @@ -547,6 +570,7 @@ def test_nodal_elastic_eqv_strain(mapdl, static_solve): assert np.allclose(seqv_ans, seqv_aligned) +@requires("pyvista") def test_plot_nodal_elastic_eqv_strain(mapdl, static_solve): assert ( mapdl.post_processing.plot_nodal_elastic_eqv_strain(smooth_shading=True) is None @@ -595,6 +619,7 @@ def test_elem_disp_norm(mapdl, static_solve): @pytest.mark.parametrize("comp", ["X", "Y", "Z", "NORM"]) +@requires("pyvista") def test_elem_disp_plot(mapdl, static_solve, comp): mapdl.post1(mute=True) mapdl.set(1, 1, mute=True) @@ -616,12 +641,14 @@ def test_element_stress(mapdl, static_solve, component, option): @pytest.mark.parametrize("comp", ["X", "1", "INT", "EQV"]) +@requires("pyvista") def test_plot_element_stress(mapdl, static_solve, comp): mapdl.post1(mute=True) mapdl.set(1, 1, mute=True) assert mapdl.post_processing.plot_element_stress(comp) is None +@requires("pyvista") def test_plot_element_values(mapdl, static_solve, verify_image_cache): verify_image_cache.high_variance_test = 600 mapdl.post1(mute=True) @@ -646,6 +673,7 @@ def test_nodal_plastic_component_strain(mapdl, plastic_solve, comp): assert np.allclose(data_ans, data) +@requires("pyvista") def test_plot_nodal_plastic_component_strain(mapdl, plastic_solve): assert mapdl.post_processing.plot_nodal_plastic_component_strain("x") is None @@ -666,6 +694,7 @@ def test_nodal_plastic_principal_strain(mapdl, plastic_solve, comp): assert np.allclose(from_grpc, from_prns) +@requires("pyvista") def test_plot_nodal_plastic_principal_strain(mapdl, plastic_solve): assert mapdl.post_processing.plot_nodal_plastic_principal_strain(1) is None @@ -681,6 +710,7 @@ def test_nodal_plastic_strain_intensity(mapdl, plastic_solve): assert np.allclose(sint_ans, sint_aligned) +@requires("pyvista") def test_plot_nodal_plastic_strain_intensity(mapdl, plastic_solve): assert mapdl.post_processing.plot_nodal_plastic_strain_intensity() is None @@ -696,6 +726,7 @@ def test_nodal_plastic_eqv_strain(mapdl, plastic_solve): assert np.allclose(seqv_ans, seqv_aligned) +@requires("pyvista") def test_plot_nodal_plastic_eqv_strain(mapdl, plastic_solve): assert ( mapdl.post_processing.plot_nodal_plastic_eqv_strain(smooth_shading=True) is None @@ -721,6 +752,7 @@ def test_nodal_contact_friction_stress(mapdl, contact_solve): assert np.allclose(sfric_prn, sfric_nod) +@requires("pyvista") def test_plot_nodal_contact_friction_stress(mapdl, contact_solve): assert ( mapdl.post_processing.plot_nodal_contact_friction_stress(smooth_shading=True) @@ -728,17 +760,20 @@ def test_plot_nodal_contact_friction_stress(mapdl, contact_solve): ) +@requires("pyvista") def test_plot_incomplete_element_selection(mapdl, contact_solve): mapdl.esel("S", "ELEM", "", 1, mapdl.mesh.n_elem // 2) assert mapdl.post_processing.plot_element_displacement() is None +@requires("pyvista") @pytest.mark.xfail(strict=False, reason="The image regression is failing. See #2435") def test_plot_incomplete_nodal_selection(mapdl, contact_solve): mapdl.nsel("S", "NODE", "", 1, mapdl.mesh.n_node // 2) assert mapdl.post_processing.plot_nodal_displacement() is None +@requires("pyvista") def test_general_plotter_returns(mapdl, static_solve, verify_image_cache): verify_image_cache.skip = True # skipping image verification @@ -857,6 +892,7 @@ def test_meta_post_plot_docstrings(): ), f"Less than three complete one-liner general plotter link in {meth.__name__}" +@requires("pyvista") def test_cuadratic_beam(mapdl, cuadratic_beam_problem): # Display elements with their nodes numbers. mapdl.eplot(show_node_numbering=True, line_width=5, cpos="xy", font_size=40) @@ -887,6 +923,7 @@ def test_cuadratic_beam(mapdl, cuadratic_beam_problem): # assert np.allclose(data_ans, data) +# @requires("pyvista") # def test_plot_nodal_thermal_component_strain(mapdl, thermal_solve): # assert mapdl.post_processing.plot_nodal_thermal_component_strain('x') is None @@ -907,6 +944,7 @@ def test_cuadratic_beam(mapdl, cuadratic_beam_problem): # assert np.allclose(from_grpc, from_prns) +# @requires("pyvista") # def test_plot_nodal_thermal_principal_strain(mapdl, thermal_solve): # assert mapdl.post_processing.plot_nodal_thermal_principal_strain(1) is None @@ -922,6 +960,7 @@ def test_cuadratic_beam(mapdl, cuadratic_beam_problem): # assert np.allclose(sint_ans, sint_aligned) +# @requires("pyvista") # def test_plot_nodal_thermal_strain_intensity(mapdl, thermal_solve): # assert mapdl.post_processing.plot_nodal_thermal_strain_intensity() is None @@ -937,6 +976,7 @@ def test_cuadratic_beam(mapdl, cuadratic_beam_problem): # assert np.allclose(seqv_ans, seqv_aligned) +# @requires("pyvista") # def test_plot_nodal_thermal_eqv_strain(mapdl, thermal_solve): # assert mapdl.post_processing.plot_nodal_thermal_eqv_strain(smooth_shading=True) is None diff --git a/tests/test_theme.py b/tests/test_theme.py index c6945938a1..ecbbaf6fab 100644 --- a/tests/test_theme.py +++ b/tests/test_theme.py @@ -1,3 +1,10 @@ +import pytest + +from conftest import has_dependency + +if not has_dependency("pyvista"): + pytest.skip(allow_module_level=True) + from ansys.mapdl.core.theme import MapdlTheme, _apply_default_theme diff --git a/tests/test_xpl.py b/tests/test_xpl.py index 26281b2086..6885ca112e 100644 --- a/tests/test_xpl.py +++ b/tests/test_xpl.py @@ -4,9 +4,10 @@ import pytest from ansys.mapdl.core.errors import MapdlCommandIgnoredError, MapdlRuntimeError +from conftest import requires # skip entire module unless HAS_GRPC -pytestmark = pytest.mark.skip_grpc +pytestmark = requires("grpc") @pytest.fixture(scope="module") @@ -33,6 +34,7 @@ def test_xpl_str(xpl): assert "file.full" in str(xpl) +@requires("ansys-math-core") def test_read_int32(xpl): vec = xpl.read("MASS") arr = vec.asarray() @@ -40,6 +42,7 @@ def test_read_int32(xpl): assert arr.dtype == np.int32 +@requires("ansys-math-core") def test_read_double(xpl): vec = xpl.read("DIAGK") arr = vec.asarray() @@ -47,6 +50,7 @@ def test_read_double(xpl): assert arr.dtype == np.double +@requires("ansys-math-core") def test_read_asarray(xpl): vec1 = xpl.read("MASS", asarray=True) vec2 = xpl.read("MASS") @@ -109,6 +113,7 @@ def test_goto(xpl): assert "Current Location : FULL::MASS" in xpl.where() +@requires("ansys-math-core") @pytest.mark.usefixtures("check_supports_extract") def test_extract(xpl): # expecting fixture to already have a non-result file open