ansys / pymapdl

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

mapdl.cmatrix doesn't work in 2020R2, 2021R1 #571

Closed linx027 closed 3 years ago

linx027 commented 3 years ago

Describe the bug This is really a very elegant way to use APDL and I'm trying to use it. But I encountered some problems in calculating the electromagnetic field. I convert an example by PyMAPDL which use the APDL command CMATRIX. After running I can't get the result by mapdl.parameters.

To Reproduce Steps to reproduce the behavior:

  1. run the following code
  2. display the mapdl.parameters

Expected behavior A array named CMATRIX in mapdl.parameters

Screenshots image

System Information:

Additional context The same error when using mapdl.gmatrix, I try the same python code with 2019R2, the command mapdl.cmatrix works well but another error occurred with mapdl.open_gui , when I exit the GUI, the error raised, which does not happen when close GUI with 2020R2, 2021R1. I'm not sure if there is a problem with my software installation or an internal error in PyMAPDL, waiting to get your reply.

Run a PyMAPDL report

"""Script generated by ansys-mapdl-core version 0.59.5"""
# %%
from ansys.mapdl.core import launch_mapdl

mapdl = launch_mapdl(loglevel="WARNING")

mapdl.run("/batch,list")

mapdl.prep7()

mapdl.title("Capacitance of two long cylinders above a ground plane")

mapdl.run("a=100")  # Cylinder inside radius (μm)

mapdl.run("d=400")  # Outer radius of air region

mapdl.run("ro=800")  # Outer radius of infinite elements

mapdl.et(1, 121)  # 8-node 2-D electrostatic element

mapdl.et(2, 110, 1, 1)  # 8-node 2-D Infinite element

mapdl.emunit("epzro", 8.854e-6)  # Set free-space permittivity for μMKSV units

mapdl.mp("perx", 1, 1)

mapdl.cyl4("d/2", "d/2", "a", 0)  # Create mode in first quadrant

mapdl.cyl4(0, 0, "ro", 0, "", 90)

mapdl.cyl4(0, 0, "2*ro", 0, "", 90)

mapdl.aovlap("all")

mapdl.numcmp("area")

mapdl.run("smrtsiz,4")

mapdl.mshape(1)  # Mesh air region

mapdl.amesh(3)

mapdl.lsel("s", "loc", "x", "1.5*ro")

mapdl.lsel("a", "loc", "y", "1.5*ro")

mapdl.lesize("all", "", "", 1)

mapdl.type(2)

mapdl.mshape(0)

mapdl.mshkey(1)

mapdl.amesh(2)  # Mesh infinite region

mapdl.run("arsymm,x,all")  # Reflect model about y axis

mapdl.nummrg("node")

mapdl.nummrg("kpoi")

mapdl.csys(1)

mapdl.nsel("s", "loc", "x", "2*ro")

mapdl.sf("all", 'inf')  # Set infinite flag in Infinite elements

mapdl.local(11, 1, "d/2", "d/2")

mapdl.nsel("s", "loc", "x", "a")

mapdl.cm("cond1", "node")  # Assign node component to 1st conductor

mapdl.local(12, 1, "-d/2", "d/2")

mapdl.nsel("s", "loc", "x", "a")

mapdl.cm("cond2", "node")  # Assign node component to 2nd conductor

mapdl.csys(0)

mapdl.nsel("s", "loc", "y", 0)

mapdl.cm("cond3", "node")  # Assign node component to ground conductor

mapdl.allsel("all")

mapdl.finish()

mapdl.run("/solu")

mapdl.cmatrix(1, "'cond'", 3, 0)  # Compute capacitance matrix coefficients
# %%
pra = mapdl.parameters

print(pra)

mapdl.finish()

mapdl.exit()
MAPDL Parameters
----------------
A                                : 100.0
D                                : 400.0
PORT                             : 50052.0
RO                               : 800.0
linx027 commented 3 years ago

