diff --git a/src/ansys/mapdl/core/_commands/preproc/materials.py b/src/ansys/mapdl/core/_commands/preproc/materials.py index 2b2183df06d..a1798eccb28 100644 --- a/src/ansys/mapdl/core/_commands/preproc/materials.py +++ b/src/ansys/mapdl/core/_commands/preproc/materials.py @@ -691,12 +691,12 @@ def mpread(self, fname="", ext="", lib="", **kwargs): ---------- fname File name and directory path (248 characters maximum, - including directory). If you do not specify the LIB + including directory). If you do not specify the ``LIB`` option, the default directory is the current working - directory. If you specify the LIB option, the default is + directory. If you specify the ``LIB`` option, the default is the following search path: the current working directory, - the user's home directory, MPLIB_DIR (as specified by the - /MPLIB,READ,PATH command) and /ansys_dir/matlib (as + the user's home directory, ``MPLIB_DIR`` (as specified by the + ``/MPLIB,READ,PATH`` command) and ``/ansys_dir/matlib`` (as defined by installation). If you use the default for your directory, you can use all 248 characters for the file name. @@ -706,25 +706,25 @@ def mpread(self, fname="", ext="", lib="", **kwargs): lib Reads material library files previously written with the - MPWRITE command. (See the description of the LIB option - for the MPWRITE command.) The only allowed value for LIB - is LIB. + MPWRITE command. (See the description of the ``LIB`` option + for the ``MPWRITE`` command.) The only allowed value for ``LIB`` + is ``LIB``. Notes ----- - Material properties written to a file without the LIB option + Material properties written to a file without the ``LIB`` option do not support nonlinear properties. Also, properties written - to a file without the LIB option are restored in the same + to a file without the ``LIB`` option are restored in the same material number as originally defined. To avoid errors, use - MPREAD with the LIB option only when reading files written - using MPWRITE with the LIB option. + ``MPREAD`` with the ``LIB`` option only when reading files written + using MPWRITE with the ``LIB`` option. - If you omit the LIB option for MPREAD, this command supports + If you omit the ``LIB`` option for ``MPREAD``, this command supports only linear properties. Material numbers are hardcoded. If you write a material file - without specifying the LIB option, then read that file in - using the MPREAD command with the LIB option, the ANSYS + without specifying the ``LIB`` option, then read that file in + using the ``MPREAD`` command with the ``LIB`` option, the ANSYS program will not write the file to a new material number. Instead, it will write the file to the "old" material number (the number specified on the MPWRITE command that created the @@ -855,9 +855,9 @@ def mpwrite(self, fname="", ext="", lib="", mat="", **kwargs): ---------- fname File name and directory path (248 characters maximum, including - directory). If you do not specify the LIB option, the default - directory is the current working directory. If you specify LIB and - you have specified a material library directory (via the /MPLIB + directory). If you do not specify the ``LIB`` option, the default + directory is the current working directory. If you specify ``LIB`` and + you have specified a material library directory (via the ``/MPLIB`` command), that directory is the default. Otherwise, the default is the current working directory. If you use the default for your directory, you can use all 248 characters for the file name. @@ -867,18 +867,18 @@ def mpwrite(self, fname="", ext="", lib="", mat="", **kwargs): ext Filename extension (eight-character maximum). - If you omit the LIB option, the default extension is - MP. If you specify the LIB option, the default extension + If you omit the ``LIB`` option, the default extension is + MP. If you specify the ``LIB`` option, the default extension is units_MPL, where units is the system of units currently - in use. (See the description of the /UNITS command.) For - example, if /UNITS is set to BIN, the extension defaults + in use. (See the description of the ``/UNITS`` command.) For + example, if ``/UNITS`` is set to BIN, the extension defaults to BIN_MPL. lib - The only value allowed for this field is the string "LIB." + The only value allowed for this field is the string ``"LIB"``. - The LIB option indicates that you wish to have properties - associated with the material (MAT) written to the + The ``LIB`` option indicates that you wish to have properties + associated with the material (``MAT``) written to the specified material library file using the material library file format. The material library file format is ASCII-text-based ANSYS command input. Certain commands @@ -888,15 +888,15 @@ def mpwrite(self, fname="", ext="", lib="", mat="", **kwargs): file independent of the material number in effect when the file was written; this enables you to restore the properties into the ANSYS database using the material - number of your choice. The LIB option also enables you to + number of your choice. The ``LIB`` option also enables you to save both linear and nonlinear properties. If you omit the - LIB option, you can save linear properties only. + ``LIB`` option, you can save linear properties only. mat Specifies the material to be written to the named material library file. There is no default; you must either specify a material or - omit the MAT argument. Even if you specify a MAT value, the ANSYS - program ignores it if the LIB argument is not specified. + omit the ``MAT`` argument. Even if you specify a ``MAT`` value, the ANSYS + program ignores it if the ``LIB`` argument is not specified. Notes ----- diff --git a/src/ansys/mapdl/core/mapdl.py b/src/ansys/mapdl/core/mapdl.py index 010e9f57e2c..41b320ad600 100644 --- a/src/ansys/mapdl/core/mapdl.py +++ b/src/ansys/mapdl/core/mapdl.py @@ -30,6 +30,7 @@ from ansys.mapdl.core.inline_functions import Query from ansys.mapdl.core.misc import ( last_created, + load_file, random_string, run_as_prep7, supress_logging, @@ -2890,3 +2891,15 @@ def _check_parameter_name(self, param_name): "Hence its use is not recommended outside them." "You might run in unexpected behaviours, for example, parameters not being show in `mapdl.parameters`." ) + + @wraps(Commands.mpread) + def mpread(self, fname="", ext="", lib="", **kwargs): + if lib: + raise NotImplementedError( + "The option 'lib' is not supported by the MAPDL gRPC server." + ) + + fname_ = fname + "." + ext + fname = load_file(self, fname_) + self._log.info("Bypassing 'MPREAD' with 'INPUT'.") + return self.input(fname) diff --git a/src/ansys/mapdl/core/math.py b/src/ansys/mapdl/core/math.py index 5f01c130007..5fcaf65f51a 100755 --- a/src/ansys/mapdl/core/math.py +++ b/src/ansys/mapdl/core/math.py @@ -11,6 +11,8 @@ from ansys.api.mapdl.v0 import mapdl_pb2 as pb_types import numpy as np +from ansys.mapdl.core.misc import load_file + from .check_version import VersionError, meets_version, version_requires from .common_grpc import ANSYS_VALUE_TYPE, DEFAULT_CHUNKSIZE, DEFAULT_FILE_CHUNK_SIZE from .errors import ANSYSDataTypeError, protect_grpc @@ -523,38 +525,7 @@ def _load_file(self, fname): If the file is local, it will be uploaded. """ - if self._mapdl._local: # pragma: no cover - base_fname = os.path.basename(fname) - if not os.path.exists(fname) and base_fname not in self._mapdl.list_files(): - raise FileNotFoundError( - f"The file {fname} could not be found in the Python working directory ('{os.getcwd()}')" - f"nor in the MAPDL working directory ('{self._mapdl.directory}')." - ) - - elif os.path.exists(fname) and base_fname in self._mapdl.list_files(): - warn( - f"The file '{base_fname} is present in both, the python working directory ('{os.getcwd()}')" - "and in the MAPDL working directory ('{self._mapdl.directory}'). " - "Using the one in the MAPDL directory.\n" - "If you prefer to use the file in the Python directory, you can use `mapdl.upload` before this command to upload it." - ) - - elif os.path.exists(fname) and base_fname not in self._mapdl.list_files(): - self._mapdl.upload(fname) - - elif not os.path.exists(fname) and base_fname in self._mapdl.list_files(): - pass - - else: - if not os.path.exists(fname) and fname not in self._mapdl.list_files(): - raise FileNotFoundError( - f"The file {fname} could not be found in the local client or remote working directory." - ) - if os.path.exists(fname): - self._mapdl.upload(fname) - - # Simplifying name for MAPDL reads it. - return os.path.basename(fname) + return load_file(self._mapdl, fname) def stiff(self, dtype=np.double, fname="file.full", asarray=False): """Load the stiffness matrix from a full file. diff --git a/src/ansys/mapdl/core/misc.py b/src/ansys/mapdl/core/misc.py index af7084518c6..88a37a95129 100644 --- a/src/ansys/mapdl/core/misc.py +++ b/src/ansys/mapdl/core/misc.py @@ -332,3 +332,49 @@ def wrapper(*args, **kwargs): func(*args, **kwargs) return wrapper + + +def load_file(mapdl, fname): + """ + Provide a file to the MAPDL instance. + + If in local: + Checks if the file exists, if not, it raises a ``FileNotFound`` exception + + If in not-local: + Check if the file exists locally or in the working directory, if not, it will raise a ``FileNotFound`` exception. + If the file is local, it will be uploaded. + + """ + if mapdl._local: # pragma: no cover + base_fname = os.path.basename(fname) + if not os.path.exists(fname) and base_fname not in mapdl.list_files(): + raise FileNotFoundError( + f"The file {fname} could not be found in the Python working directory ('{os.getcwd()}')" + f"nor in the MAPDL working directory ('{mapdl.directory}')." + ) + + elif os.path.exists(fname) and base_fname in mapdl.list_files(): + warn( + f"The file '{base_fname} is present in both, the python working directory ('{os.getcwd()}')" + f"and in the MAPDL working directory ('{mapdl.directory}'). " + "Using the one in the MAPDL directory.\n" + "If you prefer to use the file in the Python directory, you can use `mapdl.upload` before this command to upload it." + ) + + elif os.path.exists(fname) and base_fname not in mapdl.list_files(): + mapdl.upload(fname) + + elif not os.path.exists(fname) and base_fname in mapdl.list_files(): + pass + + else: + if not os.path.exists(fname) and fname not in mapdl.list_files(): + raise FileNotFoundError( + f"The file {fname} could not be found in the local client or remote working directory." + ) + if os.path.exists(fname): + mapdl.upload(fname) + + # Simplifying name for MAPDL reads it. + return os.path.basename(fname) diff --git a/tests/test_mapdl.py b/tests/test_mapdl.py index 8793446ac01..73f0366e90f 100644 --- a/tests/test_mapdl.py +++ b/tests/test_mapdl.py @@ -1467,3 +1467,34 @@ def test_seltol(mapdl, value): assert "SELECT TOLERANCE=" in mapdl.seltol(value) else: assert "SELECT TOLERANCE SET TO DEFAULT" == mapdl.seltol(value) + + +def test_mpfunctions(mapdl, cube_solve, capsys): + mapdl.prep7() + + # check writing to file + fname = "test" + ext = "mp1" + + mapdl.mpwrite(fname, ext) + assert f"{fname}.{ext}" in mapdl.list_files() + + nuxy = 0.3 + ex = 0.2100000e12 + + # Reding file in remote + mapdl.clear() + mapdl.prep7() + output = mapdl.mpread(fname, ext) + assert "PROPERTY TEMPERATURE TABLE NUM. TEMPS= 1" in output + assert "TEMPERATURE TABLE ERASED." in output + assert np.allclose(mapdl.get_value("NUXY", "1", "TEMP", 0), nuxy) + assert np.allclose(mapdl.get_value("EX", 1, "TEMP", 0), ex) + + # Test non-existing file + with pytest.raises(FileNotFoundError): + mapdl.mpread(fname="dummy", ext="dummy") + + # Test not implemented error + with pytest.raises(NotImplementedError): + mapdl.mpread(fname="dummy", ext="dummy", lib="something")