Color 3D Printing ANSYS ANSYS Mechanical and Mechanical APDL Results

[updated on 6/18/14 with images of an optimized bracket]

When we announced that Stratasys had released a color 3D Printer, I promised that I would figure out a way to get an ANSYS Mechanical or Mechanical APDL solution printed in 3D as soon as possible. Here it is:
3D-Color-FEA-Plot
Pretty cool.  I posted this picture on our social media and it got more retweets-shares-comments-likes-social media at’a boys than anything we have ever posted.  So there is definitely some interest in this. Now that the initial “WOW!” factor is gone, it is time to talk technical details and share how to get a plot made.

Stratasys Objet500 Connex3

There have been some machine around for some time that can print colors. Unfortunately they used a process that deposited a binding agent (fancy name for glue) into a bed of powder. The glue could be died different colors, allowing you to mix three base colors to get a color part. The problem with that technology is that the parts were faded and very fragile. On top of that the machines were messy and hard to run.  

With the Objet500 Connex3 from Stratasys, we now have a machine that makes robust and usable prototypes, that can be printed in color. The device uses inkjet print heads to deposit a photopolymer (a resin that hardens when you shine ultraviolet light on it) one layer at a time. This machine has four print heads: one for support, one for a base material, and two for colored material.   The base material can be black, white, or clear.  Then you can mix two colors in to get a 46 color pallet on a given run.  Download the brochure here for more details on the device, or shoot us an email.

As an example of how to use this technology, we took the results from a modal analysis on a simple low-pressure turbine blade (from a jet engine) and plotted out the deflection results for the 1st, 3rd, and 7th mode. The 7th mode also includes the exaggerated deflected shape.

Turbine-Blade-Modal-s

[Added 6/18/14]  

We recently combined ANSYS and Stratasys products for an optimization test case for a customer. We used Toplogoical optimization to remove chunks of material from an aerospace mounting bracket.  Then we 3D plotted the results to share with the international team looking at using this process to design parts that are lighter because they are not constrained by traditional manufacturing requirements. Here is what the first pass on the part looked like:
TopoOptMount_7

Getting a Printable File 

Almost every Additive Manufacturing machine, from 3D Printers to Manufacturing Systems, use an STL file as the way to define a part to be made.  The file contains triangular facets (a mesh) on the surface. The problem is that this file does not have a standard for defining colors.  The way that we get around this is you make an STL file for each color you want, sort of an STL assembly. Then when you load the files into the machine, you assign colors to each STL object.  That is great if you are printing an assembly and each solid object in you Model is a different color, but gets a bit dicey for a results contour.

So, we need a way to get an STL file for each color contour in your plot.  Right now non of the ANSYS products output an STL file.  Needless to say we have been talking with development about this and we hope there will be a built in solution at the next release.  In the interim, we have developed two methods.

Method 0: Have PADT Print your Part

Before we go over the two methods, we should mention that we offer almost every RP technology as a service to customers, including the new Objet500 Connex3. We have written a tool that converts ANSYS MAPDL models into STL’s that represent color bands.  It comes in two parts, a macro that you run to get the data, and a program we have that turns the data into STL files.

  So the easiest way to get a Color 3D Plot of your results is to:

  1. Download the macro ans2vtk.mac and run it. Instructions are in the header.
  2. Upload the resulting *.vtk file to PADT. Find instructions here.
  3. Email rp@padtinc.com and let us know the name of the file, that you want a Color 3D Print, and what units your part is and scale factor, if any, to apply to your part.  
  4. We will generate a quote.  
  5. You give us a PO or a credit card
  6. We pre-process the part and show you the resulting contours, making sure it is what you want
  7. We print it, then ship it to you.

This is a screen shot of the model in our internal tool:

3d-printing-ansys-results-valve-vtk

Method 0.5: Use the PADT Script

If you own a Connex3 and are not a service provider, we would be happy to share the internal script that we use with you.  You would follow the same process as above, but would run the script yourself to make the STL files. You will need to install some opensource tools as well. Email me to discuss.

Method 1: RST to CFD-Post to Magics 

This is how we did the first sample models, because it works out of the box and required no coding.  To use it you need to have a licence of  ANSYS CFD-Post and Magics from Materialise.  CFD Post outputs a color facet file in the VRML2 format, and Magics can convert that into a bunch of STL file.

