Skip to content

Fix/lsread to non interactive #1384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 22, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions doc/source/user_guide/mapdl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -834,17 +834,20 @@ These commands are detailed in Table-2_.

**Table 2. Non-interactive only commands.**

+---------------+-------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| | Interactive | Non-interactive | Direct Run | Notes |
+===============+=========================+==================================+======================================================================================================================+=====================================================================================================+
| * ``*CREATE`` | |:x:| Not available | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | It is recommended to create Python functions instead. |
+---------------+-------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| * ``CFOPEN`` | |:x:| Not available | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | It is recommended to use Python functions such as ``open``. |
+---------------+-------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| * ``CFCLOSE`` | |:x:| Not available | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | It is recommended to use Python functions such as ``open``. |
+---------------+-------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| * ``*VWRITE`` | |:x:| Not available | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | If you are working in a local session, it is recommended you use Python function such as ``open``. |
+---------------+-------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
+---------------+---------------------------------------------------------------------------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| | Interactive | Non-interactive | Direct Run | Notes |
+===============+=================================================================================================================================+==================================+======================================================================================================================+=====================================================================================================+
| * ``*CREATE`` | |:x:| Not available | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | It is recommended to create Python functions instead. |
+---------------+---------------------------------------------------------------------------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| * ``CFOPEN`` | |:x:| Not available | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | It is recommended to use Python functions such as ``open``. |
+---------------+---------------------------------------------------------------------------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| * ``CFCLOSE`` | |:x:| Not available | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | It is recommended to use Python functions such as ``open``. |
+---------------+---------------------------------------------------------------------------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| * ``*VWRITE`` | |:x:| Not available | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | If you are working in a local session, it is recommended you use Python function such as ``open``. |
+---------------+---------------------------------------------------------------------------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| * ``LSWRITE`` | |:heavy_check_mark:| Available (Internally running in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>`) | |:heavy_check_mark:| Available | |:heavy_minus_sign:| Only in :attr:`Mapdl.non_interactive <ansys.mapdl.core.Mapdl.non_interactive>` | |
+---------------+---------------------------------------------------------------------------------------------------------------------------------+----------------------------------+----------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+




Expand Down
61 changes: 61 additions & 0 deletions src/ansys/mapdl/core/_commands/solution/load_step_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ def lsdele(self, lsmin="", lsmax="", lsinc="", **kwargs):
def lsread(self, lsnum="", **kwargs):
"""Reads load and load step option data into the database.

.. warning:: This command can only run in non-interactive mode.
Please visit `Unsupported "Interactive" Commands
<https://mapdl.docs.pyansys.com/user_guide/mapdl.html#unsupported-interactive-commands>`_
for further information.

APDL Command: LSREAD

Parameters
Expand All @@ -83,6 +88,62 @@ def lsread(self, lsnum="", **kwargs):
existing SFGRAD specification.

This command is also valid in PREP7.

Examples
--------
Demonstrate writing out load steps using :func:`lswrite
<ansys.mapdl.core.Mapdl.lswrite> and reading them back in using
``lsread``.

>>> from ansys.mapdl.core import launch_mapdl
>>> mapdl = launch_mapdl()
>>> mapdl.clear()
>>> mapdl.prep7()

Build a 5 x 5 flat plate out of shell181 elements.

>>> mapdl.rectng(0, 5, 0, 5)
>>> mapdl.et(1, 'SHELL181')
>>> mapdl.mp('ex', 1, 10.0e5)
>>> mapdl.sectype(1, 'shell')
>>> mapdl.secdata(0.1) # 0.1 thick
>>> mapdl.esize(1)
>>> mapdl.amesh('all')

Fix the four corners

>>> mapdl.d('node(0,0,0)', 'all')
>>> mapdl.d('node(0,5,0)', 'all')
>>> mapdl.d('node(5,5,0)', 'all')
>>> mapdl.d('node(5,0,0)', 'all')

Enter the solution routine and define a force at (2,2,0).

>>> mapdl.slashsolu()
>>> mapdl.antype('static')
>>> mapdl.f('node(2,2,0)', 'fz', -10)

Write load out as load step 1 and delete all loads and displacements.

>>> mapdl.lswrite(1)
>>> mapdl.fdele('all', 'all')
>>> mapdl.ddele('all', 'all')

Read back in the loads and list them.

>>> mapdl.lsread(1)
>>> mapdl.flist()
LIST NODAL FORCES FOR SELECTED NODES 1 TO 36 BY 1
CURRENTLY SELECTED NODAL LOAD SET= FX FY FZ MX MY MZ

*** MAPDL - ENGINEERING ANALYSIS SYSTEM RELEASE 2022 R2 22.2 ***
Ansys Mechanical Enterprise
00000000 VERSION=LINUX x64 10:15:14 AUG 22, 2022 CP= 0.561

NODE LABEL REAL IMAG
26 FZ -10.0000000 0.00000000


"""
command = f"LSREAD,{lsnum}"
return self.run(command, **kwargs)
Expand Down
7 changes: 7 additions & 0 deletions src/ansys/mapdl/core/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ def __init__(self, msg=""):
RuntimeError.__init__(self, msg)


class MapdlCommandIgnoredError(RuntimeError):
"""Raised when MAPDL ignores a command."""

def __init__(self, msg=""):
RuntimeError.__init__(self, msg)


class MapdlExitedError(RuntimeError):
"""Raised when MAPDL has exited"""

Expand Down
20 changes: 19 additions & 1 deletion src/ansys/mapdl/core/mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@
StringWithLiteralRepr,
inject_docs,
)
from ansys.mapdl.core.errors import MapdlInvalidRoutineError, MapdlRuntimeError
from ansys.mapdl.core.errors import (
MapdlCommandIgnoredError,
MapdlInvalidRoutineError,
MapdlRuntimeError,
)
from ansys.mapdl.core.inline_functions import Query
from ansys.mapdl.core.misc import (
Information,
Expand Down Expand Up @@ -78,6 +82,7 @@
"*IF": "Use a python ``if`` or run as non_interactive",
"CMAT": "Run `CMAT` as ``non_interactive``.",
"*REP": "Run '*REPEAT' in ``non_interactive``.",
"LSRE": "Run 'LSREAD' in ``non_interactive``.",
}

## Soft-invalid commands
Expand Down Expand Up @@ -2707,6 +2712,11 @@ def run(self, command, write_to_log=True, mute=None, **kwargs) -> str:
text += "\n\nIgnore these messages by setting allow_ignore=True"
raise MapdlInvalidRoutineError(text)

if "command is ignored" in text:
if not self.allow_ignore:
text += "\n\nIgnore these messages by setting allow_ignore=True"
raise MapdlCommandIgnoredError(text)

# flag errors
if "*** ERROR ***" in self._response and not self._ignore_errors:
self._raise_output_errors(self._response)
Expand Down Expand Up @@ -3661,6 +3671,14 @@ def _raise_output_errors(self, response):
f"\n\nError in instance {self.name}\n\n" + error_message
)

@wraps(Commands.lsread)
def lsread(self, *args, **kwargs):
"""Wraps the ``LSREAD`` which does not work in interactive mode."""
self._log.debug("Forcing 'LSREAD' to run in non-interactive mode.")
with self.non_interactive:
super().lsread(*args, **kwargs)
return self._response.strip()

def file(self, fname="", ext="", **kwargs):
"""Specifies the data file where results are to be found.

Expand Down
3 changes: 3 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ def query(mapdl, cleared):

@pytest.fixture
def solved_box(mapdl, cleared):
mapdl.mute = True # improve stability
mapdl.prep7()
mapdl.et(1, "SOLID5")
mapdl.block(0, 10, 0, 20, 0, 30)
Expand All @@ -400,6 +401,8 @@ def solved_box(mapdl, cleared):
mapdl.antype("STATIC")
mapdl.solve()
mapdl.finish()
mapdl.mute = False

q = mapdl.queries
return q, get_details_of_nodes(mapdl)

Expand Down
34 changes: 28 additions & 6 deletions tests/test_mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pyvista.plotting import system_supports_plotting

from ansys.mapdl import core as pymapdl
from ansys.mapdl.core.errors import MapdlRuntimeError
from ansys.mapdl.core.errors import MapdlCommandIgnoredError, MapdlRuntimeError
from ansys.mapdl.core.launcher import get_start_instance, launch_mapdl
from ansys.mapdl.core.misc import random_string

Expand Down Expand Up @@ -1075,12 +1075,13 @@ def test_cdread_in_apdl_directory(mapdl, cleared):
assert asserting_cdread_cdwrite_tests(mapdl)


def test_inval_commands(mapdl, cleared):
@pytest.mark.parametrize(
"each_cmd", ["*END", "*vwrite", "/eof", "cmatrix", "*REpeAT", "lSread"]
)
def test_inval_commands(mapdl, cleared, each_cmd):
"""Test the output of invalid commands"""
cmds = ["*END", "*vwrite", "/eof", "cmatrix", "*REpeAT"]
for each_cmd in cmds:
with pytest.raises(RuntimeError):
mapdl.run(each_cmd)
with pytest.raises(RuntimeError):
mapdl.run(each_cmd)


def test_inval_commands_silent(mapdl, tmpdir, cleared):
Expand Down Expand Up @@ -1517,3 +1518,24 @@ def test_non_interactive(mapdl, cleared):
mapdl.k(2, 2, 2, 2)

assert mapdl.geometry.keypoints.shape == (2, 3)


def test_ignored_command(mapdl, cleared):
mapdl.prep7(mute=True)
mapdl.n(mute=True)
with pytest.raises(MapdlCommandIgnoredError, match="command is ignored"):
mapdl.f(1, 1, 1, 1)


def test_lsread(mapdl, cleared):
mapdl.n(1, mute=True)
mapdl.n(2, 1, 0, 0, mute=True)
mapdl.et(1, 188, mute=True)
mapdl.e(1, 2, mute=True)
mapdl.slashsolu(mute=True)
mapdl.f("all", "FX", 1, mute=True)
mapdl.lswrite(mute=True)
mapdl.fdele("all", "all", mute=True)
assert "No nodal" in mapdl.flist()
mapdl.lsread(mute=True)
assert "No nodal" not in mapdl.flist()
2 changes: 1 addition & 1 deletion tests/test_plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ def debug_orders(pl, point):
pl.iren._mouse_left_button_release(width, height)
pl.iren._mouse_move(int(width * point[0]), int(height * point[1]))

mapdl.ksel("S", "node", "", 1)
mapdl.ksel("S", "KP", "", 1)
if selection == "R" or selection == "U":
point = (285 / 1024, 280 / 800)
mapdl.ksel("a", "node", "", 2)
Expand Down