Skip to content

Commit

Permalink
Print /COM to python console (#866)
Browse files Browse the repository at this point in the history
* Adding functionality to `/COM` function

* Adding functionality to Mapdl class init.

* Adding keyword to the subclasses

* Adding unit test.

* adding info on the documentation

* removed unused package

* Fixing test unit.

* Making default print_com equal true in the converter module.

* Adding corresponding unit test.

* Added changes to launch_mapdl
  • Loading branch information
germa89 authored Jan 31, 2022
1 parent d41c65f commit 1859e7b
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 23 deletions.
2 changes: 2 additions & 0 deletions ansys/mapdl/core/_commands/session/list_controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
36 changes: 28 additions & 8 deletions ansys/mapdl/core/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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(
Expand All @@ -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):
Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions ansys/mapdl/core/launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1124,6 +1129,7 @@ def launch_mapdl(
"additional_switches": additional_switches,
"jobname": jobname,
"nproc": nproc,
"print_com": print_com,
}

if mode in ["console", "corba"]:
Expand Down
34 changes: 26 additions & 8 deletions ansys/mapdl/core/mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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):
Expand All @@ -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))

Expand Down Expand Up @@ -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()

Expand All @@ -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()])
Expand Down
4 changes: 2 additions & 2 deletions ansys/mapdl/core/mapdl_console.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
6 changes: 5 additions & 1 deletion ansys/mapdl/core/mapdl_corba.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,18 @@ 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,
log_file = 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
Expand Down
9 changes: 7 additions & 2 deletions ansys/mapdl/core/mapdl_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -230,15 +234,16 @@ 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

# port and ip are needed to setup the log
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)
Expand Down
7 changes: 7 additions & 0 deletions doc/source/user_guide/convert.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ using :func:`convert_apdl_block() <ansys.mapdl.core.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() <ansys.mapdl.core.convert_script>`
and :func:`convert_apdl_block() <ansys.mapdl.core.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
Expand Down
5 changes: 3 additions & 2 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
6 changes: 6 additions & 0 deletions tests/test_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
21 changes: 21 additions & 0 deletions tests/test_mapdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 1859e7b

Please sign in to comment.