One of the most common questions on XANSYS, and a common tech support question for us is: “Is there any way to make my result file smaller?”  In fact, we just got a support call last week on that very topic.  So we thought it would be a good topic for The Focus, and besides the standard quick answer, we can go a bit deeper and explain why.

# Why so Big?

The first thing you need to understand is why the result file is so big. One of the fundamental strengths of the ANSYS solver, back to the days when John Swanson and his team were writing the early versions, is that the wealth of information available from an FEA solution is not hidden from the user.  They took that approach that whatever can be calculated will be calculated so the user can get to it without having to solve again.  Most other tools out there do the most common calculations, average them, and then store that in the results file.

If you go back to your FEA fundamentals and take a look at our sample 2D mesh, you will quickly get an Idea of what is going on.

When an FEA mesh is solved, the program calculates the Degree of Freedom results (DOF) at each integration point in each element. For most meshes that is at the corner of each element.  This DOF solution is then used to calculate the derived values, usually stress and strain, for each node based upon the solution at the integration points for each element. Then, during post processing, the user decides how they want to average those element

So the stress in the X direction for Node 2 in our example is different for element 1 and element 2.  Element 1 uses the results it calculated with the elements shape function to get stresses and strains for node 2, and element 2 does the same thing.

Now most programs, they average these value at solve time and either store an element average, or a nodal average.  But ANSYS does not.  It stores the values for each node on each element in its results file.

By default, node 5 in our example will be stored four times in the ANSYS RST file, and each instance will contain 12 result items for a linear run (SX, SY, SXY, S1, S2, S3, SINT, SEQV, EPELX, EPELY, EPELXY, EPELEQV) and even more for 3D, non-linear, and special capability elements.

 And Now if you want, let’s digress into the nitty gritty: You can actually see what is in the RST file because ANSYS Mechanical APDL has awesome documentation.  Modern programs don’t even come close to level of detail you can find in the ANSYS MAPDL help.  Go to the Mechanical APDL in the help and them the path: // Programmer’s Manual // I. Guide to Interfacing with ANSYS // 1. Format of Binary Data Files // 1.2. Description of the Results File.  Look at the file format in section 1.2.3.  Lots of headers and such, but if you take the time to study it you will be able to see how much space each type of thing stored in the result file uses. First is stores model information.  Everything that describes the model but the geometry and loads.  If you scroll down to the “Solution data header” (use find to jump there) you have the actual results. This is the big part. Scroll down past the constants to the NSL, or the node solution list:  C * NSL    dp       1  nnod*Sumdof  The DOF Solution for each node in the nodal coordinate system. This says that the size of this record is the number of nodes (nnod) times the number of Degrees of Freedom (Sumdof).  So for a structural solid model with 10,000 nodes and only UX, UY, and UZ DOF’s, it would be 30,000 double precision numbers long. After the DOF solutions we have velocity, acceleration, reaction forces, masters, and then boundary conditions and some loads. Even some crack tip info. Then comes the big part.  The Element solution information.  Take a look at it. You have miscellaneous data, element forces.  ETABLE type data, etc… Then there is the ENS record, the Element Nodal Component Stresses.  The size is marked as “varies” because there are so many variables that define how big this record is. Read the comments. It is long but goes into explaining the huge amount of information stored here.  Study this and you will know more than you ever wanted to about what is in the RST file!.

Storing all of this information is the safest option. Everything a user might need during post processing is stored so that they do not have to rerun if they realize they need some other bit of information. But, as is usual with MAPDL, the user is given the option to change away from those defaults, and only store what they want. OUTRES really is your friend.

# You Are in Control: OUTRES

OUTRES is a unique command.  It is cumulative.  Every time you issue a command it adds or removes what you specify from what is stored in the RST file.  The basics of the command are shown in the table below, and more info can be found in the online help.  Use OUTRES, STAT to see what the current state is at any point.  Always start with OUTRES,  ERASE to make sure you have erased any previous settings, including the defaults.

Remember that this command affects the current load step. The settings get written to the load step file when you do an LSWRITE.  So if you have multiple load steps and you want the same for each, set it on the first one and it will stay there for all the others.  But if you want to change it for a given load step, you can.

If you are a GUI person you can access this from four different branches in the menus:

The first thing to play with on the command is the first argument: Item.

The default is to write everything.  What we recommend is that for most runs, using OUTRES, BASIC is good enough.  It tells the program to store displacements, reaction forces, nodal loads, and element stresses. The big thing it skips are the strains. Unless you are looking at strains, why store them.  Same with the MISC values. Most users don’t ever access these.

The next thing you can use to reduce file size is to not store the results on every element.  Use the Cname argument to specify a component you want results for.  Maybe you have a huge model but you really care about the stress over time at a few key locations.  So use a node and element components to specify what results you want for which components.  Note, you can’t use ALL, BASIC or RSOL for this option.  You need to specify a specific type of result for each component.  Remember, the command is cumulative so use a series of OUTRES commands to control this.

OUTRES, Item, Freq, Cname

