pymapdl icon indicating copy to clipboard operation
pymapdl copied to clipboard

Unexpected MAPDL server disconnection while running a series of ``aplot()``

Open germa89 opened this issue 2 years ago • 7 comments

Discussed in https://github.com/pyansys/pymapdl/discussions/1411

Originally posted by hawkoli1987 August 26, 2022 Dear All,

I am trying to generating a random range of 2D shapes in series, there are 100 numbers of such shapes in total. For each shape generated, I ordered a printout of it via mapdl.aplot(). After a bunch of such shapes were successfully generated, there is always an automatic server disconnection which stops me from generating new shapes.

However, if I simply change the aplot() to lplot(), it will complete the generation process successfully.

Another issue I had was that on one side of the shape, it's a curve that was generated by fitting a spline through a series of keypoints. Among all the area plots, I can always spot a few that looks like straight line-segments rather than a spline.

I would assume both issues are connected? and perhaps both was caused by insufficient memory? I attached my code here in a zip. Please enlighten me on this, thanks!


---------------------------------------------------------------------------
MapdlExitedError                          Traceback (most recent call last)
Input In [5], in <cell line: 124>()
    125 geo = Geometry(curve = line.tolist())
    126 mat = Material()
--> 127 get_Ue(mat, geo)

Input In [5], in get_Ue(mat, geo, c_r, force, disp, AESIZE, refine_lvl, detach_step)
    114 else:
    115     mapdl.rectng(0, geo.diameter/2, 0, geo.height)
--> 116 mapdl.aplot('ALL',cpos="xy")
    117 return

File ~\anaconda3\envs\pyansys_env\lib\site-packages\ansys\mapdl\core\mapdl.py:1478, in _MapdlCore.aplot(self, na1, na2, ninc, degen, scale, vtk, quality, show_area_numbering, show_line_numbering, color_areas, show_lines, **kwargs)
   1476 if quality < 1:
   1477     quality = 1
-> 1478 surf = self.geometry.generate_surface(11 - quality, na1, na2, ninc)
   1479 meshes = []
   1480 labels = []

File ~\anaconda3\envs\pyansys_env\lib\site-packages\ansys\mapdl\core\misc.py:324, in supress_logging.<locals>.wrapper(*args, **kwargs)
    321 if prior_log_level != "CRITICAL":
    322     mapdl._set_log_level("CRITICAL")
--> 324 out = func(*args, **kwargs)
    326 if prior_log_level != "CRITICAL":
    327     mapdl._set_log_level(prior_log_level)

File ~\anaconda3\envs\pyansys_env\lib\site-packages\ansys\mapdl\core\misc.py:346, in run_as_prep7.<locals>.wrapper(*args, **kwargs)
    343 if prior_processor != "PREP7":
    344     mapdl.prep7()
--> 346 out = func(*args, **kwargs)
    348 if prior_processor == "Begin level":
    349     mapdl.finish()

File ~\anaconda3\envs\pyansys_env\lib\site-packages\ansys\mapdl\core\mapdl_geometry.py:293, in Geometry.generate_surface(self, density, amin, amax, ninc)
    290     self._mapdl.prep7(mute=True)
    292 # Mesh and get the number of elements per area
--> 293 resp = self._mapdl.amesh("all")
    294 groups = get_elements_per_area(resp)
    296 self._mapdl.esla("S")

File ~\anaconda3\envs\pyansys_env\lib\site-packages\ansys\mapdl\core\_commands\preproc\meshing.py:182, in Meshing.amesh(self, na1, na2, ninc, **kwargs)
    160 """Generates nodes and area elements within areas.
    161 
    162 APDL Command: AMESH
   (...)
    179 This command is also valid for rezoning.
    180 """
    181 command = f"AMESH,{na1},{na2},{ninc}"
--> 182 return self.run(command, **kwargs)

