diff --git a/ansys/mapdl/core/_commands/session/list_controls.py b/ansys/mapdl/core/_commands/session/list_controls.py index c028369b59..5118de63b1 100644 --- a/ansys/mapdl/core/_commands/session/list_controls.py +++ b/ansys/mapdl/core/_commands/session/list_controls.py @@ -27,6 +27,8 @@ def com(self, comment="", **kwargs): This command is valid anywhere. """ command = "/COM,%s" % (str(comment)) + if self.print_com: + print(command) return self.run(command, **kwargs) def golist(self, **kwargs): diff --git a/ansys/mapdl/core/convert.py b/ansys/mapdl/core/convert.py index 19aac96f02..6e20bc435a 100644 --- a/ansys/mapdl/core/convert.py +++ b/ansys/mapdl/core/convert.py @@ -22,7 +22,8 @@ def convert_script( exec_file=None, macros_as_functions=True, use_function_names=True, - show_log = False + show_log = False, + print_com=True ): """Converts an ANSYS input file to a python PyMAPDL script. @@ -57,6 +58,10 @@ def convert_script( Print the converted commands using a logger (from ``logging`` Python module). + print_com : bool, optional + Print command ``/COM`` arguments to python console. + Defaults to ``True``. + Returns ------- list @@ -78,7 +83,8 @@ def convert_script( exec_file=exec_file, macros_as_functions=macros_as_functions, use_function_names=use_function_names, - show_log=show_log + show_log=show_log, + print_com=print_com ) translator.save(filename_out) @@ -92,7 +98,8 @@ def convert_apdl_block(apdl_strings, exec_file=None, macros_as_functions=True, use_function_names=True, - show_log=False): + show_log=False, + print_com=True): """Converts an ANSYS input string to a python PyMAPDL string. Parameters @@ -126,6 +133,10 @@ def convert_apdl_block(apdl_strings, Print the converted commands using a logger (from ``logging`` Python module). + print_com : bool, optional + Print command ``/COM`` arguments to python console. + Defaults to ``True``. + Returns ------- list @@ -140,7 +151,8 @@ def convert_apdl_block(apdl_strings, exec_file=exec_file, macros_as_functions=macros_as_functions, use_function_names=use_function_names, - show_log=show_log) + show_log=show_log, + print_com=print_com) if isinstance(apdl_strings, str): return translator.line_ending.join(translator.lines) @@ -154,7 +166,8 @@ def _convert(apdl_strings, exec_file=None, macros_as_functions=True, use_function_names=True, - show_log=False + show_log=False, + print_com=True ): translator = FileTranslator( @@ -163,7 +176,8 @@ def _convert(apdl_strings, exec_file=exec_file, macros_as_functions=macros_as_functions, use_function_names=use_function_names, - show_log=show_log + show_log=show_log, + print_com=print_com ) if isinstance(apdl_strings, str): @@ -210,7 +224,8 @@ def __init__( exec_file=None, macros_as_functions=True, use_function_names=True, - show_log=False + show_log=False, + print_com=True ): self._non_interactive_level = 0 self.lines = Lines(mute=not show_log) @@ -223,6 +238,7 @@ def __init__( self._infunction = False self.use_function_names = use_function_names self.comment = "" + self.print_com = print_com self.write_header() self.initialize_mapdl_object(loglevel, exec_file) @@ -277,7 +293,11 @@ def initialize_mapdl_object(self, loglevel, exec_file): exec_file_parameter = f'"{exec_file}", ' else: exec_file_parameter = "" - line = f'{self.obj_name} = launch_mapdl({exec_file_parameter}loglevel="{loglevel}")' + + if self.print_com: + line = f'{self.obj_name} = launch_mapdl({exec_file_parameter}loglevel="{loglevel}", print_com=True)' + else: + line = f'{self.obj_name} = launch_mapdl({exec_file_parameter}loglevel="{loglevel}")' self.lines.append(line) @property diff --git a/ansys/mapdl/core/launcher.py b/ansys/mapdl/core/launcher.py index db4261b265..3794007707 100644 --- a/ansys/mapdl/core/launcher.py +++ b/ansys/mapdl/core/launcher.py @@ -760,6 +760,7 @@ def launch_mapdl( verbose_mapdl=False, license_server_check=True, license_type=None, + print_com=False, **kwargs, ) -> _MapdlCore: """Start MAPDL locally in gRPC mode. @@ -885,6 +886,10 @@ def launch_mapdl( will be requested, being up to the license server to provide a specific license type. Default is ``None``. + print_com : bool, optional + Print the command ``/COM`` arguments to the standard output. + Default ``False``. + Returns ------- ansys.mapdl.core.mapdl._MapdlCore @@ -1124,6 +1129,7 @@ def launch_mapdl( "additional_switches": additional_switches, "jobname": jobname, "nproc": nproc, + "print_com": print_com, } if mode in ["console", "corba"]: diff --git a/ansys/mapdl/core/mapdl.py b/ansys/mapdl/core/mapdl.py index 556b928fd3..4fda5d4fe7 100644 --- a/ansys/mapdl/core/mapdl.py +++ b/ansys/mapdl/core/mapdl.py @@ -123,7 +123,8 @@ class _MapdlCore(Commands): """Contains methods in common between all Mapdl subclasses""" def __init__(self, loglevel='DEBUG', use_vtk=True, log_apdl=None, - log_file=False, local=True, **start_parm): + log_file=False, local=True, + print_com=False, **start_parm): """Initialize connection with MAPDL.""" self._show_matplotlib_figures = True # for testing self._query = None @@ -143,6 +144,7 @@ def __init__(self, loglevel='DEBUG', use_vtk=True, log_apdl=None, self._start_parm = start_parm self._path = start_parm.get("run_location", None) self._ignore_errors = False + self._print_com = print_com # print the command /COM input. # Setting up loggers self._log = logger.add_instance_logger(self._name, self, level=loglevel) # instance logger @@ -167,6 +169,19 @@ def __init__(self, loglevel='DEBUG', use_vtk=True, log_apdl=None, self._wrap_listing_functions() + @property + def print_com(self): + return self._print_com + + @print_com.setter + def print_com(self, value): + if isinstance(value, bool): + status = "activated" if value else "deactivated" + self._log.debug(f"The print of '/COM' commands has been {status}.") + self._print_com = value + else: + raise ValueError(f"The property ``print_com`` only allows booleans, but type {type(value)} was supplied.") + def _wrap_listing_functions(self): # Wrapping LISTING FUNCTIONS. def wrap_listing_function(func): @@ -186,11 +201,11 @@ def inner_wrapper(*args, **kwargs): return inner_wrapper for name in dir(self): - if name[0:4].upper() in CMD_LISTING: + if name[0:4].upper() in CMD_LISTING and name in dir(Commands): # avoid matching Mapdl properties which starts with same letters as MAPDL commands. func = self.__getattribute__(name) setattr(self, name, wrap_listing_function(func)) - if name[0:4].upper() in CMD_BC_LISTING: + if name[0:4].upper() in CMD_BC_LISTING and name in dir(Commands): func = self.__getattribute__(name) setattr(self, name, wrap_BC_listing_function(func)) @@ -2179,11 +2194,17 @@ def run(self, command, write_to_log=True, mute=None, **kwargs): else: # if not gRPC mute = False - command = command.strip() # check if multiline if "\n" in command or "\r" in command: raise ValueError("Use ``input_strings`` for multi-line commands") + if self._store_commands: + # If we are using NBLOCK on input, we should not strip the string + self._stored_commands.append(command) + return + + command = command.strip() + # always reset the cache self._reset_cache() @@ -2204,10 +2225,7 @@ def run(self, command, write_to_log=True, mute=None, **kwargs): # But just in case, I'm adding info as /com command = f"/com, PyAnsys: {msg}" # Using '!' makes the output of '_run' empty - if self._store_commands: - self._stored_commands.append(command) - return - elif command[:3].upper() in INVAL_COMMANDS: + if command[:3].upper() in INVAL_COMMANDS: exception = RuntimeError( 'Invalid pymapdl command "%s"\n\n%s' % (command, INVAL_COMMANDS[command[:3].upper()]) diff --git a/ansys/mapdl/core/mapdl_console.py b/ansys/mapdl/core/mapdl_console.py index 442a9caf17..2dd6ba4049 100644 --- a/ansys/mapdl/core/mapdl_console.py +++ b/ansys/mapdl/core/mapdl_console.py @@ -78,14 +78,14 @@ class MapdlConsole(_MapdlCore): Only works on Linux. """ - def __init__(self, loglevel="INFO", log_apdl=None, use_vtk=True, **start_parm): + def __init__(self, loglevel="INFO", log_apdl=None, use_vtk=True, print_com=False, **start_parm): """Opens an ANSYS process using pexpect""" self._auto_continue = True self._continue_on_error = False self._process = None self._launch(start_parm) super().__init__( - loglevel=loglevel, use_vtk=use_vtk, log_apdl=log_apdl, **start_parm + loglevel=loglevel, use_vtk=use_vtk, log_apdl=log_apdl, print_com=print_com, **start_parm ) def _launch(self, start_parm): diff --git a/ansys/mapdl/core/mapdl_corba.py b/ansys/mapdl/core/mapdl_corba.py index 49dace30ad..90e18e83f2 100644 --- a/ansys/mapdl/core/mapdl_corba.py +++ b/ansys/mapdl/core/mapdl_corba.py @@ -162,6 +162,9 @@ class MapdlCorba(_MapdlCore): Copy the log to a file called `logs.log` located where the python script is executed. Default ``True``. + print_com : bool, optional + Print the command ``/COM`` arguments to the standard output. + Default ``False``. """ def __init__(self, loglevel='INFO', log_apdl=None, use_vtk=True, @@ -169,7 +172,8 @@ def __init__(self, loglevel='INFO', log_apdl=None, use_vtk=True, log_broadcast=False, verbose=False, **start_parm): """Open a connection to MAPDL via a CORBA interface""" super().__init__(loglevel=loglevel, use_vtk=use_vtk, log_apdl=log_apdl, - log_file=log_file, log_broadcast=False, **start_parm) + log_file=log_file, log_broadcast=False, + print_com=print_com, **start_parm) self._broadcast_logger = None self._server = None diff --git a/ansys/mapdl/core/mapdl_grpc.py b/ansys/mapdl/core/mapdl_grpc.py index 0bcc9e2d39..c13f3729fb 100755 --- a/ansys/mapdl/core/mapdl_grpc.py +++ b/ansys/mapdl/core/mapdl_grpc.py @@ -207,6 +207,10 @@ class MapdlGrpc(_MapdlCore): Copy the log to a file called `logs.log` located where the python script is executed. Default ``True``. + print_com : bool, optional + Print the command ``/COM`` arguments to the standard output. + Default ``False``. + Examples -------- Connect to an instance of MAPDL already running on locally on the @@ -230,7 +234,8 @@ class MapdlGrpc(_MapdlCore): def __init__(self, ip='127.0.0.1', port=None, timeout=15, loglevel='WARNING', log_file=False, cleanup_on_exit=False, log_apdl=None, - set_no_abort=True, remove_temp_files=False, **kwargs): + set_no_abort=True, remove_temp_files=False, + print_com = False, **kwargs): """Initialize connection to the mapdl server""" self.__distributed = None @@ -238,7 +243,7 @@ def __init__(self, ip='127.0.0.1', port=None, timeout=15, loglevel='WARNING', self._port = port self._ip = ip super().__init__( - loglevel=loglevel, log_apdl=log_apdl, log_file=log_file, **kwargs + loglevel=loglevel, log_apdl=log_apdl, log_file=log_file, print_com=print_com, **kwargs ) check_valid_ip(ip) diff --git a/doc/source/user_guide/convert.rst b/doc/source/user_guide/convert.rst index 149ea6f80d..91feecfa0c 100644 --- a/doc/source/user_guide/convert.rst +++ b/doc/source/user_guide/convert.rst @@ -62,6 +62,13 @@ using :func:`convert_apdl_block() ` : FINISH""" pycode = convert_apdl_block(apdl_string) # apdl_string can be also a list of strings. + +The script conversion functions allows some interesting arguments which can be seen in +their respective function documentation, :func:`convert_script() ` +and :func:`convert_apdl_block() `. +Especially interesting are they keyword arguments ``add_imports``, ``comment_solve`` or +``print_com``. + Of particular note in the following examples is how most of the commands can be called as a method to the ansys object rather than sending a string as a command. Additionally, take note that some diff --git a/tests/test_commands.py b/tests/test_commands.py index 5fa92764d2..08c7a6f66a 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -5,7 +5,7 @@ from ansys.mapdl.core import examples from ansys.mapdl.core.commands import CommandOutput, CommandListingOutput, BoundaryConditionsListingOutput -from ansys.mapdl.core.commands import CMD_LISTING, CMD_BC_LISTING +from ansys.mapdl.core.commands import CMD_LISTING, CMD_BC_LISTING, Commands try: import pandas as pd @@ -212,7 +212,8 @@ def test_bclist(mapdl, beam_solve, func): def test_docstring_injector(mapdl, method): """Check if the docstring has been injected.""" for name in dir(mapdl): - if name[0:4].upper() == method: + if name[0:4].upper() == method and name in dir(Commands): # avoid matching Mapdl properties which starts with same letters as MAPDL commands. + func = mapdl.__getattribute__(name) # If '__func__' not present (AttributeError) very likely it has not # been wrapped. diff --git a/tests/test_convert.py b/tests/test_convert.py index 648dca38e3..21ccd642a0 100644 --- a/tests/test_convert.py +++ b/tests/test_convert.py @@ -108,3 +108,9 @@ def test_logger(capsys): translator.translate_line(line) std = capsys.readouterr() assert all(['Converted' in each for each in std.err.split('\n')[:-1]]) # last one is an empty line. + + +def test_print_com_in_converter(): + assert 'print_com=True' in convert_apdl_block("/prep7\nN,,,,") # Default + assert 'print_com=True' in convert_apdl_block("/prep7\nN,,,,", print_com=True) + assert 'print_com=True' not in convert_apdl_block("/prep7\nN,,,,", print_com=False) \ No newline at end of file diff --git a/tests/test_mapdl.py b/tests/test_mapdl.py index 23541932e3..30b292663f 100644 --- a/tests/test_mapdl.py +++ b/tests/test_mapdl.py @@ -1045,3 +1045,24 @@ def test_tbft_not_found(mapdl): mat_id = mapdl.get_value('MAT', 0, 'NUM', 'MAX') + 1 mapdl.tbft('FADD', mat_id, 'HYPER', 'MOONEY', '3', mute=True) mapdl.tbft('EADD', mat_id, 'UNIA', 'non_existing.file', '', '', mute=True) + + +def test_print_com(mapdl, capfd): + mapdl.print_com = True + string_ = "Testing print" + mapdl.com(string_) + + out, err = capfd.readouterr() + assert string_ in out + + mapdl.print_com = False + string_ = "Testing disabling print" + mapdl.com(string_) + + out, err = capfd.readouterr() + assert string_ not in out + + # Not allowed type for mapdl.print_com + for each in ['asdf', (1, 2), 2, []]: + with pytest.raises(ValueError): + mapdl.print_com = each