NOTE: For this to work you need Magics and your contours need to be pretty simple. A complex part won’t work  because Magics won’t be able to figure out the STL volumes. 

We start by attaching a CFD Post object to our model:

project-page

Open up CFD Post and make a plot you like. If you don’t know ANSYS CFD Post, here is an article we did a while back on how to use it to post ANSYS Mechanical and Mechanical APDL results. 

Set the number of contours to a smaller number. You can have up to 46 colors, but that means you have to make 46 separate STL files by hand. I picked 7 contours, which gives me 6 colors:

plot_in_cfdpost

Now simply go to File > Save Picture and select VRML as your format. Note, it will bury the plot way down in your project directories, so I like to change the path to save it at the top level of the directory:

save-wrl

The next step is to read the file in to Magics.

WRL File in Magics_Color Code

In Magics, you can select facets by color and write each one out as a separate STL file.

Once you have done that, go in to the Objet Studio Software that came with your printer and assign colors to each STL file. We just kind of eyeball the closest color to the original plot:

FEA Objet studio

You can see here that we actually printed 3 at a time, just made copies and we only had to define colors on the original.  Then Print.

Here is what it looks like in the printer when it finished. We ran some other parts next to the three valves:
printing

You’ll notice it looks all yellow. That is the support material. It is water soluble and we just wash it off when the part is done. 

Method 2: Macro for Element Based Contours

That method kind of was a pain, so we decided it would be a good idea to write a little macro in APDL that does the following:

  1. Specify number of colors and value to plot.  (It uses the current selected nodes/elements.)
  2. Select elements by contour range
  3. Create surface elements on those elements
  4. Convert those surface elements in to an STL file for each contour.

The advantage of this approach is that ANSYS MAPDL directly creates the STL files and all you have to do is read that into Objet Studio and assign colors.  The disadvantage is that it is plotting element faces, so if a contour changes across a face, it doesn’t capture it. The way it works now is that the face color is represents the contour color for the lowest value on that face.  Not ideal, but I only had about 3 hours to write something from scratch and that is as far as I got.

This is what it looks like in Objet Studio:

macro-1-in-studio

Here is the macro: mkcolstl_mac.zip

Just run in in MAPDL or put it in ANSYS Mechanical as a post processing command snippet.

3D-plots-table

ANSYS & 3D Printing: Converting your ANSYS Mechanical or MAPDL Model into an STL File

image3D printing is all the rage these days.  PADT has been involved in what should be called Additive Manufacturing since our founding twenty years ago.  So people in the ANSYS world often come to us for advice on things 3D Printer’ish.  And last week we got an email asking if we had a way to convert a deformed mesh into a STL file that can be used to print that deformed geometry.  This email caused neurons to fire that had not fired in some time. I remembered writing something but it was a long time ago.

Fortunately I have Google Desktop on my computer so I searched for ans2stl, knowing that I always called my translators ans2nnn of some kind. There it was.  Last updated in 2001, written in maybe 1995. C.  I guess I shouldn’t complain, it could have been FORTRAN. The notes say that the program has been successfully tested on Windows NT. That was a long time ago.

So I dusted it off and present it here as a way to get results from your ANSYS Mechanical or ANSYS Mechanical APDL model as a deformed STL file.

UPDATE – 7/8/2014

Since this article was written, we have done some more work with STL files. This Macro works fine on a tetrahedral mesh, but if you have hex elements, it won’t work – it assumes triangles on the face.  It also requires a macro and some ‘C’ code, which is an extra pain. So we wrote a more generic macro that works with Hex or Tet meshes, and writes the file directly. It can be a bit slow but no annoyingly slow.  We recommend you use this method instead of the ones outlined below.

Here is the macro:  writstl.zip

The Process

An STL file is basically a faceted representation of geometry. Triangles on the surface of your model. So to get an STL file of an FEA model, you simply need to generate triangles on your mesh face, write them out to a file, and convert them to an STL format.  If you want deformed geometry, simply use the UPGEOM command to move your nodes to the deformed position.

The Program

Here is the source code for the windows version of the program:

