Writing Text files with *VWRITE

A very common need in the world of ANSYS FEA simulation is to write text to a text file from within Mechanical APDL. Sometimes you are running in MAPDL, sometimes you are using ANSYS Mechanical but you still need to write stuff out using APDL with a code snippet. The way most people do that is with *VWRITE. 

Originally written to write out data in arrays, it is a very flexible and powerful command that can be used to write pretty much any type of formatted output. Something that every ANSYS user should have in their back pocket.

The Command

*VWRITE, Par1, Par2, Par3, Par4, Par5, Par6, Par7, Par8, Par9, Par10, Par11, Par12, Par13, Par14, Par15, Par16, Par17, Par18, Par19

Looks pretty simple right, just *vwrite and list what you want printed. But there is a lot more to this command.

A Lot More

First off you need to open up a file to write to.  You have a couple of options.

  1. *CFOPEN,fname, ext, –, Loc
    This opens the specified file for writing with *cfwrite and *vwrite commands.  This is the preferred method.
  2. /output,fname, ext, –, Loc
    By default *VWRITE output to standard output – the jobname.out (batch) file or the command window (interactive). So if you use /output you can redirect to a file instead of the *.out or screen.  We don’t recommend this because other stuff might get written as well to the file.

Now you have a place to write to, next you need to use *VWRITE to write. *VWRITE is a unique command because it actually uses two lines.  The first contains *VWRITE and a list of parameters and/or arrays to write and the second contains a format statement.  We will cover the first line first, and the format second.

Parameter Arguments for *VWRITE

As you can see from the command, you can have up to 19 parameters listed on a *VWRITE command.  PAR1 through PAR19 can be array, scalar, or character parameters. They can also be a constant. This is where the real flexibility comes in.  You can do something like (just look at the *VWRITE line, we will talk about the rest further on):


   1: adiv = ' | '

   2: *dim,nds, ,10

   3: *dim,temps,,10

   4: *vfill,nds(1),ramp,1,1

   5: *vfill,temps(1),rand,70,1500

   6: *cfopen,vw1.out

   7: *VWRITE,'Temp: ',nds(1),temps(1),adiv, 'TREF: ',70

   8: (A6,F8.0,g16.8,A3,A6,F10.4)

   9: *cfclose

This mixes characters, arrays, and constants in one command.  As output you get:

Temp:       1.   429.56308     | TREF:    70.0000
Temp: 2. 263.55403 | TREF: 70.0000
Temp: 3. 1482.8411 | TREF: 70.0000
Temp: 4. 605.95819 | TREF: 70.0000
Temp: 5. 782.33391 | TREF: 70.0000
Temp: 6. 1301.1332 | TREF: 70.0000
Temp: 7. 1119.4253 | TREF: 70.0000
Temp: 8. 202.87298 | TREF: 70.0000
Temp: 9. 1053.4121 | TREF: 70.0000
Temp: 10. 805.71033 | TREF: 70.0000

Array Parameters

The first thing you will notice is no *do loop.  If you supply an array parameter, *vwrite loops on the parameter from the given index (1 in this case) to the end of the array.  But if you don’t want the whole array written, you can control by placing *VLEN and/or *VMASK in front of the *VWRITE command:

  • *VLEN,nrow,ninc
    This will only write out nrow times, skipping based on ninc (defaults to 1)
    • As an example, if you want to write just the fourth value in array A() you would do:
      *VLEN,1
      *VWRITE,A(4)
      (G16.8)
  • *VMASK,Par
    You make a mask array of 0’s and 1 that is the same size as your array, and supply it to *VMASK.  *VWRITE will only write out values for your array if the mask array is not zero for the same index.

You can have a multiple dimensions on your array. *VWRITE only increments the first index. Say you specify X, Y, and Z coordinates in an array call xyz.  It would look like:

*VWRITE,xyz(1,1),XYZ(1,3),XYZ(1,3)
(3G16.8)

String Parameters

Being an older program, you are limited in what you can do with character parameters.  You are limited to 8 characters. So you just use a long string parameter several times and increment the index by 8:

   1: *dim,mystring,string,80

   2: mystring(1) = 'This is a very long sentance'

   3: *cfopen,vw2.out

   4: *VWRITE,mystring(1), mystring(9), mystring(17), mystring(25), mystring(33)

   5: (5A) 

   6: *cfclose

Kind of hokey, but it works.

Integers

Sigh.  This is the one thing that I’m not fond of in *VWRITE. The original command did not support outputting integer values.  That is because the FORTRAN I descriptor was not supported, and ANSYS stores everything as an integer anyhow. But people needed to output integer values so they took the ‘C’ format routines for *MSG and made them work with *VWRITE. So you can do a %I.  See the section on ‘C’ formatting below for more information on this.

Close the File

Before you can do anything with the file you create you need to close it.  Not to hard: *CFCLOSE does the trick.

Other Stuff you Need to Know

Don’t put a blank in there.  If you do, *vwrite stops looking at parameters.  So if you need a blank in your file, put in a space ‘ ‘ or use the X FORTRAN descriptor.

Be aware of *CFWRITE as well.  It is a way to write APDL commands to a file. If what you want to do is have your macro write a macro, *CFWRITE is better because you don’t have to do format statements. And those can be a pain when you need commas.

If your arrays are of different lengths, *VWRITE will loop for the length of the longest array. Any shorter arrays will be replaced with zeros for number arrays and blanks for character/string arrays.

You can not use *VWRITE by pasting or typing into the command line.  You have to read it from a file.

Formatting

The key, and the difficult part of using *VWRITE is the format statement. We recommend that you use the FORTRAN formatting when you are writing out large amounts of columnar data, and use the ‘C’ format if you are writing out text rich information for a report or to inform the user of something.

Many users today may not even know what a FORTRAN statement looks like.  A good place to look is:
http://www.stanford.edu/class/me200c/tutorial_77/17_format.html

Just remember that you can’t use the Integer (I) format.  The list directed format (*) also does not work.  If you are new to it also remember everything goes in parenthesis and it has to fit on one line.  It does not have to start in column 8 (if you think that is funny, you are old)

As to ‘C’ formatting, you have a lot more options but we have found that the behavior is not as consistent between Linux and windows as the FORTRAN.  But if you are more comfortable with ‘C’, do that. Not all of ‘C’ formatting works in APDL, but what does is actually documented under the *MSG command. 

Making it Work

We always recommend you work out your *VWRITE issues in a small macro that you can run over and over again as you work out the formatting.  If you are writing a snippet for ANSYS Mechanical. Go ahead and save your model, bring it up in MAPDL, then work on your *VWRITE statement till you get it right.

Some other useful suggestions are:

  • Keep things simple. Don’t try and format a novel or an HTML page with *VWRITE.  You probably could, but there are better tools for that.
  • Make sure you understand arrays, how they work in APDL, and how you have yours dimensioned.
  • Get familiar with *VMASK and *VLEN. They are useful

One Reply to “Writing Text files with *VWRITE”

  1. Hi Eric.
    There is an easier way to write large strings that makes use of the the C format descriptor:

    *dim,mystring,string,80
    mystring(1) = ‘This is a string of up to 80 characters’
    *CFOPEN,’file’,txt
    *VWRITE,mystring(1)
    %C
    *CFCLOSE

    Kind regards
    Christian