ITEM
Results item for database and file write control:
ALL — All solution items except SVAR and LOCI. This value is the default.
CINT — J-integral results.
ERASE — Resets OUTRES specifications to their default values.
STAT — Lists the current OUTRES specifications.
BASIC — Write only NSOL, RSOL, NLOAD, STRS, FGRAD, and FFLUX records to the results file and database.
NSOL — Nodal DOF solution.
V — Nodal velocity (applicable to structural full transient analysis only(ANTYPE,TRANS)).
A — Nodal acceleration (applicable to structural full transient analysis only(ANTYPE,TRANS)).
ESOL— Element solution (includes all items following):
NLOAD — Element nodal, input constraint, and force
loads (also used with the /POST1 commands
PRRFOR, NFORCE, and FSUM to calculate
STRS — Element nodal stresses.
EPEL — Element elastic strains.
EPTH — Element thermal, initial, and swelling strains.
EPPL — Element plastic strains.

EPCR — Element creep strains.
EPDI — Element diffusion strains.
FFLUX — Element nodal fluxes.
LOCI — Integration point locations.
SVAR — State variables (used only by USERMAT).
MISC — Element miscellaneous data
(SMISC and NMISC items of the ETABLE command).

Freq
Specifies how often (that is, at which substeps) to write the specified solution results item. The following values are valid:

Cname
The name of the component, created with the CM command, defining the selected set of elements or nodes for which this specification is active. If blank, the set is all entities. A component name is not allowed with the ALL, BASIC, or RSOL items.

# Use What Works for You

The help on the OUTRES command has a nice example where the user specifies different solutions for different sub steps. Check it out to get your head around what is happening:  // Command Reference // XVI. O Commands // OUTRES

Next time you run a small but typical model for you, play with the options.  Most of the time when I have a lot of load steps or a large model, I use the following in my input deck:

OUTRES,ERASE
OUTRES,BASIC

Sometimes I only care about surface stresses so they use (of course last can be replaced with all or any other frequency):

NSEL,s,ext
ESLN,S,0
CM,nxtrnl,node
CM,extrnl,elem
OUTRES,erase
OUTRES,nsol,last,nxtrnl
OUTRES,strs,last,extrnl
OUTRES,stat

Use OUTRES on the next couple of runs you do. Try BASIC, try some other things and see if you can save some disk space.

## Bringing the Value of Simulation into Perspective

Those of us who do simulation for a living spend a lot of time focusing on faster, cheaper, better.  But we rarely deal with the hard, and cold reality that better often means safer.  Please take some time to read the blog entry below from an ANSYS employee who survived and insane crash, because a bunch of nerds at Nissan ran simulations over and over again on his car so that it would protect him.  Warning… may make you mist up a bit.

http://blog.ansys.com/2012/01/26/nissan-understand-behind-realize-your-product-promise/

## Christmas Right–Left Gift Exchange Story: Film Noir Style

For our Christmas parties at PADT we generally have over 40 employees so a traditional secret Santa gift exchange takes to long. So a couple of years ago we downloaded a right-left gift exchange story from the internet and it was a big hit. We ran out of stories on the internet, so we started writing our own, usually in some sort of over-the-top style.  This year it was sort of a Film Noir style with a hard-boiled detective, a blond bombshell, and a can of Right Guard.  There is a Christmas connection, but you have to read it to get it.

If you have never played this game before it is simple. Everyone gets their gift and forms a big circle in the middle of the room.  Someone with a strong voice reads the story and every the word LEFT is read, everyone passes the package they have to the left. Every time the world RIGHT is read, everyone passes the package they have to their right.  You should pause a bit at each LEFT/RIGHT to give people a chance to pass.  Using funny voices for the dialog also helps.

– Elf Family Christmas (2017)
– Western Christmas (2016)
– Star Wars Christmas (2015)
– Fairy Tail Christmas (2014)
– Science Fiction Christmas (2013)
– Romance Christmas (2012)
– Film Noir Christmas (2011)

We hope you get as many laughs out of it as we did.

Jack Hammer sat in his office on the 5th floor of the WRIGHT insurance company building. His RIGHT hand held a cold cup of coffee, and in his LEFT was a RIGHT guard deodorant can. He wore a hat cocked slightly to the LEFT and parted his hair on the RIGHT. Two streams of cheesy Christmas music were coming through his walls, from Doctor LEFTentowskeys office on his RIGHT, and the accountant’s office on his LEFT. He didn’t know the name of the accountant, but he had LEFT Jack a Christmas Card with a picture of reindeer on the LEFT bank of the Siene in Paris, which Jack felt was just not… appropriate.

Christmas had been a lonely time for Jack ever since his wife Janice had LEFT him RIGHT before Christmas five years ago, waking up one morning and saying “We are not RIGHT for each other” She packed and walked RIGHT out the door.

As he was remembering this he heard footsteps coming down the hallway from the LEFT, and they stopped RIGHT in front of his door. After a few seconds he heard a rhythmic rapping on his door, three knocks one RIGHT after another, a pause, then three more RIGHT after that. It LEFT him a bit puzzled, but RIGHT now he needed the work and the distraction from his depressing thoughts.

He said, “Come RIGHT In”. The door opened to reveal a stunning blond bombshell. The kind that comes RIGHT out of a pinup calendar. The kind that had come into his office several times in the past and LEFT him heartbroken.

Her ruby red lips parted and she asked, with a slight accent that sounded almost Italian: “You Jack Hammer? My name is Cemento Smerigliatrice. My friend Joey RITEnhaour said you were the RIGHT man for the job?”

Her voice LEFT him a bit speechless, so he used the act of clearing off the RIGHT side of his desk to find a place to put the RIGHT guard down as an excuse to gain his composure. “I may be the RIGHT guy for the job, but it needs to be the RIGHT job.”

She walked over to his desk and around the RIGHT side to sit RIGHT there in front of him on the RIGHT corner. She said, leaving no chance LEFT for misinterpretation: “I need you to kill Santa Clause”

The statement hung there in the air, Jack was LEFT speechless.

She pouted those red lips and leaned forward, putting her ample bosom RIGHT in front of his eyes and said: “Last year, that red-coated jerk LEFT me coal. I came downstairs and found that he had eaten the cookies and drunk the milk I LEFT him. But hanging there RIGHT over the fireplace was my stocking full of coal. It just is not RIGHT!”

Jack Hammer was used to trouble, and the part of him that didn’t get LEFT on the battlefields of the Pacific during WWII enjoyed the RIGHT kind of danger. But her whole attitude LEFT him a little nervous. She had LEFT something out that just didn’t seem RIGHT.

He looked her up and down and stared RIGHT into her eyes, and noticed a small tear streaking down her LEFT cheek. He put his RIGHT and LEFT hand down on the LEFT and RIGHT arms of his chair and slowly pushed himself up until he stood RIGHT next to her. “RIGHT now gorgeous, I don’t care what is RIGHT and what is… not-RIGHT. Life has LEFT a hole RIGHT here in my heart” he lifted her RIGHT hand in his and placed it on the LEFT side of his chest. “It has LEFT me bitter, LEFT me without any hope. LEFT me without a lot of morals.”

She looked up and smiled an evil smile at him. The kind of smile that LEFT you wondering if you took a wrong turn in a bad part of town… or maybe a RIGHT turn.

He let go of her hand to reach out and pulled her body RIGHT up against his and whispered in her LEFT ear.

“Looking at you I’m guessing that if Santa LEFT you coal, you deserved it. He has every RIGHT to leave you coal, because if you check his list you would be in that naughty column on the LEFT side of the sheet. “

He then spun her around and pushed her RIGHT out the door. “The elevator is on your LEFT sweaty, you can ride it RIGHT down to hell!”

Jack Hammer sat RIGHT back down in his chair and picked up the RIGHT guard that was sitting RIGHT on his desk. Somehow, the exchange LEFT him feeling good for the first time in a long time.

Meanwhile, far up RIGHT on top of the world, a large man in a red suit set a cup of hot cocoa on the LEFT side of his desk. He crossed out the name of Jack Hammer on the LEFT side of a long list, and wrote it in on the RIGHT side, under the heading of Nice. In a deep rumbly voice, he said: “Ho Ho Ho. Every year I am LEFT with no doubt, that RIGHT around the world when people are LEFT with a simple choice, they always do what is… appropriate.

## 2011 Is Winding Down–Thank You for a Great Year!

No great revealing article this week on how to use an obscure ANSYS Mechanical APDL element to model the behavior of fluid flow in plant stems.  No hints on getting images from Workbench that will appease a project engineer so that he will give you one more week to get the dang model to converge.  No description of some great new capability that you can’t live without.

This week we just want to take a few minutes of your time to thank each and every one of you who reads PADT’s The Focus for a fantastic year in 2011, to wish those of you with a winter-solstice-positioned-holiday a very happy whatever-that-holiday-is, and to pass along our hopes that 2012 will be a better year than 2011.

Those of us who are involved in sales, support and services built around ANSYS, Inc’s products have had a great year.  Release 13 has been a very important release that has allowed many of our customers to do their jobs faster and with greater accuracy.  We hope that Santa will reward the busy little ANSYS developers around the world, they deserve it.

During the year PADT has seen good growth both in new customers who purchase their ANSYS, Inc. tools through us as well as companies that have come to PADT asking us to do simulation or training for them  We have made some new friends along the way and have enjoyed working with those of you who we have known for a while.

There are 2,334 people who have actually signed up to receive e-mails about The Focus, and a quick look at our Google Analytics data shows that over 83,856 unique page views to www.padtinc.com/blog.

If we dig a bit deeper into that data we find some interesting things:

• The most visited article was the Pretty Plotting article.   Making nice plots does matter!
• Second was an older article: 10 Things Every Mechanical APLD User Should Know!  That make us old MAPDL users very happy to see.
• Third was the article on Mapped Face Meshing.  That one kind of stumped us because it is kind of an obscure power user thing… so I guess that says you are mostly power users, which is cool.
• If we look at what pages people linger at… we find that the longest view was when someone searched on “Self Penetration” and they looked at that result page for 29 minutes. There are a lot of ways we can go with that one… I’ll just let you guys take it as you want to.
• 47% of the page views came from Europe, 38% North America, and 11% from Asia.  This international reach is something that we are very proud of.

# Looking Forward

2012 is shaping up to be a great year.  R14 is out and we are using it, and liking it.  We also expect 14.5 to come out in 2012 so we will have even more new features to use and blog about.  Also, look for PADT to announce a new simulation product that we are going to start selling in 2012 that compliments the ANSYS, Inc. product line and opens up new markets for our sales, services and training .

The biggest change you should notice in 2012 is a new PADT website.  I know, you all love the ramshackle hodge-podge of pages we have now. (Side note: in a meeting with a potential new customer the current www.PADTINC.com home page was described as being like that one house in the neighborhood where the owner does not trim the weeds, there is an old car out front, a few refrigerators, and a front porch that is falling down.)  This new site should be easier to navigate and much easier on the eyes, but full of the same rich content you have come to know and love.  We will be moving The Focus to a WordPress blog engine (giving up on windows based stuff) and expanding the blog to cover a lot more of what PADT does.  (don’t worry, you can just subscribe to The Focus and avoid articles about Doug Oatis’s latest climbing adventure).

So to all of you out there:

Best Holiday Wishes and a Very Happy New Year

## Found on the Web: Nice Video on converting MAPDL Material Properties to Engineering Data Properties

While in San Diego this week to teach a training class, PADT’s Jason Krantz did what most PADT engineers do when they have an evening in a new, exciting city – he spent the night searching the internet for useful ANSYS knowledge.  OK, maybe not.  But he did stumble on something worth sharing.

Sheldon Imaoka published a very useful ScreenCast on how to use Workbench systems to get ANSYS Mechanical APDL material properties into engineering data without having to write a translator from APDL to XML or typing the values into the Engineering Data interface.  Take a look:

We also highly recomend you visit Sheldon’t web site, ansys.net, for tons more useful info.  You can also find articles published by Sheldon in the official ANSYS blog.

## Manipulating Text Strings in ANSYS Mechanical APDL

The world is all gates, all opportunities, strings of tension waiting to be struck. – Ralph Waldo Emerson

The ANSYS Parametric Design Language has a lot of features in it.  Over the years it has grown to meet the needs of a growing population of users and has gone from a simple command scrip to a fairly sophisticated programming tool.  One area of the tool that power users find significant value is are the functions that are used to manipulate text strings.  You can use these functions to do all sorts of things that are needed to automate a process or produce more informative results.  Some examples are:

• Gather information about your model and create a screen for display on a plot or in a report
• Get information about files and directories and use that to manage, create, delete, etc…, those files.
• Build commands up so APDL can write APDL or input to other programs
• Create or modify parameter names for use in your macros

In this article we will look at strings in APDL and how to work with them.  You can find additional, more detailed information in the ANSYS Help, Mechanical APDL>ANSYS Parametric Deign Language Guide.  There is also more information on this topic and all things APDL in PADT’s Guide to the ANSYS Parametric Design Language (APDL).

# Strings in ANSYS Mechanical APDL

Pull the string, and it will follow wherever you wish. Push it, and it will go nowhere at all. – Dwight D Eisenhower

Before we talk about manipulating strings, we should do some background on strings.

Strings can either be stored as a character parameter or as a string array. Character parameters are nice because they don’t require indices when you use them, and you don’t have to define them with a *dim. The down side is that you are limited to 8 characters.

You create a string parameter by using the parameter = method:

myChr = ‘yeehah’

To be more robust and avoid size issues, you should use a string array, which you create with a *dim command:

*DIM,myString,STRING,80

This would create a text string called myString that is 80 characters long.  And you would do this if you are going to use a function to fill it.  Once you create a string you refer to it with its name and an index for the start of the string.

/title, Working on Model %myString(1)%

For a character parameter, you don’t need the index:

/title,Working on Model %myChr%

Stuff you should know about strings in APDL:

• You define the value of a string by putting the text in single quotes ‘string’
• The longest string you can have is 256 character – but don’t worry, you can string strings together.
• String arrays can be two dimensional, so if you have a bunch of text you want to keep together you can do that fairly easily.  You do have to use *dim if you do this:
• *dim,comp,string,80,  3       [Fixed on 11/19/14 ]
comp(1,1) = ‘leftSide’
comp(1,2)=’rightside’
comp(1,3)=’topside’
*do,I,1,3
cmsel,a,%comp(1,i)%
*enddo
• You can make an array of type Char as well. This is basically a list of several character parameters.
• To look at what is in your array/parameter, use *stat.

# String Functions

Money is the string with which a sardonic destiny directs the motions of its puppets. – W. Sumerset Maugham

Now on to the fun stuff!

Once you have a string you can manipulate it using the string functions.  We will look at each group.

## Strings to and from Numbers

Sometimes you have a number as a string and you need it as a number, or you need to convert a number into a string.  Those numbers can be decimal or Octal or Hex.  This Table shows the functions for going back and forth.

 Function Description VALCHR(string) Converts a string that contains a valid  decimal or integer number as text into a double precision parameter VALOCT(string) Converts a string that contains a valid  Octal number as text into a double precision parameter VALHEX(string) Converts a string that contains a valid  Hexadecimal number as text into a double precision parameter CHRVAL(num) Converts a decimal number into a text string CHROCT(num) Converts a number into a text string octal number CHRHEX(num) Converts a number into a text string hexahedral number

The most commonly used function in this group is CHARVAL() to truncate the number of decimals in a number.

## Standard String Functions

If you have every programed in FORTRAN, C or any other “old school” language you are familiar with the standard set of commands that are used to manipulate strings. APDL supports most of them:

 Function Description STRSUB(Str1,nLoc,nChar) Returns a substring of the characters in Str1.  Returns characters number nLoc to nLoc+nChar as a string. STRCAT(Str1,Str2) Concatenates Str2 onto the end of Str1. Returns a string. STRFILL(Str1,Str2,nLoc) Fill in Str1 with Str2 starting at character number nLoc in Str1. Returns a string. STRCOMP(Str1) Compress Str1 by removing all the spaces in Str1. Returns a string. STRLEFT(Str1) Left justify Str1 by removing all leading spaces from Str1. Returns a string. STRPOS(Str1,Str2) Returns the position in Str1 where Str2 can be found.  If it is not found, it returns 0.  Returns a number. STRLENG(Str1) Returns the length of Str1, excluding training spaces. Returns a number. UPCASE(Str1) Converts all the characters in Str1 to Upper Case. Returns a string. LWCASE(Str1) Converts all the characters in Str1 to Lower Case. Returns a string.

These are fairly standard and work as you would expect.

## File Name Functions

The last two functions are there for you to work with file names and directories.  There are three parts to a path name in ANSYS MAPDL:  the directory where the file is (directory), the portion of the filename before the period (filename) and the part after the period (ext).  The first function allow you to build a complete string that specifies a file and the second takes a complete path and divides it into its pieces.

 Function Description JOIN(directory,filename,extension) Creates a path string in the current OS (forward vs. backward slashes) from the supplied directory, filename, and extension.  Directory is optional. Split(Path,Option) Takes a full pathname in the current OS and splits it up into pieces. Option can be:    DIR = give just the directory    FILE = Give the filename and extension    Name = just the filename, the part before the period    EXT = give the extension, the part after the period.

# Using Strings in APDL

There is geometry in the humming of the strings, there is music in the spacing of the spheres. – Pythagoras

The examples above sort of hint at how to use strings in APDL but it is probably a good idea to explicitly talk about it.  You can use strings in commands in clever ways, some commands use strings as arguments, and you can write strings to files.

## String Substitution in a Command

This is the most common usage and the most powerfully.  Any CHAR or STRING parameter can be put into any APDL command by simply putting it inside percent signs:  %myString%

So you can do something like:

/title, Results for Substep %isbstp%.  Freq = %frq%

Some people get very sophisticated with this and build their own commands this way.  Do note that this substitution also works for numbers.  cmsel,s,ncmp%i%  where i = 32 will look to the program like cmsel,s,ncmp32.

## Strings as Arguments

This is fairly straightforward, if a command is looking for a string, give it a string.  There are not too many commands that take strings as arguments but there are a few.

## Writing Strings to Files

There are three basic ways to write to a file in APDL:  *create, *cwrite, and *vwrite.  We are not going to get into there use here, but check out the usage of each in detail in the help.

# Conclusions

There are strings in the human heart that had better not be vibrated. – Charles Dickens

This has been a very brief overview of a powerful tool in ANSYS Mechanical APDL. Take a look at the help and other resources (xansys.org, ansys.net) to learn more and just start using it.  Fun stuff.

## Post Processing FEA Results in ANSYS CFD Post

The other day there was a thread on XANSYS about the best way to create animations in ANSYS Mechanical APDL (MAPDL).  If you are an MAPDL user you know that the animation tools found there were actually way ahead of their time… in 2001.  Now they are a bit limited and the AVI file it creates uses a codec that are a bit old.  You can write a macro that creates PNG files that you can then string together into an AVI, WMV, MOOV or animated gif file.  Check out the thread (go to XANSYS and search on animation) and you can see some of the options suggested.

As I was reading the thread I remembered that one of the CFD guys from ANSYS, Inc. once asked if we used CFX Post to post process our FEA results.  I of course pretended that I knew all about it and “just didn’t have time to play with it yet.”  The next time I had time at my desk I looked it up and there it was, under File->Load Results you can set the “Files of Type” drop down to read a whole slew of ANSYS Mechanical and MAPDL files:

I then promptly forgot about it till I was reading the thread.  So, I figure the best way to remember is to store it for posterity bouncing through the tubes of the interweb  as a blog posting.

# ANSYS CFD Post

CFX Post has been generalized and renamed as CFD Post. As a long time ANSYS MAPDL bigot I have to say, and this is a very difficult admission, CFD Post is a a very nice post processor.  Maybe I think like a Torontonian or something, but no matter how long it has been since I’ve used it, I can jump right in and figure out what needs to be done.

It is a CFD post processor and you can use it to post CFX, FLUENT, FIDAP, TASKFLOW and the general CGNS files that most CFD tools create.  So the terminology is definitely oriented towards CFD users.  But because CFX supports moving meshes and conjugate heat transfer, it has most things that you need to read and post process an FEA result.  It is also scriptable and can be run in batch for process automation.

To access it you will need to have a license for one of ANSYS, Inc’s CFD tools. (this may be the justification for you to upgrade to a Multiphysics seat…)

If you are not familiar with the tool I recommend that you go into help and find the CFD-Post manual.  Inside you will find a great user guide, but more importantly there are a set of thorough tutorials. The Mixing Elbow example will teach you the basics you need to know to find your way around the interface.

Before we get into the details, it should be pointed out that you are not going to find some huge, awesome, fantastic feature in CFD Post that is not in ANSYS Mechanical.  It does pretty much the same things, just a little differently.  I find it a bit more intuitive and there are some key things it does better as well as some things that it only does.  What we recommend it for:

• Fancy animations
• Higher quality graphics
• The ability to share a 3D results files that can be viewed with a free viewer
• Batch post processing
• Comparing multiple results

# The Key Things to Know

Most things you want to do in CFD Post occur in the tree to the left of the view window.  It has multiple tabs but you will be using the Outline tab most of the time unless you are doing expressions and stuff (like *get’s in MAPDL, we will leave those as an exercise for the user).  Once you load a result you will see four top level folders:  Cases, User Locations and Plots, Report and Display Properties & Defaults:

The file you read in is shown in cases.  The external surface of your model is grouped as the Default Boundary.  You can pretty much ignore Report and Display Properties and Defaults unless you want to get fancy or for some reason you really hate the almost identical report generator in ANSYS Mechanical.

This leaves the User Locations and Plots. This is where you specify what you want to see and how you want to see it.

The most common thing to do is RMB on User Locations and Plots and insert a Contour Plot.  When you do so you get “Details” dialog below your tree that has all the options. To see the details on an existing menu item double-click on it or RMG->Edit:

Most of the options you need are in the first tab, Geometry.  The key option is the Variable. This is the result value you want to display.  The list is limited compared to MAPDL but has all of the values that are explicitly stored in the *.RST file.  You will want to set Range to local (min and max from the domain you have selected).  You can also add or delete contours with # of Contours.  I set this to 256 to get a smooth contour.

At the bottom of the Detail there is an apply button, use this to update your plot as you play with the various options.

By default the contour plot shows color bands and lines between color bands, called Isopleths in most programs. CFD Post calls them Contour lines. If you want them off, go to the Render tab and uncheck Show Contour Lines.  If you just want the lines and no color bands, then check Show Contour Lines and uncheck Show Contour Bands.  Below are some plots with the options used to create them.  Any values not specified were at their default value.

• Tree:
• Default Boundary – Off
• Contour 1 – On
• Default Legend View 1 – On
• Wireframe – On
• Detail – Geometry:
• Domains –  All Domains
• Locations – Default Boundary
• Variable – Total Mesh Displacement
• Range – Local
• # of Contours – 11
• Detail – Render
• Show Contour Bands – On
• Show Contour Lines – On
• Line Width – 1
• Constant Coloring – Off

• Tree:
• Default Boundary – Off
• Contour 1 – On
• Default Legend View 1 – On
• Wireframe – On
• Detail – Geometry:
• Domains –  All Domains
• Locations – Default Boundary
• Variable – Total Mesh Displacement
• Range – Local
• # of Contours – 256
• Detail – Render
• Show Contour Bands – On
• Show Contour Lines – OFF

• Tree:
• Default Boundary – On
• Contour 1 – On
• Default Legend View 1 – On
• Wireframe – On
• Detail – Geometry:
• Domains –  All Domains
• Locations – Default Boundary
• Variable – Total Mesh Displacement
• Range – Local
• # of Contours – 10
• Detail – Render
• Show Contour Bands – OFF
• Show Contour Lines – On
• Line Width – 5

Every once in a while you need a black and white contour plot with isopleths.  You can do that in CFD Post very easily with contour options and by going into the Cases part of the tree and editing the Default Boundary options.  On the render tab, set the color to 0 and uncheck the Lighting.   Make sure that the Default Boundary is checked so it shows up.  Now go to the Contour and:

• Adjust the number of contours to a reasonable number (10 is good)
• Under the Labels tab check Show Numbers
• Under the Render tab:
• Uncheck Show Contour Bands
• Check Show Contour Lines
• Set line width to a larger number, 2 to 5 should work depending on your geometry
• Check Constant Coloring
• Make sure Color Mode is at Default
• When you save your plot, set background to White (see below)

I could fill up another 20 screens with all the options available.  Just get in there and play with it.

# Making Images, Including 3D

The best way to get images out of CFD Post is to click the camera icon on the top toolbar, go to File->Save Picture… or use CTRL-P.

I like the PNG format, accurate but compressed well.  For higher quality you can set the resolution here as well.  I also like to check the White Background so it is easy to delete the background to make transparent images.

But note the variety of options that you have.  For very high quality images you can use the PostScript option. This gives you a vector file rather than a raster file, so you can scale it as big as you want.  We recommend this if you are making posters or something like that.  The trick is that you need to turn off the legend, the triad, the scale and everything else except for your model. Then save to PostScript and bring it in to something Like Adobe Illustrator:

There are also two options in there for 3D “images.”  These are files that you can save and give to people to look at with free viewers.  Spin them around and such.  VRML is an older standard.

Update 9/21/2016: Well, it looks like all of the viewers that were referenced in this original article are pretty much no longer supported. The good news is that two opensource tools that work with tesselated geometry that read VRML:

• Meshlab is a big powerful sledge hammer of a tool that is for editing and viewing tesselated geometry.  It can be found at: meshlab.sourceforge.net/
• Paraview is more a viewer, and is much more user friendly.  it can be found at: www.paraview.org/download/

The other option is the CFD Viewer.  This is a free viewer that you can get from the ANSYS website.  We strongly recommend this as a way to get complex results, CFD or FEA to managers and customers if 2D static plots are just not good enough. The application is very fast and lightweight and easy enough to use for a manger!

Here is a video of using the CFD Viewer:

# Multiple Result Steps

If your result file has multiple result sets in it, maybe it is a transient run or has multiple load steps, you can access those results by clicking on the little Clock icon at the top of the CFD Post window:

You get a dialog that shows each of the steps in your *.RST along with times.  To look at a specific result, click on it and hit apply.

I have not found a way for this to work with modal results yet…  For now you need to use a macro to split your modes into separate RST files.

# Animation

One of the key reasons to use CFD Post for an FEA model is to get keyframe animations.  Clinton wrote a great article on how to use this great feature a while back.   It doesn’t really do the type of 0 to result animation that we do in the FEA world (like say a mode shape animation)  What it is good at is transients.

It has lots of nice options to make a high quality file.  It also has the ability to animate the motion of the camera, which may be nice to have.  Also, if you are animating a contour plot you want to enable global ranges on your contour. To do this read the section on global variables in the “Things to Know” section below.

The defaults make an OK animation. To get a good animation you need to click on the Options button and then make sure that “White Background” is checked (or you will get JPEG’y distortion) and on the Advanced tab set Quality to High.  Last, check Don’t Encode Last MPEG frame so you can loop.

I’ve included a couple of animations I did with it here:

Basic plot:

Fancy with camera moving.  Note that when converting to GIF you loose colors (GIF is only 256 colors).  The AVI looks much nicer.

A Valve fly through. I put this one on YouTube:

Here is the animated gif:

# Comparing Cases

One of the very cool capabilities is the Compare Case function.  To use this you go to Tools->Compare Cases.  Pick two cases. That can be two files or two steps in the same file.

For our simple little example, you can see how it shows the results for case 1 and case 2 at the top, then the difference between the two at the bottom.  It works best if the mesh is the same but it will work with different meshes as long as the geometry is very close.

This is probably the most useful thing you can do in CFD Post that is not easy to do in ANSYS Mechanical.

# Other Things to Know

There are some limitations.  Take a look at the help for CFD Post in section 8.14.5.1

Setting units is hidden a bit.  Go to Edit->Options->Units and set them to what you want.

If you want a deformed shape on your plot, you access that by RMB’ing on the graphics window, but not on your part.  Then choose Deformation and then the level you want. Auto usually works best.

By default CFD Post does not know the min and max values in your result file. So if you read in a file and plot it the default contour is global and it will not be right.  You need to change the Range to local or, if you want to be able to have a global contour, you need to tell CFD Post to figure out min and max values.  You will need to do this for Animations on transient runs.  To do it go to Edit->Options->CFD-Post->Files and check “Pre-calculate global variables ranges”

## How To Post Process ANSYS FEA Results in ANSYS CFD

The other day there was a thread on XANSYS about the best way to create animations in ANSYS Mechanical APDL (MAPDL).  If you are an MAPDL user you know that the animation tools found there were actually way ahead of their time… in 2001.  Now they are a bit limited and the AVI file it creates uses a codec that are a bit old.  You can write a macro that creates PNG files that you can then string together into an AVI, WMV, MOOV or animated gif file.  Check out the thread (go to XANSYS and search on animation) and you can see some of the options suggested.

As I was reading the thread I remembered that one of the CFD guys from ANSYS, Inc. once asked if we used CFX Post to post process our FEA results.  I of course pretended that I knew all about it and “just didn’t have time to play with it yet.”  The next time I had time at my desk I looked it up and there it was, under File->Load Results you can set the “Files of Type” drop down to read a whole slew of ANSYS Mechanical and MAPDL files:

I then promptly forgot about it till I was reading the thread.  So, I figure the best way to remember is to store it for posterity bouncing through the tubes of the interweb  as a blog posting.

# ANSYS CFD Post

CFX Post has been generalized and renamed as CFD Post. As a long time ANSYS MAPDL bigot I have to say, and this is a very difficult admission, CFD Post is a a very nice post processor.  Maybe I think like a Torontonian or something, but no matter how long it has been since I’ve used it, I can jump right in and figure out what needs to be done.

It is a CFD post processor and you can use it to post CFX, FLUENT, FIDAP, TASKFLOW and the general CGNS files that most CFD tools create.  So the terminology is defiantly oriented towards CFD users.  But because CFX supports moving meshes and conjugate heat transfer, it has most things that you need to read and post process an FEA result.  It is also scriptable and can be run in batch for process automation.

If you are not familiar with the tool I recommend that you go into help and find the CFD-Post manual.  Inside you will find a great user guide, but more importantly there are a set of thorough tutorials. The Mixing Elbow example will teach you the basics you need to know to find your way around the interface.

Before we get into the details, it should be pointed out that you are not going to find some huge, awesome, fantastic feature in CFD Post that is not in ANSYS Mechanical.  It does pretty much the same things, just a little differently.  I find it a bit more intuitive and there are some key things it does better as well as some things that it only does.  What we recommend it for is fancy animations, higher quality graphics, batch post processing, and comparing multiple results in one run.

# The Key Things to Know

Most things you want to do in CFD Post occur in the tree to the left of the view window.  It has multiple tabs but you will be using the Outline tab most of the time unless you are doing expressions and stuff (like *get’s in MAPDL, we will leave those as an exercise for the user).  Once you load a result you will see four top level folders:  Cases, User Locations and Plots, Report and Display Properties & Defaults:

The file you read in is shown in cases.  The external surface of your model is grouped as the Default Boundary.  You can pretty much ignore Report and Display Properties and Defaults unless you want to get fancy or for some reason you really hate the almost identical report generator in ANSYS Mechanical.

This leaves the User Locations and Plots. This is where you specify what you want to see and how you want to see it.

The most common thing to do is RMB on User Locations and Plots and insert a Contour Plot.  When you do so you get “Details” dialog below your tree that has all the options. To see the details on an existing menu item double-click on it or RMG->Edit:

Most of the options you need are in the first tab, Geometry.  The key option is the Variable. This is the result value you want to display.  The list is limited compared to MAPDL but has all of the values that are explicitly stored in the *.RST file.  You will want to set Range to local (min and max from the domain you have selected).  You can also add or delete contours with # of Contours.  I set this to 256 to get a smooth contour.

At the bottom of the Detail there is an apply button, use this to update your plot as you play with the various options.

By default the contour plot shows color bands and lines between color bands, called Isopleths in most programs. CFD Post calls them Contour lines. If you want them off, go to the Render tab and uncheck Show Contour Lines.  If you just want the lines and no color bands, then check Show Contour Lines and uncheck Show Contour Bands.  Below are some plots with the options used to create them.  Any values not specified were at their default value:

• Tree:
• Default Boundary – Off
• Contour 1 – On
• Default Legend View 1 – On
• Wireframe – On
• Detail – Geometry:
• Domains –  All Domains
• Locations – Default Boundary
• Variable – Total Mesh Displacement
• Range – Local
• # of Contours – 11
• Detail – Render
• Show Contour Bands – On
• Show Contour Lines – On
• Line Width – 1
• Constant Coloring – Off

• Tree:
• Default Boundary – Off
• Contour 1 – On
• Default Legend View 1 – On
• Wireframe – On
• Detail – Geometry:
• Domains –  All Domains
• Locations – Default Boundary
• Variable – Total Mesh Displacement
• Range – Local
• # of Contours – 256
• Detail – Render
• Show Contour Bands – On
• Show Contour Lines – OFF

• Tree:
• Default Boundary – On
• Contour 1 – On
• Default Legend View 1 – On
• Wireframe – On
• Detail – Geometry:
• Domains –  All Domains
• Locations – Default Boundary
• Variable – Total Mesh Displacement
• Range – Local
• # of Contours – 10
• Detail – Render
• Show Contour Bands – OFF
• Show Contour Lines – On
• Line Width – 5

Every once in a while you need a black and white contour plot with isopleths.  You can do that in CFD Post very easily with contour options and by going into the Cases part of the tree and editing the Default Boundary options.  On the render tab, set the color to 0.   Make sure that the Default Boundary is checked so it shows up.  Now go to the Contour and:

• Adjust the number of contours to a reasonable number (10 is good)
• Under the Labels tab check Show Numbers
• Under the Render tab:
• Uncheck Show Contour Bands
• Check Show Contour Lines
• Set line width to a larger number, 2 to 5 should work depending on your geometry
• Check Constant Coloring
• Make sure Color Mode is at Default

I could fill up another 20 screens with all the options available.  Just get in there and play with it.

# Multiple Result Steps

If your result file has multiple result sets in it, maybe it is a transient run or has multiple load steps, you can access those results by clicking on the little Clock icon at the top of the CFD Post window:

You get a dialog that shows each of the steps in your *.RST along with times.  To look at a specific result, click on it and hit apply.

I have not found a way for this to work with modal results yet…  For now you need to use a macro to split your modes into separate RST files.

# Animation

One of the key reasons to use CFD Post for an FEA model is to get keyframe animations.  Clinton wrote a great article on how to use this great feature a while back.   It doesn’t really do the type of 0 to result animation that we do in the FEA world (like say a mode shape animation)  What it is good at is transients.

It has lots of nice options to make a high quality file.  It also has the ability to animate the motion of the camera, which may be nice to have.  Also, if you are animating a contour plot you want to enable global ranges on your contour. To do this read the section on global variables in the “Things to Know” section below.

The defaults make an OK animation. To get a good animation you need to click on the Options button and then make sure that “White Background” is checked (or you will get JPEG’y distortion) and on the Advanced tab set Quality to High.  Last, check Don’t Encode Last MPEG frame so you can loop.

I’ve included a couple of animations I did with it here:

Basic plot:

Fancy with camera moving.  Note that when converting to GIF you loose colors (GIF is only 256 colors).  The AVI looks much nicer.

A Valve fly through. I put this one on YouTube:

Here is the animated gif:

# Things to Know

There are some limitations.  Take a look at the help for CFD Post in section 8.14.5.1

Setting units is hidden a bit.  Go to Edit->Options->Units and set them to what you want.

If you want a deformed shape on your plot, you access that by RMB’ing on the graphics window, but not on your part.  Then choose Deformation and then the level you want. Auto usually works best.

## Importing and Exporting ANSYS Mechanical Loads as XML Files

I was futzing around with some loads the other day and noticed that, to my shock, that if you click on the value for a load and instead of typing a value in, click on the drop down menu and you will find that it has an Import and an Export on it.   I’m not sure when that became a capability, but I think it has been there for a while.  A quick check with the staff here at PADT and only a few knew about it.  Which makes it a great topic for The Focus.

# XML, Engineering Data, and Verbosity

The easiest way to check this out is to go into a model and insert a force into your model.  Go ahead and pick the geometry.  In the Details for the force, click on the magnitude cell and you will see a little drop-down menu triangle:

Click on that and you will see the menu:

Click on Export and give it a file name.  You will notice when you do this that it makes an XML file.  If you didn’t know it, ANSYS Mechanical uses a lot of XML.  In fact, they used to even store results in an XML file.  The good thing about XML files is that they kind of self-describe themselves and organize the data in them in a sort of object oriented way.  This makes them very easy to read and portable between programs.

XML stands for eXtensible Markup Language and it is an expansion of HTML to handle data. Check out the Wikipedia article on the topic to learn more.  XML is hear to stay and if you don’t get it, you might struggle with some advanced stuff in a lot of areas, not just ANSYS.

The down side of XML is that it is very wordy – verbose.  It has lots of text in there that specifies relationships, names, ID’s, etc…  Tags out the wazoo.  For those of us that grew up feeding our simulation programs fixed format or comma delimited files where the first line specified all the constants and the rest was the data, this can be a bit annoying.  But it does make the data portable and “human readable”

Let’s take a look at the XML file from applying a load of 0.0 lbf to our model.  The best way to view an XML file is to doubleclick on it. Your browser will bring it up and show what is inside.   If you have Dreamweaver or some other HTML editor, that will work even better.

Here is our example:

`   1: <?xml version="1.0" encoding="UTF-8" standalone="no" ?>   1.5: <ANSYS_EnggData>`

`   2:     <MaterialData/>`

`   3:     <ConvectionData/>`

`   4:     <LoadVariationData>`

`   5:           <MatML_Doc>`

`   6:               <LoadVariation>`

`   7:                     <BulkDetails>`

`   8:                         <Name>Force 2</Name>`

`   9:                         <Form>`

`  10:                               <Description/>`

`  11:                     </Form>`

`  12:                         <PropertyData property="pr1">`

`  13:                               <Data format="float">0.,0.</Data>`

`  14:                               <Qualifier>Force</Qualifier>`

`  15:                               <ParameterValue format="float" parameter="pa1">                                         0.,1.</ParameterValue>`

`  16:                     </PropertyData>`

`  17:                 </BulkDetails>`

`  18:                     <Metadata>`

`  19:                         <ParameterDetails id="pa1">`

`  20:                               <Name>Time</Name>`

`  21:                     </ParameterDetails>`

`  22:                         <PropertyDetails id="pr1">`

`  23:                               <Name>Force</Name>`

`  24:                     </PropertyDetails>`

`  25:                 </Metadata>`

`  26:             </LoadVariation>`

`  27:         </MatML_Doc>`

`  28:     </LoadVariationData>`

`  29:     <BeamSectionData/>`

`  30: </ANSYS_EnggData>`

The first thing you will notice is that the second tag (right after the XML version info) is <ANSYS_EnggData>.  That is because ANSYS already had a nice well defined format for putting tabular data into Workbench applications: EngineeringData.  So they just used the same format for loads.

The next thing you will notice is a lot of text to specify two value at two time points.  A lot of the data is just blank. There in case you need it.  To understand this let’s step back and look at tags in HTML.

A tag goes around some piece of information and describes what that information is.  Usually you have a starting tag which is the string with a less-than sign at the start and a greater-than sign at the back:

<tagString>

You then put in your information.  It could be data, text, more tags, whatever you want.  then when you are done, you close out the tag with the same string, but this time start with less-than followed by a forward slash. You still end with greater than:

</tagString>

You can nest these guys, with tags inside tags. This is how you get your object parent-child relationships.

So let’s look at our first couple of lines again, repeated here with the meat taken out (<…>) so we don’t have to scroll back and forth:

`   1: <?xml version="1.0" encoding="UTF-8" standalone="no" ?><ANSYS_EnggData>`

`   2:     <MaterialData/>`

`   3:     <ConvectionData/>`

`   4:     <LoadVariationData>`

`   5:           <MatML_Doc>`

`   6:               <LoadVariation>`

`   7:                     <BulkDetails>`

`   8:                         <...>`

`   9:                     </BulkDetails>`

`  10:                     <Metadata>`

`  11:                         <...>                       `

`  12:                     </Metadata>`

`  13:             </LoadVariation>`

`  14:         </MatML_Doc>`

`  15:     </LoadVariationData>`

`  16:     <BeamSectionData/>`

`  17: </ANSYS_EnggData>`

You will notice that a lot of the tags in our example end with a forward slash:

<tagString/>

This is an empty tag. It tells the program I got no data of this type. It does save some text compared to other market languages where you just have a blank start and end tag.

So, our example starts and ends with <ANSYS_EnggData> and </ANSYS_EnggData>  Everything between in engineering data.  Then it says no material data and no convection data.  It does say it has load variation data.  We then find the LoadVariationData tag.  This is what we actually have in the file.  It then goes one step down and has a MatML_Doc tag.  This tells the program the format of the data being given is in the MatML schema.  more on that below.

Then we break the load into two parts: The BulkDetails where the actual data values are specified and the MetaData, which tells the program information it needs to know about the data.  Then everything has its end tag, you tell the program you don’t have BeamSectionData, and you finish up.

If you want to, you can not include all the empty tags.  the <tagString/> tags.  Mechanical reads the file just fine without them.   But you can’t get rid of anything else.

# The MatML Language

MatML is “an extensible markup language (XML) developed especially for the interchange of materials information.”  You can read all about it at: http://www.matml.org/  History, examples, news, etc…  It is all there.   Like most standards, you can waste a lot of time saying what is good or bad about it.  But in the end, what matters is that everyone uses the same standard. (Of course, MatWeb doesn’t support this standard because they want you to pay for native format… grumble, grumble…).

# Looking at the Data and MetaData

Let’s look at the heart of our file, the actual data we want.  In MatML they call it BulkDetails:

`   1: <BulkDetails>`

`   2:     <Name>Force 2</Name>`

`   3:     <PropertyData property="pr1">`

`   4:         <Data format="float">0.,0.</Data>`

`   5:         <Qualifier>Force</Qualifier>`

`   6:         <ParameterValue format="float" parameter="pa1">0.,1.</ParameterValue>`

`   7:     </PropertyData>`

`   8: </BulkDetails>`

The first thing we find is the name.  This is not the name that will be used in the tree.  It is the name that will show up in the library if you combine a bunch of XML files and the name that will show up in your detail view for magnitude.  So if you make your own load, give it something descriptive here so you can pick it out of the library but not so long that you can’t read it in the detail. Calling it F1 will just tick you off in six months when you try to reuse a load.

Next is the PropertyData tag.  It will always have the name “prn” as far as I can tell, where n is an integer starting at 1 and increasing for each property in the file.  If you change it, everything gets messed up – so always use pr1.

Now the data.  You give it a format, float in most cases, then a comma delimited list.  That is it.

Then you tell the program that it is a Force with the Qualifier.

Last, you need to specify the parameters that your load will vary over.  Usually this is time.  Use <ParameterValue> to do this.  Notice how you specify a format and what the parameter is called, and this is always “pa1”  (or pan actually, where n starts at 1 and increases for each property in the file).

Now we have to tell the program some additional information about our data, which is called Meta Data.  For loads, the only thing that is supported is the definition of the type of load being specified:

`   1: <Metadata>`

`   2:     <ParameterDetails id="pa1">`

`   3:         <Name>Time</Name>`

`   4:     </ParameterDetails>`

`   5:     <PropertyDetails id="pr1">`

`   6:         <Name>Force</Name>`

`   7:     </PropertyDetails>`

`   8: </Metadata>`

Don’t worry too much about this formating stuff.  The best thing for you to do is make a load like the one you want in Mechanical, export it to XML, then modify the values inside as you see fit.  Much easier than understanding the schema… or even what a schema is.

# Units

Please notice that there are no units anywhere.  Right now all of your values must be in SI units, and Mechanical will convert when it displays the values.  This is because Mechanical always stores values internally as SI.  So, if you make your own load files, make sure you convert to SI.

This is the single biggest potential for error… so mind your units!

The process of reading in the loads is a bit more complicated then simply pointing to a file.  This is because each file can hold more than one load. You should think of the XML file as a library.

To read the file go to your Magnitude, click on the drop-down menu icon and choose “Import…”  This brings up the “Import Load History Data” dialog:

Note that instead of picking a file you are given a Data Source area and a Load History Data to Import area.  the top Data Source is the file.  Click Add… and point to your XML file.  Once it reads that file in it will always remember the file and every time you open this dialog box, it will re-read it and update the Load History data to Import values.

You can see our sample file, tt4.xml, is the library Data Source and within it are two loads.  You use the radio button to choose the load you want to apply.  Click OK and you will notice that your Details for the load now lists that name as the Magnitude:

As you can imagine, you can put a ton of loads in one file, maybe all the loads for your project.  Then use the filter to find the load you want in a big file.  This is again a reminder of why it is important to specify a useful name when you create the load.

# Formulas

The examples above deal with tabular data.  You can also store formulas in the file.  This looks a little different in the <BulkDetails> in that you specify format=”function> in the <Data> tag.  Here is an example:

# ` 1: <MatML_Doc>` ` 2: <LoadVariation>` ` 3: <BulkDetails>` ` 4: <Name>Force 2</Name>` ` 5: <Form>` ` 6: <Description/>` ` 7: </Form>` ` 8: <PropertyData property="pr1">` ` 9: <Data AngleInDegrees="1" AngularVelocityInRPM="1" ` ` 10: TemperatureUnit="3" UnitSystem="4" format="function">` ` 11: <Domain LowerLimit="0." UpperLimit="-999.">` ` 12: time` ` 13: </Domain>` ` 14: <Domain LowerLimit="0." UpperLimit="-999.">` ` 15: 1.2*sin(time/6)` ` 16: </Domain>` ` 17: </Data>` ` 18: <Qualifier>Force</Qualifier>` ` 19: <ParameterValue format="float" parameter="pa1">` ` 20: 0.,.1,.2,.3,.4,.5,.6,.7,.8,.9,` ` 21: 1.0,1.1,1.2,1.3,1.4,1.5,1.6,` ` 22: 1.7,1.8,1.9,2.0` ` 23: </ParameterValue>` ` 24: </PropertyData>` ` 25: </BulkDetails>` ` 26: <Metadata>` ` 27: <ParameterDetails id="pa1">` ` 28: <Name>Time</Name>` ` 29: </ParameterDetails>` ` 30: <PropertyDetails id="pr1">` ` 31: <Name>Force</Name>` ` 32: </PropertyDetails>` ` 33: </Metadata>` ` 34: </LoadVariation>` ` 35: MatML_Doc>`

A lot more complicated. The best way to make one of these is to do it interactively and export.

At first blush, the file looks complicated but a simple VBA script in excel or a python macro can build the file very quickly because most of the text is static, you are really just changing the data and parameter value values.  I was going to do such an example, but ran out of time.  If any of you have one or write one, please let us know so we can share.

## Making Animated GIF’s of ANSYS Graphics for Fun and Profit

In last weeks article I included some animations of some plots from the examples.  While doing that I remembered that we have received a couple of questions recently about how to get result animations in a PowerPoint or a Website.  In this article we will talk about the tool I use and give some tips on making the process better. And, it give me an excuse to write about some software other than ANSYS, Inc.

# Animated GIFs and Why we Need Them

As you know, an animation is simply a series of still images shown one right after another.  When we create Video on a computer we generally make something with 30 still frames shown every second.  Although the various formats for video have gotten much better, that is still a lot of pixels to send around. That makes a big file that may not be best for your web page or PowerPoint.  However, with modern high speed internet and fast computers, that is not the problem it used to be.  It is still a concern.

What we really have to deal with is making sure that whatever we are using to present our animation can play it.  Can the persons web browser show it?  Can PowerPoint show it?  Although YouTube is a possibility more an more, you really want a portable format that you can imped in your document or site and that everyone can see.  If you research…  the only format that fits that bill is an animated GIF.

The gif format is compact, and because the early Netscape Navigator browser supported it, it became a default format.  Even Microsoft decided to support it.  So, as in some ways, it is the least common denominator that works for everyone.  Another cool thing is that the programs treat it as an image, not as a video or animation.  You copy and paste it, insert it, place it, edit its size just like you would any JPEG, PNG, or TIFF image.

You can learn about the format on wikipedia. But if the binary info that greats you on that page causes your eyes to glaze over, you only really need to know the following:

1. It is a file format that supports multiple images all contained in one image file
2. You can specify how long to play a given image (frame)
3. It supports transparency
4. It is a standard and all web browsers and PowerPoint will display it
5. You can imbed it in a PowerPoint so you don’t have to worry about carrying your animation files around in a folder with your PowerPoint.
6. It only supports 256 colors. This is the downside of GIF’s

Unfortunately non of the ANSYS products make an animated GIF file.  They generally make an AVI, which is the most common video file, but something that most people can’t display on their website or put in a PowerPoint.  So we need to convert the AVI to a GIF, or create a GIF from a series of images.

There is one option we should mention, and that is creating an Adobe Flash file. This is a more modern and capable format but it has problems.  First and foremost, iPhones and iPads don’t display flash.  Second, to show a flash animation in PowerPoint you have to make sure a special flash player is installed.  So again, lowly GIF wins out.

# GIF Movie Gear

I use a program called GIF Movie Gear. If you Google “AVI to GIF” you will find other tools. I picked this one because it had the features I wanted, it was cheap, and it works so far just fine. Over time, I have found it to be very robust as well.  It is from a company called Gamani, and you can download a trial version or purchase it for \$29.95.  They have a nice website that lists all the features and offers some tutorials at: www.gamani.com

Once you have it installed check it out. If you have not tried similar tools in the past, go through the tutorial. It is worth the time.

For the ANSYS user, here are the important features:

1. It will import an AVI and break it into individual images (frames)
2. You can crop and resize
3. You can set the speed of the animation
4. It is easy to use (important, since if you are like me you only need it once in a while)
5. You can easily make a ping-pong animation (copy frames then reverse them)
6. You can make an animation by reading in a series of images (important for MAPDL users that want to make a high quality animation)

There are a ton more features, but these are the ones that matter to us ANSYS types.

# Building Animations from Images

If you are using Mechanical APDL (MAPDL) you can use the ANIM command to build an animation of your model as an AVI. The problem with this is that the AVI file format that ANSYS uses compresses the images to save space, and to do so it really reduces the quality of the image.  So instead, you can write your own animation macro and save a PNG file for each frame, then use GIF Movie Gear to make an animation.

To learn about how to make the images for your own animation, check out an old Focus article in Issue 49 from 2006, on page 6.  It talks about the program we used to use to make an AVI instead of a GIF, but it works the same.  You basically make a plot and save it as a PNG then modify your image and make the next one.  We use that macro in the examples below and put it here for you to use.  Take a good long look at it

You probably also want to reread (because I know you read it when we put it out) the more recent article on making pretty images from March of this year.

## A Simple Example

To get the gist of how this all works, let’s build a simple tower model, put a pressure on the side, then animate it’s displacement.  Download this macro and run it in MAPDL.  If you look at the macro the last thing it does is make a contour plot of the total deflection (PLNSOL, U, SUM).  This is what we want to animate.

So we simply type: “agif_anm1,10”  into the command line to run the animation macro and it will make 10 PNG file. Look in your working directory and you will see twrexmp000.png through twrexmp009.png.  These are the frames.  Now on to making our GIF.

Start GIF Movie Gear and you will get the little start wizard:

Click on Insert Frames.  This opens a file selection dialog box. Shift-select the 10 frames we just made and click open:

You will now see the upper right corner of the first frame… Don’t panic.  this is the size of your image and the window is small.  Click the little zoom in icon (magnifying glass with a minus sign) until you see a couple of frames.  If you click the play icon, you will see your animation play very fast.  Not what we want.

So the first thing we will do is change the animation speed by changing the duration of each frame. It is 0 by default.  Go to Animation->Timing and it will show your hyper animation again. At the bottom, change the 0 to a 20 and hit return:

That calmed things down a bit. Close that window.

At this point you can simply save your animation and be done: File->Save and give it a name.  And this is what you get:

The Bloging software resizes it. Click on the image to get the full size version.

## Changing the Size

That may not be the shape, size, or content you want.  To resize the image, use Animation->Resize:

Make sure that “Maintain aspect ratio” is checked.  If you don’t, your image can get distorted.  Then set the width or height to what you want.   I’ll use a width of 400.  Make sure the Bicubic is picked for your resizing.  The other method is slower to run but makes bad images unless you have only a few colors.  If you save this image you get the following:

Now, we may want to crop. We do that the same way: Animation->Crop. Now this is the only feature I don’t like. It shows the image in a small window.

So click on the Zoom In icon till you can see your image and drag to where you want it and click OK. Save that and you get:

# Transparency

One of the coolest things about GIF files is that you can tell the display program to not show a certain color, to make your image transparent.  This is great for PowerPoints.  To do this you need to mark one of the colors in your animation as “transparent.”

Go to Animation->Properties then click on the Global Frame tab:

Click on Transparent and it will bring up your color Pallet.  click on the black background or the black color in the table and that will be the transparent color.  Now you need to set the bottom menu to “Restore to Background before drawing next frame”.  If you don’t do this you will see ghosting.

Click OK. Save that and you get:

Not too exciting on this blog because the background is white.  But imagine we had some fancy background.  Copy and paste this into your corporate PowerPoint template and you will see:

# Converting for AVI’s

What, you are not a gray haired throw back to a past time.  You use CDF Post or ANSYS Mechanical?  You can skip a lot of the first steps and just go straight from an AVI to an Animated GIF.

Regardless of which tool you are using, you simply need to save an AVI to get started.  For ANSYS Mechanical you do that by using the animation viewer to get the animation you want then click on the “Export Video File” Icon.  Remember to make sure you have turned off the fancy Aero window stuff.

To make a CFD animation read Clinton’s Article

Now that you have the AVI file you can make a GIF. Start GIF Movie Gear and click on Open File this time.  Choose the AVI and you will see all the frames in the AVI (zoom out if you need to).  If you like what you see, just do a File->Save As and save as a GIF.

Just like the animations made from images, you can adjust the size of the image, crop, and set animations.

One thing you may notice is the banding on the background. This is in the AVI due to compression in the AVI.  So if you are making animation we recommend you create a solid background (set in the project schematic->Tools->Options->Appearance) :

And once you have done that, you can use transparency:

# Other Things You Should Know

When setting transparencies above we talk about making sure it says: “Restore to Background before drawing next frame” If you don’t, this is what your animation will look like:

For debugging it is kid of a pain to place in PowerPoint then view as slide show.  A faster way to view an animated GIF is to RMB on it in the explorer and say Open With… and choose Internet Explorer.  You can also drag it into your browser.  Much faster.

The program has an Undo.  Use it.  Try stuff, save the file, look at it, then undo if you need to.

Another thing to be aware of is Ping-Pong.  If you remember our first animation of the deflected tower, it only goes to the max deflection then snaps back to the beginning. It would be much nicer if it went back.   You can do that by going to Animation->Rearrange Frames –>Ping-Pong Animation.

Now save and you have an “up and back” animation.  The original is on the left, the ping-pong is on the right.

This tool is also a great way to grab a single frame from an animation.  Say you have an animation and you need a picture, and you don’t want to go back in to the program to make it.  Simply read the AVI into this program, find the frame you want, then do a File->Save As. Pick your format and set “Save as Style” to Individual Image(s).  Then select the “Only selected frames(s)”

That is about it.  I hope this will help you make better presentations and cool web sites.

Do you have seizures yet?

## HSFLD241/242: Modeling Enclosed Liquids

This is a second attempt at this posting.  The first attempt got 60% of the way done, then I rebooted my machine before I saved the posting… Doh.  So let’s try this again:

Every once in a while I feel the need to stop exploring all the new and cool stuff in the world of workbench and do a deep dive into something that involves names which are restricted to eight characters or less. Something that involves a script rather than a GUI click.  Something that requires you to look at a real equation, something with an integral sign in it:

I want to learn about something that uses comma delimited commands.

So, up comes ANSYS Help, dive down into the release notes for Mechanical APDL and look for something obscure but useful.  New elements…  Aha!  HSFLD21 – now that is a name to make any I-only-use-the-GUI-and-manuals-with-equations-but-without-color-animations-make-me-nervous user cringe.  Hydrostatic.  I like that word.  It reads:

This 2-D hydrostatic fluid element models fluids that are fully enclosed by 2-D planar and axisymmetric solids. This element is well suited for modeling fluid-solid interaction with incompressible or compressible fluids under uniform pressure. It can be used in geometrically linear as well as nonlinear static and transient dynamic analyses.

Now I have something I can sink my teeth in.

# The Basics on the HSFLD241 and HSFLD242

New at R13, these elements are used to model compressible or incompressible fluids that are surrounded by solids. The key assumption to be aware of is deserving of its own line:

The fluid volume has uniform pressure, temperature, and density without any gradients

So no sloshing, variation due to gravity, etc.. Take a look at FLUID80 if you want these things… maybe a future article topic.

HSFLD241 is the 2D and axisymetric version, and HSFLD242 is the 3D version.  If you look at the element pictures from the manual at the top of the posting you’ll see that they are a surface effect element with an extra node, called a pressure node.  You use ESURF to apply the element to the inside face of your enclosing volume, and you link all the faces that make up the volume by making them share a node (L or Q).  The fact that they all share the same node tells the solver that they make a volume. Besides sharing the node, they must share the same material and real number.

When you use ESURF to make the elements, it automatically makes them a positive volume by the order it defines the face nodes with.  But sometimes you may want to create a negative volume inside your positive. Say you are modeling a tire (what this element was added for actually) and you will find that the pressure node is outside of the volume.  The calculated volume is not correct.  You need to subtract volume for the elements that are actually not in your volume. Here is a cross section to try and make more sense of it.

The purple parts are the fluid.  So this is not right. You need to go in and create negative elements on any faces that face away from the origin.  You do this in two steps:  Mesh using ESURF like you normally would, then grab the elements you want to turn into negative elements and issue the ESURF,pnode,REVERSE command.  This will turn those elements into negative volumes.  The key hear is to create your geometry in a way so that you can easily select faces that point away from the center of your volume. If you don’t, you will need to write a macro that loops through the elements, checks the vector from the face centroid to the center of you volume and if it facing out, swap the element normal. Not hard, just tedious.  In our example, the negative element will look like this (color changed for clarity):

## DOF’s:

The elements have displacement (UX,UY and UX,UY,UZ) Degrees of Freedom on the face part of the element, the part that sits on your structural elements.  The pressure node has a DOF of HDSP or hydrostatic pressure by default, and both PRES and HDSP if you set KEYOPT(1) = 1.  This is so you can hook the node to other elements that have PRES DOF’s like the FLUID116.

## Real Constants

For real properties you have the ability to specify a thickness (defaults to 1) on the 2D element so the program can calculate volume correctly. Both versions have a real constant of PREF, the reference pressure. Simple enough.

## Material Properties

If you opt for an incompressible fluid, just specify a density and coefficient of thermal expansion for your material.  But if you are modeling a compressible fluid, you use a new material property table to specify the material properties:  TB,FLUID.  Within the FLUID model you have three options:  a model for liquids, a model for gases, or you can provide pressure-volume data. It is recommended that you read the theory manual on these three to understand the difference and how to use them, as well as the standard command information for the TB.

For TB,FLUID,,,,LIQUID the model is basically a squishy solid.  You give a bulk modulus, coefficient of thermal expansion, and an initial density over up to 20 temperatures.

For TB,FLUID,,,,GAS you simply give a Density. The program then simply uses the Ideal Gas Law… you remember that from freshman physics? Or was it chemistry.  I kind of remember it… sort of:

If you have a compressible fluid that does not follow the idea gas law, then you can supply your own pressure vs. volume table with TB,FLUID,,,,PVDATA.

## KEYOPT

KEYOPT(1) controls the DOF’s on the pressure node.  By default the uniform pressure for the solid is stored as HDSP.  If you set KEYOPT(1) to 1, then a PRES DOF is added and is set to be equal to HDSP.  This is so you can hook a FLUID116 up to it and flow out of your volume… more below.

KEYOPT(3) is used on the HSFLD241 element to say if it is Planer (0) or Axisymmetric (1)

Use KEYOPT(5) to turn on mass effects for the elements. Remember, this is a uniform mass. But if you have gravity or you are doing a modal analysis, you need this turned on.

Turn compressibility off by setting KEYOPT(1) to 1.

Other Basic Info

Give the manual page a read on the element.  There are a lot of output options besides the DOF solution. Stuff like Volume, Mass, and mass flow rate.

# Simple Example

(Want to know how I made this animation… that will be next weeks article.
I used a program called GIF Movie Gear, best \$29.95 I’ve spent in a while…)

So, having waded through the boring bits, let’s build a model.  Our first example is simply a 2D hollow rectangle that we apply a pressure to. Here is the macro.  Take a look at the comments and follow the process.

`   1: !Square Baloon Macro   - Example for HDSP241`

`   2: !`

`   3: ! Get in the begin level, clear the databse`

`   4: !   and go to the preprocessor`

`   5: finish`

`   6: /clear`

`   7: /prep7`

`   8: ! Define Dimensions as parameters`

`   9: wdth = 2`

`  10: hght = 4`

`  11: thk = .1`

`  12: ! Build two rectangles and subtract the inner one`

`  13: !  to make an enclosure`

`  14: blc4,(-1*wdth/2),0,wdth,hght`

`  15: blc4,(-1*wdth/2)+thk,thk,wdth-2*thk,hght-2*thk`

`  16: asba,1,2`

`  17: ! Make a component out of the inner lines - this is`

`  18: !  where we will put our HDSP elements`

`  19: lsel,s,,,5,8`

`  20: cm,l_insd,line`

`  21:  `

`  22: ! Define a 182 for the solid and 241 for the fluid`

`  23: et,1,182`

`  24: et,2,241`

`  25:  `

`  26: ! Sort of soft material for the enclosure wall`

`  27: mp,ex,1,10e5`

`  28: mp,nuxy,1,.3`

`  29: mp,dens,1,.001`

`  30:  `

`  31: ! Some fluid properties`

`  32: tb,fluid,2,,,,liquid   ! Liquid Properties`

`  33: tbdata,1,300000        ! Bulk Modulous`

`  34: tbdata,2,6.4e-4        ! Coeficient of thermal exp.`

`  35: tbdata,3,.001          ! Density`

`  36:  `

`  37: ! Mesh the enclosure wall`

`  38: type,1`

`  39: mat,1`

`  40: esize,thk/2`

`  41: amesh,all`

`  42:  `

`  43: ! Grab the inside nodes from the compenent and create`

`  44: !   the fluid mesh using esurf`

`  45: cmsel,s,l_insd`

`  46: nsll,s,1`

`  47: type,2`

`  48: mat,2`

`  49: n,999,0,2`

`  50: esurf,999  ! Tell esurf to make the "extra" node 999`

`  51:            ! That all the elements share`

`  52: allsel,all`

`  53:  `

`  54: ! Fix the bottom of the enclosure vertically`

`  55: !  And fix the bottom right corner tangentially`

`  56: !  to constrain the model`

`  57: nsel,s,loc,y,0`

`  58: d,all,uy`

`  59: nsel,r,loc,x,-1*wdth/2`

`  60: d,all,ux`

`  61: allsel`

`  62:  `

`  63: ! Specify an load of 100 psi as the internal pressure`

`  64: !  The model will ramp up to that load over the specified`

`  65: !  substeps`

`  66: d,999,hdsp,100`

`  67:  `

`  68: ! Set up Solve and Run`

`  69: /solu`

`  70: nlgeom,on`

`  71: nsubst,50,100,20`

`  72: outres,all,all   ! Don't forget to save substeps so you`

`  73:                  !   can animate them`

`  74: solve`

`  75: finish`

`  76:  `

`  77: ! Animate the resulting displacement`

`  78: /post1`

`  79: set,last`

`  80: /dscale,1,1`

`  81: plnsol,u,sum`

`  82: andata,0.5,,0,0,0,1,0,1`

One key thing to note in the code is the ESURF command.  Notice how you specify the common node as the first argument in the command. This is pretty useful and avoids making you go through and specify.  You can download the macro here.

# A More Complex Example

The help on this element is pretty cool, and it even includes an example of how to build a piston. Unfortunately it does not include the part that solves it.  So I’ve added that made some other changes, including an animation and a short trip into POST26 to get pressure and volume of the fluid over time. The code is below.  The most obvious thing when looking at this animation is the funny triangle thingy.  that is a negative element that deals with the fact that the volume is changing over time.  It is not 100% accurate but basically says any fluid above the piston needs to be subtracted.  In the image on the right, the solid geometry mesh, you can imagine that your fluid volume can be anywhere inside the piston, from the top of the yellow line to the whole length of the green.  The red dot shows the bottom corner of the piston.  If you make an element from the red dot to the top and bottom of the yellow line, no mater where the piston goes you will subtract the volume of any part of the total volume that is above the piston.  I found that kind of slick and clever of the ANSYS developers.  It doesn’t plot so cool, but it gets the job done.

Here is the code:

`   1: finish`

`   2: /clear`

`   3: /prep7`

`   4: ! Define element types`

`   5: et,1,182    !plane182`

`   6: keyopt,1,3,1    !axisymmetric option`

`   7: et,2,241    !hsfld241 `

`   8: keyopt,2,3,1 ! axi option`

`   9: ! Material properties for Steel`

`  10: mp,ex,1,2.0e5    !Young's Modulus in N/mm^2`

`  11: mp,nuxy,1,0.3    !Poisson's ratio`

`  12: mp,dens,1,7.7e-9!Density in ton/mm^3`

`  13:  `

`  14: ! Material properties for hydraulic fluid`

`  15: tb,fluid,2,,,,liquid`

`  16: tbdata,1,2000.0    !Bulk Modulus in N/mm^2`

`  17: tbdata,2,6.4e-4    !Coefficient of thermal expansion`

`  18: tbdata,3,8.42e-5!Density in ton/mm^3`

`  19: ! Nodes`

`  20: n,1,0.0,50.0    !pressure node`

`  21: ! Keypoints`

`  22: k, 1, 0.0,  0.0`

`  23: k, 2,25.0,  0.0`

`  24: k, 3,25.0,100.0`

`  25: k, 4,10.0,100.0`

`  26: k, 5,10.0, 95.0`

`  27: k, 6,20.0, 95.0`

`  28: k, 7,20.0,  5.0`

`  29: k, 8, 0.0,  5.0`

`  30: k, 9, 0.0, 80.0`

`  31: k,10,19.0, 80.0`

`  32: k,11,19.0, 85.0`

`  33: k,12, 3.5, 85.0`

`  34: k,13, 3.5,185.0`

`  35: k,14, 0.0,185.0`

`  36: ! Areas`

`  37: a,1,2,3,4,5,6,7,8`

`  38: a,9,10,11,12,13,14`

`  39: ! Planar elements`

`  40: type,1`

`  41: mat,1`

`  42: esize,2.5`

`  43: amesh,all`

`  44: ! Hydrostatic fluid elements--automatic generation`

`  45: type,2`

`  46: mat,2`

`  47: lsel,s,line,,6,9`

`  48: nsll,s,1`

`  49: esurf,1`

`  50: allsel,all`

`  51: ! Create the Negative volume element- needed to take into account`

`  52: ! the movement of the piston`

`  53: e,61,162,,1    !element with negative volume--nodes 61 and 162 swapped`

`  54: ! Symmetry boundary condition on pressure node   [REQUIRED]`

`  55: d,1,ux,0.0`

`  56: ! Symmetry boundary condition on planar mesh`

`  57: lsel,s,line,,8,14,6`

`  58: nsll,s,1`

`  59: d,all,ux,0.0`

`  60: allsel,all`

`  61: ! Fixed boundary condition on planar mesh`

`  62: lsel,s,line,,1`

`  63: nsll,s,1`

`  64: d,all,all,0.0`

`  65: allsel,all`

`  66:  `

`  67: ! Grab the nodes on top and apply a downward displacement `

`  68: nsel,s,,,179`

`  69: nsel,a,,,219`

`  70: cm,ptop,node`

`  71: d,ptop,uy,-35`

`  72:  `

`  73: ! Run the model`

`  74: finish`

`  75: /solu`

`  76: nlgeom,on`

`  77: nsubst,200,500,10`

`  78: outres,all,all`

`  79: solve`

`  80:  `

`  81: ! Go to post 26 and get pressure and volume over time`

`  82: /post26`

`  83: numvar,200`

`  84: ESOL,2,180,1 ,NMISC,2,NMISC2_2 `

`  85: nsol,3,1,HDSP`

`  86: /grtyp,2`

`  87: plvar,2 ,3`

`  88:  `

`  89: !Animate the results`

`  90: /post1`

`  91: set,last`

`  92: /dscale,1,1`

`  93: /pnum,mat,1`

`  94: /number,1`

`  95: /edge,1,1`

`  96: !esel,u,,,eflp`

`  97: pldisp`

`  98: andata,0.1,,0,0,0,1,0,1`

`  99:  `

Here is the graph of the results.  Not very exciting.

# Other things to know

OK, this was a lot more involved than planned, and there is still more to learn.  But I’ve got HR paperwork to fill out so we will wrap it up.

You should go through the verification problem for this element: VM209

• You can connect different volumes with FLUID116 elements.  This allows some pretty fancy system modeling.  Add in some control elements and electromagnetics and you can really capture some complex systems.
• Be very aware of the negative volume issues when modeling tires and such.
• After I started on this article I found out that we are in the middle of a project for a customer who is modeling an optical device that has a fluid core.  It is working very well for them. I wish I could show the model, but I would be shot by the customer.  I can say that we are getting much better results than when we modeled the volume with solids.
• The FLUID80 is a solid fluid volume element that does take into account non-uniform pressure, mass, etc… Take a look at it if these guys don’t do what you need.
• Can you do this in Workbench?  Sort of.  You should be able to write a macro that uses a component to create your hydrostatic elements and define the material properties.  You won’t be able to post process the results but you can at least set it up and bring back plots. (check out this presentation, slide 41)
• ## Workbench Scripting: Using Forms in your Script

Last week we had a very well attended Webinar on using Scripting with Workbench. We talked about how you can control projects, parameters, and material properties with python.  We also talked about how you can use python to drive data compliant applications by sending commands and/or parameters to it.  You can watch the webinar at:

Click on PADT ANSYS Webinar Series and then find the recording from August 11, 2011.

Several attendees asked if we had an example of using python to bring up a GUI on top of workbench. We did not. This is how The Focus articles are born.

# The Basics

In case you missed the webinar or didn’t follow some of it, here are the important points:

• Workbench has IronPython built into it from the ground up
• You can record whatever you do in the GUI to create scripts
• You can read those scripts in to control Workbench
• ANSYS uses IronPython because it talks to Windows programs
• Get detailed info at www.python.org, www.ironpython.net, and www.ironpython.info

Most of the examples below are derived from information I got at: http://www.ironpython.info/index.php/Contents#Windows_Forms

We will be making a GUI for the famous Tower of Test application.  We will need a place to enter in the size of the tower, a pressure load. Then a simple table showing the results when we get them. And of course, buttons to cancel and execute.

If you are already an experienced Windows programmer, this will be a slam dunk. If you are not, then you will need to make sure you learn your way around the MSDN .Net Class Library Reference:

http://msdn.microsoft.com/en-US/library/ms229335(v=VS.80).aspx

That is where you find properties and methods for the GUI.  We will be spending most of our time in System.Windows.Form.

## Why .NET?

Right now, some of you might be asking “Why .NET?”  Python supports probably over a dozen different GUI’s.  I am using .NET for a few reasons:

1. It is built into IronPython. No need to download a library and install it right
2. It will have a consistent look and feel to Workbench
3. More people know .NET than the other GUI libraries.

If you are anit-microsoft, you can poke around and find a library that fits your needs.  The process will be the same.

Anytime I try and learn a new language, I usually find a “Hello World” Example.  And, thanks to the internet I found one that only needed slight modification:

`   1: import clr`

`   2: clr.AddReference('System.Windows.Forms')`

`   3:`

`   4: from System.Windows.Forms import Application, Form, Label`

`   5:`

`   6: form = Form(Text="Hello World Form")`

`   7: label = Label(Text="Hello World!")`

`   8:`

`   9: form.Controls.Add(label)`

`  10:`

`  11: Form.ShowDialog(form)`

So first, we access the huge number of Windows tools by importing clr.  Then, get a reference to Windows Forms.  Once that is done we need to import more from Windows Forms. This is a big tool box so it has lots of levels you have to dig through.  For this guy we need to be able to do the form itself (the window) and a label (text in the window).

Now that we have our objects, we create a form with the title “Hello World Form” and a label with the text “Hello World!”  We then use the Add method to add the label control to the form. Last, we use the Show Dialog method to show the form.  TADA.

To give it a try, copy and paste this into your own text editor and then go into Workbench and choose:

File->Scripting->Open Command Window…

Then paste in the script.  Or you can save it to a file and read it in. I like to paste so I can see my error messages as it goes.

Now you are a Workbench GUI programmer.  Put it on your resume!

# Walk: Add Some Controls to the Window

Next we want to do a bit more than saying hello.

The important thing I learned that I just didn’t’ get before is that you have to make a class out of your form and any functions that get called when the user clicks on a button or interacts in any way with the form.  You do this because Windows will then pass information about the form back to the event function.

In the example below is like “Hello World” to start, then we make 4 text boxes with labels for the user to enter data into.  We then add an OK and a Cancel button.  The code is commented with an explanation of what is going on.  If something does not make sense, look it up in a python reference or ask someone who is a python programmer.

`   1: # --  Bring in the .NET stuff, and reference Forms and drawing`

`   2: import clr`

`   3: clr.AddReference('System.Windows.Forms')`

`   4: clr.AddReference('System.Drawing')`

`   5:`

`   6: #   get the objects you need from forms and drawing`

`   7: from System.Windows.Forms import Form, Label, Button, TextBox`

`   8: from System.Drawing import Point, ContentAlignment`

`   9:`

`  10: #-- The way python works with events, you have to make a class out of your form.  `

`  11: #   Then the objects `

`  12: #    you add are available in event functions.`

`  13: class TowerForm(Form):`

`  14:     def __init__(self):`

`  15: #-- First, make the form (self)`

`  16:         self.text="Tower Simulation Tool"`

`  17:         self.Height=500`

`  18:         self.Width=250`

`  19:`

`  20: #-- Create a Simple Text Label describing the tool`

`  21: #   it is not self.label because we are not going to access it in event functions`

`  22:         lbl1 = Label()`

`  23:         lbl1.Text = "This is the Tower of Test Tool. \n\`

`  24:             Please Enter values and click OK to run the \`

`  25:             model and get new results\n"`

`  26:         lbl1.Height = 50`

`  27:         lbl1.Width = 200`

`  28:`

`  29: #-- Create the Text Labels and text boxes to get Dimensions and Pressure`

`  30: #   We need to get to the textboxes so we will make them part of the class`

`  31: #`

`  32: #   some constants to make the positioning easier`

`  33:         x1 = 10`

`  34:         y1 = 80`

`  35:         w1 = 70`

`  36:         w2 = 80`

`  37:         x2 = x1 + w1 + 10`

`  38: #   Make the labels for the text boxes.  This is done in the Labe() call with `

`  39: #   Name = Value arguments `

`  40: #   instead of object.name = value to save space.  All in one line instead of `

`  41: #   four lines.`

`  42: #     The alighment is done so that the labels are all right justified to line `

`  43: #     up with the boxes. Set ContentAlignment.MiddleRight to mr to save space`

`  44:         mr = ContentAlignment.MiddleRight`

`  45:         lb_Length=Label(Text="Length", Width=w1,TextAlign=mr)`

`  46:         lb_Width  = Label(Text="Width",   Width = w1, TextAlign=mr)`

`  47:         lb_Height = Label(Text="Height",  Width = w1, TextAlign=mr)`

`  48:         lb_Press  = Label(Text="Pressure",Width = w1, TextAlign=mr)`

`  49:`

`  50: #   Make the text boxes. Note that these are put in the self. class. `

`  51: #   We do this so that when the OK `

`  52: #   button is pushed, we have access to the text boxes and therefore the values `

`  53: #   typed within`

`  54:`

`  55:         self.tb_Length = TextBox(Width = w2)`

`  56:         self.tb_Width  = TextBox(Width = w2)`

`  57:         self.tb_Height = TextBox(Width = w2)`

`  58:         self.tb_Press  = TextBox(Width = w2)`

`  59:`

`  60: #   Specify the location for the label and the text boxes.  Move down by `

`  61: #   30 after each line`

`  62:         lb_Length.Location = Point(x1,y1)`

`  63:         self.tb_Length.Location = Point(x2,y1)`

`  64:         y1 = y1 + 30`

`  65:         lb_Width.Location = Point(x1,y1)`

`  66:         self.tb_Width.Location = Point(x2,y1)`

`  67:         y1 = y1 + 30`

`  68:         lb_Height.Location = Point(x1,y1)`

`  69:         self.tb_Height.Location = Point(x2,y1)`

`  70:         y1 = y1 + 30`

`  71:         lb_Press.Location = Point(x1,y1)`

`  72:         self.tb_Press.Location = Point(x2,y1)`

`  73:`

`  74: #   Make an OK and a Cancel Button`

`  75:         okBut = Button(Text="OK", Width=50)`

`  76:         okBut.Location = Point(30,430)`

`  77: #       This is where you specify the funtion to be called when the button is clicked`

`  78: #       note that you call the function self.functionname.`

`  79:         okBut.Click += self.okButPressed`

`  80:`

`  81:         cancelBut = Button(Text="Cancel", Width=50)`

`  82:         cancelBut.Location = Point(110,430)`

`  83:         cancelBut.Click += self.cancelButPressed`

`  84:`

`  85: #   Put everything on the form (some sort of list and loop would make this easier)`

`  86:         self.Controls.Add(lbl1)`

`  87:         self.Controls.Add(lb_Length)`

`  88:         self.Controls.Add(self.tb_Length)`

`  89:         self.Controls.Add(lb_Width)`

`  90:         self.Controls.Add(self.tb_Width)`

`  91:         self.Controls.Add(lb_Height)`

`  92:         self.Controls.Add(self.tb_Height)`

`  93:         self.Controls.Add(lb_Press)`

`  94:         self.Controls.Add(self.tb_Press)`

`  95:         self.Controls.Add(okBut)`

`  96:         self.Controls.Add(cancelBut)`

`  97:`

`  98: #-- Now define the button event functions as part of the class`

`  99: #`

` 100: # Cancel simply closes the form down.  Nothing fancy`

` 101:     def cancelButPressed(self, sender, args ):`

` 102:         print 'Closing the Window... Bye...\n'`

` 103:         self.Close()`

` 104:`

` 105: # OK prints the values of the text boxes to the console`

` 106: #   This will be replaced with calls to workbench for the next step`

` 107:     def okButPressed(self, sender, args ):`

` 108:         print 'Values Entered:\n'`

` 109:         print '  Length: %s\n' %self.tb_Length.Text`

` 110:         print '   Width: %s\n' %self.tb_Width.Text`

` 111:         print '  Height: %s\n' %self.tb_Height.Text`

` 112:         print 'Pressure: %s\n' %self.tb_Press.Text`

` 113:         self.Close()`

` 114: #---------End of class definition`

` 115:`

` 116:`

` 117: # Instantiate the form and make the form visible`

` 118: print '=======================================\n'`

` 119: print 'Opening the Windows...\n'`

` 120: myForm = TowerForm()`

` 121: Form.ShowDialog(myForm)`

` 122:`

If you have not programmed a go dialog box in a while by hand, instead of using a WYSIWIG GUI builder, you can see why.  Lots of lines… lots of lines…
Here is the file without the numbers in it so you can run it in Workbench:  TowerToolTextOnly.py

# Run:  Send Values to Workbench, Update Model, Get Results

If you remember the previous article on Driving Workbench from Excel this will all look familiar.  If you don’t review the article, especially the part about getting parameters in and out of Workbench with Python.  To finish our example we will use the same basic code to:

• Get the current values from Workbench and set our dialog to show those values
• When the user hits OK:
• Set the Workbench parameters to the current dialog box parameters
• Update the model
• Get the resulting deflection and display it.

The code is shown below, with the bits added for the Workbench interaction highlighted.  Note that we also introduced the specification of font properties on a label.  Making it even more fancy.

`   1: # --  Bring in the .NET stuff, and reference Forms and drawing`

`   2: import clr`

`   3: clr.AddReference('System.Windows.Forms')`

`   4: clr.AddReference('System.Drawing')`

`   5:`

`   6: #   get the objects you need from forms and drawing`

`   7: from System.Windows.Forms import Form, Label, Button, TextBox`

`   8: from System.Drawing import Point, ContentAlignment,`

Font, FontStyle, GraphicsUnit

`   9:`

`  10: #-- The way python works with events, you have to make a class out of your form.  `

`  11: #   Then the objects `

`  12: #    you add are available in event functions.`

`  13: class TowerForm(Form):`

`  14:     def __init__(self):`

`  15: #-- First, make the form (self)`

`  16:         self.text="Tower Simulation Tool"`

`  17:         self.Height=500`

`  18:         self.Width=250`

`  19:`

`  20: #-- Create a Simple Text Label describing the tool`

`  21: #   it is not self.label because we are not going to access it in event functions`

`  22:         lbl1 = Label()`

`  23:         lbl1.Text = "This is the Tower of Test Tool. \n\`

`  24:             Please Enter values and click OK to run the \`

`  25:             model and get new results\n"`

`  26:         lbl1.Height = 50`

`  27:         lbl1.Width = 200`

`  28:`

`  29: #-- Create the Text Labels and text boxes to get Dimensions and Pressure`

`  30: #   We need to get to the textboxes so we will make them part of the class`

`  31: #`

`  32: #   some constants to make the positioning easier`

`  33:         x1 = 10`

`  34:         y1 = 80`

`  35:         w1 = 70`

`  36:         w2 = 80`

`  37:         x2 = x1 + w1 + 10`

`  38: #   Make the labels for the text boxes.  This is done in the Labe() call with `

`  39: #   Name = Value arguments `

`  40: #   instead of object.name = value to save space.  All in one line instead of `

`  41: #   four lines.`

`  42: #     The alighment is done so that the labels are all right justified to line `

`  43: #     up with the boxes. Set ContentAlignment.MiddleRight to mr to save space`

`  44:         mr = ContentAlignment.MiddleRight`

`  45:         lb_Length=Label(Text="Length", Width=w1,TextAlign=mr)`

`  46:         lb_Width  = Label(Text="Width",   Width = w1, TextAlign=mr)`

`  47:         lb_Height = Label(Text="Height",  Width = w1, TextAlign=mr)`

`  48:         lb_Press  = Label(Text="Pressure",Width = w1, TextAlign=mr)`

`  49:`

`  50: #   Make a label to give status of the update in:`

`  51:`

self.updlbl = Label(Text=” “,Width=200, Height=100,\

`  52:`

TextAlign=ContentAlignment.BottomCenter)

`  53:`

self.updlbl.Location = Point(0,200)

`  54:`

self.updlbl.Font = \

`  55:`

Font(‘Verdana’,10, FontStyle.Bold, GraphicsUnit.Point,0)

`  56:`

`  57: #   Make the text boxes. Note that these are put in the self. class. `

`  58: #   We do this so that when the OK `

`  59: #   button is pushed, we have access to the text boxes and therefore the values `

`  60: #   typed within`

`  61:`

`  62:         self.tb_Length = TextBox(Width = w2)`

`  63:         self.tb_Width  = TextBox(Width = w2)`

`  64:         self.tb_Height = TextBox(Width = w2)`

`  65:         self.tb_Press  = TextBox(Width = w2)`

`  66:`

`  67: #   Specify the location for the label and the text boxes.  Move down by `

`  68: #   30 after each line`

`  69:         lb_Length.Location = Point(x1,y1)`

`  70:         self.tb_Length.Location = Point(x2,y1)`

`  71:         y1 = y1 + 30`

`  72:         lb_Width.Location = Point(x1,y1)`

`  73:         self.tb_Width.Location = Point(x2,y1)`

`  74:         y1 = y1 + 30`

`  75:         lb_Height.Location = Point(x1,y1)`

`  76:         self.tb_Height.Location = Point(x2,y1)`

`  77:         y1 = y1 + 30`

`  78:         lb_Press.Location = Point(x1,y1)`

`  79:         self.tb_Press.Location = Point(x2,y1)`

`  80:`

`  81:         self.tb_Length.Text = Parameters.GetParameter(Name="P1").Expression`

`  82:         self.tb_Width.Text = Parameters.GetParameter(Name="P2").Expression`

`  83:         self.tb_Height.Text = Parameters.GetParameter(Name="P3").Expression`

`  84:         self.tb_Press.Text = Parameters.GetParameter(Name="P5").Expression`

`  85:`

`  86: #   Make an OK and a Cancel Button`

`  87:         okBut = Button(Text="OK", Width=50)`

`  88:         okBut.Location = Point(30,430)`

`  89: #       This is where you specify the funtion to be called when the button is clicked`

`  90: #       note that you call the function self.functionname.`

`  91:         okBut.Click += self.okButPressed`

`  92:`

`  93:         cancelBut = Button(Text="Cancel", Width=50)`

`  94:         cancelBut.Location = Point(110,430)`

`  95:         cancelBut.Click += self.cancelButPressed`

`  96:`

`  97: #   Put everything on the form (some sort of list and loop would make this easier)`

`  98:         self.Controls.Add(lbl1)`

`  99:         self.Controls.Add(lb_Length)`

` 100:         self.Controls.Add(self.tb_Length)`

` 101:         self.Controls.Add(lb_Width)`

` 102:         self.Controls.Add(self.tb_Width)`

` 103:         self.Controls.Add(lb_Height)`

` 104:         self.Controls.Add(self.tb_Height)`

` 105:         self.Controls.Add(lb_Press)`

` 106:         self.Controls.Add(self.tb_Press)`

` 107:`

` 108:         self.Controls.Add(okBut)`

` 109:         self.Controls.Add(cancelBut)`

` 110:`

` 111: #-- Now define the button event functions as part of the class`

` 112: #`

` 113: # Cancel simply closes the form down.  Nothing fancy`

` 114:     def cancelButPressed(self, sender, args ):`

` 115:         print 'Closing the Window... Bye...\n'`

` 116:         self.Close()`

` 117:`

` 118: # OK prints the values of the text boxes to the console`

` 119: #   This will be replaced with calls to workbench for the next step`

` 120:     def okButPressed(self, sender, args ):`

` 121:`

` 122: # In Workbench: Get objects for all the parameters you need access to`

` 123: #   Remember, it goes by parameter name, not the name you give them.`

` 124:`

lenParam = Parameters.GetParameter(Name=“P1”)

` 125:`

widParam = Parameters.GetParameter(Name=“P2”)

` 126:`

hgtParam = Parameters.GetParameter(Name=“P3”)

` 127:`

prsParam = Parameters.GetParameter(Name=“P5”)

` 128: # don't forget the resulting deflection output parameter:`

` 129:`

defParam = Parameters.GetParameter(Name=“P4”)

` 130:`

` 131: # Now set the workbench values to the values from the dialog`

` 132:`

lenParam.Expression = self.tb_Length.Text

` 133:`

widParam.Expression = self.tb_Width.Text

` 134:`

hgtParam.Expression = self.tb_Height.Text

` 135:`

prsParam.Expression = self.tb_Press.Text

` 136:`

self.updlbl.Text = “Updating”

` 137:`

` 138:`

Update()

` 139:`

dflValue = defParam.Value.Value

` 140:`

self.updlbl.Text = “Deflection is %s in\n” %dflValue

` 141:`

` 142:`

` 143: #---------End of class definition`

` 144:`

` 145:`

` 146: # Instantiate the form and make the form visible`

` 147: print '=======================================\n'`

` 148: print 'Opening the Windows...\n'`

` 149: myForm = TowerForm()`

` 150: Form.ShowDialog(myForm)`

` 151:`

# Next Steps and Suggestions

And that in a nutshell is the basics of putting a GUI on Workbench.  By using the calls to Workbench, .NET or any other complaint application, you can script away and do what you want.

Much more can be done.  You could have the solver you are running in update and create some plots, and then use python to find those plots (say search for any *.jpg files in the project director created after the OK button was pushed) and insert them into PowerPoint with text that you also gather.

There really are no limitations.

To learn more, try stuff.  Get to know the MSDN documentation to know what you can do to make a more professional GUI.  The Windows Forms part of ironpython.info is a great resource for this and points to MSDN as needed.

There is a lot more you can do with ANSYS  Workbench and the various solvers.  And with each release, workbench will add and document more.

If you write a cool application you can share, make sure you put it on XANSYS or send it to Sheldon at ANSYS.net.

## CAE Market Fully Analyzed… Is that Cannibalism?

Just saw a news article that a consulting company called 01 Consulting just did a study of the CAE market.  Unfortunately the report is \$2,850 so, no matter how interested I am in the results I’m not going to buy one.

However they did release an Executive Summary:

http://www.01consulting.net/02_2011_MCAE_GLOBAL_Market_ES.html

And in there they have a cool graph that shows relative size (by revenue):

The size of MathWorks was shocking to me how big they are.  At their price point that is a lot of seats.  ANSYS dominates, with between 20% and 25% of the market.

The other thing they mention is continued double digit growth in the CAE segment.  Even in these times, people are getting the message that simulation pays back big.

## Workbench and Excel, Part 2: Driving Workbench From Excel with Python

For a couple of releases now you have been able to use the very common scripting language python to script applications that are considered Workbench native: the project page, Engineering Data, DesignXplorer, and the Parameter Manager.  This is pretty cool and something that we will cover in a future The Focus article.  But one thing that most people don’t know is that python also works well with Microsoft Excel.  So if it works with Excel and Workbench, you should be able to use it to connect the two.

Now before you get too excited, realize that ANSYS Mechanical, CFX, FLUENT, CFX Post and most other solvers and post processors that launch from Workbench are not workbench native applications, so they don’t speak python. So no, this is not a replacement for PADL or CCL.  They are called “data integrated” applications in that they share data through the Workbench interface, but they have their own software structure that is unique, and their own scripting language.

So to take advantage of this python commonality you have to connect to one of the native applications, and the parameter manager makes the most sense.  And fortunately the kind technical people at ANSYS, Inc. have provided a great example in the help system to do just that. And in doing so they have cut the length of this article in half.

# ANSYS Documentation Example

You can find the example under: Workbench //  Scripting Guide // Using Scripting in ANSYS Workbench // Usage Examples // Updating a Workbench Project and Parameters from Excel.  It is a very simple example, a cantilever beam, but it shows the basics and is a great place to start.

Read the manual page completely, especially the notes at the bottom.  They point out the key things you need to know.  The files you need are in the documentation, but you need to dig up the excel/workbench files and copy the python script and get rid of the line numbers.  I’ve put them all together in a zip file to make things easier:

There are a few things worth discussing on this example before we move on to something more complicated.

## How to Run It

One thing the example leaves out is the details on how to run it.  To start, you need to copy all the files to one directory: the python script, the workbench database, the workbench files, the excel file.  Then (it does point this out) you need to set the working directory variable in the script to the directory with all the files.  Now it is time to run. To do this open up Workbench with a new project (or File->New if you already have Workbench open).  Now run the script with File->Scripting->Run Script File…

This will launch Excel and Workbench and add the command to execute the update script when you push the button.  So, what next?  Change the value for Bar Length or Load and press the button.  This should cause Workbench to update and the Maximum Deformation value to change to Updating… and then the new value when the run is done.  And that, in a nutshell, is the basics of making the two tools talk.

## How it Works

The documentation does a pretty good job of explaining the details. The important take away is that you have to do a couple of key steps in any program that is going to do this sort of thing:

1. Tell python to load the Excel stuff
2. Set up the working directory, the routines all need absolute paths to work
3. Grab cell’s from excel, grab params from Workbench, and set one to the other as needed
4. Do an update
5. Provide a mechanism to start the process (the button in this case)

If you have these steps, you can make Excel and ANSYS talk.

## Where Things Run

An important thing to get your head around is where the script is running, or more accurately, what process is reading and executing the script. The python interpreter is actually in the Workbench environment.  When you run the python script you are not running it in Excel or in the operating system.  It is running through a interpreter inside Workbench.

This is important because it controls what information is automatically available to the script as well as how you launch it.  In this example, you launch from Workbench and it starts up Excel, does stuff in Excel, and then assigns a python routine to the button. When the button is clicked, you are still running a python script in Workbench – it is just talking to Excel.

## Limitations in the Example

There are two big limitations with this example when it comes to using it on a real problem. First, it is not general enough because you have to hard code in file names, directory locations, cell locations and strings. This is not a huge deal because if you are going to use an excel based simulation tool over and over, you only have to set it up once and go.

The other problem is that the action to update the spreadsheet and model is assigned as an OLEObject to the button. Unfortunately this is only active when the script is running. Once it is done the click action is removed, and the button becomes useless… allowing for only one use of the button.  This is a significant issue.

# A More General and Complex (Sort Of) Example

A common potential usage for this sort of tool would be to provide a user with an Excel based tool that they would use to design a part and see the results.  For this example we are going to use a very complicated tool for designing towers with a rectangular cross section.  The input variables are the length, width, and height of the tower as well as a pressure applied to one face.  The output variables are the deflection from the pressure and the first 10 natural frequencies.

Of course a real example would have more complex input and output values, and the spreadsheet would probably do a lot more calculations, perhaps even optimization.

This example avoids the button problem by actually running Workbench from Excel by launching it from the command console and supplying the project file AND the python script as startup parameters to Workbench.  Workbench loads the project, runs the script, then exits.

The sheet is not that different from the ANSYS provided example. It has cells for input and output parameters.  It also has a button to update the system.  The first thing that is different is that it uses named ranges for the input and output cells.  To see the names go to Formulas->Defined Names->Name Manager.  I used “Create from Selection” to automatically assign the text in Column B to the values in Column C an D for each row.

Also note the units. Because Workbench parameters (with the exception of Design Modeler parameters) are unit sensitive, you can specify the units in those columns and use them to do unit conversion as needed. In this example only the units on the Pressure are implemented to show how this is done.

There is also a little Drop Down Yes/No choice for the user to decide if they want to save the project file or not when they are done running.

The button is also different from the ANSYS example.  Instead of being assigned an action by the python script, it executes a very simple Visual Basic routine:

Private Sub CommandButton1_Click()
retval = Shell(“C:\Program Files\Ansys Inc\V130\Framework\bin\win64\runwb2 \

-X -R updateWB2.py -F ExcelTower1.wbpj”, vbNormalFocus)
End Sub

The line uses the Shell function to execute a system level command in Windows.  The command it runs is the command line way to start Workbench.

The –X says run interactive and exit when any given command line options are completed.

The –R gives a python script to be run, and this is our python script that is presented in detail below.

The –F specifies that project file to be executed.  As an aside, you could make this program more general by having a cell in the spreadsheet hold that file name and then substituting that value in the execution string.

## The ANSYS Model

This extremely complex model can be found in the following archived project file:

The model contains a DesignModeler solid, a static structural solution, and a modal analysis. The key aspect of the model are the parameters.

The outline for the parameter manager looks like this:

The various parameters were set up in each system in the normal way, by clicking on the parameter box next to them for each value you want to supply or return.  The key thing to note here are the Names (P1-P15) for the parameters, because this is what our python script will use to change or retrieve values before and after the model update.

## The Script

The actual script we are using is shown below.  Comments have been added to describe important steps.  You can download it, without the line numbers, here:

Please don’t laugh too hard. I ran out of time to convert the code into something more concise using do loops and variables.  The whole thing could be made much more general if you know python better than I do.

`   1: # IronPython imports to enable Excel interop,`

`   2: import clr`

`   3: clr.AddReference("Microsoft.Office.Interop.Excel")`

`   4: import Microsoft.Office.Interop.Excel as Excel`

`   5: from System.Runtime.InteropServices import Marshal`

`   6:  `

`   7: # import system things needed below`

`   8: from System.IO import Directory, Path`

`   9: from System import DateTime`

`  10:  `

`  11: # use the ANSYS function GetProjectDirectory to figure out what directory you are in`

`  12: # and set that to the current directory`

`  13: projDir = GetProjectDirectory()`

`  14: Directory.SetCurrentDirectory(projDir)`

`  15:  `

`  16: # Open up a log file to put useful information in`

`  17: logFile = open("TowerTool.log","w")`

`  18:  `

`  19: # Put a header in the log file`

`  20: logFile.write("================================================\n")`

`  21: logFile.write("Tower Tool Run Log File\n")`

`  22: logFile.write("================================================\n")`

`  23: logFile.write("Start time: " + DateTime.Now.ToString('yyyy-mm-dd hh:mm:ss') + "\n")`

`  24: logFile.write("Proj Dir: %s\n\n" % projDir)`

`  25:  `

`  26:  `

`  27: # Use the Excel GetActiveObject funtion to get the object for the excel session`

`  28: ex = Marshal.GetActiveObject("Excel.Application")`

`  29: # Make Excel visible`

`  30: ex.Visible = True`

`  31: # Define the active workbook and worksheet`

`  32: wb = ex.ActiveWorkbook`

`  33: ws = wb.ActiveSheet`

`  34:  `

`  35: # In Excel: Grab values for the cells that we want data from (input cells)`

`  36: length = ws.Range["Length"](1,1).Value2`

`  37: width = ws.Range["Width"](1,1).Value2`

`  38: height = ws.Range["Height"](1,1).Value2`

`  39: press = ws.Range["Pressure"](1,1).Value2`

`  40: upress =  ws.Range["Pressure"](1,2).Value2`

`  41:  `

`  42: # In Excel: See if the user wants to save the project after the update`

`  43: saveit = ws.Range["Save_Project"](1,1).Value2`

`  44:  `

`  45: # In Workbench: Grab the parameter objects for the input values`

`  46: lenParam = Parameters.GetParameter(Name="P1")`

`  47: widParam = Parameters.GetParameter(Name="P2")`

`  48: hgtParam = Parameters.GetParameter(Name="P3")`

`  49: prsParam = Parameters.GetParameter(Name="P5")`

`  50:  `

`  51: # In Workbench: Get the object for the deflection parameter vlue`

`  52: defParam = Parameters.GetParameter(Name="P4")`

`  53:  `

`  54: #In Workbench: Set the value of the input parameters in Workbench using the values `

`  55: #   we got from Excel`

`  56: lenParam.Expression = length.ToString()`

`  57: widParam.Expression = width.ToString()`

`  58: hgtParam.Expression = height.ToString()`

`  59: prsParam.Expression = press.ToString() + " [" + upress + "]"`

`  60:  `

`  61: # Set the output values to "Calculating..." since they no longer match the input values`

`  62: ws.Range["Max_Bending_Distance"](1,1).Value2 = "Calculating..."`

`  63: ws.Range["Mode_1"](1,1).Value2 = "Calculating..."`

`  64: ws.Range["Mode_2"](1,1).Value2 = "Calculating..."`

`  65: ws.Range["Mode_3"](1,1).Value2 = "Calculating..."`

`  66: ws.Range["Mode_4"](1,1).Value2 = "Calculating..."`

`  67: ws.Range["Mode_5"](1,1).Value2 = "Calculating..."`

`  68: ws.Range["Mode_6"](1,1).Value2 = "Calculating..."`

`  69: ws.Range["Mode_7"](1,1).Value2 = "Calculating..."`

`  70: ws.Range["Mode_8"](1,1).Value2 = "Calculating..."`

`  71: ws.Range["Mode_9"](1,1).Value2 = "Calculating..."`

`  72: ws.Range["Mode_10"](1,1).Value2 = "Calculating..."`

`  73:  `

`  74: # Now let Workbench go to town and update the systems using the new parameter values`

`  75: logFile.write("Updating Project\n")`

`  76: Update()`

`  77:  `

`  78: # If asked for, save the project`

`  79:  `

`  80: if saveit == "Yes": `

`  81:     logFile.write("Saving Project\n")`

`  82:     Save()`

`  83:  `

`  84: # Assign the value of the Excel deflection cell output deflection from Workbench `

`  85: ws.Range["Max_Bending_Distance"](1,1).Value2 = defParam.Value.Value`

`  86:  `

`  87: # Now go through the value of each natural frequency in Workbench and `

`  88: #   set the corresponding cell in Excel`

`  89: #    This could be made more general or at least more concise by using a do loop`

`  90: #    Also note that instead of getting the objects, then the values the two steps are `

`  91: #    combined for these values`

`  92: ws.Range["Mode_1"](1,1).Value2 = Parameters.GetParameter(Name="P6").Value.Value`

`  93: ws.Range["Mode_2"](1,1).Value2 = Parameters.GetParameter(Name="P7").Value.Value`

`  94: ws.Range["Mode_3"](1,1).Value2 = Parameters.GetParameter(Name="P8").Value.Value`

`  95: ws.Range["Mode_4"](1,1).Value2 = Parameters.GetParameter(Name="P9").Value.Value`

`  96: ws.Range["Mode_5"](1,1).Value2 = Parameters.GetParameter(Name="P10").Value.Value`

`  97: ws.Range["Mode_6"](1,1).Value2 = Parameters.GetParameter(Name="P11").Value.Value`

`  98: ws.Range["Mode_7"](1,1).Value2 = Parameters.GetParameter(Name="P12").Value.Value`

`  99: ws.Range["Mode_8"](1,1).Value2 = Parameters.GetParameter(Name="P13").Value.Value`

` 100: ws.Range["Mode_9"](1,1).Value2 = Parameters.GetParameter(Name="P14").Value.Value`

` 101: ws.Range["Mode_10"](1,1).Value2 = Parameters.GetParameter(Name="P15").Value.Value`

` 102:  `

` 103: # Done!  Close the log file and move on `

` 104: logFile.write("End time: " + DateTime.Now.ToString('yyyy-mm-dd hh:mm:ss') + "\n")`

` 105: logFile.close()`

## Execution

Execution is pretty simple.  When the user pushes  the Update system button the program goes off and launches Workbench with the script as input.  The script changes the parameters, updates the model, saves if asked for, updates the values in the spreadsheet, then Workbench exits.

One key thing to know is the issue with working directories.  The Excel file needs to be in the same directory as the script and the project.  Sometimes Excel changes the working directory (say you opened a different spreadsheet).  If you get an error on execution that Workbench can’t find the project file, you just need to go back to Excel and do a Save As in of your file on top of itself.  That fixes the problem. More advanced users can use VBA to control directories.

## Resources

The first resource for doing this type of work is the ANSYS Workbench->Scripting Guide in the online help.

ANSYS uses a flavor of python called IronPython. They have a great web site at:

Specific info on the connection to Excel can be found at: http://www.ironpython.info/index.php/Interacting_with_Excel

# Thoughts and Suggestions

Both examples presented are pretty simple, but they have the core of what you need to drive Workbench from Excel. It really is not that hard to do and can provide a nice interface for users who don’t know Workbench.

Some areas for improvement and suggestions for a real application are:

• Use jScript in Workbench to add a button that runs a script that attaches to an open Excel file and update based on the current values in that Excel file. So instead of running Workbench in batch from Excel, pressing the button would update everything.  That seems to be a more effective way to do it. (maybe a quick article in the future if Matt help me figure out how to add a button quickly…)
• Do more with VBA or Python in the Excel file to make you Excel based tool more sophisticated.
• There is no error checking in this example… very bad.  For a real world tool a lot more code should be added to check things and to capture errors from various functions.
• As one can imagine, this can be extended to other programs.  A good example would be an optimization tool or another “calculating” tool like MathCAD or Matlab.