/*
---------------------------------------------------------------------------

 PADT--------------------------------------------------- Phoenix Analysis &
                                                        Design Technologies

---------------------------------------------------------------------------
                             www.padtinc.com
---------------------------------------------------------------------------

       Package: ans2stl

          File: ans2stl.c
          Args: rootname
        Author: Eric Miller, PADT
		(480) 813-4884 
		eric.miller@padtinc.com

	Simple program that takes the nodes and elements from the
	surface of an ANSYS FE model and converts it to a binary
	STL file.

	USAGE:
		Create and ANSYS surface mesh one of two ways:
			1: amesh the surface with triangles
			2: esurf an existing mesh with triangles
         	Write the triangle surface mesh out with nwrite/ewrite
		Run ans2stl with the rootname of the *.node and *.elem files
		   as the only argument
		This should create a binary STL file

	ASSUMPTIONS:
		The ANSYS elements are 4 noded shells (MESH200 is suggested)
		in triangular format (nodes 3 and 4 the same)

		This code has been succesfully compiled and tested
		on WindowsNT

		NOTE: There is a known issue on UNIX with byte order
				Please contact me if you need a UNIX version

	COMPILE:
		gcc -o ans2stl_win ans2stl_win.c

       10/31/01:       Cleaned up for release to XANSYS and such
       1/13/2014:	Yikes, its been 12+ years. A little update 
       			and publish on The Focus blog
			Checked it to see if it works with Windows 7. 
			It still compiles with GCC just fine.

---------------------------------------------------------------------------
PADT, Inc. provides this software to the general public as a curtesy.
Neither the company or its employees are responsible for the use or
accuracy of this software.  In short, it is free, and you get what
you pay for.
---------------------------------------------------------------------------
*/
/*======================================================

   SAMPLE ANSYS INPUT DECK THAT SHOWS USAGE

finish
/clear
/file,a2stest
/PREP7  
!----------
! Build silly geometry
BLC4,-0.6,0.35,1,-0.75,0.55 
SPH4,-0.8,-0.4,0.45 
CON4,-0.15,-0.55,0.05,0.35,0.55 
VADD,all
!------------------------
! Mesh surface with non-solved (MESH200) triangles
et,1,200,4
MSHAPE,1,2D   ! Use triangles for Areas
MSHKEY,0      ! Free mesh
SMRTSIZE,,,,,5
AMESH,all
!----------------------
! Write out nodes and elements
nwrite,a2stest,node
ewrite,a2stest,elem
!--------------------
! Execute the ans2stl program
/sys,ans2stl_win.exe a2stest

======================================================= */

#include 
#include 
#include 

typedef struct vertStruct *vert;
typedef struct facetStruct *facets;
typedef struct facetListStruct *facetList;

        int     ie[8][999999];
        float   coord[3][999999];
        int	np[999999];

struct vertStruct {
  float	x,y,z;
  float	nx,ny,nz;
  int  ivrt;
  facetList	firstFacet;
};

struct facetListStruct {
  facets	facet;
  facetList	next;
};

struct facetStruct {
  float	xn,yn,zn;
  vert	v1,v2,v3;
};

facets	theFacets;
vert	theVerts;

char	stlInpFile[80];
float	xmin,xmax,ymin,ymax,zmin,zmax;
float   ftrAngle;
int	nf,nv;  

void swapit();
void readBin();
void getnorm();
long readnodes();
long readelems();