File ~\anaconda3\envs\pyansys_env\lib\site-packages\ansys\mapdl\core\mapdl.py:2630, in _MapdlCore.run(self, command, write_to_log, mute, **kwargs)
   2627         self._check_parameter_name(param_name)
   2629 verbose = kwargs.get("verbose", False)
-> 2630 text = self._run(command, verbose=verbose, mute=mute)
   2632 if mute:
   2633     return

File ~\anaconda3\envs\pyansys_env\lib\site-packages\ansys\mapdl\core\mapdl_grpc.py:736, in MapdlGrpc._run(self, cmd, verbose, mute)
    734     response = self._send_command_stream(cmd, True)
    735 else:
--> 736     response = self._send_command(cmd, mute=mute)
    737 self._busy = False
    739 return response.strip()


File ~\anaconda3\envs\pyansys_env\lib\site-packages\ansys\mapdl\core\errors.py:138, in protect_grpc.<locals>.wrapper(*args, **kwargs)
    136     # Must close unfinished processes
    137     mapdl._close_process()
--> 138     raise MapdlExitedError("MAPDL server connection terminated") from None
    140 if threading.current_thread().__class__.__name__ == "_MainThread":
    141     received_interrupt = bool(SIGINT_TRACKER)

MapdlExitedError: MAPDL server connection terminated
---------------------------------------------------------------------------

File:

Issue.zip hawkoli1987

germa89 avatar Aug 29 '22 10:08 germa89

Interesting...

After a while it doesn't seem to do the splines properly:

image

However, the MAPDL figure does show correct geometry:

image

Hence I believe the interpolation thing it is more an mapdl-pyvista mapping issue. I will open another issue about this.

germa89 avatar Aug 29 '22 12:08 germa89

Sometimes I get weird lines:

image

germa89 avatar Aug 29 '22 12:08 germa89

I'm using a slightly modified version of OP's code:

Show me
#!/usr/bin/env python
# coding: utf-8

# In[5]:

import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
import matplotlib.pyplot as plt
import math
import random
import matplotlib.pyplot as plt
# from scipy.integrate import quad
from math import* #import all function from math
from ansys.mapdl.core import launch_mapdl
exec_loc = 'C:/Program Files/ANSYS Inc/v222/ANSYS/bin/winx64/ANSYS222.exe'

mapdl = launch_mapdl(exec_loc, port=50060, add_env_vars={'ANS_DEBUG_CRASH':1})
print(mapdl)

print(mapdl.directory)

mapdl.nerr(200, 99999999, -1)


def Coefficient_Gen(pop_size, mode = 20, center_tolerance=1, max_amplitude=8):
    n = mode   
    tol = center_tolerance
    
    Ans = np.empty(shape = (0,20))
    Bns = np.empty(shape = (0,20))
    
    while Ans[:,0].size < pop_size:
        An = np.expand_dims(np.array([random.uniform(-1, 1) for _ in range(n)]), axis = 0)
        Bn = np.expand_dims(np.array([random.uniform(-1, 1) for _ in range(n)]), axis = 0)
        line = to_Fourier(An, Bn)
        line_max = np.absolute(line).max()
        line_avg = np.average(line) 
        if line_avg<-tol or line_avg>tol or line_max>max_amplitude:
            continue
        Ans = np.vstack((Ans, An))
        Bns = np.vstack((Bns, Bn))
        DNAs = np.hstack((Ans, Bns))
    return DNAs
    
def to_Fourier(An, Bn, segment = 20):

    if An.shape == Bn.shape:
        n = An[0,:].size
    else:
        print('Error: coefficients size mismatch')
    
    x=np.arange(-np.pi,np.pi,2*np.pi/segment) #x axis has been chosen from –π to +π, value 
    x=np.expand_dims(x, 0)
    total = 0

    for i in range(n):
        if i==0.0:
            total+=An[:,i]/2 # in case n=0
            total=total[:,np.newaxis]
        else:
            total = total + An[:,i][:,np.newaxis]*np.cos(i*x)+Bn[:,i][:,np.newaxis]*np.sin(i*x)

    return total

