ansys / pymapdl

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

Topological degeneracy detected for `ASBA` command. #2292

Closed moosafly closed 11 months ago

moosafly commented 12 months ago

🤓 Before submitting the issue

🔍 Description of the bug

When I try to use subtraction to represent 1 in the matrix as having material and 0 means no material exists via mapdl.asba code and constantly loop modeling, an error like this is reported halfway through the loop

🕵️ Steps To Reproduce

mapdl = launch_mapdl()
mapdl.prep7()
matrix = np.random.randint(0,2,(30,30))

x0 = matrix.shape[0]
y0 = matrix.shape[1]
allarea = mapdl.blc4(xcorner=0,ycorner=0,width=x0*1,height=y0*1)
#Where things go wrong
for x in range(0,matrix.shape[0]):              
    for y in range(0,matrix.shape[1]):          
        if matrix[x][y] ==0:                    
            i = i+1                             
            b = mapdl.blc4(xcorner=x*1,ycorner=y
            allarea = mapdl.asba(allarea,b,'*')

💻 Which Operating System are you using?

Windows

🐍 Which Python version are you using?

3.10

📝 PyMAPDL Report

Show the Report! CRITICAL - pymapdl_global - logging - handle_exception - Uncaught exception Traceback (most recent call last): File "F:\graduate work\python\py\subtract.py", line 37, in allarea = mapdl.asba(allarea,b,'*') File "D:\python\lib\site-packages\ansys\mapdl\core\_commands\preproc\booleans.py", line 380, in asba return parse.parse_output_volume_area(self.run(command, **kwargs)) File "D:\python\lib\site-packages\ansys\mapdl\core\mapdl.py", line 3004, in run self._raise_errors(text) File "D:\python\lib\site-packages\ansys\mapdl\core\mapdl.py", line 4019, in _raise_errors self._raise_output_errors(text) File "D:\python\lib\site-packages\ansys\mapdl\core\mapdl.py", line 4091, in _raise_output_errors raise MapdlRuntimeError( ansys.mapdl.core.errors.MapdlRuntimeError: Error in instance GRPC_127.0.0.1:50052 SUBTRACT AREAS AREA NUMBERS TO BE OPERATED ON = 2 AREAS OPERATED ON WILL BE DELETED IF POSSIBLE AREA NUMBERS TO BE SUBTRACTED = 1 AREAS SUBTRACTED WILL BE DELETED IF POSSIBLE *** ERROR *** CP = 0.047 TIME= 10:58:10 Topological degeneracy detected for ASBA command. Try modifying geometry slightly or loosening the tolerance (BTOL command). If BTOL is relaxed, be sure to change the tolerance back to the default after operation. # PASTE HERE THE OUTPUT OF `python -c "from ansys.mapdl import core as pymapdl; print(pymapdl.Report())"` here ```

📝 Installed packages

Show the installed packages! import numpy as np from ansys.mapdl import core as pymapdl # PASTE HERE THE OUTPUT OF `python -m pip freeze` here ```

📝 Logger output file

Show the logger output file. # PASTE HERE THE CONTENT OF THE LOGGER OUTPUT FILE. ```
germa89 commented 12 months ago

Hi @moosafly

Can you try the advice given by the error message (using BTOL)??

For instance:


mapdl = launch_mapdl()
mapdl.prep7()
matrix = np.random.randint(0,2,(30,30))

x0 = matrix.shape[0]
y0 = matrix.shape[1]
allarea = mapdl.blc4(xcorner=0,ycorner=0,width=x0*1,height=y0*1)

#Where things go wrong

mapdl.btol(0.10E-4/2) ## reduce this number until you succeed

for x in range(0,matrix.shape[0]):              
    for y in range(0,matrix.shape[1]):          
        if matrix[x][y] ==0:                    
            i = i+1                             
            b = mapdl.blc4(xcorner=x*1,ycorner=y
            allarea = mapdl.asba(allarea,b,'*')

mapdl.btol("defa") # to reset its value.

I hope it helps!

mikerife commented 12 months ago

Hi @moosafly & @germa89 So there are a few things wrong with the code as shown:

1 b = mapdl.blc4(xcorner=x*1,ycorner=y) is incomplete. Missing the width and height.

2 allarea = mapdl.asba(allarea,b,'*') The * is not an acceptable character here.

3 You may want to pull the asba out of the loop and perform just once.

Topological degeneracies cannot be created by MAPDL so we can't get a plot to see what happened. But to get an idea of what can lead to them there are some pics in the Ansys Help:

https://ansyshelp.ansys.com/account/secured?returnurl=/Views/Secured/corp/v232/en/ans_mod/Hlp_G_MOD5_10.html

If you can correct the input file we can plot the areas prior to the asba and maybe get an idea of where/why the asba will fail. Then you can correct the geometry work-flow from there.

Mike

moosafly commented 12 months ago

@germa89 Thank you for your reply.

I think this error may not be due to Boolean tolerances. Because no matter how I increase or decrease the Boolean tolerance according to the system's recommendations, I can't solve the problem.

Also, I found a problem on Github that was similar to the one I was experiencing. It seems to be caused by subtracting a large area from a small area to get a null value. But I always keep large areas minus small areas, which should not be a problem. This is the address where I have a similar error:https://github.com/ansys/pymapdl/issues/1994

moosafly commented 12 months ago

@mikerife Thank you for your reply. The code error was caused by me pasting the copy error, here is my code:

from ansys.mapdl.core import launch_mapdl

import numpy as np
from ansys.mapdl import core as pymapdl

new_path = 'C:\\Program Files\\ANSYS Inc\\ANSYS Student\\v232\\ansys\\bin\\winx64\\ansys232.exe'
pymapdl.change_default_ansys_path(new_path)

mapdl = launch_mapdl()

print(mapdl)

mapdl.prep7()
#A 0-1 matrix of size 30×30 is created randomly
matrix = np.random.randint(0,2,(30,30))
print(matrix)
x0 = matrix.shape[0]
y0 = matrix.shape[1]

#Create a rectangle on the plane that is comparable to the size of the matrix
mapdl.blc4(xcorner=0,ycorner=0,width=x0*1,height=y0*1)
mapdl.lplot(color_lines=True,cpos = 'xy')

mapdl.btol(0.10E-4/2)
#Loop for boolean operations, using large rectangles minus small rectangles where 0 exists in the matrix
for x in range(0,matrix.shape[0]):
    for y in range(0,matrix.shape[1]):
        if matrix[x][y] ==0:

            mapdl.asba('all',mapdl.blc4(xcorner=x*1,ycorner=y*1, width=1,height=1),'*')
mapdl.lplot(color_lines=True,cpos = 'xy')
mapdl.btol("defa")

I actually want to map the 0 and 1 numbers in the rectangle to the modeling by looping through the boolean operation. In the code loop, I found that the initial boolean operation was very smooth, but when the loop reached a certain time, the code would stop and an error would be reported.

germa89 commented 11 months ago

@germa89 Thank you for your reply.

I think this error may not be due to Boolean tolerances. Because no matter how I increase or decrease the Boolean tolerance according to the system's recommendations, I can't solve the problem.

Also, I found a problem on Github that was similar to the one I was experiencing. It seems to be caused by subtracting a large area from a small area to get a null value. But I always keep large areas minus small areas, which should not be a problem. This is the address where I have a similar error:#1994

At some point BTOL should help, otherwise you are doing something fundamentally wrong (like subtracting larger areas from smaller ones).

I'm not sure what you want to achieve with the code. Maybe you can explain it?

Also the '*' is not a valid parameter.

moosafly commented 11 months ago

@germa89 Thanks again for the reminder, I'll remove the *. In fact, I want to implement a function that represents the structure with a 0-1 matrix, for example, there is no structure where matrix 0 is, and there is structure where matrix 1 is. The specific idea of my code is to first build a rectangular block of the size of the matrix, and then cycle the Boolean operation to subtract the area corresponding to the rectangular block and matrix 0, and retain the area where 1 exists, so as to realize the function of representing the structure with the matrix. Probably the realization looks like the picture I attached. image image

germa89 commented 11 months ago

Hi @moosafly

From the above plot, it seems that is working.

Furthermore, wouldn't be more efficient generating only the desired volumes?

mapdl.prep7()
#A 0-1 matrix of size 30×30 is created randomly
matrix = np.random.randint(0,2,(30,30))
print(matrix)
x0 = matrix.shape[0]
y0 = matrix.shape[1]

#Loop for boolean operations, using large rectangles minus small rectangles where 0 exists in the matrix
for x in range(0,matrix.shape[0]):
    for y in range(0,matrix.shape[1]):
        if matrix[x][y] != 0:
            mapdl.blc4(xcorner=x*1,ycorner=y*1, width=1,height=1)

mapdl.lplot(color_lines=True,cpos = 'xy')
moosafly commented 11 months ago

Hi @germa89 In fact, I made the results in the diagram in another way: modeling where matrix 1 exists, skipping where 0 exists. This method is actually a direct addition, the place where each 1 exists is added up to the model of the entire matrix, from the previous picture can also be seen that each small square is independent of each other, but this method is required to loop modeling and merge, so it is very resource-intensive, basically 20 times 20 more matrix system operation is very slow. So I want to change to the code method of building a large model at the beginning and then subtracting the unwanted areas in turn, which is equivalent to operating on only one model, so it is more resource-saving, but it is currently impossible to achieve this due to the current problem. Regarding the scale of use, I actually want to model at least a matrix of 50 by 50, so the current matrix superimposed by addition does not meet my requirements in terms of speed and scale.

germa89 commented 11 months ago

What command are you using for merging? You could use nummrg so the keypoints will be merged. It should not be very consuming I believe. @mikerife might be able to give more details.

mikerife commented 11 months ago

@moosafly @germa89 Moosafly, have you reviewed the help section provided prior on MAPDL and Booleans? The type of geometry being created will always fail as there are some areas that touch at one point - the issue of tangency in the help section. So BTOL will not help. And this is not an PyMAPDL Issue. It's expected MAPDL modeling behavior.

You can save time by writing the APDL commands to a file in the nested loop, then uploading and inputing that result file. Rather than sending the APDL command to MAPDL as a Server each time through the loop. But as @germa89 pointed out creating just the necessary areas then merging the keypoints with NUMMRG,KP once is a better option for this type of geometry creation.

Mile

moosafly commented 11 months ago

Hi,@germa89 @mikerife Thanks for the advice, I probably know how to do it. By the way, do you know which staking operation in pymapdl is. Mapdl.vdrag can implement the sweep function of a cross-section along the curve generation, but the orientation of the sweep to the final section cannot be controlled. But I want to implement the generation of volumes from two defined sections and curves between two sections, which I know is available in the ANSYS graphical interface, called lofting, but I can't find it in the Python instructions.

mikerife commented 11 months ago

HI @moosafly @germa89 What is a "staking opertion"? Lofting is not an MAPDL feature, so there would be not PyMAPDL function for it...unless @germa89 created one. Which seems like a lot of work considering PyGeometry just came out and is more suited for that. There are a lot of Ansys graphical interfaces...which one did you have in mind? Design Modeler? SpaceClaim has a lot of features in its sweep. Anyway check out the MAPDL command VEXT which can extrude and scale an area to a volume. It can act like a loft but you may need to do the operation a few times i.e. loop over the set of cross-sections (turned into scale factors) to get the final extrusion. There is a pictorial example of this in the MAPDL help.

germa89 commented 11 months ago

Hi @moosafly

I totally agree with @mikerife. I would also add that some code (or pseudo code) could help to understand your requirements. Anyways, I would open another issue for this, so we can keep a better track of it. I will close this issue, since the initial issue has been fixed/addressed.

@mikerife I don't know what is 'lofting' so I guesss I did not implement anything like that in PyMAPDL. :)