cmatrix,1,'cond',3,0 works in APDL GUI of 2020R2, 2021R1

akaszynski commented 3 years ago

Thanks for posting this. I'll hacking on this on Monday.

germa89 commented 3 years ago

@akaszynski

It seems it is an issue related on how the grpc service manage the command cmatrix. When this command is run on interactive or batch mode, the output is something like:

 *****  ANSYS SOLUTION ROUTINE  *****

 *** NOTE ***                            CP =       0.344   TIME= 09:31:08
 CMATRIX does not support multiframe restart.                            

 *** NOTE ***                            CP =       0.344   TIME= 09:31:08
 Capacitance Coefficient matrix name defaulting to cmatrix.              

  LISTING OF THE DATA ON FILE cmatrix.out

  ________________ CMATRIX SOLUTION SUMMARY ___________________

  *** Ground Capacitance Matrix ***
 Self Capacitance of conductor  1. =     0.45425E-04
 Self Capacitance of conductor  2. =     0.45425E-04
 Mutual Capacitance between conductors  1. and  2. =    -0.10049E-04
 Ground capacitance matrix is stored in 3d array parameter cmatrix ( 2., 2.,1)
  *** Lumped Capacitance Matrix ***
 Self Capacitance of conductor  1. =     0.35376E-04
 Self Capacitance of conductor  2. =     0.35376E-04
 Mutual Capacitance between conductors  1. and  2. =     0.10049E-04
 Lumped capacitance matrix is stored in 3d array parameter cmatrix ( 2., 2.,2)

 Capacitance values are per unit length

 Capacitance matricies are stored in file cmatrix .txt

 ____________________________________________________________

 ***** ROUTINE COMPLETED *****  CP =         1.922

However, when the command runs on grpc mode, it returns an empty string.

I believe it is related to the command cmatrix (in fact it is a routine) executing a "forbidden" command in the grpc mode and hence exiting the routine without making any change.

I will try to look at the source code of the cmatrix.

Caveats

akaszynski commented 3 years ago

Good findings @germa89. There's an output statement that's messing up the gRPC server. It needs to be run in non_interactive:

# Compute capacitance matrix coefficients
with mapdl.non_interactive:
    mapdl.cmatrix(1, "'cond'", 3, 0)

Normally you would access the last text response with mapdl.last_response, but due to the redirect, this isn't working and it needs to be read in with:

output = mapdl._download_as_raw('cmatrix.out').decode()

Fix is to override the method in MapdlGrpc as was done with igesin. This way we can seamlessly run the command without having the user use the non-interactive context manager.

Also, in your PR, be sure to add this as an unsupported command in: https://github.com/pyansys/pymapdl/blob/main/doc/source/user_guide/mapdl.rst

germa89 commented 3 years ago

@akaszynski discovered yesterday that CMATRIX does not work in interactive mode but it does not break the system. This opens the door to having more commands with this behavior.

For this situation (and expecting not many commands like this), these commands will be classified and described in the documentation as 'Unsupported "Interactive" Commands'. They are also added to INVAL_COMMANDS in mapdl.py (https://github.com/pyansys/pymapdl/blob/main/ansys/mapdl/core/mapdl.py). However it should be noticed that these commands won't break the server connection as other commands in this category do. In fact, CMATRIX just get ignored in interactive mode.

Other option could be to create a different section on the documentation for these commands and write a wrapper which avoid their execution in interactive modes. Maybe this could be done if we get a decent list of those commands.

akaszynski commented 3 years ago

Other option could be to create a different section on the documentation for these commands and write a wrapper which avoid their execution in interactive modes. Maybe this could be done if we get a decent list of those commands.

A list of those commands would require unit testing for each command (which we're currently missing). The assumption was that the commands would behave identically under gRPC as under stdio with some exceptions, but it's becoming clear that we should have a dedicated unit test for each command. This would help us write good example documentation, so we can kill two birds with this approach.