diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90ecdf738f..9f5c9b0d5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -151,6 +151,8 @@ jobs: python-package-name: ${{ env.PACKAGE_NAME }} dev-mode: ${{ github.ref != 'refs/heads/main' }} upload-reports: True + hide-log: false + docs-build: name: "Build documentation" diff --git a/doc/changelog.d/3636.miscellaneous.md b/doc/changelog.d/3636.miscellaneous.md new file mode 100644 index 0000000000..5d0e245a47 --- /dev/null +++ b/doc/changelog.d/3636.miscellaneous.md @@ -0,0 +1 @@ +feat: node/element selection commands returning selected ids \ No newline at end of file diff --git a/doc/changelog.d/3641.added.md b/doc/changelog.d/3641.added.md new file mode 100644 index 0000000000..401ec81a64 --- /dev/null +++ b/doc/changelog.d/3641.added.md @@ -0,0 +1 @@ +chore: update CHANGELOG for v0.69.0 \ No newline at end of file diff --git a/doc/changelog.d/3642.fixed.md b/doc/changelog.d/3642.fixed.md new file mode 100644 index 0000000000..526ce0df6e --- /dev/null +++ b/doc/changelog.d/3642.fixed.md @@ -0,0 +1 @@ +fix: timeout for file checking \ No newline at end of file diff --git a/src/ansys/mapdl/core/commands.py b/src/ansys/mapdl/core/commands.py index c6c7c489cf..935284e19d 100644 --- a/src/ansys/mapdl/core/commands.py +++ b/src/ansys/mapdl/core/commands.py @@ -193,6 +193,8 @@ "LSEL", "ASEL", "VSEL", + "ESLN", + "NSLE", ] diff --git a/src/ansys/mapdl/core/mapdl_core.py b/src/ansys/mapdl/core/mapdl_core.py index 4201a0fc3d..94626cf9c3 100644 --- a/src/ansys/mapdl/core/mapdl_core.py +++ b/src/ansys/mapdl/core/mapdl_core.py @@ -1321,6 +1321,10 @@ def wrap_xsel_function_output(method): return self.geometry.anum elif name == "VSEL": return self.geometry.vnum + elif name == "ESLN": + return self.mesh.enum + elif name == "NSLE": + return self.mesh.nnum else: return None @@ -2915,6 +2919,7 @@ def _check_mapdl_os(self): self._platform = "windows" else: # pragma: no cover raise MapdlRuntimeError("Unknown platform: {}".format(platform)) + self.logger.debug(f"MAPDL is running on {self._platform} OS.") def _check_on_docker(self): """Check if MAPDL is running on docker.""" diff --git a/src/ansys/mapdl/core/mapdl_grpc.py b/src/ansys/mapdl/core/mapdl_grpc.py index c8682296b4..8f44fe4a66 100644 --- a/src/ansys/mapdl/core/mapdl_grpc.py +++ b/src/ansys/mapdl/core/mapdl_grpc.py @@ -119,6 +119,10 @@ SESSION_ID_NAME = "__PYMAPDL_SESSION_ID__" +DEFAULT_TIME_STEP_STREAM = None +DEFAULT_TIME_STEP_STREAM_NT = 500 +DEFAULT_TIME_STEP_STREAM_POSIX = 100 + # Retry policy for gRPC calls. SERVICE_DEFAULT_CONFIG = { # see https://github.com/grpc/proposal/blob/master/A6-client-retries.md#retry-policy-capabilities @@ -1069,7 +1073,8 @@ def _send_command(self, cmd: str, mute: bool = False) -> Optional[str]: def _send_command_stream(self, cmd, verbose=False) -> str: """Send a command and expect a streaming response""" request = pb_types.CmdRequest(command=cmd) - metadata = [("time_step_stream", "100")] + time_step = self._get_time_step_stream() + metadata = [("time_step_stream", str(time_step))] stream = self._stub.SendCommandS(request, metadata=metadata) response = [] for item in stream: @@ -1775,13 +1780,14 @@ def input( execution time. Due to stability issues, the default time_step_stream is - dependent on verbosity. The defaults are: + dependent on the OS MAPDL is running on. The defaults are: - - ``verbose=True``: ``time_step_stream=500`` - - ``verbose=False``: ``time_step_stream=50`` + - Windows: ``time_step_stream=500`` + - Linux: ``time_step_stream=100`` These defaults will be ignored if ``time_step_stream`` is - manually set. + manually set. See the *Examples* section to learn how to change + the default value globally. orig_cmd : str, optional Original command. There are some cases, were input is @@ -1831,6 +1837,11 @@ def input( >>> with mapdl.non_interactive: mapdl.run("/input,inputtrigger,inp") # This inputs 'myinput.inp' + You can also change them globably using: + + >>> from ansys.mapdl.core import mapdl_grpc + >>> mapdl_grpc.DEFAULT_TIME_STEP_STREAM=100 # in milliseconds + """ # Checking compatibility # Checking the user is not reusing old api: @@ -1911,18 +1922,14 @@ def input( # are unclear filename = self._get_file_path(fname, progress_bar) - if time_step_stream is not None: - if time_step_stream <= 0: - raise ValueError("``time_step_stream`` must be greater than 0``") + time_step_stream = self._get_time_step_stream(time_step_stream) - if verbose: - if time_step_stream is None: - time_step_stream = 500 - metadata = [ - ("time_step_stream", str(time_step_stream)), - ("chunk_size", str(chunk_size)), - ] + metadata = [ + ("time_step_stream", str(time_step_stream)), + ("chunk_size", str(chunk_size)), + ] + if verbose: request = pb_types.InputFileRequest(filename=filename) strouts = self._stub.InputFileS(request, metadata=metadata) responses = [] @@ -1934,13 +1941,8 @@ def input( response = "\n".join(responses) return response.strip() - # otherwise, not verbose - if time_step_stream is None: - time_step_stream = 50 - metadata = [ - ("time_step_stream", str(time_step_stream)), - ("chunk_size", str(chunk_size)), - ] + ## + # Otherwise, not verbose # since we can't directly run /INPUT, we have to write a # temporary input file that tells MAPDL to read the input @@ -2014,6 +2016,31 @@ def input( return output + def _get_time_step_stream( + self, time_step: Optional[Union[int, float]] = None + ) -> str: + """Return the time step for checking if MAPDL is done writing the + output to the file which later will be returned as response + """ + if time_step is None: + if DEFAULT_TIME_STEP_STREAM is not None: + time_step = DEFAULT_TIME_STEP_STREAM + elif self.platform == "windows": + time_step = DEFAULT_TIME_STEP_STREAM_NT + elif self.platform == "linux": + time_step = DEFAULT_TIME_STEP_STREAM_POSIX + else: + raise ValueError( + f"The MAPDL platform ('{self.platform}') is not recognaised." + ) + + else: + if time_step <= 0: + raise ValueError("``time_step`` argument must be greater than 0``") + + self.logger.debug(f"The time_step argument is set to: {time_step}") + return time_step + def _get_file_path(self, fname: str, progress_bar: bool = False) -> str: """Find files in the Python and MAPDL working directories. diff --git a/tests/conftest.py b/tests/conftest.py index deebfcaa27..3f87e5fedd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1157,6 +1157,24 @@ def create_geometry(mapdl): return areas, keypoints +@pytest.fixture(scope="function") +def two_dimensional_mesh(mapdl, cleared): + length = 4 + height = 1 + thickness = 0.2 + mesh_size = 0.1 + + mapdl.prep7() + + mapdl.r(r1=thickness) + mapdl.et(1, "PLANE182", kop3=3, kop6=0) + mapdl.rectng(0, length, 0, height) + mapdl.mshkey(1) + mapdl.mshape(0, "2D") + mapdl.esize(mesh_size) + mapdl.amesh("ALL") + + @pytest.fixture def query(mapdl, cleared): return mapdl.queries diff --git a/tests/test_grpc.py b/tests/test_grpc.py index 808de4afab..6d0aaf6fc2 100644 --- a/tests/test_grpc.py +++ b/tests/test_grpc.py @@ -25,6 +25,7 @@ import re import shutil import sys +from unittest.mock import patch import grpc import pytest @@ -682,3 +683,32 @@ def _null_close_process(): mapdl.prep7(mapdl) mapdl._exited = False # Restoring + + +@pytest.mark.parametrize("platform", ["linux", "windows", "error"]) +def test__get_time_step_stream(mapdl, platform): + with patch("ansys.mapdl.core.mapdl_grpc.MapdlGrpc.platform", platform): + from ansys.mapdl.core import mapdl_grpc + + if platform == "linux": + DEFAULT_TIME_STEP_STREAM = mapdl_grpc.DEFAULT_TIME_STEP_STREAM_POSIX + elif platform == "windows": + DEFAULT_TIME_STEP_STREAM = mapdl_grpc.DEFAULT_TIME_STEP_STREAM_NT + else: + with pytest.raises(ValueError, match="The MAPDL platform"): + mapdl._get_time_step_stream() + + return # Early exit + + assert DEFAULT_TIME_STEP_STREAM == mapdl._get_time_step_stream() + + mapdl_grpc.DEFAULT_TIME_STEP_STREAM = 200 + assert mapdl_grpc.DEFAULT_TIME_STEP_STREAM == mapdl._get_time_step_stream() + mapdl_grpc.DEFAULT_TIME_STEP_STREAM = None + + assert 700 == mapdl._get_time_step_stream(700) + + with pytest.raises( + ValueError, match="``time_step`` argument must be greater than 0``" + ): + mapdl._get_time_step_stream(-700) diff --git a/tests/test_mesh_grpc.py b/tests/test_mesh_grpc.py index a0aaf421f7..e914974b22 100644 --- a/tests/test_mesh_grpc.py +++ b/tests/test_mesh_grpc.py @@ -317,3 +317,42 @@ def test_nodal_rotation(mapdl, cleared): ] ) assert np.allclose(nrotation_ref, nrotations[:7, :]) + + +def test_esln(mapdl, two_dimensional_mesh): + mapdl.nsel("S", "LOC", "X", 0) + selected_ids = mapdl.esln("S", 0) + expected_selected_ids = np.array([1, 41, 81, 121, 161, 201, 241, 281, 321, 361]) + assert all(selected_ids == expected_selected_ids) + + +def test_nsle(mapdl, two_dimensional_mesh): + mapdl.esel("S", "CENT", "X", 0, 0.1) + selected_ids = mapdl.nsle("S") + expected_selected_ids = np.array( + [ + 1, + 3, + 52, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + ] + ) + assert all(selected_ids == expected_selected_ids)