POP_SIZE = 100
DNA_SIZE = 40

class Material:
    """
    elastic modulus (kPa), 
    poisson ratio 
    work of adhesion (mJ/m^2)
    """
    def __init__(self, E_modulus = 500, nu=0.4, w_ad = 20):
        self.E_modulus = E_modulus*1e-3  # elasticu modulus: kPa -> uN/um^2
        self.nu = nu                     # poisson ratio: dimensionless
        self.w_ad = w_ad *1e-3           # work of adhesion: mJ/m^2 -> uN/um  

class Geometry:
    """
    unit (um)
    """    
    def __init__(self, height = 100, diameter=50, curve=[]):
        self.height = height        # fiber height: um
        self.diameter = diameter    # fiber average diameter: um
        self.curve = curve          # curved side profile, either None (straight edge) or 1D array of radius

def translateDNA(pop): # DNA samples to split into different gene groups, e.g. An, Bn
    An = pop[:,:int(DNA_SIZE/2)]
    Bn = pop[:,int(DNA_SIZE/2):]
    return An, Bn

def get_Ue(mat, geo, c_r=None, force=None, disp=None, AESIZE=5, refine_lvl=3, detach_step=5):

    # reset mapdl
    mapdl.clear()
    mapdl.prep7()   
    
    # Define element attributes
    # keyoption 3 = 1 (axis-symmetric formulation)
    mapdl.et(1, "PLANE182", kop3=1)
    
    # create cross-sectional area of fiber
    if geo.curve != []:
        line = geo.curve
        n = len(line)
        segment = geo.height/(n-1)

        for i, value in enumerate(line):
            mapdl.k(i+2, value+geo.diameter/2, i*segment)

        mapdl.ksel('all')
        mapdl.run("BSPLIN, 'all'")
        mapdl.cm("curved_edge", "LINE")

        mapdl.k(1,0,0) # starting at origin
        mapdl.k(n+2,0,geo.height) # ending at the top
        mapdl.lstr(1,2)
        mapdl.lstr(n+1,n+2)
        mapdl.lstr(n+2,1)
        try:
            mapdl.al('ALL')
        except:
            mapdl.lplot('ALL',cpos="xy")
    else:
        mapdl.rectng(0, geo.diameter/2, 0, geo.height)
    mapdl.aplot('ALL',cpos="xy")
    mapdl.aplot(vtk=False)
    return

pop = Coefficient_Gen(pop_size = POP_SIZE)   # initialize the pop DNA
An, Bn = translateDNA(pop)
lines = to_Fourier(An, Bn)
print(lines)

for ind, line in enumerate(lines):
    print(f"Line: {ind}/{len(lines)}")
    geo = Geometry(curve = line.tolist())
    mat = Material()
    get_Ue(mat, geo)

germa89 avatar Aug 29 '22 12:08 germa89

I get the same error as OP:


---------------------------------------------------------------------------
MapdlExitedError                          Traceback (most recent call last)
c:\ansys_jobs\aplot_failing\Issue.py in <module>
    138     geo = Geometry(curve = line.tolist())
    139     mat = Material()
--> 140     get_Ue(mat, geo)
    141
    142

c:\ansys_jobs\aplot_failing\Issue.py in get_Ue(mat, geo, c_r, force, disp, AESIZE, refine_lvl, detach_step)
    124             mapdl.aplot(vtk=False)
    125         except:
--> 126             mapdl.lplot('ALL',cpos="xy")
    127     else:
    128         mapdl.rectng(0, geo.diameter/2, 0, geo.height)

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\mapdl.py in lplot(self, nl1, nl2, ninc, vtk, show_line_numbering, show_keypoint_numbering, color_lines, **kwargs)
   1726             kwargs.setdefault("show_scalar_bar", False)
   1727             kwargs.setdefault("title", "MAPDL Line Plot")