/*--------------------------------*/
main(argc,argv)
     int argc;
     char *argv[];
{
  char nfname[255];
  char efname[255];
  char sfname[255];
  char s4[4];
  FILE	*sfile;
  int	nnode,nelem,i,i1,i2,i3;
  float	xn,yn,zn;

  if(argc <= 1){
        puts("Usage:  ans2stl file_root");
        exit(1);
  }
  sprintf(nfname,"%s.node",argv[1]);
  sprintf(efname,"%s.elem",argv[1]);
  sprintf(sfname,"%s.stl",argv[1]);

  nnode = readnodes(nfname);
  nelem = readelems(efname);
  nf = nelem;

  sfile = fopen(sfname,"wb");
  fwrite("PADT STL File, Solid Binary",80,1,sfile);
  swapit(&nelem,s4);    fwrite(s4,4,1,sfile);

  for(i=0;i<nelem;i++){ 
      i1 = np[ie[0][i]];
      i2 = np[ie[1][i]];
      i3 = np[ie[2][i]];
      getnorm(&xn,&yn,&zn,i1,i2,i3);

      swapit(&xn,s4);	fwrite(s4,4,1,sfile);
      swapit(&yn,s4);	fwrite(s4,4,1,sfile);
      swapit(&zn,s4);	fwrite(s4,4,1,sfile);

      swapit(&coord[0][i1],s4);	fwrite(s4,4,1,sfile);
      swapit(&coord[1][i1],s4);	fwrite(s4,4,1,sfile);
      swapit(&coord[2][i1],s4);	fwrite(s4,4,1,sfile);

      swapit(&coord[0][i2],s4);	fwrite(s4,4,1,sfile);
      swapit(&coord[1][i2],s4);	fwrite(s4,4,1,sfile);
      swapit(&coord[2][i2],s4);	fwrite(s4,4,1,sfile);

      swapit(&coord[0][i3],s4);	fwrite(s4,4,1,sfile);
      swapit(&coord[1][i3],s4);	fwrite(s4,4,1,sfile);
      swapit(&coord[2][i3],s4);	fwrite(s4,4,1,sfile);
      fwrite(s4,2,1,sfile);
  }
  fclose(sfile);
    puts(" ");
  printf("  STL Data Written to %s.stl \n",argv[1]);
    puts("  Done!!!!!!!!!");
  exit(0);
}

void  getnorm(xn,yn,zn,i1,i2,i3)
	float	*xn,*yn,*zn;
	int	i1,i2,i3;
{
	float	v1[3],v2[3];
	int	i;

        for(i=0;i<3;i++){
	  v1[i] = coord[i][i3] - coord[i][i2];
	  v2[i] = coord[i][i1] - coord[i][i2];
	}

	*xn = (v1[1]*v2[2]) - (v1[2]*v2[1]);
	*yn = (v1[2]*v2[0]) - (v1[0]*v2[2]);
	*zn = (v1[0]*v2[1]) - (v1[1]*v2[0]);
}
long readelems(fname)
        char    *fname;
{
        long num,i;
        FILE *nfile;
        char    string[256],s1[7];

        num = 0;
        nfile = fopen(fname,"r");
		if(!nfile){
			puts(" error on element file open, bye!");
			exit(1);
		}
        while(fgets(string,86,nfile)){
          for(i=0;i<8;i++){
            strncpy(s1,&string[6*i],6);
            s1[6] = '\0';
            sscanf(s1,"%d",&ie[i][num]);
          }
          num++;
        }

        printf("Number of element read: %d\n",num);
        return(num);
}

long readnodes(fname)
        char	*fname;
{
        FILE    *nfile;
        long     num,typeflag,nval,ifoo;
        char    string[256];

        num = 0;
        nfile = fopen(fname,"r");
		if(!nfile){
			puts(" error on node file open, bye!");
			exit(1);

		}
        while(fgets(string,100,nfile)){
          sscanf(string,"%d ",&nval);
          switch(nval){
            case(-888):
                typeflag = 1;
            break;
            case(-999):
                typeflag = 0;
            break;
            default:
                np[nval] = num;
                if(typeflag){
                        sscanf(string,"%d %g %g %g",
                           &ifoo,&coord[0][num],&coord[1][num],&coord[2][num]);
                }else{
                        sscanf(string,"%d %g %g %g",
                           &ifoo,&coord[0][num],&coord[1][num],&coord[2][num]);
                        fgets(string,81,nfile);
                }
num++;
            break;
        }

        }
        printf("Number of nodes read %d\n",num);
        return(num);

}

/* A Little ditty to swap the byte order, STL files are for DOS */
void swapit(s1,s2)
     char s1[4],s2[4];
{
  s2[0] = s1[0];
  s2[1] = s1[1];
  s2[2] = s1[2];
  s2[3] = s1[3];
}

ans2stl_win_2014_01_28.zip

Creating the Nodes and Elements

I’ve created a little example macro that can be used to make an STL of deformed geometry.  If you do not want the deformed geometry, simply remove or comment out the UPGEOM command.  This macro is good for MAPDL or ANSYS Mechanical, just comment out the last line  to use it with MAPDL:

et,999,200,4

type,999

esurf,all

finish ! exit whatever preprocessor your in

