ansys / pymapdl

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

Server connection lost after several interactions #1577

Open francesco123212 opened 1 year ago

francesco123212 commented 1 year ago

Before submitting the issue

Description of the bug

I am running pyAnsys from julia with PyCall, with an ansys student license (2022 R2).

I noticed that when there are several interactions with mapdl the connection might break because APDL crashes and I get the error attached below. The number of mapdl.some_command before the connection is lost looks to be completely random, sometimes it is in the order of 10, some times in the order of 100/200. The workaround I found is to use a try catch statement which in case of a lost connection will start new mapdl server connection and restore the model from a saved file. It is working, but I'm sure it's not the best solution. The flowchart of the try catch is:

mapdl.run("save,fileName''db',path")
try
  mapdl.run_multiline("""
    some APDL commands
    """)
catch
  mapdl = pymapdl.launch_mapdl(additional_switches="-smp",mode="grpc")
  mapdl.run("resume,filename,'db',path")
  mapd.run_multiline("""
    some APDL commands as above
    """)
end

Some notes:

  1. I am not using a python virtual environment b/c (i) I am working in julia so I don't know if it is necessary and (ii) it looks to be an APDL problem since it is the one that keeps crashing.
  2. I almost only use mapdl.run("an APDL command"),mapdl.run_multiline("""some APDL commands"""), mapdl.get("datum from database), could it be an issue? In the #544, which was related to *DO loops instability, it was suggested to use the python equivalent for loop. Would it be better to convert all the mapdl.run_multiline() in the pyansys equivalent commands?
  3. the try catch workaround is terrible to look at. I could do something better with a while loop, but it still would be a palliative and not a solution to APDL crashing for no apparent reasons

Thankyou all, I hope I haven't written atrocities, I am more of an APDL user than a julia/python user

Steps To Reproduce

Steps:

using PyCall pymapdl = pyimport("ansys.mapdl.core") mapdl = pymapdl.launch_mapdl(additional_switches="-smp",mode="grpc")

  * run lots of `mapdl.run_multiline("some APDL commands")`
  * run lots of `mapdl.get("some database data")`

### Which Operating System are you using?

Windows

### Which Python version are you using?

3.10

### PyMAPDL Report

<details><summary>
Show the Report!
</summary>

```text

PyError ($(Expr(:escape, :(ccall(#= C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\pyfncall.jl:43 =# @pysym(:PyObject_Call), PyPtr, (PyPtr, PyPtr, PyPtr), o, pyargsptr, kw))))) <class 'ansys.mapdl.core.errors.MapdlExitedError'>
MapdlExitedError('MAPDL server connection terminated')
  File "C:\Users\Francesco\.julia\conda\3\lib\site-packages\ansys\mapdl\core\mapdl.py", line 2540, in run_multiline
    return self.input_strings(commands=commands)
  File "C:\Users\Francesco\.julia\conda\3\lib\site-packages\ansys\mapdl\core\mapdl.py", line 2593, in input_strings
    self._flush_stored()
  File "C:\Users\Francesco\.julia\conda\3\lib\site-packages\ansys\mapdl\core\mapdl_grpc.py", line 1531, in _flush_stored
    out = self.input(
  File "C:\Users\Francesco\.julia\conda\3\lib\site-packages\ansys\mapdl\core\errors.py", line 145, in wrapper
    raise MapdlExitedError("MAPDL server connection terminated") from None

Stacktrace:
  [1] pyerr_check
    @ C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\exception.jl:62 [inlined]
  [2] pyerr_check
    @ C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\exception.jl:66 [inlined]
  [3] _handle_error(msg::String)
    @ PyCall C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\exception.jl:83
  [4] macro expansion
    @ C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\exception.jl:97 [inlined]
  [5] #107
    @ C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\pyfncall.jl:43 [inlined]
  [6] disable_sigint
    @ .\c.jl:473 [inlined]
  [7] __pycall!
    @ C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\pyfncall.jl:42 [inlined]
  [8] _pycall!(ret::PyObject, o::PyObject, args::Tuple{String}, nargs::Int64, kw::Ptr{Nothing})
    @ PyCall C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\pyfncall.jl:29
  [9] _pycall!(ret::PyObject, o::PyObject, args::Tuple{String}, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})       
    @ PyCall C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\pyfncall.jl:11
 [10] (::PyObject)(::String, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ PyCall C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\pyfncall.jl:86
 [11] (::PyObject)(::String, ::Vararg{Any})
    @ PyCall C:\Users\Francesco\.julia\packages\PyCall\ygXW2\src\pyfncall.jl:86
 [12] the function where I use mapdl.some_command

Installed packages

This is what I get with

using PyCall
py"""
       help('modules')
       """
Show the installed packages! ```text C:\Users\-\.julia\conda\3\lib\pkgutil.py:92: UserWarning: The numpy.array_api submodule is still experimental. See NEP 47. __import__(info.name) C:\Users\-\.julia\conda\3\lib\site-packages\_distutils_hack\__init__.py:18: UserWarning: Distutils was imported before Setuptools, but importing Setuptools also replaces the `distutils` module in `sys.modules`. This may lead to undesirable behaviors or errors. To avoid these issues, avoid using distutils directly, ensure that setuptools is installed in the traditional way (e.g. not an editable install), and/or make sure that setuptools is always imported before distutils. warnings.warn( C:\Users\-\.julia\conda\3\lib\site-packages\_distutils_hack\__init__.py:33: UserWarning: Setuptools is replacing distutils. warnings.warn("Setuptools is replacing distutils.") OpenSSL aifc hashlib select PIL aiohttp heapq selectors __future__ aiosignal hmac setuptools _abc antigravity html shelve _aix_support appdirs http shlex _ast argparse idlelib shutil _asyncio array idna signal _bisect ast imageio site _blake2 async_timeout imaplib six _bootsubprocess asynchat imghdr smtpd _bz2 asyncio imp smtplib _cffi_backend asyncore importlib sndhdr _codecs atexit importlib_metadata socket _codecs_cn attr inspect socketserver _codecs_hk attrs io socks _codecs_iso2022 audioop ipaddress sockshandler _codecs_jp base64 itertools sqlite3 _codecs_kr bdb json sre_compile _codecs_tw binascii keyword sre_constants _collections binhex kiwisolver sre_parse _collections_abc bisect lib2to3 ssl _compat_pickle brotli linecache stat _compression builtins locale statistics _contextvars bz2 logging string _csv cProfile lzma stringprep _ctypes calendar mailbox struct _ctypes_test certifi mailcap subprocess _datetime cffi marshal sunau _decimal cgi math symtable _distutils_hack cgitb matplotlib sys _elementtree charset_normalizer menuinst sysconfig _functools chunk mimetypes tabnanny _hashlib cmath mmap tarfile _heapq cmd modulefinder telnetlib _imp code msilib tempfile _io codecs msvcrt test _json codeop multidict test_pycosat _locale collections multiprocessing textwrap _lsprof colorama netrc this _lzma colorsys nntplib threading _markupbase compileall nt time _md5 concurrent ntpath timeit _msi conda nturl2path tkinter _multibytecodec conda_env numbers tlz _multiprocessing conda_package_handling numpy token _nsis configparser opcode tokenize _opcode contextlib operator toolz _operator contextvars optparse tqdm _osx_support contourpy os trace _overlapped copy packaging traceback _pickle copyreg pathlib tracemalloc _py_abc crypt pdb tty _pydecimal cryptography pickle turtle _pyio csv pickletools turtledemo _queue ctypes pip types _random curses pipes typing _sha1 cwp pkg_resources unicodedata _sha256 cycler pkgutil unittest _sha3 dataclasses platform urllib _sha512 datetime plistlib urllib3 _signal dateutil poplib uu _sitebuiltins dbm posixpath uuid _socket decimal pprint venv _sqlite3 difflib profile vtk _sre dis protoc_gen_swagger vtkmodules _ssl distutils pstats warnings _stat doctest pty wave _statistics email py_compile weakref _string encodings pyclbr webbrowser _strptime ensurepip pycosat wheel _struct enum pycparser win_inet_pton _symtable errno pydoc winreg _system_path faulthandler pydoc_data winsound _testbuffer filecmp pyexpat wsgiref _testcapi fileinput pyiges wslink _testconsole fnmatch pylab xdrlib _testimportmultiple fontTools pyparsing xml _testinternalcapi fractions pyvista xmlrpc _testmultiphase frozenlist queue xxlimited _thread ftplib quopri xxlimited_35 _threading_local functools random xxsubtype _tkinter gc re yarl _tracemalloc genericpath reprlib zipapp _uuid geomdl requests zipfile _warnings getopt rlcompleter zipimport _weakref getpass ruamel_yaml zipp _weakrefset gettext runpy zlib _winapi glob sched zoneinfo _xxsubinterpreters graphlib scipy _zoneinfo grpc scooby abc gzip secrets ```
mikerife commented 1 year ago

Hi @francesco123212 Sorry, I accidentally hit send on the comment before I was ready...and with a half-baked idea. Can you post some APDL that results in the server disconnection? Mike

francesco123212 commented 1 year ago

Hi @francesco123212 Sorry, I accidentally hit send on the comment before I was ready...and with a half-baked idea. Can you post some APDL that results in the server disconnection? Mike

here it is @mikerife. I use it for the prediction of the driving force in terms of SIF of a crack in notched plate, so it goes in a loop that changes the length of the crack and its height wrt the symmetry plane. (I have tested the codes on my PC and they are working):

#useless for python users
using PyCall
pymapdl = pyimport("ansys.mapdl.core")

mapdl = pymapdl.launch_mapdl(additional_switches="-smp",mode="grpc")
mapdl.run_multiline("""
  /clear
  !
  *set,toll,1e-5
  *set,pi,2*asin(1)
  !-----------------------------------------------------!
  !       SCHEMATIC ILLUSTRATION OF THE SPECIMEN        !
  !-----------------------------------------------------!
  !     /) alpha
  !    /_________________________________
  !   /         |
  !  /          |
  ! |    |      | hh2 = 7.50
  ! |    | hh1  |
  ! |____|______|________________________
  ! 
  ! <----------------LL = 40------------>
  !-----------------------------------------------------!
  !                  GEOMETRY PARAMETERS                !
  !-----------------------------------------------------!
  ! geometry
  *set,rho,0.1
  *set,hh1,2.52
  *set,hh2,7.50
  *set,LL,40
  *set,aa_notch,hh2-hh1
  *set,alpha2,90 !deg
  /prep7
  !-----------------------------------------------------!
  !   ELEMENT TYPE AND MATERIAL PROPERTIES DEFINITION   !
  !-----------------------------------------------------!
  et,1,182      !Plane 4
  keyopt,1,1,3  !Simple Enhanced strain formulation
  keyopt,1,3,2  !Plane strain
  ! mp definition
  mp,Ex,1,114e3
  mp,PRxy,1,.34
  !-----------------------------------------------------!
  !         NOMINAL GEOMETRY WO CRACKS/DEFECTS          !
  !-----------------------------------------------------!
  k,10000,-(hh1+rho)
  circle,10000,rho,,,alpha2/2
  kDele,10000
  kSel,u,loc,y,-toll,toll
  *get,tmp1,kp,kpNext(0),loc,x
  *set,tmp1,hh2+tmp1
  *get,tmp2,kp,kpNext(0),loc,y
  allSel
  k,,-hh2,tmp2+tmp1
  k,,-hh2,LL
  k,,,LL
  k
  *del,tmp1
  *del,tmp2
  !
  *get,n_kp,kp,0,count
  *do,i,2,n_kp-1
  l,i,i+1
  *endDo
  lSymm,y,all
  numMrg,kp,toll,,,low
  !merge lines
  kSel,s,loc,y,-toll,toll
  kSel,u,loc,x,-toll,toll
  lSlK,s
  lComb,all,,0
  ! now reselect all
  allSel
  aL,all             
   """)
cSys_crackTip = 11
crackLength = 0.007 #mm
cv_count = 8
elmSizes = [0.0014; 0.0028; 0.0056; 0.0112; 0.0224; 0.0448; 0.0896; 0.1792; 0.3584]
cvSizes = [0.014; 0.0252; 0.0420; 0.0756; 0.1428; 0.2772; 0.5460; 1.0836]
crackHeight = 0
crackOrientation = 0
elmAlongCrack_count = 5
# create the local reference system at crack tip
mapdl.run_multiline("""
  ksel,none
  lsel,s,loc,x,-hh2-toll,-hh1+toll
  wpoffs,,$crackHeight
  wprota,,90
  lsbw,all
  wpcsys,-1,0
  *set,x_crackTip,kx(kpnext(0))
  *set,y_crackTip,ky(kpnext(0))
  allsel
  ! now move WP at the desired location
  wpOffs,x_crackTip,y_crackTip
  wpRota,$crackOrientation
  wpOffs,$crackLength
  ! create the local reference system
  cSWpla,$cSys_crackTip
  ! move all back to the origin
  csys,0
  """)
# create cracks
crackMaker_2D(cSys_crackTip,crackLength,elmAlongCrack_count,cv_count,cvSizes)
cVMesher_2D(cv_count,elmSizes)
#=
apply BCs and solve
=#
mapdl.run_multiline("""
  lSel,s,loc,y,LL-toll,LL+toll
  sfL,all,pres,-1
  lSel,s,loc,y,-LL-toll,-LL+toll
  dL,all,0,uy
  lSel,s,loc,x,-toll,toll
  dL,all,0,symm
  allSel
  /solu
  eqSlv,pCG
  solve
  /post1
  """)
#=
PSM application on the node edge:
step0: create the named selection for the crack tip node
step1: apply PSM and compute for SFIs/N-SIFs at the crack tip/notch tip node
=#
# step0
mapdl.run_multiline("""
  ! switch to local reference system W origin at crack tip
  cSys,$cSys_crackTip
  ! select crack tip node
  kSel,s,loc,y,-toll,toll
  kSel,r,loc,x,-toll,toll
  ! switch back to 
  cSys,0
  cm,Vnotch_tip,kp
  allsel
  """)
# step 1 (for now a simplified version, only BC I already know the stress at the notch tip!)
mapdl.run_multiline("""
  ! select the kp of interet (I already know it is one!)
  cmSel,s,Vnotch_tip,kp
  ! select attached kp
  nSlK,s
  ! get ID of the node
  """)
nd_ID = int(mapdl.get("tmp","NODE",0,"NXTH"))
sy = mapdl.get("tmp","NODE",nd_ID,"S","Y")

where:

    function cvMaker_2D(cSys_crackTip::Int,cvSize::Number)
  mapdl.run_multiline("""
    cSys,$cSys_crackTip
    wpCSys,-1,$cSys_crackTip
    ! unselect all lines, areas and kps 
    asel,none
    lsel,none
    ksel,none
    ! create the square control volume
    rectng,$cvSize,-$cvSize,$cvSize,-$cvSize
    ! remove the newly created area only
    adele,all
    ! select the area to be divided by the cv lines and divide
    cmSel,all
    asel,inve
    asbl,all,all
    """)
end
function crackMaker_2D(cSys_crackTip::Int,crackLength::Number,elmAlongCrack_count::Number,cv_count::Int,cvSizes::AbstractArray)
  #=
  create the first control volume and the crack
  =#
  mapdl.run_multiline("""
    ! switch to the cSys  cSys_crackTip
    cSys,$cSys_crackTip
    wpCSys,-1,$cSys_crackTip
    ! unselect all lines and areas
    lsel,none
    asel,none
    ! create the square control volume
    rectng,$(crackLength/elmAlongCrack_count),-$(crackLength/elmAlongCrack_count),$(crackLength/elmAlongCrack_count),-$(crackLength/elmAlongCrack_count)
    rectng,$(cvSizes[1]),-$(cvSizes[1]),$(cvSizes[1]),-$(cvSizes[1])
    ! delete newly created areas only (not lines and below)
    adele,all
    asel,all
    ! divide the area by the newly created rectangles lines
    ! to obtain the first CV
    asbl,all,all
    ! select the newly created CVs (2!)
    asel,s,loc,y,-$(cvSizes[1])-toll,$(cvSizes[1])+toll
    asel,r,loc,x,-$(cvSizes[1])-toll,$(cvSizes[1])+toll
    ! divide the CVs to obtain the crack
    wprota,,-90
    asbw,all
    ! geometry manipulations to have redundant edges on the 
    ! crack
    wprota,-90,90
    lsel,s,loc,y
    lsel,r,loc,z,-$(cvSizes[1])+toll,$crackLength
    lsbw,all
    !
    asel,r,loc,y,0,$(cvSizes[1])
    agen,2,all,,,,,10,,1
    asel,r,loc,z,-$(cvSizes[1]),$(cvSizes[1])
    adele,all
    asel,s,loc,y,0-toll,$(cvSizes[1])+toll
    asel,r,loc,z,10-toll,10+toll
    agen,1,all,,,,,-10,,1,1
    wprota,180,,90
    wprota,,180
    !              
    ksel,s,loc,y,-toll,toll
    ksel,r,loc,x,-$crackLength-toll,-toll
    ksel,inve
    numMrg,kp
    asel,s,loc,y,-$(cvSizes[1])-toll,$(cvSizes[1])+toll
    asel,r,loc,x,-$(cvSizes[1])-toll,$(cvSizes[1])+toll
    ! create a named selection for the cracked areas
    cm,cracked_ar,area
    ! go back to the global cSys
    cSys,0
    ! remove unnecessary lines
    allsel
    lsla,u
    ldele,all,1
    !
    allsel
    """)
  #=
  create further CVs
  Here a try catch error could be implemented, printing a warning when error
  =#
  for i in 2:cv_count
    cv_ID = i
    cvSize = cvSizes[i]
     #=
    create the control volume selection
    =#
    cvMaker_2D(cSys_crackTip,cvSize)
    #=
    create the named selection
    =#
    mapdl.run_multiline("""
      asel,none
      cmSel,all
      asel,inve
      asel,r,loc,y,-$cvSize-toll,$cvSize+toll
      asel,r,loc,x,-$cvSize-toll,$cvSize+toll
      cm,cv%$cv_ID%_ar,area
      """)
  end
  mapdl.run_multiline("""
    allSel
    csys,0
    """)
end

function cVMesher_2D(cv_count::Number,elmSizes::AbstractArray)
  #=
  start meshing the cracked areas (cv0)
  =#
  mapdl.run_multiline("""
    cmSel,s,cracked_ar,area
    esize,$(elmSizes[1])
    amesh,all
    """)
  #=
  mesh the control volumes now
  =#
  for i in 2:cv_count
  cv_ID = i
  elmSize = elmSizes[i]
  mapdl.run_multiline("""
    cmSel,s,cv%$cv_ID%_ar,area
    esize,$elmSize
    amesh,all
    allsel
    """)
  end
  #=
  the rest of the volume
  =#
  mapdl.run_multiline("""
    allsel
    !unselect already meshed araes
    asel,u,type,,-1
    esize,$(elmSizes[end])
    amesh,all
    allsel""")
end
int(x) = floor(Int,x)
francesco123212 commented 1 year ago

I reiterate that the connnection, to my eyes, is lost completely randomly. Sometimes at the 2nd simulation, sometimes at the 20th its a bit annoying

akaszynski commented 1 year ago

@FredAns, I think this server connection instability is going to keep coming up until we fix how we're writing output to disk.

@francesco123212, whenever possible, either call commands with mute=True as in mapdl.prep7(mute=True), or enable mute globally with mapdl.mute = True as there's a known instability when outputting from MAPDL to a temporary file to get the output.

francesco123212 commented 1 year ago

@akaszynski, thanks for the advice. I tried to go with mapdl.mute = true, but it still crashes sometimes. To avoid the fatal error in my code I am doing smt like:

mapdl.run("save,fileName''db',path")
while true
  try
    mapdl.run_multiline("""
      some APDL commands
      """)
      break
  catch
    mapdl = pymapdl.launch_mapdl(additional_switches="-smp",mode="grpc")
    mapdl.mute = true
    mapdl.run("resume,fileName''db',path")
    continue
  end
end
germa89 commented 1 year ago

@akaszynski, thanks for the advice. I tried to go with mapdl.mute = true, but it still crashes sometimes. To avoid the fatal error in my code I am doing smt like:

mapdl.run("save,fileName''db',path")
while true
  try
    mapdl.run_multiline("""
      some APDL commands
      """)
      break
  catch
    mapdl = pymapdl.launch_mapdl(additional_switches="-smp",mode="grpc")
    mapdl.mute = true
    mapdl.run("resume,fileName''db',path")
    continue
  end
end

@francesco123212 does this works?

francesco123212 commented 1 year ago

Hi @germa89,

adding mapd.mute = true does not solve the connection to MAPDL issue. With the while true loop and try catch statement it works fine, but it's slow and I don't like the solution

germa89 commented 1 year ago

Personally I dont like the solution either. But if it is a server side issue, it will take a while to be solved.

francesco123212 commented 1 year ago

Could it be related to my student license?

germa89 commented 1 year ago

Honestly I don't think so/I hope not!

francesco123212 commented 1 year ago

dear @germa89, is it possible that if the code runs into several errors in APDL, then APDL crashes resulting in the loss of the connection?

germa89 commented 1 year ago

it is very likely that. You should check any error file in the mapdl.directory.