-> 1728             if not self.geometry.n_line:
   1729                 warnings.warn(
   1730                     "Either no lines have been selected or there is nothing to plot."

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\mapdl_geometry.py in n_line(self)
    363         1
    364         """
--> 365         return self._item_count("LINE")
    366
    367     @property

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\misc.py in wrapper(*args, **kwargs)
    373             mapdl._set_log_level("CRITICAL")
    374
--> 375         out = func(*args, **kwargs)
    376
    377         if prior_log_level != "CRITICAL":

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\mapdl_geometry.py in _item_count(self, entity)
    380     def _item_count(self, entity):
    381         """Return item count for a given entity."""
--> 382         return int(self._mapdl.get(entity=entity, item1="COUNT"))
    383
    384     @property

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\mapdl.py in get(self, par, entity, entnum, item1, it1num, item2, it2num, item3, **kwargs)
   2240         # Checking printout is not suppressed by checking "wrinqr" flag.
   2241         flag = 0
-> 2242         if self.wrinqr(1) != 1:  # using wrinqr is more reliable than *get
   2243             flag = 1
   2244             self._run("/gopr")

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\mapdl_grpc.py in wrinqr(self, key, **kwargs)
   2513     def wrinqr(self, key, **kwargs):
   2514         """Wrap the ``wrinqr`` method to take advantage of the gRPC methods."""
-> 2515         super().wrinqr(key, pname=TMP_VAR, mute=True, **kwargs)
   2516         return self.scalar_param(TMP_VAR)
   2517

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\_commands\inq_func.py in wrinqr(self, key, pname, **kwargs)
   1404
   1405         """
-> 1406         return self.run(f"{pname} = wrinqr({key})", **kwargs)

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\mapdl.py in run(self, command, write_to_log, mute, **kwargs)
   2694
   2695         verbose = kwargs.get("verbose", False)
-> 2696         text = self._run(command, verbose=verbose, mute=mute)
   2697
   2698         if mute:

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\mapdl_grpc.py in _run(self, cmd, verbose, mute)
    744             response = self._send_command_stream(cmd, True)
    745         else:
--> 746             response = self._send_command(cmd, mute=mute)
    747         self._busy = False
    748

~\Others_pymapdls\pymapdl_1\pymapdl\src\ansys\mapdl\core\errors.py in wrapper(*args, **kwargs)
    143             # Must close unfinished processes
    144             mapdl._close_process()
--> 145             raise MapdlExitedError("MAPDL server connection terminated") from None
    146
    147         if threading.current_thread().__class__.__name__ == "_MainThread":

MapdlExitedError: MAPDL server connection terminated

And there is no generated ANS_DEBUG_CRASH file.

germa89 avatar Aug 29 '22 12:08 germa89

The fundamental issue is we're not transferring the underlying tessellated geometry from MAPDL to Python, but rather we have to generate a faux FEA mesh overlaid on top of the existing areas. This has always been a stopgap, waiting for an API to directly transfer the tessellated faces generated with the underlying APLOT command.

Whether or not we do this depends on how long we plan on using the internal MAPDL geometry kernel. Since we have nothing to replace it with, I think we should still support it.

akaszynski avatar Aug 29 '22 14:08 akaszynski

Whether or not we do this depends on how long we plan on using the internal MAPDL geometry kernel. Since we have nothing to replace it with, I think we should still support it.

I agree on this.

I cannot understand though how the crash is happening in the current implementation. The geometry kernel should be stable enough to support create, export and delete a faux FEA mesh.

I will propose then to leave this on hold until more progress is made on the gRPC implementation.

germa89 avatar Aug 29 '22 14:08 germa89

I recheck this issue on the latest PyMAPDL version and 222, I still get the same MAPDL crash.

germa89 avatar Sep 18 '23 09:09 germa89