! move the RST file to a temp file for the UPCOORD. Comment out if you want

! the original geometry

/copy,file,rst,,stl_temp,rst

/prep7 ! Go in to PREP7

et,999,200,4 ! Create a dummy triangle element type, non-solved (200)

type,999 ! Make it the active type

esurf,all ! Surface mesh your model

!

! Update the geometry to the deformed shape

! The first argument is the scale factor, adjust to the appropriate level

! Comment this line out if you don’t want deformed geometry

upgeom,1000,,,stl_temp,rst

!

esel,type,999 ! Select those new elements

nelem ! Select the nodes associated with them

nwrite,stl_temp,node ! write the node file

ewrite,stl_temp,elem ! Write the element file

! Run the program to convert

! This assumes your executable in in c:\temp. If not, change to the proper

! location

/sys,c:\temp\ans2stl_win.exe stl_temp

! If this is a ANSYS Mechanical code snippet, then copy the resulting STL file up to

! the root directory for the project

! For MAPDL, Comment this line out.

/copy,stl_temp,stl,,stl_temp,stl,..\..

An Example

To prove this out using modern computing technology (remember, last time I used this was in 2001) I brought up my trusty valve body model and slammed 5000 lbs on one end, holding it on the top flange.  I then inserted the Commands object into the post processing branch:

image

When the model is solved, that command object will get executed after ANSYS is done doing all of its post processing, creating an STL of the deformed geometry. Here is what it looks like in the output file. You can see what it looks like when APDL executes the various commands:

/COPY FILE FROM FILE= file.rst

TO FILE= stl_temp.rst

FILE file.rst COPIED TO stl_temp.rst

1

***** ANSYS – ENGINEERING ANALYSIS SYSTEM RELEASE 15.0 *****

ANSYS Multiphysics

65420042 VERSION=WINDOWS x64 08:39:44 JAN 14, 2014 CP= 22.074

valve_stl–Static Structural (A5)

Note – This ANSYS version was linked by Licensee

***** ANSYS ANALYSIS DEFINITION (PREP7) *****

ELEMENT TYPE 999 IS MESH200 3-NODE TRIA MESHING FACET

KEYOPT( 1- 6)= 4 0 0 0 0 0

KEYOPT( 7-12)= 0 0 0 0 0 0

KEYOPT(13-18)= 0 0 0 0 0 0

CURRENT NODAL DOF SET IS UX UY UZ

THREE-DIMENSIONAL MODEL

ELEMENT TYPE SET TO 999

GENERATE ELEMENTS ON SURFACE DEFINED BY SELECTED NODES

TYPE= 999 REAL= 1 MATERIAL= 1 ESYS= 0

NUMBER OF ELEMENTS GENERATED= 13648

USING FILE stl_temp.rst

THE SCALE FACTOR HAS BEEN SET TO 1000.0

USING FILE stl_temp.rst

ESEL FOR LABEL= TYPE FROM 999 TO 999 BY 1

13648 ELEMENTS (OF 43707 DEFINED) SELECTED BY ESEL COMMAND.

SELECT ALL NODES HAVING ANY ELEMENT IN ELEMENT SET.

6814 NODES (OF 53895 DEFINED) SELECTED FROM

13648 SELECTED ELEMENTS BY NELE COMMAND.

WRITE ALL SELECTED NODES TO THE NODES FILE.

START WRITING AT THE BEGINNING OF FILE stl_temp.node

6814 NODES WERE WRITTEN TO FILE= stl_temp.node

WRITE ALL SELECTED ELEMENTS TO THE ELEMENT FILE.

START WRITTING AT THE BEGINNING OF FILE stl_temp.elem

Using Format = 14(I6)

13648 ELEMENTS WERE WRITTEN TO FILE= stl_temp.elem

SYSTEM=

c:\temp\ans2stl_win.exe stl_temp

Number of nodes read 6814

Number of element read: 13648

STL Data Written to stl_temp.stl

Done!!!!!!!!!

/COPY FILE FROM FILE= stl_temp.stl

TO FILE= ..\..\stl_temp.stl

FILE stl_temp.stl COPIED TO ..\..\stl_temp.stl

image

The resulting STL file looks great:

image

