ansys / pymapdl

Pythonic interface to MAPDL
https://mapdl.docs.pyansys.com
MIT License
428 stars 120 forks source link

Limited number of uses for mapdl.input() with gRPC #380

Closed Telos4 closed 3 years ago

Telos4 commented 3 years ago

I noticed that with the new remote gRPC instance it is only possible to use the mapdl.input() function a limited number of times (18 in my case). I guess this is caused by the maximum of 20 nested file switches as documented in the /INPUT in the APDL command reference. Each mapdl.input() seems to consume one nesting and after a while none are left.

See the attached code snipped for a minimum example:

from ansys.mapdl import core as pymapdl

# create dummy nodes file
nodes = """
n,1, 0, 0, 0
n,2, 1.344572872606749E-05, 0, 0
n,3, 3.0960156326424423E-05, 0, 0
"""
with open("nodes.win", 'w') as f:
    f.write(nodes)

# connect to remote ansys APDL
mapdl = pymapdl.Mapdl(ip='<your-ip-here>', port=50052, request_instance=True, 
                      log_level='DEBUG')
# use local APDL
#mapdl = pymapdl.launch_mapdl()  # -> leads to the same problem

for i in range(20):
    mapdl.finish()
    mapdl.run("/clear")
    mapdl.run("/Filname, mesh")
    mapdl.run("/prep7")

    # send nodes file to remote ansys server for execution
    print(i, mapdl.input('nodes.win'))  # -> works only 18 times, 
    # afterwards I get the following error/warning:
    #  *** WARNING ***                         CP =       4.797   TIME= 15:15:35
    #Invalid /INPUT file or too many levels.  

This happens even when I'm running everything local (i.e. by specifying 'localhost' as ip) and even when using pymapdl.launch_mapdl() (which makes sense because this seems to use the Mapdl class internally; in fact, in this case the mapdl.input() command actually only works 17 times).

Some information about the version I'm running:

When using the old version of pyansys it works fine:

from pyansys import launch_mapdl

# create dummy nodes file
nodes = """
n,1, 0, 0, 0
n,2, 1.344572872606749E-05, 0, 0
n,3, 3.0960156326424423E-05, 0, 0
"""
with open("nodes.win", 'w') as f:
    f.write(nodes)

# connect to remote ansys APDL
mapdl = launch_mapdl(run_location='C:/Users/<user>/ansys_workdir')

for i in range(20):
    mapdl.finish()
    mapdl.run("/clear")
    mapdl.run("/Filname, mesh")
    mapdl.run("/prep7")

    # send nodes file to remote ansys server for execution
    print(i, mapdl.input('nodes.win'))  # -> this works fine
akaszynski commented 3 years ago

That's absolutely an issue, and I can reproduce it in some situations.

Pinging @FredAns: Fred, is there any way we can manually reset the /input nest level (either from Python or server side)?

For the time being, can you try the following?

for i in range(20):
    mapdl.finish()
    mapdl.run("/clear")
    mapdl.run("/Filname, mesh")
    mapdl.run("/prep7")

    # send nodes file to remote ansys server for execution
    with mapdl.non_interactive:
        mapdl.input('nodes.win')
    print(i, mapdl.response)
Telos4 commented 3 years ago

I just tried your suggestion of using mapdl.non_interactive, but the problem still appears.

akaszynski commented 3 years ago

Thanks for trying that. I'm pinging some people internally within Ansys to figure out if we can find a workaround.

akaszynski commented 3 years ago

Just got it. The issue is that /CLEAR is being passed. If we run it using the default /CLEAR, START, it reads the start.ans file, which enters into another input level.

Fix is just to use mapdl.clear(), which is configured to use "NOSTART" by default:

from ansys.mapdl import core as pymapdl

# create dummy nodes file
nodes = """
n,1, 0, 0, 0
n,2, 1.344572872606749E-05, 0, 0
n,3, 3.0960156326424423E-05, 0, 0
"""
with open("nodes.win", 'w') as f:
    f.write(nodes)

# connect to remote ansys APDL
# mapdl = pymapdl.Mapdl(ip='<your-ip-here>', port=50052, request_instance=True, 
#                       log_level='DEBUG')
# use local APDL
mapdl = pymapdl.launch_mapdl()  # -> leads to the same problem

for i in range(50):
    mapdl.finish()
    mapdl.clear()
    mapdl.run("/Filname, mesh")
    mapdl.prep7()

    # send nodes file to remote ansys server for execution
    print(i, mapdl.input('nodes.win'))
akaszynski commented 3 years ago

I'll make a PR that captures /CLEAR commands so that you can still use mapdl.run('/clear') and pymapdl will automatically append NOSTART.

Telos4 commented 3 years ago

Thanks, using the mapdl.clear() did indeed fix the issue for me.

I've encountered this issue while investigating another problem. I'll open a new issue for that.