I use MeshLab to view my STL files because… well it is free.  Do note that the mesh looks coarser.  This is because the ANSYS mesh uses TETS with midside nodes.  When those faces get converted to triangles those midside nodes are removed, so you do get a coarser looking model.

And after getting bumped from the queue a couple of times by “paying” jobs, our RP group printed up a nice FDM version for me on one of our Stratasys uPrint Plus machines:

image

It’s kind of hard to see, so I went out to the parking lot and recorded a short video of the part, twisting it around a bit:

Here is the ANSYS Mechanical project archive if you want to play with it yourself.

Other Things to Consider

Using FE Modeler

You can use FE Modeler in a couple of different ways with STL files. First off, you can read an STL file made using the method above. If you don’t have an STL preview tool, it is an easy way to check your distorted mesh.  Just chose STL as the input file format:

image

You get this:

image

If you look back up at the open dialog you will notice that it reads a bunch of mesh formats. So one thing you could do instead of using my little program, is use FE Modeler to make your STL.  Instead of executing the program with a /SYS command, simply use a CDWRITE,DB command and then read the resulting *.CDB file into FE Modeler.  To write out the STL, just set the “Target System” to STL and then click “Write Solver File”

image

You may know, or may have noticed in the image above, that FE Modeler can read other FEA meshes.  So if you are using some other FEA package, which you should not, then you can make an STL file in FE Modeler as well.

Color Contours

The next obvious question is how do I get my color contours on the plot. Right now we don’t have that type of printer here at PADT, but I believe that the dominant 3D Color printer out, the former Z-Corp and now 3D Systems machines, will read ANSYS results files. Stratasys JUST announced a new color 3D Printer that makes usable parts. Right now they don’t have a way to do contours, but as soon as they do we will publish something.

Another option is to use a /SHOW,vrml option and then convert that to STL with the color information.

Scaling

Scaling is something you should think about. Not only the scaling on your deformed geometry, but the scaling on your model for printing.  Units can be tricky with STL files so make sure you check your model size before you print.

Smoother STL Surfaces

Your FEA mesh may be kind of coarse and the resulting STL file is even coarser because of the whole midside node thing.  Most of the smoothing tools out there will also get rid of sharp edges, so you don’t want those. Your best best is to refine your mesh or using a tool like Geomagic.

Making a CAD Model from my Deformed Mesh

Perhaps you stumbled on this posting not wanting to print your model. Maybe you want a CAD model of your deformed geometry.  You would use the same process, and then use Geomagic Studio.  It actually works very well and give you a usable CAD model when you are done.

STL File Tolerance: A Short Explanation of Faceting and Chord Height

When you are making a prototype of a CAD file, you send an STL file to the software that the machine uses to calculate how to build the part.  An STL file is made up of triangles, called facets, that cover the surface of your part.  Imagine having a a real part and a box full of small triangle. You have to paste the triangles all over the surfaces of the part till you have covered every part of the surfaces.

To illustrate what we are talking about lets start with a simple geometry: a block with a hole:

image

When we make an STL file the CAD package breaks the surfaces of the part up into triangles.  The result is something like this:

facet_02

Notice how the surface is made up of triangles.  Triangles are flat so if you don’t have enough, if the triangles are too large, you end up with visibly flat surfaces.  This example shows the default for many CAD tools, and if we make a prototype of it we will see the flat triangle bits, and it will look bad.

To solve this you need to set your tolerance to a smaller number. Each CAD package has a different way of specifying this.  Most of them use some sort of Chord Height tolerance. 

image

image

The chord height is the maximum distance from the actual surface (orange) to the facet face (green).  The smaller the Chord Height, the smaller the facets and the more accurate the curvature of the surface is represented.

Here are some examples of our sample part with different tolerances (the hole has a 2” diameter):

facet_01

0.1” Chord Height

facet_02

0.01” Chord Height

facet_03

0.001” Chord Height

facet_00

0.0001” Chord Height

That last example may be a bit extreme. 

Why not just set your tolerance very small and be done with it?  The problem with that approach is that you force the program to make a ton of triangles, and your STL file gets huge.  So you need to find a nice compromise.  0.001” seems to work well for us and is a good place to start.

if you want to view your STL files, you can usually do so in the software you use to send your parts to your RP machine. If you are using a service provider, you may want to download a tool like Meshlab or MiniMagics.